[#1213] morph/client: Protect cached values with a mutex

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-03-15 14:21:24 +03:00 committed by Alex Vanin
parent a8d2001b35
commit 9bbb136e4a
2 changed files with 23 additions and 7 deletions

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"sync"
"time" "time"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
@ -43,8 +44,11 @@ type Client struct {
} }
type cache struct { type cache struct {
nnsHash util.Uint160 // mtx protects primitive values.
groupKey *keys.PublicKey mtx sync.RWMutex
nnsHash util.Uint160
groupKey *keys.PublicKey
// txHeights is a thread-safe LRU cache for transaction heights.
txHeights *lru.Cache txHeights *lru.Cache
} }

View file

@ -85,14 +85,20 @@ func (c *Client) NNSHash() (util.Uint160, error) {
}) })
} }
if c.nnsHash.Equals(util.Uint160{}) { c.mtx.RLock()
nnsHash := c.nnsHash
c.mtx.RUnlock()
if nnsHash.Equals(util.Uint160{}) {
cs, err := c.client.GetContractStateByID(nnsContractID) cs, err := c.client.GetContractStateByID(nnsContractID)
if err != nil { if err != nil {
return util.Uint160{}, fmt.Errorf("NNS contract state: %w", err) return util.Uint160{}, fmt.Errorf("NNS contract state: %w", err)
} }
c.mtx.Lock()
c.nnsHash = cs.Hash c.nnsHash = cs.Hash
c.mtx.Unlock()
} }
return c.nnsHash, nil return nnsHash, nil
} }
func nnsResolveItem(c *client.Client, nnsHash util.Uint160, domain string) (stackitem.Item, error) { func nnsResolveItem(c *client.Client, nnsHash util.Uint160, domain string) (stackitem.Item, error) {
@ -197,8 +203,12 @@ func (c *Client) SetGroupSignerScope() error {
// contractGroupKey returns public key designating NeoFS contract group. // contractGroupKey returns public key designating NeoFS contract group.
func (c *Client) contractGroupKey() (*keys.PublicKey, error) { func (c *Client) contractGroupKey() (*keys.PublicKey, error) {
if c.groupKey != nil { c.mtx.RLock()
return c.groupKey, nil pub := c.groupKey
c.mtx.RUnlock()
if pub != nil {
return pub, nil
} }
nnsHash, err := c.NNSHash() nnsHash, err := c.NNSHash()
@ -216,11 +226,13 @@ func (c *Client) contractGroupKey() (*keys.PublicKey, error) {
return nil, err return nil, err
} }
pub, err := keys.NewPublicKeyFromString(string(bs)) pub, err = keys.NewPublicKeyFromString(string(bs))
if err != nil { if err != nil {
return nil, err return nil, err
} }
c.mtx.Lock()
c.groupKey = pub c.groupKey = pub
c.mtx.Unlock()
return pub, nil return pub, nil
} }