Skip to content

Commit

Permalink
Fix failing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fasmat committed Oct 5, 2023
1 parent b2fb3fe commit 582b03c
Show file tree
Hide file tree
Showing 19 changed files with 606 additions and 437 deletions.
315 changes: 315 additions & 0 deletions activation/nipost_integration_test.go.bak
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
package activation_test

import (
"context"
"errors"
"os"
"testing"
"time"

"github.com/spacemeshos/poet/logging"
"github.com/spacemeshos/post/config"
"github.com/spacemeshos/post/initialization"
"github.com/stretchr/testify/require"
"github.com/zeebo/assert"
"go.uber.org/mock/gomock"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.uber.org/zap/zaptest"
"golang.org/x/sync/errgroup"

"github.com/spacemeshos/go-spacemesh/activation"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/datastore"
"github.com/spacemeshos/go-spacemesh/log/logtest"
"github.com/spacemeshos/go-spacemesh/signing"
"github.com/spacemeshos/go-spacemesh/sql"
)

const (
layersPerEpoch = 10
layerDuration = time.Second
postGenesisEpoch types.EpochID = 2
)

func TestMain(m *testing.M) {
types.SetLayersPerEpoch(layersPerEpoch)
res := m.Run()
os.Exit(res)
}

func initPost(tb testing.TB, log *zap.Logger, dir string) {
tb.Helper()

cfg := activation.DefaultPostConfig()

sig, err := signing.NewEdSigner()
require.NoError(tb, err)
id := sig.NodeID()

opts := activation.DefaultPostSetupOpts()
opts.DataDir = dir
opts.ProviderID.SetInt64(int64(initialization.CPUProviderID()))
opts.Scrypt.N = 2 // Speedup initialization in tests.

goldenATXID := types.ATXID{2, 3, 4}

cdb := datastore.NewCachedDB(sql.InMemory(), logtest.New(tb))
provingOpts := activation.DefaultPostProvingOpts()
provingOpts.Flags = config.RecommendedPowFlags()
mgr, err := activation.NewPostSetupManager(id, cfg, log.Named("manager"), cdb, goldenATXID, provingOpts)
require.NoError(tb, err)

ctx, cancel := context.WithCancel(context.Background())
tb.Cleanup(cancel)

var eg errgroup.Group
lastStatus := &activation.PostSetupStatus{}
eg.Go(func() error {
timer := time.NewTicker(50 * time.Millisecond)
defer timer.Stop()

for {
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
status := mgr.Status()
require.GreaterOrEqual(tb, status.NumLabelsWritten, lastStatus.NumLabelsWritten)

if status.NumLabelsWritten == uint64(opts.NumUnits)*cfg.LabelsPerUnit {
return nil
}
require.Equal(tb, activation.PostSetupStateInProgress, status.State)
}
}
})

// Create data.
require.NoError(tb, mgr.PrepareInitializer(context.Background(), opts))
require.NoError(tb, mgr.StartSession(context.Background()))
require.NoError(tb, eg.Wait())
require.Equal(tb, activation.PostSetupStateComplete, mgr.Status().State)
}

func spawnPoet(tb testing.TB, opts ...HTTPPoetOpt) *HTTPPoetTestHarness {
tb.Helper()
ctx, cancel := context.WithCancel(logging.NewContext(context.Background(), zaptest.NewLogger(tb)))

poetProver, err := NewHTTPPoetTestHarness(ctx, tb.TempDir(), opts...)
require.NoError(tb, err)
require.NotNil(tb, poetProver)

var eg errgroup.Group
tb.Cleanup(func() {
cancel()
eg.Wait()
})
eg.Go(func() error {
err := poetProver.Service.Start(ctx)
return errors.Join(err, poetProver.Service.Close())
})

return poetProver
}

// TODO(mafa): start post service with supervisor.
func buildNIPost(tb testing.TB, postProvider *testPostManager, nipostChallenge types.NIPostChallenge, poetDb poetDbAPI, validator nipostValidator) *types.NIPost {
require.NoError(tb, postProvider.PrepareInitializer(context.Background(), postProvider.opts))
require.NoError(tb, postProvider.StartSession(context.Background()))
mclock := activation.NewMocklayerClock(gomock.NewController(tb))
mclock.EXPECT().LayerToTime(gomock.Any()).AnyTimes().DoAndReturn(
func(got types.LayerID) time.Time {
// time.Now() ~= currentLayer
genesis := time.Now().Add(-time.Duration(postGenesisEpoch.FirstLayer()) * layerDuration)
return genesis.Add(layerDuration * time.Duration(got))
},
)

epoch := layersPerEpoch * layerDuration
poetCfg := activation.PoetConfig{
PhaseShift: epoch / 2,
CycleGap: epoch / 5,
GracePeriod: epoch / 5,
RequestTimeout: epoch / 5,
RequestRetryDelay: epoch / 50,
MaxRequestRetries: 10,
}

poetProver := spawnPoet(tb, WithGenesis(time.Now()), WithEpochDuration(epoch), WithPhaseShift(poetCfg.PhaseShift), WithCycleGap(poetCfg.CycleGap))

signer, err := signing.NewEdSigner()
require.NoError(tb, err)
nb, err := activation.NewNIPostBuilder(
postProvider.id,
postProvider,
poetDb,
[]string{poetProver.RestURL().String()},
tb.TempDir(),
logtest.New(tb, zapcore.DebugLevel),
signer,
poetCfg,
mclock,
activation.WithNipostValidator(validator),
)
require.NoError(tb, err)
nipost, err := nb.BuildNIPost(context.Background(), &nipostChallenge)
require.NoError(tb, err)
return nipost
}

func TestNIPostBuilderWithClients(t *testing.T) {
challenge := types.NIPostChallenge{
PublishEpoch: postGenesisEpoch + 2,
}
poetDb := activation.NewPoetDb(sql.InMemory(), logtest.New(t).WithName("poetDb"))
postCfg := activation.DefaultPostConfig()
postCfg.PowDifficulty[0] = 1
postProvider := newTestPostManager(t, withPostConfig(postCfg))
verifier, err := activation.NewPostVerifier(postProvider.Config(), zaptest.NewLogger(t).Named("verifier"))
require.NoError(t, err)
defer verifier.Close()

v := activation.NewValidator(poetDb, postProvider.Config(), postProvider.opts.Scrypt, verifier)
nipost := buildNIPost(t, postProvider, challenge, poetDb, v)
_, err = v.NIPost(
context.Background(),
postProvider.id,
postProvider.commitmentAtxId,
nipost,
challenge.Hash(),
postProvider.opts.NumUnits,
)
require.NoError(t, err)
}

func TestNIPostBuilder_Close(t *testing.T) {
t.Parallel()
r := require.New(t)

ctrl := gomock.NewController(t)
nipostClient := activation.NewMocknipostClient(ctrl)
nipostClient.EXPECT().Status().Return(&activation.PostSetupStatus{State: activation.PostSetupStateComplete})
poetProver := spawnPoet(t, WithGenesis(time.Now()), WithEpochDuration(time.Second))
poetDb := activation.NewMockpoetDbAPI(ctrl)
challenge := types.NIPostChallenge{
PublishEpoch: postGenesisEpoch + 2,
}
mclock := activation.NewMocklayerClock(gomock.NewController(t))
mclock.EXPECT().LayerToTime(gomock.Any()).AnyTimes().DoAndReturn(
func(got types.LayerID) time.Time {
// time.Now() ~= currentLayer
genesis := time.Now().Add(-time.Duration(postGenesisEpoch.FirstLayer()) * layerDuration)
return genesis.Add(layerDuration * time.Duration(got))
},
)

sig, err := signing.NewEdSigner()
r.NoError(err)
nb, err := activation.NewNIPostBuilder(
types.NodeID{1},
nipostClient,
poetDb,
[]string{poetProver.RestURL().String()},
t.TempDir(),
logtest.New(t),
sig,
activation.PoetConfig{},
mclock,
)
r.NoError(err)

ctx, cancel := context.WithCancel(context.Background())
cancel()
nipost, err := nb.BuildNIPost(ctx, &challenge)
r.ErrorIs(err, context.Canceled)
r.Nil(nipost)
}

func TestNewNIPostBuilderNotInitialized(t *testing.T) {
r := require.New(t)

challenge := types.NIPostChallenge{
PublishEpoch: postGenesisEpoch + 2,
}
challengeHash := challenge.Hash()

postProvider := newTestPostManager(t)

epoch := layersPerEpoch * layerDuration
poetCfg := activation.PoetConfig{
PhaseShift: epoch / 5,
CycleGap: epoch / 10,
GracePeriod: epoch / 10,
RequestTimeout: epoch / 10,
RequestRetryDelay: epoch / 100,
MaxRequestRetries: 10,
}

poetClient := activation.NewMockPoetProvingServiceClient(gomock.NewController(t))
poetClient.EXPECT().Submit(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&types.PoetRound{}, nil)
poetClient.EXPECT().PoetServiceID(gomock.Any()).Return(types.PoetServiceID{ServiceID: []byte("poet")}, nil)
poetClient.EXPECT().PowParams(gomock.Any()).Return(&activation.PoetPowParams{}, nil)
poetClient.EXPECT().Address().Return("http://localhost:9999")
poetClient.EXPECT().Proof(gomock.Any(), "").Return(&types.PoetProofMessage{
PoetProof: types.PoetProof{},
}, []types.Member{types.Member(challenge.Hash())}, nil)

ctrl := gomock.NewController(t)
poetDb := activation.NewMockpoetDbAPI(ctrl)
poetDb.EXPECT().GetProof(gomock.Any()).Return(
&types.PoetProof{}, &challengeHash, nil,
)
poetDb.EXPECT().ValidateAndStore(gomock.Any(), gomock.Any()).Return(nil)
mclock := activation.NewMocklayerClock(gomock.NewController(t))
mclock.EXPECT().LayerToTime(gomock.Any()).AnyTimes().DoAndReturn(
func(got types.LayerID) time.Time {
// time.Now() ~= currentLayer
genesis := time.Now().Add(-time.Duration(postGenesisEpoch.FirstLayer()) * layerDuration)
return genesis.Add(layerDuration * time.Duration(got))
},
)

nipostValidator := activation.NewMocknipostValidator(ctrl)
nipostValidator.EXPECT().Post(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(nil)

nb, err := activation.NewNIPostBuilder(
postProvider.id,
postProvider,
poetDb,
[]string{},
t.TempDir(),
logtest.New(t),
postProvider.signer,
poetCfg,
mclock,
activation.WithNipostValidator(nipostValidator),
withPoetClients([]activation.PoetProvingServiceClient{poetProvider}),
)
require.NoError(t, err)

nipost, err := nb.BuildNIPost(context.Background(), &challenge)
r.EqualError(err, "post setup not complete")
r.Nil(nipost)

r.NoError(postProvider.PrepareInitializer(context.Background(), postProvider.opts))
r.NoError(postProvider.StartSession(context.Background()))

nipost, err = nb.BuildNIPost(context.Background(), &challenge)
r.NoError(err)
r.NotNil(nipost)

verifier, err := activation.NewPostVerifier(postProvider.cfg, zaptest.NewLogger(t).Named("verifier"))
r.NoError(err)
t.Cleanup(func() { assert.NoError(t, verifier.Close()) })
v := activation.NewValidator(poetDb, postProvider.cfg, postProvider.opts.Scrypt, verifier)
_, err = v.NIPost(
context.Background(),
postProvider.id,
postProvider.goldenATXID,
nipost,
challenge.Hash(),
postProvider.opts.NumUnits,
)
r.NoError(err)
}
Loading

0 comments on commit 582b03c

Please sign in to comment.