Skip to content

Commit

Permalink
Better bytes of bytes encoding (#279)
Browse files Browse the repository at this point in the history
  • Loading branch information
matYang authored Nov 10, 2023
1 parent 0d3027a commit 2ae9b59
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 9 deletions.
34 changes: 25 additions & 9 deletions core/services/ocr2/plugins/ccip/internal/hashlib/common.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package hashlib

import (
"strconv"
"bytes"
"encoding/binary"

"github.com/smartcontractkit/chainlink/v2/core/utils"
)
Expand All @@ -12,16 +13,31 @@ func BytesOfBytesKeccak(b [][]byte) ([32]byte, error) {
return [32]byte{}, nil
}

joinedBytes := make([]byte, 0)
joinedBytes = append(joinedBytes, intToBytes(int64(len(b)))...)
for i := range b {
joinedBytes = append(joinedBytes, intToBytes(int64(len(b[i])))...)
joinedBytes = append(joinedBytes, b[i]...)
encodedArr, err := encodeBytesOfBytes(b)
if err != nil {
return [32]byte{}, err
}

return utils.Keccak256Fixed(joinedBytes), nil
return utils.Keccak256Fixed(encodedArr), nil
}

func intToBytes(v int64) []byte {
return []byte(strconv.FormatInt(v, 10))
// encodeBytesOfBytes encodes the nested byte arrays into a single byte array as follows
// 1. total number of nested arrays is encoded into fix-size 8 bytes at the front of the result
// 2. for each nested array
// encode the array length into fixed-size 8 bytes, append to result
// append the array contents to result
func encodeBytesOfBytes(b [][]byte) ([]byte, error) {
var buffer bytes.Buffer
if err := binary.Write(&buffer, binary.BigEndian, uint64(len(b))); err != nil {
return nil, err
}
for _, arr := range b {
if err := binary.Write(&buffer, binary.BigEndian, uint64(len(arr))); err != nil {
return nil, err
}
if _, err := buffer.Write(arr); err != nil {
return nil, err
}
}
return buffer.Bytes(), nil
}
49 changes: 49 additions & 0 deletions core/services/ocr2/plugins/ccip/internal/hashlib/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,52 @@ func TestBytesOfBytesKeccak(t *testing.T) {
})

}

func TestBytesOfBytesEncoding(t *testing.T) {
tests := []struct {
name string
input [][]byte
expected []byte
}{
{
name: "0 sub array, empty slice",
input: [][]byte{},
expected: []byte{
0, 0, 0, 0, 0, 0, 0, 0,
},
},
{
name: "1 sub array",
input: [][]byte{
{0, 1, 2, 3},
},
expected: []byte{
0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 2, 3,
},
},
{
name: "3 sub array",
input: [][]byte{
{0, 1, 2, 3},
{0, 0, 0},
{7, 8},
},
expected: []byte{
0, 0, 0, 0, 0, 0, 0, 3,
0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 2, 3,
0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2, 7, 8,
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
encoded, err := encodeBytesOfBytes(tt.input)
assert.NoError(t, err)

assert.Equal(t, tt.expected, encoded)
})
}
}

0 comments on commit 2ae9b59

Please sign in to comment.