[#303] user: Make user.ID a [20]byte array
All checks were successful
DCO / DCO (pull_request) Successful in 27s
Code generation / Generate proto (pull_request) Successful in 33s
Tests and linters / Tests (pull_request) Successful in 49s
Tests and linters / Lint (pull_request) Successful in 2m7s

Signed-off-by: Ekaterina Lebedeva <ekaterina.lebedeva@yadro.com>
This commit is contained in:
Ekaterina Lebedeva 2025-01-27 19:07:45 +03:00
parent 761d087b93
commit 873f0896ca

View file

@ -12,9 +12,9 @@ import (
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
) )
const idSize = 25 const idSizeFull = 25
var zeroSlice = bytes.Repeat([]byte{0}, idSize) var zeroSlice = bytes.Repeat([]byte{0}, 20)
// ID identifies users of the FrostFS system. // ID identifies users of the FrostFS system.
// //
@ -25,7 +25,7 @@ var zeroSlice = bytes.Repeat([]byte{0}, idSize)
// so it MUST be initialized using some modifying function (e.g. SetScriptHash, // so it MUST be initialized using some modifying function (e.g. SetScriptHash,
// IDFromKey, etc.). // IDFromKey, etc.).
type ID struct { type ID struct {
w []byte w [20]byte
} }
// ReadFromV2 reads ID from the refs.OwnerID message. Returns an error if // ReadFromV2 reads ID from the refs.OwnerID message. Returns an error if
@ -33,22 +33,7 @@ type ID struct {
// //
// See also WriteToV2. // See also WriteToV2.
func (x *ID) ReadFromV2(m refs.OwnerID) error { func (x *ID) ReadFromV2(m refs.OwnerID) error {
w := m.GetValue() return x.setUserID(m.GetValue())
if len(w) != idSize {
return fmt.Errorf("invalid length %d, expected %d", len(w), idSize)
}
if w[0] != address.NEO3Prefix {
return fmt.Errorf("invalid prefix byte 0x%X, expected 0x%X", w[0], address.NEO3Prefix)
}
if !bytes.Equal(w[21:], hash.Checksum(w[:21])) {
return errors.New("checksum mismatch")
}
x.w = w
return nil
} }
// WriteToV2 writes ID to the refs.OwnerID message. // WriteToV2 writes ID to the refs.OwnerID message.
@ -56,25 +41,17 @@ func (x *ID) ReadFromV2(m refs.OwnerID) error {
// //
// See also ReadFromV2. // See also ReadFromV2.
func (x ID) WriteToV2(m *refs.OwnerID) { func (x ID) WriteToV2(m *refs.OwnerID) {
m.SetValue(x.w) m.SetValue(x.WalletBytes())
} }
// SetScriptHash forms user ID from wallet address scripthash. // SetScriptHash forms user ID from wallet address scripthash.
func (x *ID) SetScriptHash(scriptHash util.Uint160) { func (x *ID) SetScriptHash(scriptHash util.Uint160) {
if cap(x.w) < idSize { copy(x.w[:], scriptHash.BytesBE())
x.w = make([]byte, idSize)
} else if len(x.w) < idSize {
x.w = x.w[:idSize]
}
x.w[0] = address.Prefix
copy(x.w[1:], scriptHash.BytesBE())
copy(x.w[21:], hash.Checksum(x.w[:21]))
} }
// ScriptHash calculates and returns script hash of ID. // ScriptHash calculates and returns script hash of ID.
func (x *ID) ScriptHash() util.Uint160 { func (x *ID) ScriptHash() util.Uint160 {
res, _ := util.Uint160DecodeBytesBE(x.w[1:21]) res, _ := util.Uint160DecodeBytesBE(x.w[:])
return res return res
} }
@ -84,14 +61,18 @@ func (x *ID) ScriptHash() util.Uint160 {
// //
// See also Neo3 wallet docs. // See also Neo3 wallet docs.
func (x ID) WalletBytes() []byte { func (x ID) WalletBytes() []byte {
return x.w v := make([]byte, idSizeFull)
v[0] = address.Prefix
copy(v[1:], x.w[:])
copy(v[21:], hash.Checksum(v[:21]))
return v
} }
// EncodeToString encodes ID into FrostFS API V2 protocol string. // EncodeToString encodes ID into FrostFS API V2 protocol string.
// //
// See also DecodeString. // See also DecodeString.
func (x ID) EncodeToString() string { func (x ID) EncodeToString() string {
return base58.Encode(x.w) return base58.Encode(x.WalletBytes())
} }
// DecodeString decodes FrostFS API V2 protocol string. Returns an error // DecodeString decodes FrostFS API V2 protocol string. Returns an error
@ -101,14 +82,11 @@ func (x ID) EncodeToString() string {
// //
// See also EncodeToString. // See also EncodeToString.
func (x *ID) DecodeString(s string) error { func (x *ID) DecodeString(s string) error {
var err error w, err := base58.Decode(s)
x.w, err = base58.Decode(s)
if err != nil { if err != nil {
return fmt.Errorf("decode base58: %w", err) return fmt.Errorf("decode base58: %w", err)
} }
return x.setUserID(w)
return nil
} }
// String implements fmt.Stringer. // String implements fmt.Stringer.
@ -122,10 +100,28 @@ func (x ID) String() string {
// Equals defines a comparison relation between two ID instances. // Equals defines a comparison relation between two ID instances.
func (x ID) Equals(x2 ID) bool { func (x ID) Equals(x2 ID) bool {
return bytes.Equal(x.w, x2.w) return bytes.Equal(x.w[:], x2.w[:])
} }
// IsEmpty returns True, if ID is empty value. // IsEmpty returns True, if ID is empty value.
func (x ID) IsEmpty() bool { func (x ID) IsEmpty() bool {
return bytes.Equal(zeroSlice, x.w) return bytes.Equal(zeroSlice, x.w[:])
}
func (x *ID) setUserID(w []byte) error {
if len(w) != idSizeFull {
return fmt.Errorf("invalid length %d, expected %d", len(w), idSizeFull)
}
if w[0] != address.NEO3Prefix {
return fmt.Errorf("invalid prefix byte 0x%X, expected 0x%X", w[0], address.NEO3Prefix)
}
if !bytes.Equal(w[21:], hash.Checksum(w[:21])) {
return errors.New("checksum mismatch")
}
copy(x.w[:], w[1:21])
return nil
} }