Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Simplify switch to different poet services #6116

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
726b49d
check registrations by poet address
ConvallariaMaj Jul 2, 2024
3f68831
Merge branch 'refs/heads/develop' into fix/issue-5563
ConvallariaMaj Jul 9, 2024
5bba175
added:
ConvallariaMaj Jul 10, 2024
8080ed0
fixed:
ConvallariaMaj Jul 11, 2024
7a371a2
fix lint
ConvallariaMaj Jul 11, 2024
89696b1
fix lint2
ConvallariaMaj Jul 11, 2024
189aa4c
- added new test
ConvallariaMaj Jul 14, 2024
97aed33
Merge branch 'refs/heads/develop' into fix/issue-5563
ConvallariaMaj Jul 14, 2024
66ea05e
make linter happy
ConvallariaMaj Jul 15, 2024
f6f2277
fixed review issues
ConvallariaMaj Jul 18, 2024
9a5bad8
refactor tests
ConvallariaMaj Jul 23, 2024
9ffb962
refactored tests
ConvallariaMaj Jul 23, 2024
c4bb081
fix text and make linter happy
ConvallariaMaj Jul 24, 2024
46ce146
fix minor issues
ConvallariaMaj Jul 29, 2024
105e872
final review issues fix
ConvallariaMaj Aug 1, 2024
11a5323
fix test
ConvallariaMaj Aug 1, 2024
0d5dfe8
Merge branch 'refs/heads/develop' into fix/issue-5563
ConvallariaMaj Aug 1, 2024
b245229
fix issues
ConvallariaMaj Aug 2, 2024
8140012
verifying poets configuration
ConvallariaMaj Aug 2, 2024
a02a90c
verifying poets configuration on poet service layer, fixing tests, fi…
ConvallariaMaj Aug 6, 2024
e910e34
test fix
ConvallariaMaj Aug 6, 2024
28f8c17
Merge branch 'refs/heads/develop' into fix/issue-5563
ConvallariaMaj Aug 6, 2024
6d12ab6
review fixes
ConvallariaMaj Aug 6, 2024
71bd472
fix lint
ConvallariaMaj Aug 6, 2024
0ea3dc1
fix merge
ConvallariaMaj Aug 6, 2024
9dc3874
fix mocks
ConvallariaMaj Aug 6, 2024
4c44a49
Fix tests
fasmat Aug 6, 2024
15ebc7b
Fix e2e tests
fasmat Aug 6, 2024
8c8945a
Merge branch 'refs/heads/develop' into fix/issue-5563
ConvallariaMaj Aug 7, 2024
2206f37
fix test
ConvallariaMaj Aug 7, 2024
f9af85a
fix test2
ConvallariaMaj Aug 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 89 additions & 61 deletions activation/nipost.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ func NewNIPostBuilder(
opts ...NIPostBuilderOption,
) (*NIPostBuilder, error) {
b := &NIPostBuilder{
localDB: db,

localDB: db,
postService: postService,
logger: lg,
poetCfg: poetCfg,
Expand Down Expand Up @@ -208,9 +207,9 @@ func (nb *NIPostBuilder) BuildNIPost(
// WE ARE HERE PROOF BECOMES ATX PUBLICATION
// AVAILABLE DEADLINE

poetRoundStart := nb.layerClock.LayerToTime((postChallenge.PublishEpoch - 1).FirstLayer()).
curPoetRoundStart := nb.layerClock.LayerToTime((postChallenge.PublishEpoch - 1).FirstLayer()).
poszu marked this conversation as resolved.
Show resolved Hide resolved
Add(nb.poetCfg.PhaseShift)
poetRoundEnd := nb.layerClock.LayerToTime(postChallenge.PublishEpoch.FirstLayer()).
curPoetRoundEnd := nb.layerClock.LayerToTime(postChallenge.PublishEpoch.FirstLayer()).
Add(nb.poetCfg.PhaseShift).
Add(-nb.poetCfg.CycleGap)

Expand All @@ -223,42 +222,21 @@ func (nb *NIPostBuilder) BuildNIPost(
poetProofDeadline := publishEpochEnd.Add(-nb.poetCfg.CycleGap)

logger.Info("building nipost",
zap.Time("poet round start", poetRoundStart),
zap.Time("poet round end", poetRoundEnd),
zap.Time("poet round start", curPoetRoundStart),
zap.Time("poet round end", curPoetRoundEnd),
zap.Time("publish epoch end", publishEpochEnd),
zap.Uint32("publish epoch", postChallenge.PublishEpoch.Uint32()),
)

// Phase 0: Submit challenge to PoET services.
count, err := nipost.PoetRegistrationCount(nb.localDB, signer.NodeID())
// Deadline: start of PoET round: we will not accept registrations after that
submitedRegistrations, err := nb.submitPoetChallenges(
fasmat marked this conversation as resolved.
Show resolved Hide resolved
ctx,
signer,
poetProofDeadline,
curPoetRoundStart, challenge.Bytes())
if err != nil {
return nil, fmt.Errorf("failed to get poet registration count: %w", err)
}
if count == 0 {
now := time.Now()
// Deadline: start of PoET round for publish epoch. PoET won't accept registrations after that.
if poetRoundStart.Before(now) {
return nil, fmt.Errorf(
"%w: poet round has already started at %s (now: %s)",
ErrATXChallengeExpired,
poetRoundStart,
now,
)
}

submitCtx, cancel := context.WithDeadline(ctx, poetRoundStart)
defer cancel()
err := nb.submitPoetChallenges(submitCtx, signer, poetProofDeadline, challenge.Bytes())
if err != nil {
return nil, fmt.Errorf("submitting to poets: %w", err)
}
count, err := nipost.PoetRegistrationCount(nb.localDB, signer.NodeID())
if err != nil {
return nil, fmt.Errorf("failed to get poet registration count: %w", err)
}
if count == 0 {
return nil, &PoetSvcUnstableError{msg: "failed to submit challenge to any PoET", source: submitCtx.Err()}
}
return nil, fmt.Errorf("submitting to poets: %w", err)
}

// Phase 1: query PoET services for proofs
Expand All @@ -280,8 +258,8 @@ func (nb *NIPostBuilder) BuildNIPost(
)
}

events.EmitPoetWaitProof(signer.NodeID(), postChallenge.PublishEpoch, poetRoundEnd)
poetProofRef, membership, err = nb.getBestProof(ctx, signer.NodeID(), challenge, postChallenge.PublishEpoch)
events.EmitPoetWaitProof(signer.NodeID(), postChallenge.PublishEpoch, curPoetRoundEnd)
poetProofRef, membership, err = nb.getBestProof(ctx, signer.NodeID(), challenge, submitedRegistrations)
if err != nil {
return nil, &PoetSvcUnstableError{msg: "getBestProof failed", source: err}
}
Expand Down Expand Up @@ -388,23 +366,74 @@ func (nb *NIPostBuilder) submitPoetChallenge(
})
}

// Submit the challenge to all registered PoETs.
// Submit the challenge to registered PoETs with given addresses.
poszu marked this conversation as resolved.
Show resolved Hide resolved
func (nb *NIPostBuilder) submitPoetChallenges(
ctx context.Context,
signer *signing.EdSigner,
deadline time.Time,
poetProofDeadline time.Time,
curPoetRoundStartDeadline time.Time,
challenge []byte,
) error {
) ([]nipost.PoETRegistration, error) {
// check if some registrations missing
existingRegistrations, err := nipost.PoetRegistrationsByNodeId(nb.localDB, signer.NodeID())
if err != nil {
return nil, fmt.Errorf("failed to get poet registrations from db: %w", err)
}

var i int
addresses := make([]string, len(nb.poetProvers))
for _, client := range nb.poetProvers {
addresses[i] = client.Address()
i++
}
poszu marked this conversation as resolved.
Show resolved Hide resolved

existingRegistrationsMap := make(map[string]struct{})
for _, er := range existingRegistrations {
existingRegistrationsMap[er.Address] = struct{}{}
}

missingRegistrationsPoETAddresses := make(map[string]struct{})
for _, addr := range addresses {
if _, ok := existingRegistrationsMap[addr]; !ok {
missingRegistrationsPoETAddresses[addr] = struct{}{}
}
}

if len(missingRegistrationsPoETAddresses) == 0 {
return existingRegistrations, nil
}
poszu marked this conversation as resolved.
Show resolved Hide resolved

now := time.Now()
if curPoetRoundStartDeadline.Before(now) {
if len(missingRegistrationsPoETAddresses) == len(addresses) {
return nil, fmt.Errorf(
"%w: poet round has already started at %s (now: %s)",
ErrATXChallengeExpired, // no existing registration, drop current registration challenge
curPoetRoundStartDeadline,
now,
)
}
return existingRegistrations, nil
}

// send registrations to missing addresses
signature := signer.Sign(signing.POET, challenge)
prefix := bytes.Join([][]byte{signer.Prefix(), {byte(signing.POET)}}, nil)
nodeID := signer.NodeID()
g, ctx := errgroup.WithContext(ctx)
errChan := make(chan error, len(nb.poetProvers))

submitCtx, cancel := context.WithDeadline(ctx, curPoetRoundStartDeadline)
defer cancel()

g, ctx := errgroup.WithContext(submitCtx)
fasmat marked this conversation as resolved.
Show resolved Hide resolved
errChan := make(chan error, len(missingRegistrationsPoETAddresses))

for _, client := range nb.poetProvers {
g.Go(func() error {
errChan <- nb.submitPoetChallenge(ctx, nodeID, deadline, client, prefix, challenge, signature)
return nil
})
if _, ok := missingRegistrationsPoETAddresses[client.Address()]; ok {
poszu marked this conversation as resolved.
Show resolved Hide resolved
g.Go(func() error {
errChan <- nb.submitPoetChallenge(ctx, nodeID, poetProofDeadline, client, prefix, challenge, signature)
return nil
})
}
}
g.Wait()
close(errChan)
Expand All @@ -423,18 +452,19 @@ func (nb *NIPostBuilder) submitPoetChallenges(
}
if allInvalid {
nb.logger.Warn("all poet submits were too late. ATX challenge expires", log.ZShortStringer("smesherID", nodeID))
return ErrATXChallengeExpired
return nil, ErrATXChallengeExpired
}
return nil
}

func (nb *NIPostBuilder) getPoetService(ctx context.Context, address string) PoetService {
for _, service := range nb.poetProvers {
if address == service.Address() {
return service
}
existingRegistrations, err = nipost.PoetRegistrationsByNodeIdAndAddresses(nb.localDB, signer.NodeID(), addresses)
poszu marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, fmt.Errorf("failed to get poet registration count: %w", err)
}
return nil

if len(existingRegistrations) == 0 {
return nil, &PoetSvcUnstableError{msg: "failed to submit challenge to any PoET", source: ctx.Err()}
}

return existingRegistrations, nil
}

// membersContainChallenge verifies that the challenge is included in proof's members.
Expand All @@ -451,16 +481,12 @@ func (nb *NIPostBuilder) getBestProof(
ctx context.Context,
nodeID types.NodeID,
challenge types.Hash32,
publishEpoch types.EpochID,
registrations []nipost.PoETRegistration,
) (types.PoetProofRef, *types.MerkleProof, error) {
type poetProof struct {
poet *types.PoetProof
membership *types.MerkleProof
}
registrations, err := nipost.PoetRegistrations(nb.localDB, nodeID)
if err != nil {
return types.PoetProofRef{}, nil, fmt.Errorf("getting poet registrations: %w", err)
}
proofs := make(chan *poetProof, len(registrations))

var eg errgroup.Group
Expand All @@ -471,11 +497,13 @@ func (nb *NIPostBuilder) getBestProof(
zap.String("poet_address", r.Address),
zap.String("round", r.RoundID),
)
client := nb.getPoetService(ctx, r.Address)
if client == nil {

client, ok := nb.poetProvers[r.Address]
if !ok {
logger.Warn("poet client not found")
continue
}

round := r.RoundID
waitDeadline := proofDeadline(r.RoundEnd, nb.poetCfg.CycleGap)
eg.Go(func() error {
Expand Down
Loading
Loading