Unreader to unread bytes

This commit is contained in:
Jae Kwon 2014-12-29 15:14:54 -08:00
parent 946fa21dc7
commit 5bace5cce8
19 changed files with 84 additions and 57 deletions

View File

@ -49,7 +49,7 @@ func AccountEncoder(o interface{}, w io.Writer, n *int64, err *error) {
WriteBinary(o.(*Account), w, n, err) WriteBinary(o.(*Account), w, n, err)
} }
func AccountDecoder(r io.Reader, n *int64, err *error) interface{} { func AccountDecoder(r Unreader, n *int64, err *error) interface{} {
return ReadBinary(&Account{}, r, n, err) return ReadBinary(&Account{}, r, n, err)
} }

View File

@ -2,7 +2,6 @@ package account
import ( import (
"errors" "errors"
"io"
"reflect" "reflect"
"github.com/tendermint/go-ed25519" "github.com/tendermint/go-ed25519"
@ -23,8 +22,8 @@ const (
//------------------------------------- //-------------------------------------
// For binary.readReflect // For binary.readReflect
func PrivKeyDecoder(r io.Reader, n *int64, err *error) interface{} { func PrivKeyDecoder(r Unreader, n *int64, err *error) interface{} {
switch t := ReadByte(r, n, err); t { switch t := PeekByte(r, n, err); t {
case PrivKeyTypeEd25519: case PrivKeyTypeEd25519:
return ReadBinary(PrivKeyEd25519{}, r, n, err) return ReadBinary(PrivKeyEd25519{}, r, n, err)
default: default:

View File

@ -2,7 +2,6 @@ package account
import ( import (
"errors" "errors"
"io"
"reflect" "reflect"
"github.com/tendermint/go-ed25519" "github.com/tendermint/go-ed25519"
@ -26,8 +25,8 @@ const (
//------------------------------------- //-------------------------------------
// for binary.readReflect // for binary.readReflect
func PubKeyDecoder(r io.Reader, n *int64, err *error) interface{} { func PubKeyDecoder(r Unreader, n *int64, err *error) interface{} {
switch t := ReadByte(r, n, err); t { switch t := PeekByte(r, n, err); t {
case PubKeyTypeNil: case PubKeyTypeNil:
return PubKeyNil{} return PubKeyNil{}
case PubKeyTypeEd25519: case PubKeyTypeEd25519:

View File

@ -3,7 +3,6 @@ package account
import ( import (
"errors" "errors"
"fmt" "fmt"
"io"
"reflect" "reflect"
"github.com/tendermint/go-ed25519" "github.com/tendermint/go-ed25519"
@ -23,8 +22,8 @@ const (
//------------------------------------- //-------------------------------------
// for binary.readReflect // for binary.readReflect
func SignatureDecoder(r io.Reader, n *int64, err *error) interface{} { func SignatureDecoder(r Unreader, n *int64, err *error) interface{} {
switch t := ReadByte(r, n, err); t { switch t := PeekByte(r, n, err); t {
case SignatureTypeEd25519: case SignatureTypeEd25519:
return ReadBinary(SignatureEd25519{}, r, n, err) return ReadBinary(SignatureEd25519{}, r, n, err)
default: default:

View File

@ -123,8 +123,9 @@ func GreeterEncoder(o interface{}, w io.Writer, n *int64, err *error) {
} }
} }
func GreeterDecoder(r io.Reader, n *int64, err *error) interface{} { func GreeterDecoder(r *bytes.Reader, n *int64, err *error) interface{} {
switch t := ReadByte(r, n, err); t { // We must peek the type byte because ReadBinary() expects it.
switch t := PeekByte(r, n, err); t {
case GreeterTypeDog: case GreeterTypeDog:
return ReadBinary(Dog{}, r, n, err) return ReadBinary(Dog{}, r, n, err)
case GreeterTypeCat: case GreeterTypeCat:

View File

@ -5,7 +5,12 @@ import (
"reflect" "reflect"
) )
func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} { type Unreader interface {
io.Reader
UnreadByte() error
}
func ReadBinary(o interface{}, r Unreader, n *int64, err *error) interface{} {
rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
if rv.Kind() == reflect.Ptr { if rv.Kind() == reflect.Ptr {
readReflect(rv.Elem(), rt.Elem(), r, n, err) readReflect(rv.Elem(), rt.Elem(), r, n, err)

View File

@ -9,7 +9,7 @@ import (
) )
type Encoder func(o interface{}, w io.Writer, n *int64, err *error) type Encoder func(o interface{}, w io.Writer, n *int64, err *error)
type Decoder func(r io.Reader, n *int64, err *error) interface{} type Decoder func(r Unreader, n *int64, err *error) interface{}
type Comparator func(o1 interface{}, o2 interface{}) int type Comparator func(o1 interface{}, o2 interface{}) int
type Codec struct { type Codec struct {
@ -86,7 +86,7 @@ func BasicCodecEncoder(o interface{}, w io.Writer, n *int64, err *error) {
} }
} }
func BasicCodecDecoder(r io.Reader, n *int64, err *error) (o interface{}) { func BasicCodecDecoder(r Unreader, n *int64, err *error) (o interface{}) {
type_ := ReadByte(r, n, err) type_ := ReadByte(r, n, err)
switch type_ { switch type_ {
case typeByte: case typeByte:

View File

@ -18,6 +18,16 @@ func ReadByte(r io.Reader, n *int64, err *error) byte {
return buf[0] return buf[0]
} }
// NOTE: may end up advancing the reader upon error.
func PeekByte(r Unreader, n *int64, err *error) byte {
byte_ := ReadByte(r, n, err)
if *err != nil {
return 0
}
*err = r.UnreadByte()
return byte_
}
// Int8 // Int8
func WriteInt8(i int8, w io.Writer, n *int64, err *error) { func WriteInt8(i int8, w io.Writer, n *int64, err *error) {

View File

@ -47,34 +47,44 @@ func GetTypeInfo(rt reflect.Type) *TypeInfo {
// NOTE: not goroutine safe, so only call upon program init. // NOTE: not goroutine safe, so only call upon program init.
func RegisterType(info *TypeInfo) *TypeInfo { func RegisterType(info *TypeInfo) *TypeInfo {
// Register the type info
typeInfos[info.Type] = info
// Also register the underlying struct's info, if info.Type is a pointer. // Also register the underlying struct's info, if info.Type is a pointer.
// Or, if info.Type is not a pointer, register the pointer. // Or, if info.Type is not a pointer, register the pointer.
var rt, ptrRt reflect.Type
if info.Type.Kind() == reflect.Ptr { if info.Type.Kind() == reflect.Ptr {
rt := info.Type.Elem() rt, ptrRt = info.Type.Elem(), info.Type
typeInfos[rt] = info
} else { } else {
ptrRt := reflect.PtrTo(info.Type) rt, ptrRt = info.Type, reflect.PtrTo(info.Type)
typeInfos[ptrRt] = info
} }
// Register the type info
typeInfos[rt] = info
typeInfos[ptrRt] = info
// See if the type implements HasTypeByte // See if the type implements HasTypeByte
if info.Type.Implements(reflect.TypeOf((*HasTypeByte)(nil)).Elem()) { if rt.Implements(reflect.TypeOf((*HasTypeByte)(nil)).Elem()) {
zero := reflect.Zero(info.Type) zero := reflect.Zero(rt)
typeByte := zero.Interface().(HasTypeByte).TypeByte() typeByte := zero.Interface().(HasTypeByte).TypeByte()
if info.HasTypeByte && info.TypeByte != typeByte { if info.HasTypeByte && info.TypeByte != typeByte {
panic(fmt.Sprintf("Type %v expected TypeByte of %X", info.Type, typeByte)) panic(fmt.Sprintf("Type %v expected TypeByte of %X", rt, typeByte))
} } else {
info.HasTypeByte = true info.HasTypeByte = true
info.TypeByte = typeByte info.TypeByte = typeByte
} }
} else if ptrRt.Implements(reflect.TypeOf((*HasTypeByte)(nil)).Elem()) {
zero := reflect.Zero(ptrRt)
typeByte := zero.Interface().(HasTypeByte).TypeByte()
if info.HasTypeByte && info.TypeByte != typeByte {
panic(fmt.Sprintf("Type %v expected TypeByte of %X", ptrRt, typeByte))
} else {
info.HasTypeByte = true
info.TypeByte = typeByte
}
}
return info return info
} }
func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *error) { func readReflect(rv reflect.Value, rt reflect.Type, r Unreader, n *int64, err *error) {
// First, create a new struct if rv is nil pointer. // First, create a new struct if rv is nil pointer.
if rt.Kind() == reflect.Ptr && rv.IsNil() { if rt.Kind() == reflect.Ptr && rv.IsNil() {

View File

@ -5,10 +5,10 @@ import (
"crypto/sha256" "crypto/sha256"
"errors" "errors"
"fmt" "fmt"
"io"
"strings" "strings"
"sync" "sync"
. "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/merkle" "github.com/tendermint/tendermint/merkle"
) )
@ -227,7 +227,7 @@ func (ps *PartSet) IsComplete() bool {
return ps.count == ps.total return ps.count == ps.total
} }
func (ps *PartSet) GetReader() io.Reader { func (ps *PartSet) GetReader() Unreader {
if !ps.IsComplete() { if !ps.IsComplete() {
panic("Cannot GetReader() on incomplete PartSet") panic("Cannot GetReader() on incomplete PartSet")
} }

View File

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
. "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/common"
@ -41,7 +40,7 @@ func (bs *BlockStore) Height() uint {
return bs.height return bs.height
} }
func (bs *BlockStore) GetReader(key []byte) io.Reader { func (bs *BlockStore) GetReader(key []byte) Unreader {
bytez := bs.db.Get(key) bytez := bs.db.Get(key)
if bytez == nil { if bytez == nil {
return nil return nil

View File

@ -52,8 +52,8 @@ const (
//------------------------------------- //-------------------------------------
// for binary.readReflect // for binary.readReflect
func TxDecoder(r io.Reader, n *int64, err *error) interface{} { func TxDecoder(r Unreader, n *int64, err *error) interface{} {
switch t := ReadByte(r, n, err); t { switch t := PeekByte(r, n, err); t {
case TxTypeSend: case TxTypeSend:
return ReadBinary(&SendTx{}, r, n, err) return ReadBinary(&SendTx{}, r, n, err)
case TxTypeBond: case TxTypeBond:

View File

@ -111,10 +111,13 @@ func (conR *ConsensusReactor) Receive(chId byte, peer *p2p.Peer, msgBytes []byte
// Get round state // Get round state
rs := conR.conS.GetRoundState() rs := conR.conS.GetRoundState()
ps := peer.Data.Get(peerStateKey).(*PeerState) ps := peer.Data.Get(peerStateKey).(*PeerState)
_, msg_ := decodeMessage(msgBytes) _, msg_, err := decodeMessage(msgBytes)
var err error = nil if err != nil {
log.Warning("[%X] RECEIVE %v: %v ERROR: %v", chId, peer.Connection().RemoteAddress, msg_, err)
log.Debug("[%X][%v] Receive: %v", chId, peer, msg_) return
}
log.Debug("[%X] RECEIVE %v: %v", chId, peer.Connection().RemoteAddress, msg_)
log.Debug("[%X] RECEIVE BYTES: %X", chId, msgBytes)
switch chId { switch chId {
case StateCh: case StateCh:
@ -219,7 +222,7 @@ func (conR *ConsensusReactor) broadcastNewRoundStepRoutine() {
// Get seconds since beginning of height. // Get seconds since beginning of height.
// Due to the condition documented, this is safe. // Due to the condition documented, this is safe.
timeElapsed := rs.StartTime.Sub(time.Now()) timeElapsed := time.Now().Sub(rs.StartTime)
// Broadcast NewRoundStepMessage // Broadcast NewRoundStepMessage
{ {
@ -635,26 +638,26 @@ const (
) )
// TODO: check for unnecessary extra bytes at the end. // TODO: check for unnecessary extra bytes at the end.
func decodeMessage(bz []byte) (msgType byte, msg interface{}) { func decodeMessage(bz []byte) (msgType byte, msg interface{}, err error) {
n, err := new(int64), new(error) n := new(int64)
// log.Debug("decoding msg bytes: %X", bz) // log.Debug("decoding msg bytes: %X", bz)
msgType = bz[0] msgType = bz[0]
r := bytes.NewReader(bz[1:]) r := bytes.NewReader(bz[1:])
switch msgType { switch msgType {
// Messages for communicating state changes // Messages for communicating state changes
case msgTypeNewRoundStep: case msgTypeNewRoundStep:
msg = ReadBinary(&NewRoundStepMessage{}, r, n, err) msg = ReadBinary(&NewRoundStepMessage{}, r, n, &err)
case msgTypeCommitStep: case msgTypeCommitStep:
msg = ReadBinary(&CommitStepMessage{}, r, n, err) msg = ReadBinary(&CommitStepMessage{}, r, n, &err)
// Messages of data // Messages of data
case msgTypeProposal: case msgTypeProposal:
msg = ReadBinary(&Proposal{}, r, n, err) msg = ReadBinary(&Proposal{}, r, n, &err)
case msgTypePart: case msgTypePart:
msg = ReadBinary(&PartMessage{}, r, n, err) msg = ReadBinary(&PartMessage{}, r, n, &err)
case msgTypeVote: case msgTypeVote:
msg = ReadBinary(&VoteMessage{}, r, n, err) msg = ReadBinary(&VoteMessage{}, r, n, &err)
case msgTypeHasVote: case msgTypeHasVote:
msg = ReadBinary(&HasVoteMessage{}, r, n, err) msg = ReadBinary(&HasVoteMessage{}, r, n, &err)
default: default:
msg = nil msg = nil
} }

View File

@ -2,8 +2,9 @@ package merkle
import ( import (
"crypto/sha256" "crypto/sha256"
. "github.com/tendermint/tendermint/binary"
"io" "io"
. "github.com/tendermint/tendermint/binary"
) )
// Node // Node
@ -29,7 +30,7 @@ func NewIAVLNode(key interface{}, value interface{}) *IAVLNode {
} }
} }
func ReadIAVLNode(t *IAVLTree, r io.Reader, n *int64, err *error) *IAVLNode { func ReadIAVLNode(t *IAVLTree, r Unreader, n *int64, err *error) *IAVLNode {
node := &IAVLNode{} node := &IAVLNode{}
// node header & key // node header & key

View File

@ -182,7 +182,7 @@ func (c *MConnection) Send(chId byte, msg interface{}) bool {
return false return false
} }
log.Debug("[%X] Send to %v: %v", chId, c, msg) log.Debug("[%X] SEND %v: %v", chId, c.RemoteAddress, msg)
log.Debug(" Bytes: %X", BinaryBytes(msg)) log.Debug(" Bytes: %X", BinaryBytes(msg))
// Send message to channel. // Send message to channel.
@ -210,7 +210,7 @@ func (c *MConnection) TrySend(chId byte, msg interface{}) bool {
return false return false
} }
log.Debug("[%X] TrySend to %v: %v", chId, c, msg) log.Debug("[%X] TRYSEND %v: %v", chId, c.RemoteAddress, msg)
// Send message to channel. // Send message to channel.
channel, ok := c.channelsIdx[chId] channel, ok := c.channelsIdx[chId]
@ -407,6 +407,7 @@ FOR_LOOP:
Panicf("Unknown channel %X", pkt.ChannelId) Panicf("Unknown channel %X", pkt.ChannelId)
} }
msgBytes := channel.recvMsgPacket(pkt) msgBytes := channel.recvMsgPacket(pkt)
log.Warning("RECEIVE_MSG_BYTES: %X", msgBytes)
if msgBytes != nil { if msgBytes != nil {
c.onReceive(pkt.ChannelId, msgBytes) c.onReceive(pkt.ChannelId, msgBytes)
} }

View File

@ -62,8 +62,8 @@ func (p *Peer) IsStopped() bool {
return atomic.LoadUint32(&p.stopped) == 1 return atomic.LoadUint32(&p.stopped) == 1
} }
func (p *Peer) RemoteAddress() *NetAddress { func (p *Peer) Connection() *MConnection {
return p.mconn.RemoteAddress return p.mconn
} }
func (p *Peer) IsOutbound() bool { func (p *Peer) IsOutbound() bool {

View File

@ -105,7 +105,7 @@ func (pexR *PEXReactor) Receive(chId byte, src *Peer, msgBytes []byte) {
// We received some peer addresses from src. // We received some peer addresses from src.
// TODO: prevent abuse. // TODO: prevent abuse.
// (We don't want to get spammed with bad peers) // (We don't want to get spammed with bad peers)
srcAddr := src.RemoteAddress() srcAddr := src.Connection().RemoteAddress
for _, addr := range msg.(*pexAddrsMessage).Addrs { for _, addr := range msg.(*pexAddrsMessage).Addrs {
pexR.book.AddAddress(addr, srcAddr) pexR.book.AddAddress(addr, srcAddr)
} }

View File

@ -161,7 +161,7 @@ func (sw *Switch) Broadcast(chId byte, msg interface{}) (numSuccess, numFailure
return return
} }
log.Debug("[%X] Broadcast: %v", chId, msg) log.Debug("[%X] BROADCAST: %v", chId, msg)
for _, peer := range sw.peers.List() { for _, peer := range sw.peers.List() {
// XXX XXX Change. // XXX XXX Change.
// success := peer.TrySend(chId, msg) // success := peer.TrySend(chId, msg)

View File

@ -35,7 +35,7 @@ func ValidatorInfoEncoder(o interface{}, w io.Writer, n *int64, err *error) {
WriteBinary(o.(*ValidatorInfo), w, n, err) WriteBinary(o.(*ValidatorInfo), w, n, err)
} }
func ValidatorInfoDecoder(r io.Reader, n *int64, err *error) interface{} { func ValidatorInfoDecoder(r Unreader, n *int64, err *error) interface{} {
return ReadBinary(&ValidatorInfo{}, r, n, err) return ReadBinary(&ValidatorInfo{}, r, n, err)
} }
@ -110,7 +110,7 @@ func (vc validatorCodec) Encode(o interface{}, w io.Writer, n *int64, err *error
WriteBinary(o.(*Validator), w, n, err) WriteBinary(o.(*Validator), w, n, err)
} }
func (vc validatorCodec) Decode(r io.Reader, n *int64, err *error) interface{} { func (vc validatorCodec) Decode(r Unreader, n *int64, err *error) interface{} {
return ReadBinary(&Validator{}, r, n, err) return ReadBinary(&Validator{}, r, n, err)
} }