diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 37dc57e9fa..3050296b7c 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,4 +5,4 @@ When reporting an issue please make sure it contains; * A clear description of the issue * Any logs or stack traces that you can provide (use a site like https://pastebin.com for larger logs) * Steps to reproduce the issue -* The version/tag/release or commit hash it occured on \ No newline at end of file +* The version/tag/release or commit hash it occurred on diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index d3fc126f31..a1e6d591eb 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -35,7 +35,7 @@ import net.corda.node.services.transactions.bftSMaRtSerialFilter import net.corda.node.utilities.createKeyPairAndSelfSignedTLSCertificate import net.corda.node.utilities.registration.HTTPNetworkRegistrationService import net.corda.node.utilities.registration.NodeRegistrationHelper -import net.corda.node.utilities.registration.UnableToRegisterNodeWithDoormanException +import net.corda.node.utilities.registration.NodeRegistrationException import net.corda.node.utilities.saveToKeyStore import net.corda.node.utilities.saveToTrustStore import net.corda.nodeapi.internal.addShutdownHook @@ -154,13 +154,13 @@ open class NodeStartup(val args: Array) { if (cmdlineOptions.nodeRegistrationOption != null) { // Null checks for [compatibilityZoneURL], [rootTruststorePath] and [rootTruststorePassword] has been done in [CmdLineOptions.loadConfig] registerWithNetwork(conf, versionInfo, cmdlineOptions.nodeRegistrationOption) - // At this point the node registration was succesfull. We can delete the marker file. + // At this point the node registration was successful. We can delete the marker file. deleteNodeRegistrationMarker(cmdlineOptions.baseDirectory) return true } logStartupInfo(versionInfo, cmdlineOptions, conf) - } catch (e: UnableToRegisterNodeWithDoormanException) { - logger.warn("Node registration service is unavailable. Perhaps try to perform the initial registration again after a while.") + } catch (e: NodeRegistrationException) { + logger.warn("Node registration service is unavailable. Perhaps try to perform the initial registration again after a while.", e) return false } catch (e: Exception) { logger.error("Exception during node registration", e) diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/SingleThreadedStateMachineManager.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/SingleThreadedStateMachineManager.kt index cc63a6c809..ec37a41aa4 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/SingleThreadedStateMachineManager.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/SingleThreadedStateMachineManager.kt @@ -600,10 +600,11 @@ class SingleThreadedStateMachineManager( private fun scheduleTimeoutException(flow: Flow, retryCount: Int): ScheduledFuture<*> { return with(serviceHub.configuration.flowTimeout) { val timeoutDelaySeconds = timeout.seconds * Math.pow(backoffBase, retryCount.toDouble()).toLong() + val jitteredDelaySeconds = maxOf(1L, timeoutDelaySeconds/2 + (Math.random() * timeoutDelaySeconds/2).toLong()) timeoutScheduler.schedule({ val event = Event.Error(FlowTimeoutException(maxRestartCount)) flow.fiber.scheduleEvent(event) - }, timeoutDelaySeconds, TimeUnit.SECONDS) + }, jitteredDelaySeconds, TimeUnit.SECONDS) } } diff --git a/node/src/main/kotlin/net/corda/node/utilities/registration/NetworkRegistrationHelper.kt b/node/src/main/kotlin/net/corda/node/utilities/registration/NetworkRegistrationHelper.kt index d79c201e6b..db44a402df 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/registration/NetworkRegistrationHelper.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/registration/NetworkRegistrationHelper.kt @@ -28,6 +28,7 @@ import org.bouncycastle.openssl.jcajce.JcaPEMWriter import org.bouncycastle.util.io.pem.PemObject import java.io.IOException import java.io.StringWriter +import java.net.ConnectException import java.nio.file.Path import java.security.KeyPair import java.security.KeyStore @@ -100,7 +101,14 @@ open class NetworkRegistrationHelper(private val config: SSLConfiguration, val keyPair = nodeKeyStore.loadOrCreateKeyPair(SELF_SIGNED_PRIVATE_KEY) - val requestId = submitOrResumeCertificateSigningRequest(keyPair) + val requestId = try { + submitOrResumeCertificateSigningRequest(keyPair) + } catch (e: Exception) { + if (e is ConnectException || e is ServiceUnavailableException || e is IOException) { + throw NodeRegistrationException(e) + } + throw e + } val certificates = try { pollServerForCertificates(requestId) @@ -113,7 +121,7 @@ open class NetworkRegistrationHelper(private val config: SSLConfiguration, } validateCertificates(keyPair.public, certificates) storePrivateKeyWithCertificates(nodeKeyStore, keyPair, certificates, keyAlias) - onSuccess(keyPair, certificates, tlsCrlIssuerCert?.let { it.subjectX500Principal.toX500Name() }) + onSuccess(keyPair, certificates, tlsCrlIssuerCert?.subjectX500Principal?.toX500Name()) // All done, clean up temp files. requestIdStore.deleteIfExists() } @@ -193,7 +201,7 @@ open class NetworkRegistrationHelper(private val config: SSLConfiguration, if (idlePeriodDuration != null) { Thread.sleep(idlePeriodDuration.toMillis()) } else { - throw UnableToRegisterNodeWithDoormanException() + throw NodeRegistrationException(e) } } } @@ -242,7 +250,7 @@ open class NetworkRegistrationHelper(private val config: SSLConfiguration, protected open fun isTlsCrlIssuerCertRequired(): Boolean = false } -class UnableToRegisterNodeWithDoormanException : IOException() +class NodeRegistrationException(cause: Throwable?) : IOException("Unable to contact node registration service", cause) class NodeRegistrationHelper(private val config: NodeConfiguration, certService: NetworkRegistrationService, regConfig: NodeRegistrationOption, computeNextIdleDoormanConnectionPollInterval: (Duration?) -> Duration? = FixedPeriodLimitedRetrialStrategy(10, Duration.ofMinutes(1))) : NetworkRegistrationHelper(config,