mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-14 13:51:21 +00:00
Support nil pointers for Binary.
If the thing does not already have a typebyte declared, a fake one will be given (0x01). A TypeByte of 0x00 is reserved for nil things. No nil-dogs.
This commit is contained in:
@ -2,7 +2,6 @@ package account
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/tendermint/ed25519"
|
"github.com/tendermint/ed25519"
|
||||||
"github.com/tendermint/tendermint/binary"
|
"github.com/tendermint/tendermint/binary"
|
||||||
. "github.com/tendermint/tendermint/common"
|
. "github.com/tendermint/tendermint/common"
|
||||||
@ -18,47 +17,17 @@ type PubKey interface {
|
|||||||
|
|
||||||
// Types of PubKey implementations
|
// Types of PubKey implementations
|
||||||
const (
|
const (
|
||||||
PubKeyTypeNil = byte(0x00)
|
|
||||||
PubKeyTypeEd25519 = byte(0x01)
|
PubKeyTypeEd25519 = byte(0x01)
|
||||||
)
|
)
|
||||||
|
|
||||||
// for binary.readReflect
|
// for binary.readReflect
|
||||||
var _ = binary.RegisterInterface(
|
var _ = binary.RegisterInterface(
|
||||||
struct{ PubKey }{},
|
struct{ PubKey }{},
|
||||||
binary.ConcreteType{PubKeyNil{}},
|
|
||||||
binary.ConcreteType{PubKeyEd25519{}},
|
binary.ConcreteType{PubKeyEd25519{}},
|
||||||
)
|
)
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
// Implements PubKey
|
|
||||||
type PubKeyNil struct{}
|
|
||||||
|
|
||||||
func (key PubKeyNil) TypeByte() byte { return PubKeyTypeNil }
|
|
||||||
|
|
||||||
func (key PubKeyNil) IsNil() bool { return true }
|
|
||||||
|
|
||||||
func (key PubKeyNil) Address() []byte {
|
|
||||||
panic("PubKeyNil has no address")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (key PubKeyNil) VerifyBytes(msg []byte, sig_ Signature) bool {
|
|
||||||
panic("PubKeyNil cannot verify messages")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (key PubKeyEd25519) ValidateBasic() error {
|
|
||||||
if len(key) != ed25519.PublicKeySize {
|
|
||||||
return errors.New("Invalid PubKeyEd25519 key size")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (key PubKeyNil) String() string {
|
|
||||||
return "PubKeyNil{}"
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------
|
|
||||||
|
|
||||||
// Implements PubKey
|
// Implements PubKey
|
||||||
type PubKeyEd25519 []byte
|
type PubKeyEd25519 []byte
|
||||||
|
|
||||||
@ -81,6 +50,13 @@ func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
|
|||||||
return ed25519.Verify(pubKeyBytes, msg, sigBytes)
|
return ed25519.Verify(pubKeyBytes, msg, sigBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pubKey PubKeyEd25519) ValidateBasic() error {
|
||||||
|
if len(pubKey) != ed25519.PublicKeySize {
|
||||||
|
return errors.New("Invalid PubKeyEd25519 key size")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (pubKey PubKeyEd25519) String() string {
|
func (pubKey PubKeyEd25519) String() string {
|
||||||
return Fmt("PubKeyEd25519{%X}", []byte(pubKey))
|
return Fmt("PubKeyEd25519{%X}", []byte(pubKey))
|
||||||
}
|
}
|
||||||
|
@ -14,30 +14,17 @@ type Signature interface {
|
|||||||
|
|
||||||
// Types of Signature implementations
|
// Types of Signature implementations
|
||||||
const (
|
const (
|
||||||
SignatureTypeNil = byte(0x00)
|
|
||||||
SignatureTypeEd25519 = byte(0x01)
|
SignatureTypeEd25519 = byte(0x01)
|
||||||
)
|
)
|
||||||
|
|
||||||
// for binary.readReflect
|
// for binary.readReflect
|
||||||
var _ = binary.RegisterInterface(
|
var _ = binary.RegisterInterface(
|
||||||
struct{ Signature }{},
|
struct{ Signature }{},
|
||||||
binary.ConcreteType{SignatureNil{}},
|
|
||||||
binary.ConcreteType{SignatureEd25519{}},
|
binary.ConcreteType{SignatureEd25519{}},
|
||||||
)
|
)
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
// Implements Signature
|
|
||||||
type SignatureNil struct{}
|
|
||||||
|
|
||||||
func (sig SignatureNil) TypeByte() byte { return SignatureTypeNil }
|
|
||||||
|
|
||||||
func (sig SignatureNil) IsNil() bool { return true }
|
|
||||||
|
|
||||||
func (sig SignatureNil) String() string { return "SignatureNil{}" }
|
|
||||||
|
|
||||||
//-------------------------------------
|
|
||||||
|
|
||||||
// Implements Signature
|
// Implements Signature
|
||||||
type SignatureEd25519 []byte
|
type SignatureEd25519 []byte
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} {
|
|||||||
func WriteBinary(o interface{}, w io.Writer, n *int64, err *error) {
|
func WriteBinary(o interface{}, w io.Writer, n *int64, err *error) {
|
||||||
rv := reflect.ValueOf(o)
|
rv := reflect.ValueOf(o)
|
||||||
rt := reflect.TypeOf(o)
|
rt := reflect.TypeOf(o)
|
||||||
|
if rv.Kind() == reflect.Ptr {
|
||||||
|
rv, rt = rv.Elem(), rt.Elem()
|
||||||
|
}
|
||||||
writeReflect(rv, rt, w, n, err)
|
writeReflect(rv, rt, w, n, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +52,9 @@ func ReadJSONFromObject(o interface{}, object interface{}, err *error) interface
|
|||||||
func WriteJSON(o interface{}, w io.Writer, n *int64, err *error) {
|
func WriteJSON(o interface{}, w io.Writer, n *int64, err *error) {
|
||||||
rv := reflect.ValueOf(o)
|
rv := reflect.ValueOf(o)
|
||||||
rt := reflect.TypeOf(o)
|
rt := reflect.TypeOf(o)
|
||||||
|
if rv.Kind() == reflect.Ptr {
|
||||||
|
rv, rt = rv.Elem(), rt.Elem()
|
||||||
|
}
|
||||||
writeReflectJSON(rv, rt, w, n, err)
|
writeReflectJSON(rv, rt, w, n, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,13 +15,10 @@ import (
|
|||||||
type TypeInfo struct {
|
type TypeInfo struct {
|
||||||
Type reflect.Type // The type
|
Type reflect.Type // The type
|
||||||
|
|
||||||
// Custom encoder/decoder
|
// If Type is kind reflect.Interface, is registered
|
||||||
// NOTE: Not used.
|
IsRegisteredInterface bool
|
||||||
BinaryEncoder Encoder
|
ConcreteTypes map[byte]reflect.Type
|
||||||
BinaryDecoder Decoder
|
ConcreteTypeBytes map[reflect.Type]byte
|
||||||
|
|
||||||
// If Type is kind reflect.Interface
|
|
||||||
ConcreteTypes map[byte]reflect.Type
|
|
||||||
|
|
||||||
// If Type is concrete
|
// If Type is concrete
|
||||||
HasTypeByte bool
|
HasTypeByte bool
|
||||||
@ -104,6 +101,7 @@ func RegisterInterface(o interface{}, args ...interface{}) *TypeInfo {
|
|||||||
panic("RegisterInterface expects an interface")
|
panic("RegisterInterface expects an interface")
|
||||||
}
|
}
|
||||||
concreteTypes := make(map[byte]reflect.Type, 0)
|
concreteTypes := make(map[byte]reflect.Type, 0)
|
||||||
|
concreteTypesReversed := make(map[reflect.Type]byte, 0)
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
switch arg.(type) {
|
switch arg.(type) {
|
||||||
case ConcreteType:
|
case ConcreteType:
|
||||||
@ -114,17 +112,23 @@ func RegisterInterface(o interface{}, args ...interface{}) *TypeInfo {
|
|||||||
if !hasTypeByte {
|
if !hasTypeByte {
|
||||||
panic(Fmt("Expected concrete type %v to implement HasTypeByte", concreteType))
|
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 {
|
if concreteTypes[typeByte] != nil {
|
||||||
panic(Fmt("Duplicate TypeByte for type %v and %v", concreteType, concreteTypes[typeByte]))
|
panic(Fmt("Duplicate TypeByte for type %v and %v", concreteType, concreteTypes[typeByte]))
|
||||||
}
|
}
|
||||||
concreteTypes[typeByte] = concreteType
|
concreteTypes[typeByte] = concreteType
|
||||||
|
concreteTypesReversed[concreteType] = typeByte
|
||||||
default:
|
default:
|
||||||
panic(Fmt("Unexpected argument type %v", reflect.TypeOf(arg)))
|
panic(Fmt("Unexpected argument type %v", reflect.TypeOf(arg)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typeInfo := &TypeInfo{
|
typeInfo := &TypeInfo{
|
||||||
Type: it,
|
Type: it,
|
||||||
ConcreteTypes: concreteTypes,
|
IsRegisteredInterface: true,
|
||||||
|
ConcreteTypes: concreteTypes,
|
||||||
|
ConcreteTypeBytes: concreteTypesReversed,
|
||||||
}
|
}
|
||||||
typeInfos[it] = typeInfo
|
typeInfos[it] = typeInfo
|
||||||
return typeInfo
|
return typeInfo
|
||||||
@ -148,7 +152,8 @@ func RegisterType(info *TypeInfo) *TypeInfo {
|
|||||||
typeInfos[ptrRt] = info
|
typeInfos[ptrRt] = info
|
||||||
|
|
||||||
// See if the type implements HasTypeByte
|
// See if the type implements HasTypeByte
|
||||||
if rt.Kind() != reflect.Interface && rt.Implements(reflect.TypeOf((*HasTypeByte)(nil)).Elem()) {
|
if rt.Kind() != reflect.Interface &&
|
||||||
|
rt.Implements(reflect.TypeOf((*HasTypeByte)(nil)).Elem()) {
|
||||||
zero := reflect.Zero(rt)
|
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 {
|
||||||
@ -197,35 +202,60 @@ func RegisterType(info *TypeInfo) *TypeInfo {
|
|||||||
|
|
||||||
func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *error) {
|
func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *error) {
|
||||||
|
|
||||||
log.Debug("Read reflect", "type", rt)
|
|
||||||
|
|
||||||
// Get typeInfo
|
// Get typeInfo
|
||||||
typeInfo := GetTypeInfo(rt)
|
typeInfo := GetTypeInfo(rt)
|
||||||
|
|
||||||
// Custom decoder
|
if rt.Kind() == reflect.Interface {
|
||||||
if typeInfo.BinaryDecoder != nil {
|
if !typeInfo.IsRegisteredInterface {
|
||||||
decoded := typeInfo.BinaryDecoder(r, n, err)
|
// There's no way we can read such a thing.
|
||||||
rv.Set(reflect.ValueOf(decoded))
|
*err = errors.New(Fmt("Cannot read unregistered interface type %v", rt))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
typeByte := ReadByte(r, n, err)
|
||||||
|
if *err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if typeByte == 0x00 {
|
||||||
|
return // nil
|
||||||
|
}
|
||||||
|
crt, ok := typeInfo.ConcreteTypes[typeByte]
|
||||||
|
if !ok {
|
||||||
|
*err = errors.New(Fmt("Unexpected type byte %X for type %v", typeByte, crt))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
crv := reflect.New(crt).Elem()
|
||||||
|
r = NewPrefixedReader([]byte{typeByte}, r)
|
||||||
|
readReflect(crv, crt, r, n, err)
|
||||||
|
rv.Set(crv) // NOTE: orig rv is ignored.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new struct if rv is nil pointer.
|
if rt.Kind() == reflect.Ptr {
|
||||||
if rt.Kind() == reflect.Ptr && rv.IsNil() {
|
typeByte := ReadByte(r, n, err)
|
||||||
newRv := reflect.New(rt.Elem())
|
if *err != nil {
|
||||||
rv.Set(newRv)
|
return
|
||||||
rv = newRv
|
}
|
||||||
}
|
if typeByte == 0x00 {
|
||||||
|
return // nil
|
||||||
// Dereference pointer
|
}
|
||||||
// Still addressable, thus settable!
|
// Create new if rv is nil.
|
||||||
if rv.Kind() == reflect.Ptr {
|
if rv.IsNil() {
|
||||||
|
newRv := reflect.New(rt.Elem())
|
||||||
|
rv.Set(newRv)
|
||||||
|
rv = newRv
|
||||||
|
}
|
||||||
|
// Dereference pointer
|
||||||
rv, rt = rv.Elem(), rt.Elem()
|
rv, rt = rv.Elem(), rt.Elem()
|
||||||
|
typeInfo = GetTypeInfo(rt)
|
||||||
|
if typeInfo.HasTypeByte {
|
||||||
|
r = NewPrefixedReader([]byte{typeByte}, r)
|
||||||
|
}
|
||||||
|
// continue...
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read TypeByte prefix
|
// Read TypeByte prefix
|
||||||
if typeInfo.HasTypeByte {
|
if typeInfo.HasTypeByte {
|
||||||
typeByte := ReadByte(r, n, err)
|
typeByte := ReadByte(r, n, err)
|
||||||
log.Debug("Read typebyte", "typeByte", typeByte)
|
|
||||||
if typeByte != typeInfo.TypeByte {
|
if typeByte != typeInfo.TypeByte {
|
||||||
*err = errors.New(Fmt("Expected TypeByte of %X but got %X", typeInfo.TypeByte, typeByte))
|
*err = errors.New(Fmt("Expected TypeByte of %X but got %X", typeInfo.TypeByte, typeByte))
|
||||||
return
|
return
|
||||||
@ -233,19 +263,6 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch rt.Kind() {
|
switch rt.Kind() {
|
||||||
case reflect.Interface:
|
|
||||||
typeByte := ReadByte(r, n, err)
|
|
||||||
if *err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
concreteType, ok := typeInfo.ConcreteTypes[typeByte]
|
|
||||||
if !ok {
|
|
||||||
panic(Fmt("TypeByte %X not registered for interface %v", typeByte, rt))
|
|
||||||
}
|
|
||||||
newRv := reflect.New(concreteType)
|
|
||||||
readReflect(newRv.Elem(), concreteType, NewPrefixedReader([]byte{typeByte}, r), n, err)
|
|
||||||
rv.Set(newRv.Elem())
|
|
||||||
|
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
elemRt := rt.Elem()
|
elemRt := rt.Elem()
|
||||||
if elemRt.Kind() == reflect.Uint8 {
|
if elemRt.Kind() == reflect.Uint8 {
|
||||||
@ -349,36 +366,66 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rv: the reflection value of the thing to write
|
||||||
|
// rt: the type of rv as declared in the container, not necessarily rv.Type().
|
||||||
func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) {
|
func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) {
|
||||||
|
|
||||||
// Get typeInfo
|
// Get typeInfo
|
||||||
typeInfo := GetTypeInfo(rt)
|
typeInfo := GetTypeInfo(rt)
|
||||||
|
|
||||||
// Custom encoder, say for an interface type rt.
|
if rt.Kind() == reflect.Interface {
|
||||||
if typeInfo.BinaryEncoder != nil {
|
if rv.IsNil() {
|
||||||
typeInfo.BinaryEncoder(rv.Interface(), w, n, err)
|
// XXX ensure that typeByte 0 is reserved.
|
||||||
|
WriteByte(0x00, w, n, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
crv := rv.Elem() // concrete reflection value
|
||||||
|
crt := crv.Type() // concrete reflection type
|
||||||
|
if typeInfo.IsRegisteredInterface {
|
||||||
|
// See if the crt is registered.
|
||||||
|
// If so, we're more restrictive.
|
||||||
|
_, ok := typeInfo.ConcreteTypeBytes[crt]
|
||||||
|
if !ok {
|
||||||
|
switch crt.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
*err = errors.New(Fmt("Unexpected pointer type %v. Was it registered as a value receiver rather than as a pointer receiver?", crt))
|
||||||
|
case reflect.Struct:
|
||||||
|
*err = errors.New(Fmt("Unexpected struct type %v. Was it registered as a pointer receiver rather than as a value receiver?", crt))
|
||||||
|
default:
|
||||||
|
*err = errors.New(Fmt("Unexpected type %v.", crt))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We support writing unsafely for convenience.
|
||||||
|
}
|
||||||
|
// We don't have to write the typeByte here,
|
||||||
|
// the writeReflect() call below will write it.
|
||||||
|
writeReflect(crv, crt, w, n, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dereference interface
|
|
||||||
if rt.Kind() == reflect.Interface {
|
|
||||||
rv = rv.Elem()
|
|
||||||
rt = rv.Type()
|
|
||||||
// If interface type, get typeInfo of underlying type.
|
|
||||||
typeInfo = GetTypeInfo(rt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dereference pointer
|
|
||||||
if rt.Kind() == reflect.Ptr {
|
if rt.Kind() == reflect.Ptr {
|
||||||
rt = rt.Elem()
|
// Dereference pointer
|
||||||
rv = rv.Elem()
|
rv, rt = rv.Elem(), rt.Elem()
|
||||||
|
if !rv.IsValid() {
|
||||||
|
WriteByte(0x00, w, n, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !typeInfo.HasTypeByte {
|
||||||
|
WriteByte(0x01, w, n, err)
|
||||||
|
// continue...
|
||||||
|
} else {
|
||||||
|
// continue...
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write TypeByte prefix
|
// Write type byte
|
||||||
if typeInfo.HasTypeByte {
|
if typeInfo.HasTypeByte {
|
||||||
WriteByte(typeInfo.TypeByte, w, n, err)
|
WriteByte(typeInfo.TypeByte, w, n, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All other types
|
||||||
switch rt.Kind() {
|
switch rt.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
elemRt := rt.Elem()
|
elemRt := rt.Elem()
|
||||||
@ -478,22 +525,47 @@ func readTypeByteJSON(o interface{}) (typeByte byte, rest interface{}, err error
|
|||||||
|
|
||||||
func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *error) {
|
func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *error) {
|
||||||
|
|
||||||
log.Debug("Read reflect json", "type", rt)
|
|
||||||
|
|
||||||
// Get typeInfo
|
// Get typeInfo
|
||||||
typeInfo := GetTypeInfo(rt)
|
typeInfo := GetTypeInfo(rt)
|
||||||
|
|
||||||
// Create a new struct if rv is nil pointer.
|
if rt.Kind() == reflect.Interface {
|
||||||
if rt.Kind() == reflect.Ptr && rv.IsNil() {
|
if !typeInfo.IsRegisteredInterface {
|
||||||
newRv := reflect.New(rt.Elem())
|
// There's no way we can read such a thing.
|
||||||
rv.Set(newRv)
|
*err = errors.New(Fmt("Cannot read unregistered interface type %v", rt))
|
||||||
rv = newRv
|
return
|
||||||
|
}
|
||||||
|
if o == nil {
|
||||||
|
return // nil
|
||||||
|
}
|
||||||
|
typeByte, _, err_ := readTypeByteJSON(o)
|
||||||
|
if err_ != nil {
|
||||||
|
*err = err_
|
||||||
|
return
|
||||||
|
}
|
||||||
|
crt, ok := typeInfo.ConcreteTypes[typeByte]
|
||||||
|
if !ok {
|
||||||
|
*err = errors.New(Fmt("TypeByte %X not registered for interface %v", typeByte, rt))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
crv := reflect.New(crt).Elem()
|
||||||
|
readReflectJSON(crv, crt, o, err)
|
||||||
|
rv.Set(crv) // NOTE: orig rv is ignored.
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dereference pointer
|
if rt.Kind() == reflect.Ptr {
|
||||||
// Still addressable, thus settable!
|
if o == nil {
|
||||||
if rv.Kind() == reflect.Ptr {
|
return // nil
|
||||||
|
}
|
||||||
|
// Create new struct if rv is nil.
|
||||||
|
if rv.IsNil() {
|
||||||
|
newRv := reflect.New(rt.Elem())
|
||||||
|
rv.Set(newRv)
|
||||||
|
rv = newRv
|
||||||
|
}
|
||||||
|
// Dereference pointer
|
||||||
rv, rt = rv.Elem(), rt.Elem()
|
rv, rt = rv.Elem(), rt.Elem()
|
||||||
|
// continue...
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read TypeByte prefix
|
// Read TypeByte prefix
|
||||||
@ -511,20 +583,6 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch rt.Kind() {
|
switch rt.Kind() {
|
||||||
case reflect.Interface:
|
|
||||||
typeByte, _, err_ := readTypeByteJSON(o)
|
|
||||||
if err_ != nil {
|
|
||||||
*err = err_
|
|
||||||
return
|
|
||||||
}
|
|
||||||
concreteType, ok := typeInfo.ConcreteTypes[typeByte]
|
|
||||||
if !ok {
|
|
||||||
panic(Fmt("TypeByte %X not registered for interface %v", typeByte, rt))
|
|
||||||
}
|
|
||||||
newRv := reflect.New(concreteType)
|
|
||||||
readReflectJSON(newRv.Elem(), concreteType, o, err)
|
|
||||||
rv.Set(newRv.Elem())
|
|
||||||
|
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
elemRt := rt.Elem()
|
elemRt := rt.Elem()
|
||||||
if elemRt.Kind() == reflect.Uint8 {
|
if elemRt.Kind() == reflect.Uint8 {
|
||||||
@ -643,25 +701,55 @@ func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64,
|
|||||||
// Get typeInfo
|
// Get typeInfo
|
||||||
typeInfo := GetTypeInfo(rt)
|
typeInfo := GetTypeInfo(rt)
|
||||||
|
|
||||||
// Dereference interface
|
|
||||||
if rt.Kind() == reflect.Interface {
|
if rt.Kind() == reflect.Interface {
|
||||||
rv = rv.Elem()
|
if rv.IsNil() {
|
||||||
rt = rv.Type()
|
// XXX ensure that typeByte 0 is reserved.
|
||||||
// If interface type, get typeInfo of underlying type.
|
WriteTo([]byte("null"), w, n, err)
|
||||||
typeInfo = GetTypeInfo(rt)
|
return
|
||||||
|
}
|
||||||
|
crv := rv.Elem() // concrete reflection value
|
||||||
|
crt := crv.Type() // concrete reflection type
|
||||||
|
if typeInfo.IsRegisteredInterface {
|
||||||
|
// See if the crt is registered.
|
||||||
|
// If so, we're more restrictive.
|
||||||
|
_, ok := typeInfo.ConcreteTypeBytes[crt]
|
||||||
|
if !ok {
|
||||||
|
switch crt.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
*err = errors.New(Fmt("Unexpected pointer type %v. Was it registered as a value receiver rather than as a pointer receiver?", crt))
|
||||||
|
case reflect.Struct:
|
||||||
|
*err = errors.New(Fmt("Unexpected struct type %v. Was it registered as a pointer receiver rather than as a value receiver?", crt))
|
||||||
|
default:
|
||||||
|
*err = errors.New(Fmt("Unexpected type %v.", crt))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We support writing unsafely for convenience.
|
||||||
|
}
|
||||||
|
// We don't have to write the typeByte here,
|
||||||
|
// the writeReflectJSON() call below will write it.
|
||||||
|
writeReflectJSON(crv, crt, w, n, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dereference pointer
|
|
||||||
if rt.Kind() == reflect.Ptr {
|
if rt.Kind() == reflect.Ptr {
|
||||||
rt = rt.Elem()
|
// Dereference pointer
|
||||||
rv = rv.Elem()
|
rv, rt = rv.Elem(), rt.Elem()
|
||||||
|
if !rv.IsValid() {
|
||||||
|
WriteTo([]byte("null"), w, n, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// continue...
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write TypeByte prefix
|
// Write TypeByte
|
||||||
if typeInfo.HasTypeByte {
|
if typeInfo.HasTypeByte {
|
||||||
WriteTo([]byte(Fmt("[%v,", typeInfo.TypeByte)), w, n, err)
|
WriteTo([]byte(Fmt("[%v,", typeInfo.TypeByte)), w, n, err)
|
||||||
|
defer WriteTo([]byte("]"), w, n, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All other types
|
||||||
switch rt.Kind() {
|
switch rt.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
elemRt := rt.Elem()
|
elemRt := rt.Elem()
|
||||||
@ -730,10 +818,4 @@ func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64,
|
|||||||
panic(Fmt("Unknown field type %v", rt.Kind()))
|
panic(Fmt("Unknown field type %v", rt.Kind()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write TypeByte close bracket
|
|
||||||
if typeInfo.HasTypeByte {
|
|
||||||
WriteTo([]byte("]"), w, n, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
@ -120,13 +120,42 @@ func instantiateBasic() (interface{}, interface{}) {
|
|||||||
func validateBasic(o interface{}, t *testing.T) {
|
func validateBasic(o interface{}, t *testing.T) {
|
||||||
cat := o.(Cat)
|
cat := o.(Cat)
|
||||||
if cat.String != "String" {
|
if cat.String != "String" {
|
||||||
t.Errorf("Expected cat2.String == 'String', got %v", cat.String)
|
t.Errorf("Expected cat.String == 'String', got %v", cat.String)
|
||||||
}
|
}
|
||||||
if string(cat.Bytes) != "Bytes" {
|
if string(cat.Bytes) != "Bytes" {
|
||||||
t.Errorf("Expected cat2.Bytes == 'Bytes', got %X", cat.Bytes)
|
t.Errorf("Expected cat.Bytes == 'Bytes', got %X", cat.Bytes)
|
||||||
}
|
}
|
||||||
if cat.Time.Unix() != 123 {
|
if cat.Time.Unix() != 123 {
|
||||||
t.Errorf("Expected cat2.Time == 'Unix(123)', got %v", cat.Time)
|
t.Errorf("Expected cat.Time == 'Unix(123)', got %v", cat.Time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
|
||||||
|
type NilTestStruct struct {
|
||||||
|
IntPtr *int
|
||||||
|
CatPtr *Cat
|
||||||
|
Animal Animal
|
||||||
|
}
|
||||||
|
|
||||||
|
func constructNilTestStruct() interface{} {
|
||||||
|
return NilTestStruct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func instantiateNilTestStruct() (interface{}, interface{}) {
|
||||||
|
return NilTestStruct{}, &NilTestStruct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateNilTestStruct(o interface{}, t *testing.T) {
|
||||||
|
nts := o.(NilTestStruct)
|
||||||
|
if nts.IntPtr != nil {
|
||||||
|
t.Errorf("Expected nts.IntPtr to be nil, got %v", nts.IntPtr)
|
||||||
|
}
|
||||||
|
if nts.CatPtr != nil {
|
||||||
|
t.Errorf("Expected nts.CatPtr to be nil, got %v", nts.CatPtr)
|
||||||
|
}
|
||||||
|
if nts.Animal != nil {
|
||||||
|
t.Errorf("Expected nts.Animal to be nil, got %v", nts.Animal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,7 +281,7 @@ func constructComplexArray() interface{} {
|
|||||||
Bytes: []byte("Bytes"),
|
Bytes: []byte("Bytes"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&Dog{ // Even though it's a *Dog, we'll get a Dog{} back.
|
Dog{
|
||||||
SimpleStruct{
|
SimpleStruct{
|
||||||
String: "Woof",
|
String: "Woof",
|
||||||
Bytes: []byte("Bark"),
|
Bytes: []byte("Bark"),
|
||||||
@ -321,11 +350,14 @@ func init() {
|
|||||||
testCases = append(testCases, TestCase{constructComplex, instantiateComplex, validateComplex})
|
testCases = append(testCases, TestCase{constructComplex, instantiateComplex, validateComplex})
|
||||||
testCases = append(testCases, TestCase{constructComplex2, instantiateComplex2, validateComplex2})
|
testCases = append(testCases, TestCase{constructComplex2, instantiateComplex2, validateComplex2})
|
||||||
testCases = append(testCases, TestCase{constructComplexArray, instantiateComplexArray, validateComplexArray})
|
testCases = append(testCases, TestCase{constructComplexArray, instantiateComplexArray, validateComplexArray})
|
||||||
|
testCases = append(testCases, TestCase{constructNilTestStruct, instantiateNilTestStruct, validateNilTestStruct})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBinary(t *testing.T) {
|
func TestBinary(t *testing.T) {
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
|
||||||
|
log.Info(fmt.Sprintf("Running test case %v", i))
|
||||||
|
|
||||||
// Construct an object
|
// Construct an object
|
||||||
o := testCase.Constructor()
|
o := testCase.Constructor()
|
||||||
@ -340,7 +372,7 @@ func TestBinary(t *testing.T) {
|
|||||||
n, err := new(int64), new(error)
|
n, err := new(int64), new(error)
|
||||||
res := ReadBinary(instance, bytes.NewReader(data), n, err)
|
res := ReadBinary(instance, bytes.NewReader(data), n, err)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
t.Fatalf("Failed to read cat: %v", *err)
|
t.Fatalf("Failed to read into instance: %v", *err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate object
|
// Validate object
|
||||||
@ -350,7 +382,7 @@ func TestBinary(t *testing.T) {
|
|||||||
n, err = new(int64), new(error)
|
n, err = new(int64), new(error)
|
||||||
res = ReadBinary(instancePtr, bytes.NewReader(data), n, err)
|
res = ReadBinary(instancePtr, bytes.NewReader(data), n, err)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
t.Fatalf("Failed to read cat: %v", *err)
|
t.Fatalf("Failed to read into instance: %v", *err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if res != instancePtr {
|
if res != instancePtr {
|
||||||
@ -365,7 +397,9 @@ func TestBinary(t *testing.T) {
|
|||||||
|
|
||||||
func TestJSON(t *testing.T) {
|
func TestJSON(t *testing.T) {
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
|
||||||
|
log.Info(fmt.Sprintf("Running test case %v", i))
|
||||||
|
|
||||||
// Construct an object
|
// Construct an object
|
||||||
o := testCase.Constructor()
|
o := testCase.Constructor()
|
||||||
|
@ -10,7 +10,7 @@ func BinaryBytes(o interface{}) []byte {
|
|||||||
w, n, err := new(bytes.Buffer), new(int64), new(error)
|
w, n, err := new(bytes.Buffer), new(int64), new(error)
|
||||||
WriteBinary(o, w, n, err)
|
WriteBinary(o, w, n, err)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
panic(err)
|
panic(*err)
|
||||||
}
|
}
|
||||||
return w.Bytes()
|
return w.Bytes()
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ func JSONBytes(o interface{}) []byte {
|
|||||||
w, n, err := new(bytes.Buffer), new(int64), new(error)
|
w, n, err := new(bytes.Buffer), new(int64), new(error)
|
||||||
WriteJSON(o, w, n, err)
|
WriteJSON(o, w, n, err)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
panic(err)
|
panic(*err)
|
||||||
}
|
}
|
||||||
return w.Bytes()
|
return w.Bytes()
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ func BinarySha256(o interface{}) []byte {
|
|||||||
hasher, n, err := sha256.New(), new(int64), new(error)
|
hasher, n, err := sha256.New(), new(int64), new(error)
|
||||||
WriteBinary(o, hasher, n, err)
|
WriteBinary(o, hasher, n, err)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
panic(err)
|
panic(*err)
|
||||||
}
|
}
|
||||||
return hasher.Sum(nil)
|
return hasher.Sum(nil)
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ func BinaryRipemd160(o interface{}) []byte {
|
|||||||
hasher, n, err := ripemd160.New(), new(int64), new(error)
|
hasher, n, err := ripemd160.New(), new(int64), new(error)
|
||||||
WriteBinary(o, hasher, n, err)
|
WriteBinary(o, hasher, n, err)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
panic(err)
|
panic(*err)
|
||||||
}
|
}
|
||||||
return hasher.Sum(nil)
|
return hasher.Sum(nil)
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ func TestReadWrite(t *testing.T) {
|
|||||||
// Read from buffer.
|
// Read from buffer.
|
||||||
pol2 := binary.ReadBinary(&POL{}, buf, n, err).(*POL)
|
pol2 := binary.ReadBinary(&POL{}, buf, n, err).(*POL)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
t.Fatalf("Failed to read POL")
|
t.Fatalf("Failed to read POL: %v", *err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that validation succeeds.
|
// Check that validation succeeds.
|
||||||
|
@ -123,7 +123,7 @@ func (memR *MempoolReactor) SetEventSwitch(evsw *events.EventSwitch) {
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
msgTypeUnknown = byte(0x00)
|
msgTypeUnknown = byte(0x00)
|
||||||
msgTypeTx = byte(0x10)
|
msgTypeTx = byte(0x01)
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: check for unnecessary extra bytes at the end.
|
// TODO: check for unnecessary extra bytes at the end.
|
||||||
|
@ -152,7 +152,8 @@ func (n *Node) StartRPC() {
|
|||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
rpc.RegisterEventsHandler(mux, n.evsw)
|
rpc.RegisterEventsHandler(mux, n.evsw)
|
||||||
rpc.RegisterRPCFuncs(mux, core.Routes)
|
rpc.RegisterRPCFuncs(mux, core.Routes)
|
||||||
rpc.StartHTTPServer(listenAddr, mux)
|
handler := rpc.AuthenticateHandler(mux)
|
||||||
|
rpc.StartHTTPServer(listenAddr, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Switch() *p2p.Switch {
|
func (n *Node) Switch() *p2p.Switch {
|
||||||
|
@ -588,9 +588,9 @@ func (ch *Channel) updateStats() {
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
maxMsgPacketSize = 1024
|
maxMsgPacketSize = 1024
|
||||||
packetTypePing = byte(0x00)
|
packetTypePing = byte(0x01)
|
||||||
packetTypePong = byte(0x01)
|
packetTypePong = byte(0x02)
|
||||||
packetTypeMsg = byte(0x10)
|
packetTypeMsg = byte(0x03)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Messages in channels are chopped into smaller msgPackets for multiplexing.
|
// Messages in channels are chopped into smaller msgPackets for multiplexing.
|
||||||
|
@ -17,7 +17,7 @@ func GetAccount(address []byte) (*ctypes.ResponseGetAccount, error) {
|
|||||||
if account == nil {
|
if account == nil {
|
||||||
account = &acm.Account{
|
account = &acm.Account{
|
||||||
Address: address,
|
Address: address,
|
||||||
PubKey: acm.PubKeyNil{},
|
PubKey: nil,
|
||||||
Sequence: 0,
|
Sequence: 0,
|
||||||
Balance: 0,
|
Balance: 0,
|
||||||
Code: nil,
|
Code: nil,
|
||||||
|
@ -18,7 +18,7 @@ type Client interface {
|
|||||||
BroadcastTx(tx types.Tx) (*ctypes.ResponseBroadcastTx, error)
|
BroadcastTx(tx types.Tx) (*ctypes.ResponseBroadcastTx, error)
|
||||||
Call(address []byte, data []byte) (*ctypes.ResponseCall, error)
|
Call(address []byte, data []byte) (*ctypes.ResponseCall, error)
|
||||||
CallCode(code []byte, data []byte) (*ctypes.ResponseCall, error)
|
CallCode(code []byte, data []byte) (*ctypes.ResponseCall, error)
|
||||||
DumpStorage(addr []byte) (*ctypes.ResponseDumpStorage, error)
|
DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error)
|
||||||
GenPrivAccount() (*ctypes.ResponseGenPrivAccount, error)
|
GenPrivAccount() (*ctypes.ResponseGenPrivAccount, error)
|
||||||
GetAccount(address []byte) (*ctypes.ResponseGetAccount, error)
|
GetAccount(address []byte) (*ctypes.ResponseGetAccount, error)
|
||||||
GetBlock(height uint) (*ctypes.ResponseGetBlock, error)
|
GetBlock(height uint) (*ctypes.ResponseGetBlock, error)
|
||||||
@ -150,8 +150,8 @@ func (c *ClientHTTP) CallCode(code []byte, data []byte) (*ctypes.ResponseCall, e
|
|||||||
return response.Result, nil
|
return response.Result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientHTTP) DumpStorage(addr []byte) (*ctypes.ResponseDumpStorage, error) {
|
func (c *ClientHTTP) DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) {
|
||||||
values, err := argsToURLValues([]string{"addr"}, addr)
|
values, err := argsToURLValues([]string{"address"}, address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -558,11 +558,11 @@ func (c *ClientJSON) CallCode(code []byte, data []byte) (*ctypes.ResponseCall, e
|
|||||||
return response.Result, nil
|
return response.Result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientJSON) DumpStorage(addr []byte) (*ctypes.ResponseDumpStorage, error) {
|
func (c *ClientJSON) DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) {
|
||||||
request := rpc.RPCRequest{
|
request := rpc.RPCRequest{
|
||||||
JSONRPC: "2.0",
|
JSONRPC: "2.0",
|
||||||
Method: reverseFuncMap["DumpStorage"],
|
Method: reverseFuncMap["DumpStorage"],
|
||||||
Params: []interface{}{addr},
|
Params: []interface{}{address},
|
||||||
Id: 0,
|
Id: 0,
|
||||||
}
|
}
|
||||||
body, err := c.RequestResponse(request)
|
body, err := c.RequestResponse(request)
|
||||||
|
@ -101,6 +101,7 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc) http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
returns := rpcFunc.f.Call(args)
|
returns := rpcFunc.f.Call(args)
|
||||||
|
log.Debug("HTTPJSONRPC", "method", request.Method, "args", args, "returns", returns)
|
||||||
response, err := unreflectResponse(returns)
|
response, err := unreflectResponse(returns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteRPCResponse(w, NewRPCResponse(nil, err.Error()))
|
WriteRPCResponse(w, NewRPCResponse(nil, err.Error()))
|
||||||
@ -148,6 +149,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc) func(http.ResponseWriter, *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
returns := rpcFunc.f.Call(args)
|
returns := rpcFunc.f.Call(args)
|
||||||
|
log.Debug("HTTPRestRPC", "method", r.URL.Path, "args", args, "returns", returns)
|
||||||
response, err := unreflectResponse(returns)
|
response, err := unreflectResponse(returns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteRPCResponse(w, NewRPCResponse(nil, err.Error()))
|
WriteRPCResponse(w, NewRPCResponse(nil, err.Error()))
|
||||||
|
@ -4,6 +4,7 @@ package rpc
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"time"
|
"time"
|
||||||
@ -12,12 +13,12 @@ import (
|
|||||||
. "github.com/tendermint/tendermint/common"
|
. "github.com/tendermint/tendermint/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartHTTPServer(listenAddr string, mux *http.ServeMux) {
|
func StartHTTPServer(listenAddr string, handler http.Handler) {
|
||||||
log.Info(Fmt("Starting RPC HTTP server on %s", listenAddr))
|
log.Info(Fmt("Starting RPC HTTP server on %s", listenAddr))
|
||||||
go func() {
|
go func() {
|
||||||
res := http.ListenAndServe(
|
res := http.ListenAndServe(
|
||||||
listenAddr,
|
listenAddr,
|
||||||
RecoverAndLogHandler(mux),
|
RecoverAndLogHandler(handler),
|
||||||
)
|
)
|
||||||
log.Crit("RPC HTTPServer stopped", "result", res)
|
log.Crit("RPC HTTPServer stopped", "result", res)
|
||||||
}()
|
}()
|
||||||
@ -37,8 +38,40 @@ func WriteRPCResponse(w http.ResponseWriter, res RPCResponse) {
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func AuthenticateHandler(handler http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// from https://medium.com/@xoen/golang-read-from-an-io-readwriter-without-loosing-its-content-2c6911805361
|
||||||
|
// Read the content
|
||||||
|
var bodyBytes []byte
|
||||||
|
if r.Body != nil {
|
||||||
|
bodyBytes, _ = ioutil.ReadAll(r.Body)
|
||||||
|
}
|
||||||
|
// Restore the io.ReadCloser to its original state
|
||||||
|
r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||||
|
// Get body string
|
||||||
|
bodyString := string(bodyBytes)
|
||||||
|
// Also read the path+"?"+query
|
||||||
|
pathQuery := Fmt("%v?%v", r.URL.Path, r.URL.RawQuery)
|
||||||
|
// Concatenate into tuple
|
||||||
|
tuple := struct {
|
||||||
|
Body string
|
||||||
|
Path string
|
||||||
|
}{bodyString, pathQuery}
|
||||||
|
// Get sign bytes
|
||||||
|
signBytes := binary.BinaryBytes(tuple)
|
||||||
|
// Validate the sign bytes.
|
||||||
|
// XXX
|
||||||
|
log.Debug("Should sign", "bytes", signBytes)
|
||||||
|
// If validation fails
|
||||||
|
// XXX
|
||||||
|
// If validation passes
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Wraps an HTTP handler, adding error logging.
|
// Wraps an HTTP handler, adding error logging.
|
||||||
//
|
|
||||||
// If the inner function panics, the outer function recovers, logs, sends an
|
// If the inner function panics, the outer function recovers, logs, sends an
|
||||||
// HTTP 500 error response.
|
// HTTP 500 error response.
|
||||||
func RecoverAndLogHandler(handler http.Handler) http.Handler {
|
func RecoverAndLogHandler(handler http.Handler) http.Handler {
|
||||||
|
@ -258,7 +258,7 @@ func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types
|
|||||||
}
|
}
|
||||||
// Check signatures
|
// Check signatures
|
||||||
// acc := getAccount(t, byteAddr)
|
// acc := getAccount(t, byteAddr)
|
||||||
// NOTE: using the acc here instead of the in fails; its PubKeyNil ... ?
|
// NOTE: using the acc here instead of the in fails; it is nil.
|
||||||
if !in.PubKey.VerifyBytes(signBytes, in.Signature) {
|
if !in.PubKey.VerifyBytes(signBytes, in.Signature) {
|
||||||
t.Fatal(types.ErrTxInvalidSignature)
|
t.Fatal(types.ErrTxInvalidSignature)
|
||||||
}
|
}
|
||||||
|
@ -159,9 +159,9 @@ func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeade
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The accounts from the TxInputs must either already have
|
// The accounts from the TxInputs must either already have
|
||||||
// account.PubKey.(type) != PubKeyNil, (it must be known),
|
// account.PubKey.(type) != nil, (it must be known),
|
||||||
// or it must be specified in the TxInput. If redeclared,
|
// or it must be specified in the TxInput. If redeclared,
|
||||||
// the TxInput is modified and input.PubKey set to PubKeyNil.
|
// the TxInput is modified and input.PubKey set to nil.
|
||||||
func getOrMakeAccounts(state AccountGetter, ins []*types.TxInput, outs []*types.TxOutput) (map[string]*account.Account, error) {
|
func getOrMakeAccounts(state AccountGetter, ins []*types.TxInput, outs []*types.TxOutput) (map[string]*account.Account, error) {
|
||||||
accounts := map[string]*account.Account{}
|
accounts := map[string]*account.Account{}
|
||||||
for _, in := range ins {
|
for _, in := range ins {
|
||||||
@ -189,7 +189,7 @@ func getOrMakeAccounts(state AccountGetter, ins []*types.TxInput, outs []*types.
|
|||||||
if acc == nil {
|
if acc == nil {
|
||||||
acc = &account.Account{
|
acc = &account.Account{
|
||||||
Address: out.Address,
|
Address: out.Address,
|
||||||
PubKey: account.PubKeyNil{},
|
PubKey: nil,
|
||||||
Sequence: 0,
|
Sequence: 0,
|
||||||
Balance: 0,
|
Balance: 0,
|
||||||
}
|
}
|
||||||
@ -200,8 +200,8 @@ func getOrMakeAccounts(state AccountGetter, ins []*types.TxInput, outs []*types.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkInputPubKey(acc *account.Account, in *types.TxInput) error {
|
func checkInputPubKey(acc *account.Account, in *types.TxInput) error {
|
||||||
if _, isNil := acc.PubKey.(account.PubKeyNil); isNil {
|
if acc.PubKey == nil {
|
||||||
if _, isNil := in.PubKey.(account.PubKeyNil); isNil {
|
if in.PubKey == nil {
|
||||||
return types.ErrTxUnknownPubKey
|
return types.ErrTxUnknownPubKey
|
||||||
}
|
}
|
||||||
if !bytes.Equal(in.PubKey.Address(), acc.Address) {
|
if !bytes.Equal(in.PubKey.Address(), acc.Address) {
|
||||||
@ -209,7 +209,7 @@ func checkInputPubKey(acc *account.Account, in *types.TxInput) error {
|
|||||||
}
|
}
|
||||||
acc.PubKey = in.PubKey
|
acc.PubKey = in.PubKey
|
||||||
} else {
|
} else {
|
||||||
in.PubKey = account.PubKeyNil{}
|
in.PubKey = nil
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {
|
|||||||
for _, genAcc := range genDoc.Accounts {
|
for _, genAcc := range genDoc.Accounts {
|
||||||
acc := &account.Account{
|
acc := &account.Account{
|
||||||
Address: genAcc.Address,
|
Address: genAcc.Address,
|
||||||
PubKey: account.PubKeyNil{},
|
PubKey: nil,
|
||||||
Sequence: 0,
|
Sequence: 0,
|
||||||
Balance: genAcc.Amount,
|
Balance: genAcc.Amount,
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ func toVMAccount(acc *ac.Account) *vm.Account {
|
|||||||
func toStateAccount(acc *vm.Account) *ac.Account {
|
func toStateAccount(acc *vm.Account) *ac.Account {
|
||||||
pubKey, ok := acc.Other.(ac.PubKey)
|
pubKey, ok := acc.Other.(ac.PubKey)
|
||||||
if !ok {
|
if !ok {
|
||||||
pubKey = ac.PubKeyNil{}
|
pubKey = nil
|
||||||
}
|
}
|
||||||
var storageRoot []byte
|
var storageRoot []byte
|
||||||
if acc.StorageRoot.IsZero() {
|
if acc.StorageRoot.IsZero() {
|
||||||
|
@ -76,7 +76,7 @@ type TxInput struct {
|
|||||||
Amount uint64 // Must not exceed account balance
|
Amount uint64 // Must not exceed account balance
|
||||||
Sequence uint // Must be 1 greater than the last committed TxInput
|
Sequence uint // Must be 1 greater than the last committed TxInput
|
||||||
Signature account.Signature // Depends on the PubKey type and the whole Tx
|
Signature account.Signature // Depends on the PubKey type and the whole Tx
|
||||||
PubKey account.PubKey // Must not be nil, may be PubKeyNil.
|
PubKey account.PubKey // Must not be nil, may be nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (txIn *TxInput) ValidateBasic() error {
|
func (txIn *TxInput) ValidateBasic() error {
|
||||||
|
@ -40,9 +40,9 @@ type Vote struct {
|
|||||||
|
|
||||||
// Types of votes
|
// Types of votes
|
||||||
const (
|
const (
|
||||||
VoteTypePrevote = byte(0x00)
|
VoteTypePrevote = byte(0x01)
|
||||||
VoteTypePrecommit = byte(0x01)
|
VoteTypePrecommit = byte(0x02)
|
||||||
VoteTypeCommit = byte(0x02)
|
VoteTypeCommit = byte(0x03)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (vote *Vote) WriteSignBytes(w io.Writer, n *int64, err *error) {
|
func (vote *Vote) WriteSignBytes(w io.Writer, n *int64, err *error) {
|
||||||
|
Reference in New Issue
Block a user