forked from TrueCloudLab/frostfs-api-go
Merge branch 'release/1.3.0'
This commit is contained in:
commit
64c941ae06
24 changed files with 1291 additions and 1085 deletions
|
@ -1,6 +1,14 @@
|
|||
# Changelog
|
||||
This is the changelog for NeoFS-API-Go
|
||||
|
||||
## [1.3.0] - 2020-07-23
|
||||
|
||||
### Changed
|
||||
|
||||
- Format of ```refs.OwnerID``` based on NEO3.
|
||||
- Binary format of extended ACL table.
|
||||
- ```acl``` package structure.
|
||||
|
||||
## [1.2.0] - 2020-07-08
|
||||
|
||||
### Added
|
||||
|
@ -375,3 +383,4 @@ Initial public release
|
|||
[1.0.0]: https://github.com/nspcc-dev/neofs-api-go/compare/v0.7.6...v1.0.0
|
||||
[1.1.0]: https://github.com/nspcc-dev/neofs-api-go/compare/v1.0.0...v1.1.0
|
||||
[1.2.0]: https://github.com/nspcc-dev/neofs-api-go/compare/v1.1.0...v1.2.0
|
||||
[1.3.0]: https://github.com/nspcc-dev/neofs-api-go/compare/v1.2.0...v1.3.0
|
||||
|
|
|
@ -21,6 +21,9 @@ can be used for integration with NeoFS.
|
|||
[neofs-api-go v1.2.0]: https://github.com/nspcc-dev/neofs-api-go/releases/tag/v1.2.0
|
||||
* [neofs-api-go v1.2.0] supports [neofs-api v1.2.0]
|
||||
|
||||
[neofs-api-go v1.3.0]: https://github.com/nspcc-dev/neofs-api-go/releases/tag/v1.3.0
|
||||
* [neofs-api-go v1.3.0] supports [neofs-api v1.2.0]
|
||||
|
||||
## Description
|
||||
|
||||
Repository contains 13 packages that implement NeoFS core structures. These
|
||||
|
|
126
acl/extended/enum.go
Normal file
126
acl/extended/enum.go
Normal file
|
@ -0,0 +1,126 @@
|
|||
package eacl
|
||||
|
||||
const (
|
||||
// MatchUnknown is a MatchType value used to mark value as undefined.
|
||||
// Most of the tools consider MatchUnknown as incalculable.
|
||||
// Using MatchUnknown in HeaderFilter is unsafe.
|
||||
MatchUnknown MatchType = iota
|
||||
|
||||
// StringEqual is a MatchType of string equality.
|
||||
StringEqual
|
||||
|
||||
// StringNotEqual is a MatchType of string inequality.
|
||||
StringNotEqual
|
||||
)
|
||||
|
||||
const (
|
||||
// ActionUnknown is Action used to mark value as undefined.
|
||||
// Most of the tools consider ActionUnknown as incalculable.
|
||||
// Using ActionUnknown in Record is unsafe.
|
||||
ActionUnknown Action = iota
|
||||
|
||||
// ActionAllow is Action used to mark an applicability of ACL rule.
|
||||
ActionAllow
|
||||
|
||||
// ActionDeny is Action used to mark an inapplicability of ACL rule.
|
||||
ActionDeny
|
||||
)
|
||||
|
||||
const (
|
||||
// GroupUnknown is a Group value used to mark value as undefined.
|
||||
// Most of the tools consider GroupUnknown as incalculable.
|
||||
// Using GroupUnknown in Target is unsafe.
|
||||
GroupUnknown Group = iota
|
||||
|
||||
// GroupUser is a Group value for User access group.
|
||||
GroupUser
|
||||
|
||||
// GroupSystem is a Group value for System access group.
|
||||
GroupSystem
|
||||
|
||||
// GroupOthers is a Group value for Others access group.
|
||||
GroupOthers
|
||||
)
|
||||
|
||||
const (
|
||||
// HdrTypeUnknown is a HeaderType value used to mark value as undefined.
|
||||
// Most of the tools consider HdrTypeUnknown as incalculable.
|
||||
// Using HdrTypeUnknown in HeaderFilter is unsafe.
|
||||
HdrTypeUnknown HeaderType = iota
|
||||
|
||||
// HdrTypeRequest is a HeaderType for request header.
|
||||
HdrTypeRequest
|
||||
|
||||
// HdrTypeObjSys is a HeaderType for system headers of object.
|
||||
HdrTypeObjSys
|
||||
|
||||
// HdrTypeObjUsr is a HeaderType for user headers of object.
|
||||
HdrTypeObjUsr
|
||||
)
|
||||
|
||||
const (
|
||||
// OpTypeUnknown is a OperationType value used to mark value as undefined.
|
||||
// Most of the tools consider OpTypeUnknown as incalculable.
|
||||
// Using OpTypeUnknown in Record is unsafe.
|
||||
OpTypeUnknown OperationType = iota
|
||||
|
||||
// OpTypeGet is an OperationType for object.Get RPC
|
||||
OpTypeGet
|
||||
|
||||
// OpTypePut is an OperationType for object.Put RPC
|
||||
OpTypePut
|
||||
|
||||
// OpTypeHead is an OperationType for object.Head RPC
|
||||
OpTypeHead
|
||||
|
||||
// OpTypeSearch is an OperationType for object.Search RPC
|
||||
OpTypeSearch
|
||||
|
||||
// OpTypeDelete is an OperationType for object.Delete RPC
|
||||
OpTypeDelete
|
||||
|
||||
// OpTypeRange is an OperationType for object.GetRange RPC
|
||||
OpTypeRange
|
||||
|
||||
// OpTypeRangeHash is an OperationType for object.GetRangeHash RPC
|
||||
OpTypeRangeHash
|
||||
)
|
||||
|
||||
const (
|
||||
// HdrObjSysNameID is a name of ID field in system header of object.
|
||||
HdrObjSysNameID = "ID"
|
||||
|
||||
// HdrObjSysNameCID is a name of CID field in system header of object.
|
||||
HdrObjSysNameCID = "CID"
|
||||
|
||||
// HdrObjSysNameOwnerID is a name of OwnerID field in system header of object.
|
||||
HdrObjSysNameOwnerID = "OWNER_ID"
|
||||
|
||||
// HdrObjSysNameVersion is a name of Version field in system header of object.
|
||||
HdrObjSysNameVersion = "VERSION"
|
||||
|
||||
// HdrObjSysNamePayloadLength is a name of PayloadLength field in system header of object.
|
||||
HdrObjSysNamePayloadLength = "PAYLOAD_LENGTH"
|
||||
|
||||
// HdrObjSysNameCreatedUnix is a name of CreatedAt.UnitTime field in system header of object.
|
||||
HdrObjSysNameCreatedUnix = "CREATED_UNIX"
|
||||
|
||||
// HdrObjSysNameCreatedEpoch is a name of CreatedAt.Epoch field in system header of object.
|
||||
HdrObjSysNameCreatedEpoch = "CREATED_EPOCH"
|
||||
|
||||
// HdrObjSysLinkPrev is a name of previous link header in extended headers of object.
|
||||
HdrObjSysLinkPrev = "LINK_PREV"
|
||||
|
||||
// HdrObjSysLinkNext is a name of next link header in extended headers of object.
|
||||
HdrObjSysLinkNext = "LINK_NEXT"
|
||||
|
||||
// HdrObjSysLinkChild is a name of child link header in extended headers of object.
|
||||
HdrObjSysLinkChild = "LINK_CHILD"
|
||||
|
||||
// HdrObjSysLinkPar is a name of parent link header in extended headers of object.
|
||||
HdrObjSysLinkPar = "LINK_PAR"
|
||||
|
||||
// HdrObjSysLinkSG is a name of storage group link header in extended headers of object.
|
||||
HdrObjSysLinkSG = "LINK_SG"
|
||||
)
|
||||
|
333
acl/extended/marshal.go
Normal file
333
acl/extended/marshal.go
Normal file
|
@ -0,0 +1,333 @@
|
|||
package eacl
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
sliceLenSize = 2 // uint16 for len()
|
||||
actionSize = 4 // uint32
|
||||
opTypeSize = 4 // uint32
|
||||
hdrTypeSize = 4 // uint32
|
||||
matchTypeSize = 4 // uint32
|
||||
targetSize = 4 // uint32
|
||||
)
|
||||
|
||||
// MarshalTable encodes Table into a
|
||||
// binary form and returns the result.
|
||||
//
|
||||
// If table is nil, empty slice is returned.
|
||||
func MarshalTable(table Table) []byte {
|
||||
if table == nil {
|
||||
return make([]byte, 0)
|
||||
}
|
||||
|
||||
// allocate buffer
|
||||
buf := make([]byte, tableBinSize(table))
|
||||
|
||||
records := table.Records()
|
||||
|
||||
// write record number
|
||||
binary.BigEndian.PutUint16(buf, uint16(len(records)))
|
||||
off := sliceLenSize
|
||||
|
||||
// write all records
|
||||
for _, record := range records {
|
||||
// write action
|
||||
binary.BigEndian.PutUint32(buf[off:], uint32(record.Action()))
|
||||
off += actionSize
|
||||
|
||||
// write operation type
|
||||
binary.BigEndian.PutUint32(buf[off:], uint32(record.OperationType()))
|
||||
off += actionSize
|
||||
|
||||
filters := record.HeaderFilters()
|
||||
|
||||
// write filter number
|
||||
binary.BigEndian.PutUint16(buf[off:], uint16(len(filters)))
|
||||
off += sliceLenSize
|
||||
|
||||
// write all filters
|
||||
for _, filter := range filters {
|
||||
// write header type
|
||||
binary.BigEndian.PutUint32(buf[off:], uint32(filter.HeaderType()))
|
||||
off += hdrTypeSize
|
||||
|
||||
// write match type
|
||||
binary.BigEndian.PutUint32(buf[off:], uint32(filter.MatchType()))
|
||||
off += matchTypeSize
|
||||
|
||||
// write header name size
|
||||
name := []byte(filter.Name())
|
||||
binary.BigEndian.PutUint16(buf[off:], uint16(len(name)))
|
||||
off += sliceLenSize
|
||||
|
||||
// write header name bytes
|
||||
off += copy(buf[off:], name)
|
||||
|
||||
// write header value size
|
||||
val := []byte(filter.Value())
|
||||
binary.BigEndian.PutUint16(buf[off:], uint16(len(val)))
|
||||
off += sliceLenSize
|
||||
|
||||
// write header value bytes
|
||||
off += copy(buf[off:], val)
|
||||
}
|
||||
|
||||
targets := record.TargetList()
|
||||
|
||||
// write target number
|
||||
binary.BigEndian.PutUint16(buf[off:], uint16(len(targets)))
|
||||
off += sliceLenSize
|
||||
|
||||
// write all targets
|
||||
for _, target := range targets {
|
||||
// write target group
|
||||
binary.BigEndian.PutUint32(buf[off:], uint32(target.Group()))
|
||||
off += targetSize
|
||||
|
||||
keys := target.KeyList()
|
||||
|
||||
// write key number
|
||||
binary.BigEndian.PutUint16(buf[off:], uint16(len(keys)))
|
||||
off += sliceLenSize
|
||||
|
||||
// write keys
|
||||
for i := range keys {
|
||||
// write key size
|
||||
binary.BigEndian.PutUint16(buf[off:], uint16(len(keys[i])))
|
||||
off += sliceLenSize
|
||||
|
||||
// write key bytes
|
||||
off += copy(buf[off:], keys[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// returns the size of Table in a binary format.
|
||||
func tableBinSize(table Table) (sz int) {
|
||||
sz = sliceLenSize // number of records
|
||||
|
||||
records := table.Records()
|
||||
ln := len(records)
|
||||
|
||||
sz += ln * actionSize // action type of each record
|
||||
sz += ln * opTypeSize // operation type of each record
|
||||
|
||||
for _, record := range records {
|
||||
sz += sliceLenSize // number of filters
|
||||
|
||||
filters := record.HeaderFilters()
|
||||
ln := len(filters)
|
||||
|
||||
sz += ln * hdrTypeSize // header type of each filter
|
||||
sz += ln * matchTypeSize // match type of each filter
|
||||
|
||||
for _, filter := range filters {
|
||||
sz += sliceLenSize // header name size
|
||||
sz += len(filter.Name()) // header name bytes
|
||||
|
||||
sz += sliceLenSize // header value size
|
||||
sz += len(filter.Value()) // header value bytes
|
||||
}
|
||||
|
||||
sz += sliceLenSize // number of targets
|
||||
|
||||
targets := record.TargetList()
|
||||
ln = len(targets)
|
||||
|
||||
sz += ln * targetSize // target group of each target
|
||||
|
||||
for _, target := range targets {
|
||||
sz += sliceLenSize // number of keys
|
||||
|
||||
for _, key := range target.KeyList() {
|
||||
sz += sliceLenSize // key size
|
||||
sz += len(key) // key bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalTable unmarshals Table from
|
||||
// a binary representation.
|
||||
//
|
||||
// If data is empty, table w/o records is returned.
|
||||
func UnmarshalTable(data []byte) (Table, error) {
|
||||
table := WrapTable(nil)
|
||||
|
||||
if len(data) == 0 {
|
||||
return table, nil
|
||||
}
|
||||
|
||||
// decode record number
|
||||
if len(data) < sliceLenSize {
|
||||
return nil, errors.New("could not decode record number")
|
||||
}
|
||||
|
||||
recordNum := binary.BigEndian.Uint16(data)
|
||||
records := make([]Record, 0, recordNum)
|
||||
|
||||
off := sliceLenSize
|
||||
|
||||
// decode all records one by one
|
||||
for i := uint16(0); i < recordNum; i++ {
|
||||
record := WrapRecord(nil)
|
||||
|
||||
// decode action
|
||||
if len(data[off:]) < actionSize {
|
||||
return nil, errors.Errorf("could not decode action of record #%d", i)
|
||||
}
|
||||
|
||||
record.SetAction(Action(binary.BigEndian.Uint32(data[off:])))
|
||||
off += actionSize
|
||||
|
||||
// decode operation type
|
||||
if len(data[off:]) < opTypeSize {
|
||||
return nil, errors.Errorf("could not decode operation type of record #%d", i)
|
||||
}
|
||||
|
||||
record.SetOperationType(OperationType(binary.BigEndian.Uint32(data[off:])))
|
||||
off += opTypeSize
|
||||
|
||||
// decode filter number
|
||||
if len(data[off:]) < sliceLenSize {
|
||||
return nil, errors.Errorf("could not decode filter number of record #%d", i)
|
||||
}
|
||||
|
||||
filterNum := binary.BigEndian.Uint16(data[off:])
|
||||
off += sliceLenSize
|
||||
filters := make([]HeaderFilter, 0, filterNum)
|
||||
|
||||
// decode filters one by one
|
||||
for j := uint16(0); j < filterNum; j++ {
|
||||
filter := WrapFilterInfo(nil)
|
||||
|
||||
// decode header type
|
||||
if len(data[off:]) < hdrTypeSize {
|
||||
return nil, errors.Errorf("could not decode header type of filter #%d of record #%d", j, i)
|
||||
}
|
||||
|
||||
filter.SetHeaderType(HeaderType(binary.BigEndian.Uint32(data[off:])) )
|
||||
off += hdrTypeSize
|
||||
|
||||
// decode match type
|
||||
if len(data[off:]) < matchTypeSize {
|
||||
return nil, errors.Errorf("could not decode match type of filter #%d of record #%d", j, i)
|
||||
}
|
||||
|
||||
filter.SetMatchType(MatchType(binary.BigEndian.Uint32(data[off:])) )
|
||||
off += matchTypeSize
|
||||
|
||||
// decode header name size
|
||||
if len(data[off:]) < sliceLenSize {
|
||||
return nil, errors.Errorf("could not decode header name size of filter #%d of record #%d", j, i)
|
||||
}
|
||||
|
||||
hdrNameSize := int(binary.BigEndian.Uint16(data[off:]))
|
||||
off += sliceLenSize
|
||||
|
||||
// decode header name
|
||||
if len(data[off:]) < hdrNameSize {
|
||||
return nil, errors.Errorf("could not decode header name of filter #%d of record #%d", j, i)
|
||||
}
|
||||
|
||||
filter.SetName(string(data[off : off+hdrNameSize]))
|
||||
|
||||
off += hdrNameSize
|
||||
|
||||
// decode header value size
|
||||
if len(data[off:]) < sliceLenSize {
|
||||
return nil, errors.Errorf("could not decode header value size of filter #%d of record #%d", j, i)
|
||||
}
|
||||
|
||||
hdrValSize := int(binary.BigEndian.Uint16(data[off:]))
|
||||
off += sliceLenSize
|
||||
|
||||
// decode header value
|
||||
if len(data[off:]) < hdrValSize {
|
||||
return nil, errors.Errorf("could not decode header value of filter #%d of record #%d", j, i)
|
||||
}
|
||||
|
||||
filter.SetValue(string(data[off : off+hdrValSize]))
|
||||
|
||||
off += hdrValSize
|
||||
|
||||
filters = append(filters, filter)
|
||||
}
|
||||
|
||||
record.SetHeaderFilters(filters)
|
||||
|
||||
// decode target number
|
||||
if len(data[off:]) < sliceLenSize {
|
||||
return nil, errors.Errorf("could not decode target number of record #%d", i)
|
||||
}
|
||||
|
||||
targetNum := int(binary.BigEndian.Uint16(data[off:]))
|
||||
off += sliceLenSize
|
||||
|
||||
targets := make([]Target, 0, targetNum)
|
||||
|
||||
// decode targets one by one
|
||||
for j := 0; j < targetNum; j++ {
|
||||
target := WrapTarget(nil)
|
||||
|
||||
// decode target group
|
||||
if len(data[off:]) < targetSize {
|
||||
return nil, errors.Errorf("could not decode target group of target #%d of record #%d", j, i)
|
||||
}
|
||||
|
||||
target.SetGroup( Group(binary.BigEndian.Uint32(data[off:])), )
|
||||
off += targetSize
|
||||
|
||||
// decode key number
|
||||
if len(data[off:]) < sliceLenSize {
|
||||
return nil, errors.Errorf("could not decode key number of target #%d of record #%d", j, i)
|
||||
}
|
||||
|
||||
keyNum := int(binary.BigEndian.Uint16(data[off:]))
|
||||
off += sliceLenSize
|
||||
keys := make([][]byte, 0, keyNum)
|
||||
|
||||
for k := 0; k < keyNum; k++ {
|
||||
// decode key size
|
||||
if len(data[off:]) < sliceLenSize {
|
||||
return nil, errors.Errorf("could not decode size of key #%d target #%d of record #%d", k, j, i)
|
||||
}
|
||||
|
||||
keySz := int(binary.BigEndian.Uint16(data[off:]))
|
||||
off += sliceLenSize
|
||||
|
||||
// decode key
|
||||
if len(data[off:]) < keySz {
|
||||
return nil, errors.Errorf("could not decode key #%d target #%d of record #%d", k, j, i)
|
||||
}
|
||||
|
||||
key := make([]byte, keySz)
|
||||
|
||||
off += copy(key, data[off:off+keySz])
|
||||
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
target.SetKeyList(keys)
|
||||
|
||||
targets = append(targets, target)
|
||||
}
|
||||
|
||||
record.SetTargetList(targets)
|
||||
|
||||
records = append(records, record)
|
||||
}
|
||||
|
||||
table.SetRecords(records)
|
||||
|
||||
return table, nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package acl
|
||||
package eacl
|
||||
|
||||
// OperationType is an enumeration of operation types for extended ACL.
|
||||
type OperationType uint32
|
||||
|
@ -9,8 +9,11 @@ type HeaderType uint32
|
|||
// MatchType is an enumeration of match types for extended ACL.
|
||||
type MatchType uint32
|
||||
|
||||
// ExtendedACLAction is an enumeration of extended ACL actions.
|
||||
type ExtendedACLAction uint32
|
||||
// Action is an enumeration of extended ACL actions.
|
||||
type Action uint32
|
||||
|
||||
// Group is an enumeration of access groups.
|
||||
type Group uint32
|
||||
|
||||
// Header is an interface of string key-value pair,
|
||||
type Header interface {
|
||||
|
@ -37,17 +40,17 @@ type HeaderFilter interface {
|
|||
TypedHeader
|
||||
}
|
||||
|
||||
// ExtendedACLTarget is an interface of grouped information about extended ACL rule target.
|
||||
type ExtendedACLTarget interface {
|
||||
// Target is an interface of grouped information about extended ACL rule target.
|
||||
type Target interface {
|
||||
// Must return ACL target type.
|
||||
Target() Target
|
||||
Group() Group
|
||||
|
||||
// Must return public key list of ACL targets.
|
||||
KeyList() [][]byte
|
||||
}
|
||||
|
||||
// ExtendedACLRecord is an interface of record of extended ACL rule table.
|
||||
type ExtendedACLRecord interface {
|
||||
// Record is an interface of record of extended ACL rule table.
|
||||
type Record interface {
|
||||
// Must return operation type of extended ACL rule.
|
||||
OperationType() OperationType
|
||||
|
||||
|
@ -55,39 +58,16 @@ type ExtendedACLRecord interface {
|
|||
HeaderFilters() []HeaderFilter
|
||||
|
||||
// Must return target list of extended ACL rule.
|
||||
TargetList() []ExtendedACLTarget
|
||||
TargetList() []Target
|
||||
|
||||
// Must return action of extended ACL rule.
|
||||
Action() ExtendedACLAction
|
||||
Action() Action
|
||||
}
|
||||
|
||||
// ExtendedACLTable is an interface of extended ACL table.
|
||||
type ExtendedACLTable interface {
|
||||
// Table is an interface of extended ACL table.
|
||||
type Table interface {
|
||||
// Must return list of extended ACL rules.
|
||||
Records() []ExtendedACLRecord
|
||||
Records() []Record
|
||||
}
|
||||
|
||||
const (
|
||||
_ OperationType = iota
|
||||
|
||||
// OpTypeGet is an OperationType for object.Get RPC
|
||||
OpTypeGet
|
||||
|
||||
// OpTypePut is an OperationType for object.Put RPC
|
||||
OpTypePut
|
||||
|
||||
// OpTypeHead is an OperationType for object.Head RPC
|
||||
OpTypeHead
|
||||
|
||||
// OpTypeSearch is an OperationType for object.Search RPC
|
||||
OpTypeSearch
|
||||
|
||||
// OpTypeDelete is an OperationType for object.Delete RPC
|
||||
OpTypeDelete
|
||||
|
||||
// OpTypeRange is an OperationType for object.GetRange RPC
|
||||
OpTypeRange
|
||||
|
||||
// OpTypeRangeHash is an OperationType for object.GetRangeHash RPC
|
||||
OpTypeRangeHash
|
||||
)
|
528
acl/extended/wrappers.go
Normal file
528
acl/extended/wrappers.go
Normal file
|
@ -0,0 +1,528 @@
|
|||
package eacl
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-api-go/acl"
|
||||
)
|
||||
|
||||
// FilterWrapper is a wrapper over acl.EACLRecord_FilterInfo pointer.
|
||||
type FilterWrapper struct {
|
||||
filter *acl.EACLRecord_FilterInfo
|
||||
}
|
||||
|
||||
// TargetWrapper is a wrapper over acl.EACLRecord_TargetInfo pointer.
|
||||
type TargetWrapper struct {
|
||||
target *acl.EACLRecord_TargetInfo
|
||||
}
|
||||
|
||||
// RecordWrapper is a wrapper over acl.EACLRecord pointer.
|
||||
type RecordWrapper struct {
|
||||
record *acl.EACLRecord
|
||||
}
|
||||
|
||||
// TableWrapper is a wrapper over acl.EACLTable pointer.
|
||||
type TableWrapper struct {
|
||||
table *acl.EACLTable
|
||||
}
|
||||
|
||||
// WrapFilterInfo wraps EACLRecord_FilterInfo pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord_FilterInfo is initialized.
|
||||
func WrapFilterInfo(v *acl.EACLRecord_FilterInfo) FilterWrapper {
|
||||
if v == nil {
|
||||
v = new(acl.EACLRecord_FilterInfo)
|
||||
}
|
||||
|
||||
return FilterWrapper{
|
||||
filter: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapTarget wraps EACLRecord_TargetInfo pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord_TargetInfo is initialized.
|
||||
func WrapTarget(v *acl.EACLRecord_TargetInfo) TargetWrapper {
|
||||
if v == nil {
|
||||
v = new(acl.EACLRecord_TargetInfo)
|
||||
}
|
||||
|
||||
return TargetWrapper{
|
||||
target: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapRecord wraps EACLRecord pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord is initialized.
|
||||
func WrapRecord(v *acl.EACLRecord) RecordWrapper {
|
||||
if v == nil {
|
||||
v = new(acl.EACLRecord)
|
||||
}
|
||||
|
||||
return RecordWrapper{
|
||||
record: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapTable wraps EACLTable pointer.
|
||||
//
|
||||
// If argument is nil, new EACLTable is initialized.
|
||||
func WrapTable(v *acl.EACLTable) TableWrapper {
|
||||
if v == nil {
|
||||
v = new(acl.EACLTable)
|
||||
}
|
||||
|
||||
return TableWrapper{
|
||||
table: v,
|
||||
}
|
||||
}
|
||||
|
||||
// MatchType returns the match type of the filter.
|
||||
//
|
||||
// If filter is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if MatchType is not one of:
|
||||
// - EACLRecord_FilterInfo_StringEqual;
|
||||
// - EACLRecord_FilterInfo_StringNotEqual.
|
||||
func (s FilterWrapper) MatchType() (res MatchType) {
|
||||
if s.filter != nil {
|
||||
switch s.filter.GetMatchType() {
|
||||
case acl.EACLRecord_FilterInfo_StringEqual:
|
||||
res = StringEqual
|
||||
case acl.EACLRecord_FilterInfo_StringNotEqual:
|
||||
res = StringNotEqual
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetMatchType sets the match type of the filter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
//
|
||||
// MatchType is set to EACLRecord_FilterInfo_MatchUnknown if argument is not one of:
|
||||
// - StringEqual;
|
||||
// - StringNotEqual.
|
||||
func (s FilterWrapper) SetMatchType(v MatchType) {
|
||||
if s.filter != nil {
|
||||
switch v {
|
||||
case StringEqual:
|
||||
s.filter.SetMatchType(acl.EACLRecord_FilterInfo_StringEqual)
|
||||
case StringNotEqual:
|
||||
s.filter.SetMatchType(acl.EACLRecord_FilterInfo_StringNotEqual)
|
||||
default:
|
||||
s.filter.SetMatchType(acl.EACLRecord_FilterInfo_MatchUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the name of filtering header.
|
||||
//
|
||||
// If filter is not initialized, empty string returns.
|
||||
func (s FilterWrapper) Name() string {
|
||||
if s.filter == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s.filter.GetHeaderName()
|
||||
}
|
||||
|
||||
// SetName sets the name of the filtering header.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
func (s FilterWrapper) SetName(v string) {
|
||||
if s.filter != nil {
|
||||
s.filter.SetHeaderName(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Value returns the value of filtering header.
|
||||
//
|
||||
// If filter is not initialized, empty string returns.
|
||||
func (s FilterWrapper) Value() string {
|
||||
if s.filter == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s.filter.GetHeaderVal()
|
||||
}
|
||||
|
||||
// SetValue sets the value of filtering header.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
func (s FilterWrapper) SetValue(v string) {
|
||||
if s.filter != nil {
|
||||
s.filter.SetHeaderVal(v)
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderType returns the header type of the filter.
|
||||
//
|
||||
// If filter is not initialized, HdrTypeUnknown returns.
|
||||
//
|
||||
// Returns HdrTypeUnknown if Header is not one of:
|
||||
// - EACLRecord_FilterInfo_Request;
|
||||
// - EACLRecord_FilterInfo_ObjectSystem;
|
||||
// - EACLRecord_FilterInfo_ObjectUser.
|
||||
func (s FilterWrapper) HeaderType() (res HeaderType) {
|
||||
res = HdrTypeUnknown
|
||||
|
||||
if s.filter != nil {
|
||||
switch s.filter.GetHeader() {
|
||||
case acl.EACLRecord_FilterInfo_Request:
|
||||
res = HdrTypeRequest
|
||||
case acl.EACLRecord_FilterInfo_ObjectSystem:
|
||||
res = HdrTypeObjSys
|
||||
case acl.EACLRecord_FilterInfo_ObjectUser:
|
||||
res = HdrTypeObjUsr
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetHeaderType sets the header type of the filter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
//
|
||||
// Header is set to EACLRecord_FilterInfo_HeaderUnknown if argument is not one of:
|
||||
// - HdrTypeRequest;
|
||||
// - HdrTypeObjSys;
|
||||
// - HdrTypeObjUsr.
|
||||
func (s FilterWrapper) SetHeaderType(t HeaderType) {
|
||||
if s.filter != nil {
|
||||
switch t {
|
||||
case HdrTypeRequest:
|
||||
s.filter.SetHeader(acl.EACLRecord_FilterInfo_Request)
|
||||
case HdrTypeObjSys:
|
||||
s.filter.SetHeader(acl.EACLRecord_FilterInfo_ObjectSystem)
|
||||
case HdrTypeObjUsr:
|
||||
s.filter.SetHeader(acl.EACLRecord_FilterInfo_ObjectUser)
|
||||
default:
|
||||
s.filter.SetHeader(acl.EACLRecord_FilterInfo_HeaderUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Group returns the access group of the target.
|
||||
//
|
||||
// If target is not initialized, GroupUnknown returns.
|
||||
//
|
||||
// Returns GroupUnknown if Target is not one of:
|
||||
// - Target_User;
|
||||
// - GroupSystem;
|
||||
// - GroupOthers.
|
||||
func (s TargetWrapper) Group() (res Group) {
|
||||
res = GroupUnknown
|
||||
|
||||
if s.target != nil {
|
||||
switch s.target.GetTarget() {
|
||||
case acl.Target_User:
|
||||
res = GroupUser
|
||||
case acl.Target_System:
|
||||
res = GroupSystem
|
||||
case acl.Target_Others:
|
||||
res = GroupOthers
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetGroup sets the access group of the target.
|
||||
//
|
||||
// If target is not initialized, nothing changes.
|
||||
//
|
||||
// Target is set to Target_Unknown if argument is not one of:
|
||||
// - GroupUser;
|
||||
// - GroupSystem;
|
||||
// - GroupOthers.
|
||||
func (s TargetWrapper) SetGroup(g Group) {
|
||||
if s.target != nil {
|
||||
switch g {
|
||||
case GroupUser:
|
||||
s.target.SetTarget(acl.Target_User)
|
||||
case GroupSystem:
|
||||
s.target.SetTarget(acl.Target_System)
|
||||
case GroupOthers:
|
||||
s.target.SetTarget(acl.Target_Others)
|
||||
default:
|
||||
s.target.SetTarget(acl.Target_Unknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// KeyList returns the key list of the target.
|
||||
//
|
||||
// If target is not initialized, nil returns.
|
||||
func (s TargetWrapper) KeyList() [][]byte {
|
||||
if s.target == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.target.GetKeyList()
|
||||
}
|
||||
|
||||
// SetKeyList sets the key list of the target.
|
||||
//
|
||||
// If target is not initialized, nothing changes.
|
||||
func (s TargetWrapper) SetKeyList(v [][]byte) {
|
||||
if s.target != nil {
|
||||
s.target.SetKeyList(v)
|
||||
}
|
||||
}
|
||||
|
||||
// OperationType returns the operation type of the record.
|
||||
//
|
||||
// If record is not initialized, OpTypeUnknown returns.
|
||||
//
|
||||
// Returns OpTypeUnknown if Operation is not one of:
|
||||
// - EACLRecord_HEAD;
|
||||
// - EACLRecord_PUT;
|
||||
// - EACLRecord_SEARCH;
|
||||
// - EACLRecord_GET;
|
||||
// - EACLRecord_GETRANGE;
|
||||
// - EACLRecord_GETRANGEHASH;
|
||||
// - EACLRecord_DELETE.
|
||||
func (s RecordWrapper) OperationType() (res OperationType) {
|
||||
res = OpTypeUnknown
|
||||
|
||||
if s.record != nil {
|
||||
switch s.record.GetOperation() {
|
||||
case acl.EACLRecord_HEAD:
|
||||
res = OpTypeHead
|
||||
case acl.EACLRecord_PUT:
|
||||
res = OpTypePut
|
||||
case acl.EACLRecord_SEARCH:
|
||||
res = OpTypeSearch
|
||||
case acl.EACLRecord_GET:
|
||||
res = OpTypeGet
|
||||
case acl.EACLRecord_GETRANGE:
|
||||
res = OpTypeRange
|
||||
case acl.EACLRecord_GETRANGEHASH:
|
||||
res = OpTypeRangeHash
|
||||
case acl.EACLRecord_DELETE:
|
||||
res = OpTypeDelete
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetOperationType sets the operation type of the record.
|
||||
//
|
||||
// If record is not initialized, nothing changes.
|
||||
//
|
||||
// Operation is set to EACLRecord_OPERATION_UNKNOWN if argument is not one of:
|
||||
// - OpTypeHead;
|
||||
// - OpTypePut;
|
||||
// - OpTypeSearch;
|
||||
// - OpTypeGet;
|
||||
// - OpTypeRange;
|
||||
// - OpTypeRangeHash;
|
||||
// - OpTypeDelete.
|
||||
func (s RecordWrapper) SetOperationType(v OperationType) {
|
||||
if s.record != nil {
|
||||
switch v {
|
||||
case OpTypeHead:
|
||||
s.record.SetOperation(acl.EACLRecord_HEAD)
|
||||
case OpTypePut:
|
||||
s.record.SetOperation(acl.EACLRecord_PUT)
|
||||
case OpTypeSearch:
|
||||
s.record.SetOperation(acl.EACLRecord_SEARCH)
|
||||
case OpTypeGet:
|
||||
s.record.SetOperation(acl.EACLRecord_GET)
|
||||
case OpTypeRange:
|
||||
s.record.SetOperation(acl.EACLRecord_GETRANGE)
|
||||
case OpTypeRangeHash:
|
||||
s.record.SetOperation(acl.EACLRecord_GETRANGEHASH)
|
||||
case OpTypeDelete:
|
||||
s.record.SetOperation(acl.EACLRecord_DELETE)
|
||||
default:
|
||||
s.record.SetOperation(acl.EACLRecord_OPERATION_UNKNOWN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Action returns the action of the record.
|
||||
//
|
||||
// If record is not initialized, ActionUnknown returns.
|
||||
//
|
||||
// Returns ActionUnknown if Action is not one of:
|
||||
// - EACLRecord_Deny;
|
||||
// - EACLRecord_Allow.
|
||||
func (s RecordWrapper) Action() (res Action) {
|
||||
res = ActionUnknown
|
||||
|
||||
if s.record != nil {
|
||||
switch s.record.GetAction() {
|
||||
case acl.EACLRecord_Deny:
|
||||
res = ActionDeny
|
||||
case acl.EACLRecord_Allow:
|
||||
res = ActionAllow
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetAction sets the action of the record.
|
||||
//
|
||||
// If record is not initialized, nothing changes.
|
||||
//
|
||||
// Action is set to EACLRecord_ActionUnknown if argument is not one of:
|
||||
// - ActionDeny;
|
||||
// - ActionAllow.
|
||||
func (s RecordWrapper) SetAction(v Action) {
|
||||
if s.record != nil {
|
||||
switch v {
|
||||
case ActionDeny:
|
||||
s.record.SetAction(acl.EACLRecord_Deny)
|
||||
case ActionAllow:
|
||||
s.record.SetAction(acl.EACLRecord_Allow)
|
||||
default:
|
||||
s.record.SetAction(acl.EACLRecord_ActionUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderFilters returns the header filter list of the record.
|
||||
//
|
||||
// If record is not initialized, nil returns.
|
||||
func (s RecordWrapper) HeaderFilters() []HeaderFilter {
|
||||
if s.record == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
filters := s.record.GetFilters()
|
||||
|
||||
res := make([]HeaderFilter, 0, len(filters))
|
||||
|
||||
for i := range filters {
|
||||
res = append(res, WrapFilterInfo(filters[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetHeaderFilters sets the header filter list of the record.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If record is not initialized, nothing changes.
|
||||
func (s RecordWrapper) SetHeaderFilters(v []HeaderFilter) {
|
||||
if s.record == nil {
|
||||
return
|
||||
}
|
||||
|
||||
filters := make([]*acl.EACLRecord_FilterInfo, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapFilterInfo(nil)
|
||||
w.SetMatchType(v[i].MatchType())
|
||||
w.SetHeaderType(v[i].HeaderType())
|
||||
w.SetName(v[i].Name())
|
||||
w.SetValue(v[i].Value())
|
||||
|
||||
filters = append(filters, w.filter)
|
||||
}
|
||||
|
||||
s.record.SetFilters(filters)
|
||||
}
|
||||
|
||||
// TargetList returns the target list of the record.
|
||||
//
|
||||
// If record is not initialized, nil returns.
|
||||
func (s RecordWrapper) TargetList() []Target {
|
||||
if s.record == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
targets := s.record.GetTargets()
|
||||
|
||||
res := make([]Target, 0, len(targets))
|
||||
|
||||
for i := range targets {
|
||||
res = append(res, WrapTarget(targets[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetTargetList sets the target list of the record.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If record is not initialized, nothing changes.
|
||||
func (s RecordWrapper) SetTargetList(v []Target) {
|
||||
if s.record == nil {
|
||||
return
|
||||
}
|
||||
|
||||
targets := make([]*acl.EACLRecord_TargetInfo, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapTarget(nil)
|
||||
w.SetGroup(v[i].Group())
|
||||
w.SetKeyList(v[i].KeyList())
|
||||
|
||||
targets = append(targets, w.target)
|
||||
}
|
||||
|
||||
s.record.SetTargets(targets)
|
||||
}
|
||||
|
||||
// Records returns the record list of the table.
|
||||
//
|
||||
// If table is not initialized, nil returns.
|
||||
func (s TableWrapper) Records() []Record {
|
||||
if s.table == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
records := s.table.GetRecords()
|
||||
|
||||
res := make([]Record, 0, len(records))
|
||||
|
||||
for i := range records {
|
||||
res = append(res, WrapRecord(records[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetRecords sets the record list of the table.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If table is not initialized, nothing changes.
|
||||
func (s TableWrapper) SetRecords(v []Record) {
|
||||
if s.table == nil {
|
||||
return
|
||||
}
|
||||
|
||||
records := make([]*acl.EACLRecord, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapRecord(nil)
|
||||
w.SetOperationType(v[i].OperationType())
|
||||
w.SetAction(v[i].Action())
|
||||
w.SetHeaderFilters(v[i].HeaderFilters())
|
||||
w.SetTargetList(v[i].TargetList())
|
||||
|
||||
records = append(records, w.record)
|
||||
}
|
||||
|
||||
s.table.SetRecords(records)
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package acl
|
||||
package eacl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
@ -27,11 +27,11 @@ func TestEACLFilterWrapper(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEACLTargetWrapper(t *testing.T) {
|
||||
s := WrapEACLTarget(nil)
|
||||
s := WrapTarget(nil)
|
||||
|
||||
target := Target(10)
|
||||
s.SetTarget(target)
|
||||
require.Equal(t, target, s.Target())
|
||||
group := Group(3)
|
||||
s.SetGroup(group)
|
||||
require.Equal(t, group, s.Group())
|
||||
|
||||
keys := [][]byte{
|
||||
{1, 2, 3},
|
||||
|
@ -42,7 +42,7 @@ func TestEACLTargetWrapper(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEACLRecordWrapper(t *testing.T) {
|
||||
s := WrapEACLRecord(nil)
|
||||
s := WrapRecord(nil)
|
||||
|
||||
action := ActionAllow
|
||||
s.SetAction(action)
|
||||
|
@ -67,46 +67,43 @@ func TestEACLRecordWrapper(t *testing.T) {
|
|||
require.Equal(t, f1Name, filters[0].Name())
|
||||
require.Equal(t, f2Name, filters[1].Name())
|
||||
|
||||
target1 := Target(1)
|
||||
t1 := WrapEACLTarget(nil)
|
||||
t1.SetTarget(target1)
|
||||
group1 := Group(1)
|
||||
t1 := WrapTarget(nil)
|
||||
t1.SetGroup(group1)
|
||||
|
||||
target2 := Target(2)
|
||||
t2 := WrapEACLTarget(nil)
|
||||
t2.SetTarget(target2)
|
||||
group2 := Group(2)
|
||||
t2 := WrapTarget(nil)
|
||||
t2.SetGroup(group2)
|
||||
|
||||
s.SetTargetList([]ExtendedACLTarget{t1, t2})
|
||||
s.SetTargetList([]Target{t1, t2})
|
||||
|
||||
targets := s.TargetList()
|
||||
require.Len(t, targets, 2)
|
||||
require.Equal(t, target1, targets[0].Target())
|
||||
require.Equal(t, target2, targets[1].Target())
|
||||
require.Equal(t, group1, targets[0].Group())
|
||||
require.Equal(t, group2, targets[1].Group())
|
||||
}
|
||||
|
||||
func TestEACLTableWrapper(t *testing.T) {
|
||||
s := WrapEACLTable(nil)
|
||||
s := WrapTable(nil)
|
||||
|
||||
action1 := ExtendedACLAction(1)
|
||||
r1 := WrapEACLRecord(nil)
|
||||
action1 := Action(1)
|
||||
r1 := WrapRecord(nil)
|
||||
r1.SetAction(action1)
|
||||
|
||||
action2 := ExtendedACLAction(2)
|
||||
r2 := WrapEACLRecord(nil)
|
||||
action2 := Action(2)
|
||||
r2 := WrapRecord(nil)
|
||||
r2.SetAction(action2)
|
||||
|
||||
s.SetRecords([]ExtendedACLRecord{r1, r2})
|
||||
s.SetRecords([]Record{r1, r2})
|
||||
|
||||
records := s.Records()
|
||||
require.Len(t, records, 2)
|
||||
require.Equal(t, action1, records[0].Action())
|
||||
require.Equal(t, action2, records[1].Action())
|
||||
|
||||
data, err := s.MarshalBinary()
|
||||
s2, err := UnmarshalTable(MarshalTable(s))
|
||||
require.NoError(t, err)
|
||||
|
||||
s2 := WrapEACLTable(nil)
|
||||
require.NoError(t, s2.UnmarshalBinary(data))
|
||||
|
||||
records1 := s.Records()
|
||||
records2 := s2.Records()
|
||||
require.Len(t, records1, len(records2))
|
||||
|
@ -120,7 +117,7 @@ func TestEACLTableWrapper(t *testing.T) {
|
|||
require.Len(t, targets1, len(targets2))
|
||||
|
||||
for j := range targets1 {
|
||||
require.Equal(t, targets1[j].Target(), targets2[j].Target())
|
||||
require.Equal(t, targets1[j].Group(), targets2[j].Group())
|
||||
require.Equal(t, targets1[j].KeyList(), targets2[j].KeyList())
|
||||
}
|
||||
|
73
acl/types.go
73
acl/types.go
|
@ -1,78 +1,5 @@
|
|||
package acl
|
||||
|
||||
const (
|
||||
_ MatchType = iota
|
||||
|
||||
// StringEqual is a MatchType of string equality.
|
||||
StringEqual
|
||||
|
||||
// StringNotEqual is a MatchType of string inequality.
|
||||
StringNotEqual
|
||||
)
|
||||
|
||||
const (
|
||||
// ActionUndefined is ExtendedACLAction used to mark value as undefined.
|
||||
// Most of the tools consider ActionUndefined as incalculable.
|
||||
// Using ActionUndefined in ExtendedACLRecord is unsafe.
|
||||
ActionUndefined ExtendedACLAction = iota
|
||||
|
||||
// ActionAllow is ExtendedACLAction used to mark an applicability of ACL rule.
|
||||
ActionAllow
|
||||
|
||||
// ActionDeny is ExtendedACLAction used to mark an inapplicability of ACL rule.
|
||||
ActionDeny
|
||||
)
|
||||
|
||||
const (
|
||||
_ HeaderType = iota
|
||||
|
||||
// HdrTypeRequest is a HeaderType for request header.
|
||||
HdrTypeRequest
|
||||
|
||||
// HdrTypeObjSys is a HeaderType for system headers of object.
|
||||
HdrTypeObjSys
|
||||
|
||||
// HdrTypeObjUsr is a HeaderType for user headers of object.
|
||||
HdrTypeObjUsr
|
||||
)
|
||||
|
||||
const (
|
||||
// HdrObjSysNameID is a name of ID field in system header of object.
|
||||
HdrObjSysNameID = "ID"
|
||||
|
||||
// HdrObjSysNameCID is a name of CID field in system header of object.
|
||||
HdrObjSysNameCID = "CID"
|
||||
|
||||
// HdrObjSysNameOwnerID is a name of OwnerID field in system header of object.
|
||||
HdrObjSysNameOwnerID = "OWNER_ID"
|
||||
|
||||
// HdrObjSysNameVersion is a name of Version field in system header of object.
|
||||
HdrObjSysNameVersion = "VERSION"
|
||||
|
||||
// HdrObjSysNamePayloadLength is a name of PayloadLength field in system header of object.
|
||||
HdrObjSysNamePayloadLength = "PAYLOAD_LENGTH"
|
||||
|
||||
// HdrObjSysNameCreatedUnix is a name of CreatedAt.UnitTime field in system header of object.
|
||||
HdrObjSysNameCreatedUnix = "CREATED_UNIX"
|
||||
|
||||
// HdrObjSysNameCreatedEpoch is a name of CreatedAt.Epoch field in system header of object.
|
||||
HdrObjSysNameCreatedEpoch = "CREATED_EPOCH"
|
||||
|
||||
// HdrObjSysLinkPrev is a name of previous link header in extended headers of object.
|
||||
HdrObjSysLinkPrev = "LINK_PREV"
|
||||
|
||||
// HdrObjSysLinkNext is a name of next link header in extended headers of object.
|
||||
HdrObjSysLinkNext = "LINK_NEXT"
|
||||
|
||||
// HdrObjSysLinkChild is a name of child link header in extended headers of object.
|
||||
HdrObjSysLinkChild = "LINK_CHILD"
|
||||
|
||||
// HdrObjSysLinkPar is a name of parent link header in extended headers of object.
|
||||
HdrObjSysLinkPar = "LINK_PAR"
|
||||
|
||||
// HdrObjSysLinkSG is a name of storage group link header in extended headers of object.
|
||||
HdrObjSysLinkSG = "LINK_SG"
|
||||
)
|
||||
|
||||
// SetMatchType is MatchType field setter.
|
||||
func (m *EACLRecord_FilterInfo) SetMatchType(v EACLRecord_FilterInfo_MatchType) {
|
||||
|
|
498
acl/wrappers.go
498
acl/wrappers.go
|
@ -1,498 +0,0 @@
|
|||
package acl
|
||||
|
||||
// EACLFilterWrapper is a wrapper over EACLRecord_FilterInfo pointer.
|
||||
type EACLFilterWrapper struct {
|
||||
filter *EACLRecord_FilterInfo
|
||||
}
|
||||
|
||||
// EACLTargetWrapper is a wrapper over EACLRecord_TargetInfo pointer.
|
||||
type EACLTargetWrapper struct {
|
||||
target *EACLRecord_TargetInfo
|
||||
}
|
||||
|
||||
// EACLRecordWrapper is a wrapper over EACLRecord pointer.
|
||||
type EACLRecordWrapper struct {
|
||||
record *EACLRecord
|
||||
}
|
||||
|
||||
// EACLTableWrapper is a wrapper over EACLTable pointer.
|
||||
type EACLTableWrapper struct {
|
||||
table *EACLTable
|
||||
}
|
||||
|
||||
// WrapFilterInfo wraps EACLRecord_FilterInfo pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord_FilterInfo is initialized.
|
||||
func WrapFilterInfo(v *EACLRecord_FilterInfo) EACLFilterWrapper {
|
||||
if v == nil {
|
||||
v = new(EACLRecord_FilterInfo)
|
||||
}
|
||||
|
||||
return EACLFilterWrapper{
|
||||
filter: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapEACLTarget wraps EACLRecord_TargetInfo pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord_TargetInfo is initialized.
|
||||
func WrapEACLTarget(v *EACLRecord_TargetInfo) EACLTargetWrapper {
|
||||
if v == nil {
|
||||
v = new(EACLRecord_TargetInfo)
|
||||
}
|
||||
|
||||
return EACLTargetWrapper{
|
||||
target: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapEACLRecord wraps EACLRecord pointer.
|
||||
//
|
||||
// If argument is nil, new EACLRecord is initialized.
|
||||
func WrapEACLRecord(v *EACLRecord) EACLRecordWrapper {
|
||||
if v == nil {
|
||||
v = new(EACLRecord)
|
||||
}
|
||||
|
||||
return EACLRecordWrapper{
|
||||
record: v,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapEACLTable wraps EACLTable pointer.
|
||||
//
|
||||
// If argument is nil, new EACLTable is initialized.
|
||||
func WrapEACLTable(v *EACLTable) EACLTableWrapper {
|
||||
if v == nil {
|
||||
v = new(EACLTable)
|
||||
}
|
||||
|
||||
return EACLTableWrapper{
|
||||
table: v,
|
||||
}
|
||||
}
|
||||
|
||||
// MatchType returns casted result of MatchType field getter.
|
||||
//
|
||||
// If filter is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if MatchType is not one of:
|
||||
// - EACLRecord_FilterInfo_StringEqual;
|
||||
// - EACLRecord_FilterInfo_StringNotEqual.
|
||||
func (s EACLFilterWrapper) MatchType() (res MatchType) {
|
||||
if s.filter != nil {
|
||||
switch s.filter.GetMatchType() {
|
||||
case EACLRecord_FilterInfo_StringEqual:
|
||||
res = StringEqual
|
||||
case EACLRecord_FilterInfo_StringNotEqual:
|
||||
res = StringNotEqual
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetMatchType passes casted argument to MatchType field setter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
//
|
||||
// MatchType is set to EACLRecord_FilterInfo_MatchUnknown if argument is not one of:
|
||||
// - StringEqual;
|
||||
// - StringNotEqual.
|
||||
func (s EACLFilterWrapper) SetMatchType(v MatchType) {
|
||||
if s.filter != nil {
|
||||
switch v {
|
||||
case StringEqual:
|
||||
s.filter.SetMatchType(EACLRecord_FilterInfo_StringEqual)
|
||||
case StringNotEqual:
|
||||
s.filter.SetMatchType(EACLRecord_FilterInfo_StringNotEqual)
|
||||
default:
|
||||
s.filter.SetMatchType(EACLRecord_FilterInfo_MatchUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the result of HeaderName field getter.
|
||||
//
|
||||
// If filter is not initialized, empty string returns.
|
||||
func (s EACLFilterWrapper) Name() string {
|
||||
if s.filter == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s.filter.GetHeaderName()
|
||||
}
|
||||
|
||||
// SetName passes argument to HeaderName field setter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
func (s EACLFilterWrapper) SetName(v string) {
|
||||
if s.filter != nil {
|
||||
s.filter.SetHeaderName(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Value returns the result of HeaderVal field getter.
|
||||
//
|
||||
// If filter is not initialized, empty string returns.
|
||||
func (s EACLFilterWrapper) Value() string {
|
||||
if s.filter == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s.filter.GetHeaderVal()
|
||||
}
|
||||
|
||||
// SetValue passes argument to HeaderVal field setter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
func (s EACLFilterWrapper) SetValue(v string) {
|
||||
if s.filter != nil {
|
||||
s.filter.SetHeaderVal(v)
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderType returns the result of Header field getter.
|
||||
//
|
||||
// If filter is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if Header is not one of:
|
||||
// - EACLRecord_FilterInfo_Request;
|
||||
// - EACLRecord_FilterInfo_ObjectSystem;
|
||||
// - EACLRecord_FilterInfo_ObjectUser.
|
||||
func (s EACLFilterWrapper) HeaderType() (res HeaderType) {
|
||||
if s.filter != nil {
|
||||
switch s.filter.GetHeader() {
|
||||
case EACLRecord_FilterInfo_Request:
|
||||
res = HdrTypeRequest
|
||||
case EACLRecord_FilterInfo_ObjectSystem:
|
||||
res = HdrTypeObjSys
|
||||
case EACLRecord_FilterInfo_ObjectUser:
|
||||
res = HdrTypeObjUsr
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetHeaderType passes casted argument to Header field setter.
|
||||
//
|
||||
// If filter is not initialized, nothing changes.
|
||||
//
|
||||
// Header is set to EACLRecord_FilterInfo_HeaderUnknown if argument is not one of:
|
||||
// - HdrTypeRequest;
|
||||
// - HdrTypeObjSys;
|
||||
// - HdrTypeObjUsr.
|
||||
func (s EACLFilterWrapper) SetHeaderType(t HeaderType) {
|
||||
if s.filter != nil {
|
||||
switch t {
|
||||
case HdrTypeRequest:
|
||||
s.filter.SetHeader(EACLRecord_FilterInfo_Request)
|
||||
case HdrTypeObjSys:
|
||||
s.filter.SetHeader(EACLRecord_FilterInfo_ObjectSystem)
|
||||
case HdrTypeObjUsr:
|
||||
s.filter.SetHeader(EACLRecord_FilterInfo_ObjectUser)
|
||||
default:
|
||||
s.filter.SetHeader(EACLRecord_FilterInfo_HeaderUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Target returns the result of Target field getter.
|
||||
//
|
||||
// If target is not initialized, Target_Unknown returns.
|
||||
func (s EACLTargetWrapper) Target() Target {
|
||||
if s.target == nil {
|
||||
return Target_Unknown
|
||||
}
|
||||
|
||||
return s.target.GetTarget()
|
||||
}
|
||||
|
||||
// SetTarget passes argument to Target field setter.
|
||||
//
|
||||
// If target is not initialized, nothing changes.
|
||||
func (s EACLTargetWrapper) SetTarget(v Target) {
|
||||
if s.target != nil {
|
||||
s.target.SetTarget(v)
|
||||
}
|
||||
}
|
||||
|
||||
// KeyList returns the result of KeyList field getter.
|
||||
//
|
||||
// If target is not initialized, nil returns.
|
||||
func (s EACLTargetWrapper) KeyList() [][]byte {
|
||||
if s.target == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.target.GetKeyList()
|
||||
}
|
||||
|
||||
// SetKeyList passes argument to KeyList field setter.
|
||||
//
|
||||
// If target is not initialized, nothing changes.
|
||||
func (s EACLTargetWrapper) SetKeyList(v [][]byte) {
|
||||
if s.target != nil {
|
||||
s.target.SetKeyList(v)
|
||||
}
|
||||
}
|
||||
|
||||
// OperationType returns casted result of Operation field getter.
|
||||
//
|
||||
// If record is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if Operation is not one of:
|
||||
// - EACLRecord_HEAD;
|
||||
// - EACLRecord_PUT;
|
||||
// - EACLRecord_SEARCH;
|
||||
// - EACLRecord_GET;
|
||||
// - EACLRecord_GETRANGE;
|
||||
// - EACLRecord_GETRANGEHASH;
|
||||
// - EACLRecord_DELETE.
|
||||
func (s EACLRecordWrapper) OperationType() (res OperationType) {
|
||||
if s.record != nil {
|
||||
switch s.record.GetOperation() {
|
||||
case EACLRecord_HEAD:
|
||||
res = OpTypeHead
|
||||
case EACLRecord_PUT:
|
||||
res = OpTypePut
|
||||
case EACLRecord_SEARCH:
|
||||
res = OpTypeSearch
|
||||
case EACLRecord_GET:
|
||||
res = OpTypeGet
|
||||
case EACLRecord_GETRANGE:
|
||||
res = OpTypeRange
|
||||
case EACLRecord_GETRANGEHASH:
|
||||
res = OpTypeRangeHash
|
||||
case EACLRecord_DELETE:
|
||||
res = OpTypeDelete
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetOperationType passes casted argument to Operation field setter.
|
||||
//
|
||||
// If record is not initialized, nothing changes.
|
||||
//
|
||||
// Operation is set to EACLRecord_OPERATION_UNKNOWN if argument is not one of:
|
||||
// - OpTypeHead;
|
||||
// - OpTypePut;
|
||||
// - OpTypeSearch;
|
||||
// - OpTypeGet;
|
||||
// - OpTypeRange;
|
||||
// - OpTypeRangeHash;
|
||||
// - OpTypeDelete.
|
||||
func (s EACLRecordWrapper) SetOperationType(v OperationType) {
|
||||
if s.record != nil {
|
||||
switch v {
|
||||
case OpTypeHead:
|
||||
s.record.SetOperation(EACLRecord_HEAD)
|
||||
case OpTypePut:
|
||||
s.record.SetOperation(EACLRecord_PUT)
|
||||
case OpTypeSearch:
|
||||
s.record.SetOperation(EACLRecord_SEARCH)
|
||||
case OpTypeGet:
|
||||
s.record.SetOperation(EACLRecord_GET)
|
||||
case OpTypeRange:
|
||||
s.record.SetOperation(EACLRecord_GETRANGE)
|
||||
case OpTypeRangeHash:
|
||||
s.record.SetOperation(EACLRecord_GETRANGEHASH)
|
||||
case OpTypeDelete:
|
||||
s.record.SetOperation(EACLRecord_DELETE)
|
||||
default:
|
||||
s.record.SetOperation(EACLRecord_OPERATION_UNKNOWN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Action returns casted result of Action field getter.
|
||||
//
|
||||
// If record is not initialized, 0 returns.
|
||||
//
|
||||
// Returns 0 if Action is not one of:
|
||||
// - EACLRecord_Deny;
|
||||
// - EACLRecord_Allow.
|
||||
func (s EACLRecordWrapper) Action() (res ExtendedACLAction) {
|
||||
if s.record != nil {
|
||||
switch s.record.GetAction() {
|
||||
case EACLRecord_Deny:
|
||||
res = ActionDeny
|
||||
case EACLRecord_Allow:
|
||||
res = ActionAllow
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetAction passes casted argument to Action field setter.
|
||||
//
|
||||
// If record is not initialized, nothing changes.
|
||||
//
|
||||
// Action is set to EACLRecord_ActionUnknown if argument is not one of:
|
||||
// - ActionDeny;
|
||||
// - ActionAllow.
|
||||
func (s EACLRecordWrapper) SetAction(v ExtendedACLAction) {
|
||||
if s.record != nil {
|
||||
switch v {
|
||||
case ActionDeny:
|
||||
s.record.SetAction(EACLRecord_Deny)
|
||||
case ActionAllow:
|
||||
s.record.SetAction(EACLRecord_Allow)
|
||||
default:
|
||||
s.record.SetAction(EACLRecord_ActionUnknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderFilters wraps all elements from Filters field getter result and returns HeaderFilter list.
|
||||
//
|
||||
// If record is not initialized, nil returns.
|
||||
func (s EACLRecordWrapper) HeaderFilters() []HeaderFilter {
|
||||
if s.record == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
filters := s.record.GetFilters()
|
||||
|
||||
res := make([]HeaderFilter, 0, len(filters))
|
||||
|
||||
for i := range filters {
|
||||
res = append(res, WrapFilterInfo(filters[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetHeaderFilters converts HeaderFilter list to EACLRecord_FilterInfo list and passes it to Filters field setter.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If record is not initialized, nothing changes.
|
||||
func (s EACLRecordWrapper) SetHeaderFilters(v []HeaderFilter) {
|
||||
if s.record == nil {
|
||||
return
|
||||
}
|
||||
|
||||
filters := make([]*EACLRecord_FilterInfo, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapFilterInfo(nil)
|
||||
w.SetMatchType(v[i].MatchType())
|
||||
w.SetHeaderType(v[i].HeaderType())
|
||||
w.SetName(v[i].Name())
|
||||
w.SetValue(v[i].Value())
|
||||
|
||||
filters = append(filters, w.filter)
|
||||
}
|
||||
|
||||
s.record.SetFilters(filters)
|
||||
}
|
||||
|
||||
// TargetList wraps all elements from Targets field getter result and returns ExtendedACLTarget list.
|
||||
//
|
||||
// If record is not initialized, nil returns.
|
||||
func (s EACLRecordWrapper) TargetList() []ExtendedACLTarget {
|
||||
if s.record == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
targets := s.record.GetTargets()
|
||||
|
||||
res := make([]ExtendedACLTarget, 0, len(targets))
|
||||
|
||||
for i := range targets {
|
||||
res = append(res, WrapEACLTarget(targets[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetTargetList converts ExtendedACLTarget list to EACLRecord_TargetInfo list and passes it to Targets field setter.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If record is not initialized, nothing changes.
|
||||
func (s EACLRecordWrapper) SetTargetList(v []ExtendedACLTarget) {
|
||||
if s.record == nil {
|
||||
return
|
||||
}
|
||||
|
||||
targets := make([]*EACLRecord_TargetInfo, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapEACLTarget(nil)
|
||||
w.SetTarget(v[i].Target())
|
||||
w.SetKeyList(v[i].KeyList())
|
||||
|
||||
targets = append(targets, w.target)
|
||||
}
|
||||
|
||||
s.record.SetTargets(targets)
|
||||
}
|
||||
|
||||
// Records wraps all elements from Records field getter result and returns ExtendedACLRecord list.
|
||||
//
|
||||
// If table is not initialized, nil returns.
|
||||
func (s EACLTableWrapper) Records() []ExtendedACLRecord {
|
||||
if s.table == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
records := s.table.GetRecords()
|
||||
|
||||
res := make([]ExtendedACLRecord, 0, len(records))
|
||||
|
||||
for i := range records {
|
||||
res = append(res, WrapEACLRecord(records[i]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SetRecords converts ExtendedACLRecord list to EACLRecord list and passes it to Records field setter.
|
||||
//
|
||||
// Ignores nil elements of argument.
|
||||
// If table is not initialized, nothing changes.
|
||||
func (s EACLTableWrapper) SetRecords(v []ExtendedACLRecord) {
|
||||
if s.table == nil {
|
||||
return
|
||||
}
|
||||
|
||||
records := make([]*EACLRecord, 0, len(v))
|
||||
|
||||
for i := range v {
|
||||
if v[i] == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
w := WrapEACLRecord(nil)
|
||||
w.SetOperationType(v[i].OperationType())
|
||||
w.SetAction(v[i].Action())
|
||||
w.SetHeaderFilters(v[i].HeaderFilters())
|
||||
w.SetTargetList(v[i].TargetList())
|
||||
|
||||
records = append(records, w.record)
|
||||
}
|
||||
|
||||
s.table.SetRecords(records)
|
||||
}
|
||||
|
||||
// MarshalBinary returns the result of Marshal method.
|
||||
func (s EACLTableWrapper) MarshalBinary() ([]byte, error) {
|
||||
return s.table.Marshal()
|
||||
}
|
||||
|
||||
// UnmarshalBinary passes argument to Unmarshal method and returns its result.
|
||||
func (s EACLTableWrapper) UnmarshalBinary(data []byte) error {
|
||||
return s.table.Unmarshal(data)
|
||||
}
|
173
chain/address.go
173
chain/address.go
|
@ -1,16 +1,9 @@
|
|||
package chain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neofs-api-go/internal"
|
||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
)
|
||||
|
||||
// WalletAddress implements NEO address.
|
||||
|
@ -18,168 +11,20 @@ type WalletAddress [AddressLength]byte
|
|||
|
||||
const (
|
||||
// AddressLength contains size of address,
|
||||
// 0x17 byte (address version) + 20 bytes of ScriptHash + 4 bytes of checksum.
|
||||
// 1 byte of address version + 20 bytes of ScriptHash + 4 bytes of checksum.
|
||||
AddressLength = 25
|
||||
|
||||
// ScriptHashLength contains size of ScriptHash.
|
||||
ScriptHashLength = 20
|
||||
|
||||
// ErrEmptyAddress is raised when empty Address is passed.
|
||||
ErrEmptyAddress = internal.Error("empty address")
|
||||
|
||||
// ErrAddressLength is raised when passed address has wrong size.
|
||||
ErrAddressLength = internal.Error("wrong address length")
|
||||
)
|
||||
|
||||
func checksum(sign []byte) []byte {
|
||||
hash := sha256.Sum256(sign)
|
||||
hash = sha256.Sum256(hash[:])
|
||||
return hash[:4]
|
||||
}
|
||||
|
||||
// FetchPublicKeys tries to parse public keys from verification script.
|
||||
func FetchPublicKeys(vs []byte) []*ecdsa.PublicKey {
|
||||
var (
|
||||
count int
|
||||
offset int
|
||||
ln = len(vs)
|
||||
result []*ecdsa.PublicKey
|
||||
)
|
||||
|
||||
switch {
|
||||
case ln < 1: // wrong data size
|
||||
return nil
|
||||
case vs[ln-1] == 0xac: // last byte is CHECKSIG
|
||||
count = 1
|
||||
case vs[ln-1] == 0xae: // last byte is CHECKMULTISIG
|
||||
// 2nd byte from the end indicates about PK's count
|
||||
count = int(vs[ln-2] - 0x50)
|
||||
// ignores CHECKMULTISIG
|
||||
offset = 1
|
||||
default: // unknown type
|
||||
return nil
|
||||
}
|
||||
|
||||
result = make([]*ecdsa.PublicKey, 0, count)
|
||||
for i := 0; i < count; i++ {
|
||||
// ignores PUSHBYTE33 and tries to parse
|
||||
from, to := offset+1, offset+1+crypto.PublicKeyCompressedSize
|
||||
|
||||
// when passed VerificationScript has wrong size
|
||||
if len(vs) < to {
|
||||
return nil
|
||||
}
|
||||
|
||||
key := crypto.UnmarshalPublicKey(vs[from:to])
|
||||
// when wrong public key is passed
|
||||
if key == nil {
|
||||
return nil
|
||||
}
|
||||
result = append(result, key)
|
||||
|
||||
offset += 1 + crypto.PublicKeyCompressedSize
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// VerificationScript returns VerificationScript composed from public keys.
|
||||
func VerificationScript(pubs ...*ecdsa.PublicKey) []byte {
|
||||
var (
|
||||
pre []byte
|
||||
suf []byte
|
||||
body []byte
|
||||
offset int
|
||||
lnPK = len(pubs)
|
||||
ln = crypto.PublicKeyCompressedSize*lnPK + lnPK // 33 * count + count * 1 (PUSHBYTES33)
|
||||
)
|
||||
|
||||
if len(pubs) > 1 {
|
||||
pre = []byte{0x51} // one address
|
||||
suf = []byte{byte(0x50 + lnPK), 0xae} // count of PK's + CHECKMULTISIG
|
||||
} else {
|
||||
suf = []byte{0xac} // CHECKSIG
|
||||
}
|
||||
|
||||
ln += len(pre) + len(suf)
|
||||
|
||||
body = make([]byte, ln)
|
||||
offset += copy(body, pre)
|
||||
|
||||
for i := range pubs {
|
||||
body[offset] = 0x21
|
||||
offset++
|
||||
offset += copy(body[offset:], crypto.MarshalPublicKey(pubs[i]))
|
||||
}
|
||||
|
||||
copy(body[offset:], suf)
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
// KeysToAddress return NEO address composed from public keys.
|
||||
func KeysToAddress(pubs ...*ecdsa.PublicKey) string {
|
||||
if len(pubs) == 0 {
|
||||
// KeyToAddress returns NEO address composed from public key.
|
||||
func KeyToAddress(key *ecdsa.PublicKey) string {
|
||||
if key == nil {
|
||||
return ""
|
||||
}
|
||||
return Address(VerificationScript(pubs...))
|
||||
}
|
||||
|
||||
// Address returns NEO address based on passed VerificationScript.
|
||||
func Address(verificationScript []byte) string {
|
||||
sign := [AddressLength]byte{0x17}
|
||||
hash := sha256.Sum256(verificationScript)
|
||||
ripe := ripemd160.New()
|
||||
ripe.Write(hash[:])
|
||||
copy(sign[1:], ripe.Sum(nil))
|
||||
copy(sign[21:], checksum(sign[:21]))
|
||||
return base58.Encode(sign[:])
|
||||
}
|
||||
|
||||
// ReversedScriptHashToAddress parses script hash and returns valid NEO address.
|
||||
func ReversedScriptHashToAddress(sc string) (addr string, err error) {
|
||||
var data []byte
|
||||
if data, err = DecodeScriptHash(sc); err != nil {
|
||||
return
|
||||
}
|
||||
sign := [AddressLength]byte{0x17}
|
||||
copy(sign[1:], data)
|
||||
copy(sign[1+ScriptHashLength:], checksum(sign[:1+ScriptHashLength]))
|
||||
return base58.Encode(sign[:]), nil
|
||||
}
|
||||
|
||||
// IsAddress checks that passed NEO Address is valid.
|
||||
func IsAddress(s string) error {
|
||||
if s == "" {
|
||||
return ErrEmptyAddress
|
||||
} else if addr, err := base58.Decode(s); err != nil {
|
||||
return errors.Wrap(err, "base58 decode")
|
||||
} else if ln := len(addr); ln != AddressLength {
|
||||
return errors.Wrapf(ErrAddressLength, "length %d != %d", AddressLength, ln)
|
||||
} else if sum := checksum(addr[:21]); !bytes.Equal(addr[21:], sum) {
|
||||
return errors.Errorf("wrong checksum %0x != %0x",
|
||||
addr[21:], sum)
|
||||
neoPublicKey := keys.PublicKey{
|
||||
X: key.X,
|
||||
Y: key.Y,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReverseBytes returns reversed []byte of given.
|
||||
func ReverseBytes(data []byte) []byte {
|
||||
for i, j := 0, len(data)-1; i < j; i, j = i+1, j-1 {
|
||||
data[i], data[j] = data[j], data[i]
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// DecodeScriptHash parses script hash into slice of bytes.
|
||||
func DecodeScriptHash(s string) ([]byte, error) {
|
||||
if s == "" {
|
||||
return nil, ErrEmptyAddress
|
||||
} else if addr, err := hex.DecodeString(s); err != nil {
|
||||
return nil, errors.Wrap(err, "hex decode")
|
||||
} else if ln := len(addr); ln != ScriptHashLength {
|
||||
return nil, errors.Wrapf(ErrAddressLength, "length %d != %d", ScriptHashLength, ln)
|
||||
} else {
|
||||
return addr, nil
|
||||
}
|
||||
return neoPublicKey.Address()
|
||||
}
|
||||
|
|
|
@ -1,292 +1,41 @@
|
|||
package chain
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||
"github.com/nspcc-dev/neofs-crypto/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAddress(t *testing.T) {
|
||||
var (
|
||||
multiSigVerificationScript = "512103c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c57172103fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df952ae"
|
||||
multiSigAddress = "ANbvKqa2SfgTUkq43NRUhCiyxPrpUPn7S3"
|
||||
|
||||
normalVerificationScript = "2102a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61ac"
|
||||
normalAddress = "AcraNnCuPKnUYtPYyrACRCVJhLpvskbfhu"
|
||||
)
|
||||
|
||||
t.Run("check multi-sig address", func(t *testing.T) {
|
||||
data, err := hex.DecodeString(multiSigVerificationScript)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, multiSigAddress, Address(data))
|
||||
})
|
||||
|
||||
t.Run("check normal address", func(t *testing.T) {
|
||||
data, err := hex.DecodeString(normalVerificationScript)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, normalAddress, Address(data))
|
||||
})
|
||||
type addressTestCase struct {
|
||||
name string
|
||||
publicKey string
|
||||
wallet string
|
||||
}
|
||||
|
||||
func TestVerificationScript(t *testing.T) {
|
||||
t.Run("check normal", func(t *testing.T) {
|
||||
pkString := "02a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61"
|
||||
|
||||
pkBytes, err := hex.DecodeString(pkString)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk := crypto.UnmarshalPublicKey(pkBytes)
|
||||
|
||||
expect, err := hex.DecodeString(
|
||||
"21" + pkString + // PUSHBYTES33
|
||||
"ac", // CHECKSIG
|
||||
)
|
||||
|
||||
require.Equal(t, expect, VerificationScript(pk))
|
||||
})
|
||||
|
||||
t.Run("check multisig", func(t *testing.T) {
|
||||
pk1String := "03c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c5717"
|
||||
pk2String := "03fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df9"
|
||||
|
||||
pk1Bytes, err := hex.DecodeString(pk1String)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk1 := crypto.UnmarshalPublicKey(pk1Bytes)
|
||||
|
||||
pk2Bytes, err := hex.DecodeString(pk2String)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk2 := crypto.UnmarshalPublicKey(pk2Bytes)
|
||||
|
||||
expect, err := hex.DecodeString(
|
||||
"51" + // one address
|
||||
"21" + pk1String + // PUSHBYTES33
|
||||
"21" + pk2String + // PUSHBYTES33
|
||||
"52" + // 2 PublicKeys
|
||||
"ae", // CHECKMULTISIG
|
||||
)
|
||||
|
||||
require.Equal(t, expect, VerificationScript(pk1, pk2))
|
||||
})
|
||||
}
|
||||
|
||||
func TestKeysToAddress(t *testing.T) {
|
||||
t.Run("check normal", func(t *testing.T) {
|
||||
pkString := "02a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61"
|
||||
|
||||
pkBytes, err := hex.DecodeString(pkString)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk := crypto.UnmarshalPublicKey(pkBytes)
|
||||
|
||||
expect := "AcraNnCuPKnUYtPYyrACRCVJhLpvskbfhu"
|
||||
|
||||
actual := KeysToAddress(pk)
|
||||
require.Equal(t, expect, actual)
|
||||
require.NoError(t, IsAddress(actual))
|
||||
})
|
||||
|
||||
t.Run("check multisig", func(t *testing.T) {
|
||||
pk1String := "03c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c5717"
|
||||
pk2String := "03fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df9"
|
||||
|
||||
pk1Bytes, err := hex.DecodeString(pk1String)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk1 := crypto.UnmarshalPublicKey(pk1Bytes)
|
||||
|
||||
pk2Bytes, err := hex.DecodeString(pk2String)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk2 := crypto.UnmarshalPublicKey(pk2Bytes)
|
||||
|
||||
expect := "ANbvKqa2SfgTUkq43NRUhCiyxPrpUPn7S3"
|
||||
actual := KeysToAddress(pk1, pk2)
|
||||
require.Equal(t, expect, actual)
|
||||
require.NoError(t, IsAddress(actual))
|
||||
})
|
||||
}
|
||||
|
||||
func TestFetchPublicKeys(t *testing.T) {
|
||||
var (
|
||||
multiSigVerificationScript = "512103c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c57172103fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df952ae"
|
||||
normalVerificationScript = "2102a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61ac"
|
||||
|
||||
pk1String = "03c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c5717"
|
||||
pk2String = "03fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df9"
|
||||
pk3String = "02a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61"
|
||||
)
|
||||
|
||||
t.Run("shouls not fail", func(t *testing.T) {
|
||||
wrongVS, err := hex.DecodeString(multiSigVerificationScript)
|
||||
require.NoError(t, err)
|
||||
|
||||
wrongVS[len(wrongVS)-1] = 0x1
|
||||
|
||||
wrongPK, err := hex.DecodeString(multiSigVerificationScript)
|
||||
require.NoError(t, err)
|
||||
wrongPK[2] = 0x1
|
||||
|
||||
var testCases = []struct {
|
||||
name string
|
||||
value []byte
|
||||
}{
|
||||
{name: "empty VerificationScript"},
|
||||
{
|
||||
name: "wrong size VerificationScript",
|
||||
value: []byte{0x1},
|
||||
},
|
||||
{
|
||||
name: "wrong VerificationScript type",
|
||||
value: wrongVS,
|
||||
},
|
||||
{
|
||||
name: "wrong public key in VerificationScript",
|
||||
value: wrongPK,
|
||||
},
|
||||
}
|
||||
|
||||
for i := range testCases {
|
||||
tt := testCases[i]
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var keys []*ecdsa.PublicKey
|
||||
require.NotPanics(t, func() {
|
||||
keys = FetchPublicKeys(tt.value)
|
||||
})
|
||||
require.Nil(t, keys)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("check multi-sig address", func(t *testing.T) {
|
||||
data, err := hex.DecodeString(multiSigVerificationScript)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk1Bytes, err := hex.DecodeString(pk1String)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk2Bytes, err := hex.DecodeString(pk2String)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk1 := crypto.UnmarshalPublicKey(pk1Bytes)
|
||||
pk2 := crypto.UnmarshalPublicKey(pk2Bytes)
|
||||
|
||||
keys := FetchPublicKeys(data)
|
||||
require.Len(t, keys, 2)
|
||||
require.Equal(t, keys[0], pk1)
|
||||
require.Equal(t, keys[1], pk2)
|
||||
})
|
||||
|
||||
t.Run("check normal address", func(t *testing.T) {
|
||||
data, err := hex.DecodeString(normalVerificationScript)
|
||||
require.NoError(t, err)
|
||||
|
||||
pkBytes, err := hex.DecodeString(pk3String)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk := crypto.UnmarshalPublicKey(pkBytes)
|
||||
|
||||
keys := FetchPublicKeys(data)
|
||||
require.Len(t, keys, 1)
|
||||
require.Equal(t, keys[0], pk)
|
||||
})
|
||||
|
||||
t.Run("generate 10 keys VerificationScript and try parse it", func(t *testing.T) {
|
||||
var (
|
||||
count = 10
|
||||
expect = make([]*ecdsa.PublicKey, 0, count)
|
||||
)
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
key := test.DecodeKey(i)
|
||||
expect = append(expect, &key.PublicKey)
|
||||
}
|
||||
|
||||
vs := VerificationScript(expect...)
|
||||
|
||||
actual := FetchPublicKeys(vs)
|
||||
require.Equal(t, expect, actual)
|
||||
})
|
||||
}
|
||||
|
||||
func TestReversedScriptHashToAddress(t *testing.T) {
|
||||
var testCases = []struct {
|
||||
name string
|
||||
value string
|
||||
expect string
|
||||
}{
|
||||
func TestKeyToAddress(t *testing.T) {
|
||||
tests := []addressTestCase{
|
||||
{
|
||||
name: "first",
|
||||
expect: "APfiG5imQgn8dzTTfaDfqHnxo3QDUkF69A",
|
||||
value: "5696acd07f0927fd5f01946828638c9e2c90c5dc",
|
||||
"nil key",
|
||||
"",
|
||||
"",
|
||||
},
|
||||
|
||||
{
|
||||
name: "second",
|
||||
expect: "AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y",
|
||||
value: "23ba2703c53263e8d6e522dc32203339dcd8eee9",
|
||||
"correct key",
|
||||
"031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a",
|
||||
"NgzuJWWGVEwFGsRrgzj8knswEYRJrTe7sm",
|
||||
},
|
||||
}
|
||||
|
||||
for i := range testCases {
|
||||
tt := testCases[i]
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual, err := ReversedScriptHashToAddress(tt.value)
|
||||
for i := range tests {
|
||||
t.Run(tests[i].name, func(t *testing.T) {
|
||||
data, err := hex.DecodeString(tests[i].publicKey)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expect, actual)
|
||||
require.NoError(t, IsAddress(actual))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReverseBytes(t *testing.T) {
|
||||
var testCases = []struct {
|
||||
name string
|
||||
value []byte
|
||||
expect []byte
|
||||
}{
|
||||
{name: "empty"},
|
||||
{
|
||||
name: "single byte",
|
||||
expect: []byte{0x1},
|
||||
value: []byte{0x1},
|
||||
},
|
||||
|
||||
{
|
||||
name: "two bytes",
|
||||
expect: []byte{0x2, 0x1},
|
||||
value: []byte{0x1, 0x2},
|
||||
},
|
||||
|
||||
{
|
||||
name: "three bytes",
|
||||
expect: []byte{0x3, 0x2, 0x1},
|
||||
value: []byte{0x1, 0x2, 0x3},
|
||||
},
|
||||
|
||||
{
|
||||
name: "five bytes",
|
||||
expect: []byte{0x5, 0x4, 0x3, 0x2, 0x1},
|
||||
value: []byte{0x1, 0x2, 0x3, 0x4, 0x5},
|
||||
},
|
||||
|
||||
{
|
||||
name: "eight bytes",
|
||||
expect: []byte{0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1},
|
||||
value: []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8},
|
||||
},
|
||||
}
|
||||
|
||||
for i := range testCases {
|
||||
tt := testCases[i]
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual := ReverseBytes(tt.value)
|
||||
require.Equal(t, tt.expect, actual)
|
||||
|
||||
key := crypto.UnmarshalPublicKey(data)
|
||||
|
||||
require.Equal(t, tests[i].wallet, KeyToAddress(key))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package container
|
|||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neofs-api-go/internal"
|
||||
"github.com/nspcc-dev/neofs-api-go/refs"
|
||||
|
@ -63,6 +64,13 @@ func (m *Container) ID() (CID, error) {
|
|||
return refs.CIDForBytes(data), nil
|
||||
}
|
||||
|
||||
// Merge used by proto.Clone
|
||||
func (m *Container) Merge(src proto.Message) {
|
||||
if tmp, ok := src.(*Container); ok {
|
||||
*m = *tmp
|
||||
}
|
||||
}
|
||||
|
||||
// Empty checks that container is empty.
|
||||
func (m *Container) Empty() bool {
|
||||
return m.Capacity == 0 || bytes.Equal(m.Salt.Bytes(), emptySalt) || bytes.Equal(m.OwnerID.Bytes(), emptyOwner)
|
||||
|
|
1
go.mod
1
go.mod
|
@ -7,6 +7,7 @@ require (
|
|||
github.com/golang/protobuf v1.4.2
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/mr-tron/base58 v1.1.3
|
||||
github.com/nspcc-dev/neo-go v0.90.0
|
||||
github.com/nspcc-dev/neofs-crypto v0.3.0
|
||||
github.com/nspcc-dev/netmap v1.7.0
|
||||
github.com/nspcc-dev/tzhash v1.4.0
|
||||
|
|
83
go.sum
83
go.sum
|
@ -14,14 +14,23 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
|
|||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/CityOfZion/neo-go v0.62.1-pre.0.20191114145240-e740fbe708f8/go.mod h1:MJCkWUBhi9pn/CrYO1Q3P687y2KeahrOPS9BD9LDGb0=
|
||||
github.com/CityOfZion/neo-go v0.70.1-pre.0.20191209120015-fccb0085941e/go.mod h1:0enZl0az8xA6PVkwzEOwPWVJGqlt/GO4hA4kmQ5Xzig=
|
||||
github.com/CityOfZion/neo-go v0.70.1-pre.0.20191212173117-32ac01130d4c/go.mod h1:JtlHfeqLywZLswKIKFnAp+yzezY4Dji9qlfQKB2OD/I=
|
||||
github.com/CityOfZion/neo-go v0.71.1-pre.0.20200129171427-f773ec69fb84/go.mod h1:FLI526IrRWHmcsO+mHsCbj64pJZhwQFTLJZu+A4PGOA=
|
||||
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
|
||||
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
|
||||
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/awalterschulze/gographviz v0.0.0-20181013152038-b2885df04310 h1:t+qxRrRtwNiUYA+Xh2jSXhoG2grnMCMKX4Fg6lx9X1U=
|
||||
|
@ -35,28 +44,40 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm
|
|||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM=
|
||||
github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:rZfgFAXFS/z/lEd6LJmf9HVZ1LkgYiHx5pHhV5DR16M=
|
||||
github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
|
@ -65,7 +86,9 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
|
|||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-redis/redis v6.10.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
|
@ -91,6 +114,9 @@ github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ
|
|||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
|
@ -134,8 +160,11 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
|||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
|
@ -148,19 +177,27 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
|||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
|
@ -176,20 +213,36 @@ github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW
|
|||
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
|
||||
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20191205084618-dacb1a30c254/go.mod h1:w1Ln2aT+dBlPhLnuZhBV+DfPEdS2CHWWLp5JTScY3bw=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20191209120240-0d6b7568d9ae/go.mod h1:3FjXOoHmA51EGfb5GS/HOv7VdmngNRTssSeQ729dvGY=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a/go.mod h1:/YFK+XOxxg0Bfm6P92lY5eDSLYfp06XOdL8KAVgXjVk=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1/go.mod h1:O0qtn62prQSqizzoagHmuuKoz8QMkU3SzBoKdEvm3aQ=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200711144034-c526ccc6f570/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E=
|
||||
github.com/nspcc-dev/hrw v1.0.8 h1:vwRuJXZXgkMvf473vFzeWGCfY1WBVeSHAEHvR4u3/Cg=
|
||||
github.com/nspcc-dev/hrw v1.0.8/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
|
||||
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
|
||||
github.com/nspcc-dev/neo-go v0.90.0 h1:ABNDrJuF9C1XuLQu0q9DKSVMlg9eQn/g6rX8Jbr31bo=
|
||||
github.com/nspcc-dev/neo-go v0.90.0/go.mod h1:pPFdnApJwUSRAnpdiPBZl7I7jv0doDg5naecpSPK4+Q=
|
||||
github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=
|
||||
github.com/nspcc-dev/neofs-crypto v0.2.3/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
||||
github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM=
|
||||
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
||||
github.com/nspcc-dev/netmap v1.7.0 h1:ak64xn/gPdgYw4tsqSSF7kAGQGbEpeuJEF3XwBX4L9Y=
|
||||
github.com/nspcc-dev/netmap v1.7.0/go.mod h1:mhV3UOg9ljQmu0teQShD6+JYX09XY5gu2I4hIByCH9M=
|
||||
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/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||
github.com/nspcc-dev/tzhash v1.4.0 h1:RVIR+mxOBHl58CE99+DXtE31ylD5PEkZSoWqoj4fVjg=
|
||||
github.com/nspcc-dev/tzhash v1.4.0/go.mod h1:Z8gp/VZbyWgPhaMp/KTmeoW5UTynp/N60g0jTtSzBws=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
@ -201,6 +254,7 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr
|
|||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
|
||||
github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
|
||||
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
|
@ -212,16 +266,19 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
|
|||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
|
@ -238,10 +295,12 @@ github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
|||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
@ -254,9 +313,17 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
|
|||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/goleveldb v0.0.0-20180307113352-169b1b37be73/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/yuin/gopher-lua v0.0.0-20191128022950-c6266f4fe8d7/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
@ -264,9 +331,11 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
|
|||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -289,6 +358,7 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG
|
|||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -317,11 +387,15 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -330,8 +404,14 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
|
@ -342,6 +422,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180318012157-96caea41033d/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -408,9 +489,11 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
|
|
|
@ -3,6 +3,7 @@ package hash
|
|||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neofs-api-go/internal"
|
||||
"github.com/nspcc-dev/tzhash/tz"
|
||||
|
@ -78,6 +79,13 @@ func (h Hash) Validate(hashes []Hash) bool {
|
|||
return err == nil && ok
|
||||
}
|
||||
|
||||
// Merge used by proto.Clone
|
||||
func (h *Hash) Merge(src proto.Message) {
|
||||
if tmp, ok := src.(*Hash); ok {
|
||||
*h = *tmp
|
||||
}
|
||||
}
|
||||
|
||||
// Sum returns Tillich-Zémor checksum of data.
|
||||
func Sum(data []byte) Hash { return tz.Sum(data) }
|
||||
|
||||
|
|
|
@ -13,4 +13,7 @@ type Custom interface {
|
|||
MarshalTo(data []byte) (int, error)
|
||||
Unmarshal(data []byte) error
|
||||
proto.Message
|
||||
|
||||
// Should contains for proto.Clone
|
||||
proto.Merger
|
||||
}
|
||||
|
|
|
@ -163,6 +163,13 @@ func (m *Object) SetHeader(h *Header) {
|
|||
m.AddHeader(h)
|
||||
}
|
||||
|
||||
// Merge used by proto.Clone
|
||||
func (m *Object) Merge(src proto.Message) {
|
||||
if tmp, ok := src.(*Object); ok {
|
||||
tmp.CopyTo(m)
|
||||
}
|
||||
}
|
||||
|
||||
func (m Header) typeOf(t isHeader_Value) (ok bool) {
|
||||
switch t.(type) {
|
||||
case *Header_Link:
|
||||
|
@ -233,8 +240,15 @@ func (m *Object) Copy() (obj *Object) {
|
|||
// This function creates copies on every available data slice.
|
||||
func (m *Object) CopyTo(o *Object) {
|
||||
o.SystemHeader = m.SystemHeader
|
||||
o.Headers = make([]Header, len(m.Headers))
|
||||
o.Payload = make([]byte, len(m.Payload))
|
||||
|
||||
if m.Headers != nil {
|
||||
o.Headers = make([]Header, len(m.Headers))
|
||||
}
|
||||
|
||||
if m.Payload != nil {
|
||||
o.Payload = make([]byte, len(m.Payload))
|
||||
copy(o.Payload, m.Payload)
|
||||
}
|
||||
|
||||
for i := range m.Headers {
|
||||
switch v := m.Headers[i].Value.(type) {
|
||||
|
@ -246,23 +260,23 @@ func (m *Object) CopyTo(o *Object) {
|
|||
},
|
||||
}
|
||||
case *Header_HomoHash:
|
||||
hash := proto.Clone(&v.HomoHash).(*Hash)
|
||||
o.Headers[i] = Header{
|
||||
Value: &Header_HomoHash{
|
||||
HomoHash: v.HomoHash,
|
||||
HomoHash: *hash,
|
||||
},
|
||||
}
|
||||
case *Header_Token:
|
||||
token := *v.Token
|
||||
o.Headers[i] = Header{
|
||||
Value: &Header_Token{
|
||||
Token: v.Token,
|
||||
Token: &token,
|
||||
},
|
||||
}
|
||||
default:
|
||||
o.Headers[i] = *proto.Clone(&m.Headers[i]).(*Header)
|
||||
}
|
||||
}
|
||||
|
||||
copy(o.Payload, m.Payload)
|
||||
}
|
||||
|
||||
// Address returns object's address.
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/nspcc-dev/neofs-api-go/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/service"
|
||||
"github.com/nspcc-dev/neofs-api-go/storagegroup"
|
||||
|
@ -17,7 +18,7 @@ Object:
|
|||
SystemHeader:
|
||||
- ID=7e0b9c6c-aabc-4985-949e-2680e577b48b
|
||||
- CID=11111111111111111111111111111111
|
||||
- OwnerID=ALYeYC41emF6MrmUMc4a8obEPdgFhq9ran
|
||||
- OwnerID=NQHKh7fKGieCPrPuiEkY58ucRFwWMyU1Mc
|
||||
- Version=1
|
||||
- PayloadLength=1
|
||||
- CreatedAt={UnixTime=1 Epoch=1}
|
||||
|
@ -33,7 +34,7 @@ Object:
|
|||
- Type=Tombstone
|
||||
Value=MARKED
|
||||
- Type=Token
|
||||
Value={ID=7e0b9c6c-aabc-4985-949e-2680e577b48b OwnerID=ALYeYC41emF6MrmUMc4a8obEPdgFhq9ran Verb=Search Address=11111111111111111111111111111111/7e0b9c6c-aabc-4985-949e-2680e577b48b Created=1 ValidUntil=2 SessionKey=010203040506 Signature=010203040506}
|
||||
Value={ID=7e0b9c6c-aabc-4985-949e-2680e577b48b OwnerID=NQHKh7fKGieCPrPuiEkY58ucRFwWMyU1Mc Verb=Search Address=11111111111111111111111111111111/7e0b9c6c-aabc-4985-949e-2680e577b48b Created=1 ValidUntil=2 SessionKey=010203040506 Signature=010203040506}
|
||||
- Type=HomoHash
|
||||
Value=1111111111111111111111111111111111111111111111111111111111111111
|
||||
- Type=PayloadChecksum
|
||||
|
@ -192,11 +193,23 @@ func TestObject_Copy(t *testing.T) {
|
|||
},
|
||||
})
|
||||
|
||||
cp := obj.Copy()
|
||||
{ // Copying
|
||||
cp := obj.Copy()
|
||||
|
||||
_, h := cp.LastHeader(HeaderType(TokenHdr))
|
||||
require.NotNil(t, h)
|
||||
require.Equal(t, token, h.GetValue().(*Header_Token).Token)
|
||||
_, h := cp.LastHeader(HeaderType(TokenHdr))
|
||||
require.NotNil(t, h)
|
||||
require.Equal(t, token, h.GetValue().(*Header_Token).Token)
|
||||
}
|
||||
|
||||
{ // Cloning
|
||||
cl := proto.Clone(obj).(*Object)
|
||||
require.Equal(t, obj, cl)
|
||||
|
||||
_, h := cl.LastHeader(HeaderType(TokenHdr))
|
||||
h.GetToken().SetID(service.TokenID{3, 2, 1})
|
||||
|
||||
require.NotEqual(t, token, h.GetToken())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/sha256"
|
||||
"strings"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/nspcc-dev/neofs-api-go/internal"
|
||||
)
|
||||
|
||||
|
@ -66,3 +67,14 @@ func (m Address) Hash() ([]byte, error) {
|
|||
h := sha256.Sum256(append(m.ObjectID.Bytes(), m.CID.Bytes()...))
|
||||
return h[:], nil
|
||||
}
|
||||
|
||||
// Merge used by proto.Clone
|
||||
func (m *Address) Merge(src proto.Message) {
|
||||
if addr, ok := src.(*Address); ok {
|
||||
cid := proto.Clone(&addr.CID).(*CID)
|
||||
oid := proto.Clone(&addr.ObjectID).(*ObjectID)
|
||||
|
||||
m.CID = *cid
|
||||
m.ObjectID = *oid
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/sha256"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -94,3 +95,10 @@ func (c CID) Verify(data []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Merge used by proto.Clone
|
||||
func (c *CID) Merge(src proto.Message) {
|
||||
if cid, ok := src.(*CID); ok {
|
||||
*c = *cid
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,23 +4,28 @@ import (
|
|||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neofs-api-go/chain"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// NewOwnerID returns generated OwnerID from passed public keys.
|
||||
func NewOwnerID(keys ...*ecdsa.PublicKey) (owner OwnerID, err error) {
|
||||
if len(keys) == 0 {
|
||||
// NewOwnerID returns generated OwnerID from passed public key.
|
||||
func NewOwnerID(key *ecdsa.PublicKey) (owner OwnerID, err error) {
|
||||
if key == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var d []byte
|
||||
d, err = base58.Decode(chain.KeysToAddress(keys...))
|
||||
|
||||
d, err = base58.Decode(chain.KeyToAddress(key))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
copy(owner[:], d)
|
||||
return owner, nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Size returns OwnerID size in bytes (OwnerIDSize).
|
||||
|
@ -63,3 +68,10 @@ func (o *OwnerID) Unmarshal(data []byte) error {
|
|||
copy((*o)[:], data)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Merge used by proto.Clone
|
||||
func (o *OwnerID) Merge(src proto.Message) {
|
||||
if uid, ok := src.(*OwnerID); ok {
|
||||
*o = *uid
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,19 @@ func TestSGID(t *testing.T) {
|
|||
require.NoError(t, sgid2.Unmarshal(data))
|
||||
require.Equal(t, sgid1, sgid2)
|
||||
})
|
||||
|
||||
t.Run("check that proto.Clone works like expected", func(t *testing.T) {
|
||||
var (
|
||||
sgid1 UUID
|
||||
sgid2 *UUID
|
||||
)
|
||||
|
||||
sgid1, err := NewSGID()
|
||||
require.NoError(t, err)
|
||||
|
||||
sgid2 = proto.Clone(&sgid1).(*SGID)
|
||||
require.Equal(t, sgid1, *sgid2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUUID(t *testing.T) {
|
||||
|
@ -66,7 +79,7 @@ func TestOwnerID(t *testing.T) {
|
|||
t.Run("check that marshal/unmarshal works like expected", func(t *testing.T) {
|
||||
var u1, u2 OwnerID
|
||||
|
||||
owner, err := NewOwnerID()
|
||||
owner, err := NewOwnerID(nil)
|
||||
require.NoError(t, err)
|
||||
require.True(t, owner.Empty())
|
||||
|
||||
|
@ -80,6 +93,18 @@ func TestOwnerID(t *testing.T) {
|
|||
require.NoError(t, u2.Unmarshal(data))
|
||||
require.Equal(t, u1, u2)
|
||||
})
|
||||
|
||||
t.Run("check that proto.Clone works like expected", func(t *testing.T) {
|
||||
var u2 *OwnerID
|
||||
|
||||
key := test.DecodeKey(0)
|
||||
|
||||
u1, err := NewOwnerID(&key.PublicKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
u2 = proto.Clone(&u1).(*OwnerID)
|
||||
require.Equal(t, u1, *u2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddress(t *testing.T) {
|
||||
|
@ -109,4 +134,8 @@ func TestAddress(t *testing.T) {
|
|||
actual, err := ParseAddress(expect)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expect, actual.String())
|
||||
|
||||
addr := proto.Clone(actual).(*Address)
|
||||
require.Equal(t, actual, addr)
|
||||
require.Equal(t, expect, addr.String())
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -74,3 +75,10 @@ func (u *UUID) Parse(id string) error {
|
|||
copy((*u)[:], tmp[:])
|
||||
return nil
|
||||
}
|
||||
|
||||
// Merge used by proto.Clone
|
||||
func (u *UUID) Merge(src proto.Message) {
|
||||
if tmp, ok := src.(*UUID); ok {
|
||||
*u = *tmp
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"io"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/nspcc-dev/neofs-api-go/internal"
|
||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||
)
|
||||
|
@ -109,6 +110,13 @@ func (t testCustomField) MarshalTo(data []byte) (int, error) { return 0, nil }
|
|||
// Marshal skip, it's for test usage only.
|
||||
func (t testCustomField) Marshal() ([]byte, error) { return nil, nil }
|
||||
|
||||
// Merge used by proto.Clone
|
||||
func (t *testCustomField) Merge(src proto.Message) {
|
||||
if tmp, ok := src.(*testCustomField); ok {
|
||||
*t = *tmp
|
||||
}
|
||||
}
|
||||
|
||||
// GetBearerToken wraps Bearer field and return BearerToken interface.
|
||||
//
|
||||
// If Bearer field value is nil, nil returns.
|
||||
|
|
Loading…
Reference in a new issue