Update to math/rand/v2 (#7657)
Replace all of Boulder's usage of the Go stdlib "math/rand" package with the newer "math/rand/v2" package which first became available in go1.22. This package has an improved API and faster performance across the board. See https://go.dev/blog/randv2 and https://go.dev/blog/chacha8rand for details.
This commit is contained in:
parent
8380bb9b92
commit
61b484c13b
|
@ -4,15 +4,16 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/miekg/dns"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
)
|
||||
|
||||
// ServerProvider represents a type which can provide a list of addresses for
|
||||
|
@ -306,7 +307,7 @@ func (dp *dynamicProvider) Addrs() ([]string, error) {
|
|||
var r []string
|
||||
dp.mu.RLock()
|
||||
for ip, ports := range dp.addrs {
|
||||
port := fmt.Sprint(ports[rand.Intn(len(ports))])
|
||||
port := fmt.Sprint(ports[rand.IntN(len(ports))])
|
||||
addr := net.JoinHostPort(ip, port)
|
||||
r = append(r, addr)
|
||||
}
|
||||
|
|
4
ca/ca.go
4
ca/ca.go
|
@ -14,7 +14,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
mrand "math/rand"
|
||||
mrand "math/rand/v2"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -535,7 +535,7 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
|
|||
if !ok || len(issuerPool) == 0 {
|
||||
return nil, nil, berrors.InternalServerError("no issuers found for public key algorithm %s", csr.PublicKeyAlgorithm)
|
||||
}
|
||||
issuer := issuerPool[mrand.Intn(len(issuerPool))]
|
||||
issuer := issuerPool[mrand.IntN(len(issuerPool))]
|
||||
|
||||
if issuer.Cert.NotAfter.Before(notAfter) {
|
||||
err = berrors.InternalServerError("cannot issue a certificate that expires after the issuer certificate")
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
"errors"
|
||||
"log"
|
||||
"math/big"
|
||||
mrand "math/rand"
|
||||
mrand "math/rand/v2"
|
||||
"os"
|
||||
"slices"
|
||||
"sort"
|
||||
|
@ -355,7 +355,7 @@ func TestGetAndProcessCerts(t *testing.T) {
|
|||
reg := satest.CreateWorkingRegistration(t, isa.SA{Impl: sa})
|
||||
test.AssertNotError(t, err, "Couldn't create registration")
|
||||
for range 5 {
|
||||
rawCert.SerialNumber = big.NewInt(mrand.Int63())
|
||||
rawCert.SerialNumber = big.NewInt(mrand.Int64())
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, &rawCert, &rawCert, &testKey.PublicKey, testKey)
|
||||
test.AssertNotError(t, err, "Couldn't create certificate")
|
||||
_, err = sa.AddCertificate(context.Background(), &sapb.AddCertificateRequest{
|
||||
|
|
|
@ -3,7 +3,7 @@ package notmain
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
@ -104,9 +104,9 @@ func (cl *client) loadFromDB(ctx context.Context, speed ProcessingSpeed, startFr
|
|||
if result.err != nil {
|
||||
errorCount++
|
||||
if errorCount < 10 ||
|
||||
(errorCount < 1000 && rand.Intn(1000) < 100) ||
|
||||
(errorCount < 100000 && rand.Intn(1000) < 10) ||
|
||||
(rand.Intn(1000) < 1) {
|
||||
(errorCount < 1000 && rand.IntN(1000) < 100) ||
|
||||
(errorCount < 100000 && rand.IntN(1000) < 10) ||
|
||||
(rand.IntN(1000) < 1) {
|
||||
cl.logger.Errf("error: %s", result.err)
|
||||
}
|
||||
} else {
|
||||
|
@ -115,9 +115,9 @@ func (cl *client) loadFromDB(ctx context.Context, speed ProcessingSpeed, startFr
|
|||
|
||||
total := successCount + errorCount
|
||||
if total < 10 ||
|
||||
(total < 1000 && rand.Intn(1000) < 100) ||
|
||||
(total < 100000 && rand.Intn(1000) < 10) ||
|
||||
(rand.Intn(1000) < 1) {
|
||||
(total < 1000 && rand.IntN(1000) < 100) ||
|
||||
(total < 100000 && rand.IntN(1000) < 10) ||
|
||||
(rand.IntN(1000) < 1) {
|
||||
cl.logger.Infof("stored %d responses, %d errors", successCount, errorCount)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
mrand "math/rand"
|
||||
mrand "math/rand/v2"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
|
|
|
@ -2,7 +2,7 @@ package updater
|
|||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -21,7 +21,7 @@ func (cu *crlUpdater) Run(ctx context.Context) error {
|
|||
|
||||
// Wait for a random number of nanoseconds less than the updatePeriod, so
|
||||
// that process restarts do not skip or delay shards deterministically.
|
||||
waitTimer := time.NewTimer(time.Duration(rand.Int63n(cu.updatePeriod.Nanoseconds())))
|
||||
waitTimer := time.NewTimer(time.Duration(rand.Int64N(cu.updatePeriod.Nanoseconds())))
|
||||
defer waitTimer.Stop()
|
||||
select {
|
||||
case <-waitTimer.C:
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -314,6 +314,6 @@ func (ll List) PickOne(operator string, expiry time.Time) (string, string, error
|
|||
return "", "", fmt.Errorf("no log found for group %q and expiry %s", operator, expiry)
|
||||
}
|
||||
|
||||
log := candidates[rand.Intn(len(candidates))]
|
||||
log := candidates[rand.IntN(len(candidates))]
|
||||
return log.Url, log.Key, nil
|
||||
}
|
||||
|
|
|
@ -21,13 +21,12 @@
|
|||
package grpcrand
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
r = rand.New(rand.NewPCG(rand.Uint64(), rand.Uint64()))
|
||||
mu sync.Mutex
|
||||
)
|
||||
|
||||
|
@ -42,14 +41,14 @@ func Int() int {
|
|||
func Int63n(n int64) int64 {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
return r.Int63n(n)
|
||||
return r.Int64N(n)
|
||||
}
|
||||
|
||||
// Intn implements rand.Intn on the grpcrand global source.
|
||||
func Intn(n int) int {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
return r.Intn(n)
|
||||
return r.IntN(n)
|
||||
}
|
||||
|
||||
// Float64 implements rand.Float64 on the grpcrand global source.
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
@ -353,7 +353,7 @@ func (sa *StorageAuthority) NewOrderAndAuthzs(_ context.Context, req *sapb.NewOr
|
|||
Names: req.NewOrder.Names,
|
||||
V2Authorizations: req.NewOrder.V2Authorizations,
|
||||
// Mock new fields generated by the database transaction.
|
||||
Id: rand.Int63(),
|
||||
Id: rand.Int64(),
|
||||
Created: timestamppb.Now(),
|
||||
// A new order is never processing because it can't have been finalized yet.
|
||||
BeganProcessing: false,
|
||||
|
|
|
@ -40,7 +40,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
@ -153,7 +153,7 @@ var hashToString = map[crypto.Hash]string{
|
|||
}
|
||||
|
||||
func SampledError(log blog.Logger, sampleRate int, format string, a ...interface{}) {
|
||||
if sampleRate > 0 && rand.Intn(sampleRate) == 0 {
|
||||
if sampleRate > 0 && rand.IntN(sampleRate) == 0 {
|
||||
log.Errf(format, a...)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"net"
|
||||
"net/mail"
|
||||
"os"
|
||||
|
@ -46,7 +46,7 @@ func New(challengeTypes map[core.AcmeChallenge]bool, log blog.Logger) (*Authorit
|
|||
log: log,
|
||||
enabledChallenges: challengeTypes,
|
||||
// We don't need real randomness for this.
|
||||
pseudoRNG: rand.New(rand.NewSource(99)),
|
||||
pseudoRNG: rand.New(rand.NewPCG(rand.Uint64(), rand.Uint64())),
|
||||
}
|
||||
|
||||
return &pa, nil
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
mrand "math/rand"
|
||||
mrand "math/rand/v2"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
|
@ -2401,7 +2401,7 @@ func (msa *mockSAWithAuthzs) GetAuthorizations2(ctx context.Context, req *sapb.G
|
|||
func (msa *mockSAWithAuthzs) NewOrderAndAuthzs(ctx context.Context, req *sapb.NewOrderAndAuthzsRequest, _ ...grpc.CallOption) (*corepb.Order, error) {
|
||||
authzIDs := req.NewOrder.V2Authorizations
|
||||
for range req.NewAuthzs {
|
||||
authzIDs = append(authzIDs, mrand.Int63())
|
||||
authzIDs = append(authzIDs, mrand.Int64())
|
||||
}
|
||||
return &corepb.Order{
|
||||
// Fields from the input new order request.
|
||||
|
@ -2411,7 +2411,7 @@ func (msa *mockSAWithAuthzs) NewOrderAndAuthzs(ctx context.Context, req *sapb.Ne
|
|||
V2Authorizations: authzIDs,
|
||||
CertificateProfileName: req.NewOrder.CertificateProfileName,
|
||||
// Mock new fields generated by the database transaction.
|
||||
Id: mrand.Int63(),
|
||||
Id: mrand.Int64(),
|
||||
Created: timestamppb.Now(),
|
||||
// A new order is never processing because it can't have been finalized yet.
|
||||
BeganProcessing: false,
|
||||
|
|
|
@ -2,7 +2,7 @@ package ratelimits
|
|||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -43,7 +43,7 @@ func setup(t *testing.T) (context.Context, map[string]*Limiter, *TransactionBuil
|
|||
// runs.
|
||||
randIP := make(net.IP, 4)
|
||||
for i := range 4 {
|
||||
randIP[i] = byte(rand.Intn(256))
|
||||
randIP[i] = byte(rand.IntN(256))
|
||||
}
|
||||
|
||||
// Construct a limiter for each source.
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
"math/bits"
|
||||
mrand "math/rand"
|
||||
mrand "math/rand/v2"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
|
@ -3358,7 +3358,7 @@ func TestSerialsForIncident(t *testing.T) {
|
|||
"1335": true, "1336": true, "1337": true, "1338": true,
|
||||
}
|
||||
for i := range expectedSerials {
|
||||
randInt := func() int64 { return mrand.Int63() }
|
||||
randInt := func() int64 { return mrand.Int64() }
|
||||
_, err := testIncidentsDbMap.ExecContext(ctx,
|
||||
fmt.Sprintf("INSERT INTO incident_foo (%s) VALUES ('%s', %d, %d, '%s')",
|
||||
"serial, registrationID, orderID, lastNoticeSent",
|
||||
|
|
|
@ -6,14 +6,15 @@ package semaphore_test
|
|||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/letsencrypt/boulder/semaphore"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/letsencrypt/boulder/semaphore"
|
||||
)
|
||||
|
||||
const maxSleep = 1 * time.Millisecond
|
||||
|
@ -21,7 +22,7 @@ const maxSleep = 1 * time.Millisecond
|
|||
func HammerWeighted(sem *semaphore.Weighted, n int64, loops int) {
|
||||
for i := 0; i < loops; i++ {
|
||||
_ = sem.Acquire(context.Background(), n)
|
||||
time.Sleep(time.Duration(rand.Int63n(int64(maxSleep/time.Nanosecond))) * time.Nanosecond)
|
||||
time.Sleep(time.Duration(rand.Int64N(int64(maxSleep/time.Nanosecond))) * time.Nanosecond)
|
||||
sem.Release(n)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -161,7 +161,7 @@ func (is *integrationSrv) addChainOrPre(w http.ResponseWriter, r *http.Request,
|
|||
is.submissions[hostnames]++
|
||||
is.Unlock()
|
||||
|
||||
if is.flakinessRate != 0 && rand.Intn(100) < is.flakinessRate {
|
||||
if is.flakinessRate != 0 && rand.IntN(100) < is.flakinessRate {
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package acme
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
mrand "math/rand"
|
||||
mrand "math/rand/v2"
|
||||
"strings"
|
||||
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
|
@ -67,7 +67,7 @@ func (strategy randomChallengeStrategy) PickChallenge(authz *core.Authorization)
|
|||
if len(authz.Challenges) == 0 {
|
||||
return nil, ErrPickChallengeAuthzMissingChallenges
|
||||
}
|
||||
return &authz.Challenges[mrand.Intn(len(authz.Challenges))], nil
|
||||
return &authz.Challenges[mrand.IntN(len(authz.Challenges))], nil
|
||||
}
|
||||
|
||||
// preferredTypeChallengeStrategy is a ChallengeStrategy implementation that
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
mrand "math/rand"
|
||||
mrand "math/rand/v2"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -72,7 +72,7 @@ func getAccount(s *State, c *acmeCache) error {
|
|||
}
|
||||
|
||||
// Select a random account from the state and put it into the context
|
||||
c.acct = s.accts[mrand.Intn(len(s.accts))]
|
||||
c.acct = s.accts[mrand.IntN(len(s.accts))]
|
||||
c.ns = &nonceSource{s: s}
|
||||
return nil
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ func randDomain(base string) string {
|
|||
func newOrder(s *State, c *acmeCache) error {
|
||||
// Pick a random number of names within the constraints of the maxNamesPerCert
|
||||
// parameter
|
||||
orderSize := 1 + mrand.Intn(s.maxNamesPerCert-1)
|
||||
orderSize := 1 + mrand.IntN(s.maxNamesPerCert-1)
|
||||
// Generate that many random domain names. There may be some duplicates, we
|
||||
// don't care. The ACME server will collapse those down for us, how handy!
|
||||
dnsNames := []identifier.ACMEIdentifier{}
|
||||
|
@ -231,7 +231,7 @@ func newOrder(s *State, c *acmeCache) error {
|
|||
// popPendingOrder *removes* a random pendingOrder from the context, returning
|
||||
// it.
|
||||
func popPendingOrder(c *acmeCache) *OrderJSON {
|
||||
orderIndex := mrand.Intn(len(c.pendingOrders))
|
||||
orderIndex := mrand.IntN(len(c.pendingOrders))
|
||||
order := c.pendingOrders[orderIndex]
|
||||
c.pendingOrders = append(c.pendingOrders[:orderIndex], c.pendingOrders[orderIndex+1:]...)
|
||||
return order
|
||||
|
@ -465,7 +465,7 @@ func pollOrderForCert(order *OrderJSON, s *State, c *acmeCache) (*OrderJSON, err
|
|||
// popFulfilledOrder **removes** a fulfilled order from the context, returning
|
||||
// it. Fulfilled orders have all of their authorizations satisfied.
|
||||
func popFulfilledOrder(c *acmeCache) string {
|
||||
orderIndex := mrand.Intn(len(c.fulfilledOrders))
|
||||
orderIndex := mrand.IntN(len(c.fulfilledOrders))
|
||||
order := c.fulfilledOrders[orderIndex]
|
||||
c.fulfilledOrders = append(c.fulfilledOrders[:orderIndex], c.fulfilledOrders[orderIndex+1:]...)
|
||||
return order
|
||||
|
@ -580,7 +580,7 @@ func postAsGet(s *State, c *acmeCache, url string, latencyTag string) (*http.Res
|
|||
}
|
||||
|
||||
func popCertificate(c *acmeCache) string {
|
||||
certIndex := mrand.Intn(len(c.certs))
|
||||
certIndex := mrand.IntN(len(c.certs))
|
||||
certURL := c.certs[certIndex]
|
||||
c.certs = append(c.certs[:certIndex], c.certs[certIndex+1:]...)
|
||||
return certURL
|
||||
|
|
|
@ -3,7 +3,7 @@ package va
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"math/rand/v2"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
mrand "math/rand"
|
||||
mrand "math/rand/v2"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
@ -1213,7 +1213,7 @@ func TestHTTPBadPort(t *testing.T) {
|
|||
// Pick a random port between 40000 and 65000 - with great certainty we won't
|
||||
// have an HTTP server listening on this port and the test will fail as
|
||||
// intended
|
||||
badPort := 40000 + mrand.Intn(25000)
|
||||
badPort := 40000 + mrand.IntN(25000)
|
||||
va.httpPort = badPort
|
||||
|
||||
_, err := va.validateHTTP01(ctx, dnsi("localhost"), expectedToken, expectedKeyAuthorization)
|
||||
|
|
Loading…
Reference in New Issue