Remote TypeByte()

This commit is contained in:
Jae Kwon 2015-04-14 15:57:16 -07:00
parent 37ddf3d09e
commit e5d34befde
12 changed files with 148 additions and 266 deletions

View File

@ -8,7 +8,6 @@ import (
// PrivKey is part of PrivAccount and state.PrivValidator. // PrivKey is part of PrivAccount and state.PrivValidator.
type PrivKey interface { type PrivKey interface {
TypeByte() byte
Sign(msg []byte) Signature Sign(msg []byte) Signature
PubKey() PubKey PubKey() PubKey
} }
@ -21,7 +20,7 @@ const (
// for binary.readReflect // for binary.readReflect
var _ = binary.RegisterInterface( var _ = binary.RegisterInterface(
struct{ PrivKey }{}, struct{ PrivKey }{},
binary.ConcreteType{PrivKeyEd25519{}}, binary.ConcreteType{PrivKeyEd25519{}, PrivKeyTypeEd25519},
) )
//------------------------------------- //-------------------------------------
@ -29,8 +28,6 @@ var _ = binary.RegisterInterface(
// Implements PrivKey // Implements PrivKey
type PrivKeyEd25519 []byte type PrivKeyEd25519 []byte
func (privKey PrivKeyEd25519) TypeByte() byte { return PrivKeyTypeEd25519 }
func (privKey PrivKeyEd25519) Sign(msg []byte) Signature { func (privKey PrivKeyEd25519) Sign(msg []byte) Signature {
pubKey := privKey.PubKey().(PubKeyEd25519) pubKey := privKey.PubKey().(PubKeyEd25519)
privKeyBytes := new([64]byte) privKeyBytes := new([64]byte)

View File

@ -9,7 +9,6 @@ import (
// PubKey is part of Account and Validator. // PubKey is part of Account and Validator.
type PubKey interface { type PubKey interface {
TypeByte() byte
IsNil() bool IsNil() bool
Address() []byte Address() []byte
VerifyBytes(msg []byte, sig Signature) bool VerifyBytes(msg []byte, sig Signature) bool
@ -23,7 +22,7 @@ const (
// for binary.readReflect // for binary.readReflect
var _ = binary.RegisterInterface( var _ = binary.RegisterInterface(
struct{ PubKey }{}, struct{ PubKey }{},
binary.ConcreteType{PubKeyEd25519{}}, binary.ConcreteType{PubKeyEd25519{}, PubKeyTypeEd25519},
) )
//------------------------------------- //-------------------------------------
@ -31,8 +30,6 @@ var _ = binary.RegisterInterface(
// Implements PubKey // Implements PubKey
type PubKeyEd25519 []byte type PubKeyEd25519 []byte
func (pubKey PubKeyEd25519) TypeByte() byte { return PubKeyTypeEd25519 }
func (pubKey PubKeyEd25519) IsNil() bool { return false } func (pubKey PubKeyEd25519) IsNil() bool { return false }
// TODO: Or should this just be BinaryRipemd160(key)? (The difference is the TypeByte.) // TODO: Or should this just be BinaryRipemd160(key)? (The difference is the TypeByte.)

View File

@ -9,7 +9,6 @@ import (
// Signature is a part of Txs and consensus Votes. // Signature is a part of Txs and consensus Votes.
type Signature interface { type Signature interface {
TypeByte() byte
} }
// Types of Signature implementations // Types of Signature implementations
@ -20,7 +19,7 @@ const (
// for binary.readReflect // for binary.readReflect
var _ = binary.RegisterInterface( var _ = binary.RegisterInterface(
struct{ Signature }{}, struct{ Signature }{},
binary.ConcreteType{SignatureEd25519{}}, binary.ConcreteType{SignatureEd25519{}, SignatureTypeEd25519},
) )
//------------------------------------- //-------------------------------------
@ -28,8 +27,6 @@ var _ = binary.RegisterInterface(
// Implements Signature // Implements Signature
type SignatureEd25519 []byte type SignatureEd25519 []byte
func (sig SignatureEd25519) TypeByte() byte { return SignatureTypeEd25519 }
func (sig SignatureEd25519) IsNil() bool { return false } func (sig SignatureEd25519) IsNil() bool { return false }
func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 }

View File

@ -1,3 +1,9 @@
### NOTICE
This documentation is out of date.
* 0x00 is reserved as a nil byte for RegisterInterface
* moved TypeByte() into RegisterInterface/ConcreteType
# `tendermint/binary` # `tendermint/binary`
The `binary` submodule encodes primary types and structs into bytes. The `binary` submodule encodes primary types and structs into bytes.
@ -127,4 +133,4 @@ is encoded or decoded directly:
WriteBinary(Dog{}, buf, n, err) // Writes GreeterTypeDog byte WriteBinary(Dog{}, buf, n, err) // Writes GreeterTypeDog byte
dog_ := ReadBinary(Dog{}, buf, n, err) // Expects to read GreeterTypeDog byte dog_ := ReadBinary(Dog{}, buf, n, err) // Expects to read GreeterTypeDog byte
dog := dog_.(Dog) // ok if *err != nil, otherwise dog_ == nil. dog := dog_.(Dog) // ok if *err != nil, otherwise dog_ == nil.
``` ```

View File

@ -17,12 +17,11 @@ type TypeInfo struct {
// If Type is kind reflect.Interface, is registered // If Type is kind reflect.Interface, is registered
IsRegisteredInterface bool IsRegisteredInterface bool
ConcreteTypes map[byte]reflect.Type ByteToType map[byte]reflect.Type
ConcreteTypeBytes map[reflect.Type]byte TypeToByte map[reflect.Type]byte
// If Type is concrete // If Type is concrete
HasTypeByte bool Byte byte
TypeByte byte
// If Type is kind reflect.Struct // If Type is kind reflect.Struct
Fields []StructFieldInfo Fields []StructFieldInfo
@ -47,12 +46,15 @@ func GetTypeFromStructDeclaration(o interface{}) reflect.Type {
return rt.Field(0).Type return rt.Field(0).Type
} }
// If o implements HasTypeByte, returns (true, typeByte) func SetByteForType(typeByte byte, rt reflect.Type) {
func GetTypeByteFromStruct(o interface{}) (hasTypeByte bool, typeByte byte) { typeInfo := GetTypeInfo(rt)
if _, ok := o.(HasTypeByte); ok { if typeInfo.Byte != 0x00 && typeInfo.Byte != typeByte {
return true, o.(HasTypeByte).TypeByte() panic(Fmt("Type %v already registered with type byte %X", rt, typeByte))
} else { }
return false, byte(0x00) typeInfo.Byte = typeByte
// If pointer, we need to set it for the concrete type as well.
if rt.Kind() == reflect.Ptr {
SetByteForType(typeByte, rt.Elem())
} }
} }
@ -65,14 +67,6 @@ const (
rfc2822 = "Mon Jan 02 15:04:05 -0700 2006" rfc2822 = "Mon Jan 02 15:04:05 -0700 2006"
) )
// If a type implements TypeByte, the byte is included
// as the first byte for encoding and decoding.
// This is primarily used to encode interfaces types.
// The interface should be declared with RegisterInterface()
type HasTypeByte interface {
TypeByte() byte
}
// NOTE: do not access typeInfos directly, but call GetTypeInfo() // NOTE: do not access typeInfos directly, but call GetTypeInfo()
var typeInfosMtx sync.Mutex var typeInfosMtx sync.Mutex
var typeInfos = map[reflect.Type]*TypeInfo{} var typeInfos = map[reflect.Type]*TypeInfo{}
@ -82,96 +76,52 @@ func GetTypeInfo(rt reflect.Type) *TypeInfo {
defer typeInfosMtx.Unlock() defer typeInfosMtx.Unlock()
info := typeInfos[rt] info := typeInfos[rt]
if info == nil { if info == nil {
info = &TypeInfo{Type: rt} info = MakeTypeInfo(rt)
RegisterType(info) typeInfos[rt] = info
} }
return info return info
} }
// For use with the RegisterInterface declaration // For use with the RegisterInterface declaration
type ConcreteType struct { type ConcreteType struct {
O interface{} O interface{}
Byte byte
} }
// Must use this to register an interface to properly decode the // Must use this to register an interface to properly decode the
// underlying concrete type. // underlying concrete type.
func RegisterInterface(o interface{}, args ...interface{}) *TypeInfo { func RegisterInterface(o interface{}, ctypes ...ConcreteType) *TypeInfo {
it := GetTypeFromStructDeclaration(o) it := GetTypeFromStructDeclaration(o)
if it.Kind() != reflect.Interface { if it.Kind() != reflect.Interface {
panic("RegisterInterface expects an interface") panic("RegisterInterface expects an interface")
} }
concreteTypes := make(map[byte]reflect.Type, 0) toType := make(map[byte]reflect.Type, 0)
concreteTypesReversed := make(map[reflect.Type]byte, 0) toByte := make(map[reflect.Type]byte, 0)
for _, arg := range args { for _, ctype := range ctypes {
switch arg.(type) { crt := reflect.TypeOf(ctype.O)
case ConcreteType: typeByte := ctype.Byte
concreteTypeInfo := arg.(ConcreteType) SetByteForType(typeByte, crt)
concreteType := reflect.TypeOf(concreteTypeInfo.O) if typeByte == 0x00 {
hasTypeByte, typeByte := GetTypeByteFromStruct(concreteTypeInfo.O) panic(Fmt("Byte of 0x00 is reserved for nil (%v)", ctype))
//fmt.Println(Fmt("HasTypeByte: %v typeByte: %X type: %X", hasTypeByte, typeByte, concreteType))
if !hasTypeByte {
panic(Fmt("Expected concrete type %v to implement HasTypeByte", concreteType))
}
if typeByte == 0x00 {
panic(Fmt("TypeByte of 0x00 is reserved for nil (%v)", concreteType))
}
if concreteTypes[typeByte] != nil {
panic(Fmt("Duplicate TypeByte for type %v and %v", concreteType, concreteTypes[typeByte]))
}
concreteTypes[typeByte] = concreteType
concreteTypesReversed[concreteType] = typeByte
default:
panic(Fmt("Unexpected argument type %v", reflect.TypeOf(arg)))
} }
if toType[typeByte] != nil {
panic(Fmt("Duplicate Byte for type %v and %v", ctype, toType[typeByte]))
}
toType[typeByte] = crt
toByte[crt] = typeByte
} }
typeInfo := &TypeInfo{ typeInfo := &TypeInfo{
Type: it, Type: it,
IsRegisteredInterface: true, IsRegisteredInterface: true,
ConcreteTypes: concreteTypes, ByteToType: toType,
ConcreteTypeBytes: concreteTypesReversed, TypeToByte: toByte,
} }
typeInfos[it] = typeInfo typeInfos[it] = typeInfo
return typeInfo return typeInfo
} }
// Registers and possibly modifies the TypeInfo. func MakeTypeInfo(rt reflect.Type) *TypeInfo {
// NOTE: not goroutine safe, so only call upon program init. info := &TypeInfo{Type: rt}
func RegisterType(info *TypeInfo) *TypeInfo {
// Also register the dereferenced struct if info.Type is a pointer.
// Or, if info.Type is not a pointer, register the pointer.
var rt, ptrRt reflect.Type
if info.Type.Kind() == reflect.Ptr {
rt, ptrRt = info.Type.Elem(), info.Type
} else {
rt, ptrRt = info.Type, reflect.PtrTo(info.Type)
}
// Register the type info
typeInfos[rt] = info
typeInfos[ptrRt] = info
// See if the type implements HasTypeByte
if rt.Kind() != reflect.Interface &&
rt.Implements(reflect.TypeOf((*HasTypeByte)(nil)).Elem()) {
zero := reflect.Zero(rt)
typeByte := zero.Interface().(HasTypeByte).TypeByte()
if info.HasTypeByte && info.TypeByte != typeByte {
panic(Fmt("Type %v expected TypeByte of %X", rt, typeByte))
} else {
info.HasTypeByte = true
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("Type %v expected TypeByte of %X", ptrRt, typeByte))
} else {
info.HasTypeByte = true
info.TypeByte = typeByte
}
}
// If struct, register field name options // If struct, register field name options
if rt.Kind() == reflect.Struct { if rt.Kind() == reflect.Struct {
@ -218,7 +168,7 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
if typeByte == 0x00 { if typeByte == 0x00 {
return // nil return // nil
} }
crt, ok := typeInfo.ConcreteTypes[typeByte] crt, ok := typeInfo.ByteToType[typeByte]
if !ok { if !ok {
*err = errors.New(Fmt("Unexpected type byte %X for type %v", typeByte, crt)) *err = errors.New(Fmt("Unexpected type byte %X for type %v", typeByte, crt))
return return
@ -247,17 +197,17 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
// Dereference pointer // Dereference pointer
rv, rt = rv.Elem(), rt.Elem() rv, rt = rv.Elem(), rt.Elem()
typeInfo = GetTypeInfo(rt) typeInfo = GetTypeInfo(rt)
if typeInfo.HasTypeByte { if typeInfo.Byte != 0x00 {
r = NewPrefixedReader([]byte{typeByte}, r) r = NewPrefixedReader([]byte{typeByte}, r)
} }
// continue... // continue...
} }
// Read TypeByte prefix // Read Byte prefix
if typeInfo.HasTypeByte { if typeInfo.Byte != 0x00 {
typeByte := ReadByte(r, n, err) typeByte := ReadByte(r, n, err)
if typeByte != typeInfo.TypeByte { if typeByte != typeInfo.Byte {
*err = errors.New(Fmt("Expected TypeByte of %X but got %X", typeInfo.TypeByte, typeByte)) *err = errors.New(Fmt("Expected Byte of %X but got %X", typeInfo.Byte, typeByte))
return return
} }
} }
@ -384,7 +334,7 @@ func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err
if typeInfo.IsRegisteredInterface { if typeInfo.IsRegisteredInterface {
// See if the crt is registered. // See if the crt is registered.
// If so, we're more restrictive. // If so, we're more restrictive.
_, ok := typeInfo.ConcreteTypeBytes[crt] _, ok := typeInfo.TypeToByte[crt]
if !ok { if !ok {
switch crt.Kind() { switch crt.Kind() {
case reflect.Ptr: case reflect.Ptr:
@ -408,11 +358,12 @@ func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err
if rt.Kind() == reflect.Ptr { if rt.Kind() == reflect.Ptr {
// Dereference pointer // Dereference pointer
rv, rt = rv.Elem(), rt.Elem() rv, rt = rv.Elem(), rt.Elem()
typeInfo = GetTypeInfo(rt)
if !rv.IsValid() { if !rv.IsValid() {
WriteByte(0x00, w, n, err) WriteByte(0x00, w, n, err)
return return
} }
if !typeInfo.HasTypeByte { if typeInfo.Byte == 0x00 {
WriteByte(0x01, w, n, err) WriteByte(0x01, w, n, err)
// continue... // continue...
} else { } else {
@ -421,8 +372,8 @@ func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err
} }
// Write type byte // Write type byte
if typeInfo.HasTypeByte { if typeInfo.Byte != 0x00 {
WriteByte(typeInfo.TypeByte, w, n, err) WriteByte(typeInfo.Byte, w, n, err)
} }
// All other types // All other types
@ -507,14 +458,14 @@ func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func readTypeByteJSON(o interface{}) (typeByte byte, rest interface{}, err error) { func readByteJSON(o interface{}) (typeByte byte, rest interface{}, err error) {
oSlice, ok := o.([]interface{}) oSlice, ok := o.([]interface{})
if !ok { if !ok {
err = errors.New(Fmt("Expected type [TypeByte,?] but got type %v", reflect.TypeOf(o))) err = errors.New(Fmt("Expected type [Byte,?] but got type %v", reflect.TypeOf(o)))
return return
} }
if len(oSlice) != 2 { if len(oSlice) != 2 {
err = errors.New(Fmt("Expected [TypeByte,?] len 2 but got len %v", len(oSlice))) err = errors.New(Fmt("Expected [Byte,?] len 2 but got len %v", len(oSlice)))
return return
} }
typeByte_, ok := oSlice[0].(float64) typeByte_, ok := oSlice[0].(float64)
@ -537,14 +488,14 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro
if o == nil { if o == nil {
return // nil return // nil
} }
typeByte, _, err_ := readTypeByteJSON(o) typeByte, _, err_ := readByteJSON(o)
if err_ != nil { if err_ != nil {
*err = err_ *err = err_
return return
} }
crt, ok := typeInfo.ConcreteTypes[typeByte] crt, ok := typeInfo.ByteToType[typeByte]
if !ok { if !ok {
*err = errors.New(Fmt("TypeByte %X not registered for interface %v", typeByte, rt)) *err = errors.New(Fmt("Byte %X not registered for interface %v", typeByte, rt))
return return
} }
crv := reflect.New(crt).Elem() crv := reflect.New(crt).Elem()
@ -565,18 +516,19 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro
} }
// Dereference pointer // Dereference pointer
rv, rt = rv.Elem(), rt.Elem() rv, rt = rv.Elem(), rt.Elem()
typeInfo = GetTypeInfo(rt)
// continue... // continue...
} }
// Read TypeByte prefix // Read Byte prefix
if typeInfo.HasTypeByte { if typeInfo.Byte != 0x00 {
typeByte, rest, err_ := readTypeByteJSON(o) typeByte, rest, err_ := readByteJSON(o)
if err_ != nil { if err_ != nil {
*err = err_ *err = err_
return return
} }
if typeByte != typeInfo.TypeByte { if typeByte != typeInfo.Byte {
*err = errors.New(Fmt("Expected TypeByte of %X but got %X", typeInfo.TypeByte, byte(typeByte))) *err = errors.New(Fmt("Expected Byte of %X but got %X", typeInfo.Byte, byte(typeByte)))
return return
} }
o = rest o = rest
@ -697,6 +649,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro
} }
func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) { func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) {
log.Debug(Fmt("writeReflectJSON(%v, %v, %v, %v, %v)", rv, rt, w, n, err))
// Get typeInfo // Get typeInfo
typeInfo := GetTypeInfo(rt) typeInfo := GetTypeInfo(rt)
@ -712,7 +665,7 @@ func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64,
if typeInfo.IsRegisteredInterface { if typeInfo.IsRegisteredInterface {
// See if the crt is registered. // See if the crt is registered.
// If so, we're more restrictive. // If so, we're more restrictive.
_, ok := typeInfo.ConcreteTypeBytes[crt] _, ok := typeInfo.TypeToByte[crt]
if !ok { if !ok {
switch crt.Kind() { switch crt.Kind() {
case reflect.Ptr: case reflect.Ptr:
@ -736,6 +689,7 @@ func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64,
if rt.Kind() == reflect.Ptr { if rt.Kind() == reflect.Ptr {
// Dereference pointer // Dereference pointer
rv, rt = rv.Elem(), rt.Elem() rv, rt = rv.Elem(), rt.Elem()
typeInfo = GetTypeInfo(rt)
if !rv.IsValid() { if !rv.IsValid() {
WriteTo([]byte("null"), w, n, err) WriteTo([]byte("null"), w, n, err)
return return
@ -743,9 +697,9 @@ func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64,
// continue... // continue...
} }
// Write TypeByte // Write Byte
if typeInfo.HasTypeByte { if typeInfo.Byte != 0x00 {
WriteTo([]byte(Fmt("[%v,", typeInfo.TypeByte)), w, n, err) WriteTo([]byte(Fmt("[%v,", typeInfo.Byte)), w, n, err)
defer WriteTo([]byte("]"), w, n, err) defer WriteTo([]byte("]"), w, n, err)
} }

View File

@ -30,33 +30,25 @@ type Cat struct {
SimpleStruct SimpleStruct
} }
func (cat Cat) TypeByte() byte { return AnimalTypeCat }
// Implements Animal // Implements Animal
type Dog struct { type Dog struct {
SimpleStruct SimpleStruct
} }
func (dog Dog) TypeByte() byte { return AnimalTypeDog }
// Implements Animal // Implements Animal
type Snake []byte type Snake []byte
func (snake Snake) TypeByte() byte { return AnimalTypeSnake }
// Implements Animal // Implements Animal
type Viper struct { type Viper struct {
Bytes []byte Bytes []byte
} }
func (viper *Viper) TypeByte() byte { return AnimalTypeViper }
var _ = RegisterInterface( var _ = RegisterInterface(
struct{ Animal }{}, struct{ Animal }{},
ConcreteType{Cat{}}, ConcreteType{Cat{}, AnimalTypeCat},
ConcreteType{Dog{}}, ConcreteType{Dog{}, AnimalTypeDog},
ConcreteType{Snake{}}, ConcreteType{Snake{}, AnimalTypeSnake},
ConcreteType{&Viper{}}, ConcreteType{&Viper{}, AnimalTypeViper},
) )
func TestAnimalInterface(t *testing.T) { func TestAnimalInterface(t *testing.T) {

View File

@ -116,15 +116,15 @@ func (bcR *BlockchainReactor) RemovePeer(peer *p2p.Peer, reason interface{}) {
// Implements Reactor // Implements Reactor
func (bcR *BlockchainReactor) Receive(chId byte, src *p2p.Peer, msgBytes []byte) { func (bcR *BlockchainReactor) Receive(chId byte, src *p2p.Peer, msgBytes []byte) {
_, msg_, err := DecodeMessage(msgBytes) _, msg, err := DecodeMessage(msgBytes)
if err != nil { if err != nil {
log.Warn("Error decoding message", "error", err) log.Warn("Error decoding message", "error", err)
return return
} }
log.Info("Received message", "msg", msg_) log.Info("Received message", "msg", msg)
switch msg := msg_.(type) { switch msg := msg.(type) {
case bcBlockRequestMessage: case bcBlockRequestMessage:
// Got a request for a block. Respond with block if we have it. // Got a request for a block. Respond with block if we have it.
block := bcR.store.LoadBlock(msg.Height) block := bcR.store.LoadBlock(msg.Height)
@ -251,28 +251,25 @@ func (bcR *BlockchainReactor) SetEventSwitch(evsw *events.EventSwitch) {
// Messages // Messages
const ( const (
msgTypeUnknown = byte(0x00)
msgTypeBlockRequest = byte(0x10) msgTypeBlockRequest = byte(0x10)
msgTypeBlockResponse = byte(0x11) msgTypeBlockResponse = byte(0x11)
msgTypePeerStatus = byte(0x20) msgTypePeerStatus = byte(0x20)
) )
// TODO: check for unnecessary extra bytes at the end. type BlockchainMessage interface{}
func DecodeMessage(bz []byte) (msgType byte, msg interface{}, err error) {
n := new(int64) var _ = binary.RegisterInterface(
struct{ BlockchainMessage }{},
binary.ConcreteType{bcBlockRequestMessage{}, msgTypeBlockRequest},
binary.ConcreteType{bcBlockResponseMessage{}, msgTypeBlockResponse},
binary.ConcreteType{bcPeerStatusMessage{}, msgTypePeerStatus},
)
func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) {
msgType = bz[0] msgType = bz[0]
n := new(int64)
r := bytes.NewReader(bz) r := bytes.NewReader(bz)
switch msgType { msg = binary.ReadBinary(&msg, r, n, &err)
case msgTypeBlockRequest:
msg = binary.ReadBinary(bcBlockRequestMessage{}, r, n, &err)
case msgTypeBlockResponse:
msg = binary.ReadBinary(bcBlockResponseMessage{}, r, n, &err)
case msgTypePeerStatus:
msg = binary.ReadBinary(bcPeerStatusMessage{}, r, n, &err)
default:
log.Warn(Fmt("Ignoring unknown message %X", bz))
msg = nil
}
return return
} }
@ -282,8 +279,6 @@ type bcBlockRequestMessage struct {
Height uint Height uint
} }
func (m bcBlockRequestMessage) TypeByte() byte { return msgTypeBlockRequest }
func (m bcBlockRequestMessage) String() string { func (m bcBlockRequestMessage) String() string {
return fmt.Sprintf("[bcBlockRequestMessage %v]", m.Height) return fmt.Sprintf("[bcBlockRequestMessage %v]", m.Height)
} }
@ -294,8 +289,6 @@ type bcBlockResponseMessage struct {
Block *types.Block Block *types.Block
} }
func (m bcBlockResponseMessage) TypeByte() byte { return msgTypeBlockResponse }
func (m bcBlockResponseMessage) String() string { func (m bcBlockResponseMessage) String() string {
return fmt.Sprintf("[bcBlockResponseMessage %v]", m.Block.Height) return fmt.Sprintf("[bcBlockResponseMessage %v]", m.Block.Height)
} }
@ -306,8 +299,6 @@ type bcPeerStatusMessage struct {
Height uint Height uint
} }
func (m bcPeerStatusMessage) TypeByte() byte { return msgTypePeerStatus }
func (m bcPeerStatusMessage) String() string { func (m bcPeerStatusMessage) String() string {
return fmt.Sprintf("[bcPeerStatusMessage %v]", m.Height) return fmt.Sprintf("[bcPeerStatusMessage %v]", m.Height)
} }

View File

@ -17,29 +17,22 @@ type NoncedCommand struct {
type Command interface{} type Command interface{}
const (
commandTypeRunProcess = 0x01
commandTypeStopProcess = 0x02
commandTypeListProcesses = 0x03
commandTypeServeFile = 0x04
)
// for binary.readReflect // for binary.readReflect
var _ = binary.RegisterInterface( var _ = binary.RegisterInterface(
struct{ Command }{}, struct{ Command }{},
binary.ConcreteType{CommandRunProcess{}}, binary.ConcreteType{CommandRunProcess{}, commandTypeRunProcess},
binary.ConcreteType{CommandStopProcess{}}, binary.ConcreteType{CommandStopProcess{}, commandTypeStopProcess},
binary.ConcreteType{CommandListProcesses{}}, binary.ConcreteType{CommandListProcesses{}, commandTypeListProcesses},
binary.ConcreteType{CommandServeFile{}}, binary.ConcreteType{CommandServeFile{}, commandTypeServeFile},
) )
const (
typeByteRunProcess = 0x01
typeByteStopProcess = 0x02
typeByteListProcesses = 0x03
typeByteServeFile = 0x04
)
// TODO: This is actually not cleaner than a method call.
// In fact, this is stupid.
func (_ CommandRunProcess) TypeByte() byte { return typeByteRunProcess }
func (_ CommandStopProcess) TypeByte() byte { return typeByteStopProcess }
func (_ CommandListProcesses) TypeByte() byte { return typeByteListProcesses }
func (_ CommandServeFile) TypeByte() byte { return typeByteServeFile }
type CommandRunProcess struct { type CommandRunProcess struct {
Wait bool Wait bool
Label string Label string

View File

@ -763,31 +763,24 @@ const (
msgTypeHasVote = byte(0x14) msgTypeHasVote = byte(0x14)
) )
type ConsensusMessage interface{}
var _ = binary.RegisterInterface(
struct{ ConsensusMessage }{},
binary.ConcreteType{NewRoundStepMessage{}, msgTypeNewRoundStep},
binary.ConcreteType{CommitStepMessage{}, msgTypeCommitStep},
binary.ConcreteType{ProposalMessage{}, msgTypeProposal},
binary.ConcreteType{PartMessage{}, msgTypePart},
binary.ConcreteType{VoteMessage{}, msgTypeVote},
binary.ConcreteType{HasVoteMessage{}, msgTypeHasVote},
)
// 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{}, err error) { func DecodeMessage(bz []byte) (msgType byte, msg ConsensusMessage, err error) {
n := new(int64)
// log.Debug(Fmt("decoding msg bytes: %X", bz))
msgType = bz[0] msgType = bz[0]
n := new(int64)
r := bytes.NewReader(bz) r := bytes.NewReader(bz)
switch msgType { msg = binary.ReadBinary(&msg, r, n, &err)
// Messages for communicating state changes
case msgTypeNewRoundStep:
msg = binary.ReadBinary(&NewRoundStepMessage{}, r, n, &err)
case msgTypeCommitStep:
msg = binary.ReadBinary(&CommitStepMessage{}, r, n, &err)
// Messages of data
case msgTypeProposal:
msg = binary.ReadBinary(&ProposalMessage{}, r, n, &err)
case msgTypePart:
msg = binary.ReadBinary(&PartMessage{}, r, n, &err)
case msgTypeVote:
msg = binary.ReadBinary(&VoteMessage{}, r, n, &err)
case msgTypeHasVote:
msg = binary.ReadBinary(&HasVoteMessage{}, r, n, &err)
default:
log.Warn(Fmt("Ignoring unknown message %X", bz))
msg = nil
}
return return
} }
@ -800,8 +793,6 @@ type NewRoundStepMessage struct {
SecondsSinceStartTime uint SecondsSinceStartTime uint
} }
func (m *NewRoundStepMessage) TypeByte() byte { return msgTypeNewRoundStep }
func (m *NewRoundStepMessage) String() string { func (m *NewRoundStepMessage) String() string {
return fmt.Sprintf("[NewRoundStep H:%v R:%v S:%v]", m.Height, m.Round, m.Step) return fmt.Sprintf("[NewRoundStep H:%v R:%v S:%v]", m.Height, m.Round, m.Step)
} }
@ -814,8 +805,6 @@ type CommitStepMessage struct {
BlockBitArray BitArray BlockBitArray BitArray
} }
func (m *CommitStepMessage) TypeByte() byte { return msgTypeCommitStep }
func (m *CommitStepMessage) String() string { func (m *CommitStepMessage) String() string {
return fmt.Sprintf("[CommitStep H:%v BP:%v BA:%v]", m.Height, m.BlockParts, m.BlockBitArray) return fmt.Sprintf("[CommitStep H:%v BP:%v BA:%v]", m.Height, m.BlockParts, m.BlockBitArray)
} }
@ -826,8 +815,6 @@ type ProposalMessage struct {
Proposal *Proposal Proposal *Proposal
} }
func (m *ProposalMessage) TypeByte() byte { return msgTypeProposal }
func (m *ProposalMessage) String() string { func (m *ProposalMessage) String() string {
return fmt.Sprintf("[Proposal %v]", m.Proposal) return fmt.Sprintf("[Proposal %v]", m.Proposal)
} }
@ -846,8 +833,6 @@ type PartMessage struct {
Part *types.Part Part *types.Part
} }
func (m *PartMessage) TypeByte() byte { return msgTypePart }
func (m *PartMessage) String() string { func (m *PartMessage) String() string {
return fmt.Sprintf("[Part H:%v R:%v T:%X P:%v]", m.Height, m.Round, m.Type, m.Part) return fmt.Sprintf("[Part H:%v R:%v T:%X P:%v]", m.Height, m.Round, m.Type, m.Part)
} }
@ -859,8 +844,6 @@ type VoteMessage struct {
Vote *types.Vote Vote *types.Vote
} }
func (m *VoteMessage) TypeByte() byte { return msgTypeVote }
func (m *VoteMessage) String() string { func (m *VoteMessage) String() string {
return fmt.Sprintf("[Vote VI:%v V:%v]", m.ValidatorIndex, m.Vote) return fmt.Sprintf("[Vote VI:%v V:%v]", m.ValidatorIndex, m.Vote)
} }
@ -874,8 +857,6 @@ type HasVoteMessage struct {
Index uint Index uint
} }
func (m *HasVoteMessage) TypeByte() byte { return msgTypeHasVote }
func (m *HasVoteMessage) String() string { func (m *HasVoteMessage) String() string {
return fmt.Sprintf("[HasVote %v/%v T:%X]", m.Height, m.Round, m.Type) return fmt.Sprintf("[HasVote %v/%v T:%X]", m.Height, m.Round, m.Type)
} }

View File

@ -6,7 +6,6 @@ import (
"sync/atomic" "sync/atomic"
"github.com/tendermint/tendermint/binary" "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/events" "github.com/tendermint/tendermint/events"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
@ -123,22 +122,21 @@ func (memR *MempoolReactor) SetEventSwitch(evsw *events.EventSwitch) {
// Messages // Messages
const ( const (
msgTypeUnknown = byte(0x00) msgTypeTx = byte(0x01)
msgTypeTx = byte(0x01)
) )
// TODO: check for unnecessary extra bytes at the end. type MempoolMessage interface{}
func DecodeMessage(bz []byte) (msgType byte, msg interface{}, err error) {
n := new(int64) var _ = binary.RegisterInterface(
struct{ MempoolMessage }{},
binary.ConcreteType{TxMessage{}, msgTypeTx},
)
func DecodeMessage(bz []byte) (msgType byte, msg MempoolMessage, err error) {
msgType = bz[0] msgType = bz[0]
n := new(int64)
r := bytes.NewReader(bz) r := bytes.NewReader(bz)
switch msgType { msg = binary.ReadBinary(&msg, r, n, &err)
case msgTypeTx:
msg = binary.ReadBinary(&TxMessage{}, r, n, &err)
default:
log.Warn(Fmt("Ignoring unknown message %X", bz))
msg = nil
}
return return
} }
@ -148,8 +146,6 @@ type TxMessage struct {
Tx types.Tx Tx types.Tx
} }
func (m *TxMessage) TypeByte() byte { return msgTypeTx }
func (m *TxMessage) String() string { func (m *TxMessage) String() string {
return fmt.Sprintf("[TxMessage %v]", m.Tx) return fmt.Sprintf("[TxMessage %v]", m.Tx)
} }

View File

@ -92,7 +92,7 @@ func (pexR *PEXReactor) RemovePeer(peer *Peer, reason interface{}) {
func (pexR *PEXReactor) Receive(chId byte, src *Peer, msgBytes []byte) { func (pexR *PEXReactor) Receive(chId byte, src *Peer, msgBytes []byte) {
// decode message // decode message
msg, err := DecodeMessage(msgBytes) _, msg, err := DecodeMessage(msgBytes)
if err != nil { if err != nil {
log.Warn("Error decoding message", "error", err) log.Warn("Error decoding message", "error", err)
return return
@ -219,29 +219,25 @@ func (pexR *PEXReactor) SetEventSwitch(evsw *events.EventSwitch) {
// Messages // Messages
const ( const (
msgTypeUnknown = byte(0x00)
msgTypeRequest = byte(0x01) msgTypeRequest = byte(0x01)
msgTypeAddrs = byte(0x02) msgTypeAddrs = byte(0x02)
msgTypeHandshake = byte(0x03) msgTypeHandshake = byte(0x03)
) )
// TODO: check for unnecessary extra bytes at the end. type PexMessage interface{}
func DecodeMessage(bz []byte) (msg interface{}, err error) {
var _ = binary.RegisterInterface(
struct{ PexMessage }{},
binary.ConcreteType{pexHandshakeMessage{}, msgTypeHandshake},
binary.ConcreteType{pexRequestMessage{}, msgTypeRequest},
binary.ConcreteType{pexAddrsMessage{}, msgTypeAddrs},
)
func DecodeMessage(bz []byte) (msgType byte, msg PexMessage, err error) {
msgType = bz[0]
n := new(int64) n := new(int64)
msgType := bz[0]
r := bytes.NewReader(bz) r := bytes.NewReader(bz)
// log.Debug(Fmt("decoding msg bytes: %X", bz)) msg = binary.ReadBinary(&msg, r, n, &err)
switch msgType {
case msgTypeHandshake:
msg = binary.ReadBinary(&pexHandshakeMessage{}, r, n, &err)
case msgTypeRequest:
msg = &pexRequestMessage{}
case msgTypeAddrs:
msg = binary.ReadBinary(&pexAddrsMessage{}, r, n, &err)
default:
log.Warn(Fmt("Ignoring unknown message %X", bz))
msg = nil
}
return return
} }
@ -252,8 +248,6 @@ type pexHandshakeMessage struct {
Network string Network string
} }
func (m *pexHandshakeMessage) TypeByte() byte { return msgTypeHandshake }
func (m *pexHandshakeMessage) String() string { func (m *pexHandshakeMessage) String() string {
return "[pexHandshake]" return "[pexHandshake]"
} }
@ -264,8 +258,6 @@ A pexRequestMessage requests additional peer addresses.
type pexRequestMessage struct { type pexRequestMessage struct {
} }
func (m *pexRequestMessage) TypeByte() byte { return msgTypeRequest }
func (m *pexRequestMessage) String() string { func (m *pexRequestMessage) String() string {
return "[pexRequest]" return "[pexRequest]"
} }
@ -277,8 +269,6 @@ type pexAddrsMessage struct {
Addrs []*NetAddress Addrs []*NetAddress
} }
func (m *pexAddrsMessage) TypeByte() byte { return msgTypeAddrs }
func (m *pexAddrsMessage) String() string { func (m *pexAddrsMessage) String() string {
return fmt.Sprintf("[pexAddrs %v]", m.Addrs) return fmt.Sprintf("[pexAddrs %v]", m.Addrs)
} }

View File

@ -61,12 +61,12 @@ const (
// for binary.readReflect // for binary.readReflect
var _ = binary.RegisterInterface( var _ = binary.RegisterInterface(
struct{ Tx }{}, struct{ Tx }{},
binary.ConcreteType{&SendTx{}}, binary.ConcreteType{&SendTx{}, TxTypeSend},
binary.ConcreteType{&CallTx{}}, binary.ConcreteType{&CallTx{}, TxTypeCall},
binary.ConcreteType{&BondTx{}}, binary.ConcreteType{&BondTx{}, TxTypeBond},
binary.ConcreteType{&UnbondTx{}}, binary.ConcreteType{&UnbondTx{}, TxTypeUnbond},
binary.ConcreteType{&RebondTx{}}, binary.ConcreteType{&RebondTx{}, TxTypeRebond},
binary.ConcreteType{&DupeoutTx{}}, binary.ConcreteType{&DupeoutTx{}, TxTypeDupeout},
) )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -132,8 +132,6 @@ type SendTx struct {
Outputs []*TxOutput Outputs []*TxOutput
} }
func (tx *SendTx) TypeByte() byte { return TxTypeSend }
func (tx *SendTx) WriteSignBytes(w io.Writer, n *int64, err *error) { func (tx *SendTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
binary.WriteUvarint(uint(len(tx.Inputs)), w, n, err) binary.WriteUvarint(uint(len(tx.Inputs)), w, n, err)
for _, in := range tx.Inputs { for _, in := range tx.Inputs {
@ -159,8 +157,6 @@ type CallTx struct {
Data []byte Data []byte
} }
func (tx *CallTx) TypeByte() byte { return TxTypeCall }
func (tx *CallTx) WriteSignBytes(w io.Writer, n *int64, err *error) { func (tx *CallTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
tx.Input.WriteSignBytes(w, n, err) tx.Input.WriteSignBytes(w, n, err)
binary.WriteByteSlice(tx.Address, w, n, err) binary.WriteByteSlice(tx.Address, w, n, err)
@ -181,8 +177,6 @@ type BondTx struct {
UnbondTo []*TxOutput UnbondTo []*TxOutput
} }
func (tx *BondTx) TypeByte() byte { return TxTypeBond }
func (tx *BondTx) WriteSignBytes(w io.Writer, n *int64, err *error) { func (tx *BondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
binary.WriteBinary(tx.PubKey, w, n, err) binary.WriteBinary(tx.PubKey, w, n, err)
binary.WriteUvarint(uint(len(tx.Inputs)), w, n, err) binary.WriteUvarint(uint(len(tx.Inputs)), w, n, err)
@ -207,8 +201,6 @@ type UnbondTx struct {
Signature account.SignatureEd25519 Signature account.SignatureEd25519
} }
func (tx *UnbondTx) TypeByte() byte { return TxTypeUnbond }
func (tx *UnbondTx) WriteSignBytes(w io.Writer, n *int64, err *error) { func (tx *UnbondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
binary.WriteByteSlice(tx.Address, w, n, err) binary.WriteByteSlice(tx.Address, w, n, err)
binary.WriteUvarint(tx.Height, w, n, err) binary.WriteUvarint(tx.Height, w, n, err)
@ -226,8 +218,6 @@ type RebondTx struct {
Signature account.SignatureEd25519 Signature account.SignatureEd25519
} }
func (tx *RebondTx) TypeByte() byte { return TxTypeRebond }
func (tx *RebondTx) WriteSignBytes(w io.Writer, n *int64, err *error) { func (tx *RebondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
binary.WriteByteSlice(tx.Address, w, n, err) binary.WriteByteSlice(tx.Address, w, n, err)
binary.WriteUvarint(tx.Height, w, n, err) binary.WriteUvarint(tx.Height, w, n, err)
@ -245,8 +235,6 @@ type DupeoutTx struct {
VoteB Vote VoteB Vote
} }
func (tx *DupeoutTx) TypeByte() byte { return TxTypeDupeout }
func (tx *DupeoutTx) WriteSignBytes(w io.Writer, n *int64, err *error) { func (tx *DupeoutTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
panic("DupeoutTx has no sign bytes") panic("DupeoutTx has no sign bytes")
} }