-
Notifications
You must be signed in to change notification settings - Fork 11
/
dash.go
152 lines (124 loc) · 3.57 KB
/
dash.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package types
import (
"bytes"
"errors"
fmt "fmt"
"github.com/dashpay/tenderdash/crypto"
"github.com/dashpay/tenderdash/crypto/bls12381"
)
// VoteExtensions is a container type for grouped vote extensions by type
type VoteExtensions []*VoteExtension
var (
errExtensionNil = errors.New("vote extension is nil")
errExtensionSignEmpty = errors.New("vote extension signature is missing")
errExtensionSignTooBig = fmt.Errorf("vote extension signature is too big (max: %d)", bls12381.SignatureSize)
errExtensionSignRequestIDNotSupported = errors.New("vote extension sign request id is not supported")
errExtensionSignRequestIDWrongPrefix = errors.New("vote extension sign request id must have dpevote or \\x06plwdtx prefix")
)
// Clone returns a shallow copy of current vote-extension
//
// Clone of nil will panic
func (v *VoteExtension) Clone() VoteExtension {
if v == nil {
panic("cannot clone nil vote-extension")
}
ve := VoteExtension{
Type: v.Type,
Extension: v.Extension,
Signature: v.Signature,
}
if v.XSignRequestId != nil && v.XSignRequestId.Size() > 0 {
ve.XSignRequestId = &VoteExtension_SignRequestId{
SignRequestId: v.GetSignRequestId(),
}
}
return ve
}
// Copy returns a deep copy of current vote-extension.
func (v *VoteExtension) Copy() VoteExtension {
if v == nil {
panic("cannot copy nil vote-extension")
}
ve := VoteExtension{
Type: v.Type,
Extension: bytes.Clone(v.Extension),
Signature: bytes.Clone(v.Signature),
}
if v.XSignRequestId != nil && v.XSignRequestId.Size() > 0 {
ve.XSignRequestId = &VoteExtension_SignRequestId{
SignRequestId: bytes.Clone(v.GetSignRequestId()),
}
}
return ve
}
func (v *VoteExtension) Equal(other *VoteExtension) bool {
if v == nil || other == nil {
return false
}
if v.Type != other.Type {
return false
}
if !bytes.Equal(v.Extension, other.Extension) {
return false
}
if !bytes.Equal(v.Signature, other.Signature) {
return false
}
// one of them is nil, but not both
if (v.XSignRequestId != nil) != (other.XSignRequestId != nil) {
return false
}
if v.XSignRequestId != nil && other.XSignRequestId != nil {
if !bytes.Equal(v.GetSignRequestId(), other.GetSignRequestId()) {
return false
}
}
return true
}
// Validate checks the validity of the vote-extension
func (v *VoteExtension) Validate() error {
if v == nil {
return errExtensionNil
}
if v.Type == VoteExtensionType_DEFAULT {
return fmt.Errorf("vote extension type %s is not supported", v.Type.String())
}
if v.Type == VoteExtensionType_THRESHOLD_RECOVER_RAW {
if len(v.Extension) != crypto.HashSize {
return fmt.Errorf("invalid %s vote extension size: got %d, expected %d",
v.Type.String(), len(v.Extension), crypto.HashSize)
}
}
if len(v.Extension) > 0 && len(v.Signature) == 0 {
return errExtensionSignEmpty
}
if len(v.Signature) > bls12381.SignatureSize {
return errExtensionSignTooBig
}
if v.XSignRequestId != nil && v.XSignRequestId.Size() > 0 {
if v.Type != VoteExtensionType_THRESHOLD_RECOVER_RAW {
return errExtensionSignRequestIDNotSupported
}
var validPrefixes = []string{"\x06plwdtx", "dpevote"}
requestID := v.GetSignRequestId()
var validPrefix bool
for _, prefix := range validPrefixes {
if bytes.HasPrefix(requestID, []byte(prefix)) {
validPrefix = true
break
}
}
if !validPrefix {
return errExtensionSignRequestIDWrongPrefix
}
}
return nil
}
func (v VoteExtensions) Contains(other VoteExtension) bool {
for _, ext := range v {
if ext.Equal(&other) {
return true
}
}
return false
}