Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
0e4f21fc
Commit
0e4f21fc
authored
Apr 10, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
whisper: polish the Envelope a bit, prep for tests.
parent
7d8ce53e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
75 additions
and
65 deletions
+75
-65
envelope.go
whisper/envelope.go
+66
-57
main.go
whisper/main.go
+1
-1
message.go
whisper/message.go
+1
-1
message_test.go
whisper/message_test.go
+4
-4
whisper.go
whisper/whisper.go
+2
-1
whisper_test.go
whisper/whisper_test.go
+1
-1
No files found.
whisper/envelope.go
View file @
0e4f21fc
// 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,33 +27,60 @@ 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
)
d
:=
make
([]
byte
,
64
)
copy
(
d
[
:
32
],
self
.
rlpWithoutNonce
())
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
:
],
nonce
)
firstBit
:=
common
.
FirstBitSet
(
common
.
BigD
(
crypto
.
Sha3
(
d
)))
if
firstBit
>
bestBit
{
self
.
Nonce
,
bestBit
=
nonce
,
firstBit
}
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
)
copy
(
d
[
:
32
],
self
.
rlpWithoutNonce
())
binary
.
BigEndian
.
PutUint32
(
d
[
60
:
],
self
.
Nonce
)
return
common
.
FirstBitSet
(
common
.
BigD
(
crypto
.
Sha3
(
d
)))
>
0
}
// 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
{
message
:=
&
Message
{
Flags
:
data
[
0
],
}
data
=
data
[
1
:
]
...
...
@@ -65,57 +93,38 @@ func (self *Envelope) Open(key *ecdsa.PrivateKey) (msg *Message, err error) {
}
message
.
Payload
=
data
if
key
!=
nil
{
message
.
Payload
,
err
=
crypto
.
Decrypt
(
key
,
message
.
Payload
)
switch
err
{
case
nil
:
// OK
case
ecies
.
ErrInvalidPublicKey
:
// Payload isn't encrypted
return
&
message
,
err
default
:
return
nil
,
fmt
.
Errorf
(
"unable to open envelope. Decrypt failed: %v"
,
err
)
}
// Short circuit if the encryption was requested
if
key
==
nil
{
return
message
,
nil
}
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
)
then
:=
time
.
Now
()
.
Add
(
dura
)
.
UnixNano
()
for
n
:=
uint32
(
0
);
time
.
Now
()
.
UnixNano
()
<
then
;
{
for
i
:=
0
;
i
<
1024
;
i
++
{
binary
.
BigEndian
.
PutUint32
(
d
[
60
:
],
n
)
// Otherwise try to decrypt the message
message
.
Payload
,
err
=
crypto
.
Decrypt
(
key
,
message
.
Payload
)
switch
err
{
case
nil
:
return
message
,
nil
fbs
:=
common
.
FirstBitSet
(
common
.
BigD
(
crypto
.
Sha3
(
d
)))
if
fbs
>
bestBit
{
bestBit
=
fbs
self
.
Nonce
=
n
}
case
ecies
.
ErrInvalidPublicKey
:
// Payload isn't encrypted
return
message
,
err
n
++
}
default
:
return
nil
,
fmt
.
Errorf
(
"unable to open envelope, decrypt failed: %v"
,
err
)
}
}
func
(
self
*
Envelope
)
valid
()
bool
{
d
:=
make
([]
byte
,
64
)
enc
,
_
:=
rlp
.
EncodeToBytes
(
self
.
withoutNonce
())
copy
(
d
[
:
32
],
enc
)
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
}
// 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
{
...
...
whisper/main.go
View file @
0e4f21fc
...
...
@@ -69,7 +69,7 @@ func selfSend(shh *whisper.Whisper, payload []byte) error {
})
// Wrap the payload and encrypt it
msg
:=
whisper
.
NewMessage
(
payload
)
envelope
,
err
:=
msg
.
Wrap
(
whisper
.
DefaultP
ow
,
whisper
.
Options
{
envelope
,
err
:=
msg
.
Wrap
(
whisper
.
DefaultP
roofOfWork
,
whisper
.
Options
{
From
:
id
,
To
:
&
id
.
PublicKey
,
TTL
:
whisper
.
DefaultTimeToLive
,
...
...
whisper/message.go
View file @
0e4f21fc
...
...
@@ -17,7 +17,7 @@ import (
// protocol. These are wrapped into Envelopes that need not be understood by
// intermediate nodes, just forwarded.
type
Message
struct
{
Flags
byte
// First bit i
t
signature presence, rest reserved and should be random
Flags
byte
// First bit i
s
signature presence, rest reserved and should be random
Signature
[]
byte
Payload
[]
byte
Sent
int64
...
...
whisper/message_test.go
View file @
0e4f21fc
...
...
@@ -13,7 +13,7 @@ func TestMessageSimpleWrap(t *testing.T) {
payload
:=
[]
byte
(
"hello world"
)
msg
:=
NewMessage
(
payload
)
if
_
,
err
:=
msg
.
Wrap
(
DefaultP
ow
,
Options
{});
err
!=
nil
{
if
_
,
err
:=
msg
.
Wrap
(
DefaultP
roofOfWork
,
Options
{});
err
!=
nil
{
t
.
Fatalf
(
"failed to wrap message: %v"
,
err
)
}
if
msg
.
Flags
&
128
!=
0
{
...
...
@@ -36,7 +36,7 @@ func TestMessageCleartextSignRecover(t *testing.T) {
payload
:=
[]
byte
(
"hello world"
)
msg
:=
NewMessage
(
payload
)
if
_
,
err
:=
msg
.
Wrap
(
DefaultP
ow
,
Options
{
if
_
,
err
:=
msg
.
Wrap
(
DefaultP
roofOfWork
,
Options
{
From
:
key
,
});
err
!=
nil
{
t
.
Fatalf
(
"failed to sign message: %v"
,
err
)
...
...
@@ -69,7 +69,7 @@ func TestMessageAnonymousEncryptDecrypt(t *testing.T) {
payload
:=
[]
byte
(
"hello world"
)
msg
:=
NewMessage
(
payload
)
envelope
,
err
:=
msg
.
Wrap
(
DefaultP
ow
,
Options
{
envelope
,
err
:=
msg
.
Wrap
(
DefaultP
roofOfWork
,
Options
{
To
:
&
key
.
PublicKey
,
})
if
err
!=
nil
{
...
...
@@ -104,7 +104,7 @@ func TestMessageFullCrypto(t *testing.T) {
payload
:=
[]
byte
(
"hello world"
)
msg
:=
NewMessage
(
payload
)
envelope
,
err
:=
msg
.
Wrap
(
DefaultP
ow
,
Options
{
envelope
,
err
:=
msg
.
Wrap
(
DefaultP
roofOfWork
,
Options
{
From
:
fromKey
,
To
:
&
toKey
.
PublicKey
,
})
...
...
whisper/whisper.go
View file @
0e4f21fc
...
...
@@ -29,7 +29,8 @@ type MessageEvent struct {
}
const
(
DefaultTimeToLive
=
50
*
time
.
Second
DefaultTimeToLive
=
50
*
time
.
Second
DefaultProofOfWork
=
50
*
time
.
Millisecond
)
type
Whisper
struct
{
...
...
whisper/whisper_test.go
View file @
0e4f21fc
...
...
@@ -18,7 +18,7 @@ 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
.
Wrap
(
DefaultP
ow
,
Options
{
envelope
,
err
:=
msg
.
Wrap
(
DefaultP
roofOfWork
,
Options
{
TTL
:
DefaultTimeToLive
,
From
:
id
,
To
:
&
id
.
PublicKey
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment