forked from TrueCloudLab/frostfs-sdk-go
[#170] checksum: Drop Empty
method
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
9c502a9cae
commit
fd13e61266
11 changed files with 188 additions and 253 deletions
|
@ -1,15 +1,23 @@
|
||||||
package checksum
|
package checksum
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
|
"github.com/nspcc-dev/tzhash/tz"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Checksum represents v2-compatible checksum.
|
// Checksum represents checksum of some digital data.
|
||||||
|
//
|
||||||
|
// Checksum is mutually compatible with github.com/nspcc-dev/neofs-api-go/v2/refs.Checksum
|
||||||
|
// message. See ReadFromV2 / WriteToV2 methods.
|
||||||
|
//
|
||||||
|
// Instances can be created using built-in var declaration.
|
||||||
|
//
|
||||||
|
// Note that direct typecast is not safe and may result in loss of compatibility:
|
||||||
|
// _ = Checksum(refs.Checksum{}) // not recommended
|
||||||
type Checksum refs.Checksum
|
type Checksum refs.Checksum
|
||||||
|
|
||||||
// Type represents the enumeration
|
// Type represents the enumeration
|
||||||
|
@ -23,29 +31,33 @@ const (
|
||||||
// SHA256 is a SHA256 checksum type.
|
// SHA256 is a SHA256 checksum type.
|
||||||
SHA256
|
SHA256
|
||||||
|
|
||||||
// TZ is a Tillich-Zemor checksum type.
|
// TZ is a Tillich-Zémor checksum type.
|
||||||
TZ
|
TZ
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewFromV2 wraps v2 Checksum message to Checksum.
|
// ReadFromV2 reads Checksum from the refs.Checksum message.
|
||||||
//
|
//
|
||||||
// Nil refs.Checksum converts to nil.
|
// See also WriteToV2.
|
||||||
func NewFromV2(cV2 *refs.Checksum) *Checksum {
|
func (c *Checksum) ReadFromV2(m refs.Checksum) {
|
||||||
return (*Checksum)(cV2)
|
*c = Checksum(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates and initializes blank Checksum.
|
// WriteToV2 writes Checksum to the refs.Checksum message.
|
||||||
|
// The message must not be nil.
|
||||||
//
|
//
|
||||||
// Defaults:
|
// See also ReadFromV2.
|
||||||
// - sum: nil;
|
func (c Checksum) WriteToV2(m *refs.Checksum) {
|
||||||
// - type: Unknown.
|
*m = (refs.Checksum)(c)
|
||||||
func New() *Checksum {
|
|
||||||
return NewFromV2(new(refs.Checksum))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type returns checksum type.
|
// Type returns checksum type.
|
||||||
func (c *Checksum) Type() Type {
|
//
|
||||||
switch (*refs.Checksum)(c).GetType() {
|
// Zero Checksum has Unknown checksum type.
|
||||||
|
//
|
||||||
|
// See also SetTillichZemor and SetSHA256.
|
||||||
|
func (c Checksum) Type() Type {
|
||||||
|
v2 := (refs.Checksum)(c)
|
||||||
|
switch v2.GetType() {
|
||||||
case refs.SHA256:
|
case refs.SHA256:
|
||||||
return SHA256
|
return SHA256
|
||||||
case refs.TillichZemor:
|
case refs.TillichZemor:
|
||||||
|
@ -55,93 +67,77 @@ func (c *Checksum) Type() Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sum returns checksum bytes.
|
// Value returns checksum bytes. Return value
|
||||||
func (c *Checksum) Sum() []byte {
|
// MUST NOT be mutated.
|
||||||
return (*refs.Checksum)(c).GetSum()
|
//
|
||||||
|
// Zero Checksum has nil sum.
|
||||||
|
//
|
||||||
|
// See also SetTillichZemor and SetSHA256.
|
||||||
|
func (c Checksum) Value() []byte {
|
||||||
|
v2 := (refs.Checksum)(c)
|
||||||
|
return v2.GetSum()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSHA256 sets checksum to SHA256 hash.
|
// SetSHA256 sets checksum to SHA256 hash.
|
||||||
|
//
|
||||||
|
// See also Calculate.
|
||||||
func (c *Checksum) SetSHA256(v [sha256.Size]byte) {
|
func (c *Checksum) SetSHA256(v [sha256.Size]byte) {
|
||||||
checksum := (*refs.Checksum)(c)
|
v2 := (*refs.Checksum)(c)
|
||||||
|
|
||||||
checksum.SetType(refs.SHA256)
|
v2.SetType(refs.SHA256)
|
||||||
checksum.SetSum(v[:])
|
v2.SetSum(v[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTillichZemor sets checksum to Tillich-Zemor hash.
|
// Calculate calculates checksum and sets it
|
||||||
func (c *Checksum) SetTillichZemor(v [64]byte) {
|
// to the passed checksum. Checksum must not be nil.
|
||||||
checksum := (*refs.Checksum)(c)
|
|
||||||
|
|
||||||
checksum.SetType(refs.TillichZemor)
|
|
||||||
checksum.SetSum(v[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 converts Checksum to v2 Checksum message.
|
|
||||||
//
|
//
|
||||||
// Nil Checksum converts to nil.
|
// Does nothing if the passed type is not one of the:
|
||||||
func (c *Checksum) ToV2() *refs.Checksum {
|
// * SHA256;
|
||||||
return (*refs.Checksum)(c)
|
// * TZ.
|
||||||
}
|
//
|
||||||
|
// Does not mutate the passed value.
|
||||||
func Equal(cs1, cs2 *Checksum) bool {
|
//
|
||||||
return cs1.Type() == cs2.Type() && bytes.Equal(cs1.Sum(), cs2.Sum())
|
// See also SetSHA256, SetTillichZemor.
|
||||||
}
|
func Calculate(c *Checksum, t Type, v []byte) {
|
||||||
|
switch t {
|
||||||
// Marshal marshals Checksum into a protobuf binary form.
|
case SHA256:
|
||||||
func (c *Checksum) Marshal() ([]byte, error) {
|
c.SetSHA256(sha256.Sum256(v))
|
||||||
return (*refs.Checksum)(c).StableMarshal(nil)
|
case TZ:
|
||||||
}
|
c.SetTillichZemor(tz.Sum(v))
|
||||||
|
|
||||||
// Unmarshal unmarshals protobuf binary representation of Checksum.
|
|
||||||
func (c *Checksum) Unmarshal(data []byte) error {
|
|
||||||
return (*refs.Checksum)(c).Unmarshal(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Checksum to protobuf JSON format.
|
|
||||||
func (c *Checksum) MarshalJSON() ([]byte, error) {
|
|
||||||
return (*refs.Checksum)(c).MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Checksum from protobuf JSON format.
|
|
||||||
func (c *Checksum) UnmarshalJSON(data []byte) error {
|
|
||||||
return (*refs.Checksum)(c).UnmarshalJSON(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Checksum) String() string {
|
|
||||||
return hex.EncodeToString((*refs.Checksum)(c).GetSum())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses Checksum from its string representation.
|
|
||||||
func (c *Checksum) Parse(s string) error {
|
|
||||||
data, err := hex.DecodeString(s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var typ refs.ChecksumType
|
|
||||||
|
|
||||||
switch ln := len(data); ln {
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported checksum length %d", ln)
|
}
|
||||||
case sha256.Size:
|
|
||||||
typ = refs.SHA256
|
|
||||||
case 64:
|
|
||||||
typ = refs.TillichZemor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cV2 := (*refs.Checksum)(c)
|
// SetTillichZemor sets checksum to Tillich-Zémor hash.
|
||||||
cV2.SetType(typ)
|
|
||||||
cV2.SetSum(data)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns string representation of Type.
|
|
||||||
//
|
//
|
||||||
// String mapping:
|
// See also Calculate.
|
||||||
// * TZ: TZ;
|
func (c *Checksum) SetTillichZemor(v [tz.Size]byte) {
|
||||||
// * SHA256: SHA256;
|
v2 := (*refs.Checksum)(c)
|
||||||
// * Unknown, default: CHECKSUM_TYPE_UNSPECIFIED.
|
|
||||||
|
v2.SetType(refs.TillichZemor)
|
||||||
|
v2.SetSum(v[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
//
|
||||||
|
// String is designed to be human-readable, and its format MAY differ between
|
||||||
|
// SDK versions.
|
||||||
|
func (c Checksum) String() string {
|
||||||
|
v2 := (refs.Checksum)(c)
|
||||||
|
return fmt.Sprintf("%s:%s", c.Type(), hex.EncodeToString(v2.GetSum()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty returns true if it is called on
|
||||||
|
// zero checksum.
|
||||||
|
func (c Checksum) Empty() bool {
|
||||||
|
v2 := (refs.Checksum)(c)
|
||||||
|
return v2.GetSum() == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
//
|
||||||
|
// String is designed to be human-readable, and its format MAY differ between
|
||||||
|
// SDK versions.
|
||||||
func (m Type) String() string {
|
func (m Type) String() string {
|
||||||
var m2 refs.ChecksumType
|
var m2 refs.ChecksumType
|
||||||
|
|
||||||
|
@ -156,26 +152,3 @@ func (m Type) String() string {
|
||||||
|
|
||||||
return m2.String()
|
return m2.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromString parses Type from a string representation.
|
|
||||||
// It is a reverse action to String().
|
|
||||||
//
|
|
||||||
// Returns true if s was parsed successfully.
|
|
||||||
func (m *Type) FromString(s string) bool {
|
|
||||||
var g refs.ChecksumType
|
|
||||||
|
|
||||||
ok := g.FromString(s)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
switch g {
|
|
||||||
default:
|
|
||||||
*m = Unknown
|
|
||||||
case refs.TillichZemor:
|
|
||||||
*m = TZ
|
|
||||||
case refs.SHA256:
|
|
||||||
*m = SHA256
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,19 +6,12 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
|
"github.com/nspcc-dev/tzhash/tz"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func randSHA256(t *testing.T) [sha256.Size]byte {
|
|
||||||
cSHA256 := [sha256.Size]byte{}
|
|
||||||
_, err := rand.Read(cSHA256[:])
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return cSHA256
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksum(t *testing.T) {
|
func TestChecksum(t *testing.T) {
|
||||||
c := New()
|
var c Checksum
|
||||||
|
|
||||||
cSHA256 := [sha256.Size]byte{}
|
cSHA256 := [sha256.Size]byte{}
|
||||||
_, _ = rand.Read(cSHA256[:])
|
_, _ = rand.Read(cSHA256[:])
|
||||||
|
@ -26,150 +19,62 @@ func TestChecksum(t *testing.T) {
|
||||||
c.SetSHA256(cSHA256)
|
c.SetSHA256(cSHA256)
|
||||||
|
|
||||||
require.Equal(t, SHA256, c.Type())
|
require.Equal(t, SHA256, c.Type())
|
||||||
require.Equal(t, cSHA256[:], c.Sum())
|
require.Equal(t, cSHA256[:], c.Value())
|
||||||
|
|
||||||
cV2 := c.ToV2()
|
var cV2 refs.Checksum
|
||||||
|
c.WriteToV2(&cV2)
|
||||||
|
|
||||||
require.Equal(t, refs.SHA256, cV2.GetType())
|
require.Equal(t, refs.SHA256, cV2.GetType())
|
||||||
require.Equal(t, cSHA256[:], cV2.GetSum())
|
require.Equal(t, cSHA256[:], cV2.GetSum())
|
||||||
|
|
||||||
cTZ := [64]byte{}
|
cTZ := [tz.Size]byte{}
|
||||||
_, _ = rand.Read(cSHA256[:])
|
_, _ = rand.Read(cSHA256[:])
|
||||||
|
|
||||||
c.SetTillichZemor(cTZ)
|
c.SetTillichZemor(cTZ)
|
||||||
|
|
||||||
require.Equal(t, TZ, c.Type())
|
require.Equal(t, TZ, c.Type())
|
||||||
require.Equal(t, cTZ[:], c.Sum())
|
require.Equal(t, cTZ[:], c.Value())
|
||||||
|
|
||||||
cV2 = c.ToV2()
|
c.WriteToV2(&cV2)
|
||||||
|
|
||||||
require.Equal(t, refs.TillichZemor, cV2.GetType())
|
require.Equal(t, refs.TillichZemor, cV2.GetType())
|
||||||
require.Equal(t, cTZ[:], cV2.GetSum())
|
require.Equal(t, cTZ[:], cV2.GetSum())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEqualChecksums(t *testing.T) {
|
|
||||||
require.True(t, Equal(nil, nil))
|
|
||||||
|
|
||||||
csSHA := [sha256.Size]byte{}
|
|
||||||
_, _ = rand.Read(csSHA[:])
|
|
||||||
|
|
||||||
cs1 := New()
|
|
||||||
cs1.SetSHA256(csSHA)
|
|
||||||
|
|
||||||
cs2 := New()
|
|
||||||
cs2.SetSHA256(csSHA)
|
|
||||||
|
|
||||||
require.True(t, Equal(cs1, cs2))
|
|
||||||
|
|
||||||
csSHA[0]++
|
|
||||||
cs2.SetSHA256(csSHA)
|
|
||||||
|
|
||||||
require.False(t, Equal(cs1, cs2))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksumEncoding(t *testing.T) {
|
|
||||||
cs := New()
|
|
||||||
cs.SetSHA256(randSHA256(t))
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data, err := cs.Marshal()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
c2 := New()
|
|
||||||
require.NoError(t, c2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, cs, c2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
|
||||||
data, err := cs.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cs2 := New()
|
|
||||||
require.NoError(t, cs2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, cs, cs2)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("string", func(t *testing.T) {
|
|
||||||
cs2 := New()
|
|
||||||
|
|
||||||
require.NoError(t, cs2.Parse(cs.String()))
|
|
||||||
|
|
||||||
require.Equal(t, cs, cs2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewChecksumFromV2(t *testing.T) {
|
|
||||||
t.Run("from nil", func(t *testing.T) {
|
|
||||||
var x *refs.Checksum
|
|
||||||
|
|
||||||
require.Nil(t, NewFromV2(x))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksum_ToV2(t *testing.T) {
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
|
||||||
var x *Checksum
|
|
||||||
|
|
||||||
require.Nil(t, x.ToV2())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewChecksum(t *testing.T) {
|
func TestNewChecksum(t *testing.T) {
|
||||||
t.Run("default values", func(t *testing.T) {
|
t.Run("default values", func(t *testing.T) {
|
||||||
chs := New()
|
var chs Checksum
|
||||||
|
|
||||||
// check initial values
|
// check initial values
|
||||||
require.Equal(t, Unknown, chs.Type())
|
require.Equal(t, Unknown, chs.Type())
|
||||||
require.Nil(t, chs.Sum())
|
require.Nil(t, chs.Value())
|
||||||
|
|
||||||
// convert to v2 message
|
// convert to v2 message
|
||||||
chsV2 := chs.ToV2()
|
var chsV2 refs.Checksum
|
||||||
|
chs.WriteToV2(&chsV2)
|
||||||
|
|
||||||
require.Equal(t, refs.UnknownChecksum, chsV2.GetType())
|
require.Equal(t, refs.UnknownChecksum, chsV2.GetType())
|
||||||
require.Nil(t, chsV2.GetSum())
|
require.Nil(t, chsV2.GetSum())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type enumIface interface {
|
func TestCalculation(t *testing.T) {
|
||||||
FromString(string) bool
|
var c Checksum
|
||||||
String() string
|
payload := []byte{0, 1, 2, 3, 4, 5}
|
||||||
}
|
|
||||||
|
|
||||||
type enumStringItem struct {
|
t.Run("SHA256", func(t *testing.T) {
|
||||||
val enumIface
|
orig := sha256.Sum256(payload)
|
||||||
str string
|
|
||||||
}
|
|
||||||
|
|
||||||
func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) {
|
Calculate(&c, SHA256, payload)
|
||||||
for _, item := range items {
|
|
||||||
require.Equal(t, item.str, item.val.String())
|
|
||||||
|
|
||||||
s := item.val.String()
|
require.Equal(t, orig[:], c.Value())
|
||||||
|
})
|
||||||
|
|
||||||
require.True(t, e.FromString(s), s)
|
t.Run("TZ", func(t *testing.T) {
|
||||||
|
orig := tz.Sum(payload)
|
||||||
|
|
||||||
require.EqualValues(t, item.val, e, item.val)
|
Calculate(&c, TZ, payload)
|
||||||
}
|
|
||||||
|
|
||||||
// incorrect strings
|
require.Equal(t, orig[:], c.Value())
|
||||||
for _, str := range []string{
|
|
||||||
"some string",
|
|
||||||
"undefined",
|
|
||||||
} {
|
|
||||||
require.False(t, e.FromString(str))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChecksumType_String(t *testing.T) {
|
|
||||||
toPtr := func(v Type) *Type {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
testEnumStrings(t, new(Type), []enumStringItem{
|
|
||||||
{val: toPtr(TZ), str: "TZ"},
|
|
||||||
{val: toPtr(SHA256), str: "SHA256"},
|
|
||||||
{val: toPtr(Unknown), str: "CHECKSUM_TYPE_UNSPECIFIED"},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
18
checksum/doc.go
Normal file
18
checksum/doc.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
Package checksum provides primitives to work with checksums.
|
||||||
|
|
||||||
|
Checksum is a basic type of data checksums.
|
||||||
|
For example, calculating checksums:
|
||||||
|
// retrieving any payload for hashing
|
||||||
|
|
||||||
|
var sha256Sum Checksum
|
||||||
|
Calculate(&sha256Sum, SHA256, payload) // sha256Sum contains SHA256 hash of the payload
|
||||||
|
|
||||||
|
var tzSum Checksum
|
||||||
|
Calculate(&tzSum, TZ, payload) // tzSum contains TZ hash of the payload
|
||||||
|
|
||||||
|
Using package types in an application is recommended to potentially work with
|
||||||
|
different protocol versions with which these types are compatible.
|
||||||
|
|
||||||
|
*/
|
||||||
|
package checksum
|
13
checksum/test/doc.go
Normal file
13
checksum/test/doc.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
Package checksumtest provides functions for convenient testing of checksum package API.
|
||||||
|
|
||||||
|
Note that importing the package into source files is highly discouraged.
|
||||||
|
|
||||||
|
Random instance generation functions can be useful when testing expects any value, e.g.:
|
||||||
|
import checksumtest "github.com/nspcc-dev/neofs-sdk-go/checksum/test"
|
||||||
|
|
||||||
|
cs := checksumtest.Checksum()
|
||||||
|
// test the value
|
||||||
|
|
||||||
|
*/
|
||||||
|
package checksumtest
|
|
@ -13,9 +13,9 @@ func Checksum() *checksum.Checksum {
|
||||||
|
|
||||||
rand.Read(cs[:])
|
rand.Read(cs[:])
|
||||||
|
|
||||||
x := checksum.New()
|
var x checksum.Checksum
|
||||||
|
|
||||||
x.SetSHA256(cs)
|
x.SetSHA256(cs)
|
||||||
|
|
||||||
return x
|
return &x
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -11,6 +11,7 @@ require (
|
||||||
github.com/nspcc-dev/hrw v1.0.9
|
github.com/nspcc-dev/hrw v1.0.9
|
||||||
github.com/nspcc-dev/neo-go v0.98.0
|
github.com/nspcc-dev/neo-go v0.98.0
|
||||||
github.com/nspcc-dev/neofs-api-go/v2 v2.12.1
|
github.com/nspcc-dev/neofs-api-go/v2 v2.12.1
|
||||||
|
github.com/nspcc-dev/tzhash v1.5.2
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
go.uber.org/zap v1.18.1
|
go.uber.org/zap v1.18.1
|
||||||
)
|
)
|
||||||
|
|
5
go.sum
5
go.sum
|
@ -187,6 +187,8 @@ github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211201182451-a5b61c4f6477/go.mod h1:d
|
||||||
github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||||
|
github.com/nspcc-dev/tzhash v1.5.2 h1:GuIQPOY2xpl5ZE1pbUbz+QdKXVOTyzbbxSVv0nBfa98=
|
||||||
|
github.com/nspcc-dev/tzhash v1.5.2/go.mod h1:gwAx6mcsbkfY+JVp+PovoP2Gvw6y57W8dj7zDHKOhzI=
|
||||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
@ -350,8 +352,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
|
||||||
|
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -20,10 +21,10 @@ var errIncorrectID = errors.New("incorrect object identifier")
|
||||||
// CalculatePayloadChecksum calculates and returns checksum of
|
// CalculatePayloadChecksum calculates and returns checksum of
|
||||||
// object payload bytes.
|
// object payload bytes.
|
||||||
func CalculatePayloadChecksum(payload []byte) *checksum.Checksum {
|
func CalculatePayloadChecksum(payload []byte) *checksum.Checksum {
|
||||||
res := checksum.New()
|
var res checksum.Checksum
|
||||||
res.SetSHA256(sha256.Sum256(payload))
|
checksum.Calculate(&res, checksum.SHA256, payload)
|
||||||
|
|
||||||
return res
|
return &res
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalculateAndSetPayloadChecksum calculates checksum of current
|
// CalculateAndSetPayloadChecksum calculates checksum of current
|
||||||
|
@ -38,7 +39,7 @@ func CalculateAndSetPayloadChecksum(obj *Object) {
|
||||||
// corresponds to its payload.
|
// corresponds to its payload.
|
||||||
func VerifyPayloadChecksum(obj *Object) error {
|
func VerifyPayloadChecksum(obj *Object) error {
|
||||||
actual := CalculatePayloadChecksum(obj.Payload())
|
actual := CalculatePayloadChecksum(obj.Payload())
|
||||||
if !checksum.Equal(obj.PayloadChecksum(), actual) {
|
if !bytes.Equal(obj.PayloadChecksum().Value(), actual.Value()) {
|
||||||
return errCheckSumMismatch
|
return errCheckSumMismatch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,33 +201,45 @@ func (o *Object) SetCreationEpoch(v uint64) {
|
||||||
|
|
||||||
// PayloadChecksum returns checksum of the object payload.
|
// PayloadChecksum returns checksum of the object payload.
|
||||||
func (o *Object) PayloadChecksum() *checksum.Checksum {
|
func (o *Object) PayloadChecksum() *checksum.Checksum {
|
||||||
return checksum.NewFromV2(
|
var v checksum.Checksum
|
||||||
(*object.Object)(o).
|
v.ReadFromV2(
|
||||||
|
*(*object.Object)(o).
|
||||||
GetHeader().
|
GetHeader().
|
||||||
GetPayloadHash(),
|
GetPayloadHash(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPayloadChecksum sets checksum of the object payload.
|
// SetPayloadChecksum sets checksum of the object payload.
|
||||||
func (o *Object) SetPayloadChecksum(v *checksum.Checksum) {
|
func (o *Object) SetPayloadChecksum(v *checksum.Checksum) {
|
||||||
|
var v2 refs.Checksum
|
||||||
|
v.WriteToV2(&v2)
|
||||||
|
|
||||||
o.setHeaderField(func(h *object.Header) {
|
o.setHeaderField(func(h *object.Header) {
|
||||||
h.SetPayloadHash(v.ToV2())
|
h.SetPayloadHash(&v2)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// PayloadHomomorphicHash returns homomorphic hash of the object payload.
|
// PayloadHomomorphicHash returns homomorphic hash of the object payload.
|
||||||
func (o *Object) PayloadHomomorphicHash() *checksum.Checksum {
|
func (o *Object) PayloadHomomorphicHash() *checksum.Checksum {
|
||||||
return checksum.NewFromV2(
|
var v checksum.Checksum
|
||||||
(*object.Object)(o).
|
v.ReadFromV2(
|
||||||
|
*(*object.Object)(o).
|
||||||
GetHeader().
|
GetHeader().
|
||||||
GetHomomorphicHash(),
|
GetHomomorphicHash(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPayloadHomomorphicHash sets homomorphic hash of the object payload.
|
// SetPayloadHomomorphicHash sets homomorphic hash of the object payload.
|
||||||
func (o *Object) SetPayloadHomomorphicHash(v *checksum.Checksum) {
|
func (o *Object) SetPayloadHomomorphicHash(v *checksum.Checksum) {
|
||||||
|
var v2 refs.Checksum
|
||||||
|
v.WriteToV2(&v2)
|
||||||
|
|
||||||
o.setHeaderField(func(h *object.Header) {
|
o.setHeaderField(func(h *object.Header) {
|
||||||
h.SetHomomorphicHash(v.ToV2())
|
h.SetHomomorphicHash(&v2)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,23 +122,23 @@ func TestObject_SetCreationEpoch(t *testing.T) {
|
||||||
|
|
||||||
func TestObject_SetPayloadChecksum(t *testing.T) {
|
func TestObject_SetPayloadChecksum(t *testing.T) {
|
||||||
obj := New()
|
obj := New()
|
||||||
cs := checksum.New()
|
var cs checksum.Checksum
|
||||||
cs.SetSHA256(randSHA256Checksum(t))
|
cs.SetSHA256(randSHA256Checksum(t))
|
||||||
|
|
||||||
obj.SetPayloadChecksum(cs)
|
obj.SetPayloadChecksum(&cs)
|
||||||
|
|
||||||
require.Equal(t, cs, obj.PayloadChecksum())
|
require.Equal(t, &cs, obj.PayloadChecksum())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObject_SetPayloadHomomorphicHash(t *testing.T) {
|
func TestObject_SetPayloadHomomorphicHash(t *testing.T) {
|
||||||
obj := New()
|
obj := New()
|
||||||
|
|
||||||
cs := checksum.New()
|
var cs checksum.Checksum
|
||||||
cs.SetTillichZemor(randTZChecksum(t))
|
cs.SetTillichZemor(randTZChecksum(t))
|
||||||
|
|
||||||
obj.SetPayloadHomomorphicHash(cs)
|
obj.SetPayloadHomomorphicHash(&cs)
|
||||||
|
|
||||||
require.Equal(t, cs, obj.PayloadHomomorphicHash())
|
require.Equal(t, &cs, obj.PayloadHomomorphicHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObject_SetAttributes(t *testing.T) {
|
func TestObject_SetAttributes(t *testing.T) {
|
||||||
|
|
|
@ -43,14 +43,23 @@ func (sg *StorageGroup) SetValidationDataSize(epoch uint64) {
|
||||||
// ValidationDataHash returns homomorphic hash from the
|
// ValidationDataHash returns homomorphic hash from the
|
||||||
// concatenation of the payloads of the storage group members.
|
// concatenation of the payloads of the storage group members.
|
||||||
func (sg *StorageGroup) ValidationDataHash() *checksum.Checksum {
|
func (sg *StorageGroup) ValidationDataHash() *checksum.Checksum {
|
||||||
return checksum.NewFromV2(
|
if v2 := (*storagegroup.StorageGroup)(sg).GetValidationHash(); v2 != nil {
|
||||||
(*storagegroup.StorageGroup)(sg).GetValidationHash())
|
var v checksum.Checksum
|
||||||
|
v.ReadFromV2(*v2)
|
||||||
|
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetValidationDataHash sets homomorphic hash from the
|
// SetValidationDataHash sets homomorphic hash from the
|
||||||
// concatenation of the payloads of the storage group members.
|
// concatenation of the payloads of the storage group members.
|
||||||
func (sg *StorageGroup) SetValidationDataHash(hash *checksum.Checksum) {
|
func (sg *StorageGroup) SetValidationDataHash(hash *checksum.Checksum) {
|
||||||
(*storagegroup.StorageGroup)(sg).SetValidationHash(hash.ToV2())
|
var v2 refs.Checksum
|
||||||
|
hash.WriteToV2(&v2)
|
||||||
|
|
||||||
|
(*storagegroup.StorageGroup)(sg).SetValidationHash(&v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExpirationEpoch returns last NeoFS epoch number
|
// ExpirationEpoch returns last NeoFS epoch number
|
||||||
|
|
Loading…
Reference in a new issue