mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
whisper: mail server introduced
This commit is contained in:
parent
b392986c5c
commit
202ac23df2
5 changed files with 235 additions and 63 deletions
168
cmd/wnode/mailserver.go
Normal file
168
cmd/wnode/mailserver.go
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
// Copyright 2016 The go-ethereum Authors
|
||||||
|
// This file is part of go-ethereum.
|
||||||
|
//
|
||||||
|
// go-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// go-ethereum is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||||
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WMailServer struct {
|
||||||
|
db *leveldb.DB
|
||||||
|
w *whisper.Whisper
|
||||||
|
pow float64
|
||||||
|
key []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type DBKey struct {
|
||||||
|
timestamp uint32
|
||||||
|
hash common.Hash
|
||||||
|
raw []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDbKey(t uint32, h common.Hash) *DBKey {
|
||||||
|
const sz = common.HashLength + sizeOfInt
|
||||||
|
var k DBKey
|
||||||
|
k.timestamp = t
|
||||||
|
k.hash = h
|
||||||
|
k.raw = make([]byte, sz)
|
||||||
|
binary.BigEndian.PutUint32(k.raw, k.timestamp)
|
||||||
|
copy(k.raw[sizeOfInt:], k.hash[:])
|
||||||
|
return &k
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, pow float64) {
|
||||||
|
var err error
|
||||||
|
if len(path) == 0 {
|
||||||
|
utils.Fatalf("DB file is not specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(password) == 0 {
|
||||||
|
utils.Fatalf("Password is not specified for MailServer")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.db, err = leveldb.OpenFile(path, nil)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to open DB file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.w = shh
|
||||||
|
s.pow = pow
|
||||||
|
|
||||||
|
err = s.w.AddSymKey(mailServerKeyName, []byte(password))
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to create symmetric key for MailServer: %s", err)
|
||||||
|
}
|
||||||
|
s.key = s.w.GetSymKey(mailServerKeyName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WMailServer) Close() {
|
||||||
|
if s.db != nil {
|
||||||
|
s.db.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WMailServer) Archive(env *whisper.Envelope) {
|
||||||
|
key := NewDbKey(env.Expiry-env.TTL, env.Hash())
|
||||||
|
rawEnvelope, err := rlp.EncodeToBytes(env)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("rlp.EncodeToBytes failed: %s", err)
|
||||||
|
} else {
|
||||||
|
err = s.db.Put(key.raw, rawEnvelope, nil)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Writing to DB failed: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WMailServer) DeliverMail(peer *whisper.Peer, request *whisper.Envelope) {
|
||||||
|
ok, lower, upper, topic := s.validate(peer, request)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var zero common.Hash
|
||||||
|
var empty whisper.TopicType
|
||||||
|
kl := NewDbKey(lower, zero)
|
||||||
|
ku := NewDbKey(upper, zero)
|
||||||
|
i := s.db.NewIterator(&util.Range{Start: kl.raw, Limit: ku.raw}, nil)
|
||||||
|
defer i.Release()
|
||||||
|
|
||||||
|
for i.Next() {
|
||||||
|
var envelope whisper.Envelope
|
||||||
|
err = envelope.DecodeBytes(i.Value())
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("RLP decoding failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if topic == empty || envelope.Topic == topic {
|
||||||
|
err = s.w.SendP2PDirect(peer, &envelope)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Failed to send direct message to peer: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = i.Error()
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Level DB iterator error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WMailServer) validate(peer *whisper.Peer, request *whisper.Envelope) (bool, uint32, uint32, whisper.TopicType) {
|
||||||
|
var topic whisper.TopicType
|
||||||
|
if s.pow > 0.0 && request.PoW() < s.pow {
|
||||||
|
return false, 0, 0, topic
|
||||||
|
}
|
||||||
|
|
||||||
|
f := whisper.Filter{KeySym: s.key}
|
||||||
|
decrypted := request.Open(&f)
|
||||||
|
if decrypted == nil {
|
||||||
|
glog.V(logger.Warn).Infof("Failed to decrypt p2p request")
|
||||||
|
return false, 0, 0, topic
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(decrypted.Payload) < sizeOfInt*2 {
|
||||||
|
glog.V(logger.Warn).Infof("Undersized p2p request")
|
||||||
|
return false, 0, 0, topic
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytes.Equal(peer.ID(), decrypted.Signature) {
|
||||||
|
glog.V(logger.Warn).Infof("Wrong signature of p2p request")
|
||||||
|
return false, 0, 0, topic
|
||||||
|
}
|
||||||
|
|
||||||
|
lower := binary.BigEndian.Uint32(decrypted.Payload[:sizeOfInt])
|
||||||
|
upper := binary.BigEndian.Uint32(decrypted.Payload[sizeOfInt : sizeOfInt*2])
|
||||||
|
|
||||||
|
if len(decrypted.Payload) == sizeOfInt*2+whisper.TopicLength {
|
||||||
|
topic = whisper.BytesToTopic(decrypted.Payload[sizeOfInt*2 : sizeOfInt*2+whisper.TopicLength])
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, lower, upper, topic
|
||||||
|
}
|
||||||
|
|
@ -43,7 +43,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||||
"golang.org/x/crypto/pbkdf2"
|
"golang.org/x/crypto/pbkdf2"
|
||||||
)
|
)
|
||||||
|
|
@ -53,7 +52,7 @@ const sizeOfInt = 4
|
||||||
var (
|
var (
|
||||||
quitCommand = "~Q"
|
quitCommand = "~Q"
|
||||||
enodePrefix = "enode://"
|
enodePrefix = "enode://"
|
||||||
mailServerKeyName = "fd8c027e29852ef"
|
mailServerKeyName = "958e04ab302fb36ad2616a352cbac79dfa08f43d325d0833e07061a9ef8c383d"
|
||||||
)
|
)
|
||||||
|
|
||||||
// singletons
|
// singletons
|
||||||
|
|
@ -81,7 +80,7 @@ var (
|
||||||
echoMode = flag.Bool("e", false, "echo mode: prints some arguments for diagnostics")
|
echoMode = flag.Bool("e", false, "echo mode: prints some arguments for diagnostics")
|
||||||
bootstrapMode = flag.Bool("b", false, "boostrap node: don't actively connect to peers, wait for incoming connections")
|
bootstrapMode = flag.Bool("b", false, "boostrap node: don't actively connect to peers, wait for incoming connections")
|
||||||
forwarderMode = flag.Bool("f", false, "forwarder mode: only forward messages, neither send nor decrypt messages")
|
forwarderMode = flag.Bool("f", false, "forwarder mode: only forward messages, neither send nor decrypt messages")
|
||||||
mailServerMode = flag.Bool("m", false, "mail server mode: delivers expired messages on demand")
|
mailServerMode = flag.Bool("s", false, "mail server mode: delivers expired messages on demand")
|
||||||
requestMail = flag.Bool("r", false, "request expired messages from the bootstrap server")
|
requestMail = flag.Bool("r", false, "request expired messages from the bootstrap server")
|
||||||
asymmetricMode = flag.Bool("a", false, "use asymmetric encryption")
|
asymmetricMode = flag.Bool("a", false, "use asymmetric encryption")
|
||||||
testMode = flag.Bool("t", false, "use of predefined parameters for diagnostics")
|
testMode = flag.Bool("t", false, "use of predefined parameters for diagnostics")
|
||||||
|
|
@ -150,7 +149,6 @@ func echo() {
|
||||||
fmt.Printf("mspow = %f \n", *argServerPoW)
|
fmt.Printf("mspow = %f \n", *argServerPoW)
|
||||||
fmt.Printf("ip = %s \n", *argIP)
|
fmt.Printf("ip = %s \n", *argIP)
|
||||||
fmt.Printf("salt = %s \n", *argSalt)
|
fmt.Printf("salt = %s \n", *argSalt)
|
||||||
fmt.Printf("topic = %x \n", topic)
|
|
||||||
fmt.Printf("pub = %s \n", common.ToHex(crypto.FromECDSAPub(pub)))
|
fmt.Printf("pub = %s \n", common.ToHex(crypto.FromECDSAPub(pub)))
|
||||||
fmt.Printf("idfile = %s \n", *argIDFile)
|
fmt.Printf("idfile = %s \n", *argIDFile)
|
||||||
fmt.Printf("dbpath = %s \n", *argDBPath)
|
fmt.Printf("dbpath = %s \n", *argDBPath)
|
||||||
|
|
@ -175,7 +173,7 @@ func initialize() {
|
||||||
|
|
||||||
if *bootstrapMode {
|
if *bootstrapMode {
|
||||||
if len(*argIP) == 0 {
|
if len(*argIP) == 0 {
|
||||||
argIP = scanLineA("Please enter your IP and port (e.g. 127.0.0.1:30303): ")
|
argIP = scanLineA("Please enter your IP and port (e.g. 127.0.0.1:30348): ")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if len(*argEnode) == 0 {
|
if len(*argEnode) == 0 {
|
||||||
|
|
@ -185,12 +183,13 @@ func initialize() {
|
||||||
peers = append(peers, peer)
|
peers = append(peers, peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *mailServerMode && len(msPassword) == 0 {
|
if *mailServerMode {
|
||||||
msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ")
|
if len(msPassword) == 0 {
|
||||||
if err != nil {
|
msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ")
|
||||||
utils.Fatalf("Failed to read Mail Server password: %s", err)
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to read Mail Server password: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shh = whisper.NewWhisper(&mailServer)
|
shh = whisper.NewWhisper(&mailServer)
|
||||||
mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW)
|
mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -247,16 +246,29 @@ func isKeyValid(k *ecdsa.PublicKey) bool {
|
||||||
|
|
||||||
func configureNode() {
|
func configureNode() {
|
||||||
var err error
|
var err error
|
||||||
|
var p2pAccept bool
|
||||||
|
|
||||||
if *forwarderMode {
|
if *forwarderMode {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if *asymmetricMode && len(*argPub) == 0 {
|
if *asymmetricMode {
|
||||||
s := scanLine("Please enter the peer's public key: ")
|
if len(*argPub) == 0 {
|
||||||
pub = crypto.ToECDSAPub(common.FromHex(s))
|
s := scanLine("Please enter the peer's public key: ")
|
||||||
if !isKeyValid(pub) {
|
pub = crypto.ToECDSAPub(common.FromHex(s))
|
||||||
utils.Fatalf("Error: invalid public key")
|
if !isKeyValid(pub) {
|
||||||
|
utils.Fatalf("Error: invalid public key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if *requestMail {
|
||||||
|
p2pAccept = true
|
||||||
|
if len(msPassword) == 0 {
|
||||||
|
msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ")
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to read Mail Server password: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,15 +295,14 @@ func configureNode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if *requestMail && len(msPassword) == 0 {
|
filter := whisper.Filter{
|
||||||
msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ")
|
KeySym: symKey,
|
||||||
if err != nil {
|
KeyAsym: asymKey,
|
||||||
utils.Fatalf("Failed to read Mail Server password: %s", err)
|
Topics: []whisper.TopicType{topic},
|
||||||
}
|
AcceptP2P: p2pAccept,
|
||||||
}
|
}
|
||||||
|
filterID = shh.Watch(&filter)
|
||||||
filter := &whisper.Filter{KeySym: symKey, KeyAsym: asymKey, Topics: []whisper.TopicType{topic}}
|
fmt.Printf("Filter is configured for the topic: %x \n", topic)
|
||||||
filterID = shh.Watch(filter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateTopic(password, salt []byte) {
|
func generateTopic(password, salt []byte) {
|
||||||
|
|
@ -451,7 +462,10 @@ func printMessageInfo(msg *whisper.ReceivedMessage) {
|
||||||
|
|
||||||
func requestExpiredMessagesLoop() {
|
func requestExpiredMessagesLoop() {
|
||||||
var key, peerID []byte
|
var key, peerID []byte
|
||||||
var timeLow, timeUpp, t uint32
|
var timeLow, timeUpp uint32
|
||||||
|
var t string
|
||||||
|
var xt, empty whisper.TopicType
|
||||||
|
|
||||||
err := shh.AddSymKey(mailServerKeyName, []byte(msPassword))
|
err := shh.AddSymKey(mailServerKeyName, []byte(msPassword))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to create symmetric key for mail request: %s", err)
|
utils.Fatalf("Failed to create symmetric key for mail request: %s", err)
|
||||||
|
|
@ -463,16 +477,23 @@ func requestExpiredMessagesLoop() {
|
||||||
for {
|
for {
|
||||||
timeLow = scanUint("Please enter the lower limit of the time range (unix timestamp): ")
|
timeLow = scanUint("Please enter the lower limit of the time range (unix timestamp): ")
|
||||||
timeUpp = scanUint("Please enter the upper limit of the time range (unix timestamp): ")
|
timeUpp = scanUint("Please enter the upper limit of the time range (unix timestamp): ")
|
||||||
t = scanUint("Please enter the topic: ")
|
t = scanLine("Please enter the topic (hexadecimal): ")
|
||||||
|
if len(t) >= whisper.TopicLength*2 {
|
||||||
|
x, err := hex.DecodeString(t)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to parse the topic: %s", err)
|
||||||
|
}
|
||||||
|
xt = whisper.BytesToTopic(x)
|
||||||
|
}
|
||||||
if timeUpp == 0 {
|
if timeUpp == 0 {
|
||||||
timeUpp = 0xFFFFFFFF
|
timeUpp = 0xFFFFFFFF
|
||||||
}
|
}
|
||||||
|
|
||||||
data := make([]byte, sizeOfInt*3)
|
data := make([]byte, sizeOfInt*2+whisper.TopicLength)
|
||||||
binary.BigEndian.PutUint32(data, timeLow)
|
binary.BigEndian.PutUint32(data, timeLow)
|
||||||
binary.BigEndian.PutUint32(data[sizeOfInt:], timeUpp)
|
binary.BigEndian.PutUint32(data[sizeOfInt:], timeUpp)
|
||||||
binary.BigEndian.PutUint32(data[sizeOfInt*2:], t)
|
copy(data[sizeOfInt*2:], xt[:])
|
||||||
if t == 0 {
|
if xt == empty {
|
||||||
data = data[:sizeOfInt*2]
|
data = data[:sizeOfInt*2]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -489,12 +510,7 @@ func requestExpiredMessagesLoop() {
|
||||||
utils.Fatalf("Wrap failed: %s", err)
|
utils.Fatalf("Wrap failed: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
encoded, err := rlp.EncodeToBytes(env)
|
err = shh.RequestHistoricMessages(peerID, env)
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("RLP encoding failed: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = shh.RequestHistoricMessages(peerID, encoded)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to send P2P message: %s", err)
|
utils.Fatalf("Failed to send P2P message: %s", err)
|
||||||
}
|
}
|
||||||
|
|
@ -526,11 +542,3 @@ func extractIdFromEnode(s string) []byte {
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is a temporary stub, will be expanded later
|
|
||||||
type WMailServer struct{}
|
|
||||||
|
|
||||||
func (s *WMailServer) Archive(env *whisper.Envelope) {}
|
|
||||||
func (s *WMailServer) DeliverMail(peer *whisper.Peer, data []byte) {}
|
|
||||||
func (s *WMailServer) Init(w *whisper.Whisper, path string, password string, pow float64) {}
|
|
||||||
func (s *WMailServer) Close() {}
|
|
||||||
|
|
|
||||||
|
|
@ -93,12 +93,12 @@ func (api *PublicWhisperAPI) MarkPeerTrusted(peerID hexutil.Bytes) error {
|
||||||
// data contains parameters (time frame, payment details, etc.), required
|
// data contains parameters (time frame, payment details, etc.), required
|
||||||
// by the remote email-like server. Whisper is not aware about the data format,
|
// by the remote email-like server. Whisper is not aware about the data format,
|
||||||
// it will just forward the raw data to the server.
|
// it will just forward the raw data to the server.
|
||||||
func (api *PublicWhisperAPI) RequestHistoricMessages(peerID hexutil.Bytes, data hexutil.Bytes) error {
|
//func (api *PublicWhisperAPI) RequestHistoricMessages(peerID hexutil.Bytes, data hexutil.Bytes) error {
|
||||||
if api.whisper == nil {
|
// if api.whisper == nil {
|
||||||
return whisperOffLineErr
|
// return whisperOffLineErr
|
||||||
}
|
// }
|
||||||
return api.whisper.RequestHistoricMessages(peerID, data)
|
// return api.whisper.RequestHistoricMessages(peerID, data)
|
||||||
}
|
//}
|
||||||
|
|
||||||
// HasIdentity checks if the whisper node is configured with the private key
|
// HasIdentity checks if the whisper node is configured with the private key
|
||||||
// of the specified public pair.
|
// of the specified public pair.
|
||||||
|
|
|
||||||
|
|
@ -83,5 +83,5 @@ func (e unknownVersionError) Error() string {
|
||||||
// in order to bypass the expiry checks.
|
// in order to bypass the expiry checks.
|
||||||
type MailServer interface {
|
type MailServer interface {
|
||||||
Archive(env *Envelope)
|
Archive(env *Envelope)
|
||||||
DeliverMail(whisperPeer *Peer, data []byte)
|
DeliverMail(whisperPeer *Peer, request *Envelope)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
"golang.org/x/crypto/pbkdf2"
|
"golang.org/x/crypto/pbkdf2"
|
||||||
set "gopkg.in/fatih/set.v0"
|
set "gopkg.in/fatih/set.v0"
|
||||||
)
|
)
|
||||||
|
|
@ -125,13 +124,13 @@ func (w *Whisper) MarkPeerTrusted(peerID []byte) error {
|
||||||
return nil
|
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)
|
p, err := w.getPeer(peerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.trusted = true
|
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 {
|
func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error {
|
||||||
|
|
@ -361,25 +360,22 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
||||||
// therefore might not satisfy the PoW, expiry and other requirements.
|
// therefore might not satisfy the PoW, expiry and other requirements.
|
||||||
// these messages are only accepted from the trusted peer.
|
// these messages are only accepted from the trusted peer.
|
||||||
if p.trusted {
|
if p.trusted {
|
||||||
var envelopes []*Envelope
|
var envelope Envelope
|
||||||
if err := packet.Decode(&envelopes); err != nil {
|
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)
|
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)")
|
return fmt.Errorf("garbage received (directMessage)")
|
||||||
}
|
}
|
||||||
for _, envelope := range envelopes {
|
wh.postEvent(&envelope, true)
|
||||||
wh.postEvent(envelope, true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case p2pRequestCode:
|
case p2pRequestCode:
|
||||||
// Must be processed if mail server is implemented. Otherwise ignore.
|
// Must be processed if mail server is implemented. Otherwise ignore.
|
||||||
if wh.mailServer != nil {
|
if wh.mailServer != nil {
|
||||||
s := rlp.NewStream(packet.Payload, uint64(packet.Size))
|
var request Envelope
|
||||||
data, err := s.Bytes()
|
if err := packet.Decode(&request); err != nil {
|
||||||
if err == nil {
|
glog.V(logger.Warn).Infof("%v: failed to decode p2p request message: [%v], peer will be disconnected", p.peer, err)
|
||||||
wh.mailServer.DeliverMail(p, data)
|
return fmt.Errorf("garbage received (p2p request)")
|
||||||
} else {
|
|
||||||
glog.V(logger.Error).Infof("%v: bad requestHistoricMessages received: [%v]", p.peer, err)
|
|
||||||
}
|
}
|
||||||
|
wh.mailServer.DeliverMail(p, &request)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// New message types might be implemented in the future versions of Whisper.
|
// New message types might be implemented in the future versions of Whisper.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue