aboutsummaryrefslogtreecommitdiffstats
path: root/core/crypto
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2019-04-06 17:04:11 +0800
committerGitHub <noreply@github.com>2019-04-06 17:04:11 +0800
commit99e3dfee0eb2ffbb4fb0afb8e65664a7c9d91bcd (patch)
tree2de83006c9464548c682b86bbcc1a2f7f9417ff5 /core/crypto
parentd433231363d622acb26f8fa9b072470c179dbc62 (diff)
downloaddexon-consensus-99e3dfee0eb2ffbb4fb0afb8e65664a7c9d91bcd.tar
dexon-consensus-99e3dfee0eb2ffbb4fb0afb8e65664a7c9d91bcd.tar.gz
dexon-consensus-99e3dfee0eb2ffbb4fb0afb8e65664a7c9d91bcd.tar.bz2
dexon-consensus-99e3dfee0eb2ffbb4fb0afb8e65664a7c9d91bcd.tar.lz
dexon-consensus-99e3dfee0eb2ffbb4fb0afb8e65664a7c9d91bcd.tar.xz
dexon-consensus-99e3dfee0eb2ffbb4fb0afb8e65664a7c9d91bcd.tar.zst
dexon-consensus-99e3dfee0eb2ffbb4fb0afb8e65664a7c9d91bcd.zip
core, core: crypto: dkg: fix concurrent access bug (#551)
* core: crypto: dkg: fix concurrent access bug * core: fix concurrent bug
Diffstat (limited to 'core/crypto')
-rw-r--r--core/crypto/dkg/dkg.go25
-rw-r--r--core/crypto/dkg/dkg_test.go14
2 files changed, 30 insertions, 9 deletions
diff --git a/core/crypto/dkg/dkg.go b/core/crypto/dkg/dkg.go
index b89ad10..ab43f51 100644
--- a/core/crypto/dkg/dkg.go
+++ b/core/crypto/dkg/dkg.go
@@ -450,11 +450,10 @@ func (prvs *PrivateKeyShares) Share(ID ID) (*PrivateKey, bool) {
// NewEmptyPublicKeyShares creates an empty public key shares.
func NewEmptyPublicKeyShares() *PublicKeyShares {
- cache := &publicKeySharesCache{
- index: make(map[ID]int),
- }
pubShares := &PublicKeyShares{}
- pubShares.cache.Store(cache)
+ pubShares.cache.Store(&publicKeySharesCache{
+ index: make(map[ID]int),
+ })
return pubShares
}
@@ -481,9 +480,9 @@ func (pubs *PublicKeyShares) Share(ID ID) (*PublicKey, error) {
}
// AddShare adds a share.
-func (pubs *PublicKeyShares) AddShare(ID ID, share *PublicKey) error {
+func (pubs *PublicKeyShares) AddShare(shareID ID, share *PublicKey) error {
cache := pubs.cache.Load().(*publicKeySharesCache)
- if idx, exist := cache.index[ID]; exist {
+ if idx, exist := cache.index[shareID]; exist {
if !share.publicKey.IsEqual(&cache.share[idx].publicKey) {
return ErrDuplicatedShare
}
@@ -492,9 +491,17 @@ func (pubs *PublicKeyShares) AddShare(ID ID, share *PublicKey) error {
pubs.lock.Lock()
defer pubs.lock.Unlock()
cache = pubs.cache.Load().(*publicKeySharesCache)
- cache.index[ID] = len(cache.share)
- cache.share = append(cache.share, *share)
- pubs.cache.Store(cache)
+ newCache := &publicKeySharesCache{
+ index: make(map[ID]int, len(cache.index)+1),
+ share: make([]PublicKey, len(cache.share), len(cache.share)+1),
+ }
+ for k, v := range cache.index {
+ newCache.index[k] = v
+ }
+ copy(newCache.share, cache.share)
+ newCache.index[shareID] = len(newCache.share)
+ newCache.share = append(newCache.share, *share)
+ pubs.cache.Store(newCache)
return nil
}
diff --git a/core/crypto/dkg/dkg_test.go b/core/crypto/dkg/dkg_test.go
index a679cf4..84dc2d4 100644
--- a/core/crypto/dkg/dkg_test.go
+++ b/core/crypto/dkg/dkg_test.go
@@ -394,6 +394,20 @@ func (s *DKGTestSuite) TestPublicKeySharesMove() {
req.True(pubShares2.Equal(pubShares3))
}
+func (s *DKGTestSuite) TestPublicKeySharesConcurrent() {
+ t := 5
+ n := 10
+ IDs := make(IDs, n)
+ for i := range IDs {
+ id := common.NewRandomHash()
+ IDs[i] = NewID(id[:])
+ }
+ _, pubShare := NewPrivateKeyShares(t)
+ for _, id := range IDs {
+ go pubShare.Share(id)
+ }
+}
+
func (s *DKGTestSuite) TestPrivateKeySharesEquality() {
var req = s.Require()
IDs := s.genID(2)