This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 346
/
validators.go
136 lines (118 loc) · 3.34 KB
/
validators.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
package validator
import (
"math/big"
"github.com/hyperledger/burrow/crypto"
)
type Writer interface {
SetPower(id *crypto.PublicKey, power *big.Int) (flow *big.Int, err error)
}
type Reader interface {
Power(id crypto.Address) (*big.Int, error)
}
type Iterable interface {
IterateValidators(func(id crypto.Addressable, power *big.Int) error) error
}
type IterableReader interface {
Reader
Iterable
}
type ReaderWriter interface {
Reader
Writer
}
type IterableReaderWriter interface {
ReaderWriter
Iterable
}
type History interface {
ValidatorChanges(blocksAgo int) IterableReader
Validators(blocksAgo int) IterableReader
}
func AddPower(vs ReaderWriter, id *crypto.PublicKey, power *big.Int) error {
// Current power + power
currentPower, err := vs.Power(id.GetAddress())
if err != nil {
return err
}
_, err = vs.SetPower(id, new(big.Int).Add(currentPower, power))
return err
}
func SubtractPower(vs ReaderWriter, id *crypto.PublicKey, power *big.Int) error {
currentPower, err := vs.Power(id.GetAddress())
if err != nil {
return err
}
_, err = vs.SetPower(id, new(big.Int).Sub(currentPower, power))
return err
}
// Returns the asymmetric difference, diff, between two Sets such that applying diff to before results in after
func Diff(before, after IterableReader) (*Set, error) {
diff := NewSet()
err := after.IterateValidators(func(id crypto.Addressable, powerAfter *big.Int) error {
powerBefore, err := before.Power(id.GetAddress())
if err != nil {
return err
}
// Exclude any powers from before that much after
if powerBefore.Cmp(powerAfter) != 0 {
diff.ChangePower(id.GetPublicKey(), powerAfter)
}
return nil
})
if err != nil {
return nil, err
}
// Make sure to zero any validators in before but not in after
err = before.IterateValidators(func(id crypto.Addressable, powerBefore *big.Int) error {
powerAfter, err := after.Power(id.GetAddress())
if err != nil {
return err
}
// If there is a difference value then add to diff
if powerAfter.Cmp(powerBefore) != 0 {
diff.ChangePower(id.GetPublicKey(), powerAfter)
}
return nil
})
if err != nil {
return nil, err
}
return diff, nil
}
func Write(vs Writer, vsOther Iterable) error {
return vsOther.IterateValidators(func(id crypto.Addressable, power *big.Int) error {
_, err := vs.SetPower(id.GetPublicKey(), power)
return err
})
}
// Adds vsOther to vs
func Add(vs ReaderWriter, vsOther Iterable) error {
return vsOther.IterateValidators(func(id crypto.Addressable, power *big.Int) error {
return AddPower(vs, id.GetPublicKey(), power)
})
}
// Subtracts vsOther from vs
func Subtract(vs ReaderWriter, vsOther Iterable) error {
return vsOther.IterateValidators(func(id crypto.Addressable, power *big.Int) error {
return SubtractPower(vs, id.GetPublicKey(), power)
})
}
func copySet(trim bool, vss []Iterable) *Set {
vsCopy := newSet()
vsCopy.trim = trim
for _, vs := range vss {
vs.IterateValidators(func(id crypto.Addressable, power *big.Int) error {
vsCopy.ChangePower(id.GetPublicKey(), power)
return nil
})
}
return vsCopy
}
// Copy each of iterable in vss into a new Set - note any iterations errors thrown by the iterable itself will be swallowed
// Use Write instead if source iterables may error
func Copy(vss ...Iterable) *Set {
return copySet(false, vss)
}
func CopyTrim(vss ...Iterable) *Set {
return copySet(true, vss)
}