Skip to content

Commit

Permalink
go/control/api: Improve node registration status clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
abukosek committed Apr 28, 2023
1 parent 5950615 commit 2922d29
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 19 deletions.
10 changes: 10 additions & 0 deletions .changelog/5256.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
go/control/api: Improve node registration status clarity

Two new fields have been added to the node's control status output
under the registration status section:

- `successful` - true if the registration succeeded.
- `error` - error message if the registration failed.

Also, if the registration descriptor is expired, it is no longer
shown in the output.
11 changes: 11 additions & 0 deletions go/control/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ type IdentityStatus struct {

// RegistrationStatus is the node registration status.
type RegistrationStatus struct {
// LastAttemptSuccessful is true if the last registration attempt has been
// successful.
LastAttemptSuccessful bool `json:"last_attempt_successful"`

// LastAttemptErrorMessage contains the error message if the last
// registration attempt has not been successful.
LastAttemptErrorMessage string `json:"last_attempt_error_message,omitempty"`

// LastAttempt is the time of the last registration attempt.
LastAttempt time.Time `json:"last_attempt"`

// LastRegistration is the time of the last successful registration with the consensus registry
// service. In case the node did not successfully register yet, it will be the zero timestamp.
LastRegistration time.Time `json:"last_registration"`
Expand Down
3 changes: 3 additions & 0 deletions go/oasis-test-runner/scenario/e2e/runtime/node_shutdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ func (sc *nodeShutdownImpl) Run(childEnv *env.Env) error { //nolint: gocyclo
if status.Registration.Descriptor == nil {
return fmt.Errorf("node has not registered")
}
if !status.Registration.LastAttemptSuccessful || status.Registration.LastAttemptErrorMessage != "" {
return fmt.Errorf("node registration was not successful")
}

sc.Logger.Info("requesting node shutdown")
args := []string{
Expand Down
60 changes: 41 additions & 19 deletions go/worker/registration/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ func (w *Worker) gatherConsensusAddresses(sentryConsensusAddrs []node.ConsensusA
return validatedAddrs, nil
}

func (w *Worker) registerNode(epoch beacon.EpochTime, hook RegisterNodeHook) error {
func (w *Worker) registerNode(epoch beacon.EpochTime, hook RegisterNodeHook) (err error) {
identityPublic := w.identity.NodeSigner.Public()
w.logger.Info("performing node (re-)registration",
"epoch", epoch,
Expand Down Expand Up @@ -898,7 +898,31 @@ func (w *Worker) registerNode(epoch beacon.EpochTime, hook RegisterNodeHook) err
SoftwareVersion: node.SoftwareVersion(version.SoftwareVersion),
}

if err := hook(&nodeDesc); err != nil {
// Update the registration status on successful or failed registration.
defer func() {
w.Lock()
defer w.Unlock()

switch err {
case nil:
w.status.LastAttemptSuccessful = true
w.status.LastAttemptErrorMessage = ""
w.status.LastAttempt = time.Now()
w.status.LastRegistration = time.Now()
w.status.Descriptor = &nodeDesc
default:
w.status.LastAttemptSuccessful = false
w.status.LastAttemptErrorMessage = err.Error()
w.status.LastAttempt = time.Now()
if w.status.Descriptor != nil {
if w.status.Descriptor.Expiration < uint64(epoch) {
w.status.Descriptor = nil
}
}
}
}()

if err = hook(&nodeDesc); err != nil {
return err
}

Expand All @@ -908,16 +932,19 @@ func (w *Worker) registerNode(epoch beacon.EpochTime, hook RegisterNodeHook) err
w.logger.Error("not registering: no runtimes provided while runtimes are required",
"node_descriptor", nodeDesc,
)
return fmt.Errorf("registration: no runtimes provided while runtimes are required")

err = fmt.Errorf("registration: no runtimes provided while runtimes are required")
return
}

sentryConsensusAddrs := w.querySentries()

// Add Consensus Addresses if required.
if nodeDesc.HasRoles(registry.ConsensusAddressRequiredRoles) {
addrs, err := w.gatherConsensusAddresses(sentryConsensusAddrs)
if err != nil {
return fmt.Errorf("error gathering consensus addresses: %w", err)
addrs, grr := w.gatherConsensusAddresses(sentryConsensusAddrs)
if grr != nil {
err = fmt.Errorf("error gathering consensus addresses: %w", grr)
return
}
nodeDesc.Consensus.Addresses = addrs
}
Expand All @@ -941,30 +968,25 @@ func (w *Worker) registerNode(epoch beacon.EpochTime, hook RegisterNodeHook) err
nodeSigners = append([]signature.Signer{w.identity.NodeSigner}, nodeSigners...)
}

sigNode, err := node.MultiSignNode(nodeSigners, registry.RegisterNodeSignatureContext, &nodeDesc)
if err != nil {
sigNode, grr := node.MultiSignNode(nodeSigners, registry.RegisterNodeSignatureContext, &nodeDesc)
if grr != nil {
w.logger.Error("failed to register node: unable to sign node descriptor",
"err", err,
"err", grr,
)
return err
err = fmt.Errorf("unable to sign node descriptor: %w", grr)
return
}

tx := registry.NewRegisterNodeTx(0, nil, sigNode)
if err := consensus.SignAndSubmitTx(w.ctx, w.consensus, w.registrationSigner, tx); err != nil {
if err = consensus.SignAndSubmitTx(w.ctx, w.consensus, w.registrationSigner, tx); err != nil {
w.logger.Error("failed to register node",
"err", err,
)
return err
return
}

// Update the registration status on successful registration.
w.RLock()
w.status.LastRegistration = time.Now()
w.status.Descriptor = &nodeDesc
w.RUnlock()

w.logger.Info("node registered with the registry")
return nil
return
}

func (w *Worker) querySentries() []node.ConsensusAddress {
Expand Down

0 comments on commit 2922d29

Please sign in to comment.