diff --git a/pkg/provision/auth.go b/pkg/provision/auth.go index 653b4c91..5c38633b 100644 --- a/pkg/provision/auth.go +++ b/pkg/provision/auth.go @@ -2,50 +2,55 @@ package provision import ( "context" - "crypto/ed25519" "fmt" + "time" - lru "github.com/hashicorp/golang-lru" + cache "github.com/patrickmn/go-cache" "github.com/pkg/errors" + "github.com/rs/zerolog/log" "github.com/threefoldtech/zosbase/pkg/stubs" ) +const ( + keyExpiration = 60 * time.Minute + keyCleanup = 10 * time.Minute +) + type substrateTwins struct { substrateGateway *stubs.SubstrateGatewayStub - mem *lru.Cache + mem *cache.Cache } // NewSubstrateTwins creates a substrate users db that implements the provision.Users interface. func NewSubstrateTwins(substrateGateway *stubs.SubstrateGatewayStub) (Twins, error) { - cache, err := lru.New(1024) - if err != nil { - return nil, err - } - return &substrateTwins{ substrateGateway: substrateGateway, - mem: cache, + mem: cache.New(keyExpiration, keyCleanup), }, nil } // GetKey gets twins public key func (s *substrateTwins) GetKey(id uint32) ([]byte, error) { - if value, ok := s.mem.Get(id); ok { + cacheKey := fmt.Sprint(id) + if value, ok := s.mem.Get(cacheKey); ok { return value.([]byte), nil } + + log.Debug().Uint32("twin", id).Msg("twin public key cache expired, fetching from substrate") user, err := s.substrateGateway.GetTwin(context.Background(), id) if err != nil { return nil, errors.Wrapf(err, "could not get user with id '%d'", id) } - key := user.Account.PublicKey() - s.mem.Add(id, key) - return key, nil + pk := user.Account.PublicKey() + s.mem.Set(cacheKey, pk, cache.DefaultExpiration) + return pk, nil } type substrateAdmins struct { - twin uint32 - pk ed25519.PublicKey + substrateGateway *stubs.SubstrateGatewayStub + twin uint32 + mem *cache.Cache } // NewSubstrateAdmins creates a substrate twins db that implements the provision.Users interface. @@ -56,13 +61,10 @@ func NewSubstrateAdmins(substrateGateway *stubs.SubstrateGatewayStub, farmID uin return nil, errors.Wrap(err, "failed to get farm") } - twin, err := substrateGateway.GetTwin(context.Background(), uint32(farm.TwinID)) - if err != nil { - return nil, err - } return &substrateAdmins{ - twin: uint32(farm.TwinID), - pk: twin.Account.PublicKey(), + substrateGateway: substrateGateway, + twin: uint32(farm.TwinID), + mem: cache.New(keyExpiration, keyCleanup), }, nil } @@ -72,5 +74,18 @@ func (s *substrateAdmins) GetKey(id uint32) ([]byte, error) { return nil, fmt.Errorf("twin with id '%d' is not an admin", id) } - return []byte(s.pk), nil + cacheKey := fmt.Sprint(id) + if value, ok := s.mem.Get(cacheKey); ok { + return value.([]byte), nil + } + + log.Debug().Uint32("twin", id).Msg("admin public key cache expired, fetching from substrate") + twin, err := s.substrateGateway.GetTwin(context.Background(), id) + if err != nil { + return nil, errors.Wrapf(err, "could not get admin twin with id '%d'", id) + } + + pk := twin.Account.PublicKey() + s.mem.Set(cacheKey, pk, cache.DefaultExpiration) + return pk, nil }