diff options
Diffstat (limited to 'rpc/utils.go')
-rw-r--r-- | rpc/utils.go | 42 |
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)) } |