From 377a8c14c0461fb552bf2ec15c2c20dc8f9bde6e Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 15 Jul 2024 02:31:42 +0200 Subject: [PATCH 01/26] fixed timeouts --- activation/activation.go | 40 +++++++++---- activation/nipost.go | 5 +- activation/poet.go | 31 +++++----- activation/poet_client_test.go | 56 ++++++++++++------- cmd/root.go | 14 +++-- config/mainnet.go | 23 +++++--- config/presets/fastnet.go | 4 +- config/presets/standalone.go | 4 +- .../distributed_post_verification_test.go | 4 +- 9 files changed, 117 insertions(+), 64 deletions(-) diff --git a/activation/activation.go b/activation/activation.go index dfd58f455f..9fae5b2c65 100644 --- a/activation/activation.go +++ b/activation/activation.go @@ -39,21 +39,40 @@ var ( // PoetConfig is the configuration to interact with the poet server. type PoetConfig struct { - PhaseShift time.Duration `mapstructure:"phase-shift"` - CycleGap time.Duration `mapstructure:"cycle-gap"` - GracePeriod time.Duration `mapstructure:"grace-period"` - RequestTimeout time.Duration `mapstructure:"poet-request-timeout"` - RequestRetryDelay time.Duration `mapstructure:"retry-delay"` + ClientConfig + RegistrationConfig +} + +type ClientConfig struct { + DefaultRequestTimeout time.Duration `mapstructure:"poet-client-default-request-timeout"` + RequestRetryDelay time.Duration `mapstructure:"poet-client-retry-delay"` + CertifierInfoCacheTTL time.Duration `mapstructure:"poet-client-certifier-info-cache-ttl"` + MaxRequestRetries int `mapstructure:"poet-client-retry-max"` +} + +// RegistrationConfig sets up settings for successful registration to new PoET round +type RegistrationConfig struct { + // Start of new PoET round + PhaseShift time.Duration `mapstructure:"phase-shift"` + // A gap between end of old PoET round and start of new one + CycleGap time.Duration `mapstructure:"cycle-gap"` + // Time in the end of cycle gap, when PoST challenge must be build and send to PoET server + GracePeriod time.Duration `mapstructure:"grace-period"` + // Period to find positioning ATX. Must be less, than GracePeriod PositioningATXSelectionTimeout time.Duration `mapstructure:"positioning-atx-selection-timeout"` - CertifierInfoCacheTTL time.Duration `mapstructure:"certifier-info-cache-ttl"` - MaxRequestRetries int `mapstructure:"retry-max"` + // Period to submit PoST challenge to PoET server. Must be not greater than GracePeriod + SubmitChallengeTimeout time.Duration `mapstructure:"submit-challenge-timeout"` + // Period to get PoET proof + GetProofTimeout time.Duration `mapstructure:"get-proof-timeout"` } func DefaultPoetConfig() PoetConfig { return PoetConfig{ - RequestRetryDelay: 400 * time.Millisecond, - MaxRequestRetries: 10, - CertifierInfoCacheTTL: 5 * time.Minute, + ClientConfig: ClientConfig{ + RequestRetryDelay: 400 * time.Millisecond, + MaxRequestRetries: 10, + CertifierInfoCacheTTL: 5 * time.Minute, + }, } } @@ -547,7 +566,6 @@ func (b *Builder) BuildNIPostChallenge(ctx context.Context, nodeID types.NodeID) case <-time.After(time.Until(wait)): } } - if b.poetCfg.PositioningATXSelectionTimeout > 0 { var cancel context.CancelFunc diff --git a/activation/nipost.go b/activation/nipost.go index 3ee0b17b65..6366c685b8 100644 --- a/activation/nipost.go +++ b/activation/nipost.go @@ -281,7 +281,7 @@ func (nb *NIPostBuilder) BuildNIPost( } events.EmitPoetWaitProof(signer.NodeID(), postChallenge.PublishEpoch, poetRoundEnd) - poetProofRef, membership, err = nb.getBestProof(ctx, signer.NodeID(), challenge, postChallenge.PublishEpoch) + poetProofRef, membership, err = nb.getBestProof(ctx, signer.NodeID(), challenge) if err != nil { return nil, &PoetSvcUnstableError{msg: "getBestProof failed", source: err} } @@ -372,7 +372,7 @@ func (nb *NIPostBuilder) submitPoetChallenge( logger.Debug("submitting challenge to poet proving service") - submitCtx, cancel := withConditionalTimeout(ctx, nb.poetCfg.RequestTimeout) + submitCtx, cancel := withConditionalTimeout(ctx, nb.poetCfg.SubmitChallengeTimeout) defer cancel() round, err := client.Submit(submitCtx, deadline, prefix, challenge, signature, nodeID) @@ -451,7 +451,6 @@ func (nb *NIPostBuilder) getBestProof( ctx context.Context, nodeID types.NodeID, challenge types.Hash32, - publishEpoch types.EpochID, ) (types.PoetProofRef, *types.MerkleProof, error) { type poetProof struct { poet *types.PoetProof diff --git a/activation/poet.go b/activation/poet.go index 174e3b66c1..10ebb82327 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -340,10 +340,13 @@ type certifierInfo struct { // poetService is a higher-level interface to communicate with a PoET service. // It wraps the HTTP client, adding additional functionality. type poetService struct { - db poetDbAPI - logger *zap.Logger - client PoetClient - requestTimeout time.Duration + db poetDbAPI + logger *zap.Logger + client PoetClient + + defaultRequestTimeout time.Duration + submitChallengeRequestTimeout time.Duration + getProofRequestTimeout time.Duration // Used to avoid concurrent requests for proof. gettingProof sync.Mutex @@ -393,12 +396,14 @@ 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, + defaultRequestTimeout: cfg.DefaultRequestTimeout, + submitChallengeRequestTimeout: cfg.SubmitChallengeTimeout, + getProofRequestTimeout: cfg.GetProofTimeout, + certifierInfoTTL: cfg.CertifierInfoCacheTTL, + proofMembers: make(map[string][]types.Hash32, 1), } for _, opt := range opts { @@ -432,7 +437,7 @@ func (c *poetService) authorize( // TODO: remove this fallback once we migrate to certificates fully. logger.Debug("querying for poet pow parameters") - powCtx, cancel := withConditionalTimeout(ctx, c.requestTimeout) + powCtx, cancel := withConditionalTimeout(ctx, c.defaultRequestTimeout) defer cancel() powParams, err := c.client.PowParams(powCtx) if err != nil { @@ -480,7 +485,7 @@ func (c *poetService) Submit( logger.Debug("submitting challenge to poet proving service") - submitCtx, cancel := withConditionalTimeout(ctx, c.requestTimeout) + submitCtx, cancel := withConditionalTimeout(ctx, c.submitChallengeRequestTimeout) defer cancel() round, err := c.client.Submit(submitCtx, deadline, prefix, challenge, signature, nodeID, *auth) switch { @@ -498,7 +503,7 @@ func (c *poetService) Submit( } func (c *poetService) Proof(ctx context.Context, roundID string) (*types.PoetProof, []types.Hash32, error) { - getProofsCtx, cancel := withConditionalTimeout(ctx, c.requestTimeout) + getProofsCtx, cancel := withConditionalTimeout(ctx, c.getProofRequestTimeout) defer cancel() c.gettingProof.Lock() diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index 6b8e5126f6..4aee683312 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -30,20 +30,25 @@ func Test_HTTPPoetClient_ParsesURL(t *testing.T) { t.Run("add http if missing", func(t *testing.T) { t.Parallel() - client, err := NewHTTPPoetClient(types.PoetServer{Address: "bla"}, PoetConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, - }) + client, err := NewHTTPPoetClient(types.PoetServer{Address: "bla"}, + PoetConfig{ + RegistrationConfig: RegistrationConfig{ + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap}, + }) require.NoError(t, err) require.Equal(t, "http://bla", client.baseURL.String()) }) t.Run("do not change scheme if present", func(t *testing.T) { t.Parallel() - client, err := NewHTTPPoetClient(types.PoetServer{Address: "https://bla"}, PoetConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, - }) + client, err := NewHTTPPoetClient(types.PoetServer{Address: "https://bla"}, + PoetConfig{ + RegistrationConfig: RegistrationConfig{ + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, + }, + }) require.NoError(t, err) require.Equal(t, "https://bla", client.baseURL.String()) }) @@ -65,8 +70,10 @@ func Test_HTTPPoetClient_Submit(t *testing.T) { cfg := server.DefaultRoundConfig() client, err := NewHTTPPoetClient(types.PoetServer{Address: ts.URL}, PoetConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, + RegistrationConfig: RegistrationConfig{ + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, + }, }, withCustomHttpClient(ts.Client())) require.NoError(t, err) @@ -113,10 +120,13 @@ func Test_HTTPPoetClient_Address_Mainnet(t *testing.T) { for _, url := range poETServers { t.Run(url, func(t *testing.T) { - client, err := NewHTTPPoetClient(types.PoetServer{Address: url}, PoetConfig{ - PhaseShift: poetCfg.PhaseShift, - CycleGap: poetCfg.CycleGap, - }) + client, err := NewHTTPPoetClient(types.PoetServer{Address: url}, + PoetConfig{ + RegistrationConfig: RegistrationConfig{ + PhaseShift: poetCfg.PhaseShift, + CycleGap: poetCfg.CycleGap, + }, + }) require.NoError(t, err) require.Equal(t, url, client.Address()) }) @@ -139,8 +149,10 @@ func Test_HTTPPoetClient_Proof(t *testing.T) { cfg := server.DefaultRoundConfig() client, err := NewHTTPPoetClient(types.PoetServer{Address: ts.URL}, PoetConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, + RegistrationConfig: RegistrationConfig{ + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, + }, }, withCustomHttpClient(ts.Client())) require.NoError(t, err) @@ -209,7 +221,9 @@ func TestPoetClient_QueryProofTimeout(t *testing.T) { Pubkey: types.NewBase64Enc([]byte("pubkey")), } cfg := PoetConfig{ - RequestTimeout: time.Millisecond * 100, + ClientConfig: ClientConfig{ + DefaultRequestTimeout: time.Millisecond * 100, + }, } client, err := NewHTTPPoetClient(server, cfg, withCustomHttpClient(ts.Client())) require.NoError(t, err) @@ -225,7 +239,7 @@ func TestPoetClient_QueryProofTimeout(t *testing.T) { }) } eg.Wait() - require.WithinDuration(t, start.Add(cfg.RequestTimeout), time.Now(), time.Millisecond*300) + require.WithinDuration(t, start.Add(cfg.DefaultRequestTimeout), time.Now(), time.Millisecond*300) } func TestPoetClient_Certify(t *testing.T) { @@ -253,7 +267,7 @@ func TestPoetClient_Certify(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{RequestTimeout: time.Millisecond * 100} + cfg := PoetConfig{ClientConfig: ClientConfig{DefaultRequestTimeout: time.Millisecond * 100}} cert := certifier.PoetCert{Data: []byte("abc")} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) @@ -299,7 +313,7 @@ func TestPoetClient_ObtainsCertOnSubmit(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{RequestTimeout: time.Millisecond * 100} + cfg := PoetConfig{ClientConfig: ClientConfig{DefaultRequestTimeout: time.Millisecond * 100}} cert := certifier.PoetCert{Data: []byte("abc")} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) @@ -358,7 +372,7 @@ func TestPoetClient_RecertifiesOnAuthFailure(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{RequestTimeout: time.Millisecond * 100} + cfg := PoetConfig{ClientConfig: ClientConfig{DefaultRequestTimeout: time.Millisecond * 100}} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) diff --git a/cmd/root.go b/cmd/root.go index 5d8409cfad..1f7f0d3997 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -320,13 +320,17 @@ func AddFlags(flagSet *pflag.FlagSet, cfg *config.Config) (configPath *string) { /**======================== PoET Flags ========================== **/ flagSet.DurationVar(&cfg.POET.PhaseShift, "phase-shift", - cfg.POET.PhaseShift, "phase shift of poet server") + cfg.POET.PhaseShift, "phase shift of poet server: time, when poet round starts") flagSet.DurationVar(&cfg.POET.CycleGap, "cycle-gap", - cfg.POET.CycleGap, "cycle gap of poet server") + cfg.POET.CycleGap, "cycle gap of poet server: gap between poet rounds") flagSet.DurationVar(&cfg.POET.GracePeriod, "grace-period", - cfg.POET.GracePeriod, "time before PoET round starts when the node builds and submits a challenge") - flagSet.DurationVar(&cfg.POET.RequestTimeout, "poet-request-timeout", - cfg.POET.RequestTimeout, "timeout for poet requests") + cfg.POET.GracePeriod, "time before poet round starts, when the node builds and submits a challenge") + flagSet.DurationVar(&cfg.POET.SubmitChallengeTimeout, "submit-challenge-timeout", + cfg.POET.SubmitChallengeTimeout, "time within grace period, when post challenge must be submitted to poet server") + flagSet.DurationVar(&cfg.POET.GetProofTimeout, "get-proof-timeout", + cfg.POET.GetProofTimeout, "time period when ready poet proof must be fetched") + flagSet.DurationVar(&cfg.POET.DefaultRequestTimeout, "poet-default-request-timeout", + cfg.POET.DefaultRequestTimeout, "default timeout for poet requests") /**======================== bootstrap data updater Flags ========================== **/ diff --git a/config/mainnet.go b/config/mainnet.go index 40b123edba..d01fa1e24f 100644 --- a/config/mainnet.go +++ b/config/mainnet.go @@ -160,14 +160,21 @@ func MainnetConfig() Config { BeaconSyncWeightUnits: 800, }, POET: activation.PoetConfig{ - PhaseShift: 240 * time.Hour, - CycleGap: 12 * time.Hour, - GracePeriod: 1 * time.Hour, - PositioningATXSelectionTimeout: 50 * time.Minute, - // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - RequestTimeout: 1100 * time.Second, - RequestRetryDelay: 10 * time.Second, - MaxRequestRetries: 10, + ClientConfig: activation.ClientConfig{ + // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + DefaultRequestTimeout: 1100 * time.Second, + RequestRetryDelay: 10 * time.Second, + MaxRequestRetries: 10, + }, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: 240 * time.Hour, + CycleGap: 12 * time.Hour, + GracePeriod: 1 * time.Hour, + SubmitChallengeTimeout: 1 * time.Hour, + PositioningATXSelectionTimeout: 50 * time.Minute, + // GetProofTimeout = DefaultRequestTimeout + GetProofTimeout: 1100 * time.Second, // ~ 18 min + }, }, POST: activation.PostConfig{ MinNumUnits: 4, diff --git a/config/presets/fastnet.go b/config/presets/fastnet.go index de09ac0d19..a83ec65201 100644 --- a/config/presets/fastnet.go +++ b/config/presets/fastnet.go @@ -92,9 +92,11 @@ func fastnet() config.Config { conf.Beacon.VotesLimit = 100 conf.POET.GracePeriod = 10 * time.Second + conf.POET.SubmitChallengeTimeout = 10 * time.Second + conf.POET.GetProofTimeout = 12 * time.Second // equal to DefaultRequestTimeout conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.RequestTimeout = 12 * time.Second // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + conf.POET.DefaultRequestTimeout = 12 * time.Second // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestRetryDelay = 1 * time.Second conf.POET.MaxRequestRetries = 3 return conf diff --git a/config/presets/standalone.go b/config/presets/standalone.go index 290b615971..1bba75015e 100644 --- a/config/presets/standalone.go +++ b/config/presets/standalone.go @@ -80,7 +80,9 @@ func standalone() config.Config { conf.POET.GracePeriod = 12 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.RequestTimeout = 12 * time.Second // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + conf.POET.GetProofTimeout = 12 * time.Second // equal to DefaultRequestTimeout + conf.POET.SubmitChallengeTimeout = 12 * time.Second + conf.POET.DefaultRequestTimeout = 12 * time.Second // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestRetryDelay = 1 * time.Second conf.POET.MaxRequestRetries = 3 diff --git a/systest/tests/distributed_post_verification_test.go b/systest/tests/distributed_post_verification_test.go index a719fc6145..df7e2ab5c7 100644 --- a/systest/tests/distributed_post_verification_test.go +++ b/systest/tests/distributed_post_verification_test.go @@ -64,7 +64,9 @@ func TestPostMalfeasanceProof(t *testing.T) { cfg.P2P.DataDir = filepath.Join(testDir, "p2p-dir") require.NoError(t, os.Mkdir(cfg.P2P.DataDir, os.ModePerm)) - cfg.POET.RequestTimeout = time.Minute + cfg.POET.DefaultRequestTimeout = time.Minute + cfg.POET.GetProofTimeout = time.Minute + cfg.POET.SubmitChallengeTimeout = time.Minute cfg.POET.MaxRequestRetries = 10 var bootnodes []*cluster.NodeClient From d12209475165f8fd518a37d8b17397e4ef810184 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 15 Jul 2024 03:25:58 +0200 Subject: [PATCH 02/26] fix tests + make linter happy --- activation/activation.go | 2 +- activation/activation_multi_test.go | 13 +++++- activation/activation_test.go | 59 +++++++++++++++++------- activation/builder_v2_test.go | 4 +- activation/e2e/activation_test.go | 18 +++++--- activation/e2e/atx_merge_test.go | 8 ++-- activation/e2e/builds_atx_v2_test.go | 8 ++-- activation/e2e/checkpoint_merged_test.go | 8 ++-- activation/e2e/checkpoint_test.go | 8 ++-- activation/e2e/nipost_test.go | 16 ++++--- activation/e2e/validation_test.go | 8 ++-- activation/nipost_test.go | 8 ++-- activation/poet_client_test.go | 3 +- cmd/root.go | 3 +- config/presets/fastnet.go | 3 +- config/presets/standalone.go | 3 +- config/presets/testnet.go | 19 +++++--- 17 files changed, 129 insertions(+), 62 deletions(-) diff --git a/activation/activation.go b/activation/activation.go index 9fae5b2c65..842c1ca5d7 100644 --- a/activation/activation.go +++ b/activation/activation.go @@ -50,7 +50,7 @@ type ClientConfig struct { MaxRequestRetries int `mapstructure:"poet-client-retry-max"` } -// RegistrationConfig sets up settings for successful registration to new PoET round +// RegistrationConfig sets up settings for successful registration to new PoET round. type RegistrationConfig struct { // Start of new PoET round PhaseShift time.Duration `mapstructure:"phase-shift"` diff --git a/activation/activation_multi_test.go b/activation/activation_multi_test.go index ce795e53b5..b5e3198699 100644 --- a/activation/activation_multi_test.go +++ b/activation/activation_multi_test.go @@ -232,7 +232,10 @@ func TestRegossip(t *testing.T) { } func Test_Builder_Multi_InitialPost(t *testing.T) { - tab := newTestBuilder(t, 5, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 5, WithPoetConfig( + PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration * 4}, + })) var eg errgroup.Group for _, sig := range tab.signers { @@ -271,7 +274,13 @@ func Test_Builder_Multi_InitialPost(t *testing.T) { func Test_Builder_Multi_HappyPath(t *testing.T) { layerDuration := 2 * time.Second - tab := newTestBuilder(t, 3, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4, CycleGap: layerDuration})) + tab := newTestBuilder(t, 3, WithPoetConfig( + PoetConfig{ + RegistrationConfig: RegistrationConfig{ + PhaseShift: layerDuration * 4, + CycleGap: layerDuration, + }, + })) // step 1: build initial posts initialPostChan := make(chan struct{}) diff --git a/activation/activation_test.go b/activation/activation_test.go index a3c696cb24..bc78c5e497 100644 --- a/activation/activation_test.go +++ b/activation/activation_test.go @@ -344,7 +344,10 @@ func TestBuilder_StopSmeshing_failsWhenNotStarted(t *testing.T) { } func TestBuilder_PublishActivationTx_HappyFlow(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig( + PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -380,7 +383,9 @@ func TestBuilder_PublishActivationTx_HappyFlow(t *testing.T) { // failing with ErrATXChallengeExpired. func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { // Arrange - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] // current layer is too late to be able to build a nipost on time @@ -429,7 +434,9 @@ func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { } func TestBuilder_PublishActivationTx_FaultyNet(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -502,7 +509,7 @@ func TestBuilder_PublishActivationTx_FaultyNet(t *testing.T) { func TestBuilder_PublishActivationTx_UsesExistingChallengeOnLatePublish(t *testing.T) { poetCfg := PoetConfig{ - PhaseShift: layerDuration * 4, + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, } tab := newTestBuilder(t, 1, WithPoetConfig(poetCfg)) sig := maps.Values(tab.signers)[0] @@ -580,7 +587,9 @@ func TestBuilder_PublishActivationTx_UsesExistingChallengeOnLatePublish(t *testi } func TestBuilder_PublishActivationTx_RebuildNIPostWhenTargetEpochPassed(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] posEpoch := types.EpochID(2) @@ -665,7 +674,9 @@ func TestBuilder_PublishActivationTx_RebuildNIPostWhenTargetEpochPassed(t *testi } func TestBuilder_PublishActivationTx_NoPrevATX(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -702,7 +713,9 @@ func TestBuilder_PublishActivationTx_NoPrevATX(t *testing.T) { } func TestBuilder_PublishActivationTx_NoPrevATX_PublishFails_InitialPost_preserved(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -779,7 +792,9 @@ func TestBuilder_PublishActivationTx_PrevATXWithoutPrevATX(t *testing.T) { r := require.New(t) // Arrange - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] otherSigner, err := signing.NewEdSigner() @@ -873,7 +888,9 @@ func TestBuilder_PublishActivationTx_TargetsEpochBasedOnPosAtx(t *testing.T) { r := require.New(t) // Arrange - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] otherSigner, err := signing.NewEdSigner() @@ -970,7 +987,9 @@ func TestBuilder_PublishActivationTx_TargetsEpochBasedOnPosAtx(t *testing.T) { } func TestBuilder_PublishActivationTx_FailsWhenNIPostBuilderFails(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -1029,7 +1048,7 @@ func TestBuilder_RetryPublishActivationTx(t *testing.T) { tab := newTestBuilder( t, 1, - WithPoetConfig(PoetConfig{PhaseShift: 150 * time.Millisecond}), + WithPoetConfig(PoetConfig{RegistrationConfig: RegistrationConfig{PhaseShift: 150 * time.Millisecond}}), WithPoetRetryInterval(retryInterval), ) sig := maps.Values(tab.signers)[0] @@ -1140,7 +1159,9 @@ func TestBuilder_RetryPublishActivationTx(t *testing.T) { } func TestBuilder_InitialProofGeneratedOnce(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] post := nipost.Post{ @@ -1179,7 +1200,9 @@ func TestBuilder_InitialProofGeneratedOnce(t *testing.T) { } func TestBuilder_InitialPostIsPersisted(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] commitmentATX := types.RandomATXID() @@ -1212,7 +1235,9 @@ func TestBuilder_InitialPostIsPersisted(t *testing.T) { } func TestBuilder_InitialPostLogErrorMissingVRFNonce(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + })) sig := maps.Values(tab.signers)[0] commitmentATX := types.RandomATXID() @@ -1275,8 +1300,10 @@ func TestWaitPositioningAtx(t *testing.T) { } { t.Run(tc.desc, func(t *testing.T) { tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - PhaseShift: tc.shift, - GracePeriod: tc.grace, + RegistrationConfig: RegistrationConfig{ + PhaseShift: tc.shift, + GracePeriod: tc.grace, + }, })) sig := maps.Values(tab.signers)[0] diff --git a/activation/builder_v2_test.go b/activation/builder_v2_test.go index 209570b7c4..88199cab41 100644 --- a/activation/builder_v2_test.go +++ b/activation/builder_v2_test.go @@ -19,7 +19,7 @@ import ( func TestBuilder_BuildsInitialAtxV2(t *testing.T) { tab := newTestBuilder(t, 1, - WithPoetConfig(PoetConfig{PhaseShift: layerDuration}), + WithPoetConfig(PoetConfig{RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}}), BuilderAtxVersions(AtxVersions{1: types.AtxV2})) tab.SetCoinbase(types.Address{1, 2, 3, 4}) @@ -73,7 +73,7 @@ func TestBuilder_BuildsInitialAtxV2(t *testing.T) { func TestBuilder_SwitchesToBuildV2(t *testing.T) { tab := newTestBuilder(t, 1, - WithPoetConfig(PoetConfig{PhaseShift: layerDuration}), + WithPoetConfig(PoetConfig{RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}}), BuilderAtxVersions(AtxVersions{4: types.AtxV2})) sig := maps.Values(tab.signers)[0] diff --git a/activation/e2e/activation_test.go b/activation/e2e/activation_test.go index e2bd4dd098..87545d94fa 100644 --- a/activation/e2e/activation_test.go +++ b/activation/e2e/activation_test.go @@ -85,12 +85,18 @@ func Test_BuilderWithMultipleClients(t *testing.T) { epoch := layerDuration * layersPerEpoch genesis := time.Now().Add(layerDuration).Round(layerDuration) poetCfg := activation.PoetConfig{ - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - RequestTimeout: epoch / 5, - RequestRetryDelay: epoch / 50, - MaxRequestRetries: 10, + ClientConfig: activation.ClientConfig{ + DefaultRequestTimeout: epoch / 5, + RequestRetryDelay: epoch / 50, + MaxRequestRetries: 10, + }, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, + SubmitChallengeTimeout: epoch / 4, + GetProofTimeout: epoch / 5, + }, } scrypt := testPostSetupOpts(t).Scrypt diff --git a/activation/e2e/atx_merge_test.go b/activation/e2e/atx_merge_test.go index fda7593427..9627db20c3 100644 --- a/activation/e2e/atx_merge_test.go +++ b/activation/e2e/atx_merge_test.go @@ -241,9 +241,11 @@ func Test_MarryAndMerge(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, + }, } client := ae2e.NewTestPoetClient(2) diff --git a/activation/e2e/builds_atx_v2_test.go b/activation/e2e/builds_atx_v2_test.go index 9c56b565be..356610fdff 100644 --- a/activation/e2e/builds_atx_v2_test.go +++ b/activation/e2e/builds_atx_v2_test.go @@ -78,9 +78,11 @@ func TestBuilder_SwitchesToBuildV2(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - PhaseShift: epoch, - CycleGap: epoch * 3 / 4, - GracePeriod: epoch / 4, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: epoch, + CycleGap: epoch * 3 / 4, + GracePeriod: epoch / 4, + }, } clock, err := timesync.NewClock( diff --git a/activation/e2e/checkpoint_merged_test.go b/activation/e2e/checkpoint_merged_test.go index cc5cfb00bd..525e03a612 100644 --- a/activation/e2e/checkpoint_merged_test.go +++ b/activation/e2e/checkpoint_merged_test.go @@ -76,9 +76,11 @@ func Test_CheckpointAfterMerge(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, + }, } client := ae2e.NewTestPoetClient(2) diff --git a/activation/e2e/checkpoint_test.go b/activation/e2e/checkpoint_test.go index 048469b2ff..4f0962bb57 100644 --- a/activation/e2e/checkpoint_test.go +++ b/activation/e2e/checkpoint_test.go @@ -67,9 +67,11 @@ func TestCheckpoint_PublishingSoloATXs(t *testing.T) { epoch := layerDuration * time.Duration(layersPerEpoch) poetCfg := activation.PoetConfig{ - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, + }, } client := ae2e.NewTestPoetClient(1) poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger) diff --git a/activation/e2e/nipost_test.go b/activation/e2e/nipost_test.go index 2a135e3256..60a2ed8750 100644 --- a/activation/e2e/nipost_test.go +++ b/activation/e2e/nipost_test.go @@ -172,9 +172,11 @@ func TestNIPostBuilderWithClients(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - PhaseShift: epoch / 2, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: epoch / 2, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, + }, } mclock := activation.NewMocklayerClock(ctrl) @@ -266,9 +268,11 @@ func Test_NIPostBuilderWithMultipleClients(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - PhaseShift: epoch / 2, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: epoch / 2, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, + }, } poetDb := activation.NewPoetDb(db, logger.Named("poetDb")) diff --git a/activation/e2e/validation_test.go b/activation/e2e/validation_test.go index 124a5762f3..975104065c 100644 --- a/activation/e2e/validation_test.go +++ b/activation/e2e/validation_test.go @@ -45,9 +45,11 @@ func TestValidator_Validate(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - PhaseShift: epoch / 2, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: epoch / 2, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, + }, } poetDb := activation.NewPoetDb(sql.InMemory(), logger.Named("poetDb")) diff --git a/activation/nipost_test.go b/activation/nipost_test.go index a351345d9f..dd6936c66f 100644 --- a/activation/nipost_test.go +++ b/activation/nipost_test.go @@ -588,7 +588,7 @@ func TestNIPostBuilder_ManyPoETs_SubmittingChallenge_DeadlineReached(t *testing. } poetCfg := PoetConfig{ - PhaseShift: layerDuration * layersPerEpoch / 2, + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration * layersPerEpoch / 2}, } sig, err := signing.NewEdSigner() @@ -686,7 +686,7 @@ func TestNIPSTBuilder_PoetUnstable(t *testing.T) { t.Parallel() challenge := types.RandomHash() poetCfg := PoetConfig{ - PhaseShift: layerDuration, + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, } sig, err := signing.NewEdSigner() require.NoError(t, err) @@ -971,7 +971,7 @@ func TestNIPoSTBuilder_Continues_After_Interrupted(t *testing.T) { poet.EXPECT().Address().AnyTimes().Return("http://localhost:9999") poetCfg := PoetConfig{ - PhaseShift: layerDuration * layersPerEpoch / 2, + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration * layersPerEpoch / 2}, } postClient := NewMockPostClient(ctrl) @@ -1107,7 +1107,7 @@ func TestNIPostBuilder_Mainnet_Poet_Workaround(t *testing.T) { ) poetCfg := PoetConfig{ - PhaseShift: layerDuration * layersPerEpoch / 2, + RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration * layersPerEpoch / 2}, } sig, err := signing.NewEdSigner() diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index 4aee683312..3f8e83176e 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -34,7 +34,8 @@ func Test_HTTPPoetClient_ParsesURL(t *testing.T) { PoetConfig{ RegistrationConfig: RegistrationConfig{ PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap}, + CycleGap: cfg.CycleGap, + }, }) require.NoError(t, err) require.Equal(t, "http://bla", client.baseURL.String()) diff --git a/cmd/root.go b/cmd/root.go index 1f7f0d3997..68a868e6c2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -326,7 +326,8 @@ func AddFlags(flagSet *pflag.FlagSet, cfg *config.Config) (configPath *string) { flagSet.DurationVar(&cfg.POET.GracePeriod, "grace-period", cfg.POET.GracePeriod, "time before poet round starts, when the node builds and submits a challenge") flagSet.DurationVar(&cfg.POET.SubmitChallengeTimeout, "submit-challenge-timeout", - cfg.POET.SubmitChallengeTimeout, "time within grace period, when post challenge must be submitted to poet server") + cfg.POET.SubmitChallengeTimeout, + "time within grace period, when post challenge must be submitted to poet server") flagSet.DurationVar(&cfg.POET.GetProofTimeout, "get-proof-timeout", cfg.POET.GetProofTimeout, "time period when ready poet proof must be fetched") flagSet.DurationVar(&cfg.POET.DefaultRequestTimeout, "poet-default-request-timeout", diff --git a/config/presets/fastnet.go b/config/presets/fastnet.go index a83ec65201..348897a2e5 100644 --- a/config/presets/fastnet.go +++ b/config/presets/fastnet.go @@ -96,7 +96,8 @@ func fastnet() config.Config { conf.POET.GetProofTimeout = 12 * time.Second // equal to DefaultRequestTimeout conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.DefaultRequestTimeout = 12 * time.Second // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + conf.POET.DefaultRequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second conf.POET.MaxRequestRetries = 3 return conf diff --git a/config/presets/standalone.go b/config/presets/standalone.go index 1bba75015e..0cdbe9e52a 100644 --- a/config/presets/standalone.go +++ b/config/presets/standalone.go @@ -82,7 +82,8 @@ func standalone() config.Config { conf.POET.PhaseShift = 30 * time.Second conf.POET.GetProofTimeout = 12 * time.Second // equal to DefaultRequestTimeout conf.POET.SubmitChallengeTimeout = 12 * time.Second - conf.POET.DefaultRequestTimeout = 12 * time.Second // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + conf.POET.DefaultRequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second conf.POET.MaxRequestRetries = 3 diff --git a/config/presets/testnet.go b/config/presets/testnet.go index 892d924aaf..1167a4d281 100644 --- a/config/presets/testnet.go +++ b/config/presets/testnet.go @@ -112,12 +112,19 @@ func testnet() config.Config { BeaconSyncWeightUnits: 800, }, POET: activation.PoetConfig{ - PhaseShift: 12 * time.Hour, - CycleGap: 2 * time.Hour, - GracePeriod: 10 * time.Minute, - RequestTimeout: 550 * time.Second, // RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - RequestRetryDelay: 5 * time.Second, - MaxRequestRetries: 10, + ClientConfig: activation.ClientConfig{ + // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + DefaultRequestTimeout: 550 * time.Second, + RequestRetryDelay: 5 * time.Second, + MaxRequestRetries: 10, + }, + RegistrationConfig: activation.RegistrationConfig{ + PhaseShift: 12 * time.Hour, + CycleGap: 2 * time.Hour, + GracePeriod: 10 * time.Minute, + GetProofTimeout: 550 * time.Second, + SubmitChallengeTimeout: 10 * time.Minute, + }, }, POST: activation.PostConfig{ MinNumUnits: 2, From fd3414eed93d98633f4ce491ebffa28952ef8383 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 15 Jul 2024 12:47:44 +0200 Subject: [PATCH 03/26] revert config structure --- activation/activation.go | 17 ++-------- activation/activation_multi_test.go | 8 ++--- activation/builder_v2_test.go | 4 +-- activation/e2e/activation_test.go | 20 +++++------- activation/e2e/atx_merge_test.go | 8 ++--- activation/e2e/builds_atx_v2_test.go | 8 ++--- activation/e2e/checkpoint_merged_test.go | 8 ++--- activation/e2e/checkpoint_test.go | 8 ++--- activation/e2e/nipost_test.go | 16 ++++----- activation/e2e/validation_test.go | 8 ++--- activation/poet_client_test.go | 41 +++++++++--------------- config/mainnet.go | 27 +++++++--------- config/presets/testnet.go | 22 ++++++------- 13 files changed, 73 insertions(+), 122 deletions(-) diff --git a/activation/activation.go b/activation/activation.go index 842c1ca5d7..10d7e8a201 100644 --- a/activation/activation.go +++ b/activation/activation.go @@ -39,19 +39,10 @@ var ( // PoetConfig is the configuration to interact with the poet server. type PoetConfig struct { - ClientConfig - RegistrationConfig -} - -type ClientConfig struct { DefaultRequestTimeout time.Duration `mapstructure:"poet-client-default-request-timeout"` RequestRetryDelay time.Duration `mapstructure:"poet-client-retry-delay"` CertifierInfoCacheTTL time.Duration `mapstructure:"poet-client-certifier-info-cache-ttl"` MaxRequestRetries int `mapstructure:"poet-client-retry-max"` -} - -// RegistrationConfig sets up settings for successful registration to new PoET round. -type RegistrationConfig struct { // Start of new PoET round PhaseShift time.Duration `mapstructure:"phase-shift"` // A gap between end of old PoET round and start of new one @@ -68,11 +59,9 @@ type RegistrationConfig struct { func DefaultPoetConfig() PoetConfig { return PoetConfig{ - ClientConfig: ClientConfig{ - RequestRetryDelay: 400 * time.Millisecond, - MaxRequestRetries: 10, - CertifierInfoCacheTTL: 5 * time.Minute, - }, + RequestRetryDelay: 400 * time.Millisecond, + MaxRequestRetries: 10, + CertifierInfoCacheTTL: 5 * time.Minute, } } diff --git a/activation/activation_multi_test.go b/activation/activation_multi_test.go index b5e3198699..6368f50427 100644 --- a/activation/activation_multi_test.go +++ b/activation/activation_multi_test.go @@ -234,7 +234,7 @@ func TestRegossip(t *testing.T) { func Test_Builder_Multi_InitialPost(t *testing.T) { tab := newTestBuilder(t, 5, WithPoetConfig( PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration * 4}, + PhaseShift: layerDuration * 4, })) var eg errgroup.Group @@ -276,10 +276,8 @@ func Test_Builder_Multi_HappyPath(t *testing.T) { layerDuration := 2 * time.Second tab := newTestBuilder(t, 3, WithPoetConfig( PoetConfig{ - RegistrationConfig: RegistrationConfig{ - PhaseShift: layerDuration * 4, - CycleGap: layerDuration, - }, + PhaseShift: layerDuration * 4, + CycleGap: layerDuration, })) // step 1: build initial posts diff --git a/activation/builder_v2_test.go b/activation/builder_v2_test.go index 88199cab41..209570b7c4 100644 --- a/activation/builder_v2_test.go +++ b/activation/builder_v2_test.go @@ -19,7 +19,7 @@ import ( func TestBuilder_BuildsInitialAtxV2(t *testing.T) { tab := newTestBuilder(t, 1, - WithPoetConfig(PoetConfig{RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}}), + WithPoetConfig(PoetConfig{PhaseShift: layerDuration}), BuilderAtxVersions(AtxVersions{1: types.AtxV2})) tab.SetCoinbase(types.Address{1, 2, 3, 4}) @@ -73,7 +73,7 @@ func TestBuilder_BuildsInitialAtxV2(t *testing.T) { func TestBuilder_SwitchesToBuildV2(t *testing.T) { tab := newTestBuilder(t, 1, - WithPoetConfig(PoetConfig{RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}}), + WithPoetConfig(PoetConfig{PhaseShift: layerDuration}), BuilderAtxVersions(AtxVersions{4: types.AtxV2})) sig := maps.Values(tab.signers)[0] diff --git a/activation/e2e/activation_test.go b/activation/e2e/activation_test.go index 87545d94fa..a97074af00 100644 --- a/activation/e2e/activation_test.go +++ b/activation/e2e/activation_test.go @@ -85,18 +85,14 @@ func Test_BuilderWithMultipleClients(t *testing.T) { epoch := layerDuration * layersPerEpoch genesis := time.Now().Add(layerDuration).Round(layerDuration) poetCfg := activation.PoetConfig{ - ClientConfig: activation.ClientConfig{ - DefaultRequestTimeout: epoch / 5, - RequestRetryDelay: epoch / 50, - MaxRequestRetries: 10, - }, - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - SubmitChallengeTimeout: epoch / 4, - GetProofTimeout: epoch / 5, - }, + DefaultRequestTimeout: epoch / 5, + RequestRetryDelay: epoch / 50, + MaxRequestRetries: 10, + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, + SubmitChallengeTimeout: epoch / 4, + GetProofTimeout: epoch / 5, } scrypt := testPostSetupOpts(t).Scrypt diff --git a/activation/e2e/atx_merge_test.go b/activation/e2e/atx_merge_test.go index 9627db20c3..fda7593427 100644 --- a/activation/e2e/atx_merge_test.go +++ b/activation/e2e/atx_merge_test.go @@ -241,11 +241,9 @@ func Test_MarryAndMerge(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - }, + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, } client := ae2e.NewTestPoetClient(2) diff --git a/activation/e2e/builds_atx_v2_test.go b/activation/e2e/builds_atx_v2_test.go index 356610fdff..9c56b565be 100644 --- a/activation/e2e/builds_atx_v2_test.go +++ b/activation/e2e/builds_atx_v2_test.go @@ -78,11 +78,9 @@ func TestBuilder_SwitchesToBuildV2(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: epoch, - CycleGap: epoch * 3 / 4, - GracePeriod: epoch / 4, - }, + PhaseShift: epoch, + CycleGap: epoch * 3 / 4, + GracePeriod: epoch / 4, } clock, err := timesync.NewClock( diff --git a/activation/e2e/checkpoint_merged_test.go b/activation/e2e/checkpoint_merged_test.go index 525e03a612..cc5cfb00bd 100644 --- a/activation/e2e/checkpoint_merged_test.go +++ b/activation/e2e/checkpoint_merged_test.go @@ -76,11 +76,9 @@ func Test_CheckpointAfterMerge(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - }, + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, } client := ae2e.NewTestPoetClient(2) diff --git a/activation/e2e/checkpoint_test.go b/activation/e2e/checkpoint_test.go index 4f0962bb57..048469b2ff 100644 --- a/activation/e2e/checkpoint_test.go +++ b/activation/e2e/checkpoint_test.go @@ -67,11 +67,9 @@ func TestCheckpoint_PublishingSoloATXs(t *testing.T) { epoch := layerDuration * time.Duration(layersPerEpoch) poetCfg := activation.PoetConfig{ - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - }, + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, } client := ae2e.NewTestPoetClient(1) poetService := activation.NewPoetServiceWithClient(poetDb, client, poetCfg, logger) diff --git a/activation/e2e/nipost_test.go b/activation/e2e/nipost_test.go index 60a2ed8750..2a135e3256 100644 --- a/activation/e2e/nipost_test.go +++ b/activation/e2e/nipost_test.go @@ -172,11 +172,9 @@ func TestNIPostBuilderWithClients(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: epoch / 2, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - }, + PhaseShift: epoch / 2, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, } mclock := activation.NewMocklayerClock(ctrl) @@ -268,11 +266,9 @@ func Test_NIPostBuilderWithMultipleClients(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: epoch / 2, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - }, + PhaseShift: epoch / 2, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, } poetDb := activation.NewPoetDb(db, logger.Named("poetDb")) diff --git a/activation/e2e/validation_test.go b/activation/e2e/validation_test.go index 975104065c..124a5762f3 100644 --- a/activation/e2e/validation_test.go +++ b/activation/e2e/validation_test.go @@ -45,11 +45,9 @@ func TestValidator_Validate(t *testing.T) { genesis := time.Now().Add(layerDuration).Round(layerDuration) epoch := layersPerEpoch * layerDuration poetCfg := activation.PoetConfig{ - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: epoch / 2, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - }, + PhaseShift: epoch / 2, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, } poetDb := activation.NewPoetDb(sql.InMemory(), logger.Named("poetDb")) diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index 3f8e83176e..4d1e9c51d3 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -32,10 +32,9 @@ func Test_HTTPPoetClient_ParsesURL(t *testing.T) { t.Parallel() client, err := NewHTTPPoetClient(types.PoetServer{Address: "bla"}, PoetConfig{ - RegistrationConfig: RegistrationConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, - }, + + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, }) require.NoError(t, err) require.Equal(t, "http://bla", client.baseURL.String()) @@ -45,10 +44,8 @@ func Test_HTTPPoetClient_ParsesURL(t *testing.T) { t.Parallel() client, err := NewHTTPPoetClient(types.PoetServer{Address: "https://bla"}, PoetConfig{ - RegistrationConfig: RegistrationConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, - }, + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, }) require.NoError(t, err) require.Equal(t, "https://bla", client.baseURL.String()) @@ -71,10 +68,8 @@ func Test_HTTPPoetClient_Submit(t *testing.T) { cfg := server.DefaultRoundConfig() client, err := NewHTTPPoetClient(types.PoetServer{Address: ts.URL}, PoetConfig{ - RegistrationConfig: RegistrationConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, - }, + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, }, withCustomHttpClient(ts.Client())) require.NoError(t, err) @@ -123,10 +118,8 @@ func Test_HTTPPoetClient_Address_Mainnet(t *testing.T) { t.Run(url, func(t *testing.T) { client, err := NewHTTPPoetClient(types.PoetServer{Address: url}, PoetConfig{ - RegistrationConfig: RegistrationConfig{ - PhaseShift: poetCfg.PhaseShift, - CycleGap: poetCfg.CycleGap, - }, + PhaseShift: poetCfg.PhaseShift, + CycleGap: poetCfg.CycleGap, }) require.NoError(t, err) require.Equal(t, url, client.Address()) @@ -150,10 +143,8 @@ func Test_HTTPPoetClient_Proof(t *testing.T) { cfg := server.DefaultRoundConfig() client, err := NewHTTPPoetClient(types.PoetServer{Address: ts.URL}, PoetConfig{ - RegistrationConfig: RegistrationConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, - }, + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, }, withCustomHttpClient(ts.Client())) require.NoError(t, err) @@ -222,9 +213,7 @@ func TestPoetClient_QueryProofTimeout(t *testing.T) { Pubkey: types.NewBase64Enc([]byte("pubkey")), } cfg := PoetConfig{ - ClientConfig: ClientConfig{ - DefaultRequestTimeout: time.Millisecond * 100, - }, + DefaultRequestTimeout: time.Millisecond * 100, } client, err := NewHTTPPoetClient(server, cfg, withCustomHttpClient(ts.Client())) require.NoError(t, err) @@ -268,7 +257,7 @@ func TestPoetClient_Certify(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{ClientConfig: ClientConfig{DefaultRequestTimeout: time.Millisecond * 100}} + cfg := PoetConfig{DefaultRequestTimeout: time.Millisecond * 100} cert := certifier.PoetCert{Data: []byte("abc")} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) @@ -314,7 +303,7 @@ func TestPoetClient_ObtainsCertOnSubmit(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{ClientConfig: ClientConfig{DefaultRequestTimeout: time.Millisecond * 100}} + cfg := PoetConfig{DefaultRequestTimeout: time.Millisecond * 100} cert := certifier.PoetCert{Data: []byte("abc")} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) @@ -373,7 +362,7 @@ func TestPoetClient_RecertifiesOnAuthFailure(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{ClientConfig: ClientConfig{DefaultRequestTimeout: time.Millisecond * 100}} + cfg := PoetConfig{DefaultRequestTimeout: time.Millisecond * 100} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) diff --git a/config/mainnet.go b/config/mainnet.go index d01fa1e24f..c279d5819f 100644 --- a/config/mainnet.go +++ b/config/mainnet.go @@ -160,21 +160,18 @@ func MainnetConfig() Config { BeaconSyncWeightUnits: 800, }, POET: activation.PoetConfig{ - ClientConfig: activation.ClientConfig{ - // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - DefaultRequestTimeout: 1100 * time.Second, - RequestRetryDelay: 10 * time.Second, - MaxRequestRetries: 10, - }, - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: 240 * time.Hour, - CycleGap: 12 * time.Hour, - GracePeriod: 1 * time.Hour, - SubmitChallengeTimeout: 1 * time.Hour, - PositioningATXSelectionTimeout: 50 * time.Minute, - // GetProofTimeout = DefaultRequestTimeout - GetProofTimeout: 1100 * time.Second, // ~ 18 min - }, + // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + DefaultRequestTimeout: 1100 * time.Second, + RequestRetryDelay: 10 * time.Second, + MaxRequestRetries: 10, + PhaseShift: 240 * time.Hour, + CycleGap: 12 * time.Hour, + GracePeriod: 1 * time.Hour, + // SubmitChallengeTimeout = GracePeriod + SubmitChallengeTimeout: 1 * time.Hour, + PositioningATXSelectionTimeout: 50 * time.Minute, + // GetProofTimeout = DefaultRequestTimeout + GetProofTimeout: 1100 * time.Second, // ~ 18 min }, POST: activation.PostConfig{ MinNumUnits: 4, diff --git a/config/presets/testnet.go b/config/presets/testnet.go index 1167a4d281..2b7663cfb1 100644 --- a/config/presets/testnet.go +++ b/config/presets/testnet.go @@ -112,19 +112,15 @@ func testnet() config.Config { BeaconSyncWeightUnits: 800, }, POET: activation.PoetConfig{ - ClientConfig: activation.ClientConfig{ - // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - DefaultRequestTimeout: 550 * time.Second, - RequestRetryDelay: 5 * time.Second, - MaxRequestRetries: 10, - }, - RegistrationConfig: activation.RegistrationConfig{ - PhaseShift: 12 * time.Hour, - CycleGap: 2 * time.Hour, - GracePeriod: 10 * time.Minute, - GetProofTimeout: 550 * time.Second, - SubmitChallengeTimeout: 10 * time.Minute, - }, + // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + DefaultRequestTimeout: 550 * time.Second, + RequestRetryDelay: 5 * time.Second, + MaxRequestRetries: 10, + PhaseShift: 12 * time.Hour, + CycleGap: 2 * time.Hour, + GracePeriod: 10 * time.Minute, + GetProofTimeout: 550 * time.Second, + SubmitChallengeTimeout: 10 * time.Minute, }, POST: activation.PostConfig{ MinNumUnits: 2, From e3d6d8a2dbc0e076e2a02c4979850e9d0da65e7a Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 15 Jul 2024 12:52:28 +0200 Subject: [PATCH 04/26] revert config structure2 --- activation/nipost_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/activation/nipost_test.go b/activation/nipost_test.go index dd6936c66f..a351345d9f 100644 --- a/activation/nipost_test.go +++ b/activation/nipost_test.go @@ -588,7 +588,7 @@ func TestNIPostBuilder_ManyPoETs_SubmittingChallenge_DeadlineReached(t *testing. } poetCfg := PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration * layersPerEpoch / 2}, + PhaseShift: layerDuration * layersPerEpoch / 2, } sig, err := signing.NewEdSigner() @@ -686,7 +686,7 @@ func TestNIPSTBuilder_PoetUnstable(t *testing.T) { t.Parallel() challenge := types.RandomHash() poetCfg := PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + PhaseShift: layerDuration, } sig, err := signing.NewEdSigner() require.NoError(t, err) @@ -971,7 +971,7 @@ func TestNIPoSTBuilder_Continues_After_Interrupted(t *testing.T) { poet.EXPECT().Address().AnyTimes().Return("http://localhost:9999") poetCfg := PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration * layersPerEpoch / 2}, + PhaseShift: layerDuration * layersPerEpoch / 2, } postClient := NewMockPostClient(ctrl) @@ -1107,7 +1107,7 @@ func TestNIPostBuilder_Mainnet_Poet_Workaround(t *testing.T) { ) poetCfg := PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration * layersPerEpoch / 2}, + PhaseShift: layerDuration * layersPerEpoch / 2, } sig, err := signing.NewEdSigner() From 94383d7aed47ff7dc7b0cbd66061d88743386bdc Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 15 Jul 2024 14:16:21 +0200 Subject: [PATCH 05/26] fix tests --- activation/activation_test.go | 51 +++++++-------------- activation/nipost.go | 5 +-- activation/nipost_test.go | 84 +++++++++++++++++++++++++++++++++++ activation/poet.go | 2 + 4 files changed, 103 insertions(+), 39 deletions(-) diff --git a/activation/activation_test.go b/activation/activation_test.go index bc78c5e497..84c3439571 100644 --- a/activation/activation_test.go +++ b/activation/activation_test.go @@ -346,7 +346,7 @@ func TestBuilder_StopSmeshing_failsWhenNotStarted(t *testing.T) { func TestBuilder_PublishActivationTx_HappyFlow(t *testing.T) { tab := newTestBuilder(t, 1, WithPoetConfig( PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + PhaseShift: layerDuration, })) sig := maps.Values(tab.signers)[0] @@ -384,8 +384,7 @@ func TestBuilder_PublishActivationTx_HappyFlow(t *testing.T) { func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { // Arrange tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] // current layer is too late to be able to build a nipost on time @@ -435,7 +434,7 @@ func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { func TestBuilder_PublishActivationTx_FaultyNet(t *testing.T) { tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + PhaseShift: layerDuration, })) sig := maps.Values(tab.signers)[0] @@ -509,7 +508,7 @@ func TestBuilder_PublishActivationTx_FaultyNet(t *testing.T) { func TestBuilder_PublishActivationTx_UsesExistingChallengeOnLatePublish(t *testing.T) { poetCfg := PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + PhaseShift: layerDuration, } tab := newTestBuilder(t, 1, WithPoetConfig(poetCfg)) sig := maps.Values(tab.signers)[0] @@ -587,9 +586,7 @@ func TestBuilder_PublishActivationTx_UsesExistingChallengeOnLatePublish(t *testi } func TestBuilder_PublishActivationTx_RebuildNIPostWhenTargetEpochPassed(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] posEpoch := types.EpochID(2) @@ -674,9 +671,7 @@ func TestBuilder_PublishActivationTx_RebuildNIPostWhenTargetEpochPassed(t *testi } func TestBuilder_PublishActivationTx_NoPrevATX(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -713,9 +708,7 @@ func TestBuilder_PublishActivationTx_NoPrevATX(t *testing.T) { } func TestBuilder_PublishActivationTx_NoPrevATX_PublishFails_InitialPost_preserved(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -793,7 +786,7 @@ func TestBuilder_PublishActivationTx_PrevATXWithoutPrevATX(t *testing.T) { // Arrange tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, + PhaseShift: layerDuration, })) sig := maps.Values(tab.signers)[0] @@ -888,9 +881,7 @@ func TestBuilder_PublishActivationTx_TargetsEpochBasedOnPosAtx(t *testing.T) { r := require.New(t) // Arrange - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] otherSigner, err := signing.NewEdSigner() @@ -987,9 +978,7 @@ func TestBuilder_PublishActivationTx_TargetsEpochBasedOnPosAtx(t *testing.T) { } func TestBuilder_PublishActivationTx_FailsWhenNIPostBuilderFails(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -1048,7 +1037,7 @@ func TestBuilder_RetryPublishActivationTx(t *testing.T) { tab := newTestBuilder( t, 1, - WithPoetConfig(PoetConfig{RegistrationConfig: RegistrationConfig{PhaseShift: 150 * time.Millisecond}}), + WithPoetConfig(PoetConfig{PhaseShift: 150 * time.Millisecond}), WithPoetRetryInterval(retryInterval), ) sig := maps.Values(tab.signers)[0] @@ -1159,9 +1148,7 @@ func TestBuilder_RetryPublishActivationTx(t *testing.T) { } func TestBuilder_InitialProofGeneratedOnce(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] post := nipost.Post{ @@ -1200,9 +1187,7 @@ func TestBuilder_InitialProofGeneratedOnce(t *testing.T) { } func TestBuilder_InitialPostIsPersisted(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] commitmentATX := types.RandomATXID() @@ -1235,9 +1220,7 @@ func TestBuilder_InitialPostIsPersisted(t *testing.T) { } func TestBuilder_InitialPostLogErrorMissingVRFNonce(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{PhaseShift: layerDuration}, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] commitmentATX := types.RandomATXID() @@ -1300,10 +1283,8 @@ func TestWaitPositioningAtx(t *testing.T) { } { t.Run(tc.desc, func(t *testing.T) { tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - RegistrationConfig: RegistrationConfig{ - PhaseShift: tc.shift, - GracePeriod: tc.grace, - }, + PhaseShift: tc.shift, + GracePeriod: tc.grace, })) sig := maps.Values(tab.signers)[0] diff --git a/activation/nipost.go b/activation/nipost.go index 6366c685b8..72317eaff6 100644 --- a/activation/nipost.go +++ b/activation/nipost.go @@ -372,10 +372,7 @@ func (nb *NIPostBuilder) submitPoetChallenge( logger.Debug("submitting challenge to poet proving service") - submitCtx, cancel := withConditionalTimeout(ctx, nb.poetCfg.SubmitChallengeTimeout) - defer cancel() - - round, err := client.Submit(submitCtx, deadline, prefix, challenge, signature, nodeID) + round, err := client.Submit(ctx, deadline, prefix, challenge, signature, nodeID) if err != nil { return &PoetSvcUnstableError{msg: "failed to submit challenge to poet service", source: err} } diff --git a/activation/nipost_test.go b/activation/nipost_test.go index a351345d9f..38083fdfe9 100644 --- a/activation/nipost_test.go +++ b/activation/nipost_test.go @@ -807,6 +807,90 @@ func TestNIPSTBuilder_PoetUnstable(t *testing.T) { }) } +func TestPoetTimeoutsParameters(t *testing.T) { + t.Parallel() + + sig, err := signing.NewEdSigner() + require.NoError(t, err) + + challenge := &types.NIPostChallenge{ + PublishEpoch: postGenesisEpoch + 2, + } + + t.Run("submit challenge timeout is too short -> fail", func(t *testing.T) { + db := localsql.InMemory() + + require.NoError(t, nipost.AddChallenge(db, sig.NodeID(), challenge)) + challengeHash := wire.NIPostChallengeToWireV1(challenge).Hash() + + ctrl := gomock.NewController(t) + mclock := defaultLayerClockMock(ctrl) + + poetProver := NewMockPoetService(ctrl) + poetProver.EXPECT(). + Submit(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), sig.NodeID()). + Return(nil, context.DeadlineExceeded) + poetProver.EXPECT().Address().AnyTimes().Return("http://localhost:9999") + + postService := NewMockpostService(ctrl) + + nb, err := NewNIPostBuilder( + db, + postService, + zaptest.NewLogger(t), + PoetConfig{SubmitChallengeTimeout: 1 * time.Microsecond}, + mclock, + nil, + WithPoetServices(poetProver), + ) + require.NoError(t, err) + + nipst, err := nb.BuildNIPost(context.Background(), sig, challengeHash, challenge) + require.ErrorIs(t, err, ErrPoetServiceUnstable) + require.Nil(t, nipst) + }) + + t.Run("get proof timeout is too short -> fail", func(t *testing.T) { + db := localsql.InMemory() + + require.NoError(t, nipost.AddChallenge(db, sig.NodeID(), challenge)) + challengeHash := wire.NIPostChallengeToWireV1(challenge).Hash() + + ctrl := gomock.NewController(t) + mclock := defaultLayerClockMock(ctrl) + + poetProver := NewMockPoetService(ctrl) + poetProver.EXPECT().Address().AnyTimes().Return("http://localhost:9999") + poetProver.EXPECT().Proof(gomock.Any(), "1").Return(nil, nil, context.DeadlineExceeded) + postService := NewMockpostService(ctrl) + + err = nipost.AddPoetRegistration(db, sig.NodeID(), nipost.PoETRegistration{ + ChallengeHash: challengeHash, + Address: "http://localhost:9999", + RoundID: "1", + RoundEnd: time.Now().Add(1 * time.Second), + }) + require.NoError(t, err) + + nb, err := NewNIPostBuilder( + db, + postService, + zaptest.NewLogger(t), + PoetConfig{ + GetProofTimeout: 1 * time.Microsecond, + }, + mclock, + nil, + WithPoetServices(poetProver), + ) + require.NoError(t, err) + + nipst, err := nb.BuildNIPost(context.Background(), sig, challengeHash, challenge) + require.ErrorIs(t, err, ErrPoetServiceUnstable) + require.Nil(t, nipst) + }) +} + // TestNIPoSTBuilder_StaleChallenge checks if // it properly detects that the challenge is stale and the poet round has already started. func TestNIPoSTBuilder_StaleChallenge(t *testing.T) { diff --git a/activation/poet.go b/activation/poet.go index 10ebb82327..c8d3abd75e 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -498,6 +498,8 @@ func (c *poetService) Submit( return nil, fmt.Errorf("recertifying: %w", err) } return c.client.Submit(submitCtx, deadline, prefix, challenge, signature, nodeID, *auth) + case errors.Is(err, context.DeadlineExceeded): + logger.Warn("failed to submit challenge: probably submit challenge timeout is too short", zap.Error(err)) } return nil, fmt.Errorf("submitting challenge: %w", err) } From 4fad1a07814fcaf9c18024e79de7771d592cd2f5 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 15 Jul 2024 14:23:22 +0200 Subject: [PATCH 06/26] make linter happy --- activation/activation_test.go | 3 ++- activation/poet_client_test.go | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/activation/activation_test.go b/activation/activation_test.go index 84c3439571..6ee804ff40 100644 --- a/activation/activation_test.go +++ b/activation/activation_test.go @@ -384,7 +384,8 @@ func TestBuilder_PublishActivationTx_HappyFlow(t *testing.T) { func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { // Arrange tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - PhaseShift: layerDuration})) + PhaseShift: layerDuration, + })) sig := maps.Values(tab.signers)[0] // current layer is too late to be able to build a nipost on time diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index 4d1e9c51d3..6cc952750e 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -32,7 +32,6 @@ func Test_HTTPPoetClient_ParsesURL(t *testing.T) { t.Parallel() client, err := NewHTTPPoetClient(types.PoetServer{Address: "bla"}, PoetConfig{ - PhaseShift: cfg.PhaseShift, CycleGap: cfg.CycleGap, }) From 9ff59582447ca3e6d1b8b7d2ba979e5c951af6af Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Tue, 16 Jul 2024 01:32:54 +0200 Subject: [PATCH 07/26] fix review issue --- activation/activation_test.go | 2 +- cmd/root.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/activation/activation_test.go b/activation/activation_test.go index 6ee804ff40..d8c2b3b43a 100644 --- a/activation/activation_test.go +++ b/activation/activation_test.go @@ -587,7 +587,7 @@ func TestBuilder_PublishActivationTx_UsesExistingChallengeOnLatePublish(t *testi } func TestBuilder_PublishActivationTx_RebuildNIPostWhenTargetEpochPassed(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] posEpoch := types.EpochID(2) diff --git a/cmd/root.go b/cmd/root.go index 68a868e6c2..ca5bce0d3e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -320,7 +320,7 @@ func AddFlags(flagSet *pflag.FlagSet, cfg *config.Config) (configPath *string) { /**======================== PoET Flags ========================== **/ flagSet.DurationVar(&cfg.POET.PhaseShift, "phase-shift", - cfg.POET.PhaseShift, "phase shift of poet server: time, when poet round starts") + cfg.POET.PhaseShift, "phase shift of poet server: duration after epoch start, at which poet round starts") flagSet.DurationVar(&cfg.POET.CycleGap, "cycle-gap", cfg.POET.CycleGap, "cycle gap of poet server: gap between poet rounds") flagSet.DurationVar(&cfg.POET.GracePeriod, "grace-period", From 4046cc5eeb19220c3db5b00fb09e4c5e2d2b34ed Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Tue, 16 Jul 2024 13:25:11 +0200 Subject: [PATCH 08/26] fix review issue + revert naming --- CHANGELOG.md | 9 ++++++++ activation/activation.go | 12 +++++----- activation/activation_test.go | 22 ++++++++----------- activation/e2e/activation_test.go | 4 ++-- activation/nipost_test.go | 2 +- activation/poet.go | 8 +++---- activation/poet_client_test.go | 10 ++++----- cmd/root.go | 8 +++---- config/mainnet.go | 18 +++++++-------- config/presets/fastnet.go | 6 ++--- config/presets/standalone.go | 6 ++--- config/presets/testnet.go | 6 ++--- .../distributed_post_verification_test.go | 4 ++-- 13 files changed, 60 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87f1876ac2..4884c5a6d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ See [RELEASE](./RELEASE.md) for workflow instructions. +## UNRELEASED +### Improvements +* [#6035](https://github.com/spacemeshos/go-spacemesh/issues/6035) + Added poet config parameters to establish submit registration challenge and fetch poet proof timeouts. + - `submit-challenge-timeout`: Timeout duration for submitting registration challenges to the PoET service. + Optional parameter, if not set, submitting will be continued till end of cyclegap + - `fetch-proof-timeout`: Timeout duration for fetching proofs from PoET service. + Optional parameter, if not set, fetching proof will be continued till beginning of cyclegap in publish epoch + ## Release v1.6.1 ### Improvements diff --git a/activation/activation.go b/activation/activation.go index 10d7e8a201..a41b5b0b8b 100644 --- a/activation/activation.go +++ b/activation/activation.go @@ -39,10 +39,10 @@ var ( // PoetConfig is the configuration to interact with the poet server. type PoetConfig struct { - DefaultRequestTimeout time.Duration `mapstructure:"poet-client-default-request-timeout"` - RequestRetryDelay time.Duration `mapstructure:"poet-client-retry-delay"` - CertifierInfoCacheTTL time.Duration `mapstructure:"poet-client-certifier-info-cache-ttl"` - MaxRequestRetries int `mapstructure:"poet-client-retry-max"` + RequestTimeout time.Duration `mapstructure:"poet-request-timeout"` + RequestRetryDelay time.Duration `mapstructure:"retry-delay"` + CertifierInfoCacheTTL time.Duration `mapstructure:"certifier-info-cache-ttl"` + MaxRequestRetries int `mapstructure:"retry-max"` // Start of new PoET round PhaseShift time.Duration `mapstructure:"phase-shift"` // A gap between end of old PoET round and start of new one @@ -53,8 +53,8 @@ type PoetConfig struct { PositioningATXSelectionTimeout time.Duration `mapstructure:"positioning-atx-selection-timeout"` // Period to submit PoST challenge to PoET server. Must be not greater than GracePeriod SubmitChallengeTimeout time.Duration `mapstructure:"submit-challenge-timeout"` - // Period to get PoET proof - GetProofTimeout time.Duration `mapstructure:"get-proof-timeout"` + // Period to fetch PoET proof + FetchProofTimeout time.Duration `mapstructure:"fetch-proof-timeout"` } func DefaultPoetConfig() PoetConfig { diff --git a/activation/activation_test.go b/activation/activation_test.go index d8c2b3b43a..ee41e03a3c 100644 --- a/activation/activation_test.go +++ b/activation/activation_test.go @@ -384,7 +384,7 @@ func TestBuilder_PublishActivationTx_HappyFlow(t *testing.T) { func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { // Arrange tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - PhaseShift: layerDuration, + PhaseShift: layerDuration * 4, })) sig := maps.Values(tab.signers)[0] @@ -435,7 +435,7 @@ func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { func TestBuilder_PublishActivationTx_FaultyNet(t *testing.T) { tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - PhaseShift: layerDuration, + PhaseShift: layerDuration * 4, })) sig := maps.Values(tab.signers)[0] @@ -508,9 +508,7 @@ func TestBuilder_PublishActivationTx_FaultyNet(t *testing.T) { } func TestBuilder_PublishActivationTx_UsesExistingChallengeOnLatePublish(t *testing.T) { - poetCfg := PoetConfig{ - PhaseShift: layerDuration, - } + poetCfg := PoetConfig{PhaseShift: layerDuration * 4} tab := newTestBuilder(t, 1, WithPoetConfig(poetCfg)) sig := maps.Values(tab.signers)[0] @@ -672,7 +670,7 @@ func TestBuilder_PublishActivationTx_RebuildNIPostWhenTargetEpochPassed(t *testi } func TestBuilder_PublishActivationTx_NoPrevATX(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -709,7 +707,7 @@ func TestBuilder_PublishActivationTx_NoPrevATX(t *testing.T) { } func TestBuilder_PublishActivationTx_NoPrevATX_PublishFails_InitialPost_preserved(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -786,9 +784,7 @@ func TestBuilder_PublishActivationTx_PrevATXWithoutPrevATX(t *testing.T) { r := require.New(t) // Arrange - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - PhaseShift: layerDuration, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] otherSigner, err := signing.NewEdSigner() @@ -882,7 +878,7 @@ func TestBuilder_PublishActivationTx_TargetsEpochBasedOnPosAtx(t *testing.T) { r := require.New(t) // Arrange - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] otherSigner, err := signing.NewEdSigner() @@ -979,7 +975,7 @@ func TestBuilder_PublishActivationTx_TargetsEpochBasedOnPosAtx(t *testing.T) { } func TestBuilder_PublishActivationTx_FailsWhenNIPostBuilderFails(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -1221,7 +1217,7 @@ func TestBuilder_InitialPostIsPersisted(t *testing.T) { } func TestBuilder_InitialPostLogErrorMissingVRFNonce(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] commitmentATX := types.RandomATXID() diff --git a/activation/e2e/activation_test.go b/activation/e2e/activation_test.go index a97074af00..929dedecc8 100644 --- a/activation/e2e/activation_test.go +++ b/activation/e2e/activation_test.go @@ -85,14 +85,14 @@ func Test_BuilderWithMultipleClients(t *testing.T) { epoch := layerDuration * layersPerEpoch genesis := time.Now().Add(layerDuration).Round(layerDuration) poetCfg := activation.PoetConfig{ - DefaultRequestTimeout: epoch / 5, + RequestTimeout: epoch / 5, RequestRetryDelay: epoch / 50, MaxRequestRetries: 10, PhaseShift: epoch, CycleGap: 3 * epoch / 4, GracePeriod: epoch / 4, SubmitChallengeTimeout: epoch / 4, - GetProofTimeout: epoch / 5, + FetchProofTimeout: epoch / 5, } scrypt := testPostSetupOpts(t).Scrypt diff --git a/activation/nipost_test.go b/activation/nipost_test.go index 38083fdfe9..2d4ae049ce 100644 --- a/activation/nipost_test.go +++ b/activation/nipost_test.go @@ -877,7 +877,7 @@ func TestPoetTimeoutsParameters(t *testing.T) { postService, zaptest.NewLogger(t), PoetConfig{ - GetProofTimeout: 1 * time.Microsecond, + FetchProofTimeout: 1 * time.Microsecond, }, mclock, nil, diff --git a/activation/poet.go b/activation/poet.go index c8d3abd75e..c8974f2dda 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -346,7 +346,7 @@ type poetService struct { defaultRequestTimeout time.Duration submitChallengeRequestTimeout time.Duration - getProofRequestTimeout time.Duration + fetchProofRequestTimeout time.Duration // Used to avoid concurrent requests for proof. gettingProof sync.Mutex @@ -399,9 +399,9 @@ func NewPoetServiceWithClient( db: db, logger: logger, client: client, - defaultRequestTimeout: cfg.DefaultRequestTimeout, + defaultRequestTimeout: cfg.RequestTimeout, submitChallengeRequestTimeout: cfg.SubmitChallengeTimeout, - getProofRequestTimeout: cfg.GetProofTimeout, + fetchProofRequestTimeout: cfg.FetchProofTimeout, certifierInfoTTL: cfg.CertifierInfoCacheTTL, proofMembers: make(map[string][]types.Hash32, 1), } @@ -505,7 +505,7 @@ func (c *poetService) Submit( } func (c *poetService) Proof(ctx context.Context, roundID string) (*types.PoetProof, []types.Hash32, error) { - getProofsCtx, cancel := withConditionalTimeout(ctx, c.getProofRequestTimeout) + getProofsCtx, cancel := withConditionalTimeout(ctx, c.fetchProofRequestTimeout) defer cancel() c.gettingProof.Lock() diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index 6cc952750e..e0744fca9a 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -212,7 +212,7 @@ func TestPoetClient_QueryProofTimeout(t *testing.T) { Pubkey: types.NewBase64Enc([]byte("pubkey")), } cfg := PoetConfig{ - DefaultRequestTimeout: time.Millisecond * 100, + RequestTimeout: time.Millisecond * 100, } client, err := NewHTTPPoetClient(server, cfg, withCustomHttpClient(ts.Client())) require.NoError(t, err) @@ -228,7 +228,7 @@ func TestPoetClient_QueryProofTimeout(t *testing.T) { }) } eg.Wait() - require.WithinDuration(t, start.Add(cfg.DefaultRequestTimeout), time.Now(), time.Millisecond*300) + require.WithinDuration(t, start.Add(cfg.RequestTimeout), time.Now(), time.Millisecond*300) } func TestPoetClient_Certify(t *testing.T) { @@ -256,7 +256,7 @@ func TestPoetClient_Certify(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{DefaultRequestTimeout: time.Millisecond * 100} + cfg := PoetConfig{RequestTimeout: time.Millisecond * 100} cert := certifier.PoetCert{Data: []byte("abc")} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) @@ -302,7 +302,7 @@ func TestPoetClient_ObtainsCertOnSubmit(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{DefaultRequestTimeout: time.Millisecond * 100} + cfg := PoetConfig{RequestTimeout: time.Millisecond * 100} cert := certifier.PoetCert{Data: []byte("abc")} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) @@ -361,7 +361,7 @@ func TestPoetClient_RecertifiesOnAuthFailure(t *testing.T) { Address: ts.URL, Pubkey: types.NewBase64Enc([]byte("pubkey")), } - cfg := PoetConfig{DefaultRequestTimeout: time.Millisecond * 100} + cfg := PoetConfig{RequestTimeout: time.Millisecond * 100} ctrl := gomock.NewController(t) mCertifier := NewMockcertifierService(ctrl) diff --git a/cmd/root.go b/cmd/root.go index ca5bce0d3e..8724ad5a20 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -328,10 +328,10 @@ func AddFlags(flagSet *pflag.FlagSet, cfg *config.Config) (configPath *string) { flagSet.DurationVar(&cfg.POET.SubmitChallengeTimeout, "submit-challenge-timeout", cfg.POET.SubmitChallengeTimeout, "time within grace period, when post challenge must be submitted to poet server") - flagSet.DurationVar(&cfg.POET.GetProofTimeout, "get-proof-timeout", - cfg.POET.GetProofTimeout, "time period when ready poet proof must be fetched") - flagSet.DurationVar(&cfg.POET.DefaultRequestTimeout, "poet-default-request-timeout", - cfg.POET.DefaultRequestTimeout, "default timeout for poet requests") + flagSet.DurationVar(&cfg.POET.FetchProofTimeout, "get-proof-timeout", + cfg.POET.FetchProofTimeout, "time period when ready poet proof must be fetched") + flagSet.DurationVar(&cfg.POET.RequestTimeout, "poet-default-request-timeout", + cfg.POET.RequestTimeout, "default timeout for poet requests") /**======================== bootstrap data updater Flags ========================== **/ diff --git a/config/mainnet.go b/config/mainnet.go index c279d5819f..3f123be373 100644 --- a/config/mainnet.go +++ b/config/mainnet.go @@ -160,18 +160,18 @@ func MainnetConfig() Config { BeaconSyncWeightUnits: 800, }, POET: activation.PoetConfig{ - // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - DefaultRequestTimeout: 1100 * time.Second, - RequestRetryDelay: 10 * time.Second, - MaxRequestRetries: 10, - PhaseShift: 240 * time.Hour, - CycleGap: 12 * time.Hour, - GracePeriod: 1 * time.Hour, + // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + RequestTimeout: 1100 * time.Second, + RequestRetryDelay: 10 * time.Second, + MaxRequestRetries: 10, + PhaseShift: 240 * time.Hour, + CycleGap: 12 * time.Hour, + GracePeriod: 1 * time.Hour, // SubmitChallengeTimeout = GracePeriod SubmitChallengeTimeout: 1 * time.Hour, PositioningATXSelectionTimeout: 50 * time.Minute, - // GetProofTimeout = DefaultRequestTimeout - GetProofTimeout: 1100 * time.Second, // ~ 18 min + // FetchProofTimeout = RequestTimeout + FetchProofTimeout: 1100 * time.Second, // ~ 18 min }, POST: activation.PostConfig{ MinNumUnits: 4, diff --git a/config/presets/fastnet.go b/config/presets/fastnet.go index 348897a2e5..3bf545f384 100644 --- a/config/presets/fastnet.go +++ b/config/presets/fastnet.go @@ -93,11 +93,11 @@ func fastnet() config.Config { conf.POET.GracePeriod = 10 * time.Second conf.POET.SubmitChallengeTimeout = 10 * time.Second - conf.POET.GetProofTimeout = 12 * time.Second // equal to DefaultRequestTimeout + conf.POET.FetchProofTimeout = 12 * time.Second // equal to RequestTimeout conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - conf.POET.DefaultRequestTimeout = 12 * time.Second + // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second conf.POET.MaxRequestRetries = 3 return conf diff --git a/config/presets/standalone.go b/config/presets/standalone.go index 0cdbe9e52a..8432387721 100644 --- a/config/presets/standalone.go +++ b/config/presets/standalone.go @@ -80,10 +80,10 @@ func standalone() config.Config { conf.POET.GracePeriod = 12 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.GetProofTimeout = 12 * time.Second // equal to DefaultRequestTimeout + conf.POET.FetchProofTimeout = 12 * time.Second // equal to RequestTimeout conf.POET.SubmitChallengeTimeout = 12 * time.Second - // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - conf.POET.DefaultRequestTimeout = 12 * time.Second + // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second conf.POET.MaxRequestRetries = 3 diff --git a/config/presets/testnet.go b/config/presets/testnet.go index 2b7663cfb1..35d60f1add 100644 --- a/config/presets/testnet.go +++ b/config/presets/testnet.go @@ -112,14 +112,14 @@ func testnet() config.Config { BeaconSyncWeightUnits: 800, }, POET: activation.PoetConfig{ - // DefaultRequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - DefaultRequestTimeout: 550 * time.Second, + // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 + RequestTimeout: 550 * time.Second, RequestRetryDelay: 5 * time.Second, MaxRequestRetries: 10, PhaseShift: 12 * time.Hour, CycleGap: 2 * time.Hour, GracePeriod: 10 * time.Minute, - GetProofTimeout: 550 * time.Second, + FetchProofTimeout: 550 * time.Second, SubmitChallengeTimeout: 10 * time.Minute, }, POST: activation.PostConfig{ diff --git a/systest/tests/distributed_post_verification_test.go b/systest/tests/distributed_post_verification_test.go index df7e2ab5c7..7a5e9b7166 100644 --- a/systest/tests/distributed_post_verification_test.go +++ b/systest/tests/distributed_post_verification_test.go @@ -64,8 +64,8 @@ func TestPostMalfeasanceProof(t *testing.T) { cfg.P2P.DataDir = filepath.Join(testDir, "p2p-dir") require.NoError(t, os.Mkdir(cfg.P2P.DataDir, os.ModePerm)) - cfg.POET.DefaultRequestTimeout = time.Minute - cfg.POET.GetProofTimeout = time.Minute + cfg.POET.RequestTimeout = time.Minute + cfg.POET.FetchProofTimeout = time.Minute cfg.POET.SubmitChallengeTimeout = time.Minute cfg.POET.MaxRequestRetries = 10 From ab0b71edaf2a561bf558fbf0921911691f7d326f Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 10:04:32 +0200 Subject: [PATCH 09/26] removed overengineering --- CHANGELOG.md | 9 ---- activation/activation.go | 4 -- activation/nipost_test.go | 84 ------------------------------------ activation/poet.go | 31 +++++-------- config/mainnet.go | 5 --- config/presets/fastnet.go | 2 - config/presets/standalone.go | 2 - config/presets/testnet.go | 14 +++--- 8 files changed, 17 insertions(+), 134 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4884c5a6d5..87f1876ac2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,6 @@ See [RELEASE](./RELEASE.md) for workflow instructions. -## UNRELEASED -### Improvements -* [#6035](https://github.com/spacemeshos/go-spacemesh/issues/6035) - Added poet config parameters to establish submit registration challenge and fetch poet proof timeouts. - - `submit-challenge-timeout`: Timeout duration for submitting registration challenges to the PoET service. - Optional parameter, if not set, submitting will be continued till end of cyclegap - - `fetch-proof-timeout`: Timeout duration for fetching proofs from PoET service. - Optional parameter, if not set, fetching proof will be continued till beginning of cyclegap in publish epoch - ## Release v1.6.1 ### Improvements diff --git a/activation/activation.go b/activation/activation.go index a41b5b0b8b..f039c794d9 100644 --- a/activation/activation.go +++ b/activation/activation.go @@ -51,10 +51,6 @@ type PoetConfig struct { GracePeriod time.Duration `mapstructure:"grace-period"` // Period to find positioning ATX. Must be less, than GracePeriod PositioningATXSelectionTimeout time.Duration `mapstructure:"positioning-atx-selection-timeout"` - // Period to submit PoST challenge to PoET server. Must be not greater than GracePeriod - SubmitChallengeTimeout time.Duration `mapstructure:"submit-challenge-timeout"` - // Period to fetch PoET proof - FetchProofTimeout time.Duration `mapstructure:"fetch-proof-timeout"` } func DefaultPoetConfig() PoetConfig { diff --git a/activation/nipost_test.go b/activation/nipost_test.go index 2d4ae049ce..a351345d9f 100644 --- a/activation/nipost_test.go +++ b/activation/nipost_test.go @@ -807,90 +807,6 @@ func TestNIPSTBuilder_PoetUnstable(t *testing.T) { }) } -func TestPoetTimeoutsParameters(t *testing.T) { - t.Parallel() - - sig, err := signing.NewEdSigner() - require.NoError(t, err) - - challenge := &types.NIPostChallenge{ - PublishEpoch: postGenesisEpoch + 2, - } - - t.Run("submit challenge timeout is too short -> fail", func(t *testing.T) { - db := localsql.InMemory() - - require.NoError(t, nipost.AddChallenge(db, sig.NodeID(), challenge)) - challengeHash := wire.NIPostChallengeToWireV1(challenge).Hash() - - ctrl := gomock.NewController(t) - mclock := defaultLayerClockMock(ctrl) - - poetProver := NewMockPoetService(ctrl) - poetProver.EXPECT(). - Submit(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), sig.NodeID()). - Return(nil, context.DeadlineExceeded) - poetProver.EXPECT().Address().AnyTimes().Return("http://localhost:9999") - - postService := NewMockpostService(ctrl) - - nb, err := NewNIPostBuilder( - db, - postService, - zaptest.NewLogger(t), - PoetConfig{SubmitChallengeTimeout: 1 * time.Microsecond}, - mclock, - nil, - WithPoetServices(poetProver), - ) - require.NoError(t, err) - - nipst, err := nb.BuildNIPost(context.Background(), sig, challengeHash, challenge) - require.ErrorIs(t, err, ErrPoetServiceUnstable) - require.Nil(t, nipst) - }) - - t.Run("get proof timeout is too short -> fail", func(t *testing.T) { - db := localsql.InMemory() - - require.NoError(t, nipost.AddChallenge(db, sig.NodeID(), challenge)) - challengeHash := wire.NIPostChallengeToWireV1(challenge).Hash() - - ctrl := gomock.NewController(t) - mclock := defaultLayerClockMock(ctrl) - - poetProver := NewMockPoetService(ctrl) - poetProver.EXPECT().Address().AnyTimes().Return("http://localhost:9999") - poetProver.EXPECT().Proof(gomock.Any(), "1").Return(nil, nil, context.DeadlineExceeded) - postService := NewMockpostService(ctrl) - - err = nipost.AddPoetRegistration(db, sig.NodeID(), nipost.PoETRegistration{ - ChallengeHash: challengeHash, - Address: "http://localhost:9999", - RoundID: "1", - RoundEnd: time.Now().Add(1 * time.Second), - }) - require.NoError(t, err) - - nb, err := NewNIPostBuilder( - db, - postService, - zaptest.NewLogger(t), - PoetConfig{ - FetchProofTimeout: 1 * time.Microsecond, - }, - mclock, - nil, - WithPoetServices(poetProver), - ) - require.NoError(t, err) - - nipst, err := nb.BuildNIPost(context.Background(), sig, challengeHash, challenge) - require.ErrorIs(t, err, ErrPoetServiceUnstable) - require.Nil(t, nipst) - }) -} - // TestNIPoSTBuilder_StaleChallenge checks if // it properly detects that the challenge is stale and the poet round has already started. func TestNIPoSTBuilder_StaleChallenge(t *testing.T) { diff --git a/activation/poet.go b/activation/poet.go index c8974f2dda..9d86ef2f2f 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -344,9 +344,7 @@ type poetService struct { logger *zap.Logger client PoetClient - defaultRequestTimeout time.Duration - submitChallengeRequestTimeout time.Duration - fetchProofRequestTimeout time.Duration + requestTimeout time.Duration // Used to avoid concurrent requests for proof. gettingProof sync.Mutex @@ -396,14 +394,12 @@ func NewPoetServiceWithClient( opts ...PoetServiceOpt, ) *poetService { poetClient := &poetService{ - db: db, - logger: logger, - client: client, - defaultRequestTimeout: cfg.RequestTimeout, - submitChallengeRequestTimeout: cfg.SubmitChallengeTimeout, - fetchProofRequestTimeout: cfg.FetchProofTimeout, - certifierInfoTTL: cfg.CertifierInfoCacheTTL, - proofMembers: make(map[string][]types.Hash32, 1), + db: db, + logger: logger, + client: client, + requestTimeout: cfg.RequestTimeout, + certifierInfoTTL: cfg.CertifierInfoCacheTTL, + proofMembers: make(map[string][]types.Hash32, 1), } for _, opt := range opts { @@ -437,7 +433,7 @@ func (c *poetService) authorize( // TODO: remove this fallback once we migrate to certificates fully. logger.Debug("querying for poet pow parameters") - powCtx, cancel := withConditionalTimeout(ctx, c.defaultRequestTimeout) + powCtx, cancel := withConditionalTimeout(ctx, c.requestTimeout) defer cancel() powParams, err := c.client.PowParams(powCtx) if err != nil { @@ -485,9 +481,7 @@ func (c *poetService) Submit( logger.Debug("submitting challenge to poet proving service") - submitCtx, cancel := withConditionalTimeout(ctx, c.submitChallengeRequestTimeout) - defer cancel() - round, err := c.client.Submit(submitCtx, deadline, prefix, challenge, signature, nodeID, *auth) + round, err := c.client.Submit(ctx, deadline, prefix, challenge, signature, nodeID, *auth) switch { case err == nil: return round, nil @@ -497,7 +491,7 @@ func (c *poetService) Submit( if err != nil { return nil, fmt.Errorf("recertifying: %w", err) } - return c.client.Submit(submitCtx, deadline, prefix, challenge, signature, nodeID, *auth) + return c.client.Submit(ctx, deadline, prefix, challenge, signature, nodeID, *auth) case errors.Is(err, context.DeadlineExceeded): logger.Warn("failed to submit challenge: probably submit challenge timeout is too short", zap.Error(err)) } @@ -505,9 +499,6 @@ func (c *poetService) Submit( } func (c *poetService) Proof(ctx context.Context, roundID string) (*types.PoetProof, []types.Hash32, error) { - getProofsCtx, cancel := withConditionalTimeout(ctx, c.fetchProofRequestTimeout) - defer cancel() - c.gettingProof.Lock() defer c.gettingProof.Unlock() @@ -520,7 +511,7 @@ func (c *poetService) Proof(ctx context.Context, roundID string) (*types.PoetPro c.logger.Warn("cached members found but proof not found in db", zap.String("round_id", roundID), zap.Error(err)) } - proof, members, err := c.client.Proof(getProofsCtx, roundID) + proof, members, err := c.client.Proof(ctx, roundID) if err != nil { return nil, nil, fmt.Errorf("getting proof: %w", err) } diff --git a/config/mainnet.go b/config/mainnet.go index 3f123be373..79666f7c1c 100644 --- a/config/mainnet.go +++ b/config/mainnet.go @@ -167,11 +167,6 @@ func MainnetConfig() Config { PhaseShift: 240 * time.Hour, CycleGap: 12 * time.Hour, GracePeriod: 1 * time.Hour, - // SubmitChallengeTimeout = GracePeriod - SubmitChallengeTimeout: 1 * time.Hour, - PositioningATXSelectionTimeout: 50 * time.Minute, - // FetchProofTimeout = RequestTimeout - FetchProofTimeout: 1100 * time.Second, // ~ 18 min }, POST: activation.PostConfig{ MinNumUnits: 4, diff --git a/config/presets/fastnet.go b/config/presets/fastnet.go index 3bf545f384..0e811edc00 100644 --- a/config/presets/fastnet.go +++ b/config/presets/fastnet.go @@ -92,8 +92,6 @@ func fastnet() config.Config { conf.Beacon.VotesLimit = 100 conf.POET.GracePeriod = 10 * time.Second - conf.POET.SubmitChallengeTimeout = 10 * time.Second - conf.POET.FetchProofTimeout = 12 * time.Second // equal to RequestTimeout conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 diff --git a/config/presets/standalone.go b/config/presets/standalone.go index 8432387721..12eb0308d2 100644 --- a/config/presets/standalone.go +++ b/config/presets/standalone.go @@ -80,8 +80,6 @@ func standalone() config.Config { conf.POET.GracePeriod = 12 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.FetchProofTimeout = 12 * time.Second // equal to RequestTimeout - conf.POET.SubmitChallengeTimeout = 12 * time.Second // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second diff --git a/config/presets/testnet.go b/config/presets/testnet.go index 35d60f1add..4ce4606886 100644 --- a/config/presets/testnet.go +++ b/config/presets/testnet.go @@ -113,14 +113,12 @@ func testnet() config.Config { }, POET: activation.PoetConfig{ // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - RequestTimeout: 550 * time.Second, - RequestRetryDelay: 5 * time.Second, - MaxRequestRetries: 10, - PhaseShift: 12 * time.Hour, - CycleGap: 2 * time.Hour, - GracePeriod: 10 * time.Minute, - FetchProofTimeout: 550 * time.Second, - SubmitChallengeTimeout: 10 * time.Minute, + RequestTimeout: 550 * time.Second, + RequestRetryDelay: 5 * time.Second, + MaxRequestRetries: 10, + PhaseShift: 12 * time.Hour, + CycleGap: 2 * time.Hour, + GracePeriod: 10 * time.Minute, }, POST: activation.PostConfig{ MinNumUnits: 2, From c969205aa9feeb61465ab7ba62c8f8dad8a8b04b Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 10:09:18 +0200 Subject: [PATCH 10/26] removed overengineering2 --- activation/e2e/activation_test.go | 14 ++++++-------- cmd/root.go | 5 ----- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/activation/e2e/activation_test.go b/activation/e2e/activation_test.go index 929dedecc8..2732daed61 100644 --- a/activation/e2e/activation_test.go +++ b/activation/e2e/activation_test.go @@ -85,14 +85,12 @@ func Test_BuilderWithMultipleClients(t *testing.T) { epoch := layerDuration * layersPerEpoch genesis := time.Now().Add(layerDuration).Round(layerDuration) poetCfg := activation.PoetConfig{ - RequestTimeout: epoch / 5, - RequestRetryDelay: epoch / 50, - MaxRequestRetries: 10, - PhaseShift: epoch, - CycleGap: 3 * epoch / 4, - GracePeriod: epoch / 4, - SubmitChallengeTimeout: epoch / 4, - FetchProofTimeout: epoch / 5, + RequestTimeout: epoch / 5, + RequestRetryDelay: epoch / 50, + MaxRequestRetries: 10, + PhaseShift: epoch, + CycleGap: 3 * epoch / 4, + GracePeriod: epoch / 4, } scrypt := testPostSetupOpts(t).Scrypt diff --git a/cmd/root.go b/cmd/root.go index 8724ad5a20..e4af0c60ff 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -325,11 +325,6 @@ func AddFlags(flagSet *pflag.FlagSet, cfg *config.Config) (configPath *string) { cfg.POET.CycleGap, "cycle gap of poet server: gap between poet rounds") flagSet.DurationVar(&cfg.POET.GracePeriod, "grace-period", cfg.POET.GracePeriod, "time before poet round starts, when the node builds and submits a challenge") - flagSet.DurationVar(&cfg.POET.SubmitChallengeTimeout, "submit-challenge-timeout", - cfg.POET.SubmitChallengeTimeout, - "time within grace period, when post challenge must be submitted to poet server") - flagSet.DurationVar(&cfg.POET.FetchProofTimeout, "get-proof-timeout", - cfg.POET.FetchProofTimeout, "time period when ready poet proof must be fetched") flagSet.DurationVar(&cfg.POET.RequestTimeout, "poet-default-request-timeout", cfg.POET.RequestTimeout, "default timeout for poet requests") From 9435aeefd384adada18d99fd3eada43da5775e98 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 10:10:13 +0200 Subject: [PATCH 11/26] removed overengineering2 --- systest/tests/distributed_post_verification_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/systest/tests/distributed_post_verification_test.go b/systest/tests/distributed_post_verification_test.go index 7a5e9b7166..a719fc6145 100644 --- a/systest/tests/distributed_post_verification_test.go +++ b/systest/tests/distributed_post_verification_test.go @@ -65,8 +65,6 @@ func TestPostMalfeasanceProof(t *testing.T) { require.NoError(t, os.Mkdir(cfg.P2P.DataDir, os.ModePerm)) cfg.POET.RequestTimeout = time.Minute - cfg.POET.FetchProofTimeout = time.Minute - cfg.POET.SubmitChallengeTimeout = time.Minute cfg.POET.MaxRequestRetries = 10 var bootnodes []*cluster.NodeClient From d515791c9a9dd778ff7b65d03932738301567280 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 13:39:27 +0200 Subject: [PATCH 12/26] reverted timeout to Proof method, fixed some tests --- activation/activation_test.go | 4 ++-- activation/poet.go | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/activation/activation_test.go b/activation/activation_test.go index ee41e03a3c..70f8436928 100644 --- a/activation/activation_test.go +++ b/activation/activation_test.go @@ -1145,7 +1145,7 @@ func TestBuilder_RetryPublishActivationTx(t *testing.T) { } func TestBuilder_InitialProofGeneratedOnce(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] post := nipost.Post{ @@ -1184,7 +1184,7 @@ func TestBuilder_InitialProofGeneratedOnce(t *testing.T) { } func TestBuilder_InitialPostIsPersisted(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] commitmentATX := types.RandomATXID() diff --git a/activation/poet.go b/activation/poet.go index 9d86ef2f2f..a803f7d925 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -511,7 +511,10 @@ func (c *poetService) Proof(ctx context.Context, roundID string) (*types.PoetPro c.logger.Warn("cached members found but proof not found in db", zap.String("round_id", roundID), zap.Error(err)) } - proof, members, err := c.client.Proof(ctx, roundID) + proofCtx, cacnel := withConditionalTimeout(ctx, c.requestTimeout) + defer cacnel() + + proof, members, err := c.client.Proof(proofCtx, roundID) if err != nil { return nil, nil, fmt.Errorf("getting proof: %w", err) } From 50a3e0ec737940dd813a57371a7d47c569cc1ee9 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 13:56:18 +0200 Subject: [PATCH 13/26] added PositioningATXSelectionTimeout to all envs --- config/mainnet.go | 13 +++++++------ config/presets/fastnet.go | 1 + config/presets/standalone.go | 1 + 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/config/mainnet.go b/config/mainnet.go index 79666f7c1c..267b5a6da0 100644 --- a/config/mainnet.go +++ b/config/mainnet.go @@ -161,12 +161,13 @@ func MainnetConfig() Config { }, POET: activation.PoetConfig{ // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - RequestTimeout: 1100 * time.Second, - RequestRetryDelay: 10 * time.Second, - MaxRequestRetries: 10, - PhaseShift: 240 * time.Hour, - CycleGap: 12 * time.Hour, - GracePeriod: 1 * time.Hour, + RequestTimeout: 1100 * time.Second, + RequestRetryDelay: 10 * time.Second, + MaxRequestRetries: 10, + PhaseShift: 240 * time.Hour, + CycleGap: 12 * time.Hour, + GracePeriod: 1 * time.Hour, + PositioningATXSelectionTimeout: 50 * time.Minute, }, POST: activation.PostConfig{ MinNumUnits: 4, diff --git a/config/presets/fastnet.go b/config/presets/fastnet.go index 0e811edc00..d645a53c10 100644 --- a/config/presets/fastnet.go +++ b/config/presets/fastnet.go @@ -94,6 +94,7 @@ func fastnet() config.Config { conf.POET.GracePeriod = 10 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second + conf.POET.PositioningATXSelectionTimeout = 25 * time.Minute // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second diff --git a/config/presets/standalone.go b/config/presets/standalone.go index 12eb0308d2..29b2d11bcd 100644 --- a/config/presets/standalone.go +++ b/config/presets/standalone.go @@ -80,6 +80,7 @@ func standalone() config.Config { conf.POET.GracePeriod = 12 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second + conf.POET.PositioningATXSelectionTimeout = 25 * time.Minute // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second From 4d067c6c45e8f48b776f85c691338fcd85cbbf07 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 16:05:20 +0200 Subject: [PATCH 14/26] fix test and timeout --- activation/poet.go | 8 ++++---- config/presets/standalone.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/activation/poet.go b/activation/poet.go index a803f7d925..1ba28e6014 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -499,6 +499,9 @@ func (c *poetService) Submit( } func (c *poetService) Proof(ctx context.Context, roundID string) (*types.PoetProof, []types.Hash32, error) { + getProofsCtx, cancel := withConditionalTimeout(ctx, c.requestTimeout) + defer cancel() + c.gettingProof.Lock() defer c.gettingProof.Unlock() @@ -511,10 +514,7 @@ func (c *poetService) Proof(ctx context.Context, roundID string) (*types.PoetPro c.logger.Warn("cached members found but proof not found in db", zap.String("round_id", roundID), zap.Error(err)) } - proofCtx, cacnel := withConditionalTimeout(ctx, c.requestTimeout) - defer cacnel() - - proof, members, err := c.client.Proof(proofCtx, roundID) + proof, members, err := c.client.Proof(getProofsCtx, roundID) if err != nil { return nil, nil, fmt.Errorf("getting proof: %w", err) } diff --git a/config/presets/standalone.go b/config/presets/standalone.go index 29b2d11bcd..af622b7715 100644 --- a/config/presets/standalone.go +++ b/config/presets/standalone.go @@ -80,7 +80,7 @@ func standalone() config.Config { conf.POET.GracePeriod = 12 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.PositioningATXSelectionTimeout = 25 * time.Minute + conf.POET.PositioningATXSelectionTimeout = 25 * time.Second // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second From fcd2ab1eb73c9b67270155804ed289119832eb44 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 16:10:45 +0200 Subject: [PATCH 15/26] revert unnecessary changes --- activation/activation_multi_test.go | 11 ++--------- activation/activation_test.go | 17 ++++++----------- activation/e2e/activation_test.go | 6 +++--- activation/poet_client_test.go | 27 ++++++++++++--------------- config/presets/fastnet.go | 2 +- 5 files changed, 24 insertions(+), 39 deletions(-) diff --git a/activation/activation_multi_test.go b/activation/activation_multi_test.go index 6368f50427..ce795e53b5 100644 --- a/activation/activation_multi_test.go +++ b/activation/activation_multi_test.go @@ -232,10 +232,7 @@ func TestRegossip(t *testing.T) { } func Test_Builder_Multi_InitialPost(t *testing.T) { - tab := newTestBuilder(t, 5, WithPoetConfig( - PoetConfig{ - PhaseShift: layerDuration * 4, - })) + tab := newTestBuilder(t, 5, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) var eg errgroup.Group for _, sig := range tab.signers { @@ -274,11 +271,7 @@ func Test_Builder_Multi_InitialPost(t *testing.T) { func Test_Builder_Multi_HappyPath(t *testing.T) { layerDuration := 2 * time.Second - tab := newTestBuilder(t, 3, WithPoetConfig( - PoetConfig{ - PhaseShift: layerDuration * 4, - CycleGap: layerDuration, - })) + tab := newTestBuilder(t, 3, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4, CycleGap: layerDuration})) // step 1: build initial posts initialPostChan := make(chan struct{}) diff --git a/activation/activation_test.go b/activation/activation_test.go index 70f8436928..a3c696cb24 100644 --- a/activation/activation_test.go +++ b/activation/activation_test.go @@ -344,10 +344,7 @@ func TestBuilder_StopSmeshing_failsWhenNotStarted(t *testing.T) { } func TestBuilder_PublishActivationTx_HappyFlow(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig( - PoetConfig{ - PhaseShift: layerDuration, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration})) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -383,9 +380,7 @@ func TestBuilder_PublishActivationTx_HappyFlow(t *testing.T) { // failing with ErrATXChallengeExpired. func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { // Arrange - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - PhaseShift: layerDuration * 4, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] // current layer is too late to be able to build a nipost on time @@ -434,9 +429,7 @@ func TestBuilder_Loop_WaitsOnStaleChallenge(t *testing.T) { } func TestBuilder_PublishActivationTx_FaultyNet(t *testing.T) { - tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{ - PhaseShift: layerDuration * 4, - })) + tab := newTestBuilder(t, 1, WithPoetConfig(PoetConfig{PhaseShift: layerDuration * 4})) sig := maps.Values(tab.signers)[0] posEpoch := postGenesisEpoch @@ -508,7 +501,9 @@ func TestBuilder_PublishActivationTx_FaultyNet(t *testing.T) { } func TestBuilder_PublishActivationTx_UsesExistingChallengeOnLatePublish(t *testing.T) { - poetCfg := PoetConfig{PhaseShift: layerDuration * 4} + poetCfg := PoetConfig{ + PhaseShift: layerDuration * 4, + } tab := newTestBuilder(t, 1, WithPoetConfig(poetCfg)) sig := maps.Values(tab.signers)[0] diff --git a/activation/e2e/activation_test.go b/activation/e2e/activation_test.go index 2732daed61..e2bd4dd098 100644 --- a/activation/e2e/activation_test.go +++ b/activation/e2e/activation_test.go @@ -85,12 +85,12 @@ func Test_BuilderWithMultipleClients(t *testing.T) { epoch := layerDuration * layersPerEpoch genesis := time.Now().Add(layerDuration).Round(layerDuration) poetCfg := activation.PoetConfig{ - RequestTimeout: epoch / 5, - RequestRetryDelay: epoch / 50, - MaxRequestRetries: 10, PhaseShift: epoch, CycleGap: 3 * epoch / 4, GracePeriod: epoch / 4, + RequestTimeout: epoch / 5, + RequestRetryDelay: epoch / 50, + MaxRequestRetries: 10, } scrypt := testPostSetupOpts(t).Scrypt diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index e0744fca9a..6b8e5126f6 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -30,22 +30,20 @@ func Test_HTTPPoetClient_ParsesURL(t *testing.T) { t.Run("add http if missing", func(t *testing.T) { t.Parallel() - client, err := NewHTTPPoetClient(types.PoetServer{Address: "bla"}, - PoetConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, - }) + client, err := NewHTTPPoetClient(types.PoetServer{Address: "bla"}, PoetConfig{ + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, + }) require.NoError(t, err) require.Equal(t, "http://bla", client.baseURL.String()) }) t.Run("do not change scheme if present", func(t *testing.T) { t.Parallel() - client, err := NewHTTPPoetClient(types.PoetServer{Address: "https://bla"}, - PoetConfig{ - PhaseShift: cfg.PhaseShift, - CycleGap: cfg.CycleGap, - }) + client, err := NewHTTPPoetClient(types.PoetServer{Address: "https://bla"}, PoetConfig{ + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, + }) require.NoError(t, err) require.Equal(t, "https://bla", client.baseURL.String()) }) @@ -115,11 +113,10 @@ func Test_HTTPPoetClient_Address_Mainnet(t *testing.T) { for _, url := range poETServers { t.Run(url, func(t *testing.T) { - client, err := NewHTTPPoetClient(types.PoetServer{Address: url}, - PoetConfig{ - PhaseShift: poetCfg.PhaseShift, - CycleGap: poetCfg.CycleGap, - }) + client, err := NewHTTPPoetClient(types.PoetServer{Address: url}, PoetConfig{ + PhaseShift: poetCfg.PhaseShift, + CycleGap: poetCfg.CycleGap, + }) require.NoError(t, err) require.Equal(t, url, client.Address()) }) diff --git a/config/presets/fastnet.go b/config/presets/fastnet.go index d645a53c10..6ea5ee5fe4 100644 --- a/config/presets/fastnet.go +++ b/config/presets/fastnet.go @@ -94,7 +94,7 @@ func fastnet() config.Config { conf.POET.GracePeriod = 10 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.PositioningATXSelectionTimeout = 25 * time.Minute + conf.POET.PositioningATXSelectionTimeout = 25 * time.Second // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second From eb4e6230007b877ee5d25d977cc2534239ae6a7b Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 16:19:40 +0200 Subject: [PATCH 16/26] added PositioningATXSelectionTimeout to test env --- config/presets/fastnet.go | 2 +- config/presets/standalone.go | 2 +- config/presets/testnet.go | 13 +++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/config/presets/fastnet.go b/config/presets/fastnet.go index 6ea5ee5fe4..ac3373fe86 100644 --- a/config/presets/fastnet.go +++ b/config/presets/fastnet.go @@ -94,7 +94,7 @@ func fastnet() config.Config { conf.POET.GracePeriod = 10 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.PositioningATXSelectionTimeout = 25 * time.Second + conf.POET.PositioningATXSelectionTimeout = 8 * time.Second // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second diff --git a/config/presets/standalone.go b/config/presets/standalone.go index af622b7715..d293690a2e 100644 --- a/config/presets/standalone.go +++ b/config/presets/standalone.go @@ -80,7 +80,7 @@ func standalone() config.Config { conf.POET.GracePeriod = 12 * time.Second conf.POET.CycleGap = 30 * time.Second conf.POET.PhaseShift = 30 * time.Second - conf.POET.PositioningATXSelectionTimeout = 25 * time.Second + conf.POET.PositioningATXSelectionTimeout = 8 * time.Second // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 conf.POET.RequestTimeout = 12 * time.Second conf.POET.RequestRetryDelay = 1 * time.Second diff --git a/config/presets/testnet.go b/config/presets/testnet.go index 4ce4606886..f081c47a43 100644 --- a/config/presets/testnet.go +++ b/config/presets/testnet.go @@ -113,12 +113,13 @@ func testnet() config.Config { }, POET: activation.PoetConfig{ // RequestTimeout = RequestRetryDelay * 2 * MaxRequestRetries*(MaxRequestRetries+1)/2 - RequestTimeout: 550 * time.Second, - RequestRetryDelay: 5 * time.Second, - MaxRequestRetries: 10, - PhaseShift: 12 * time.Hour, - CycleGap: 2 * time.Hour, - GracePeriod: 10 * time.Minute, + RequestTimeout: 550 * time.Second, + RequestRetryDelay: 5 * time.Second, + MaxRequestRetries: 10, + PositioningATXSelectionTimeout: 8 * time.Minute, + PhaseShift: 12 * time.Hour, + CycleGap: 2 * time.Hour, + GracePeriod: 10 * time.Minute, }, POST: activation.PostConfig{ MinNumUnits: 2, From bfe0c34b798a598088bcc5469b948ceffa8fd94a Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 17 Jul 2024 16:23:02 +0200 Subject: [PATCH 17/26] fix flag --- cmd/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index e4af0c60ff..99fd98ac19 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -325,7 +325,7 @@ func AddFlags(flagSet *pflag.FlagSet, cfg *config.Config) (configPath *string) { cfg.POET.CycleGap, "cycle gap of poet server: gap between poet rounds") flagSet.DurationVar(&cfg.POET.GracePeriod, "grace-period", cfg.POET.GracePeriod, "time before poet round starts, when the node builds and submits a challenge") - flagSet.DurationVar(&cfg.POET.RequestTimeout, "poet-default-request-timeout", + flagSet.DurationVar(&cfg.POET.RequestTimeout, "poet-request-timeout", cfg.POET.RequestTimeout, "default timeout for poet requests") /**======================== bootstrap data updater Flags ========================== **/ From bc743d2875287862807d9e7f6153f3318681f434 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Thu, 18 Jul 2024 10:25:49 +0200 Subject: [PATCH 18/26] added changelog --- CHANGELOG.md | 5 +++++ activation/poet.go | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87f1876ac2..638f9bb380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ See [RELEASE](./RELEASE.md) for workflow instructions. +## UNRELEASED +### Improvements +* [#6035](https://github.com/spacemeshos/go-spacemesh/issues/6035) Fixed an issue where the node retried registering for the PoET round + only for 15-20 minutes instead of continuing until the start of the round + ## Release v1.6.1 ### Improvements diff --git a/activation/poet.go b/activation/poet.go index 1ba28e6014..3b2f2ab411 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -492,8 +492,6 @@ func (c *poetService) Submit( return nil, fmt.Errorf("recertifying: %w", err) } return c.client.Submit(ctx, deadline, prefix, challenge, signature, nodeID, *auth) - case errors.Is(err, context.DeadlineExceeded): - logger.Warn("failed to submit challenge: probably submit challenge timeout is too short", zap.Error(err)) } return nil, fmt.Errorf("submitting challenge: %w", err) } From 0d30ee15f75d2f6b1c0ecb2064c89461c0370ec8 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Sat, 27 Jul 2024 19:30:46 +0200 Subject: [PATCH 19/26] unlimited retry --- activation/poet.go | 51 ++++++++++++++++++++++++---------- activation/poet_client_test.go | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 14 deletions(-) diff --git a/activation/poet.go b/activation/poet.go index 3b2f2ab411..54cf68f735 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "math" "net/http" "net/url" "sync" @@ -32,6 +33,12 @@ var ( errCertificatesNotSupported = errors.New("poet doesn't support certificates") ) +const ( + submitPath = "/v1/submit" + infoPath = "/v1/info" + proofPath = "/v1/proofs" +) + type PoetPowParams struct { Challenge []byte Difficulty uint @@ -66,10 +73,11 @@ type PoetClient interface { // HTTPPoetClient implements PoetProvingServiceClient interface. type HTTPPoetClient struct { - id []byte - baseURL *url.URL - client *retryablehttp.Client - logger *zap.Logger + id []byte + baseURL *url.URL + client *retryablehttp.Client + submitChallengeClient *retryablehttp.Client + logger *zap.Logger } func checkRetry(ctx context.Context, resp *http.Response, err error) (bool, error) { @@ -133,6 +141,14 @@ func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClie CheckRetry: checkRetry, } + submitChallengeClient := &retryablehttp.Client{ + RetryMax: math.MaxInt, + RetryWaitMin: cfg.RequestRetryDelay, + RetryWaitMax: 2 * cfg.RequestRetryDelay, + Backoff: retryablehttp.LinearJitterBackoff, + CheckRetry: checkRetry, + } + baseURL, err := url.Parse(server.Address) if err != nil { return nil, fmt.Errorf("parsing address: %w", err) @@ -142,10 +158,11 @@ func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClie } poetClient := &HTTPPoetClient{ - id: server.Pubkey.Bytes(), - baseURL: baseURL, - client: client, - logger: zap.NewNop(), + id: server.Pubkey.Bytes(), + baseURL: baseURL, + client: client, + submitChallengeClient: submitChallengeClient, + logger: zap.NewNop(), } for _, opt := range opts { opt(poetClient) @@ -155,11 +172,11 @@ func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClie "created poet client", zap.Stringer("url", baseURL), zap.Binary("pubkey", server.Pubkey.Bytes()), - zap.Int("max retries", client.RetryMax), + zap.Int("default max retries", client.RetryMax), + zap.Int("submit challenge max retries", submitChallengeClient.RetryMax), zap.Duration("min retry wait", client.RetryWaitMin), zap.Duration("max retry wait", client.RetryWaitMax), ) - return poetClient, nil } @@ -230,7 +247,7 @@ func (c *HTTPPoetClient) Submit( } resBody := rpcapi.SubmitResponse{} - if err := c.req(ctx, http.MethodPost, "/v1/submit", &request, &resBody); err != nil { + if err := c.req(ctx, http.MethodPost, submitPath, &request, &resBody); err != nil { return nil, fmt.Errorf("submitting challenge: %w", err) } roundEnd := time.Time{} @@ -243,7 +260,7 @@ func (c *HTTPPoetClient) Submit( func (c *HTTPPoetClient) info(ctx context.Context) (*rpcapi.InfoResponse, error) { resBody := rpcapi.InfoResponse{} - if err := c.req(ctx, http.MethodGet, "/v1/info", nil, &resBody); err != nil { + if err := c.req(ctx, http.MethodGet, infoPath, nil, &resBody); err != nil { return nil, fmt.Errorf("getting poet info: %w", err) } return &resBody, nil @@ -252,7 +269,7 @@ func (c *HTTPPoetClient) info(ctx context.Context) (*rpcapi.InfoResponse, error) // Proof implements PoetProvingServiceClient. func (c *HTTPPoetClient) Proof(ctx context.Context, roundID string) (*types.PoetProofMessage, []types.Hash32, error) { resBody := rpcapi.ProofResponse{} - if err := c.req(ctx, http.MethodGet, fmt.Sprintf("/v1/proofs/%s", roundID), nil, &resBody); err != nil { + if err := c.req(ctx, http.MethodGet, fmt.Sprintf(proofPath+"/%s", roundID), nil, &resBody); err != nil { return nil, nil, fmt.Errorf("getting proof: %w", err) } @@ -296,7 +313,13 @@ func (c *HTTPPoetClient) req(ctx context.Context, method, path string, reqBody, } req.Header.Set("Content-Type", "application/json") - res, err := c.client.Do(req) + var res *http.Response + + if path == submitPath { + res, err = c.submitChallengeClient.Do(req) + } else { + res, err = c.client.Do(req) + } if err != nil { return fmt.Errorf("doing request: %w", err) } diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index 6b8e5126f6..41a1573e58 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -82,6 +82,57 @@ func Test_HTTPPoetClient_Submit(t *testing.T) { require.NoError(t, err) } +func Test_HTTPPoetClient_SubmitTillCtxDeadlineReached(t *testing.T) { + t.Parallel() + + ctxWithDeadline, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second)) + defer cancel() + + mux := http.NewServeMux() + mux.HandleFunc("POST /v1/submit", func(w http.ResponseWriter, r *http.Request) { + now := time.Now() + deadline, _ := ctxWithDeadline.Deadline() + remain := deadline.Sub(now) + + if remain.Seconds() <= time.Second.Seconds() { + resp, err := protojson.Marshal(&rpcapi.SubmitResponse{}) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } else { + w.Write(resp) + } + return + } + http.Error(w, "some_error", http.StatusInternalServerError) + }) + + ts := httptest.NewServer(mux) + defer ts.Close() + + cfg := server.DefaultRoundConfig() + client, err := NewHTTPPoetClient(types.PoetServer{Address: ts.URL}, PoetConfig{ + PhaseShift: cfg.PhaseShift, + CycleGap: cfg.CycleGap, + MaxRequestRetries: 1, + }, withCustomHttpClient(ts.Client())) + require.NoError(t, err) + + startTime := time.Now() + _, err = client.Submit( + ctxWithDeadline, + time.Time{}, + nil, + nil, + types.EmptyEdSignature, + types.NodeID{}, + PoetAuth{}, + ) + duration := time.Since(startTime) + + require.NoError(t, err) + require.GreaterOrEqual(t, duration.Seconds(), float64(4)) +} + func Test_HTTPPoetClient_Address(t *testing.T) { t.Parallel() t.Run("with scheme", func(t *testing.T) { From c5be14de7c953e7924217dbd061b30711b0a4ba5 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Thu, 1 Aug 2024 22:21:13 +0200 Subject: [PATCH 20/26] fix issues --- activation/poet.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/activation/poet.go b/activation/poet.go index 022dc412ac..6fc525f1d7 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -146,8 +146,7 @@ func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClie RetryMax: math.MaxInt, RetryWaitMin: cfg.RequestRetryDelay, RetryWaitMax: 2 * cfg.RequestRetryDelay, - Backoff: retryablehttp.LinearJitterBackoff, - CheckRetry: checkRetry, + Backoff: retryablehttp.DefaultBackoff, } baseURL, err := url.Parse(server.Address) From 2c53d3e31f21fce9ccaeec3aec352a51d496a022 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 7 Aug 2024 23:08:53 +0200 Subject: [PATCH 21/26] review fixes --- CHANGELOG.md | 5 ++--- activation/poet.go | 24 +++++++++++------------- activation/poet_client_test.go | 22 ++++------------------ 3 files changed, 17 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f004ae6f9..ba6073d2dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ See [RELEASE](./RELEASE.md) for workflow instructions. ### Features ### Improvements +* [#6035](https://github.com/spacemeshos/go-spacemesh/issues/6035) Fixed an issue where the node retried registering for the PoET round + only for 15-20 minutes instead of continuing until the start of the round ## Release v1.6.4 @@ -24,9 +26,6 @@ See [RELEASE](./RELEASE.md) for workflow instructions. * [#6142](https://github.com/spacemeshos/go-spacemesh/pull/6142) Fix node not dropping peers that are broadcasting invalid ATXs. - -* [#6035](https://github.com/spacemeshos/go-spacemesh/issues/6035) Fixed an issue where the node retried registering for the PoET round - only for 15-20 minutes instead of continuing until the start of the round ## Release v1.6.3 ### Improvements diff --git a/activation/poet.go b/activation/poet.go index 6fc525f1d7..55e3f26819 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -147,6 +147,7 @@ func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClie RetryWaitMin: cfg.RequestRetryDelay, RetryWaitMax: 2 * cfg.RequestRetryDelay, Backoff: retryablehttp.DefaultBackoff, + CheckRetry: retryablehttp.DefaultRetryPolicy, } baseURL, err := url.Parse(server.Address) @@ -190,7 +191,7 @@ func (c *HTTPPoetClient) Address() string { func (c *HTTPPoetClient) PowParams(ctx context.Context) (*PoetPowParams, error) { resBody := rpcapi.PowParamsResponse{} - if err := c.req(ctx, http.MethodGet, "/v1/pow_params", nil, &resBody); err != nil { + if err := c.req(ctx, http.MethodGet, "/v1/pow_params", nil, &resBody, c.client); err != nil { return nil, fmt.Errorf("querying PoW params: %w", err) } @@ -247,7 +248,7 @@ func (c *HTTPPoetClient) Submit( } resBody := rpcapi.SubmitResponse{} - if err := c.req(ctx, http.MethodPost, submitPath, &request, &resBody); err != nil { + if err := c.req(ctx, http.MethodPost, submitPath, &request, &resBody, c.submitChallengeClient); err != nil { return nil, fmt.Errorf("submitting challenge: %w", err) } roundEnd := time.Time{} @@ -260,7 +261,7 @@ func (c *HTTPPoetClient) Submit( func (c *HTTPPoetClient) info(ctx context.Context) (*rpcapi.InfoResponse, error) { resBody := rpcapi.InfoResponse{} - if err := c.req(ctx, http.MethodGet, infoPath, nil, &resBody); err != nil { + if err := c.req(ctx, http.MethodGet, infoPath, nil, &resBody, c.client); err != nil { return nil, fmt.Errorf("getting poet info: %w", err) } return &resBody, nil @@ -269,7 +270,7 @@ func (c *HTTPPoetClient) info(ctx context.Context) (*rpcapi.InfoResponse, error) // Proof implements PoetProvingServiceClient. func (c *HTTPPoetClient) Proof(ctx context.Context, roundID string) (*types.PoetProofMessage, []types.Hash32, error) { resBody := rpcapi.ProofResponse{} - if err := c.req(ctx, http.MethodGet, fmt.Sprintf(proofPath+"/%s", roundID), nil, &resBody); err != nil { + if err := c.req(ctx, http.MethodGet, fmt.Sprintf("%s/%s", proofPath, roundID), nil, &resBody, c.client); err != nil { return nil, nil, fmt.Errorf("getting proof: %w", err) } @@ -301,7 +302,11 @@ func (c *HTTPPoetClient) Proof(ctx context.Context, roundID string) (*types.Poet return &proof, members, nil } -func (c *HTTPPoetClient) req(ctx context.Context, method, path string, reqBody, resBody proto.Message) error { +func (c *HTTPPoetClient) req( + ctx context.Context, + method, path string, + reqBody, resBody proto.Message, + client *retryablehttp.Client) error { jsonReqBody, err := protojson.Marshal(reqBody) if err != nil { return fmt.Errorf("marshaling request body: %w", err) @@ -313,13 +318,7 @@ func (c *HTTPPoetClient) req(ctx context.Context, method, path string, reqBody, } req.Header.Set("Content-Type", "application/json") - var res *http.Response - - if path == submitPath { - res, err = c.submitChallengeClient.Do(req) - } else { - res, err = c.client.Do(req) - } + res, err := client.Do(req) if err != nil { return fmt.Errorf("doing request: %w", err) } @@ -350,7 +349,6 @@ func (c *HTTPPoetClient) req(ctx context.Context, method, path string, reqBody, return fmt.Errorf("decoding response body to proto: %w", err) } } - return nil } diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index 41a1573e58..52d49ee8dd 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -85,24 +85,13 @@ func Test_HTTPPoetClient_Submit(t *testing.T) { func Test_HTTPPoetClient_SubmitTillCtxDeadlineReached(t *testing.T) { t.Parallel() + const maxRequests = 1 + ctxWithDeadline, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second)) defer cancel() mux := http.NewServeMux() mux.HandleFunc("POST /v1/submit", func(w http.ResponseWriter, r *http.Request) { - now := time.Now() - deadline, _ := ctxWithDeadline.Deadline() - remain := deadline.Sub(now) - - if remain.Seconds() <= time.Second.Seconds() { - resp, err := protojson.Marshal(&rpcapi.SubmitResponse{}) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } else { - w.Write(resp) - } - return - } http.Error(w, "some_error", http.StatusInternalServerError) }) @@ -113,11 +102,10 @@ func Test_HTTPPoetClient_SubmitTillCtxDeadlineReached(t *testing.T) { client, err := NewHTTPPoetClient(types.PoetServer{Address: ts.URL}, PoetConfig{ PhaseShift: cfg.PhaseShift, CycleGap: cfg.CycleGap, - MaxRequestRetries: 1, + MaxRequestRetries: maxRequests, }, withCustomHttpClient(ts.Client())) require.NoError(t, err) - startTime := time.Now() _, err = client.Submit( ctxWithDeadline, time.Time{}, @@ -127,10 +115,8 @@ func Test_HTTPPoetClient_SubmitTillCtxDeadlineReached(t *testing.T) { types.NodeID{}, PoetAuth{}, ) - duration := time.Since(startTime) - require.NoError(t, err) - require.GreaterOrEqual(t, duration.Seconds(), float64(4)) + require.ErrorIs(t, err, context.DeadlineExceeded) } func Test_HTTPPoetClient_Address(t *testing.T) { From 8e729ea49b2968f8f232578b9a389581c739572a Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 12 Aug 2024 09:16:05 +0200 Subject: [PATCH 22/26] minor fixes --- activation/activation.go | 14 ++++++++------ activation/poet.go | 10 ++++------ activation/poet_client_test.go | 24 +++++++++++------------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/activation/activation.go b/activation/activation.go index ee0227b249..9f7e11b723 100644 --- a/activation/activation.go +++ b/activation/activation.go @@ -40,13 +40,15 @@ var ( // PoetConfig is the configuration to interact with the poet server. type PoetConfig struct { // Start of new PoET round - PhaseShift time.Duration `mapstructure:"phase-shift"` + PhaseShift time.Duration `mapstructure:"phase-shift"` // A gap between end of old PoET round and start of new one - CycleGap time.Duration `mapstructure:"cycle-gap"` - // Time in the end of cycle gap, when PoST challenge must be build and send to PoET server - GracePeriod time.Duration `mapstructure:"grace-period"` - RequestTimeout time.Duration `mapstructure:"poet-request-timeout"` - RequestRetryDelay time.Duration `mapstructure:"retry-delay"` + CycleGap time.Duration `mapstructure:"cycle-gap"` + // Time duration measured from the end of cycle gap, when we start to build the NiPoST challenge. + // The later we start (the smaller this value is) + // the higher is the chance for getting a good positioning ATX. + GracePeriod time.Duration `mapstructure:"grace-period"` + RequestTimeout time.Duration `mapstructure:"poet-request-timeout"` + RequestRetryDelay time.Duration `mapstructure:"retry-delay"` // Period to find positioning ATX. Must be less, than GracePeriod PositioningATXSelectionTimeout time.Duration `mapstructure:"positioning-atx-selection-timeout"` CertifierInfoCacheTTL time.Duration `mapstructure:"certifier-info-cache-ttl"` diff --git a/activation/poet.go b/activation/poet.go index d08da76255..b9d0c4d720 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -35,9 +35,7 @@ var ( ) const ( - submitPath = "/v1/submit" - infoPath = "/v1/info" - proofPath = "/v1/proofs" + proofPath = "/v1/proofs" ) type PoetPowParams struct { @@ -248,7 +246,7 @@ func (c *HTTPPoetClient) Submit( } resBody := rpcapi.SubmitResponse{} - if err := c.req(ctx, http.MethodPost, submitPath, &request, &resBody, c.submitChallengeClient); err != nil { + if err := c.req(ctx, http.MethodPost, "/v1/submit", &request, &resBody, c.submitChallengeClient); err != nil { return nil, fmt.Errorf("submitting challenge: %w", err) } roundEnd := time.Time{} @@ -261,7 +259,7 @@ func (c *HTTPPoetClient) Submit( func (c *HTTPPoetClient) info(ctx context.Context) (*rpcapi.InfoResponse, error) { resBody := rpcapi.InfoResponse{} - if err := c.req(ctx, http.MethodGet, infoPath, nil, &resBody, c.client); err != nil { + if err := c.req(ctx, http.MethodGet, "/v1/info", nil, &resBody, c.client); err != nil { return nil, fmt.Errorf("getting poet info: %w", err) } return &resBody, nil @@ -270,7 +268,7 @@ func (c *HTTPPoetClient) info(ctx context.Context) (*rpcapi.InfoResponse, error) // Proof implements PoetProvingServiceClient. func (c *HTTPPoetClient) Proof(ctx context.Context, roundID string) (*types.PoetProofMessage, []types.Hash32, error) { resBody := rpcapi.ProofResponse{} - if err := c.req(ctx, http.MethodGet, fmt.Sprintf("%s/%s", proofPath, roundID), nil, &resBody, c.client); err != nil { + if err := c.req(ctx, http.MethodGet, fmt.Sprintf("/v1/proofs/%s", roundID), nil, &resBody, c.client); err != nil { return nil, nil, fmt.Errorf("getting proof: %w", err) } diff --git a/activation/poet_client_test.go b/activation/poet_client_test.go index 3f577579df..c2eda2d964 100644 --- a/activation/poet_client_test.go +++ b/activation/poet_client_test.go @@ -84,32 +84,30 @@ func Test_HTTPPoetClient_Submit(t *testing.T) { require.NoError(t, err) } -func Test_HTTPPoetClient_SubmitTillCtxDeadlineReached(t *testing.T) { +func Test_HTTPPoetClient_SubmitTillCtxCanceled(t *testing.T) { t.Parallel() - - const maxRequests = 1 - - ctxWithDeadline, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second)) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() - + tries := 0 mux := http.NewServeMux() mux.HandleFunc("POST /v1/submit", func(w http.ResponseWriter, r *http.Request) { + tries += 1 + if tries == 3 { + cancel() + } http.Error(w, "some_error", http.StatusInternalServerError) }) - ts := httptest.NewServer(mux) defer ts.Close() - cfg := server.DefaultRoundConfig() client, err := NewHTTPPoetClient(types.PoetServer{Address: ts.URL}, PoetConfig{ PhaseShift: cfg.PhaseShift, CycleGap: cfg.CycleGap, - MaxRequestRetries: maxRequests, + MaxRequestRetries: 1, }, withCustomHttpClient(ts.Client())) require.NoError(t, err) - _, err = client.Submit( - ctxWithDeadline, + ctx, time.Time{}, nil, nil, @@ -117,8 +115,8 @@ func Test_HTTPPoetClient_SubmitTillCtxDeadlineReached(t *testing.T) { types.NodeID{}, PoetAuth{}, ) - - require.ErrorIs(t, err, context.DeadlineExceeded) + require.ErrorIs(t, err, context.Canceled) + require.Equal(t, 3, tries) } func Test_HTTPPoetClient_Address(t *testing.T) { From 1e7976301268d0c8377d69bb0a9e14c1063c1b11 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 12 Aug 2024 09:25:00 +0200 Subject: [PATCH 23/26] make linter happy --- activation/poet.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/activation/poet.go b/activation/poet.go index fb4d5a38b7..dc12e68012 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -35,10 +35,6 @@ var ( ErrIncompatiblePhaseShift = errors.New("fetched poet phase_shift is incompatible with configured phase_shift") ) -const ( - proofPath = "/v1/proofs" -) - type PoetPowParams struct { Challenge []byte Difficulty uint @@ -319,7 +315,8 @@ func (c *HTTPPoetClient) req( ctx context.Context, method, path string, reqBody, resBody proto.Message, - client *retryablehttp.Client) error { + client *retryablehttp.Client, +) error { jsonReqBody, err := protojson.Marshal(reqBody) if err != nil { return fmt.Errorf("marshaling request body: %w", err) From 1d0dfb01a1deeec787c0cf7ca37127bb90d6760e Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Mon, 12 Aug 2024 09:45:17 +0200 Subject: [PATCH 24/26] fix comment --- activation/activation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activation/activation.go b/activation/activation.go index 9f7e11b723..53624c2fb1 100644 --- a/activation/activation.go +++ b/activation/activation.go @@ -39,7 +39,7 @@ var ( // PoetConfig is the configuration to interact with the poet server. type PoetConfig struct { - // Start of new PoET round + // Offset from the epoch start when the poet round starts PhaseShift time.Duration `mapstructure:"phase-shift"` // A gap between end of old PoET round and start of new one CycleGap time.Duration `mapstructure:"cycle-gap"` From de5cd55721a19b065398c48043bbbcd09a8721a4 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 14 Aug 2024 09:52:18 +0200 Subject: [PATCH 25/26] custom linear jitter --- activation/poet.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/activation/poet.go b/activation/poet.go index dc12e68012..888919663d 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "math" + "math/rand" "net/http" "net/url" "sync" @@ -128,13 +129,31 @@ func WithLogger(logger *zap.Logger) PoetClientOpts { } } +func customLinearJitterBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { + attemptNum++ + if max <= min { + return min * time.Duration(attemptNum) + } + + source := rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) + + jitter := source.Float64() * float64(max-min) + jitterMin := int64(jitter) + int64(min) + + sleep := time.Duration(jitterMin * int64(attemptNum)) + if sleep > max { + sleep = max + } + return sleep +} + // NewHTTPPoetClient returns new instance of HTTPPoetClient connecting to the specified url. func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClientOpts) (*HTTPPoetClient, error) { client := &retryablehttp.Client{ RetryMax: cfg.MaxRequestRetries, RetryWaitMin: cfg.RequestRetryDelay, RetryWaitMax: 2 * cfg.RequestRetryDelay, - Backoff: retryablehttp.LinearJitterBackoff, + Backoff: customLinearJitterBackoff, CheckRetry: checkRetry, } @@ -161,6 +180,7 @@ func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClie submitChallengeClient: submitChallengeClient, logger: zap.NewNop(), } + for _, opt := range opts { opt(poetClient) } From 3ac16db9c79472d29d5cb5af4e0d8a94bea7d569 Mon Sep 17 00:00:00 2001 From: ConvallariaMaj Date: Wed, 14 Aug 2024 11:33:02 +0200 Subject: [PATCH 26/26] fix review issues --- CHANGELOG.md | 1 + activation/activation.go | 9 +++++---- activation/poet.go | 23 ++++++----------------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da21a3c98..9ba268ee7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ such and the node will continue to scan new ATXs for their validity. * [#6142](https://github.com/spacemeshos/go-spacemesh/pull/6142) Fix node not dropping peers that are broadcasting invalid ATXs. + ## Release v1.6.3 ### Improvements diff --git a/activation/activation.go b/activation/activation.go index 53624c2fb1..cea8b0b778 100644 --- a/activation/activation.go +++ b/activation/activation.go @@ -41,11 +41,12 @@ var ( type PoetConfig struct { // Offset from the epoch start when the poet round starts PhaseShift time.Duration `mapstructure:"phase-shift"` - // A gap between end of old PoET round and start of new one + // CycleGap gives the duration between the end of a PoET round and the start of the next CycleGap time.Duration `mapstructure:"cycle-gap"` - // Time duration measured from the end of cycle gap, when we start to build the NiPoST challenge. - // The later we start (the smaller this value is) - // the higher is the chance for getting a good positioning ATX. + // GracePeriod defines the time before the start of the next PoET round until the node + // waits before building its NiPoST challenge. Shorter durations allow the node to + // possibly pick a better positioning ATX, but come with the risk that the node might + // not be able to validate that ATX and has to fall back to using its own previous ATX. GracePeriod time.Duration `mapstructure:"grace-period"` RequestTimeout time.Duration `mapstructure:"poet-request-timeout"` RequestRetryDelay time.Duration `mapstructure:"retry-delay"` diff --git a/activation/poet.go b/activation/poet.go index 888919663d..844cd0038b 100644 --- a/activation/poet.go +++ b/activation/poet.go @@ -6,7 +6,7 @@ import ( "fmt" "io" "math" - "math/rand" + "math/rand/v2" "net/http" "net/url" "sync" @@ -129,22 +129,11 @@ func WithLogger(logger *zap.Logger) PoetClientOpts { } } -func customLinearJitterBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { - attemptNum++ +func customLinearJitterBackoff(min, max time.Duration, _ int, _ *http.Response) time.Duration { if max <= min { - return min * time.Duration(attemptNum) + return min } - - source := rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) - - jitter := source.Float64() * float64(max-min) - jitterMin := int64(jitter) + int64(min) - - sleep := time.Duration(jitterMin * int64(attemptNum)) - if sleep > max { - sleep = max - } - return sleep + return min + rand.N(max-min) } // NewHTTPPoetClient returns new instance of HTTPPoetClient connecting to the specified url. @@ -153,7 +142,7 @@ func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClie RetryMax: cfg.MaxRequestRetries, RetryWaitMin: cfg.RequestRetryDelay, RetryWaitMax: 2 * cfg.RequestRetryDelay, - Backoff: customLinearJitterBackoff, + Backoff: retryablehttp.LinearJitterBackoff, CheckRetry: checkRetry, } @@ -161,7 +150,7 @@ func NewHTTPPoetClient(server types.PoetServer, cfg PoetConfig, opts ...PoetClie RetryMax: math.MaxInt, RetryWaitMin: cfg.RequestRetryDelay, RetryWaitMax: 2 * cfg.RequestRetryDelay, - Backoff: retryablehttp.DefaultBackoff, + Backoff: customLinearJitterBackoff, CheckRetry: retryablehttp.DefaultRetryPolicy, }