diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 895e55b44d..4905d502a4 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -51,7 +51,7 @@ import ( ) const ( - ClientIdentifier = "Geth " + ClientIdentifier = "Geth" Version = "1.0.1" VersionMajor = 1 VersionMinor = 0 diff --git a/eth/backend.go b/eth/backend.go index 086182920c..487e56071f 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -45,7 +45,6 @@ import ( "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/nat" - "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/whisper" ) @@ -738,48 +737,53 @@ func mergeDatabases(datadir string, newdb func(path string) (common.Database, er } defer database.Close() - glog.Infoln("Merging blockchain database...") + // Migrate blocks chainDb, err := newdb(chainPath) if err != nil { return fmt.Errorf("state db err: %v", err) } defer chainDb.Close() - if db, ok := chainDb.(*ethdb.LDBDatabase); ok { - it := db.NewIterator() + if chain, ok := chainDb.(*ethdb.LDBDatabase); ok { + glog.Infoln("Merging blockchain database...") + it := chain.NewIterator() for it.Next() { database.Put(it.Key(), it.Value()) } + it.Release() } - glog.Infoln("Merging state database...") - state := filepath.Join(datadir, "state") - stateDb, err := newdb(state) + // Migrate state + stateDb, err := newdb(filepath.Join(datadir, "state")) if err != nil { return fmt.Errorf("state db err: %v", err) } defer stateDb.Close() - if db, ok := chainDb.(*ethdb.LDBDatabase); ok { - it := db.NewIterator() + if state, ok := stateDb.(*ethdb.LDBDatabase); ok { + glog.Infoln("Merging state database...") + it := state.NewIterator() for it.Next() { - database.Put(append(trie.StatePre, it.Key()...), it.Value()) + database.Put(it.Key(), it.Value()) } + it.Release() } - glog.Infoln("Merging transaction database...") - extra := filepath.Join(datadir, "extra") - extraDb, err := newdb(extra) + // Migrate transaction / receipts + extraDb, err := newdb(filepath.Join(datadir, "extra")) if err != nil { return fmt.Errorf("state db err: %v", err) } defer extraDb.Close() - if db, ok := chainDb.(*ethdb.LDBDatabase); ok { - it := db.NewIterator() + if extra, ok := extraDb.(*ethdb.LDBDatabase); ok { + glog.Infoln("Merging transaction database...") + + it := extra.NewIterator() for it.Next() { database.Put(it.Key(), it.Value()) } + it.Release() } return nil diff --git a/p2p/peer_error.go b/p2p/peer_error.go index b1762a6ee8..62c7b665dd 100644 --- a/p2p/peer_error.go +++ b/p2p/peer_error.go @@ -66,7 +66,7 @@ const ( DiscUnexpectedIdentity DiscSelf DiscReadTimeout - DiscSubprotocolError + DiscSubprotocolError = 0x10 ) var discReasonToString = [...]string{ diff --git a/p2p/rlpx.go b/p2p/rlpx.go index fd43f565e4..aaa7338547 100644 --- a/p2p/rlpx.go +++ b/p2p/rlpx.go @@ -267,6 +267,10 @@ func initiatorEncHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey, remoteID d } func newInitiatorHandshake(remoteID discover.NodeID) (*encHandshake, error) { + rpub, err := remoteID.Pubkey() + if err != nil { + return nil, fmt.Errorf("bad remoteID: %v", err) + } // generate random initiator nonce n := make([]byte, shaLen) if _, err := rand.Read(n); err != nil { @@ -277,10 +281,6 @@ func newInitiatorHandshake(remoteID discover.NodeID) (*encHandshake, error) { if err != nil { return nil, err } - rpub, err := remoteID.Pubkey() - if err != nil { - return nil, fmt.Errorf("bad remoteID: %v", err) - } h := &encHandshake{ initiator: true, remoteID: remoteID, @@ -417,6 +417,14 @@ func decodeAuthMsg(prv *ecdsa.PrivateKey, token []byte, auth []byte) (*encHandsh if err != nil { return nil, err } + + // validate the sha3 of recovered pubkey + remoteRandomPubMAC := msg[sigLen : sigLen+shaLen] + shaRemoteRandomPub := crypto.Sha3(remoteRandomPub[1:]) + if !bytes.Equal(remoteRandomPubMAC, shaRemoteRandomPub) { + return nil, fmt.Errorf("sha3 of recovered ephemeral pubkey does not match checksum in auth message") + } + h.remoteRandomPub, _ = importPublicKey(remoteRandomPub) return h, nil } diff --git a/rlp/decode.go b/rlp/decode.go index c0b5f06994..1381f5274e 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -183,6 +183,8 @@ func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) { return decodeBigIntNoPtr, nil case isUint(kind): return decodeUint, nil + case kind == reflect.Bool: + return decodeBool, nil case kind == reflect.String: return decodeString, nil case kind == reflect.Slice || kind == reflect.Array: @@ -211,6 +213,15 @@ func decodeUint(s *Stream, val reflect.Value) error { return nil } +func decodeBool(s *Stream, val reflect.Value) error { + b, err := s.Bool() + if err != nil { + return wrapStreamError(err, val.Type()) + } + val.SetBool(b) + return nil +} + func decodeString(s *Stream, val reflect.Value) error { b, err := s.Bytes() if err != nil { @@ -697,6 +708,24 @@ func (s *Stream) uint(maxbits int) (uint64, error) { } } +// Bool reads an RLP string of up to 1 byte and returns its contents +// as an boolean. If the input does not contain an RLP string, the +// returned error will be ErrExpectedString. +func (s *Stream) Bool() (bool, error) { + num, err := s.uint(8) + if err != nil { + return false, err + } + switch num { + case 0: + return false, nil + case 1: + return true, nil + default: + return false, fmt.Errorf("rlp: invalid boolean value: %d", num) + } +} + // List starts decoding an RLP list. If the input does not contain a // list, the returned error will be ErrExpectedList. When the list's // end has been reached, any Stream operation will return EOL. diff --git a/rlp/decode_test.go b/rlp/decode_test.go index 331faa9d83..d6b0611dd0 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -19,6 +19,7 @@ package rlp import ( "bytes" "encoding/hex" + "errors" "fmt" "io" "math/big" @@ -116,6 +117,9 @@ func TestStreamErrors(t *testing.T) { {"817F", calls{"Uint"}, nil, ErrCanonSize}, {"8180", calls{"Uint"}, nil, nil}, + // Non-valid boolean + {"02", calls{"Bool"}, nil, errors.New("rlp: invalid boolean value: 2")}, + // Size tags must use the smallest possible encoding. // Leading zero bytes in the size tag are also rejected. {"8100", calls{"Uint"}, nil, ErrCanonSize}, @@ -315,6 +319,11 @@ var ( ) var decodeTests = []decodeTest{ + // booleans + {input: "01", ptr: new(bool), value: true}, + {input: "80", ptr: new(bool), value: false}, + {input: "02", ptr: new(bool), error: "rlp: invalid boolean value: 2"}, + // integers {input: "05", ptr: new(uint32), value: uint32(5)}, {input: "80", ptr: new(uint32), value: uint32(0)}, diff --git a/rlp/encode.go b/rlp/encode.go index 0ddef7bbb5..b525ae4e7a 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -361,6 +361,8 @@ func makeWriter(typ reflect.Type) (writer, error) { return writeBigIntNoPtr, nil case isUint(kind): return writeUint, nil + case kind == reflect.Bool: + return writeBool, nil case kind == reflect.String: return writeString, nil case kind == reflect.Slice && isByte(typ.Elem()): @@ -398,6 +400,15 @@ func writeUint(val reflect.Value, w *encbuf) error { return nil } +func writeBool(val reflect.Value, w *encbuf) error { + if val.Bool() { + w.str = append(w.str, 0x01) + } else { + w.str = append(w.str, 0x80) + } + return nil +} + func writeBigIntPtr(val reflect.Value, w *encbuf) error { ptr := val.Interface().(*big.Int) if ptr == nil { diff --git a/rlp/encode_test.go b/rlp/encode_test.go index e83c76b51e..60bd956926 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -71,6 +71,10 @@ type encTest struct { } var encTests = []encTest{ + // booleans + {val: true, output: "01"}, + {val: false, output: "80"}, + // integers {val: uint32(0), output: "80"}, {val: uint32(127), output: "7F"}, diff --git a/trie/cache.go b/trie/cache.go index 99d8033a6d..e475fc861a 100644 --- a/trie/cache.go +++ b/trie/cache.go @@ -38,8 +38,6 @@ func NewCache(backend Backend) *Cache { } func (self *Cache) Get(key []byte) []byte { - key = append(StatePre, key...) - data := self.store[string(key)] if data == nil { data, _ = self.backend.Get(key) @@ -49,8 +47,6 @@ func (self *Cache) Get(key []byte) []byte { } func (self *Cache) Put(key []byte, data []byte) { - key = append(StatePre, key...) - self.batch.Put(key, data) self.store[string(key)] = data } diff --git a/trie/trie.go b/trie/trie.go index 2970bc185e..abf48a8509 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -27,8 +27,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" ) -var StatePre = []byte("state-") - func ParanoiaCheck(t1 *Trie, backend Backend) (bool, *Trie) { t2 := New(nil, backend)