Browse Source

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.
pull/55/head
Jae Kwon 10 years ago
parent
commit
6d6f061f19
20 changed files with 299 additions and 178 deletions
  1. +7
    -31
      account/pubkey.go
  2. +0
    -13
      account/signature.go
  3. +6
    -0
      binary/binary.go
  4. +176
    -94
      binary/reflect.go
  5. +42
    -8
      binary/reflect_test.go
  6. +4
    -4
      binary/util.go
  7. +1
    -1
      consensus/pol_test.go
  8. +1
    -1
      mempool/reactor.go
  9. +2
    -1
      node/node.go
  10. +3
    -3
      p2p/connection.go
  11. +1
    -1
      rpc/core/accounts.go
  12. +5
    -5
      rpc/core_client/client_methods.go
  13. +2
    -0
      rpc/handlers.go
  14. +36
    -3
      rpc/http_server.go
  15. +1
    -1
      rpc/test/helpers.go
  16. +6
    -6
      state/execution.go
  17. +1
    -1
      state/genesis.go
  18. +1
    -1
      state/tx_cache.go
  19. +1
    -1
      types/tx.go
  20. +3
    -3
      types/vote.go

+ 7
- 31
account/pubkey.go View File

@ -2,7 +2,6 @@ package account
import (
"errors"
"github.com/tendermint/ed25519"
"github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
@ -18,47 +17,17 @@ type PubKey interface {
// Types of PubKey implementations
const (
PubKeyTypeNil = byte(0x00)
PubKeyTypeEd25519 = byte(0x01)
)
// for binary.readReflect
var _ = binary.RegisterInterface(
struct{ PubKey }{},
binary.ConcreteType{PubKeyNil{}},
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
type PubKeyEd25519 []byte
@ -81,6 +50,13 @@ func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
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 {
return Fmt("PubKeyEd25519{%X}", []byte(pubKey))
}

+ 0
- 13
account/signature.go View File

@ -14,30 +14,17 @@ type Signature interface {
// Types of Signature implementations
const (
SignatureTypeNil = byte(0x00)
SignatureTypeEd25519 = byte(0x01)
)
// for binary.readReflect
var _ = binary.RegisterInterface(
struct{ Signature }{},
binary.ConcreteType{SignatureNil{}},
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
type SignatureEd25519 []byte


+ 6
- 0
binary/binary.go View File

@ -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) {
rv := reflect.ValueOf(o)
rt := reflect.TypeOf(o)
if rv.Kind() == reflect.Ptr {
rv, rt = rv.Elem(), rt.Elem()
}
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) {
rv := reflect.ValueOf(o)
rt := reflect.TypeOf(o)
if rv.Kind() == reflect.Ptr {
rv, rt = rv.Elem(), rt.Elem()
}
writeReflectJSON(rv, rt, w, n, err)
}


+ 176
- 94
binary/reflect.go View File

@ -15,13 +15,10 @@ import (
type TypeInfo struct {
Type reflect.Type // The type
// Custom encoder/decoder
// NOTE: Not used.
BinaryEncoder Encoder
BinaryDecoder Decoder
// If Type is kind reflect.Interface
ConcreteTypes map[byte]reflect.Type
// If Type is kind reflect.Interface, is registered
IsRegisteredInterface bool
ConcreteTypes map[byte]reflect.Type
ConcreteTypeBytes map[reflect.Type]byte
// If Type is concrete
HasTypeByte bool
@ -104,6 +101,7 @@ func RegisterInterface(o interface{}, args ...interface{}) *TypeInfo {
panic("RegisterInterface expects an interface")
}
concreteTypes := make(map[byte]reflect.Type, 0)
concreteTypesReversed := make(map[reflect.Type]byte, 0)
for _, arg := range args {
switch arg.(type) {
case ConcreteType:
@ -114,17 +112,23 @@ func RegisterInterface(o interface{}, args ...interface{}) *TypeInfo {
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)))
}
}
typeInfo := &TypeInfo{
Type: it,
ConcreteTypes: concreteTypes,
Type: it,
IsRegisteredInterface: true,
ConcreteTypes: concreteTypes,
ConcreteTypeBytes: concreteTypesReversed,
}
typeInfos[it] = typeInfo
return typeInfo
@ -148,7 +152,8 @@ func RegisterType(info *TypeInfo) *TypeInfo {
typeInfos[ptrRt] = info
// 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)
typeByte := zero.Interface().(HasTypeByte).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) {
log.Debug("Read reflect", "type", rt)
// Get typeInfo
typeInfo := GetTypeInfo(rt)
// Custom decoder
if typeInfo.BinaryDecoder != nil {
decoded := typeInfo.BinaryDecoder(r, n, err)
rv.Set(reflect.ValueOf(decoded))
if rt.Kind() == reflect.Interface {
if !typeInfo.IsRegisteredInterface {
// There's no way we can read such a thing.
*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
}
// Create a new struct if rv is nil pointer.
if rt.Kind() == reflect.Ptr && rv.IsNil() {
newRv := reflect.New(rt.Elem())
rv.Set(newRv)
rv = newRv
}
// Dereference pointer
// Still addressable, thus settable!
if rv.Kind() == reflect.Ptr {
if rt.Kind() == reflect.Ptr {
typeByte := ReadByte(r, n, err)
if *err != nil {
return
}
if typeByte == 0x00 {
return // nil
}
// Create new 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()
typeInfo = GetTypeInfo(rt)
if typeInfo.HasTypeByte {
r = NewPrefixedReader([]byte{typeByte}, r)
}
// continue...
}
// Read TypeByte prefix
if typeInfo.HasTypeByte {
typeByte := ReadByte(r, n, err)
log.Debug("Read typebyte", "typeByte", typeByte)
if typeByte != typeInfo.TypeByte {
*err = errors.New(Fmt("Expected TypeByte of %X but got %X", typeInfo.TypeByte, typeByte))
return
@ -233,19 +263,6 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
}
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:
elemRt := rt.Elem()
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) {
// Get typeInfo
typeInfo := GetTypeInfo(rt)
// Custom encoder, say for an interface type rt.
if typeInfo.BinaryEncoder != nil {
typeInfo.BinaryEncoder(rv.Interface(), w, n, err)
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)
if rv.IsNil() {
// 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
}
// Dereference pointer
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
rv = rv.Elem()
// Dereference pointer
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 {
WriteByte(typeInfo.TypeByte, w, n, err)
}
// All other types
switch rt.Kind() {
case reflect.Slice:
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) {
log.Debug("Read reflect json", "type", rt)
// Get typeInfo
typeInfo := GetTypeInfo(rt)
// Create a new struct if rv is nil pointer.
if rt.Kind() == reflect.Ptr && rv.IsNil() {
newRv := reflect.New(rt.Elem())
rv.Set(newRv)
rv = newRv
if rt.Kind() == reflect.Interface {
if !typeInfo.IsRegisteredInterface {
// There's no way we can read such a thing.
*err = errors.New(Fmt("Cannot read unregistered interface type %v", rt))
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
// Still addressable, thus settable!
if rv.Kind() == reflect.Ptr {
if rt.Kind() == reflect.Ptr {
if o == nil {
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()
// continue...
}
// Read TypeByte prefix
@ -511,20 +583,6 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro
}
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:
elemRt := rt.Elem()
if elemRt.Kind() == reflect.Uint8 {
@ -643,25 +701,55 @@ func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64,
// Get typeInfo
typeInfo := GetTypeInfo(rt)
// Dereference interface
if rt.Kind() == reflect.Interface {
rv = rv.Elem()
rt = rv.Type()
// If interface type, get typeInfo of underlying type.
typeInfo = GetTypeInfo(rt)
if rv.IsNil() {
// XXX ensure that typeByte 0 is reserved.
WriteTo([]byte("null"), 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 writeReflectJSON() call below will write it.
writeReflectJSON(crv, crt, w, n, err)
return
}
// Dereference pointer
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
rv = rv.Elem()
// Dereference pointer
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 {
WriteTo([]byte(Fmt("[%v,", typeInfo.TypeByte)), w, n, err)
defer WriteTo([]byte("]"), w, n, err)
}
// All other types
switch rt.Kind() {
case reflect.Slice:
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()))
}
// Write TypeByte close bracket
if typeInfo.HasTypeByte {
WriteTo([]byte("]"), w, n, err)
}
}
//-----------------------------------------------------------------------------

+ 42
- 8
binary/reflect_test.go View File

@ -120,13 +120,42 @@ func instantiateBasic() (interface{}, interface{}) {
func validateBasic(o interface{}, t *testing.T) {
cat := o.(Cat)
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" {
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 {
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"),
},
},
&Dog{ // Even though it's a *Dog, we'll get a Dog{} back.
Dog{
SimpleStruct{
String: "Woof",
Bytes: []byte("Bark"),
@ -321,11 +350,14 @@ func init() {
testCases = append(testCases, TestCase{constructComplex, instantiateComplex, validateComplex})
testCases = append(testCases, TestCase{constructComplex2, instantiateComplex2, validateComplex2})
testCases = append(testCases, TestCase{constructComplexArray, instantiateComplexArray, validateComplexArray})
testCases = append(testCases, TestCase{constructNilTestStruct, instantiateNilTestStruct, validateNilTestStruct})
}
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
o := testCase.Constructor()
@ -340,7 +372,7 @@ func TestBinary(t *testing.T) {
n, err := new(int64), new(error)
res := ReadBinary(instance, bytes.NewReader(data), n, err)
if *err != nil {
t.Fatalf("Failed to read cat: %v", *err)
t.Fatalf("Failed to read into instance: %v", *err)
}
// Validate object
@ -350,7 +382,7 @@ func TestBinary(t *testing.T) {
n, err = new(int64), new(error)
res = ReadBinary(instancePtr, bytes.NewReader(data), n, err)
if *err != nil {
t.Fatalf("Failed to read cat: %v", *err)
t.Fatalf("Failed to read into instance: %v", *err)
}
if res != instancePtr {
@ -365,7 +397,9 @@ func TestBinary(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
o := testCase.Constructor()


+ 4
- 4
binary/util.go View File

@ -10,7 +10,7 @@ func BinaryBytes(o interface{}) []byte {
w, n, err := new(bytes.Buffer), new(int64), new(error)
WriteBinary(o, w, n, err)
if *err != nil {
panic(err)
panic(*err)
}
return w.Bytes()
}
@ -19,7 +19,7 @@ func JSONBytes(o interface{}) []byte {
w, n, err := new(bytes.Buffer), new(int64), new(error)
WriteJSON(o, w, n, err)
if *err != nil {
panic(err)
panic(*err)
}
return w.Bytes()
}
@ -42,7 +42,7 @@ func BinarySha256(o interface{}) []byte {
hasher, n, err := sha256.New(), new(int64), new(error)
WriteBinary(o, hasher, n, err)
if *err != nil {
panic(err)
panic(*err)
}
return hasher.Sum(nil)
}
@ -51,7 +51,7 @@ func BinaryRipemd160(o interface{}) []byte {
hasher, n, err := ripemd160.New(), new(int64), new(error)
WriteBinary(o, hasher, n, err)
if *err != nil {
panic(err)
panic(*err)
}
return hasher.Sum(nil)
}

+ 1
- 1
consensus/pol_test.go View File

@ -202,7 +202,7 @@ func TestReadWrite(t *testing.T) {
// Read from buffer.
pol2 := binary.ReadBinary(&POL{}, buf, n, err).(*POL)
if *err != nil {
t.Fatalf("Failed to read POL")
t.Fatalf("Failed to read POL: %v", *err)
}
// Check that validation succeeds.


+ 1
- 1
mempool/reactor.go View File

@ -123,7 +123,7 @@ func (memR *MempoolReactor) SetEventSwitch(evsw *events.EventSwitch) {
const (
msgTypeUnknown = byte(0x00)
msgTypeTx = byte(0x10)
msgTypeTx = byte(0x01)
)
// TODO: check for unnecessary extra bytes at the end.


+ 2
- 1
node/node.go View File

@ -152,7 +152,8 @@ func (n *Node) StartRPC() {
mux := http.NewServeMux()
rpc.RegisterEventsHandler(mux, n.evsw)
rpc.RegisterRPCFuncs(mux, core.Routes)
rpc.StartHTTPServer(listenAddr, mux)
handler := rpc.AuthenticateHandler(mux)
rpc.StartHTTPServer(listenAddr, handler)
}
func (n *Node) Switch() *p2p.Switch {


+ 3
- 3
p2p/connection.go View File

@ -588,9 +588,9 @@ func (ch *Channel) updateStats() {
const (
maxMsgPacketSize = 1024
packetTypePing = byte(0x00)
packetTypePong = byte(0x01)
packetTypeMsg = byte(0x10)
packetTypePing = byte(0x01)
packetTypePong = byte(0x02)
packetTypeMsg = byte(0x03)
)
// Messages in channels are chopped into smaller msgPackets for multiplexing.


+ 1
- 1
rpc/core/accounts.go View File

@ -17,7 +17,7 @@ func GetAccount(address []byte) (*ctypes.ResponseGetAccount, error) {
if account == nil {
account = &acm.Account{
Address: address,
PubKey: acm.PubKeyNil{},
PubKey: nil,
Sequence: 0,
Balance: 0,
Code: nil,


+ 5
- 5
rpc/core_client/client_methods.go View File

@ -18,7 +18,7 @@ type Client interface {
BroadcastTx(tx types.Tx) (*ctypes.ResponseBroadcastTx, error)
Call(address []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)
GetAccount(address []byte) (*ctypes.ResponseGetAccount, 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
}
func (c *ClientHTTP) DumpStorage(addr []byte) (*ctypes.ResponseDumpStorage, error) {
values, err := argsToURLValues([]string{"addr"}, addr)
func (c *ClientHTTP) DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) {
values, err := argsToURLValues([]string{"address"}, address)
if err != nil {
return nil, err
}
@ -558,11 +558,11 @@ func (c *ClientJSON) CallCode(code []byte, data []byte) (*ctypes.ResponseCall, e
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{
JSONRPC: "2.0",
Method: reverseFuncMap["DumpStorage"],
Params: []interface{}{addr},
Params: []interface{}{address},
Id: 0,
}
body, err := c.RequestResponse(request)


+ 2
- 0
rpc/handlers.go View File

@ -101,6 +101,7 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc) http.HandlerFunc {
return
}
returns := rpcFunc.f.Call(args)
log.Debug("HTTPJSONRPC", "method", request.Method, "args", args, "returns", returns)
response, err := unreflectResponse(returns)
if err != nil {
WriteRPCResponse(w, NewRPCResponse(nil, err.Error()))
@ -148,6 +149,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc) func(http.ResponseWriter, *http.Request)
return
}
returns := rpcFunc.f.Call(args)
log.Debug("HTTPRestRPC", "method", r.URL.Path, "args", args, "returns", returns)
response, err := unreflectResponse(returns)
if err != nil {
WriteRPCResponse(w, NewRPCResponse(nil, err.Error()))


+ 36
- 3
rpc/http_server.go View File

@ -4,6 +4,7 @@ package rpc
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"runtime/debug"
"time"
@ -12,12 +13,12 @@ import (
. "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))
go func() {
res := http.ListenAndServe(
listenAddr,
RecoverAndLogHandler(mux),
RecoverAndLogHandler(handler),
)
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.
//
// If the inner function panics, the outer function recovers, logs, sends an
// HTTP 500 error response.
func RecoverAndLogHandler(handler http.Handler) http.Handler {


+ 1
- 1
rpc/test/helpers.go View File

@ -258,7 +258,7 @@ func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types
}
// Check signatures
// 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) {
t.Fatal(types.ErrTxInvalidSignature)
}


+ 6
- 6
state/execution.go View File

@ -159,9 +159,9 @@ func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeade
}
// 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,
// 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) {
accounts := map[string]*account.Account{}
for _, in := range ins {
@ -189,7 +189,7 @@ func getOrMakeAccounts(state AccountGetter, ins []*types.TxInput, outs []*types.
if acc == nil {
acc = &account.Account{
Address: out.Address,
PubKey: account.PubKeyNil{},
PubKey: nil,
Sequence: 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 {
if _, isNil := acc.PubKey.(account.PubKeyNil); isNil {
if _, isNil := in.PubKey.(account.PubKeyNil); isNil {
if acc.PubKey == nil {
if in.PubKey == nil {
return types.ErrTxUnknownPubKey
}
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
} else {
in.PubKey = account.PubKeyNil{}
in.PubKey = nil
}
return nil
}


+ 1
- 1
state/genesis.go View File

@ -61,7 +61,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {
for _, genAcc := range genDoc.Accounts {
acc := &account.Account{
Address: genAcc.Address,
PubKey: account.PubKeyNil{},
PubKey: nil,
Sequence: 0,
Balance: genAcc.Amount,
}


+ 1
- 1
state/tx_cache.go View File

@ -163,7 +163,7 @@ func toVMAccount(acc *ac.Account) *vm.Account {
func toStateAccount(acc *vm.Account) *ac.Account {
pubKey, ok := acc.Other.(ac.PubKey)
if !ok {
pubKey = ac.PubKeyNil{}
pubKey = nil
}
var storageRoot []byte
if acc.StorageRoot.IsZero() {


+ 1
- 1
types/tx.go View File

@ -76,7 +76,7 @@ type TxInput struct {
Amount uint64 // Must not exceed account balance
Sequence uint // Must be 1 greater than the last committed TxInput
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 {


+ 3
- 3
types/vote.go View File

@ -40,9 +40,9 @@ type Vote struct {
// Types of votes
const (
VoteTypePrevote = byte(0x00)
VoteTypePrecommit = byte(0x01)
VoteTypeCommit = byte(0x02)
VoteTypePrevote = byte(0x01)
VoteTypePrecommit = byte(0x02)
VoteTypeCommit = byte(0x03)
)
func (vote *Vote) WriteSignBytes(w io.Writer, n *int64, err *error) {


Loading…
Cancel
Save