Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scale: allocate slice elements when decoding #587

Merged
merged 10 commits into from
Feb 3, 2020
Merged
27 changes: 20 additions & 7 deletions codec/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,6 @@ func (sd *Decoder) DecodeArray(t interface{}) (interface{}, error) {
v = reflect.ValueOf(t)
}

if v.Len() == 0 {
return t, nil
}

var err error
var o interface{}

Expand All @@ -341,10 +337,12 @@ func (sd *Decoder) DecodeArray(t interface{}) (interface{}, error) {
return t, nil
}

sl := reflect.MakeSlice(v.Type(), int(length), int(length))

for i := 0; i < int(length); i++ {
arrayValue := v.Index(i)
arrayValue := sl.Index(i)

switch v.Index(i).Interface().(type) {
switch sl.Index(i).Interface().(type) {
case []byte:
o, err = sd.DecodeByteArray()
if err != nil {
Expand All @@ -371,7 +369,14 @@ func (sd *Decoder) DecodeArray(t interface{}) (interface{}, error) {
}
}

return t, err
switch t.(type) {
case [][]byte:
copy(t.([][]byte), sl.Interface().([][]byte))
case [][32]byte:
copy(t.([][32]byte), sl.Interface().([][32]byte))
}

return sl.Interface(), err
}

// DecodeTuple accepts a byte array representing the SCALE encoded tuple and an interface. This interface should be a pointer
Expand Down Expand Up @@ -415,6 +420,14 @@ func (sd *Decoder) DecodeTuple(t interface{}) (interface{}, error) {
// get the pointer to the value and set the value
ptr := fieldValue.(*[]byte)
*ptr = o.([]byte)
case [][]byte:
o, err = sd.DecodeArray([][]byte{})
if err != nil {
break
}

ptr := fieldValue.(*[][]byte)
*ptr = o.([][]byte)
case int8:
o, err = sd.DecodeFixedWidthInt(int8(0))
if err != nil {
Expand Down
11 changes: 6 additions & 5 deletions codec/decode_ptr.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,20 +193,21 @@ func (sd *Decoder) DecodePtrBool(output interface{}) error {

// DecodePtrIntArray decodes a byte array to an array of ints
func (sd *Decoder) DecodePtrIntArray(t interface{}) error {
_, err := sd.DecodeInteger()
length, err := sd.DecodeInteger()
if err != nil {
return err
}

for i := range t.([]int) {
//var temp int64
//var err error
sl := make([]int, length)
for i := range sl {
temp, err := sd.DecodeInteger()
t.([]int)[i] = int(temp)
sl[i] = int(temp)
if err != nil {
break
}
}

copy(t.([]int), sl)
return nil
}

Expand Down
33 changes: 32 additions & 1 deletion codec/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ var decodeTupleTests = []decodeTupleTest{
}

var decodeArrayTests = []decodeArrayTest{
{val: []byte{}, t: [][]byte{}, output: [][]byte{}},
{val: []byte{0x00}, t: []int{}, output: []int{}},
{val: []byte{0x04, 0x04}, t: make([]int, 1), output: []int{1}},
{val: []byte{0x10, 0x04, 0x08, 0x0c, 0x10}, t: make([]int, 4), output: []int{1, 2, 3, 4}},
Expand Down Expand Up @@ -508,3 +507,35 @@ func TestDecodeArrays(t *testing.T) {
}
}
}

func TestDecodeEmptyArray(t *testing.T) {
expected := &struct {
Number *big.Int
Digest [][]byte
}{
big.NewInt(9),
[][]byte{{0xa, 0xb, 0xc, 0xd}, {0xe, 0xf}},
}

testStruct := &struct {
Number *big.Int
Digest [][]byte
}{
big.NewInt(0),
[][]byte{},
}

enc, err := Encode(expected)
if err != nil {
t.Fatal(err)
}

output, err := Decode(enc, testStruct)
if err != nil {
t.Fatal(err)
}

if !reflect.DeepEqual(output, expected) {
t.Fatalf("Fail: got %v expected %v", output, expected)
}
}
8 changes: 4 additions & 4 deletions consensus/babe/babe.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ func (b *Session) buildBlock(parent *types.Header, slot Slot) (*types.Block, err
// initialize block header
encodedHeader, err := scale.Encode(header)
if err != nil {
return nil, err
return nil, fmt.Errorf("cannot encode header: %s", err)
}
err = b.initializeBlock(encodedHeader)
if err != nil {
Expand All @@ -304,21 +304,21 @@ func (b *Session) buildBlock(parent *types.Header, slot Slot) (*types.Block, err
// add block inherents
err = b.buildBlockInherents(slot)
if err != nil {
return nil, err
return nil, fmt.Errorf("cannot build inherents: %s", err)
}

// add block extrinsics
included, err := b.buildBlockExtrinsics(slot)
if err != nil {
return nil, err
return nil, fmt.Errorf("cannot build extrisnics: %s", err)
}

// finalize block
log.Trace("build_block finalize block")
block, err := b.finalizeBlock()
if err != nil {
b.addToQueue(included)
return nil, err
return nil, fmt.Errorf("cannot finalize block: %s", err)
}

block.Header.ParentHash = parent.Hash()
Expand Down
13 changes: 7 additions & 6 deletions consensus/babe/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ func (b *Session) finalizeBlock() (*types.Block, error) {
return nil, err
}

bh := &types.Block{
Header: new(types.Header),
Body: new(types.Body),
}

// TODO: finalize block actually returns a header, not a block. need to update this function
// as well as buildBlock
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bh := new(types.Header)
_, err = scale.Decode(data, bh)
return bh, err
return &types.Block{
Header: bh,
Body: nil,
}, err
}
2 changes: 1 addition & 1 deletion core/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func TestValidateTransaction(t *testing.T) {
// https://github.com/paritytech/substrate/blob/ea2644a235f4b189c8029b9c9eac9d4df64ee91e/core/test-runtime/src/system.rs#L190
expected := &transaction.Validity{
Priority: 69,
Requires: [][]byte{{}},
Requires: [][]byte{},
// https://github.com/paritytech/substrate/blob/ea2644a235f4b189c8029b9c9eac9d4df64ee91e/core/test-runtime/src/system.rs#L173
Provides: [][]byte{{146, 157, 61, 99, 63, 98, 30, 242, 128, 49, 150, 90, 140, 165, 187, 249}},
Longevity: 64,
Expand Down
2 changes: 1 addition & 1 deletion p2p/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ func TestDecodeBlockAnnounceMessage(t *testing.T) {
Number: big.NewInt(1),
StateRoot: stateRoot,
ExtrinsicsRoot: extrinsicsRoot,
Digest: nil,
Digest: [][]byte{},
}

if !reflect.DeepEqual(bhm, expected) {
Expand Down