Skip to content

Commit c765903

Browse files
authored
Removed hard-coded constant in sortition.go. (#3558)
## Summary Remove a hardcoded constant in sortition.go which was used as the denominator in determining the selection ratio. This clarifies what the maximum possible output size is of the output VRF based on the SHA algorithm used to generate it. ## Purpose This is simply a code quality change to make it easier to read and understand without any focus on new functionality or performance. It is unlikely that the VRF SHA length used by Algorand will changed, so the generalization to a dynamic length based on the length of the Crypto digest is only for the reader. The use of an `init` function to initialize the `maxFloat` once rather than anytime `sortition` runs is a minor optimization, but likely to be neglibile in the grand scheme of things. ## Test Plan Due to the usage of C src code, a simple `go test -v ./data/committee/sortition/` cannot be executed without the proper configurations. However, circle CI should be able to execute the unit tests automatically and verify the changes. Recommendation: Running the recommended make targets to test the changes did not automatically due to missing dependencies, so potentially a Dockerfile could help resolve this for future contributors.
1 parent f0b85f6 commit c765903

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

data/committee/sortition/sortition.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,19 @@ package sortition
2222
// #include <stdlib.h>
2323
// #include "sortition.h"
2424
import "C"
25+
2526
import (
27+
"fmt"
2628
"math/big"
29+
"strings"
2730

2831
"github.com/algorand/go-algorand/crypto"
2932
)
3033

34+
const precision = uint(8 * (crypto.DigestSize + 1))
35+
36+
var maxFloat *big.Float
37+
3138
// Select runs the sortition function and returns the number of time the key was selected
3239
func Select(money uint64, totalMoney uint64, expectedSize float64, vrfOutput crypto.Digest) uint64 {
3340
binomialN := float64(money)
@@ -36,18 +43,23 @@ func Select(money uint64, totalMoney uint64, expectedSize float64, vrfOutput cry
3643
t := &big.Int{}
3744
t.SetBytes(vrfOutput[:])
3845

39-
precision := uint(8 * (len(vrfOutput) + 1))
40-
max, b, err := big.ParseFloat("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0, precision, big.ToNearestEven)
41-
if b != 16 || err != nil {
42-
panic("failed to parse big float constant in sortition")
43-
}
44-
4546
h := big.Float{}
4647
h.SetPrec(precision)
4748
h.SetInt(t)
4849

4950
ratio := big.Float{}
50-
cratio, _ := ratio.Quo(&h, max).Float64()
51+
cratio, _ := ratio.Quo(&h, maxFloat).Float64()
5152

5253
return uint64(C.sortition_binomial_cdf_walk(C.double(binomialN), C.double(binomialP), C.double(cratio), C.uint64_t(money)))
5354
}
55+
56+
func init() {
57+
var b int
58+
var err error
59+
maxFloatString := fmt.Sprintf("0x%s", strings.Repeat("ff", crypto.DigestSize))
60+
maxFloat, b, err = big.ParseFloat(maxFloatString, 0, precision, big.ToNearestEven)
61+
if b != 16 || err != nil {
62+
err = fmt.Errorf("failed to parse big float constant in sortition : %w", err)
63+
panic(err)
64+
}
65+
}

0 commit comments

Comments
 (0)