Skip to content

Commit

Permalink
Improve visibility around poet registrations in events (#6382)
Browse files Browse the repository at this point in the history
Closes #5565

## Motivation

Provide new events for:

- created poet client (URL)
- registered in poet (URL, challenge, round)
- got proof from poet (URL, round, ticks)
- selected best poet proof (URL, round, ticks)

## Test Plan

New functionality tested as a part of node/node_test and activation/nipost_test.

## TODO

- [x] Requires spacemeshos/api#382 than bump in that module version
- [x] Explain motivation or link existing issue(s)
- [x] Test changes and document test plan
- [ ] Update documentation as needed
- [x] Update [changelog](../CHANGELOG.md) as needed
  • Loading branch information
jellonek committed Oct 18, 2024
1 parent 58b0c6c commit b7d0db9
Show file tree
Hide file tree
Showing 21 changed files with 216 additions and 33 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ See [RELEASE](./RELEASE.md) for workflow instructions.

### Upgrade information

New event types introduced in the API of the node, see [API #382](https://github.com/spacemeshos/api/pull/382) and 2
previously existing events where renamed. Old events were marked as deprecated. Please update your automations to use
new event types.

### Highlights

### Features
Expand All @@ -21,6 +25,8 @@ See [RELEASE](./RELEASE.md) for workflow instructions.
* [#6393](https://github.com/spacemeshos/go-spacemesh/pull/6393) Further improved proposal building process to avoid
late proposals in 1:N setups and during cyclegap.

* [#6382](https://github.com/spacemeshos/go-spacemesh/pull/6382) Improve visibility around poet registrations in events.

## v1.7.4

### Improvements
Expand Down
1 change: 1 addition & 0 deletions activation/activation.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ func (b *Builder) BuildNIPostChallenge(ctx context.Context, nodeID types.NodeID)
zap.Time("waiting until", wait),
)
events.EmitPoetWaitRound(nodeID, currentEpochId, publishEpochId, wait)
events.EmitWaitingForPoETRegistrationWindow(nodeID, currentEpochId, publishEpochId, wait)
select {
case <-ctx.Done():
return nil, ctx.Err()
Expand Down
6 changes: 5 additions & 1 deletion activation/e2e/atx_merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ import (
"github.com/spacemeshos/go-spacemesh/timesync"
)

const (
testTickSize = 1
)

func constructMerkleProof(t testing.TB, members []types.Hash32, ids map[uint64]bool) wire.MerkleProofV2 {
t.Helper()

Expand Down Expand Up @@ -248,7 +252,7 @@ func Test_MarryAndMerge(t *testing.T) {
}

client := ae2e.NewTestPoetClient(2, poetCfg)
poetSvc := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetSvc := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)

clock, err := timesync.NewClock(
timesync.WithGenesisTime(genesis),
Expand Down
2 changes: 1 addition & 1 deletion activation/e2e/builds_atx_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func TestBuilder_SwitchesToBuildV2(t *testing.T) {
t.Cleanup(clock.Close)

client := ae2e.NewTestPoetClient(1, poetCfg)
poetClient := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetClient := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)

localDB := localsql.InMemory()
nb, err := activation.NewNIPostBuilder(
Expand Down
4 changes: 2 additions & 2 deletions activation/e2e/checkpoint_merged_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func Test_CheckpointAfterMerge(t *testing.T) {
}

client := ae2e.NewTestPoetClient(2, poetCfg)
poetSvc := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetSvc := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)

clock, err := timesync.NewClock(
timesync.WithGenesisTime(genesis),
Expand Down Expand Up @@ -285,7 +285,7 @@ func Test_CheckpointAfterMerge(t *testing.T) {
require.NoError(t, err)
cdb = datastore.NewCachedDB(newDB, logger)

poetSvc = activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetSvc = activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)
validator = activation.NewValidator(newDB, poetDb, cfg, opts.Scrypt, verifier)
require.NoError(t, err)
atxHdlr = activation.NewHandler(
Expand Down
4 changes: 2 additions & 2 deletions activation/e2e/checkpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestCheckpoint_PublishingSoloATXs(t *testing.T) {
GracePeriod: epoch / 4,
}
client := ae2e.NewTestPoetClient(1, poetCfg)
poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)

// ensure that genesis aligns with layer timings
genesis := time.Now().Add(layerDuration).Round(layerDuration)
Expand Down Expand Up @@ -191,7 +191,7 @@ func TestCheckpoint_PublishingSoloATXs(t *testing.T) {
require.NoError(t, err)
cdb = datastore.NewCachedDB(newDB, logger)
atxdata, err = atxsdata.Warm(newDB, 1, logger, sig)
poetService = activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetService = activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)
validator = activation.NewValidator(newDB, poetDb, cfg, opts.Scrypt, verifier)
require.NoError(t, err)
atxHdlr = activation.NewHandler(
Expand Down
4 changes: 2 additions & 2 deletions activation/e2e/nipost_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func TestNIPostBuilderWithClients(t *testing.T) {
require.NoError(t, err)

client := ae2e.NewTestPoetClient(1, poetCfg)
poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)

localDB := localsql.InMemory()
nb, err := activation.NewNIPostBuilder(
Expand Down Expand Up @@ -275,7 +275,7 @@ func Test_NIPostBuilderWithMultipleClients(t *testing.T) {
poetDb, err := activation.NewPoetDb(db, logger.Named("poetDb"))
require.NoError(t, err)
client := ae2e.NewTestPoetClient(len(signers), poetCfg)
poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)

mclock := activation.NewMocklayerClock(ctrl)
mclock.EXPECT().LayerToTime(gomock.Any()).AnyTimes().DoAndReturn(
Expand Down
1 change: 1 addition & 0 deletions activation/e2e/poet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (h *HTTPPoetTestHarness) Client(
h.ServerCfg(),
cfg,
logger,
1,
opts...,
)
}
Expand Down
2 changes: 1 addition & 1 deletion activation/e2e/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestValidator_Validate(t *testing.T) {
poetDb, err := activation.NewPoetDb(statesql.InMemory(), logger.Named("poetDb"))
require.NoError(t, err)
client := ae2e.NewTestPoetClient(1, poetCfg)
poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger)
poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger, testTickSize)

mclock := activation.NewMocklayerClock(ctrl)
mclock.EXPECT().LayerToTime(gomock.Any()).AnyTimes().DoAndReturn(
Expand Down
3 changes: 3 additions & 0 deletions activation/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ type PoetService interface {

// Proof returns the proof for the given round ID.
Proof(ctx context.Context, roundID string) (*types.PoetProof, []types.Hash32, error)

// TickSize returns tickSize configured for particular PoET service
TickSize() uint64
}

// A certifier client that the certifierService uses to obtain certificates
Expand Down
38 changes: 38 additions & 0 deletions activation/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions activation/nipost.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func (nb *NIPostBuilder) BuildNIPost(
}

events.EmitPoetWaitProof(signer.NodeID(), postChallenge.PublishEpoch, curPoetRoundEnd)
events.EmitWaitingForPoETRoundEnd(signer.NodeID(), postChallenge.PublishEpoch, curPoetRoundEnd)
poetProofRef, membership, err = nb.getBestProof(ctx, signer.NodeID(), challenge, submittedRegistrations)
if err != nil {
return nil, &PoetSvcUnstableError{msg: "getBestProof failed", source: err}
Expand Down Expand Up @@ -525,6 +526,9 @@ func (nb *NIPostBuilder) getBestProof(
type poetProof struct {
poet *types.PoetProof
membership *types.MerkleProof
round string
url string
ticks uint64
}
proofs := make(chan *poetProof, len(registrations))

Expand Down Expand Up @@ -568,6 +572,9 @@ func (nb *NIPostBuilder) getBestProof(
proofs <- &poetProof{
poet: proof,
membership: membership,
round: round,
url: client.Address(),
ticks: proof.LeafCount / client.TickSize(),
}
return nil
})
Expand Down Expand Up @@ -600,6 +607,12 @@ func (nb *NIPostBuilder) getBestProof(
zap.Binary("ref", ref[:]),
log.ZShortStringer("smesherID", nodeID),
)
events.EmitBestProofSelected(
nodeID,
bestProof.url,
bestProof.round,
bestProof.ticks,
)
return ref, bestProof.membership, nil
}

Expand Down
4 changes: 4 additions & 0 deletions activation/nipost_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func defaultPoetServiceMock(t *testing.T, ctrl *gomock.Controller, address strin
AnyTimes().
Return(&types.PoetRound{}, nil)
poet.EXPECT().Address().AnyTimes().Return(address).AnyTimes()
poet.EXPECT().TickSize().AnyTimes().Return(uint64(1)).AnyTimes()
return poet
}

Expand Down Expand Up @@ -582,6 +583,7 @@ func TestNIPostBuilder_ManyPoETs_SubmittingChallenge_DeadlineReached(t *testing.
Proof(gomock.Any(), gomock.Any()).
Return(proof, []types.Hash32{challenge}, nil)
poet.EXPECT().Address().AnyTimes().Return("http://localhost:9998")
poet.EXPECT().TickSize().AnyTimes().Return(uint64(1)).AnyTimes()
poets = append(poets, poet)
}

Expand Down Expand Up @@ -639,6 +641,7 @@ func TestNIPostBuilder_ManyPoETs_AllFinished(t *testing.T) {
Submit(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
Return(&types.PoetRound{}, nil)
poet.EXPECT().Address().AnyTimes().Return("http://localhost:9999")
poet.EXPECT().TickSize().AnyTimes().Return(uint64(1)).AnyTimes()
poet.EXPECT().Proof(gomock.Any(), "").Return(proofWorse, []types.Hash32{challenge}, nil)
poets = append(poets, poet)
}
Expand Down Expand Up @@ -1274,6 +1277,7 @@ func TestNIPoSTBuilder_Continues_After_Interrupted(t *testing.T) {
})
poet.EXPECT().Proof(gomock.Any(), "").Return(proof, []types.Hash32{challenge}, nil)
poet.EXPECT().Address().AnyTimes().Return("http://localhost:9999")
poet.EXPECT().TickSize().AnyTimes().Return(uint64(1))

poetCfg := PoetConfig{
PhaseShift: layerDuration * layersPerEpoch / 2,
Expand Down
19 changes: 18 additions & 1 deletion activation/poet.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/spacemeshos/go-spacemesh/activation/metrics"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/events"
"github.com/spacemeshos/go-spacemesh/log"
"github.com/spacemeshos/go-spacemesh/sql"
"github.com/spacemeshos/go-spacemesh/sql/localsql/certifier"
Expand Down Expand Up @@ -245,7 +246,10 @@ func (c *HTTPPoetClient) Submit(
roundEnd = time.Now().Add(resBody.RoundEnd.AsDuration())
}

return &types.PoetRound{ID: resBody.RoundId, End: roundEnd}, nil
round := types.PoetRound{ID: resBody.RoundId, End: roundEnd}
events.EmitRegisteredInPoet(nodeID, c.Address(), round.ID)

return &round, nil
}

func (c *HTTPPoetClient) Info(ctx context.Context) (*types.PoetInfo, error) {
Expand Down Expand Up @@ -400,6 +404,9 @@ type poetService struct {
expectedPhaseShift time.Duration
infoCache cachedData[*types.PoetInfo]
powParamsCache cachedData[*PoetPowParams]

// Used to calculate ticks from PoetProof.LeafCount.
tickSize uint64
}

type PoetServiceOpt func(*poetService)
Expand All @@ -415,6 +422,7 @@ func NewPoetService(
server types.PoetServer,
cfg PoetConfig,
logger *zap.Logger,
tickSize uint64,
opts ...PoetServiceOpt,
) (*poetService, error) {
client, err := NewHTTPPoetClient(server, cfg, WithLogger(logger))
Expand All @@ -426,6 +434,7 @@ func NewPoetService(
client,
cfg,
logger,
tickSize,
opts...,
), nil
}
Expand All @@ -435,6 +444,7 @@ func NewPoetServiceWithClient(
client PoetClient,
cfg PoetConfig,
logger *zap.Logger,
tickSize uint64,
opts ...PoetServiceOpt,
) *poetService {
service := &poetService{
Expand All @@ -446,6 +456,7 @@ func NewPoetServiceWithClient(
powParamsCache: cachedData[*PoetPowParams]{ttl: cfg.PowParamsCacheTTL},
proofMembers: make(map[string][]types.Hash32, 1),
expectedPhaseShift: cfg.PhaseShift,
tickSize: tickSize,
}
for _, opt := range opts {
opt(service)
Expand All @@ -465,6 +476,10 @@ func NewPoetServiceWithClient(
return service
}

func (c *poetService) TickSize() uint64 {
return c.tickSize
}

func (c *poetService) verifyPhaseShiftConfiguration(ctx context.Context) error {
info, err := c.getInfo(ctx)
if err != nil {
Expand Down Expand Up @@ -617,6 +632,8 @@ func (c *poetService) Proof(ctx context.Context, roundID string) (*types.PoetPro
clear(c.proofMembers)
c.proofMembers[roundID] = members

events.EmitProofDownloadedFromPoet(c.Address(), proof.RoundID, proof.LeafCount/c.tickSize)

return &proof.PoetProof, members, nil
}

Expand Down
Loading

0 comments on commit b7d0db9

Please sign in to comment.