diff --git a/core/src/main/kotlin/net/corda/core/internal/ServiceHubCoreInternal.kt b/core/src/main/kotlin/net/corda/core/internal/ServiceHubCoreInternal.kt index 04cc543b81..5897984c1d 100644 --- a/core/src/main/kotlin/net/corda/core/internal/ServiceHubCoreInternal.kt +++ b/core/src/main/kotlin/net/corda/core/internal/ServiceHubCoreInternal.kt @@ -2,6 +2,7 @@ package net.corda.core.internal import co.paralleluniverse.fibers.Suspendable import net.corda.core.DeleteForDJVM +import net.corda.core.internal.notary.NotaryService import net.corda.core.node.ServiceHub import net.corda.core.node.StatesToRecord import java.util.concurrent.ExecutorService @@ -14,6 +15,11 @@ interface ServiceHubCoreInternal : ServiceHub { val attachmentTrustCalculator: AttachmentTrustCalculator + /** + * Optional `NotaryService` which will be `null` for all non-Notary nodes. + */ + val notaryService: NotaryService? + fun createTransactionsResolver(flow: ResolveTransactionsFlow): TransactionsResolver } diff --git a/core/src/main/kotlin/net/corda/core/internal/notary/NotaryService.kt b/core/src/main/kotlin/net/corda/core/internal/notary/NotaryService.kt index 5b1c1b35af..216022523a 100644 --- a/core/src/main/kotlin/net/corda/core/internal/notary/NotaryService.kt +++ b/core/src/main/kotlin/net/corda/core/internal/notary/NotaryService.kt @@ -14,6 +14,19 @@ abstract class NotaryService : SingletonSerializeAsToken() { abstract val services: ServiceHub abstract val notaryIdentityKey: PublicKey + /** + * Interfaces for the request and result formats of queries supported by notary services. To + * implement a new query, you must: + * + * - Define data classes which implement the [Query.Request] and [Query.Result] interfaces + * - Add corresponding handling for the new classes within the notary service implementations + * that you want to support the query. + */ + interface Query { + interface Request + interface Result + } + abstract fun start() abstract fun stop() @@ -22,4 +35,18 @@ abstract class NotaryService : SingletonSerializeAsToken() { * @param otherPartySession client [Party] making the request */ abstract fun createServiceFlow(otherPartySession: FlowSession): FlowLogic + + /** + * Processes a [Query.Request] and returns a [Query.Result]. + * + * Note that this always throws an [UnsupportedOperationException] to handle notary + * implementations that do not support this functionality. This must be overridden by + * notary implementations wishing to support query functionality. + * + * Overrides of this function may themselves still throw an [UnsupportedOperationException], + * if they do not support specific query implementations + */ + open fun processQuery(query: Query.Request): Query.Result { + throw UnsupportedOperationException("Notary has not implemented query support") + } } \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index ec24382622..985e598673 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -367,6 +367,8 @@ abstract class AbstractNode(val configuration: NodeConfiguration, private val checkpointDumper = CheckpointDumperImpl(checkpointStorage, database, services, services.configuration.baseDirectory) + private var notaryService: NotaryService? = null + private val nodeServicesContext = object : NodeServicesContext { override val platformVersion = versionInfo.platformVersion override val configurationWithOptions = configuration.configurationWithOptions @@ -524,7 +526,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, // the KMS is meant for derived temporary keys used in transactions, and we're not supposed to sign things with // the identity key. But the infrastructure to make that easy isn't here yet. keyManagementService.start(keyPairs) - val notaryService = maybeStartNotaryService(myNotaryIdentity) + notaryService = maybeStartNotaryService(myNotaryIdentity) installCordaServices() contractUpgradeService.start() vaultService.start() @@ -1160,6 +1162,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration, override val attachmentTrustCalculator: AttachmentTrustCalculator get() = this@AbstractNode.attachmentTrustCalculator override val diagnosticsService: DiagnosticsService get() = this@AbstractNode.diagnosticsService override val externalOperationExecutor: ExecutorService get() = this@AbstractNode.externalOperationExecutor + override val notaryService: NotaryService? get() = this@AbstractNode.notaryService private lateinit var _myInfo: NodeInfo override val myInfo: NodeInfo get() = _myInfo diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/dsl/TestDSL.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/dsl/TestDSL.kt index fc12fedc19..fa3ec67c93 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/dsl/TestDSL.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/dsl/TestDSL.kt @@ -9,6 +9,7 @@ import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowException import net.corda.core.identity.Party import net.corda.core.internal.* +import net.corda.core.internal.notary.NotaryService import net.corda.core.node.ServiceHub import net.corda.core.node.ServicesForResolution import net.corda.core.node.services.AttachmentId @@ -127,6 +128,8 @@ data class TestTransactionDSLInterpreter private constructor( override val cordappProvider: CordappProvider = ledgerInterpreter.services.cordappProvider + + override val notaryService: NotaryService? = null } private fun copy(): TestTransactionDSLInterpreter =