mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
whisper: final update
This commit is contained in:
parent
539e3f3586
commit
ffd1bf83ed
5 changed files with 94 additions and 18 deletions
|
|
@ -32,6 +32,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/console"
|
||||
|
|
@ -80,6 +84,7 @@ var (
|
|||
asymmetricMode = flag.Bool("a", false, "use asymmetric encryption")
|
||||
testMode = flag.Bool("t", false, "use of predefined parameters for diagnostics")
|
||||
generateKey = flag.Bool("k", false, "generate and show the private key")
|
||||
fileExMode = flag.Bool("x", false, "file exchange mode")
|
||||
|
||||
argVerbosity = flag.Int("verbosity", int(log.LvlWarn), "log verbosity level")
|
||||
argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds")
|
||||
|
|
@ -87,12 +92,13 @@ var (
|
|||
argPoW = flag.Float64("pow", whisper.DefaultMinimumPoW, "PoW for normal messages in float format (e.g. 2.7)")
|
||||
argServerPoW = flag.Float64("mspow", whisper.DefaultMinimumPoW, "PoW requirement for Mail Server request")
|
||||
|
||||
argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)")
|
||||
argPub = flag.String("pub", "", "public key for asymmetric encryption")
|
||||
argDBPath = flag.String("dbpath", "", "path to the server's DB directory")
|
||||
argIDFile = flag.String("idfile", "", "file name with node id (private key)")
|
||||
argEnode = flag.String("boot", "", "bootstrap node you want to connect to (e.g. enode://e454......08d50@52.176.211.200:16428)")
|
||||
argTopic = flag.String("topic", "", "topic in hexadecimal format (e.g. 70a4beef)")
|
||||
argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)")
|
||||
argPub = flag.String("pub", "", "public key for asymmetric encryption")
|
||||
argDBPath = flag.String("dbpath", "", "path to the server's DB directory")
|
||||
argIDFile = flag.String("idfile", "", "file name with node id (private key)")
|
||||
argEnode = flag.String("boot", "", "bootstrap node you want to connect to (e.g. enode://e454......08d50@52.176.211.200:16428)")
|
||||
argTopic = flag.String("topic", "", "topic in hexadecimal format (e.g. 70a4beef)")
|
||||
argSaveDir = flag.String("savedir", "", "directory where incoming messages will be saved as files")
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
@ -134,6 +140,14 @@ func processArgs() {
|
|||
}
|
||||
}
|
||||
|
||||
if len(*argSaveDir) > 0 {
|
||||
if _, err := os.Stat(*argSaveDir); os.IsNotExist(err) {
|
||||
utils.Fatalf("Download directory '%s' does not exist", *argSaveDir)
|
||||
}
|
||||
} else if *fileExMode {
|
||||
utils.Fatalf("Parameter 'savedir' is mandatory for file exchange mode")
|
||||
}
|
||||
|
||||
if *echoMode {
|
||||
echo()
|
||||
}
|
||||
|
|
@ -374,6 +388,8 @@ func run() {
|
|||
|
||||
if *requestMail {
|
||||
requestExpiredMessagesLoop()
|
||||
} else if *fileExMode {
|
||||
sendFilesLoop()
|
||||
} else {
|
||||
sendLoop()
|
||||
}
|
||||
|
|
@ -399,6 +415,31 @@ func sendLoop() {
|
|||
}
|
||||
}
|
||||
|
||||
func sendFilesLoop() {
|
||||
for {
|
||||
s := scanLine("")
|
||||
if s == quitCommand {
|
||||
fmt.Println("Quit command received")
|
||||
close(done)
|
||||
break
|
||||
}
|
||||
b, err := ioutil.ReadFile(s)
|
||||
if err != nil {
|
||||
fmt.Printf(">>> Error: %s \n", err)
|
||||
continue
|
||||
} else {
|
||||
h := sendMsg(b)
|
||||
if (h == common.Hash{}) {
|
||||
fmt.Printf(">>> Error: message was not sent \n")
|
||||
} else {
|
||||
timestamp := time.Now().Unix()
|
||||
from := crypto.PubkeyToAddress(asymKey.PublicKey)
|
||||
fmt.Printf("\n%d <%x>: sent message with hash %x\n", timestamp, from, h)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func scanLine(prompt string) string {
|
||||
if len(prompt) > 0 {
|
||||
fmt.Print(prompt)
|
||||
|
|
@ -425,7 +466,7 @@ func scanUint(prompt string) uint32 {
|
|||
return uint32(i)
|
||||
}
|
||||
|
||||
func sendMsg(payload []byte) {
|
||||
func sendMsg(payload []byte) common.Hash {
|
||||
params := whisper.MessageParams{
|
||||
Src: asymKey,
|
||||
Dst: pub,
|
||||
|
|
@ -441,13 +482,16 @@ func sendMsg(payload []byte) {
|
|||
envelope, err := msg.Wrap(¶ms)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to seal message: %v \n", err)
|
||||
return
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
err = shh.Send(envelope)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to send message: %v \n", err)
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
return envelope.Hash()
|
||||
}
|
||||
|
||||
func messageLoop() {
|
||||
|
|
@ -463,7 +507,11 @@ func messageLoop() {
|
|||
case <-ticker.C:
|
||||
messages := f.Retrieve()
|
||||
for _, msg := range messages {
|
||||
printMessageInfo(msg)
|
||||
if *fileExMode {
|
||||
saveMessageInFile(msg)
|
||||
} else {
|
||||
printMessageInfo(msg)
|
||||
}
|
||||
}
|
||||
case <-done:
|
||||
return
|
||||
|
|
@ -487,6 +535,29 @@ func printMessageInfo(msg *whisper.ReceivedMessage) {
|
|||
}
|
||||
}
|
||||
|
||||
func saveMessageInFile(msg *whisper.ReceivedMessage) {
|
||||
timestamp := fmt.Sprintf("%d", msg.Sent)
|
||||
name := fmt.Sprintf("%x", msg.EnvelopeHash)
|
||||
|
||||
var address common.Address
|
||||
if msg.Src != nil {
|
||||
address = crypto.PubkeyToAddress(*msg.Src)
|
||||
}
|
||||
|
||||
if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) {
|
||||
// message from myself: don't save, only report
|
||||
fmt.Printf("\n%s <%x>: message received: '%s'\n", timestamp, address, name)
|
||||
} else {
|
||||
fullpath := filepath.Join(*argSaveDir, name)
|
||||
err := ioutil.WriteFile(fullpath, msg.Payload, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("\n%s [%x]: message received but not saved: %s\n", timestamp, address, err)
|
||||
} else {
|
||||
fmt.Printf("\n%s [%x]: message received and saved as '%s'\n", timestamp, address, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func requestExpiredMessagesLoop() {
|
||||
var key, peerID []byte
|
||||
var timeLow, timeUpp uint32
|
||||
|
|
@ -502,7 +573,7 @@ func requestExpiredMessagesLoop() {
|
|||
utils.Fatalf("Failed to save symmetric key for mail request: %s", err)
|
||||
}
|
||||
peerID = extractIdFromEnode(*argEnode)
|
||||
shh.MarkPeerTrusted(peerID)
|
||||
shh.AllowP2PMessagesFromPeer(peerID)
|
||||
|
||||
for {
|
||||
timeLow = scanUint("Please enter the lower limit of the time range (unix timestamp): ")
|
||||
|
|
|
|||
|
|
@ -86,13 +86,19 @@ func (api *PublicWhisperAPI) SetMinimumPoW(val float64) error {
|
|||
return api.whisper.SetMinimumPoW(val)
|
||||
}
|
||||
|
||||
// MarkPeerTrusted marks specific peer trusted, which will allow it
|
||||
// AllowP2PMessagesFromPeer marks specific peer trusted, which will allow it
|
||||
// to send historic (expired) messages.
|
||||
func (api *PublicWhisperAPI) MarkPeerTrusted(peerID hexutil.Bytes) error {
|
||||
func (api *PublicWhisperAPI) AllowP2PMessagesFromPeer(enode string) error {
|
||||
if api.whisper == nil {
|
||||
return whisperOffLineErr
|
||||
}
|
||||
return api.whisper.MarkPeerTrusted(peerID)
|
||||
n, err := discover.ParseNode(enode)
|
||||
if err != nil {
|
||||
info := "Failed to parse enode of trusted peer: " + err.Error()
|
||||
log.Error(info)
|
||||
return errors.New(info)
|
||||
}
|
||||
return api.whisper.AllowP2PMessagesFromPeer(n.ID[:])
|
||||
}
|
||||
|
||||
// RequestHistoricMessages requests the peer to deliver the old (expired) messages.
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ const (
|
|||
keyIdSize = 32
|
||||
|
||||
DefaultMaxMessageLength = 1024 * 1024
|
||||
DefaultMinimumPoW = 10.0 // todo: review after testing.
|
||||
DefaultMinimumPoW = 2.0 // todo: review after testing.
|
||||
|
||||
padSizeLimitLower = 128 // it can not be less - we don't want to reveal the absence of signature
|
||||
padSizeLimitUpper = 256 // just an arbitrary number, could be changed without losing compatibility
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ type Whisper struct {
|
|||
// Param s should be passed if you want to implement mail server, otherwise nil.
|
||||
func New() *Whisper {
|
||||
whisper := &Whisper{
|
||||
privateKeys: make(map[string]*ecdsa.PrivateKey),
|
||||
//identities: make(map[string]*ecdsa.PrivateKey),
|
||||
privateKeys: make(map[string]*ecdsa.PrivateKey),
|
||||
symKeys: make(map[string][]byte),
|
||||
envelopes: make(map[common.Hash]*Envelope),
|
||||
expirations: make(map[uint32]*set.SetNonTS),
|
||||
|
|
@ -158,7 +157,7 @@ func (w *Whisper) getPeer(peerID []byte) (*Peer, error) {
|
|||
|
||||
// MarkPeerTrusted marks specific peer trusted, which will allow it
|
||||
// to send historic (expired) messages.
|
||||
func (w *Whisper) MarkPeerTrusted(peerID []byte) error {
|
||||
func (w *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error {
|
||||
p, err := w.getPeer(peerID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func TestWhisperBasic(t *testing.T) {
|
|||
if peer != nil {
|
||||
t.Fatal("found peer for random key.")
|
||||
}
|
||||
if err := w.MarkPeerTrusted(peerID); err == nil {
|
||||
if err := w.AllowP2PMessagesFromPeer(peerID); err == nil {
|
||||
t.Fatalf("failed MarkPeerTrusted.")
|
||||
}
|
||||
exist := w.HasSymKey("non-existing")
|
||||
|
|
|
|||
Loading…
Reference in a new issue