forked from wealdtech/go-merkletree
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parameters.go
150 lines (128 loc) · 3.81 KB
/
parameters.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
// Copyright © 2023 Weald Technology Trading.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package merkletree
import (
"errors"
"github.com/debabky/go-merkletree/v2/blake2b"
)
type parameters struct {
data [][]byte
values uint64
hashes map[uint64][]byte
indices []uint64
salt bool
sorted bool
hash HashType
}
// Parameter is the interface for service parameters.
type Parameter interface {
apply(p *parameters)
}
type parameterFunc func(*parameters)
func (f parameterFunc) apply(p *parameters) {
f(p)
}
// WithData sets the data for the merkle tree.
func WithData(data [][]byte) Parameter {
return parameterFunc(func(p *parameters) {
p.data = data
})
}
// WithValues sets the values for the merkle proof.
func WithValues(values uint64) Parameter {
return parameterFunc(func(p *parameters) {
p.values = values
})
}
// WithHashes sets the indexed hashes of values that cannot be calculated from the proof.
func WithHashes(hashes map[uint64][]byte) Parameter {
return parameterFunc(func(p *parameters) {
p.hashes = hashes
})
}
// WithIndices sets the indices that can be calculated from the proof.
func WithIndices(indices []uint64) Parameter {
return parameterFunc(func(p *parameters) {
p.indices = indices
})
}
// WithSalt sets the salt for the merkle tree or proof.
func WithSalt(salt bool) Parameter {
return parameterFunc(func(p *parameters) {
p.salt = salt
})
}
// WithSorted sets the sorted for the merkle tree.
func WithSorted(sorted bool) Parameter {
return parameterFunc(func(p *parameters) {
p.sorted = sorted
})
}
// WithHashType sets the hash type for the merkle tree or proof.
func WithHashType(hash HashType) Parameter {
return parameterFunc(func(p *parameters) {
p.hash = hash
})
}
// parseAndCheckTreeParameters parses and checks parameters to ensure that mandatory parameters are present and correct.
func parseAndCheckTreeParameters(params ...Parameter) (*parameters, error) {
parameters := parameters{
hash: blake2b.New(),
}
for _, p := range params {
if params != nil {
p.apply(¶meters)
}
}
if parameters.hash == nil {
return nil, errors.New("no hash type specified")
}
if len(parameters.data) == 0 {
return nil, errors.New("tree must have at least 1 piece of data")
}
if parameters.values != 0 {
return nil, errors.New("merkle tree does not use the values parameter")
}
if len(parameters.hashes) != 0 {
return nil, errors.New("merkle tree does not use the hashes parameter")
}
if len(parameters.indices) != 0 {
return nil, errors.New("merkle tree does not use the indices parameter")
}
return ¶meters, nil
}
// parseAndCheckMultiProofParameters parses and checks parameters to ensure that mandatory parameters are present and correct.
func parseAndCheckMultiProofParameters(params ...Parameter) (*parameters, error) {
parameters := parameters{
hash: blake2b.New(),
}
for _, p := range params {
if params != nil {
p.apply(¶meters)
}
}
if parameters.hash == nil {
return nil, errors.New("no hash type specified")
}
if parameters.values == 0 {
return nil, errors.New("no values specified")
}
// Hashes can be empty.
if len(parameters.indices) == 0 {
return nil, errors.New("no indices specified")
}
if len(parameters.data) != 0 {
return nil, errors.New("proof does not use the data parameter")
}
return ¶meters, nil
}