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
06697775
Commit
06697775
authored
Mar 21, 2015
by
obscuren
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'conversion' of github.com-obscure:ethereum/go-ethereum into conversion
parents
abce6804
069c87b9
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
201 additions
and
355 deletions
+201
-355
main.go
cmd/blocktest/main.go
+0
-213
rlp.go
common/rlp.go
+1
-1
rlp_test.go
common/rlp_test.go
+16
-12
value.go
common/value.go
+40
-29
value_test.go
common/value_test.go
+1
-1
keypair.go
crypto/keypair.go
+1
-9
backend.go
eth/backend.go
+1
-1
memory_database.go
ethdb/memory_database.go
+1
-1
decode.go
rlp/decode.go
+31
-1
decode_test.go
rlp/decode_test.go
+35
-1
encode.go
rlp/encode.go
+19
-11
envelope.go
whisper/envelope.go
+26
-31
peer.go
whisper/peer.go
+9
-12
sort.go
whisper/sort.go
+6
-2
sort_test.go
whisper/sort_test.go
+10
-6
whisper.go
whisper/whisper.go
+4
-24
No files found.
cmd/blocktest/main.go
deleted
100644 → 0
View file @
abce6804
/*
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 Lesser 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 Lesser General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @authors
* Gustav Simonsson <gustav.simonsson@gmail.com>
* @date 2015
*
*/
package
main
import
(
"bytes"
"encoding/hex"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"math/big"
"os"
"runtime"
"strings"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/core"
types
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/rlp"
)
type
Account
struct
{
Balance
string
Code
string
Nonce
string
Storage
map
[
string
]
string
}
type
BlockHeader
struct
{
Bloom
string
Coinbase
string
Difficulty
string
ExtraData
string
GasLimit
string
GasUsed
string
MixHash
string
Nonce
string
Number
string
ParentHash
string
ReceiptTrie
string
SeedHash
string
StateRoot
string
Timestamp
string
TransactionsTrie
string
UncleHash
string
}
type
Tx
struct
{
Data
string
GasLimit
string
GasPrice
string
Nonce
string
R
string
S
string
To
string
V
string
Value
string
}
type
Block
struct
{
BlockHeader
BlockHeader
Rlp
string
Transactions
[]
Tx
UncleHeaders
[]
string
}
type
Test
struct
{
Blocks
[]
Block
GenesisBlockHeader
BlockHeader
Pre
map
[
string
]
Account
}
func
main
()
{
flag
.
Usage
=
func
()
{
fmt
.
Fprintf
(
os
.
Stderr
,
"%s <testfile>
\n
"
,
os
.
Args
[
0
])
flag
.
PrintDefaults
()
}
flag
.
Parse
()
runtime
.
GOMAXPROCS
(
runtime
.
NumCPU
())
logger
.
AddLogSystem
(
logger
.
NewStdLogSystem
(
os
.
Stderr
,
log
.
LstdFlags
,
logger
.
DebugDetailLevel
))
defer
func
()
{
logger
.
Flush
()
}()
if
len
(
os
.
Args
)
<
2
{
utils
.
Fatalf
(
"Please specify a test file as the first argument."
)
}
blocks
,
err
:=
loadBlocksFromTestFile
(
os
.
Args
[
1
])
if
err
!=
nil
{
utils
.
Fatalf
(
"Could not load blocks: %v"
,
err
)
}
chain
:=
memchain
()
chain
.
ResetWithGenesisBlock
(
blocks
[
0
])
if
err
=
chain
.
InsertChain
(
types
.
Blocks
{
blocks
[
1
]});
err
!=
nil
{
utils
.
Fatalf
(
"Error: %v"
,
err
)
}
else
{
fmt
.
Println
(
"PASS"
)
}
}
func
memchain
()
*
core
.
ChainManager
{
blockdb
,
err
:=
ethdb
.
NewMemDatabase
()
if
err
!=
nil
{
utils
.
Fatalf
(
"Could not create in-memory database: %v"
,
err
)
}
statedb
,
err
:=
ethdb
.
NewMemDatabase
()
if
err
!=
nil
{
utils
.
Fatalf
(
"Could not create in-memory database: %v"
,
err
)
}
return
core
.
NewChainManager
(
blockdb
,
statedb
,
new
(
event
.
TypeMux
))
}
func
loadBlocksFromTestFile
(
filePath
string
)
(
blocks
types
.
Blocks
,
err
error
)
{
fileContent
,
err
:=
ioutil
.
ReadFile
(
filePath
)
if
err
!=
nil
{
return
}
bt
:=
make
(
map
[
string
]
Test
)
if
err
=
json
.
Unmarshal
(
fileContent
,
&
bt
);
err
!=
nil
{
return
}
// TODO: support multiple blocks; loop over all blocks
gbh
:=
new
(
types
.
Header
)
// Let's use slighlty different namings for the same things, because that's awesome.
gbh
.
ParentHash
,
err
=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
ParentHash
)
gbh
.
UncleHash
,
err
=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
UncleHash
)
gbh
.
Coinbase
,
err
=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
Coinbase
)
gbh
.
Root
,
err
=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
StateRoot
)
gbh
.
TxHash
,
err
=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
TransactionsTrie
)
gbh
.
ReceiptHash
,
err
=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
ReceiptTrie
)
gbh
.
Bloom
,
err
=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
Bloom
)
gbh
.
MixDigest
,
err
=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
MixHash
)
//gbh.SeedHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.SeedHash)
d
,
_
:=
new
(
big
.
Int
)
.
SetString
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
Difficulty
,
10
)
gbh
.
Difficulty
=
d
n
,
_
:=
new
(
big
.
Int
)
.
SetString
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
Number
,
10
)
gbh
.
Number
=
n
gl
,
_
:=
new
(
big
.
Int
)
.
SetString
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
GasLimit
,
10
)
gbh
.
GasLimit
=
gl
gu
,
_
:=
new
(
big
.
Int
)
.
SetString
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
GasUsed
,
10
)
gbh
.
GasUsed
=
gu
ts
,
_
:=
new
(
big
.
Int
)
.
SetString
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
Timestamp
,
0
)
gbh
.
Time
=
ts
.
Uint64
()
extra
,
err
:=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
ExtraData
)
gbh
.
Extra
=
string
(
extra
)
// TODO: change ExtraData to byte array
nonce
,
_
:=
hex_decode
(
bt
[
"SimpleTx"
]
.
GenesisBlockHeader
.
Nonce
)
gbh
.
Nonce
=
nonce
if
err
!=
nil
{
return
}
gb
:=
types
.
NewBlockWithHeader
(
gbh
)
//gb.uncles = *new([]*types.Header)
//gb.transactions = *new(types.Transactions)
gb
.
Td
=
new
(
big
.
Int
)
gb
.
Reward
=
new
(
big
.
Int
)
testBlock
:=
new
(
types
.
Block
)
rlpBytes
,
err
:=
hex_decode
(
bt
[
"SimpleTx"
]
.
Blocks
[
0
]
.
Rlp
)
err
=
rlp
.
Decode
(
bytes
.
NewReader
(
rlpBytes
),
&
testBlock
)
if
err
!=
nil
{
return
}
blocks
=
types
.
Blocks
{
gb
,
testBlock
,
}
return
}
func
hex_decode
(
s
string
)
(
res
[]
byte
,
err
error
)
{
return
hex
.
DecodeString
(
strings
.
TrimPrefix
(
s
,
"0x"
))
}
common/rlp.go
View file @
06697775
...
...
@@ -112,7 +112,7 @@ func Encode(object interface{}) []byte {
if
object
!=
nil
{
switch
t
:=
object
.
(
type
)
{
case
*
Value
:
buff
.
Write
(
Encode
(
t
.
Raw
()
))
buff
.
Write
(
Encode
(
t
.
Val
))
case
RlpEncodable
:
buff
.
Write
(
Encode
(
t
.
RlpData
()))
// Code dup :-/
...
...
common/rlp_test.go
View file @
06697775
...
...
@@ -5,6 +5,8 @@ import (
"math/big"
"reflect"
"testing"
"github.com/ethereum/go-ethereum/rlp"
)
func
TestNonInterfaceSlice
(
t
*
testing
.
T
)
{
...
...
@@ -19,13 +21,16 @@ func TestNonInterfaceSlice(t *testing.T) {
func
TestRlpValueEncoding
(
t
*
testing
.
T
)
{
val
:=
EmptyValue
()
val
.
AppendList
()
.
Append
(
1
)
.
Append
(
2
)
.
Append
(
3
)
val
.
Append
(
"4"
)
.
AppendList
()
.
Append
(
5
)
val
.
AppendList
()
.
Append
(
byte
(
1
))
.
Append
(
byte
(
2
))
.
Append
(
byte
(
3
)
)
val
.
Append
(
"4"
)
.
AppendList
()
.
Append
(
byte
(
5
)
)
res
:=
val
.
Encode
()
res
,
err
:=
rlp
.
EncodeToBytes
(
val
)
if
err
!=
nil
{
t
.
Fatalf
(
"encode error: %v"
,
err
)
}
exp
:=
Encode
([]
interface
{}{[]
interface
{}{
1
,
2
,
3
},
"4"
,
[]
interface
{}{
5
}})
if
bytes
.
Compare
(
res
,
exp
)
!=
0
{
t
.
Errorf
(
"expected %
q, got %q"
,
res
,
exp
)
t
.
Errorf
(
"expected %
x, got %x"
,
exp
,
res
)
}
}
...
...
@@ -57,9 +62,7 @@ func TestValueSlice(t *testing.T) {
func
TestLargeData
(
t
*
testing
.
T
)
{
data
:=
make
([]
byte
,
100000
)
enc
:=
Encode
(
data
)
value
:=
NewValue
(
enc
)
value
.
Decode
()
value
:=
NewValueFromBytes
(
enc
)
if
value
.
Len
()
!=
len
(
data
)
{
t
.
Error
(
"Expected data to be"
,
len
(
data
),
"got"
,
value
.
Len
())
}
...
...
@@ -133,15 +136,16 @@ func TestEncodeDecodeBigInt(t *testing.T) {
}
func
TestEncodeDecodeBytes
(
t
*
testing
.
T
)
{
b
:=
NewValue
([]
interface
{}{[]
byte
{
1
,
2
,
3
,
4
,
5
},
byte
(
6
)})
val
:=
NewValueFromBytes
(
b
.
Encode
())
if
!
b
.
Cmp
(
val
)
{
t
.
Errorf
(
"Expected %v, got %v"
,
val
,
b
)
bv
:=
NewValue
([]
interface
{}{[]
byte
{
1
,
2
,
3
,
4
,
5
},
[]
byte
{
6
}})
b
,
_
:=
rlp
.
EncodeToBytes
(
bv
)
val
:=
NewValueFromBytes
(
b
)
if
!
bv
.
Cmp
(
val
)
{
t
.
Errorf
(
"Expected %#v, got %#v"
,
bv
,
val
)
}
}
func
TestEncodeZero
(
t
*
testing
.
T
)
{
b
:=
NewValue
(
0
)
.
Encode
(
)
b
,
_
:=
rlp
.
EncodeToBytes
(
NewValue
(
0
)
)
exp
:=
[]
byte
{
0xc0
}
if
bytes
.
Compare
(
b
,
exp
)
==
0
{
t
.
Error
(
"Expected"
,
exp
,
"got"
,
b
)
...
...
common/value.go
View file @
06697775
...
...
@@ -3,18 +3,30 @@ package common
import
(
"bytes"
"fmt"
"io"
"math/big"
"reflect"
"strconv"
"github.com/ethereum/go-ethereum/rlp"
)
// Data values are returned by the rlp decoder. The data values represents
// one item within the rlp data structure. It's responsible for all the casting
// It always returns something valid
type
Value
struct
{
Val
interface
{}
kind
reflect
.
Value
}
// Value can hold values of certain basic types and provides ways to
// convert between types without bothering to check whether the
// conversion is actually meaningful.
//
// It currently supports the following types:
//
// - int{,8,16,32,64}
// - uint{,8,16,32,64}
// - *big.Int
// - []byte, string
// - []interface{}
//
// Value is useful whenever you feel that Go's types limit your
// ability to express yourself. In these situations, use Value and
// forget about this strong typing nonsense.
type
Value
struct
{
Val
interface
{}
}
func
(
val
*
Value
)
String
()
string
{
return
fmt
.
Sprintf
(
"%x"
,
val
.
Val
)
...
...
@@ -38,7 +50,6 @@ func (val *Value) IsNil() bool {
}
func
(
val
*
Value
)
Len
()
int
{
//return val.kind.Len()
if
data
,
ok
:=
val
.
Val
.
([]
interface
{});
ok
{
return
len
(
data
)
}
...
...
@@ -46,14 +57,6 @@ func (val *Value) Len() int {
return
len
(
val
.
Bytes
())
}
func
(
val
*
Value
)
Raw
()
interface
{}
{
return
val
.
Val
}
func
(
val
*
Value
)
Interface
()
interface
{}
{
return
val
.
Val
}
func
(
val
*
Value
)
Uint
()
uint64
{
if
Val
,
ok
:=
val
.
Val
.
(
uint8
);
ok
{
return
uint64
(
Val
)
...
...
@@ -260,26 +263,34 @@ func (self *Value) DeepCmp(o *Value) bool {
return
bytes
.
Compare
(
self
.
Bytes
(),
o
.
Bytes
())
==
0
}
func
(
val
*
Value
)
Encode
()
[]
byte
{
return
Encode
(
val
.
Val
)
func
(
self
*
Value
)
DecodeRLP
(
s
*
rlp
.
Stream
)
error
{
var
v
interface
{}
if
err
:=
s
.
Decode
(
&
v
);
err
!=
nil
{
return
err
}
self
.
Val
=
v
return
nil
}
// Assume that the data we have is encoded
func
(
self
*
Value
)
Decode
()
{
v
,
_
:=
Decode
(
self
.
Bytes
(),
0
)
self
.
Val
=
v
//self.Val = DecodeWithReader(bytes.NewBuffer(self.Bytes()))
func
(
self
*
Value
)
EncodeRLP
(
w
io
.
Writer
)
error
{
if
self
==
nil
{
w
.
Write
(
rlp
.
EmptyList
)
return
nil
}
else
{
return
rlp
.
Encode
(
w
,
self
.
Val
)
}
}
// NewValueFromBytes decodes RLP data.
// The contained value will be nil if data contains invalid RLP.
func
NewValueFromBytes
(
data
[]
byte
)
*
Value
{
v
:=
new
(
Value
)
if
len
(
data
)
!=
0
{
value
:=
NewValue
(
data
)
value
.
Decode
()
return
value
if
err
:=
rlp
.
DecodeBytes
(
data
,
v
);
err
!=
nil
{
v
.
Val
=
nil
}
}
return
NewValue
(
nil
)
return
v
}
// Value setters
...
...
common/value_test.go
View file @
06697775
...
...
@@ -35,7 +35,7 @@ func (s *ValueSuite) TestValueTypes(c *checker.C) {
c
.
Assert
(
str
.
Str
(),
checker
.
Equals
,
strExp
)
c
.
Assert
(
num
.
Uint
(),
checker
.
Equals
,
numExp
)
c
.
Assert
(
NewValue
(
inter
.
Interface
()
)
.
Cmp
(
NewValue
(
interExp
)),
checker
.
Equals
,
true
)
c
.
Assert
(
NewValue
(
inter
.
Val
)
.
Cmp
(
NewValue
(
interExp
)),
checker
.
Equals
,
true
)
c
.
Assert
(
byt
.
Bytes
(),
checker
.
DeepEquals
,
bytExp
)
c
.
Assert
(
bigInt
.
BigInt
(),
checker
.
DeepEquals
,
bigExp
)
}
...
...
crypto/keypair.go
View file @
06697775
...
...
@@ -3,8 +3,8 @@ package crypto
import
(
"strings"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
)
type
KeyPair
struct
{
...
...
@@ -48,11 +48,3 @@ func (k *KeyPair) Mnemonic() string {
func
(
k
*
KeyPair
)
AsStrings
()
(
string
,
string
,
string
,
string
)
{
return
k
.
Mnemonic
(),
common
.
Bytes2Hex
(
k
.
Address
()),
common
.
Bytes2Hex
(
k
.
PrivateKey
),
common
.
Bytes2Hex
(
k
.
PublicKey
)
}
func
(
k
*
KeyPair
)
RlpEncode
()
[]
byte
{
return
k
.
RlpValue
()
.
Encode
()
}
func
(
k
*
KeyPair
)
RlpValue
()
*
common
.
Value
{
return
common
.
NewValue
(
k
.
PrivateKey
)
}
eth/backend.go
View file @
06697775
...
...
@@ -206,7 +206,7 @@ func New(config *Config) (*Ethereum, error) {
ethProto
:=
EthProtocol
(
config
.
ProtocolVersion
,
config
.
NetworkId
,
eth
.
txPool
,
eth
.
chainManager
,
eth
.
blockPool
)
protocols
:=
[]
p2p
.
Protocol
{
ethProto
}
if
config
.
Shh
{
//
protocols = append(protocols, eth.whisper.Protocol())
protocols
=
append
(
protocols
,
eth
.
whisper
.
Protocol
())
}
eth
.
net
=
&
p2p
.
Server
{
...
...
ethdb/memory_database.go
View file @
06697775
...
...
@@ -49,7 +49,7 @@ func (db *MemDatabase) Print() {
for
key
,
val
:=
range
db
.
db
{
fmt
.
Printf
(
"%x(%d): "
,
key
,
len
(
key
))
node
:=
common
.
NewValueFromBytes
(
val
)
fmt
.
Printf
(
"%q
\n
"
,
node
.
Interface
()
)
fmt
.
Printf
(
"%q
\n
"
,
node
.
Val
)
}
}
...
...
rlp/decode.go
View file @
06697775
...
...
@@ -367,7 +367,12 @@ func makePtrDecoder(typ reflect.Type) (decoder, error) {
dec
:=
func
(
s
*
Stream
,
val
reflect
.
Value
)
(
err
error
)
{
_
,
size
,
err
:=
s
.
Kind
()
if
err
!=
nil
||
size
==
0
&&
s
.
byteval
==
0
{
val
.
Set
(
reflect
.
Zero
(
typ
))
// set to nil
// rearm s.Kind. This is important because the input
// position must advance to the next value even though
// we don't read anything.
s
.
kind
=
-
1
// set the pointer to nil.
val
.
Set
(
reflect
.
Zero
(
typ
))
return
err
}
newval
:=
val
...
...
@@ -535,6 +540,31 @@ func (s *Stream) Bytes() ([]byte, error) {
}
}
// Raw reads a raw encoded value including RLP type information.
func
(
s
*
Stream
)
Raw
()
([]
byte
,
error
)
{
kind
,
size
,
err
:=
s
.
Kind
()
if
err
!=
nil
{
return
nil
,
err
}
if
kind
==
Byte
{
s
.
kind
=
-
1
// rearm Kind
return
[]
byte
{
s
.
byteval
},
nil
}
// the original header has already been read and is no longer
// available. read content and put a new header in front of it.
start
:=
headsize
(
size
)
buf
:=
make
([]
byte
,
uint64
(
start
)
+
size
)
if
err
:=
s
.
readFull
(
buf
[
start
:
]);
err
!=
nil
{
return
nil
,
err
}
if
kind
==
String
{
puthead
(
buf
,
0x80
,
0xB8
,
size
)
}
else
{
puthead
(
buf
,
0xC0
,
0xF7
,
size
)
}
return
buf
,
nil
}
var
errUintOverflow
=
errors
.
New
(
"rlp: uint overflow"
)
// Uint reads an RLP string of up to 8 bytes and returns its contents
...
...
rlp/decode_test.go
View file @
06697775
...
...
@@ -39,7 +39,7 @@ func TestStreamKind(t *testing.T) {
s
:=
NewStream
(
bytes
.
NewReader
(
unhex
(
test
.
input
)))
kind
,
len
,
err
:=
s
.
Kind
()
if
err
!=
nil
{
t
.
Errorf
(
"test %d:
Type
returned error: %v"
,
i
,
err
)
t
.
Errorf
(
"test %d:
Kind
returned error: %v"
,
i
,
err
)
continue
}
if
kind
!=
test
.
wantKind
{
...
...
@@ -93,6 +93,23 @@ func TestStreamErrors(t *testing.T) {
{
"C3C2010201"
,
calls
{
"List"
,
"List"
,
"Uint"
,
"Uint"
,
"ListEnd"
,
"Uint"
},
EOL
},
{
"00"
,
calls
{
"ListEnd"
},
errNotInList
},
{
"C40102"
,
calls
{
"List"
,
"Uint"
,
"ListEnd"
},
errNotAtEOL
},
// This test verifies that the input position is advanced
// correctly when calling Bytes for empty strings. Kind can be called
// any number of times in between and doesn't advance.
{
"C3808080"
,
calls
{
"List"
,
// enter the list
"Bytes"
,
// past first element
"Kind"
,
"Kind"
,
"Kind"
,
// this shouldn't advance
"Bytes"
,
// past second element
"Kind"
,
"Kind"
,
// can't hurt to try
"Bytes"
,
// past final element
"Bytes"
,
// this one should fail
},
EOL
},
}
testfor
:
...
...
@@ -148,6 +165,20 @@ func TestStreamList(t *testing.T) {
}
}
func
TestStreamRaw
(
t
*
testing
.
T
)
{
s
:=
NewStream
(
bytes
.
NewReader
(
unhex
(
"C58401010101"
)))
s
.
List
()
want
:=
unhex
(
"8401010101"
)
raw
,
err
:=
s
.
Raw
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
bytes
.
Equal
(
want
,
raw
)
{
t
.
Errorf
(
"raw mismatch: got %x, want %x"
,
raw
,
want
)
}
}
func
TestDecodeErrors
(
t
*
testing
.
T
)
{
r
:=
bytes
.
NewReader
(
nil
)
...
...
@@ -314,6 +345,9 @@ var decodeTests = []decodeTest{
{
input
:
"C109"
,
ptr
:
new
(
*
[]
uint
),
value
:
&
[]
uint
{
9
}},
{
input
:
"C58403030303"
,
ptr
:
new
(
*
[][]
byte
),
value
:
&
[][]
byte
{{
3
,
3
,
3
,
3
}}},
// check that input position is advanced also for empty values.
{
input
:
"C3808005"
,
ptr
:
new
([]
*
uint
),
value
:
[]
*
uint
{
nil
,
nil
,
uintp
(
5
)}},
// pointer should be reset to nil
{
input
:
"05"
,
ptr
:
sharedPtr
,
value
:
uintp
(
5
)},
{
input
:
"80"
,
ptr
:
sharedPtr
,
value
:
(
*
uint
)(
nil
)},
...
...
rlp/encode.go
View file @
06697775
...
...
@@ -70,7 +70,7 @@ func (e flatenc) EncodeRLP(out io.Writer) error {
newhead
:=
eb
.
lheads
[
prevnheads
]
copy
(
eb
.
lheads
[
prevnheads
:
],
eb
.
lheads
[
prevnheads
+
1
:
])
eb
.
lheads
=
eb
.
lheads
[
:
len
(
eb
.
lheads
)
-
1
]
eb
.
lhsize
-=
newhead
.
tagsize
(
)
eb
.
lhsize
-=
headsize
(
uint64
(
newhead
.
size
)
)
return
nil
}
...
...
@@ -155,21 +155,29 @@ type listhead struct {
// encode writes head to the given buffer, which must be at least
// 9 bytes long. It returns the encoded bytes.
func
(
head
*
listhead
)
encode
(
buf
[]
byte
)
[]
byte
{
if
head
.
size
<
56
{
buf
[
0
]
=
0xC0
+
byte
(
head
.
size
)
return
buf
[
:
1
]
}
else
{
sizesize
:=
putint
(
buf
[
1
:
],
uint64
(
head
.
size
))
buf
[
0
]
=
0xF7
+
byte
(
sizesize
)
return
buf
[
:
sizesize
+
1
]
return
buf
[
:
puthead
(
buf
,
0xC0
,
0xF7
,
uint64
(
head
.
size
))]
}
// headsize returns the size of a list or string header
// for a value of the given size.
func
headsize
(
size
uint64
)
int
{
if
size
<
56
{
return
1
}
return
1
+
intsize
(
size
)
}
func
(
head
*
listhead
)
tagsize
()
int
{
if
head
.
size
<
56
{
// puthead writes a list or string header to buf.
// buf must be at least 9 bytes long.
func
puthead
(
buf
[]
byte
,
smalltag
,
largetag
byte
,
size
uint64
)
int
{
if
size
<
56
{
buf
[
0
]
=
smalltag
+
byte
(
size
)
return
1
}
else
{
sizesize
:=
putint
(
buf
[
1
:
],
size
)
buf
[
0
]
=
largetag
+
byte
(
sizesize
)
return
sizesize
+
1
}
return
1
+
intsize
(
uint64
(
head
.
size
))
}
func
newencbuf
()
*
encbuf
{
...
...
whisper/envelope.go
View file @
06697775
...
...
@@ -18,26 +18,31 @@ const (
type
Envelope
struct
{
Expiry
uint32
// Whisper protocol specifies int32, really should be int64
T
tl
uint32
// ^^^^^^
T
TL
uint32
// ^^^^^^
Topics
[][]
byte
Data
[]
byte
Nonce
uint32
hash
Hash
hash
common
.
Hash
}
func
(
self
*
Envelope
)
Hash
()
Hash
{
if
self
.
hash
==
EmptyHash
{
self
.
hash
=
H
(
crypto
.
Sha3
(
common
.
Encode
(
self
)))
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
)
return
&
Envelope
{
uint32
(
exp
.
Unix
()),
uint32
(
ttl
.
Seconds
()),
topics
,
data
.
Bytes
(),
0
,
Hash
{}}
return
&
Envelope
{
Expiry
:
uint32
(
exp
.
Unix
()),
TTL
:
uint32
(
ttl
.
Seconds
()),
Topics
:
topics
,
Data
:
data
.
Bytes
(),
Nonce
:
0
,
}
}
func
(
self
*
Envelope
)
Seal
(
pow
time
.
Duration
)
{
...
...
@@ -76,7 +81,8 @@ func (self *Envelope) Open(prv *ecdsa.PrivateKey) (msg *Message, err error) {
func
(
self
*
Envelope
)
proveWork
(
dura
time
.
Duration
)
{
var
bestBit
int
d
:=
make
([]
byte
,
64
)
copy
(
d
[
:
32
],
common
.
Encode
(
self
.
withoutNonce
()))
enc
,
_
:=
rlp
.
EncodeToBytes
(
self
.
withoutNonce
())
copy
(
d
[
:
32
],
enc
)
then
:=
time
.
Now
()
.
Add
(
dura
)
.
UnixNano
()
for
n
:=
uint32
(
0
);
time
.
Now
()
.
UnixNano
()
<
then
;
{
...
...
@@ -96,39 +102,28 @@ func (self *Envelope) proveWork(dura time.Duration) {
func
(
self
*
Envelope
)
valid
()
bool
{
d
:=
make
([]
byte
,
64
)
copy
(
d
[
:
32
],
common
.
Encode
(
self
.
withoutNonce
()))
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
.
T
tl
,
common
.
ByteSliceToInterface
(
self
.
Topics
)
,
self
.
Data
}
return
[]
interface
{}{
self
.
Expiry
,
self
.
T
TL
,
self
.
Topics
,
self
.
Data
}
}
func
(
self
*
Envelope
)
RlpData
()
interface
{}
{
return
[]
interface
{}{
self
.
Expiry
,
self
.
Ttl
,
common
.
ByteSliceToInterface
(
self
.
Topics
),
self
.
Data
,
self
.
Nonce
}
}
// rlpenv is an Envelope but is not an rlp.Decoder.
// It is used for decoding because we need to
type
rlpenv
Envelope
func
(
self
*
Envelope
)
DecodeRLP
(
s
*
rlp
.
Stream
)
error
{
var
extenv
struct
{
Expiry
uint32
Ttl
uint32
Topics
[][]
byte
Data
[]
byte
Nonce
uint32
raw
,
err
:=
s
.
Raw
()
if
err
!=
nil
{
return
err
}
if
err
:=
s
.
Decode
(
&
extenv
);
err
!=
nil
{
if
err
:=
rlp
.
DecodeBytes
(
raw
,
(
*
rlpenv
)(
self
)
);
err
!=
nil
{
return
err
}
self
.
Expiry
=
extenv
.
Expiry
self
.
Ttl
=
extenv
.
Ttl
self
.
Topics
=
extenv
.
Topics
self
.
Data
=
extenv
.
Data
self
.
Nonce
=
extenv
.
Nonce
// TODO We should use the stream directly here.
self
.
hash
=
H
(
crypto
.
Sha3
(
common
.
Encode
(
self
)))
self
.
hash
=
crypto
.
Sha3Hash
(
raw
)
return
nil
}
whisper/peer.go
View file @
06697775
...
...
@@ -10,7 +10,7 @@ import (
)
const
(
protocolVersion
=
0x02
protocolVersion
uint64
=
0x02
)
type
peer
struct
{
...
...
@@ -66,21 +66,18 @@ out:
}
func
(
self
*
peer
)
broadcast
(
envelopes
[]
*
Envelope
)
error
{
envs
:=
make
([]
interface
{},
len
(
envelopes
))
i
:=
0
for
_
,
envelope
:=
range
envelopes
{
if
!
self
.
known
.
Has
(
envelope
.
Hash
())
{
envs
[
i
]
=
envelope
self
.
known
.
Add
(
envelope
.
Hash
())
i
++
envs
:=
make
([]
*
Envelope
,
0
,
len
(
envelopes
))
for
_
,
env
:=
range
envelopes
{
if
!
self
.
known
.
Has
(
env
.
Hash
())
{
envs
=
append
(
envs
,
env
)
self
.
known
.
Add
(
env
.
Hash
())
}
}
if
i
>
0
{
if
err
:=
p2p
.
Send
(
self
.
ws
,
envelopesMsg
,
envs
[
:
i
]);
err
!=
nil
{
if
len
(
envs
)
>
0
{
if
err
:=
p2p
.
Send
(
self
.
ws
,
envelopesMsg
,
envs
);
err
!=
nil
{
return
err
}
self
.
peer
.
DebugDetailln
(
"broadcasted"
,
i
,
"message(s)"
)
self
.
peer
.
DebugDetailln
(
"broadcasted"
,
len
(
envs
)
,
"message(s)"
)
}
return
nil
}
...
...
whisper/sort.go
View file @
06697775
package
whisper
import
"sort"
import
(
"sort"
"github.com/ethereum/go-ethereum/common"
)
type
sortedKeys
struct
{
k
[]
int32
...
...
@@ -10,7 +14,7 @@ func (self *sortedKeys) Len() int { return len(self.k) }
func
(
self
*
sortedKeys
)
Less
(
i
,
j
int
)
bool
{
return
self
.
k
[
i
]
<
self
.
k
[
j
]
}
func
(
self
*
sortedKeys
)
Swap
(
i
,
j
int
)
{
self
.
k
[
i
],
self
.
k
[
j
]
=
self
.
k
[
j
],
self
.
k
[
i
]
}
func
sortKeys
(
m
map
[
int32
]
Hash
)
[]
int32
{
func
sortKeys
(
m
map
[
int32
]
common
.
Hash
)
[]
int32
{
sorted
:=
new
(
sortedKeys
)
sorted
.
k
=
make
([]
int32
,
len
(
m
))
i
:=
0
...
...
whisper/sort_test.go
View file @
06697775
package
whisper
import
"testing"
import
(
"testing"
"github.com/ethereum/go-ethereum/common"
)
func
TestSorting
(
t
*
testing
.
T
)
{
m
:=
map
[
int32
]
Hash
{
1
:
HS
(
"1"
)
,
3
:
HS
(
"3"
)
,
2
:
HS
(
"2"
)
,
5
:
HS
(
"5"
)
,
m
:=
map
[
int32
]
common
.
Hash
{
1
:
{
1
}
,
3
:
{
3
}
,
2
:
{
2
}
,
5
:
{
5
}
,
}
exp
:=
[]
int32
{
1
,
2
,
3
,
5
}
res
:=
sortKeys
(
m
)
...
...
whisper/whisper.go
View file @
06697775
package
whisper
import
(
"bytes"
"crypto/ecdsa"
"errors"
"sync"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/ecies"
"github.com/ethereum/go-ethereum/event/filter"
...
...
@@ -15,26 +15,6 @@ import (
"gopkg.in/fatih/set.v0"
)
// MOVE ME
type
Hash
struct
{
hash
string
}
var
EmptyHash
Hash
func
H
(
hash
[]
byte
)
Hash
{
return
Hash
{
string
(
hash
)}
}
func
HS
(
hash
string
)
Hash
{
return
Hash
{
hash
}
}
func
(
self
Hash
)
Compare
(
other
Hash
)
int
{
return
bytes
.
Compare
([]
byte
(
self
.
hash
),
[]
byte
(
other
.
hash
))
}
// MOVE ME END
const
(
statusMsg
=
0x0
envelopesMsg
=
0x01
...
...
@@ -55,7 +35,7 @@ type Whisper struct {
filters
*
filter
.
Filters
mmu
sync
.
RWMutex
messages
map
[
Hash
]
*
Envelope
messages
map
[
common
.
Hash
]
*
Envelope
expiry
map
[
uint32
]
*
set
.
SetNonTS
quit
chan
struct
{}
...
...
@@ -65,7 +45,7 @@ type Whisper struct {
func
New
()
*
Whisper
{
whisper
:=
&
Whisper
{
messages
:
make
(
map
[
Hash
]
*
Envelope
),
messages
:
make
(
map
[
common
.
Hash
]
*
Envelope
),
filters
:
filter
.
New
(),
expiry
:
make
(
map
[
uint32
]
*
set
.
SetNonTS
),
quit
:
make
(
chan
struct
{}),
...
...
@@ -239,7 +219,7 @@ func (self *Whisper) expire() {
}
hashSet
.
Each
(
func
(
v
interface
{})
bool
{
delete
(
self
.
messages
,
v
.
(
Hash
))
delete
(
self
.
messages
,
v
.
(
common
.
Hash
))
return
true
})
self
.
expiry
[
then
]
.
Clear
()
...
...
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