Skip to content

Commit

Permalink
SSZ: Switch to Little Endian (#1354)
Browse files Browse the repository at this point in the history
* Change encode to little endian

* Fix decode
  • Loading branch information
houjieth authored and Nishant Das committed Jan 21, 2019
1 parent 779bccb commit 247e8a5
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 138 deletions.
16 changes: 8 additions & 8 deletions shared/ssz/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func decodeUint16(r io.Reader, val reflect.Value) (uint32, error) {
if err := readBytes(r, 2, b); err != nil {
return 0, err
}
val.SetUint(uint64(binary.BigEndian.Uint16(b)))
val.SetUint(uint64(binary.LittleEndian.Uint16(b)))
return 2, nil
}

Expand All @@ -110,7 +110,7 @@ func decodeUint32(r io.Reader, val reflect.Value) (uint32, error) {
if err := readBytes(r, 4, b); err != nil {
return 0, err
}
val.SetUint(uint64(binary.BigEndian.Uint32(b)))
val.SetUint(uint64(binary.LittleEndian.Uint32(b)))
return 4, nil
}

Expand All @@ -119,7 +119,7 @@ func decodeUint64(r io.Reader, val reflect.Value) (uint32, error) {
if err := readBytes(r, 8, b); err != nil {
return 0, err
}
val.SetUint(uint64(binary.BigEndian.Uint64(b)))
val.SetUint(uint64(binary.LittleEndian.Uint64(b)))
return 8, nil
}

Expand All @@ -128,7 +128,7 @@ func decodeBytes(r io.Reader, val reflect.Value) (uint32, error) {
if err := readBytes(r, lengthBytes, sizeEnc); err != nil {
return 0, err
}
size := binary.BigEndian.Uint32(sizeEnc)
size := binary.LittleEndian.Uint32(sizeEnc)

if size == 0 {
val.SetBytes([]byte{})
Expand All @@ -148,7 +148,7 @@ func decodeByteArray(r io.Reader, val reflect.Value) (uint32, error) {
if err := readBytes(r, lengthBytes, sizeEnc); err != nil {
return 0, err
}
size := binary.BigEndian.Uint32(sizeEnc)
size := binary.LittleEndian.Uint32(sizeEnc)

if size != uint32(val.Len()) {
return 0, fmt.Errorf("input byte array size (%d) isn't euqal to output array size (%d)", size, val.Len())
Expand All @@ -172,7 +172,7 @@ func makeSliceDecoder(typ reflect.Type) (decoder, error) {
if err := readBytes(r, lengthBytes, sizeEnc); err != nil {
return 0, fmt.Errorf("failed to decode header of slice: %v", err)
}
size := binary.BigEndian.Uint32(sizeEnc)
size := binary.LittleEndian.Uint32(sizeEnc)

if size == 0 {
// We prefer decode into nil, not empty slice
Expand Down Expand Up @@ -220,7 +220,7 @@ func makeArrayDecoder(typ reflect.Type) (decoder, error) {
if err := readBytes(r, lengthBytes, sizeEnc); err != nil {
return 0, fmt.Errorf("failed to decode header of slice: %v", err)
}
size := binary.BigEndian.Uint32(sizeEnc)
size := binary.LittleEndian.Uint32(sizeEnc)

i, decodeSize := 0, uint32(0)
for ; i < val.Len() && decodeSize < size; i++ {
Expand Down Expand Up @@ -251,7 +251,7 @@ func makeStructDecoder(typ reflect.Type) (decoder, error) {
if err := readBytes(r, lengthBytes, sizeEnc); err != nil {
return 0, fmt.Errorf("failed to decode header of struct: %v", err)
}
size := binary.BigEndian.Uint32(sizeEnc)
size := binary.LittleEndian.Uint32(sizeEnc)

if size == 0 {
return lengthBytes, nil
Expand Down
92 changes: 46 additions & 46 deletions shared/ssz/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,102 +30,102 @@ var decodeTests = []decodeTest{

// uint16
{input: "0000", ptr: new(uint16), value: uint16(0)},
{input: "0001", ptr: new(uint16), value: uint16(1)},
{input: "0010", ptr: new(uint16), value: uint16(16)},
{input: "0080", ptr: new(uint16), value: uint16(128)},
{input: "00FF", ptr: new(uint16), value: uint16(255)},
{input: "0100", ptr: new(uint16), value: uint16(1)},
{input: "1000", ptr: new(uint16), value: uint16(16)},
{input: "8000", ptr: new(uint16), value: uint16(128)},
{input: "FF00", ptr: new(uint16), value: uint16(255)},
{input: "FFFF", ptr: new(uint16), value: uint16(65535)},

// uint32
{input: "00000000", ptr: new(uint32), value: uint32(0)},
{input: "00000001", ptr: new(uint32), value: uint32(1)},
{input: "00000010", ptr: new(uint32), value: uint32(16)},
{input: "00000080", ptr: new(uint32), value: uint32(128)},
{input: "000000FF", ptr: new(uint32), value: uint32(255)},
{input: "0000FFFF", ptr: new(uint32), value: uint32(65535)},
{input: "01000000", ptr: new(uint32), value: uint32(1)},
{input: "10000000", ptr: new(uint32), value: uint32(16)},
{input: "80000000", ptr: new(uint32), value: uint32(128)},
{input: "FF000000", ptr: new(uint32), value: uint32(255)},
{input: "FFFF0000", ptr: new(uint32), value: uint32(65535)},
{input: "FFFFFFFF", ptr: new(uint32), value: uint32(4294967295)},

// uint64
{input: "0000000000000000", ptr: new(uint64), value: uint64(0)},
{input: "0000000000000001", ptr: new(uint64), value: uint64(1)},
{input: "0000000000000010", ptr: new(uint64), value: uint64(16)},
{input: "0000000000000080", ptr: new(uint64), value: uint64(128)},
{input: "00000000000000FF", ptr: new(uint64), value: uint64(255)},
{input: "000000000000FFFF", ptr: new(uint64), value: uint64(65535)},
{input: "00000000FFFFFFFF", ptr: new(uint64), value: uint64(4294967295)},
{input: "0100000000000000", ptr: new(uint64), value: uint64(1)},
{input: "1000000000000000", ptr: new(uint64), value: uint64(16)},
{input: "8000000000000000", ptr: new(uint64), value: uint64(128)},
{input: "FF00000000000000", ptr: new(uint64), value: uint64(255)},
{input: "FFFF000000000000", ptr: new(uint64), value: uint64(65535)},
{input: "FFFFFFFF00000000", ptr: new(uint64), value: uint64(4294967295)},
{input: "FFFFFFFFFFFFFFFF", ptr: new(uint64), value: uint64(18446744073709551615)},

// bytes
{input: "00000000", ptr: new([]byte), value: []byte{}},
{input: "0000000101", ptr: new([]byte), value: []byte{1}},
{input: "00000006 010203040506", ptr: new([]byte), value: []byte{1, 2, 3, 4, 5, 6}},
{input: "00000000", ptr:new([]byte), value: []byte{}},
{input: "0100000001", ptr: new([]byte), value: []byte{1}},
{input: "06000000 010203040506", ptr: new([]byte), value: []byte{1, 2, 3, 4, 5, 6}},

// slice
{input: "00000000", ptr: new([]uint16), value: []uint16(nil)},
{input: "00000004 0001 0002", ptr: new([]uint16), value: []uint16{1, 2}},
{input: "00000018 00000008 0001 0002 0003 0004 00000008 0005 0006 0007 0008", ptr: new([][]uint16),
{input: "04000000 0100 0200", ptr: new([]uint16), value: []uint16{1, 2}},
{input: "18000000 08000000 0100 0200 0300 0400 08000000 0500 0600 0700 0800", ptr: new([][]uint16),
value: [][]uint16{
{1, 2, 3, 4},
{5, 6, 7, 8},
},
},

// array
{input: "00000001 01", ptr: new([1]byte), value: [1]byte{1}},
{input: "00000006 010203040506", ptr: new([6]byte), value: [6]byte{1, 2, 3, 4, 5, 6}},
{input: "00000002 0001", ptr: new([1]uint16), value: [1]uint16{1}},
{input: "00000004 0001 0002", ptr: new([2]uint16), value: [2]uint16{1, 2}},
{input: "00000018 00000008 0001 0002 0003 0004 00000008 0005 0006 0007 0008", ptr: new([2][4]uint16),
{input: "01000000 01", ptr: new([1]byte), value: [1]byte{1}},
{input: "06000000 010203040506", ptr: new([6]byte), value: [6]byte{1, 2, 3, 4, 5, 6}},
{input: "02000000 0100", ptr: new([1]uint16), value: [1]uint16{1}},
{input: "04000000 0100 0200", ptr: new([2]uint16), value: [2]uint16{1, 2}},
{input: "18000000 08000000 0100 0200 0300 0400 08000000 0500 0600 0700 0800", ptr: new([2][4]uint16),
value: [2][4]uint16{
{1, 2, 3, 4},
{5, 6, 7, 8},
},
},

// struct
{input: "00000003 00 0000", ptr: new(simpleStruct), value: simpleStruct{}},
{input: "00000003 0002 01", ptr: new(simpleStruct), value: simpleStruct{B: 2, A: 1}},
{input: "00000007 03 00000002 0006", ptr: new(outerStruct),
{input: "03000000 00 0000", ptr: new(simpleStruct), value: simpleStruct{}},
{input: "03000000 0200 01", ptr: new(simpleStruct), value: simpleStruct{B: 2, A: 1}},
{input: "07000000 03 02000000 0600", ptr: new(outerStruct),
value: outerStruct{
V: 3,
SubV: innerStruct{6},
}},

// slice + struct
{input: "00000012 0000000E 00000003 000201 00000003 000403", ptr: new(arrayStruct),
{input: "12000000 0E000000 03000000 020001 03000000 040003", ptr: new(arrayStruct),
value: arrayStruct{
V: []simpleStruct{
{B: 2, A: 1},
{B: 4, A: 3},
},
}},
{input: "00000016 00000007 03 00000002 0006 00000007 05 00000002 0007", ptr: new([]outerStruct),
{input: "16000000 07000000 03 02000000 0600 07000000 05 02000002 0700", ptr: new([]outerStruct),
value: []outerStruct{
{V: 3, SubV: innerStruct{V: 6}},
{V: 5, SubV: innerStruct{V: 7}},
}},

// pointer
{input: "00000003 0002 01", ptr: new(*simpleStruct), value: &simpleStruct{B: 2, A: 1}},
{input: "00000008 00000003 0002 01 03", ptr: new(pointerStruct),
{input: "03000000 0200 01", ptr: new(*simpleStruct), value: &simpleStruct{B: 2, A: 1}},
{input: "08000000 03000000 0200 01 03", ptr: new(pointerStruct),
value: pointerStruct{P: &simpleStruct{B: 2, A: 1}, V: 3}},
{input: "00000008 00000003 0002 01 03", ptr: new(*pointerStruct),
{input: "08000000 03000000 0200 01 03", ptr: new(*pointerStruct),
value: &pointerStruct{P: &simpleStruct{B: 2, A: 1}, V: 3}},
{input: "00000004 01020304", ptr: new(*[]uint8), value: &[]uint8{1, 2, 3, 4}},
{input: "00000010 0000000000000001 0000000000000002", ptr: new(*[]uint64), value: &[]uint64{1, 2}},
{input: "0000000E 00000003 0002 01 00000003 0004 03", ptr: new([]*simpleStruct),
{input: "04000000 01020304", ptr: new(*[]uint8), value: &[]uint8{1, 2, 3, 4}},
{input: "10000000 0100000000000000 0200000000000000", ptr: new(*[]uint64), value: &[]uint64{1, 2}},
{input: "0E000000 03000000 0200 01 03000000 0400 03", ptr: new([]*simpleStruct),
value: []*simpleStruct{
{B: 2, A: 1},
{B: 4, A: 3},
},
},
{input: "0000000E 00000003 0002 01 00000003 0004 03", ptr: new([2]*simpleStruct),
{input: "0E000000 03000000 0200 01 03000000 0400 03", ptr: new([2]*simpleStruct),
value: [2]*simpleStruct{
{B: 2, A: 1},
{B: 4, A: 3},
},
},
{input: "00000018 00000008 00000003 0002 01 00 00000008 00000003 0004 03 01", ptr: new([]*pointerStruct),
{input: "18000000 08000000 03000000 0200 01 00 08000000 03000000 0400 03 01", ptr: new([]*pointerStruct),
value: []*pointerStruct{
{P: &simpleStruct{B: 2, A: 1}, V: 0},
{P: &simpleStruct{B: 4, A: 3}, V: 1},
Expand All @@ -148,28 +148,28 @@ var decodeTests = []decodeTest{
{input: "00", ptr: new(uint16), error: "decode error: can only read 1 bytes while expected to read 2 bytes for output type uint16"},

// error: bytes: wrong input
{input: "00000001", ptr: new([]byte), error: "decode error: can only read 0 bytes while expected to read 1 bytes for output type []uint8"},
{input: "01000000", ptr: new([]byte), error: "decode error: can only read 0 bytes while expected to read 1 bytes for output type []uint8"},

// error: slice: wrong header
{input: "000001", ptr: new([]uint16), error: "decode error: failed to decode header of slice: can only read 3 bytes while expected to read 4 bytes for output type []uint16"},
{input: "010000", ptr: new([]uint16), error: "decode error: failed to decode header of slice: can only read 3 bytes while expected to read 4 bytes for output type []uint16"},

// error: slice: wrong input
{input: "00000001", ptr: new([]uint16), error: "decode error: failed to decode element of slice: can only read 0 bytes while expected to read 2 bytes for output type []uint16"},
{input: "01000000", ptr: new([]uint16), error: "decode error: failed to decode element of slice: can only read 0 bytes while expected to read 2 bytes for output type []uint16"},

// error: byte array: wrong input
{input: "00000001 01", ptr: new([2]byte), error: "decode error: input byte array size (1) isn't euqal to output array size (2) for output type [2]uint8"},
{input: "01000000 01", ptr: new([2]byte), error: "decode error: input byte array size (1) isn't euqal to output array size (2) for output type [2]uint8"},

// error: array: input too short
{input: "00000002 0001", ptr: new([2]uint16), error: "decode error: input is too short for output type [2]uint16"},
{input: "02000000 0100", ptr: new([2]uint16), error: "decode error: input is too short for output type [2]uint16"},

// error: array: input too long
{input: "00000004 0001 0002", ptr: new([1]uint16), error: "decode error: input is too long for output type [1]uint16"},
{input: "04000000 0100 0200", ptr: new([1]uint16), error: "decode error: input is too long for output type [1]uint16"},

// error: struct: wrong header
{input: "000001", ptr: new(simpleStruct), error: "decode error: failed to decode header of struct: can only read 3 bytes while expected to read 4 bytes for output type ssz.simpleStruct"},
{input: "010000", ptr: new(simpleStruct), error: "decode error: failed to decode header of struct: can only read 3 bytes while expected to read 4 bytes for output type ssz.simpleStruct"},

// error: struct: wrong input
{input: "00000003 01 02", ptr: new(simpleStruct), error: "decode error: failed to decode field of slice: can only read 0 bytes while expected to read 1 bytes for output type ssz.simpleStruct"},
{input: "03000000 01 02", ptr: new(simpleStruct), error: "decode error: failed to decode field of slice: can only read 0 bytes while expected to read 1 bytes for output type ssz.simpleStruct"},
}

func runTests(t *testing.T, decode func([]byte, interface{}) error) {
Expand Down
14 changes: 7 additions & 7 deletions shared/ssz/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,23 +121,23 @@ func encodeUint8(val reflect.Value, w *encbuf) error {
func encodeUint16(val reflect.Value, w *encbuf) error {
v := val.Uint()
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, uint16(v))
binary.LittleEndian.PutUint16(b, uint16(v))
w.str = append(w.str, b...)
return nil
}

func encodeUint32(val reflect.Value, w *encbuf) error {
v := val.Uint()
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, uint32(v))
binary.LittleEndian.PutUint32(b, uint32(v))
w.str = append(w.str, b...)
return nil
}

func encodeUint64(val reflect.Value, w *encbuf) error {
v := val.Uint()
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(v))
binary.LittleEndian.PutUint64(b, uint64(v))
w.str = append(w.str, b...)
return nil
}
Expand All @@ -149,7 +149,7 @@ func makeBytesEncoder() (encoder, encodeSizer, error) {
if len(val.Bytes()) >= 2<<32 {
return errors.New("bytes oversize")
}
binary.BigEndian.PutUint32(sizeEnc, uint32(len(b)))
binary.LittleEndian.PutUint32(sizeEnc, uint32(len(b)))
w.str = append(w.str, sizeEnc...)
w.str = append(w.str, val.Bytes()...)
return nil
Expand All @@ -176,7 +176,7 @@ func makeByteArrayEncoder() (encoder, encodeSizer, error) {
if val.Len() >= 2<<32 {
return errors.New("bytes oversize")
}
binary.BigEndian.PutUint32(sizeEnc, uint32(val.Len()))
binary.LittleEndian.PutUint32(sizeEnc, uint32(val.Len()))
w.str = append(w.str, sizeEnc...)
w.str = append(w.str, val.Slice(0, val.Len()).Bytes()...)
return nil
Expand Down Expand Up @@ -208,7 +208,7 @@ func makeSliceEncoder(typ reflect.Type) (encoder, encodeSizer, error) {
if totalSize >= 2<<32 {
return errors.New("slice oversize")
}
binary.BigEndian.PutUint32(totalSizeEnc, uint32(totalSize))
binary.LittleEndian.PutUint32(totalSizeEnc, uint32(totalSize))
copy(w.str[origBufSize:origBufSize+lengthBytes], totalSizeEnc)
return nil
}
Expand Down Expand Up @@ -243,7 +243,7 @@ func makeStructEncoder(typ reflect.Type) (encoder, encodeSizer, error) {
if totalSize >= 2<<32 {
return errors.New("struct oversize")
}
binary.BigEndian.PutUint32(totalSizeEnc, uint32(totalSize))
binary.LittleEndian.PutUint32(totalSizeEnc, uint32(totalSize))
copy(w.str[origBufSize:origBufSize+lengthBytes], totalSizeEnc)
return nil
}
Expand Down
Loading

0 comments on commit 247e8a5

Please sign in to comment.