aboutsummaryrefslogtreecommitdiffstats
path: root/whisper
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-04-16 07:14:27 +0800
committerobscuren <geffobscura@gmail.com>2015-04-16 07:28:24 +0800
commit3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a (patch)
treeb2d4a5e7fcc1da2fd5b1aa3c139ddc7594c8646c /whisper
parent97d2954e227049a089652d91e6fb0ea1c8115cc6 (diff)
parentc4678ffd77a18a9d03c888fdf242c9e5915b9f5f (diff)
downloadgo-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar
go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.gz
go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.bz2
go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.lz
go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.xz
go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.zst
go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.zip
Merge branch 'develop' into downloader-proto
Diffstat (limited to 'whisper')
-rw-r--r--whisper/envelope.go139
-rw-r--r--whisper/main.go77
-rw-r--r--whisper/message.go121
-rw-r--r--whisper/message_test.go138
-rw-r--r--whisper/messages_test.go50
-rw-r--r--whisper/whisper.go5
-rw-r--r--whisper/whisper_test.go4
7 files changed, 359 insertions, 175 deletions
diff --git a/whisper/envelope.go b/whisper/envelope.go
index 20e3e6d39..f35a40a42 100644
--- a/whisper/envelope.go
+++ b/whisper/envelope.go
@@ -1,3 +1,6 @@
+// Contains the Whisper protocol Envelope element. For formal details please see
+// the specs at https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec#envelopes.
+
package whisper
import (
@@ -12,10 +15,8 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
-const (
- DefaultPow = 50 * time.Millisecond
-)
-
+// Envelope represents a clear-text data packet to transmit through the Whisper
+// network. Its contents may or may not be encrypted and signed.
type Envelope struct {
Expiry uint32 // Whisper protocol specifies int32, really should be int64
TTL uint32 // ^^^^^^
@@ -26,96 +27,104 @@ type Envelope struct {
hash common.Hash
}
-func (self *Envelope) Hash() common.Hash {
- if (self.hash == common.Hash{}) {
- enc, _ := rlp.EncodeToBytes(self)
- self.hash = crypto.Sha3Hash(enc)
- }
- return self.hash
-}
-
-func NewEnvelope(ttl time.Duration, topics [][]byte, data *Message) *Envelope {
- exp := time.Now().Add(ttl)
+// NewEnvelope wraps a Whisper message with expiration and destination data
+// included into an envelope for network forwarding.
+func NewEnvelope(ttl time.Duration, topics [][]byte, msg *Message) *Envelope {
return &Envelope{
- Expiry: uint32(exp.Unix()),
+ Expiry: uint32(time.Now().Add(ttl).Unix()),
TTL: uint32(ttl.Seconds()),
Topics: topics,
- Data: data.Bytes(),
+ Data: msg.bytes(),
Nonce: 0,
}
}
+// Seal closes the envelope by spending the requested amount of time as a proof
+// of work on hashing the data.
func (self *Envelope) Seal(pow time.Duration) {
- self.proveWork(pow)
-}
-
-func (self *Envelope) Open(prv *ecdsa.PrivateKey) (msg *Message, err error) {
- data := self.Data
- var message Message
- dataStart := 1
- if data[0] > 0 {
- if len(data) < 66 {
- return nil, fmt.Errorf("unable to open envelope. First bit set but len(data) < 66")
- }
- dataStart = 66
- message.Flags = data[0]
- message.Signature = data[1:66]
- }
-
- payload := data[dataStart:]
- if prv != nil {
- message.Payload, err = crypto.Decrypt(prv, payload)
- switch err {
- case nil: // OK
- 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)
- }
- }
-
- return &message, nil
-}
-
-func (self *Envelope) proveWork(dura time.Duration) {
- var bestBit int
d := make([]byte, 64)
- enc, _ := rlp.EncodeToBytes(self.withoutNonce())
- copy(d[:32], enc)
+ copy(d[:32], self.rlpWithoutNonce())
- then := time.Now().Add(dura).UnixNano()
- for n := uint32(0); time.Now().UnixNano() < then; {
+ finish, bestBit := time.Now().Add(pow).UnixNano(), 0
+ for nonce := uint32(0); time.Now().UnixNano() < finish; {
for i := 0; i < 1024; i++ {
- binary.BigEndian.PutUint32(d[60:], n)
+ binary.BigEndian.PutUint32(d[60:], nonce)
- fbs := common.FirstBitSet(common.BigD(crypto.Sha3(d)))
- if fbs > bestBit {
- bestBit = fbs
- self.Nonce = n
+ firstBit := common.FirstBitSet(common.BigD(crypto.Sha3(d)))
+ if firstBit > bestBit {
+ self.Nonce, bestBit = nonce, firstBit
}
-
- n++
+ nonce++
}
}
}
+// valid checks whether the claimed proof of work was indeed executed.
+// TODO: Is this really useful? Isn't this always true?
func (self *Envelope) valid() bool {
d := make([]byte, 64)
- enc, _ := rlp.EncodeToBytes(self.withoutNonce())
- copy(d[:32], enc)
+ copy(d[:32], self.rlpWithoutNonce())
binary.BigEndian.PutUint32(d[60:], self.Nonce)
+
return common.FirstBitSet(common.BigD(crypto.Sha3(d))) > 0
}
-func (self *Envelope) withoutNonce() interface{} {
- return []interface{}{self.Expiry, self.TTL, self.Topics, self.Data}
+// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce.
+func (self *Envelope) rlpWithoutNonce() []byte {
+ enc, _ := rlp.EncodeToBytes([]interface{}{self.Expiry, self.TTL, self.Topics, self.Data})
+ return enc
+}
+
+// Open extracts the message contained within a potentially encrypted envelope.
+func (self *Envelope) Open(key *ecdsa.PrivateKey) (msg *Message, err error) {
+ // Split open the payload into a message construct
+ data := self.Data
+
+ message := &Message{
+ Flags: data[0],
+ }
+ data = data[1:]
+
+ if message.Flags&128 == 128 {
+ if len(data) < 65 {
+ return nil, fmt.Errorf("unable to open envelope. First bit set but len(data) < 65")
+ }
+ message.Signature, data = data[:65], data[65:]
+ }
+ message.Payload = data
+
+ // Short circuit if the encryption was requested
+ if key == nil {
+ return message, nil
+ }
+ // Otherwise try to decrypt the message
+ message.Payload, err = crypto.Decrypt(key, message.Payload)
+ switch err {
+ case nil:
+ return message, nil
+
+ case ecies.ErrInvalidPublicKey: // Payload isn't encrypted
+ return message, err
+
+ default:
+ return nil, fmt.Errorf("unable to open envelope, decrypt failed: %v", err)
+ }
+}
+
+// Hash returns the SHA3 hash of the envelope, calculating it if not yet done.
+func (self *Envelope) Hash() common.Hash {
+ if (self.hash == common.Hash{}) {
+ enc, _ := rlp.EncodeToBytes(self)
+ self.hash = crypto.Sha3Hash(enc)
+ }
+ return self.hash
}
// rlpenv is an Envelope but is not an rlp.Decoder.
// It is used for decoding because we need to
type rlpenv Envelope
+// DecodeRLP decodes an Envelope from an RLP data stream.
func (self *Envelope) DecodeRLP(s *rlp.Stream) error {
raw, err := s.Raw()
if err != nil {
diff --git a/whisper/main.go b/whisper/main.go
index 9f35dbb8d..422f0fa3b 100644
--- a/whisper/main.go
+++ b/whisper/main.go
@@ -1,37 +1,90 @@
// +build none
+// Contains a simple whisper peer setup and self messaging to allow playing
+// around with the protocol and API without a fancy client implementation.
+
package main
import (
"fmt"
"log"
"os"
+ "time"
- "github.com/ethereum/go-ethereum/crypto/secp256k1"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/whisper"
)
func main() {
logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel))
- pub, _ := secp256k1.GenerateKeyPair()
-
- whisper := whisper.New()
+ // Generate the peer identity
+ key, err := crypto.GenerateKey()
+ if err != nil {
+ fmt.Printf("Failed to generate peer key: %v.\n", err)
+ os.Exit(-1)
+ }
+ name := common.MakeName("whisper-go", "1.0")
+ shh := whisper.New()
- srv := p2p.Server{
+ // Create an Ethereum peer to communicate through
+ server := p2p.Server{
+ PrivateKey: key,
MaxPeers: 10,
- Identity: p2p.NewSimpleClientIdentity("whisper-go", "1.0", "", string(pub)),
+ Name: name,
+ Protocols: []p2p.Protocol{shh.Protocol()},
ListenAddr: ":30300",
- NAT: p2p.UPNP(),
-
- Protocols: []p2p.Protocol{whisper.Protocol()},
+ NAT: nat.Any(),
}
- if err := srv.Start(); err != nil {
- fmt.Println("could not start server:", err)
+ fmt.Println("Starting Ethereum peer...")
+ if err := server.Start(); err != nil {
+ fmt.Printf("Failed to start Ethereum peer: %v.\n", err)
os.Exit(1)
}
- select {}
+ // Send a message to self to check that something works
+ payload := fmt.Sprintf("Hello world, this is %v. In case you're wondering, the time is %v", name, time.Now())
+ if err := selfSend(shh, []byte(payload)); err != nil {
+ fmt.Printf("Failed to self message: %v.\n", err)
+ os.Exit(-1)
+ }
+}
+
+// SendSelf wraps a payload into a Whisper envelope and forwards it to itself.
+func selfSend(shh *whisper.Whisper, payload []byte) error {
+ ok := make(chan struct{})
+
+ // Start watching for self messages, output any arrivals
+ id := shh.NewIdentity()
+ shh.Watch(whisper.Filter{
+ To: &id.PublicKey,
+ Fn: func(msg *whisper.Message) {
+ fmt.Printf("Message received: %s, signed with 0x%x.\n", string(msg.Payload), msg.Signature)
+ close(ok)
+ },
+ })
+ // Wrap the payload and encrypt it
+ msg := whisper.NewMessage(payload)
+ envelope, err := msg.Wrap(whisper.DefaultProofOfWork, whisper.Options{
+ From: id,
+ To: &id.PublicKey,
+ TTL: whisper.DefaultTimeToLive,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to seal message: %v", err)
+ }
+ // Dump the message into the system and wait for it to pop back out
+ if err := shh.Send(envelope); err != nil {
+ return fmt.Errorf("failed to send self-message: %v", err)
+ }
+ select {
+ case <-ok:
+ case <-time.After(time.Second):
+ return fmt.Errorf("failed to receive message in time")
+ }
+ return nil
}
diff --git a/whisper/message.go b/whisper/message.go
index ad6a1bcff..2666ee6e0 100644
--- a/whisper/message.go
+++ b/whisper/message.go
@@ -1,7 +1,11 @@
+// Contains the Whisper protocol Message element. For formal details please see
+// the specs at https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec#messages.
+
package whisper
import (
"crypto/ecdsa"
+ "math/rand"
"time"
"github.com/ethereum/go-ethereum/crypto"
@@ -9,8 +13,11 @@ import (
"github.com/ethereum/go-ethereum/logger/glog"
)
+// Message represents an end-user data packet to trasmit through the Whisper
+// protocol. These are wrapped into Envelopes that need not be understood by
+// intermediate nodes, just forwarded.
type Message struct {
- Flags byte
+ Flags byte // First bit is signature presence, rest reserved and should be random
Signature []byte
Payload []byte
Sent int64
@@ -18,71 +25,95 @@ type Message struct {
To *ecdsa.PublicKey
}
+// Options specifies the exact way a message should be wrapped into an Envelope.
+type Options struct {
+ From *ecdsa.PrivateKey
+ To *ecdsa.PublicKey
+ TTL time.Duration
+ Topics [][]byte
+}
+
+// NewMessage creates and initializes a non-signed, non-encrypted Whisper message.
func NewMessage(payload []byte) *Message {
- return &Message{Flags: 0, Payload: payload, Sent: time.Now().Unix()}
+ // Construct an initial flag set: bit #1 = 0 (no signature), rest random
+ flags := byte(rand.Intn(128))
+
+ // Assemble and return the message
+ return &Message{
+ Flags: flags,
+ Payload: payload,
+ Sent: time.Now().Unix(),
+ }
}
-func (self *Message) hash() []byte {
- return crypto.Sha3(append([]byte{self.Flags}, self.Payload...))
+// Wrap bundles the message into an Envelope to transmit over the network.
+//
+// pow (Proof Of Work) controls how much time to spend on hashing the message,
+// inherently controlling its priority through the network (smaller hash, bigger
+// priority).
+//
+// The user can control the amount of identity, privacy and encryption through
+// the options parameter as follows:
+// - options.From == nil && options.To == nil: anonymous broadcast
+// - options.From != nil && options.To == nil: signed broadcast (known sender)
+// - options.From == nil && options.To != nil: encrypted anonymous message
+// - options.From != nil && options.To != nil: encrypted signed message
+func (self *Message) Wrap(pow time.Duration, options Options) (*Envelope, error) {
+ // Use the default TTL if non was specified
+ if options.TTL == 0 {
+ options.TTL = DefaultTimeToLive
+ }
+ // Sign and encrypt the message if requested
+ if options.From != nil {
+ if err := self.sign(options.From); err != nil {
+ return nil, err
+ }
+ }
+ if options.To != nil {
+ if err := self.encrypt(options.To); err != nil {
+ return nil, err
+ }
+ }
+ // Wrap the processed message, seal it and return
+ envelope := NewEnvelope(options.TTL, options.Topics, self)
+ envelope.Seal(pow)
+
+ return envelope, nil
}
+// sign calculates and sets the cryptographic signature for the message , also
+// setting the sign flag.
func (self *Message) sign(key *ecdsa.PrivateKey) (err error) {
- self.Flags = 1
+ self.Flags |= 1 << 7
self.Signature, err = crypto.Sign(self.hash(), key)
return
}
+// Recover retrieves the public key of the message signer.
func (self *Message) Recover() *ecdsa.PublicKey {
- defer func() { recover() }() // in case of invalid sig
+ defer func() { recover() }() // in case of invalid signature
+
pub, err := crypto.SigToPub(self.hash(), self.Signature)
if err != nil {
- glog.V(logger.Error).Infof("Could not get pubkey from signature: ", err)
+ glog.V(logger.Error).Infof("Could not get public key from signature: %v", err)
return nil
}
return pub
}
-func (self *Message) Encrypt(to *ecdsa.PublicKey) (err error) {
+// encrypt encrypts a message payload with a public key.
+func (self *Message) encrypt(to *ecdsa.PublicKey) (err error) {
self.Payload, err = crypto.Encrypt(to, self.Payload)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (self *Message) Bytes() []byte {
- return append([]byte{self.Flags}, append(self.Signature, self.Payload...)...)
+ return
}
-type Opts struct {
- From *ecdsa.PrivateKey
- To *ecdsa.PublicKey
- Ttl time.Duration
- Topics [][]byte
+// hash calculates the SHA3 checksum of the message flags and payload.
+func (self *Message) hash() []byte {
+ return crypto.Sha3(append([]byte{self.Flags}, self.Payload...))
}
-func (self *Message) Seal(pow time.Duration, opts Opts) (*Envelope, error) {
- if opts.From != nil {
- err := self.sign(opts.From)
- if err != nil {
- return nil, err
- }
- }
-
- if opts.To != nil {
- err := self.Encrypt(opts.To)
- if err != nil {
- return nil, err
- }
- }
-
- if opts.Ttl == 0 {
- opts.Ttl = DefaultTtl
- }
-
- envelope := NewEnvelope(opts.Ttl, opts.Topics, self)
- envelope.Seal(pow)
-
- return envelope, nil
+// bytes flattens the message contents (flags, signature and payload) into a
+// single binary blob.
+func (self *Message) bytes() []byte {
+ return append([]byte{self.Flags}, append(self.Signature, self.Payload...)...)
}
diff --git a/whisper/message_test.go b/whisper/message_test.go
new file mode 100644
index 000000000..8d4c5e990
--- /dev/null
+++ b/whisper/message_test.go
@@ -0,0 +1,138 @@
+package whisper
+
+import (
+ "bytes"
+ "crypto/elliptic"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+// Tests whether a message can be wrapped without any identity or encryption.
+func TestMessageSimpleWrap(t *testing.T) {
+ payload := []byte("hello world")
+
+ msg := NewMessage(payload)
+ if _, err := msg.Wrap(DefaultProofOfWork, Options{}); err != nil {
+ t.Fatalf("failed to wrap message: %v", err)
+ }
+ if msg.Flags&128 != 0 {
+ t.Fatalf("signature flag mismatch: have %d, want %d", (msg.Flags&128)>>7, 0)
+ }
+ if len(msg.Signature) != 0 {
+ t.Fatalf("signature found for simple wrapping: 0x%x", msg.Signature)
+ }
+ if bytes.Compare(msg.Payload, payload) != 0 {
+ t.Fatalf("payload mismatch after wrapping: have 0x%x, want 0x%x", msg.Payload, payload)
+ }
+}
+
+// Tests whether a message can be signed, and wrapped in plain-text.
+func TestMessageCleartextSignRecover(t *testing.T) {
+ key, err := crypto.GenerateKey()
+ if err != nil {
+ t.Fatalf("failed to create crypto key: %v", err)
+ }
+ payload := []byte("hello world")
+
+ msg := NewMessage(payload)
+ if _, err := msg.Wrap(DefaultProofOfWork, Options{
+ From: key,
+ }); err != nil {
+ t.Fatalf("failed to sign message: %v", err)
+ }
+ if msg.Flags&128 != 128 {
+ t.Fatalf("signature flag mismatch: have %d, want %d", (msg.Flags&128)>>7, 1)
+ }
+ if bytes.Compare(msg.Payload, payload) != 0 {
+ t.Fatalf("payload mismatch after signing: have 0x%x, want 0x%x", msg.Payload, payload)
+ }
+
+ pubKey := msg.Recover()
+ if pubKey == nil {
+ t.Fatalf("failed to recover public key")
+ }
+ p1 := elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y)
+ p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
+ if !bytes.Equal(p1, p2) {
+ t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1)
+ }
+}
+
+// Tests whether a message can be encrypted and decrypted using an anonymous
+// sender (i.e. no signature).
+func TestMessageAnonymousEncryptDecrypt(t *testing.T) {
+ key, err := crypto.GenerateKey()
+ if err != nil {
+ t.Fatalf("failed to create recipient crypto key: %v", err)
+ }
+ payload := []byte("hello world")
+
+ msg := NewMessage(payload)
+ envelope, err := msg.Wrap(DefaultProofOfWork, Options{
+ To: &key.PublicKey,
+ })
+ if err != nil {
+ t.Fatalf("failed to encrypt message: %v", err)
+ }
+ if msg.Flags&128 != 0 {
+ t.Fatalf("signature flag mismatch: have %d, want %d", (msg.Flags&128)>>7, 0)
+ }
+ if len(msg.Signature) != 0 {
+ t.Fatalf("signature found for anonymous message: 0x%x", msg.Signature)
+ }
+
+ out, err := envelope.Open(key)
+ if err != nil {
+ t.Fatalf("failed to open encrypted message: %v", err)
+ }
+ if !bytes.Equal(out.Payload, payload) {
+ t.Error("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload)
+ }
+}
+
+// Tests whether a message can be properly signed and encrypted.
+func TestMessageFullCrypto(t *testing.T) {
+ fromKey, err := crypto.GenerateKey()
+ if err != nil {
+ t.Fatalf("failed to create sender crypto key: %v", err)
+ }
+ toKey, err := crypto.GenerateKey()
+ if err != nil {
+ t.Fatalf("failed to create recipient crypto key: %v", err)
+ }
+
+ payload := []byte("hello world")
+ msg := NewMessage(payload)
+ envelope, err := msg.Wrap(DefaultProofOfWork, Options{
+ From: fromKey,
+ To: &toKey.PublicKey,
+ })
+ if err != nil {
+ t.Fatalf("failed to encrypt message: %v", err)
+ }
+ if msg.Flags&128 != 128 {
+ t.Fatalf("signature flag mismatch: have %d, want %d", (msg.Flags&128)>>7, 1)
+ }
+ if len(msg.Signature) == 0 {
+ t.Fatalf("no signature found for signed message")
+ }
+
+ out, err := envelope.Open(toKey)
+ if err != nil {
+ t.Fatalf("failed to open encrypted message: %v", err)
+ }
+ if !bytes.Equal(out.Payload, payload) {
+ t.Error("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload)
+ }
+
+ pubKey := out.Recover()
+ if pubKey == nil {
+ t.Fatalf("failed to recover public key")
+ }
+ p1 := elliptic.Marshal(crypto.S256(), fromKey.PublicKey.X, fromKey.PublicKey.Y)
+ p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
+ if !bytes.Equal(p1, p2) {
+ t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1)
+ }
+}
diff --git a/whisper/messages_test.go b/whisper/messages_test.go
deleted file mode 100644
index 93caa31b3..000000000
--- a/whisper/messages_test.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package whisper
-
-import (
- "bytes"
- "crypto/elliptic"
- "fmt"
- "testing"
-
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-func TestSign(t *testing.T) {
- prv, _ := crypto.GenerateKey()
- msg := NewMessage([]byte("hello world"))
- msg.sign(prv)
-
- pubKey := msg.Recover()
- p1 := elliptic.Marshal(crypto.S256(), prv.PublicKey.X, prv.PublicKey.Y)
- p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
-
- if !bytes.Equal(p1, p2) {
- t.Error("recovered pub key did not match")
- }
-}
-
-func TestMessageEncryptDecrypt(t *testing.T) {
- prv1, _ := crypto.GenerateKey()
- prv2, _ := crypto.GenerateKey()
-
- data := []byte("hello world")
- msg := NewMessage(data)
- envelope, err := msg.Seal(DefaultPow, Opts{
- From: prv1,
- To: &prv2.PublicKey,
- })
- if err != nil {
- fmt.Println(err)
- t.FailNow()
- }
-
- msg1, err := envelope.Open(prv2)
- if err != nil {
- t.Error(err)
- t.FailNow()
- }
-
- if !bytes.Equal(msg1.Payload, data) {
- t.Error("encryption error. data did not match")
- }
-}
diff --git a/whisper/whisper.go b/whisper/whisper.go
index 00dcb1932..d803e27d4 100644
--- a/whisper/whisper.go
+++ b/whisper/whisper.go
@@ -28,7 +28,10 @@ type MessageEvent struct {
Message *Message
}
-const DefaultTtl = 50 * time.Second
+const (
+ DefaultTimeToLive = 50 * time.Second
+ DefaultProofOfWork = 50 * time.Millisecond
+)
type Whisper struct {
protocol p2p.Protocol
diff --git a/whisper/whisper_test.go b/whisper/whisper_test.go
index 3e3945a0a..b29e34a5e 100644
--- a/whisper/whisper_test.go
+++ b/whisper/whisper_test.go
@@ -18,8 +18,8 @@ func TestEvent(t *testing.T) {
})
msg := NewMessage([]byte(fmt.Sprintf("Hello world. This is whisper-go. Incase you're wondering; the time is %v", time.Now())))
- envelope, err := msg.Seal(DefaultPow, Opts{
- Ttl: DefaultTtl,
+ envelope, err := msg.Wrap(DefaultProofOfWork, Options{
+ TTL: DefaultTimeToLive,
From: id,
To: &id.PublicKey,
})