Skip to content

Commit

Permalink
Add missing hasher - substrate rc3 version support (centrifuge#89)
Browse files Browse the repository at this point in the history
* Revert "Add ExtrinsicSignatureV5 (centrifuge#68)"

This reverts commit 461cf42.

* Add missing hasher

* review comments

* fix test
  • Loading branch information
mikiquantum authored and LeeSmet committed Aug 28, 2020
1 parent 9cfd4a7 commit 3010561
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 4 deletions.
78 changes: 78 additions & 0 deletions hash/blake2b.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls
//
// Copyright 2019 Centrifuge GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package hash

import (
"hash"

"golang.org/x/crypto/blake2b"
)

type blake2b128Concat struct {
hasher hash.Hash
data []byte
}

// NewBlake2b128Concat returns an instance of blake2b concat hasher
func NewBlake2b128Concat(k []byte) (hash.Hash, error) {
h, err := blake2b.New(16, k)
if err != nil {
return nil, err
}
return &blake2b128Concat{hasher: h, data: k}, nil
}

// Write (via the embedded io.Writer interface) adds more data to the running hash.
func (bc *blake2b128Concat) Write(p []byte) (n int, err error) {
bc.data = append(bc.data, p...)
return bc.hasher.Write(p)
}

// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
func (bc *blake2b128Concat) Sum(b []byte) []byte {
return append(bc.hasher.Sum(b), bc.data...)
}

// Reset resets the Hash to its initial state.
func (bc *blake2b128Concat) Reset() {
bc.data = nil
bc.hasher.Reset()
}

// Size returns the number of bytes Sum will return.
func (bc *blake2b128Concat) Size() int {
return len(bc.Sum(nil))
}

// BlockSize returns the hash's underlying block size.
// The Write method must be able to accept any amount
// of data, but it may operate more efficiently if all writes
// are a multiple of the block size.
func (bc *blake2b128Concat) BlockSize() int {
return bc.hasher.BlockSize()
}

// NewBlake2b128 returns blake2b-128 hasher
func NewBlake2b128(k []byte) (hash.Hash, error) {
return blake2b.New(16, k)
}

// NewBlake2b256 returns blake2b-256 hasher
func NewBlake2b256(k []byte) (hash.Hash, error) {
return blake2b.New256(k)
}
38 changes: 38 additions & 0 deletions hash/blake2b_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls
//
// Copyright 2019 Centrifuge GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package hash

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestBlake2_128Concat(t *testing.T) {
h, err := NewBlake2b128Concat(nil)
assert.NoError(t, err)
n, err := h.Write([]byte("abc"))
assert.NoError(t, err)
assert.Equal(t, 3, n)
assert.Equal(t, []byte{
0xcf, 0x4a, 0xb7, 0x91, 0xc6, 0x2b, 0x8d, 0x2b, 0x21, 0x9, 0xc9, 0x2, 0x75, 0x28, 0x78, 0x16, 0x61, 0x62, 0x63,
}, h.Sum(nil))
assert.Equal(t, 128, h.BlockSize())
assert.Equal(t, 19, h.Size())
h.Reset()
assert.Equal(t, 16, h.Size())
}
60 changes: 60 additions & 0 deletions hash/identity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls
//
// Copyright 2019 Centrifuge GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package hash

import (
"hash"
)

type identity struct {
data []byte
}

func NewIdentity(b []byte) hash.Hash {
return &identity{data: b}
}

// Write (via the embedded io.Writer interface) adds more data to the running hash.
// It never returns an error.
func (i *identity) Write(p []byte) (n int, err error) {
i.data = append(i.data, p...)
return len(p), nil
}

// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
func (i *identity) Sum(b []byte) []byte {
return append(b, i.data...)
}

// Reset resets the Hash to its initial state.
func (i *identity) Reset() {
i.data = make([]byte, 0)
}

// Size returns the number of bytes Sum will return.
func (i *identity) Size() int {
return len(i.Sum(nil))
}

// BlockSize returns the hash's underlying block size.
// The Write method must be able to accept any amount
// of data, but it may operate more efficiently if all writes
// are a multiple of the block size.
func (i *identity) BlockSize() int {
return 0
}
28 changes: 28 additions & 0 deletions hash/identity_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls
//
// Copyright 2019 Centrifuge GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package hash

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestIdentity(t *testing.T) {
h := NewIdentity([]byte("abc"))
assert.Equal(t, []byte{0x61, 0x62, 0x63}, h.Sum(nil))
}
18 changes: 14 additions & 4 deletions types/metadataV10.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"hash"
"strings"

"github.com/leesmet/go-substrate-rpc-client/blake2b"
ghash "github.com/leesmet/go-substrate-rpc-client/hash"
"github.com/leesmet/go-substrate-rpc-client/scale"
"github.com/leesmet/go-substrate-rpc-client/xxhash"
)
Expand Down Expand Up @@ -367,6 +367,7 @@ type StorageHasherV10 struct {
IsTwox128 bool // 3
IsTwox256 bool // 4
IsTwox64Concat bool // 5
IsIdentity bool // 6
}

func (s *StorageHasherV10) Decode(decoder scale.Decoder) error {
Expand All @@ -389,6 +390,8 @@ func (s *StorageHasherV10) Decode(decoder scale.Decoder) error {
s.IsTwox256 = true
case 5:
s.IsTwox64Concat = true
case 6:
s.IsIdentity = true
default:
return fmt.Errorf("received unexpected storage hasher type %v", t)
}
Expand All @@ -410,6 +413,8 @@ func (s StorageHasherV10) Encode(encoder scale.Encoder) error {
t = 4
case s.IsTwox64Concat:
t = 5
case s.IsIdentity:
t = 6
default:
return fmt.Errorf("expected storage hasher, but none was set: %v", s)
}
Expand All @@ -419,17 +424,17 @@ func (s StorageHasherV10) Encode(encoder scale.Encoder) error {
func (s StorageHasherV10) HashFunc() (hash.Hash, error) {
// Blake2_128
if s.IsBlake2_128 {
return blake2b.New128(nil)
return ghash.NewBlake2b128(nil)
}

// Blake2_256
if s.IsBlake2_256 {
return blake2b.New256(nil)
return ghash.NewBlake2b256(nil)
}

// Blake2_128Concat
if s.IsBlake2_128Concat {
return blake2b.New128Concat(nil)
return ghash.NewBlake2b128Concat(nil)
}

// Twox128
Expand All @@ -447,5 +452,10 @@ func (s StorageHasherV10) HashFunc() (hash.Hash, error) {
return xxhash.New64Concat(nil), nil
}

// Identity
if s.IsIdentity {
return ghash.NewIdentity(nil), nil
}

return nil, errors.New("hash function type not yet supported")
}

0 comments on commit 3010561

Please sign in to comment.