Merge remote-tracking branch 'obscuren/db-merge-fix' into limits-changes

This commit is contained in:
Anthony Eufemio 2015-08-14 06:10:42 +09:00
commit 0a2e667523
10 changed files with 86 additions and 27 deletions

View file

@ -45,7 +45,6 @@ import (
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/whisper" "github.com/ethereum/go-ethereum/whisper"
) )
@ -738,48 +737,53 @@ func mergeDatabases(datadir string, newdb func(path string) (common.Database, er
} }
defer database.Close() defer database.Close()
glog.Infoln("Merging blockchain database...") // Migrate blocks
chainDb, err := newdb(chainPath) chainDb, err := newdb(chainPath)
if err != nil { if err != nil {
return fmt.Errorf("state db err: %v", err) return fmt.Errorf("state db err: %v", err)
} }
defer chainDb.Close() defer chainDb.Close()
if db, ok := chainDb.(*ethdb.LDBDatabase); ok { if chain, ok := chainDb.(*ethdb.LDBDatabase); ok {
it := db.NewIterator() glog.Infoln("Merging blockchain database...")
it := chain.NewIterator()
for it.Next() { for it.Next() {
database.Put(it.Key(), it.Value()) database.Put(it.Key(), it.Value())
} }
it.Release()
} }
glog.Infoln("Merging state database...") // Migrate state
state := filepath.Join(datadir, "state") stateDb, err := newdb(filepath.Join(datadir, "state"))
stateDb, err := newdb(state)
if err != nil { if err != nil {
return fmt.Errorf("state db err: %v", err) return fmt.Errorf("state db err: %v", err)
} }
defer stateDb.Close() defer stateDb.Close()
if db, ok := chainDb.(*ethdb.LDBDatabase); ok { if state, ok := stateDb.(*ethdb.LDBDatabase); ok {
it := db.NewIterator() glog.Infoln("Merging state database...")
it := state.NewIterator()
for it.Next() { 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...") // Migrate transaction / receipts
extra := filepath.Join(datadir, "extra") extraDb, err := newdb(filepath.Join(datadir, "extra"))
extraDb, err := newdb(extra)
if err != nil { if err != nil {
return fmt.Errorf("state db err: %v", err) return fmt.Errorf("state db err: %v", err)
} }
defer extraDb.Close() defer extraDb.Close()
if db, ok := chainDb.(*ethdb.LDBDatabase); ok { if extra, ok := extraDb.(*ethdb.LDBDatabase); ok {
it := db.NewIterator() glog.Infoln("Merging transaction database...")
it := extra.NewIterator()
for it.Next() { for it.Next() {
database.Put(it.Key(), it.Value()) database.Put(it.Key(), it.Value())
} }
it.Release()
} }
return nil return nil

View file

@ -66,7 +66,7 @@ const (
DiscUnexpectedIdentity DiscUnexpectedIdentity
DiscSelf DiscSelf
DiscReadTimeout DiscReadTimeout
DiscSubprotocolError DiscSubprotocolError = 0x10
) )
var discReasonToString = [...]string{ var discReasonToString = [...]string{

View file

@ -267,6 +267,10 @@ func initiatorEncHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey, remoteID d
} }
func newInitiatorHandshake(remoteID discover.NodeID) (*encHandshake, error) { 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 // generate random initiator nonce
n := make([]byte, shaLen) n := make([]byte, shaLen)
if _, err := rand.Read(n); err != nil { if _, err := rand.Read(n); err != nil {
@ -277,10 +281,6 @@ func newInitiatorHandshake(remoteID discover.NodeID) (*encHandshake, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
rpub, err := remoteID.Pubkey()
if err != nil {
return nil, fmt.Errorf("bad remoteID: %v", err)
}
h := &encHandshake{ h := &encHandshake{
initiator: true, initiator: true,
remoteID: remoteID, remoteID: remoteID,
@ -417,6 +417,14 @@ func decodeAuthMsg(prv *ecdsa.PrivateKey, token []byte, auth []byte) (*encHandsh
if err != nil { if err != nil {
return nil, err 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) h.remoteRandomPub, _ = importPublicKey(remoteRandomPub)
return h, nil return h, nil
} }

View file

@ -183,6 +183,8 @@ func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) {
return decodeBigIntNoPtr, nil return decodeBigIntNoPtr, nil
case isUint(kind): case isUint(kind):
return decodeUint, nil return decodeUint, nil
case kind == reflect.Bool:
return decodeBool, nil
case kind == reflect.String: case kind == reflect.String:
return decodeString, nil return decodeString, nil
case kind == reflect.Slice || kind == reflect.Array: case kind == reflect.Slice || kind == reflect.Array:
@ -211,6 +213,15 @@ func decodeUint(s *Stream, val reflect.Value) error {
return nil 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 { func decodeString(s *Stream, val reflect.Value) error {
b, err := s.Bytes() b, err := s.Bytes()
if err != nil { 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 starts decoding an RLP list. If the input does not contain a
// list, the returned error will be ErrExpectedList. When the list's // list, the returned error will be ErrExpectedList. When the list's
// end has been reached, any Stream operation will return EOL. // end has been reached, any Stream operation will return EOL.

View file

@ -19,6 +19,7 @@ package rlp
import ( import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"io" "io"
"math/big" "math/big"
@ -116,6 +117,9 @@ func TestStreamErrors(t *testing.T) {
{"817F", calls{"Uint"}, nil, ErrCanonSize}, {"817F", calls{"Uint"}, nil, ErrCanonSize},
{"8180", calls{"Uint"}, nil, nil}, {"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. // Size tags must use the smallest possible encoding.
// Leading zero bytes in the size tag are also rejected. // Leading zero bytes in the size tag are also rejected.
{"8100", calls{"Uint"}, nil, ErrCanonSize}, {"8100", calls{"Uint"}, nil, ErrCanonSize},
@ -315,6 +319,11 @@ var (
) )
var decodeTests = []decodeTest{ 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 // integers
{input: "05", ptr: new(uint32), value: uint32(5)}, {input: "05", ptr: new(uint32), value: uint32(5)},
{input: "80", ptr: new(uint32), value: uint32(0)}, {input: "80", ptr: new(uint32), value: uint32(0)},

View file

@ -361,6 +361,8 @@ func makeWriter(typ reflect.Type) (writer, error) {
return writeBigIntNoPtr, nil return writeBigIntNoPtr, nil
case isUint(kind): case isUint(kind):
return writeUint, nil return writeUint, nil
case kind == reflect.Bool:
return writeBool, nil
case kind == reflect.String: case kind == reflect.String:
return writeString, nil return writeString, nil
case kind == reflect.Slice && isByte(typ.Elem()): case kind == reflect.Slice && isByte(typ.Elem()):
@ -398,6 +400,15 @@ func writeUint(val reflect.Value, w *encbuf) error {
return nil 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 { func writeBigIntPtr(val reflect.Value, w *encbuf) error {
ptr := val.Interface().(*big.Int) ptr := val.Interface().(*big.Int)
if ptr == nil { if ptr == nil {

View file

@ -71,6 +71,10 @@ type encTest struct {
} }
var encTests = []encTest{ var encTests = []encTest{
// booleans
{val: true, output: "01"},
{val: false, output: "80"},
// integers // integers
{val: uint32(0), output: "80"}, {val: uint32(0), output: "80"},
{val: uint32(127), output: "7F"}, {val: uint32(127), output: "7F"},

View file

@ -38,8 +38,6 @@ func NewCache(backend Backend) *Cache {
} }
func (self *Cache) Get(key []byte) []byte { func (self *Cache) Get(key []byte) []byte {
key = append(StatePre, key...)
data := self.store[string(key)] data := self.store[string(key)]
if data == nil { if data == nil {
data, _ = self.backend.Get(key) data, _ = self.backend.Get(key)
@ -49,8 +47,6 @@ func (self *Cache) Get(key []byte) []byte {
} }
func (self *Cache) Put(key []byte, data []byte) { func (self *Cache) Put(key []byte, data []byte) {
key = append(StatePre, key...)
self.batch.Put(key, data) self.batch.Put(key, data)
self.store[string(key)] = data self.store[string(key)] = data
} }

View file

@ -27,8 +27,6 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
) )
var StatePre = []byte("state-")
func ParanoiaCheck(t1 *Trie, backend Backend) (bool, *Trie) { func ParanoiaCheck(t1 *Trie, backend Backend) (bool, *Trie) {
t2 := New(nil, backend) t2 := New(nil, backend)