Skip to content

Commit

Permalink
[backport] poet caching opts (#6201)
Browse files Browse the repository at this point in the history
* configure poet /v1/info cache ttl in presets (#6198)

## Motivation

For the cache to work, it needs to have non-zero TTL set

* cache poet's /v1/pow_params with TTL (#6199)

## Motivation

Similarly to /v1/info, we query /v1/pow_params very often (once per submit per node ID). As the contents returned from this endpoint change rarely (once per epoch), it makes sense to cache the result.

* update changelog
  • Loading branch information
poszu authored Aug 1, 2024
1 parent 52b14e6 commit 334d6cc
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 26 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

See [RELEASE](./RELEASE.md) for workflow instructions.

## Release v1.6.6

### Improvements

* [#6198](https://github.com/spacemeshos/go-spacemesh/pull/6198) Configure default TTL for caching poet's /v1/info
* [#6199](https://github.com/spacemeshos/go-spacemesh/pull/6199) Cache poet's /v1/pow_params

## Release v1.6.5

### Improvements
Expand Down
2 changes: 2 additions & 0 deletions activation/activation.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type PoetConfig struct {
RequestRetryDelay time.Duration `mapstructure:"retry-delay"`
PositioningATXSelectionTimeout time.Duration `mapstructure:"positioning-atx-selection-timeout"`
CertifierInfoCacheTTL time.Duration `mapstructure:"certifier-info-cache-ttl"`
PowParamsCacheTTL time.Duration `mapstructure:"pow-params-cache-ttl"`
MaxRequestRetries int `mapstructure:"retry-max"`
}

Expand All @@ -54,6 +55,7 @@ func DefaultPoetConfig() PoetConfig {
RequestRetryDelay: 400 * time.Millisecond,
MaxRequestRetries: 10,
CertifierInfoCacheTTL: 5 * time.Minute,
PowParamsCacheTTL: 5 * time.Minute,
}
}

Expand Down
75 changes: 49 additions & 26 deletions activation/poet.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,29 @@ func (c *HTTPPoetClient) req(ctx context.Context, method, path string, reqBody,
}

type certifierInfo struct {
obtained time.Time
url *url.URL
pubkey []byte
url *url.URL
pubkey []byte
}

type cachedData[T any] struct {
mu sync.Mutex
data T
exp time.Time
ttl time.Duration
}

func (c *cachedData[T]) get(init func() (T, error)) (T, error) {
c.mu.Lock()
defer c.mu.Unlock()
if time.Now().Before(c.exp) {
return c.data, nil
}
d, err := init()
if err == nil {
c.data = d
c.exp = time.Now().Add(c.ttl)
}
return d, err
}

// poetService is a higher-level interface to communicate with a PoET service.
Expand All @@ -353,9 +373,8 @@ type poetService struct {

certifier certifierService

certifierInfoTTL time.Duration
certifierInfo certifierInfo
certifierInfoMutex sync.Mutex
certifierInfoCache cachedData[*certifierInfo]
powParamsCache cachedData[*PoetPowParams]
}

type PoetServiceOpt func(*poetService)
Expand Down Expand Up @@ -394,12 +413,13 @@ func NewPoetServiceWithClient(
opts ...PoetServiceOpt,
) *poetService {
poetClient := &poetService{
db: db,
logger: logger,
client: client,
requestTimeout: cfg.RequestTimeout,
certifierInfoTTL: cfg.CertifierInfoCacheTTL,
proofMembers: make(map[string][]types.Hash32, 1),
db: db,
logger: logger,
client: client,
requestTimeout: cfg.RequestTimeout,
certifierInfoCache: cachedData[*certifierInfo]{ttl: cfg.CertifierInfoCacheTTL},
powParamsCache: cachedData[*PoetPowParams]{ttl: cfg.PowParamsCacheTTL},
proofMembers: make(map[string][]types.Hash32, 1),
}

for _, opt := range opts {
Expand Down Expand Up @@ -435,7 +455,7 @@ func (c *poetService) authorize(
logger.Debug("querying for poet pow parameters")
powCtx, cancel := withConditionalTimeout(ctx, c.requestTimeout)
defer cancel()
powParams, err := c.client.PowParams(powCtx)
powParams, err := c.powParams(powCtx)
if err != nil {
return nil, &PoetSvcUnstableError{msg: "failed to get PoW params", source: err}
}
Expand Down Expand Up @@ -552,19 +572,22 @@ func (c *poetService) recertify(ctx context.Context, id types.NodeID) (*certifie
}

func (c *poetService) getCertifierInfo(ctx context.Context) (*url.URL, []byte, error) {
c.certifierInfoMutex.Lock()
defer c.certifierInfoMutex.Unlock()
if time.Since(c.certifierInfo.obtained) < c.certifierInfoTTL {
return c.certifierInfo.url, c.certifierInfo.pubkey, nil
}
url, pubkey, err := c.client.CertifierInfo(ctx)
info, err := c.certifierInfoCache.get(func() (*certifierInfo, error) {
url, pubkey, err := c.client.CertifierInfo(ctx)
if err != nil {
return nil, fmt.Errorf("getting certifier info: %w", err)
}
return &certifierInfo{url: url, pubkey: pubkey}, nil
})
if err != nil {
return nil, nil, fmt.Errorf("getting certifier info: %w", err)
}
c.certifierInfo = certifierInfo{
obtained: time.Now(),
url: url,
pubkey: pubkey,
return nil, nil, err
}
return c.certifierInfo.url, c.certifierInfo.pubkey, nil

return info.url, info.pubkey, nil
}

func (c *poetService) powParams(ctx context.Context) (*PoetPowParams, error) {
return c.powParamsCache.get(func() (*PoetPowParams, error) {
return c.client.PowParams(ctx)
})
}
34 changes: 34 additions & 0 deletions activation/poet_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,3 +421,37 @@ func TestPoetService_CachesCertifierInfo(t *testing.T) {
})
}
}

func TestPoetService_CachesPowParams(t *testing.T) {
t.Parallel()
type test struct {
name string
ttl time.Duration
}
for _, tc := range []test{
{name: "cache enabled", ttl: time.Hour},
{name: "cache disabled"},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
cfg := DefaultPoetConfig()
cfg.PowParamsCacheTTL = tc.ttl
client := NewMockPoetClient(gomock.NewController(t))
poet := NewPoetServiceWithClient(nil, client, cfg, zaptest.NewLogger(t))

params := PoetPowParams{
Challenge: types.RandomBytes(10),
Difficulty: 8,
}
exp := client.EXPECT().PowParams(gomock.Any()).Return(&params, nil)
if tc.ttl == 0 {
exp.Times(5)
}
for range 5 {
got, err := poet.powParams(context.Background())
require.NoError(t, err)
require.Equal(t, params, *got)
}
})
}
}
2 changes: 2 additions & 0 deletions config/mainnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ func MainnetConfig() Config {
CycleGap: 12 * time.Hour,
GracePeriod: 1 * time.Hour,
PositioningATXSelectionTimeout: 50 * time.Minute,
CertifierInfoCacheTTL: 5 * time.Minute,
PowParamsCacheTTL: 5 * time.Minute,
// RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2
RequestTimeout: 1100 * time.Second,
RequestRetryDelay: 10 * time.Second,
Expand Down
3 changes: 3 additions & 0 deletions config/presets/fastnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,8 @@ func fastnet() config.Config {
conf.POET.RequestTimeout = 12 * time.Second // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2
conf.POET.RequestRetryDelay = 1 * time.Second
conf.POET.MaxRequestRetries = 3
conf.POET.CertifierInfoCacheTTL = time.Minute
conf.POET.PowParamsCacheTTL = 10 * time.Second

return conf
}
2 changes: 2 additions & 0 deletions config/presets/standalone.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ func standalone() config.Config {
conf.POET.RequestTimeout = 12 * time.Second // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2
conf.POET.RequestRetryDelay = 1 * time.Second
conf.POET.MaxRequestRetries = 3
conf.POET.CertifierInfoCacheTTL = time.Minute
conf.POET.PowParamsCacheTTL = 10 * time.Second

conf.P2P.DisableNatPort = true

Expand Down
3 changes: 3 additions & 0 deletions config/presets/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ func testnet() config.Config {
RequestTimeout: 550 * time.Second, // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2
RequestRetryDelay: 5 * time.Second,
MaxRequestRetries: 10,

CertifierInfoCacheTTL: 5 * time.Minute,
PowParamsCacheTTL: 5 * time.Minute,
},
POST: activation.PostConfig{
MinNumUnits: 2,
Expand Down

0 comments on commit 334d6cc

Please sign in to comment.