1// Copyright (C) 2019 Storj Labs, Inc.
2// See LICENSE for copying information.
3
4package pb
5
6import (
7	"bytes"
8	"reflect"
9
10	"github.com/gogo/protobuf/proto"
11
12	"storj.io/common/storj"
13)
14
15// Equal compares two Protobuf messages via serialization.
16func Equal(msg1, msg2 proto.Message) bool {
17	// reflect.DeepEqual and proto.Equal don't seem work in all cases
18	// todo:  see how slow this is compared to custom equality checks
19	if msg1 == nil {
20		return msg2 == nil
21	}
22	if reflect.TypeOf(msg1) != reflect.TypeOf(msg2) {
23		return false
24	}
25	msg1Bytes, err := Marshal(msg1)
26	if err != nil {
27		return false
28	}
29	msg2Bytes, err := Marshal(msg2)
30	if err != nil {
31		return false
32	}
33	return bytes.Equal(msg1Bytes, msg2Bytes)
34}
35
36// NodesToIDs extracts Node-s into a list of ids.
37func NodesToIDs(nodes []*Node) storj.NodeIDList {
38	ids := make(storj.NodeIDList, len(nodes))
39	for i, node := range nodes {
40		if node != nil {
41			ids[i] = node.Id
42		}
43	}
44	return ids
45}
46
47// CopyNode returns a deep copy of a node
48// It would be better to use `proto.Clone` but it is curently incompatible
49// with gogo's customtype extension.
50// (see https://github.com/gogo/protobuf/issues/147).
51func CopyNode(src *Node) (dst *Node) {
52	node := Node{Id: storj.NodeID{}}
53	copy(node.Id[:], src.Id[:])
54
55	if src.Address != nil {
56		node.Address = &NodeAddress{
57			Transport: src.Address.Transport,
58			Address:   src.Address.Address,
59		}
60	}
61
62	return &node
63}
64
65// AddressEqual compares two node addresses.
66func AddressEqual(a1, a2 *NodeAddress) bool {
67	if a1 == nil && a2 == nil {
68		return true
69	}
70	if a1 == nil || a2 == nil {
71		return false
72	}
73	return a1.Transport == a2.Transport &&
74		a1.Address == a2.Address
75}
76
77// NewRedundancySchemeToStorj creates new storj.RedundancyScheme from the given
78// protobuf RedundancyScheme.
79func NewRedundancySchemeToStorj(scheme *RedundancyScheme) *storj.RedundancyScheme {
80	return &storj.RedundancyScheme{
81		Algorithm:      storj.RedundancyAlgorithm(scheme.GetType()),
82		ShareSize:      scheme.GetErasureShareSize(),
83		RequiredShares: int16(scheme.GetMinReq()),
84		RepairShares:   int16(scheme.GetRepairThreshold()),
85		OptimalShares:  int16(scheme.GetSuccessThreshold()),
86		TotalShares:    int16(scheme.GetTotal()),
87	}
88}
89