mirror of
https://github.com/corda/corda.git
synced 2024-12-20 13:33:12 +00:00
Add MockNet support for custom Notary class
This commit is contained in:
parent
70b2a94fda
commit
100457afc0
@ -41,6 +41,8 @@ Version 5.0
|
|||||||
Version 4.2
|
Version 4.2
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
* The MockNet now supports setting a custom Notary class name, as was already supported by normal node config. See :doc:`tutorial-custom-notary`.
|
||||||
|
|
||||||
* Contract attachments are now automatically whitelisted by the node if another contract attachment is present with the same contract classes,
|
* Contract attachments are now automatically whitelisted by the node if another contract attachment is present with the same contract classes,
|
||||||
signed by the same public keys, and uploaded by a trusted uploader. This allows the node to resolve transactions that use earlier versions
|
signed by the same public keys, and uploaded by a trusted uploader. This allows the node to resolve transactions that use earlier versions
|
||||||
of a contract without having to manually install that version, provided a newer version is installed. Similarly, non-contract attachments
|
of a contract without having to manually install that version, provided a newer version is installed. Similarly, non-contract attachments
|
||||||
|
@ -33,3 +33,16 @@ To enable the service, add the following to the node configuration:
|
|||||||
validating : true # Set to false if your service is non-validating
|
validating : true # Set to false if your service is non-validating
|
||||||
className : "net.corda.notarydemo.MyCustomValidatingNotaryService" # The fully qualified name of your service class
|
className : "net.corda.notarydemo.MyCustomValidatingNotaryService" # The fully qualified name of your service class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Testing your custom notary service
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
To create a flow test that uses your custom notary service, you can set the class name of the custom notary service as follows in your flow test:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../testing/node-driver/src/test/kotlin/net/corda/testing/node/CustomNotaryTest.kt
|
||||||
|
:language: kotlin
|
||||||
|
:start-after: START 1
|
||||||
|
:end-before: END 1
|
||||||
|
|
||||||
|
After this, your custom notary will be the default notary on the mock network, and can be used in the same way as described in :doc:`flow-testing`.
|
||||||
|
|
||||||
|
@ -123,8 +123,9 @@ data class MockNetworkParameters(
|
|||||||
*
|
*
|
||||||
* @property name The name of the notary node.
|
* @property name The name of the notary node.
|
||||||
* @property validating Boolean for whether the notary is validating or non-validating.
|
* @property validating Boolean for whether the notary is validating or non-validating.
|
||||||
|
* @property className String the optional name of a notary service class to load. If null, a builtin notary is loaded.
|
||||||
*/
|
*/
|
||||||
data class MockNetworkNotarySpec(val name: CordaX500Name, val validating: Boolean = true) {
|
data class MockNetworkNotarySpec(val name: CordaX500Name, val validating: Boolean = true, val className: String? = null) {
|
||||||
constructor(name: CordaX500Name) : this(name, validating = true)
|
constructor(name: CordaX500Name) : this(name, validating = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,10 +249,10 @@ open class InternalMockNetwork(cordappPackages: List<String> = emptyList(),
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
internal open fun createNotaries(): List<TestStartedNode> {
|
internal open fun createNotaries(): List<TestStartedNode> {
|
||||||
return notarySpecs.map { (name, validating) ->
|
return notarySpecs.map { (name, validating, className) ->
|
||||||
createNode(InternalMockNodeParameters(
|
createNode(InternalMockNodeParameters(
|
||||||
legalName = name,
|
legalName = name,
|
||||||
configOverrides = { doReturn(NotaryConfig(validating)).whenever(it).notary }
|
configOverrides = { doReturn(NotaryConfig(validating, className = className)).whenever(it).notary }
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
package net.corda.testing.node
|
||||||
|
|
||||||
|
import net.corda.core.flows.FlowException
|
||||||
|
import net.corda.core.flows.FlowLogic
|
||||||
|
import net.corda.core.flows.FlowSession
|
||||||
|
import net.corda.core.flows.NotaryFlow
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.internal.notary.NotaryService
|
||||||
|
import net.corda.core.utilities.getOrThrow
|
||||||
|
import net.corda.node.services.api.ServiceHubInternal
|
||||||
|
import net.corda.testing.contracts.DummyContract
|
||||||
|
import net.corda.testing.core.ALICE_NAME
|
||||||
|
import net.corda.testing.core.singleIdentity
|
||||||
|
import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP
|
||||||
|
import net.corda.testing.node.internal.enclosedCordapp
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import java.security.PublicKey
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class CustomNotaryTest {
|
||||||
|
private lateinit var mockNet: MockNetwork
|
||||||
|
private lateinit var notaryNode: StartedMockNode
|
||||||
|
private lateinit var aliceNode: StartedMockNode
|
||||||
|
private lateinit var notary: Party
|
||||||
|
private lateinit var alice: Party
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
// START 1
|
||||||
|
mockNet = MockNetwork(MockNetworkParameters(
|
||||||
|
cordappsForAllNodes = listOf(DUMMY_CONTRACTS_CORDAPP, enclosedCordapp()),
|
||||||
|
notarySpecs = listOf(MockNetworkNotarySpec(
|
||||||
|
name = CordaX500Name("Custom Notary", "Amsterdam", "NL"),
|
||||||
|
className = "net.corda.testing.node.CustomNotaryTest\$CustomNotaryService",
|
||||||
|
validating = false // Can also be validating if preferred.
|
||||||
|
))
|
||||||
|
))
|
||||||
|
// END 1
|
||||||
|
aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||||
|
notaryNode = mockNet.defaultNotaryNode
|
||||||
|
notary = mockNet.defaultNotaryIdentity
|
||||||
|
alice = aliceNode.info.singleIdentity()
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
mockNet.stopNodes()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = CustomNotaryException::class)
|
||||||
|
fun `custom notary service is active`() {
|
||||||
|
val tx = DummyContract.generateInitial(Random().nextInt(), notary, alice.ref(0))
|
||||||
|
val stx = aliceNode.services.signInitialTransaction(tx)
|
||||||
|
val future = aliceNode.startFlow(NotaryFlow.Client(stx))
|
||||||
|
mockNet.runNetwork()
|
||||||
|
future.getOrThrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : NotaryService() {
|
||||||
|
|
||||||
|
override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic<Void?> =
|
||||||
|
object : FlowLogic<Void?>() {
|
||||||
|
override fun call(): Void? {
|
||||||
|
throw CustomNotaryException("Proof that a custom notary service is running!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun start() {}
|
||||||
|
override fun stop() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomNotaryException(message: String) : FlowException(message)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user