aboutsummaryrefslogtreecommitdiffstats
path: root/rpc/utils.go
diff options
context:
space:
mode:
Diffstat (limited to 'rpc/utils.go')
-rw-r--r--rpc/utils.go42
1 files changed, 34 insertions, 8 deletions
diff --git a/rpc/utils.go b/rpc/utils.go
index 1ac6698f5..b590ba62f 100644
--- a/rpc/utils.go
+++ b/rpc/utils.go
@@ -17,17 +17,26 @@
package rpc
import (
- "crypto/rand"
+ "bufio"
+ crand "crypto/rand"
+ "encoding/binary"
"encoding/hex"
- "errors"
"math/big"
+ "math/rand"
"reflect"
+ "sync"
+ "time"
"unicode"
"unicode/utf8"
"golang.org/x/net/context"
)
+var (
+ subscriptionIDGenMu sync.Mutex
+ subscriptionIDGen = idGenerator()
+)
+
// Is this an exported - upper case - name?
func isExported(name string) bool {
rune, _ := utf8.DecodeRuneInString(name)
@@ -218,11 +227,28 @@ METHODS:
return callbacks, subscriptions
}
-func newSubscriptionID() (string, error) {
- var subid [16]byte
- n, _ := rand.Read(subid[:])
- if n != 16 {
- return "", errors.New("Unable to generate subscription id")
+// idGenerator helper utility that generates a (pseudo) random sequence of
+// bytes that are used to generate identifiers.
+func idGenerator() *rand.Rand {
+ if seed, err := binary.ReadVarint(bufio.NewReader(crand.Reader)); err == nil {
+ return rand.New(rand.NewSource(seed))
+ }
+ return rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
+}
+
+// NewID generates a identifier that can be used as an identifier in the RPC interface.
+// e.g. filter and subscription identifier.
+func NewID() ID {
+ subscriptionIDGenMu.Lock()
+ defer subscriptionIDGenMu.Unlock()
+
+ id := make([]byte, 16)
+ for i := 0; i < len(id); i += 7 {
+ val := subscriptionIDGen.Int63()
+ for j := 0; i+j < len(id) && j < 7; j++ {
+ id[i+j] = byte(val)
+ val >>= 8
+ }
}
- return "0x" + hex.EncodeToString(subid[:]), nil
+ return ID("0x" + hex.EncodeToString(id))
}