diff --git a/pkg/audit/result.go b/pkg/audit/result.go new file mode 100644 index 00000000..c5af81ad --- /dev/null +++ b/pkg/audit/result.go @@ -0,0 +1,258 @@ +package audit + +import ( + "github.com/nspcc-dev/neofs-api-go/pkg/container" + "github.com/nspcc-dev/neofs-api-go/pkg/object" + "github.com/nspcc-dev/neofs-api-go/v2/audit" + "github.com/nspcc-dev/neofs-api-go/v2/refs" +) + +// Result represents v2-compatible data audit result. +type Result audit.DataAuditResult + +// NewFromV2 wraps v2 DataAuditResult message to Result. +func NewResultFromV2(aV2 *audit.DataAuditResult) *Result { + return (*Result)(aV2) +} + +// New creates and initializes blank Result. +func NewResult() *Result { + return NewResultFromV2(new(audit.DataAuditResult)) +} + +// ToV2 converts Result to v2 DataAuditResult message. +func (r *Result) ToV2() *audit.DataAuditResult { + return (*audit.DataAuditResult)(r) +} + +// Marshal marshals Result into a protobuf binary form. +// +// Buffer is allocated when the argument is empty. +// Otherwise, the first buffer is used. +func (r *Result) Marshal(b ...[]byte) ([]byte, error) { + var buf []byte + if len(b) > 0 { + buf = b[0] + } + + return (*audit.DataAuditResult)(r). + StableMarshal(buf) +} + +// Unmarshal unmarshals protobuf binary representation of Result. +func (r *Result) Unmarshal(data []byte) error { + return (*audit.DataAuditResult)(r). + Unmarshal(data) +} + +// MarshalJSON encodes Result to protobuf JSON format. +func (r *Result) MarshalJSON() ([]byte, error) { + return (*audit.DataAuditResult)(r). + MarshalJSON() +} + +// UnmarshalJSON decodes Result from protobuf JSON format. +func (r *Result) UnmarshalJSON(data []byte) error { + return (*audit.DataAuditResult)(r). + UnmarshalJSON(data) +} + +// AuditEpoch returns epoch number when the Data Audit was conducted. +func (r *Result) AuditEpoch() uint64 { + return (*audit.DataAuditResult)(r). + GetAuditEpoch() +} + +// SetAuditEpoch sets epoch number when the Data Audit was conducted. +func (r *Result) SetAuditEpoch(epoch uint64) { + (*audit.DataAuditResult)(r). + SetAuditEpoch(epoch) +} + +// ContainerID returns container under audit. +func (r *Result) ContainerID() *container.ID { + return container.NewIDFromV2( + (*audit.DataAuditResult)(r). + GetContainerID(), + ) +} + +// SetContainerID sets container under audit. +func (r *Result) SetContainerID(id *container.ID) { + (*audit.DataAuditResult)(r). + SetContainerID(id.ToV2()) +} + +// PublicKey returns public key of the auditing InnerRing node in a binary format. +func (r *Result) PublicKey() []byte { + return (*audit.DataAuditResult)(r). + GetPublicKey() +} + +// SetPublicKey sets public key of the auditing InnerRing node in a binary format. +func (r *Result) SetPublicKey(key []byte) { + (*audit.DataAuditResult)(r). + SetPublicKey(key) +} + +// PassSG returns list of Storage Groups that passed audit PoR stage. +func (r *Result) PassSG() []*object.ID { + mV2 := (*audit.DataAuditResult)(r). + GetPassSG() + + if mV2 == nil { + return nil + } + + m := make([]*object.ID, len(mV2)) + + for i := range mV2 { + m[i] = object.NewIDFromV2(mV2[i]) + } + + return m +} + +// SetPassSG sets list of Storage Groups that passed audit PoR stage. +func (r *Result) SetPassSG(list []*object.ID) { + mV2 := (*audit.DataAuditResult)(r). + GetPassSG() + + if list == nil { + mV2 = nil + } else { + ln := len(list) + + if cap(mV2) >= ln { + mV2 = mV2[:0] + } else { + mV2 = make([]*refs.ObjectID, 0, ln) + } + + for i := 0; i < ln; i++ { + mV2 = append(mV2, list[i].ToV2()) + } + } + + (*audit.DataAuditResult)(r). + SetPassSG(mV2) +} + +// FailSG returns list of Storage Groups that failed audit PoR stage. +func (r *Result) FailSG() []*object.ID { + mV2 := (*audit.DataAuditResult)(r). + GetFailSG() + + if mV2 == nil { + return nil + } + + m := make([]*object.ID, len(mV2)) + + for i := range mV2 { + m[i] = object.NewIDFromV2(mV2[i]) + } + + return m +} + +// SetFailSG sets list of Storage Groups that failed audit PoR stage. +func (r *Result) SetFailSG(list []*object.ID) { + mV2 := (*audit.DataAuditResult)(r). + GetFailSG() + + if list == nil { + mV2 = nil + } else { + ln := len(list) + + if cap(mV2) >= ln { + mV2 = mV2[:0] + } else { + mV2 = make([]*refs.ObjectID, 0, ln) + } + + for i := 0; i < ln; i++ { + mV2 = append(mV2, list[i].ToV2()) + } + } + + (*audit.DataAuditResult)(r). + SetFailSG(mV2) +} + +// Hit returns number of sampled objects under audit placed +// in an optimal way according to the containers placement policy +// when checking PoP. +func (r *Result) Hit() uint32 { + return (*audit.DataAuditResult)(r). + GetHit() +} + +// SetHit sets number of sampled objects under audit placed +// in an optimal way according to the containers placement policy +// when checking PoP. +func (r *Result) SetHit(hit uint32) { + (*audit.DataAuditResult)(r). + SetHit(hit) +} + +// Miss returns number of sampled objects under audit placed +// in suboptimal way according to the containers placement policy, +// but still at a satisfactory level when checking PoP. +func (r *Result) Miss() uint32 { + return (*audit.DataAuditResult)(r). + GetMiss() +} + +// SetMiss sets number of sampled objects under audit placed +// in suboptimal way according to the containers placement policy, +// but still at a satisfactory level when checking PoP. +func (r *Result) SetMiss(miss uint32) { + (*audit.DataAuditResult)(r). + SetMiss(miss) +} + +// Fail returns number of sampled objects under audit stored +// in a way not confirming placement policy or not found at all +// when checking PoP. +func (r *Result) Fail() uint32 { + return (*audit.DataAuditResult)(r). + GetFail() +} + +// SetFail sets number of sampled objects under audit stored +// in a way not confirming placement policy or not found at all +// when checking PoP. +func (r *Result) SetFail(fail uint32) { + (*audit.DataAuditResult)(r). + SetFail(fail) +} + +// PassNodes returns list of storage node public keys that +// passed at least one PDP. +func (r *Result) PassNodes() [][]byte { + return (*audit.DataAuditResult)(r). + GetPassNodes() +} + +// SetPassNodes sets list of storage node public keys that +// passed at least one PDP. +func (r *Result) SetPassNodes(list [][]byte) { + (*audit.DataAuditResult)(r). + SetPassNodes(list) +} + +// FailNodes returns list of storage node public keys that +// failed at least one PDP. +func (r *Result) FailNodes() [][]byte { + return (*audit.DataAuditResult)(r). + GetFailNodes() +} + +// SetFailNodes sets list of storage node public keys that +// failed at least one PDP. +func (r *Result) SetFailNodes(list [][]byte) { + (*audit.DataAuditResult)(r). + SetFailNodes(list) +} diff --git a/pkg/audit/result_test.go b/pkg/audit/result_test.go new file mode 100644 index 00000000..8f860376 --- /dev/null +++ b/pkg/audit/result_test.go @@ -0,0 +1,109 @@ +package audit_test + +import ( + "crypto/rand" + "crypto/sha256" + "testing" + + "github.com/nspcc-dev/neofs-api-go/pkg/audit" + "github.com/nspcc-dev/neofs-api-go/pkg/container" + "github.com/nspcc-dev/neofs-api-go/pkg/object" + "github.com/stretchr/testify/require" +) + +func testSHA256() (cs [sha256.Size]byte) { + _, _ = rand.Read(cs[:]) + return +} + +func testCID() *container.ID { + cid := container.NewID() + cid.SetSHA256(testSHA256()) + + return cid +} + +func testOID() *object.ID { + id := object.NewID() + id.SetSHA256(testSHA256()) + + return id +} + +func TestResult(t *testing.T) { + r := audit.NewResult() + + epoch := uint64(13) + r.SetAuditEpoch(epoch) + require.Equal(t, epoch, r.AuditEpoch()) + + cid := testCID() + r.SetContainerID(cid) + require.Equal(t, cid, r.ContainerID()) + + key := []byte{1, 2, 3} + r.SetPublicKey(key) + require.Equal(t, key, r.PublicKey()) + + passSG := []*object.ID{testOID(), testOID()} + r.SetPassSG(passSG) + require.Equal(t, passSG, r.PassSG()) + + failSG := []*object.ID{testOID(), testOID()} + r.SetFailSG(failSG) + require.Equal(t, failSG, r.FailSG()) + + hit := uint32(1) + r.SetHit(hit) + require.Equal(t, hit, r.Hit()) + + miss := uint32(2) + r.SetMiss(miss) + require.Equal(t, miss, r.Miss()) + + fail := uint32(3) + r.SetFail(fail) + require.Equal(t, fail, r.Fail()) + + passNodes := [][]byte{{1}, {2}} + r.SetPassNodes(passNodes) + require.Equal(t, passNodes, r.PassNodes()) + + failNodes := [][]byte{{3}, {4}} + r.SetFailNodes(failNodes) + require.Equal(t, failNodes, r.FailNodes()) +} + +func TestStorageGroupEncoding(t *testing.T) { + r := audit.NewResult() + r.SetAuditEpoch(13) + r.SetContainerID(testCID()) + r.SetPublicKey([]byte{1, 2, 3}) + r.SetPassSG([]*object.ID{testOID(), testOID()}) + r.SetFailSG([]*object.ID{testOID(), testOID()}) + r.SetHit(1) + r.SetMiss(2) + r.SetFail(3) + r.SetPassNodes([][]byte{{1}, {2}}) + r.SetFailNodes([][]byte{{3}, {4}}) + + t.Run("binary", func(t *testing.T) { + data, err := r.Marshal() + require.NoError(t, err) + + r2 := audit.NewResult() + require.NoError(t, r2.Unmarshal(data)) + + require.Equal(t, r, r2) + }) + + t.Run("json", func(t *testing.T) { + data, err := r.MarshalJSON() + require.NoError(t, err) + + r2 := audit.NewResult() + require.NoError(t, r2.UnmarshalJSON(data)) + + require.Equal(t, r, r2) + }) +} diff --git a/v2/audit/convert.go b/v2/audit/convert.go new file mode 100644 index 00000000..40dcd3b6 --- /dev/null +++ b/v2/audit/convert.go @@ -0,0 +1,76 @@ +package audit + +import ( + audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/refs" +) + +// DataAuditResultToGRPCMessage converts unified DataAuditResult structure +// into gRPC DataAuditResult message. +func DataAuditResultToGRPCMessage(a *DataAuditResult) *audit.DataAuditResult { + if a == nil { + return nil + } + + m := new(audit.DataAuditResult) + + m.SetAuditEpoch(a.GetAuditEpoch()) + + m.SetContainerId( + refs.ContainerIDToGRPCMessage(a.GetContainerID()), + ) + + m.SetPublicKey(a.GetPublicKey()) + + m.SetPassSg( + refs.ObjectIDListToGRPCMessage(a.GetPassSG()), + ) + + m.SetFailSg( + refs.ObjectIDListToGRPCMessage(a.GetFailSG()), + ) + + m.SetHit(a.GetHit()) + m.SetMiss(a.GetMiss()) + m.SetFail(a.GetFail()) + + m.SetPassNodes(a.GetPassNodes()) + m.SetFailNodes(a.GetFailNodes()) + + return m +} + +// DataAuditResultFromGRPCMessage converts gRPC message DataAuditResult +// into unified DataAuditResult structure. +func DataAuditResultFromGRPCMessage(m *audit.DataAuditResult) *DataAuditResult { + if m == nil { + return nil + } + + a := new(DataAuditResult) + + a.SetAuditEpoch(m.GetAuditEpoch()) + + a.SetContainerID( + refs.ContainerIDFromGRPCMessage(m.GetContainerId()), + ) + + a.SetPublicKey(m.GetPublicKey()) + + a.SetPassSG( + refs.ObjectIDListFromGRPCMessage(m.GetPassSg()), + ) + + a.SetFailSG( + refs.ObjectIDListFromGRPCMessage(m.GetFailSg()), + ) + + a.SetHit(m.GetHit()) + a.SetMiss(m.GetMiss()) + a.SetFail(m.GetFail()) + + a.SetPassNodes(m.GetPassNodes()) + a.SetFailNodes(m.GetFailNodes()) + + return a +} diff --git a/v2/audit/grpc/types.go b/v2/audit/grpc/types.go new file mode 100644 index 00000000..7390d89f --- /dev/null +++ b/v2/audit/grpc/types.go @@ -0,0 +1,75 @@ +package audit + +import ( + refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" +) + +// SetAuditEpoch is an AuditEpoch field setter. +func (x *DataAuditResult) SetAuditEpoch(v uint64) { + if x != nil { + x.AuditEpoch = v + } +} + +// SetContainerId is a ContainerId field setter. +func (x *DataAuditResult) SetContainerId(v *refs.ContainerID) { + if x != nil { + x.ContainerId = v + } +} + +// SetPublicKey is a PublicKey field setter. +func (x *DataAuditResult) SetPublicKey(v []byte) { + if x != nil { + x.PublicKey = v + } +} + +// SetPassSg is a PassSg field setter. +func (x *DataAuditResult) SetPassSg(v []*refs.ObjectID) { + if x != nil { + x.PassSg = v + } +} + +// SetFailSg is a FailSg field setter. +func (x *DataAuditResult) SetFailSg(v []*refs.ObjectID) { + if x != nil { + x.FailSg = v + } +} + +// SetHit is a Hit field setter. +func (x *DataAuditResult) SetHit(v uint32) { + if x != nil { + x.Hit = v + } +} + +// SetMiss is a Miss field setter. +func (x *DataAuditResult) SetMiss(v uint32) { + if x != nil { + x.Miss = v + } +} + +// SetFail is a Fail field setter. +func (x *DataAuditResult) SetFail(v uint32) { + if x != nil { + x.Fail = v + } +} + +// SetPassNodes is a PassNodes field setter. +func (x *DataAuditResult) SetPassNodes(v [][]byte) { + if x != nil { + x.PassNodes = v + } +} + +// SetFailNodes is a FailNodes field setter. +func (x *DataAuditResult) SetFailNodes(v [][]byte) { + if x != nil { + x.FailNodes = v + } +} diff --git a/v2/audit/json.go b/v2/audit/json.go new file mode 100644 index 00000000..80cb33ac --- /dev/null +++ b/v2/audit/json.go @@ -0,0 +1,26 @@ +package audit + +import ( + audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" + "google.golang.org/protobuf/encoding/protojson" +) + +func (a *DataAuditResult) MarshalJSON() ([]byte, error) { + return protojson.MarshalOptions{ + EmitUnpopulated: true, + }.Marshal( + DataAuditResultToGRPCMessage(a), + ) +} + +func (a *DataAuditResult) UnmarshalJSON(data []byte) error { + msg := new(audit.DataAuditResult) + + if err := protojson.Unmarshal(data, msg); err != nil { + return err + } + + *a = *DataAuditResultFromGRPCMessage(msg) + + return nil +} diff --git a/v2/audit/json_test.go b/v2/audit/json_test.go new file mode 100644 index 00000000..f1cae450 --- /dev/null +++ b/v2/audit/json_test.go @@ -0,0 +1,20 @@ +package audit_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-api-go/v2/audit" + "github.com/stretchr/testify/require" +) + +func TestDataAuditResultJSON(t *testing.T) { + a := generateDataAuditResult() + + data, err := a.MarshalJSON() + require.NoError(t, err) + + a2 := new(audit.DataAuditResult) + require.NoError(t, a2.UnmarshalJSON(data)) + + require.Equal(t, a, a2) +} diff --git a/v2/audit/marshal.go b/v2/audit/marshal.go new file mode 100644 index 00000000..c0174c7a --- /dev/null +++ b/v2/audit/marshal.go @@ -0,0 +1,143 @@ +package audit + +import ( + "github.com/nspcc-dev/neofs-api-go/util/proto" + audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" + "github.com/nspcc-dev/neofs-api-go/v2/refs" + goproto "google.golang.org/protobuf/proto" +) + +const ( + _ = iota + auditEpochFNum + cidFNum + pubKeyFNum + passSGFNum + failSGFNum + hitFNum + missFNum + failFNum + passNodesFNum + failNodesFNum +) + +// StableMarshal marshals unified DataAuditResult structure into a protobuf +// binary format without field order shuffle. +func (a *DataAuditResult) StableMarshal(buf []byte) ([]byte, error) { + if a == nil { + return []byte{}, nil + } + + if buf == nil { + buf = make([]byte, a.StableSize()) + } + + var ( + offset, n int + err error + ) + + n, err = proto.Fixed64Marshal(auditEpochFNum, buf[offset:], a.auditEpoch) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.NestedStructureMarshal(cidFNum, buf[offset:], a.cid) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.BytesMarshal(pubKeyFNum, buf[offset:], a.pubKey) + if err != nil { + return nil, err + } + + offset += n + + n, err = refs.ObjectIDNestedListMarshal(passSGFNum, buf[offset:], a.passSG) + if err != nil { + return nil, err + } + + offset += n + + n, err = refs.ObjectIDNestedListMarshal(failSGFNum, buf[offset:], a.failSG) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.UInt32Marshal(hitFNum, buf[offset:], a.hit) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.UInt32Marshal(missFNum, buf[offset:], a.miss) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.UInt32Marshal(failFNum, buf[offset:], a.fail) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.RepeatedBytesMarshal(passNodesFNum, buf[offset:], a.passNodes) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.RepeatedBytesMarshal(failNodesFNum, buf[offset:], a.failNodes) + if err != nil { + return nil, err + } + + return buf, nil +} + +// StableSize returns byte length of DataAuditResult structure +// marshaled by StableMarshal function. +func (a *DataAuditResult) StableSize() (size int) { + if a == nil { + return 0 + } + + size += proto.Fixed64Size(auditEpochFNum, a.auditEpoch) + size += proto.NestedStructureSize(cidFNum, a.cid) + size += proto.BytesSize(pubKeyFNum, a.pubKey) + size += refs.ObjectIDNestedListSize(passSGFNum, a.passSG) + size += refs.ObjectIDNestedListSize(failSGFNum, a.failSG) + size += proto.UInt32Size(hitFNum, a.hit) + size += proto.UInt32Size(missFNum, a.miss) + size += proto.UInt32Size(failFNum, a.fail) + size += proto.RepeatedBytesSize(passNodesFNum, a.passNodes) + size += proto.RepeatedBytesSize(failNodesFNum, a.failNodes) + + return size +} + +// Unmarshal unmarshals DataAuditResult structure from its protobuf +// binary representation. +func (a *DataAuditResult) Unmarshal(data []byte) error { + m := new(audit.DataAuditResult) + if err := goproto.Unmarshal(data, m); err != nil { + return err + } + + *a = *DataAuditResultFromGRPCMessage(m) + + return nil +} diff --git a/v2/audit/marshal_test.go b/v2/audit/marshal_test.go new file mode 100644 index 00000000..bb80652e --- /dev/null +++ b/v2/audit/marshal_test.go @@ -0,0 +1,55 @@ +package audit_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-api-go/v2/audit" + "github.com/nspcc-dev/neofs-api-go/v2/refs" + "github.com/stretchr/testify/require" +) + +func TestDataAuditResult_StableMarshal(t *testing.T) { + from := generateDataAuditResult() + + t.Run("non empty", func(t *testing.T) { + wire, err := from.StableMarshal(nil) + require.NoError(t, err) + + to := new(audit.DataAuditResult) + require.NoError(t, to.Unmarshal(wire)) + + require.Equal(t, from, to) + }) +} + +func generateDataAuditResult() *audit.DataAuditResult { + a := new(audit.DataAuditResult) + + oid1 := new(refs.ObjectID) + oid1.SetValue([]byte("Object ID 1")) + + oid2 := new(refs.ObjectID) + oid2.SetValue([]byte("Object ID 2")) + + cid := new(refs.ContainerID) + cid.SetValue([]byte("Container ID")) + + a.SetAuditEpoch(13) + a.SetContainerID(cid) + a.SetPublicKey([]byte("Public key")) + a.SetPassSG([]*refs.ObjectID{oid1, oid2}) + a.SetFailSG([]*refs.ObjectID{oid2, oid1}) + a.SetHit(1) + a.SetMiss(2) + a.SetFail(3) + a.SetPassNodes([][]byte{ + {1, 2}, + {3, 4}, + }) + a.SetFailNodes([][]byte{ + {5, 6}, + {7, 8}, + }) + + return a +} diff --git a/v2/audit/types.go b/v2/audit/types.go new file mode 100644 index 00000000..97676e16 --- /dev/null +++ b/v2/audit/types.go @@ -0,0 +1,197 @@ +package audit + +import ( + "github.com/nspcc-dev/neofs-api-go/v2/refs" +) + +// DataAuditResult is a unified structure of +// DataAuditResult message from proto definition. +type DataAuditResult struct { + auditEpoch uint64 + + hit, miss, fail uint32 + + cid *refs.ContainerID + + pubKey []byte + + passSG, failSG []*refs.ObjectID + + failNodes, passNodes [][]byte +} + +// GetAuditEpoch returns epoch number when the Data Audit was conducted. +func (a *DataAuditResult) GetAuditEpoch() uint64 { + if a != nil { + return a.auditEpoch + } + + return 0 +} + +// SetAuditEpoch sets epoch number when the Data Audit was conducted. +func (a *DataAuditResult) SetAuditEpoch(v uint64) { + if a != nil { + a.auditEpoch = v + } +} + +// GetContainerID returns container under audit. +func (a *DataAuditResult) GetContainerID() *refs.ContainerID { + if a != nil { + return a.cid + } + + return nil +} + +// SetContainerID sets container under audit. +func (a *DataAuditResult) SetContainerID(v *refs.ContainerID) { + if a != nil { + a.cid = v + } +} + +// GetPublicKey returns public key of the auditing InnerRing node in a binary format. +func (a *DataAuditResult) GetPublicKey() []byte { + if a != nil { + return a.pubKey + } + + return nil +} + +// SetPublicKey sets public key of the auditing InnerRing node in a binary format. +func (a *DataAuditResult) SetPublicKey(v []byte) { + if a != nil { + a.pubKey = v + } +} + +// GetPassSG returns list of Storage Groups that passed audit PoR stage. +func (a *DataAuditResult) GetPassSG() []*refs.ObjectID { + if a != nil { + return a.passSG + } + + return nil +} + +// SetPassSG sets list of Storage Groups that passed audit PoR stage. +func (a *DataAuditResult) SetPassSG(v []*refs.ObjectID) { + if a != nil { + a.passSG = v + } +} + +// GetFailSG returns list of Storage Groups that failed audit PoR stage. +func (a *DataAuditResult) GetFailSG() []*refs.ObjectID { + if a != nil { + return a.failSG + } + + return nil +} + +// SetFailSG sets list of Storage Groups that failed audit PoR stage. +func (a *DataAuditResult) SetFailSG(v []*refs.ObjectID) { + if a != nil { + a.failSG = v + } +} + +// GetHit returns number of sampled objects under audit placed +// in an optimal way according to the containers placement policy +// when checking PoP. +func (a *DataAuditResult) GetHit() uint32 { + if a != nil { + return a.hit + } + + return 0 +} + +// SetHit sets number of sampled objects under audit placed +// in an optimal way according to the containers placement policy +// when checking PoP. +func (a *DataAuditResult) SetHit(v uint32) { + if a != nil { + a.hit = v + } +} + +// GetMiss returns number of sampled objects under audit placed +// in suboptimal way according to the containers placement policy, +// but still at a satisfactory level when checking PoP. +func (a *DataAuditResult) GetMiss() uint32 { + if a != nil { + return a.miss + } + + return 0 +} + +// SetMiss sets number of sampled objects under audit placed +// in suboptimal way according to the containers placement policy, +// but still at a satisfactory level when checking PoP. +func (a *DataAuditResult) SetMiss(v uint32) { + if a != nil { + a.miss = v + } +} + +// GetFail returns number of sampled objects under audit stored +// in a way not confirming placement policy or not found at all +// when checking PoP. +func (a *DataAuditResult) GetFail() uint32 { + if a != nil { + return a.fail + } + + return 0 +} + +// SetFail sets number of sampled objects under audit stored +// in a way not confirming placement policy or not found at all +// when checking PoP. +func (a *DataAuditResult) SetFail(v uint32) { + if a != nil { + a.fail = v + } +} + +// GetPassNodes returns list of storage node public keys that +// passed at least one PDP. +func (a *DataAuditResult) GetPassNodes() [][]byte { + if a != nil { + return a.passNodes + } + + return nil +} + +// SetPassNodes sets list of storage node public keys that +// passed at least one PDP. +func (a *DataAuditResult) SetPassNodes(v [][]byte) { + if a != nil { + a.passNodes = v + } +} + +// GetFailNodes returns list of storage node public keys that +// failed at least one PDP. +func (a *DataAuditResult) GetFailNodes() [][]byte { + if a != nil { + return a.failNodes + } + + return nil +} + +// SetFailNodes sets list of storage node public keys that +// failed at least one PDP. +func (a *DataAuditResult) SetFailNodes(v [][]byte) { + if a != nil { + a.failNodes = v + } +}