diff --git a/activation/e2e/poet_test.go b/activation/e2e/poet_test.go index 9d8376c285f..2881f40be38 100644 --- a/activation/e2e/poet_test.go +++ b/activation/e2e/poet_test.go @@ -82,14 +82,10 @@ func NewHTTPPoetTestHarness(ctx context.Context, poetdir string, opts ...HTTPPoe } func TestHTTPPoet(t *testing.T) { - if testing.Short() { - t.Skip() - } t.Parallel() r := require.New(t) var eg errgroup.Group - poetDir := t.TempDir() t.Cleanup(func() { r.NoError(eg.Wait()) }) @@ -126,10 +122,58 @@ func TestHTTPPoet(t *testing.T) { signature := signer.Sign(signing.POET, ch.Bytes()) prefix := bytes.Join([][]byte{signer.Prefix(), {byte(signing.POET)}}, nil) - poetRound, err := client.Submit(context.Background(), prefix, ch.Bytes(), signature, signer.NodeID(), activation.PoetPoW{ + poetRound, err := client.Submit(context.Background(), time.Time{}, prefix, ch.Bytes(), signature, signer.NodeID(), activation.PoetPoW{ Nonce: nonce, Params: *resp, }) r.NoError(err) r.NotNil(poetRound) } + +func TestSubmitTooLate(t *testing.T) { + t.Parallel() + r := require.New(t) + + var eg errgroup.Group + poetDir := t.TempDir() + t.Cleanup(func() { r.NoError(eg.Wait()) }) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + c, err := NewHTTPPoetTestHarness(ctx, poetDir) + r.NoError(err) + r.NotNil(c) + + eg.Go(func() error { + err := c.Service.Start(ctx) + return errors.Join(err, c.Service.Close()) + }) + + client, err := activation.NewHTTPPoetClient(c.RestURL().String(), activation.DefaultPoetConfig(), activation.WithLogger(zaptest.NewLogger(t))) + require.NoError(t, err) + + resp, err := client.PowParams(context.Background()) + r.NoError(err) + + signer, err := signing.NewEdSigner(signing.WithPrefix([]byte("prefix"))) + require.NoError(t, err) + ch := types.RandomHash() + + nonce, err := shared.FindSubmitPowNonce( + context.Background(), + resp.Challenge, + ch.Bytes(), + signer.NodeID().Bytes(), + uint(resp.Difficulty), + ) + r.NoError(err) + + signature := signer.Sign(signing.POET, ch.Bytes()) + prefix := bytes.Join([][]byte{signer.Prefix(), {byte(signing.POET)}}, nil) + + _, err = client.Submit(context.Background(), time.Now(), prefix, ch.Bytes(), signature, signer.NodeID(), activation.PoetPoW{ + Nonce: nonce, + Params: *resp, + }) + r.ErrorIs(err, activation.ErrInvalidRequest) +} diff --git a/activation/nipost_test.go b/activation/nipost_test.go index b57bdfa7cb5..5b806489ebd 100644 --- a/activation/nipost_test.go +++ b/activation/nipost_test.go @@ -355,121 +355,6 @@ func TestNIPostBuilder_ManyPoETs_SubmittingChallenge_DeadlineReached(t *testing. req.EqualValues(ref[:], nipost.PostMetadata.Challenge) } -func TestNIPostBuilder_PoetInvalidRequest(t *testing.T) { - t.Parallel() - // Arrange - req := require.New(t) - challenge := types.NIPostChallenge{ - PublishEpoch: postGenesisEpoch + 1, - } - - ctrl := gomock.NewController(t) - - poet := NewMockPoetProvingServiceClient(ctrl) - poet.EXPECT().PoetServiceID(gomock.Any()).AnyTimes().Return(types.PoetServiceID{ServiceID: []byte("poet0")}, nil) - poet.EXPECT().Submit(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&types.PoetRound{}, ErrInvalidRequest) - poet.EXPECT().PowParams(gomock.Any()).Return(&PoetPowParams{}, nil) - poet.EXPECT().Address().Return("http://localhost:9999") - - sig, err := signing.NewEdSigner() - req.NoError(err) - postProvider := NewMockpostSetupProvider(ctrl) - postProvider.EXPECT().Status().Return(&PostSetupStatus{State: PostSetupStateComplete}) - postProvider.EXPECT().CommitmentAtx().Return(types.EmptyATXID, nil).AnyTimes() - postProvider.EXPECT().LastOpts().Return(&PostSetupOpts{}).AnyTimes() - - nb, err := NewNIPostBuilder( - types.NodeID{1}, - postProvider, - NewMockpoetDbAPI(ctrl), - []string{}, - t.TempDir(), - logtest.New(t), - sig, - PoetConfig{PhaseShift: layerDuration * layersPerEpoch / 2}, - defaultLayerClockMock(t), - WithNipostValidator(NewMocknipostValidator(ctrl)), - withPoetClients([]PoetProvingServiceClient{poet}), - ) - req.NoError(err) - - // Act - _, err = nb.BuildNIPost(context.Background(), &challenge) - req.ErrorIs(err, ErrATXChallengeExpired) -} - -func TestNIPostBuilder_OnePoetInvalidRequest(t *testing.T) { - t.Parallel() - // Arrange - req := require.New(t) - challenge := types.NIPostChallenge{ - PublishEpoch: postGenesisEpoch + 1, - } - - proof := &types.PoetProofMessage{PoetProof: types.PoetProof{}} - - ctrl := gomock.NewController(t) - nipostValidator := NewMocknipostValidator(ctrl) - poetDb := NewMockpoetDbAPI(ctrl) - poetDb.EXPECT().ValidateAndStore(gomock.Any(), gomock.Any()).Return(nil) - - poets := make([]PoetProvingServiceClient, 0, 2) - { - poet := NewMockPoetProvingServiceClient(ctrl) - poet.EXPECT().PoetServiceID(gomock.Any()).AnyTimes().Return(types.PoetServiceID{ServiceID: []byte("poet0")}, nil) - poet.EXPECT().Submit(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&types.PoetRound{}, ErrInvalidRequest) - poet.EXPECT().PowParams(gomock.Any()).Return(&PoetPowParams{}, nil) - poet.EXPECT().Address().Return("http://localhost:9999") - poets = append(poets, poet) - } - { - poet := NewMockPoetProvingServiceClient(ctrl) - poet.EXPECT().PoetServiceID(gomock.Any()).AnyTimes().Return(types.PoetServiceID{ServiceID: []byte("poet1")}, nil) - poet.EXPECT().Submit(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&types.PoetRound{}, nil) - poet.EXPECT().Proof(gomock.Any(), gomock.Any()).Return(proof, []types.Member{types.Member(challenge.Hash())}, nil) - poet.EXPECT().PowParams(gomock.Any()).Return(&PoetPowParams{}, nil) - poet.EXPECT().Address().Return("http://localhost:9998") - poets = append(poets, poet) - } - - sig, err := signing.NewEdSigner() - req.NoError(err) - postProvider := NewMockpostSetupProvider(ctrl) - postProvider.EXPECT().Status().Return(&PostSetupStatus{State: PostSetupStateComplete}) - postProvider.EXPECT().CommitmentAtx().Return(types.EmptyATXID, nil).AnyTimes() - postProvider.EXPECT().LastOpts().Return(&PostSetupOpts{}).AnyTimes() - postProvider.EXPECT().GenerateProof(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( - func(ctx context.Context, challenge []byte, _ ...proving.OptionFunc) (*types.Post, *types.PostMetadata, error) { - return &types.Post{}, &types.PostMetadata{ - Challenge: challenge, - }, nil - }, - ) - nipostValidator.EXPECT().Post(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(nil) - nb, err := NewNIPostBuilder( - types.NodeID{1}, - postProvider, - poetDb, - []string{}, - t.TempDir(), - logtest.New(t), - sig, - PoetConfig{PhaseShift: layerDuration * layersPerEpoch / 2}, - defaultLayerClockMock(t), - WithNipostValidator(nipostValidator), - withPoetClients(poets), - ) - req.NoError(err) - - // Act - nipost, err := nb.BuildNIPost(context.Background(), &challenge) - req.NoError(err) - - // Verify - ref, _ := proof.Ref() - req.EqualValues(ref[:], nipost.PostMetadata.Challenge) -} - func TestNIPostBuilder_ManyPoETs_AllFinished(t *testing.T) { t.Parallel() // Arrange diff --git a/activation/post_test.go b/activation/post_test.go index 605c82fc322..7820751dee6 100644 --- a/activation/post_test.go +++ b/activation/post_test.go @@ -10,6 +10,7 @@ import ( "github.com/spacemeshos/post/config" "github.com/spacemeshos/post/initialization" "github.com/spacemeshos/post/shared" + "github.com/spacemeshos/post/verifying" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" "golang.org/x/sync/errgroup" @@ -220,6 +221,53 @@ func TestPostSetupManager_InitialStatus(t *testing.T) { req.Zero(status.NumLabelsWritten) } +func TestPostSetupManager_GenerateProof(t *testing.T) { + req := require.New(t) + ch := make([]byte, 32) + + mgr := newTestPostManager(t) + + // Attempt to generate proof. + _, _, err := mgr.GenerateProof(context.Background(), ch) + req.EqualError(err, errNotComplete.Error()) + + // Create data. + req.NoError(mgr.PrepareInitializer(context.Background(), mgr.opts)) + req.NoError(mgr.StartSession(context.Background())) + + // Generate proof. + p, m, err := mgr.GenerateProof(context.Background(), ch) + req.NoError(err) + + // Verify the proof + verifier, err := verifying.NewProofVerifier() + req.NoError(err) + defer verifier.Close() + err = verifier.Verify(&shared.Proof{ + Nonce: p.Nonce, + Indices: p.Indices, + Pow: p.Pow, + }, &shared.ProofMetadata{ + NodeId: mgr.id.Bytes(), + CommitmentAtxId: mgr.goldenATXID.Bytes(), + Challenge: ch, + NumUnits: mgr.opts.NumUnits, + LabelsPerUnit: m.LabelsPerUnit, + }, + config.DefaultConfig(), + logtest.New(t).WithName("verifying").Zap(), + verifying.WithLabelScryptParams(mgr.opts.Scrypt), + ) + req.NoError(err) + + // Re-instantiate `PostSetupManager`. + mgr = newTestPostManager(t) + + // Attempt to generate proof. + _, _, err = mgr.GenerateProof(context.Background(), ch) + req.ErrorIs(err, errNotComplete) +} + func TestPostSetupManager_VRFNonce(t *testing.T) { req := require.New(t) @@ -408,7 +456,6 @@ type testPostManager struct { cdb *datastore.CachedDB } -// TODO(mafa): start post service with supervisor. func newTestPostManager(tb testing.TB) *testPostManager { tb.Helper()