Revert "Introducing network parameters."

This reverts commit d04e487
This commit is contained in:
Shams Asari 2017-11-15 12:58:37 +00:00
parent e4f5e16bf4
commit 953a4a3790
24 changed files with 89 additions and 275 deletions

View File

@ -1684,27 +1684,6 @@ public @interface net.corda.core.messaging.RPCReturnsObservables
@org.jetbrains.annotations.NotNull public abstract net.corda.core.messaging.FlowHandle startFlow(net.corda.core.flows.FlowLogic) @org.jetbrains.annotations.NotNull public abstract net.corda.core.messaging.FlowHandle startFlow(net.corda.core.flows.FlowLogic)
@org.jetbrains.annotations.NotNull public abstract net.corda.core.messaging.FlowProgressHandle startTrackedFlow(net.corda.core.flows.FlowLogic) @org.jetbrains.annotations.NotNull public abstract net.corda.core.messaging.FlowProgressHandle startTrackedFlow(net.corda.core.flows.FlowLogic)
## ##
@net.corda.core.serialization.CordaSerializable public final class net.corda.core.node.NetworkParameters extends java.lang.Object
public <init>(int, List, java.time.Duration, int, int, java.time.Instant, int)
public final int component1()
@org.jetbrains.annotations.NotNull public final List component2()
@org.jetbrains.annotations.NotNull public final java.time.Duration component3()
public final int component4()
public final int component5()
@org.jetbrains.annotations.NotNull public final java.time.Instant component6()
public final int component7()
@org.jetbrains.annotations.NotNull public final net.corda.core.node.NetworkParameters copy(int, List, java.time.Duration, int, int, java.time.Instant, int)
public boolean equals(Object)
public final int getEpoch()
@org.jetbrains.annotations.NotNull public final java.time.Duration getEventHorizon()
public final int getMaxMessageSize()
public final int getMaxTransactionSize()
public final int getMinimumPlatformVersion()
@org.jetbrains.annotations.NotNull public final java.time.Instant getModifiedTime()
@org.jetbrains.annotations.NotNull public final List getNotaries()
public int hashCode()
public String toString()
##
@net.corda.core.serialization.CordaSerializable public final class net.corda.core.node.NodeInfo extends java.lang.Object @net.corda.core.serialization.CordaSerializable public final class net.corda.core.node.NodeInfo extends java.lang.Object
public <init>(List, List, int, long) public <init>(List, List, int, long)
@org.jetbrains.annotations.NotNull public final List component1() @org.jetbrains.annotations.NotNull public final List component1()
@ -1723,17 +1702,6 @@ public @interface net.corda.core.messaging.RPCReturnsObservables
public final boolean isLegalIdentity(net.corda.core.identity.Party) public final boolean isLegalIdentity(net.corda.core.identity.Party)
public String toString() public String toString()
## ##
@net.corda.core.serialization.CordaSerializable public final class net.corda.core.node.NotaryInfo extends java.lang.Object
public <init>(net.corda.core.identity.Party, boolean)
@org.jetbrains.annotations.NotNull public final net.corda.core.identity.Party component1()
public final boolean component2()
@org.jetbrains.annotations.NotNull public final net.corda.core.node.NotaryInfo copy(net.corda.core.identity.Party, boolean)
public boolean equals(Object)
@org.jetbrains.annotations.NotNull public final net.corda.core.identity.Party getIdentity()
public final boolean getValidating()
public int hashCode()
public String toString()
##
@net.corda.core.DoNotImplement public interface net.corda.core.node.ServiceHub extends net.corda.core.node.ServicesForResolution @net.corda.core.DoNotImplement public interface net.corda.core.node.ServiceHub extends net.corda.core.node.ServicesForResolution
@org.jetbrains.annotations.NotNull public abstract net.corda.core.transactions.SignedTransaction addSignature(net.corda.core.transactions.SignedTransaction) @org.jetbrains.annotations.NotNull public abstract net.corda.core.transactions.SignedTransaction addSignature(net.corda.core.transactions.SignedTransaction)
@org.jetbrains.annotations.NotNull public abstract net.corda.core.transactions.SignedTransaction addSignature(net.corda.core.transactions.SignedTransaction, java.security.PublicKey) @org.jetbrains.annotations.NotNull public abstract net.corda.core.transactions.SignedTransaction addSignature(net.corda.core.transactions.SignedTransaction, java.security.PublicKey)

2
.idea/compiler.xml generated
View File

@ -43,6 +43,8 @@
<module name="docs_source_example-code_main" target="1.8" /> <module name="docs_source_example-code_main" target="1.8" />
<module name="docs_source_example-code_test" target="1.8" /> <module name="docs_source_example-code_test" target="1.8" />
<module name="docs_test" target="1.8" /> <module name="docs_test" target="1.8" />
<module name="experimental-kryo-hook_main" target="1.8" />
<module name="experimental-kryo-hook_test" target="1.8" />
<module name="example-code_integrationTest" target="1.8" /> <module name="example-code_integrationTest" target="1.8" />
<module name="example-code_main" target="1.8" /> <module name="example-code_main" target="1.8" />
<module name="example-code_test" target="1.8" /> <module name="example-code_test" target="1.8" />

View File

@ -1,40 +0,0 @@
package net.corda.core.node
import net.corda.core.identity.Party
import net.corda.core.serialization.CordaSerializable
import java.time.Duration
import java.time.Instant
/**
* @property minimumPlatformVersion
* @property notaries
* @property eventHorizon
* @property maxMessageSize Maximum P2P message sent over the wire in bytes.
* @property maxTransactionSize Maximum permitted transaction size in bytes.
* @property modifiedTime
* @property epoch Version number of the network parameters. Starting from 1, this will always increment on each new set
* of parameters.
*/
// TODO Wire up the parameters
@CordaSerializable
data class NetworkParameters(
val minimumPlatformVersion: Int,
val notaries: List<NotaryInfo>,
val eventHorizon: Duration,
val maxMessageSize: Int,
val maxTransactionSize: Int,
val modifiedTime: Instant,
val epoch: Int
) {
init {
require(minimumPlatformVersion > 0) { "minimumPlatformVersion must be at least 1" }
require(notaries.distinctBy { it.identity } == notaries) { "Duplicate notary identities" }
require(epoch > 0) { "epoch must be at least 1" }
}
}
/**
*
*/
@CordaSerializable
data class NotaryInfo(val identity: Party, val validating: Boolean)

View File

@ -53,6 +53,7 @@ interface NetworkMapCacheBase {
* *
* Note that the identities are sorted based on legal name, and the ordering might change once new notaries are introduced. * Note that the identities are sorted based on legal name, and the ordering might change once new notaries are introduced.
*/ */
// TODO this list will be taken from NetworkParameters distributed by NetworkMap.
val notaryIdentities: List<Party> val notaryIdentities: List<Party>
// DOCEND 1 // DOCEND 1
@ -116,7 +117,7 @@ interface NetworkMapCacheBase {
fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name } fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name }
// DOCEND 2 // DOCEND 2
/** Returns true if and only if the given [Party] is a notary, which is defined by the network parameters. */ /** Checks whether a given party is an advertised notary identity. */
fun isNotary(party: Party): Boolean = party in notaryIdentities fun isNotary(party: Party): Boolean = party in notaryIdentities
/** /**

View File

@ -13,8 +13,6 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.deleteIfExists import net.corda.core.internal.deleteIfExists
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.NotaryInfo
import net.corda.core.node.services.NotaryService
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
@ -23,12 +21,11 @@ import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.config.BFTSMaRtConfiguration import net.corda.node.services.config.BFTSMaRtConfiguration
import net.corda.node.services.config.NotaryConfig import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.transactions.BFTNonValidatingNotaryService
import net.corda.node.services.transactions.minClusterSize import net.corda.node.services.transactions.minClusterSize
import net.corda.node.services.transactions.minCorrectReplicas import net.corda.node.services.transactions.minCorrectReplicas
import net.corda.node.utilities.ServiceIdentityGenerator import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentity
import net.corda.testing.common.internal.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand import net.corda.testing.dummyCommand
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
@ -57,26 +54,19 @@ class BFTNotaryServiceTests {
notary = ServiceIdentityGenerator.generateToDisk( notary = ServiceIdentityGenerator.generateToDisk(
replicaIds.map { mockNet.baseDirectory(mockNet.nextNodeId + it) }, replicaIds.map { mockNet.baseDirectory(mockNet.nextNodeId + it) },
CordaX500Name("BFT", "Zurich", "CH"), CordaX500Name(BFTNonValidatingNotaryService.id, "BFT", "Zurich", "CH")
NotaryService.constructId(validating = false, bft = true)) )
val networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(notary, false))))
val clusterAddresses = replicaIds.map { NetworkHostAndPort("localhost", 11000 + it * 10) } val clusterAddresses = replicaIds.map { NetworkHostAndPort("localhost", 11000 + it * 10) }
val nodes = replicaIds.map { replicaId -> replicaIds.forEach { replicaId ->
mockNet.createUnstartedNode(MockNodeParameters(configOverrides = { mockNet.createNode(MockNodeParameters(configOverrides = {
val notary = NotaryConfig(validating = false, bftSMaRt = BFTSMaRtConfiguration(replicaId, clusterAddresses, exposeRaces = exposeRaces)) val notary = NotaryConfig(validating = false, bftSMaRt = BFTSMaRtConfiguration(replicaId, clusterAddresses, exposeRaces = exposeRaces))
doReturn(notary).whenever(it).notary doReturn(notary).whenever(it).notary
})) }))
} + mockNet.createUnstartedNode() }
// MockNetwork doesn't support BFT clusters, so we create all the nodes we need unstarted, and then install the node = mockNet.createNode()
// network-parameters in their directories before they're started.
node = nodes.map { node ->
networkParameters.install(mockNet.baseDirectory(node.id))
node.start()
}.last()
} }
/** Failure mode is the redundant replica gets stuck in startup, so we can't dispose it cleanly at the end. */ /** Failure mode is the redundant replica gets stuck in startup, so we can't dispose it cleanly at the end. */

View File

@ -13,6 +13,7 @@ import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.node.services.Permissions.Companion.startFlow import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.node.services.transactions.RaftValidatingNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.driver.NodeHandle import net.corda.testing.driver.NodeHandle
@ -41,7 +42,7 @@ class DistributedServiceTests {
driver( driver(
extraCordappPackagesToScan = listOf("net.corda.finance.contracts"), extraCordappPackagesToScan = listOf("net.corda.finance.contracts"),
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name, rpcUsers = listOf(testUser), cluster = ClusterSpec.Raft(clusterSize = 3)))) notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name.copy(commonName = RaftValidatingNotaryService.id), rpcUsers = listOf(testUser), cluster = ClusterSpec.Raft(clusterSize = 3))))
{ {
alice = startNode(providedName = ALICE.name, rpcUsers = listOf(testUser)).getOrThrow() alice = startNode(providedName = ALICE.name, rpcUsers = listOf(testUser)).getOrThrow()
raftNotaryIdentity = defaultNotaryIdentity raftNotaryIdentity = defaultNotaryIdentity

View File

@ -20,7 +20,10 @@ import net.corda.core.internal.concurrent.openFuture
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.node.* import net.corda.core.node.*
import net.corda.core.node.services.* import net.corda.core.node.services.*
import net.corda.core.serialization.* import net.corda.core.serialization.SerializationWhitelist
import net.corda.core.serialization.SerializeAsToken
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.serialization.serialize
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.debug import net.corda.core.utilities.debug
@ -43,15 +46,8 @@ import net.corda.node.services.events.ScheduledActivityObserver
import net.corda.node.services.identity.PersistentIdentityService import net.corda.node.services.identity.PersistentIdentityService
import net.corda.node.services.keys.PersistentKeyManagementService import net.corda.node.services.keys.PersistentKeyManagementService
import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.network.NetworkMapCacheImpl
import net.corda.node.services.network.NodeInfoWatcher
import net.corda.node.services.network.PersistentNetworkMapCache
import net.corda.node.services.persistence.*
import net.corda.node.services.network.* import net.corda.node.services.network.*
import net.corda.node.services.persistence.DBCheckpointStorage import net.corda.node.services.persistence.*
import net.corda.node.services.persistence.DBTransactionMappingStorage
import net.corda.node.services.persistence.DBTransactionStorage
import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.node.services.schema.HibernateObserver import net.corda.node.services.schema.HibernateObserver
import net.corda.node.services.schema.NodeSchemaService import net.corda.node.services.schema.NodeSchemaService
import net.corda.node.services.statemachine.* import net.corda.node.services.statemachine.*
@ -89,8 +85,6 @@ import net.corda.core.crypto.generateKeyPair as cryptoGenerateKeyPair
* Marked as SingletonSerializeAsToken to prevent the invisible reference to AbstractNode in the ServiceHub accidentally * Marked as SingletonSerializeAsToken to prevent the invisible reference to AbstractNode in the ServiceHub accidentally
* sweeping up the Node into the Kryo checkpoint serialization via any flows holding a reference to ServiceHub. * sweeping up the Node into the Kryo checkpoint serialization via any flows holding a reference to ServiceHub.
*/ */
// TODO Log warning if this node is a notary but not one of the ones specified in the network parameters, both for core and custom
// In theory the NodeInfo for the node should be passed in, instead, however currently this is constructed by the // In theory the NodeInfo for the node should be passed in, instead, however currently this is constructed by the
// AbstractNode. It should be possible to generate the NodeInfo outside of AbstractNode, so it can be passed in. // AbstractNode. It should be possible to generate the NodeInfo outside of AbstractNode, so it can be passed in.
abstract class AbstractNode(val configuration: NodeConfiguration, abstract class AbstractNode(val configuration: NodeConfiguration,
@ -120,7 +114,6 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
// low-performance prototyping period. // low-performance prototyping period.
protected abstract val serverThread: AffinityExecutor protected abstract val serverThread: AffinityExecutor
protected lateinit var networkParameters: NetworkParameters
private val cordappServices = MutableClassToInstanceMap.create<SerializeAsToken>() private val cordappServices = MutableClassToInstanceMap.create<SerializeAsToken>()
private val flowFactories = ConcurrentHashMap<Class<out FlowLogic<*>>, InitiatedFlowFactory<*>>() private val flowFactories = ConcurrentHashMap<Class<out FlowLogic<*>>, InitiatedFlowFactory<*>>()
@ -186,7 +179,6 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
log.info("Node starting up ...") log.info("Node starting up ...")
initCertificate() initCertificate()
val keyPairs = initNodeInfo() val keyPairs = initNodeInfo()
readNetworkParameters()
val schemaService = NodeSchemaService(cordappLoader) val schemaService = NodeSchemaService(cordappLoader)
// Do all of this in a database transaction so anything that might need a connection has one. // Do all of this in a database transaction so anything that might need a connection has one.
val (startedImpl, schedulerService) = initialiseDatabasePersistence(schemaService) { database -> val (startedImpl, schedulerService) = initialiseDatabasePersistence(schemaService) { database ->
@ -257,18 +249,13 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
val keyPairs = mutableSetOf(identityKeyPair) val keyPairs = mutableSetOf(identityKeyPair)
myNotaryIdentity = configuration.notary?.let { myNotaryIdentity = configuration.notary?.let {
if (it.isClusterConfig) {
val (notaryIdentity, notaryIdentityKeyPair) = obtainIdentity(it) val (notaryIdentity, notaryIdentityKeyPair) = obtainIdentity(it)
keyPairs += notaryIdentityKeyPair keyPairs += notaryIdentityKeyPair
notaryIdentity notaryIdentity
} else {
// In case of a single notary service myNotaryIdentity will be the node's single identity.
identity
}
} }
info = NodeInfo( info = NodeInfo(
myAddresses(), myAddresses(),
setOf(identity, myNotaryIdentity).filterNotNull(), listOf(identity, myNotaryIdentity).filterNotNull(),
versionInfo.platformVersion, versionInfo.platformVersion,
platformClock.instant().toEpochMilli() platformClock.instant().toEpochMilli()
) )
@ -596,13 +583,6 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
return PersistentKeyManagementService(identityService, keyPairs) return PersistentKeyManagementService(identityService, keyPairs)
} }
private fun readNetworkParameters() {
val file = configuration.baseDirectory / "network-parameters"
networkParameters = file.readAll().deserialize<SignedData<NetworkParameters>>().verified()
log.info(networkParameters.toString())
check(networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) { "Node is too old for the network" }
}
private fun makeCoreNotaryService(notaryConfig: NotaryConfig, database: CordaPersistence): NotaryService { private fun makeCoreNotaryService(notaryConfig: NotaryConfig, database: CordaPersistence): NotaryService {
val notaryKey = myNotaryIdentity?.owningKey ?: throw IllegalArgumentException("No notary identity initialized when creating a notary service") val notaryKey = myNotaryIdentity?.owningKey ?: throw IllegalArgumentException("No notary identity initialized when creating a notary service")
return notaryConfig.run { return notaryConfig.run {
@ -661,16 +641,22 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
private fun obtainIdentity(notaryConfig: NotaryConfig?): Pair<PartyAndCertificate, KeyPair> { private fun obtainIdentity(notaryConfig: NotaryConfig?): Pair<PartyAndCertificate, KeyPair> {
val keyStore = KeyStoreWrapper(configuration.nodeKeystore, configuration.keyStorePassword) val keyStore = KeyStoreWrapper(configuration.nodeKeystore, configuration.keyStorePassword)
val (id, singleName) = if (notaryConfig == null || !notaryConfig.isClusterConfig) { val (id, singleName) = if (notaryConfig == null) {
// Node's main identity or if it's a single node notary // Node's main identity
Pair("identity", myLegalName) Pair("identity", myLegalName)
} else { } else {
val notaryId = notaryConfig.run { val notaryId = notaryConfig.run {
NotaryService.constructId(validating, raft != null, bftSMaRt != null, custom) NotaryService.constructId(validating, raft != null, bftSMaRt != null, custom)
} }
// The node is part of a distributed notary whose identity must already be generated beforehand. if (!notaryConfig.isClusterConfig) {
// Node's notary identity
Pair(notaryId, myLegalName.copy(commonName = notaryId))
} else {
// The node is part of a distributed notary whose identity must already be generated beforehand
Pair(notaryId, null) Pair(notaryId, null)
} }
}
// TODO: Integrate with Key management service? // TODO: Integrate with Key management service?
val privateKeyAlias = "$id-private-key" val privateKeyAlias = "$id-private-key"
@ -734,13 +720,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
override val stateMachineRecordedTransactionMapping = DBTransactionMappingStorage() override val stateMachineRecordedTransactionMapping = DBTransactionMappingStorage()
override val auditService = DummyAuditService() override val auditService = DummyAuditService()
override val transactionVerifierService by lazy { makeTransactionVerifierService() } override val transactionVerifierService by lazy { makeTransactionVerifierService() }
override val networkMapCache by lazy { override val networkMapCache by lazy { NetworkMapCacheImpl(PersistentNetworkMapCache(database), identityService) }
NetworkMapCacheImpl(
PersistentNetworkMapCache(
database,
networkParameters.notaries),
identityService)
}
override val vaultService by lazy { makeVaultService(keyManagementService, stateLoader, database.hibernateConfig) } override val vaultService by lazy { makeVaultService(keyManagementService, stateLoader, database.hibernateConfig) }
override val contractUpgradeService by lazy { ContractUpgradeServiceImpl() } override val contractUpgradeService by lazy { ContractUpgradeServiceImpl() }
override val attachments: AttachmentStorage get() = this@AbstractNode.attachments override val attachments: AttachmentStorage get() = this@AbstractNode.attachments

View File

@ -117,6 +117,7 @@ data class NodeConfigurationImpl(
// This is a sanity feature do not remove. // This is a sanity feature do not remove.
require(!useTestClock || devMode) { "Cannot use test clock outside of dev mode" } require(!useTestClock || devMode) { "Cannot use test clock outside of dev mode" }
require(devModeOptions == null || devMode) { "Cannot use devModeOptions outside of dev mode" } require(devModeOptions == null || devMode) { "Cannot use devModeOptions outside of dev mode" }
require(myLegalName.commonName == null) { "Common name must be null: $myLegalName" }
} }
} }

View File

@ -12,9 +12,9 @@ import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.schemas.NodeInfoSchemaV1 import net.corda.core.internal.schemas.NodeInfoSchemaV1
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.NotaryInfo
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.NetworkMapCache.MapChange
import net.corda.core.node.services.NotaryService
import net.corda.core.node.services.PartyInfo import net.corda.core.node.services.PartyInfo
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
@ -32,7 +32,6 @@ import java.security.PublicKey
import java.util.* import java.util.*
import javax.annotation.concurrent.ThreadSafe import javax.annotation.concurrent.ThreadSafe
import kotlin.collections.HashMap import kotlin.collections.HashMap
import kotlin.collections.HashSet
class NetworkMapCacheImpl( class NetworkMapCacheImpl(
networkMapCacheBase: NetworkMapCacheBaseInternal, networkMapCacheBase: NetworkMapCacheBaseInternal,
@ -62,15 +61,13 @@ class NetworkMapCacheImpl(
* Extremely simple in-memory cache of the network map. * Extremely simple in-memory cache of the network map.
*/ */
@ThreadSafe @ThreadSafe
open class PersistentNetworkMapCache( open class PersistentNetworkMapCache(private val database: CordaPersistence) : SingletonSerializeAsToken(), NetworkMapCacheBaseInternal {
private val database: CordaPersistence,
notaries: List<NotaryInfo>
) : SingletonSerializeAsToken(), NetworkMapCacheBaseInternal {
companion object { companion object {
val logger = loggerFor<PersistentNetworkMapCache>() val logger = loggerFor<PersistentNetworkMapCache>()
} }
// TODO Cleanup registered and party nodes // TODO Small explanation, partyNodes and registeredNodes is left in memory as it was before, because it will be removed in
// next PR that gets rid of services. These maps are used only for queries by service.
protected val registeredNodes: MutableMap<PublicKey, NodeInfo> = Collections.synchronizedMap(HashMap()) protected val registeredNodes: MutableMap<PublicKey, NodeInfo> = Collections.synchronizedMap(HashMap())
protected val partyNodes: MutableList<NodeInfo> get() = registeredNodes.map { it.value }.toMutableList() protected val partyNodes: MutableList<NodeInfo> get() = registeredNodes.map { it.value }.toMutableList()
private val _changed = PublishSubject.create<MapChange>() private val _changed = PublishSubject.create<MapChange>()
@ -84,9 +81,22 @@ open class PersistentNetworkMapCache(
override val nodeReady: CordaFuture<Void?> get() = _registrationFuture override val nodeReady: CordaFuture<Void?> get() = _registrationFuture
private var _loadDBSuccess: Boolean = false private var _loadDBSuccess: Boolean = false
override val loadDBSuccess get() = _loadDBSuccess override val loadDBSuccess get() = _loadDBSuccess
// TODO From the NetworkMapService redesign doc: Remove the concept of network services.
override val notaryIdentities: List<Party> = notaries.map { it.identity } // As a temporary hack, just assume for now that every network has a notary service named "Notary Service" that can be looked up in the map.
private val validatingNotaries = notaries.mapNotNullTo(HashSet()) { if (it.validating) it.identity else null } // This should eliminate the only required usage of services.
// It is ensured on node startup when constructing a notary that the name contains "notary".
override val notaryIdentities: List<Party>
get() {
return partyNodes
.flatMap {
// TODO: validate notary identity certificates before loading into network map cache.
// Notary certificates have to be signed by the doorman directly
it.legalIdentities
}
.filter { it.name.commonName?.startsWith(NotaryService.ID_PREFIX) ?: false }
.toSet() // Distinct, because of distributed service nodes
.sortedBy { it.name.toString() }
}
init { init {
database.transaction { loadFromDB(session) } database.transaction { loadFromDB(session) }
@ -117,7 +127,7 @@ open class PersistentNetworkMapCache(
} }
} }
override fun isValidatingNotary(party: Party): Boolean = party in validatingNotaries override fun isValidatingNotary(party: Party): Boolean = isNotary(party) && "validating" in party.name.commonName!!
override fun getPartyInfo(party: Party): PartyInfo? { override fun getPartyInfo(party: Party): PartyInfo? {
val nodes = database.transaction { queryByIdentityKey(session, party.owningKey) } val nodes = database.transaction { queryByIdentityKey(session, party.owningKey) }
@ -300,6 +310,7 @@ open class PersistentNetworkMapCache(
id = 0, id = 0,
hash = nodeInfo.serialize().hash.toString(), hash = nodeInfo.serialize().hash.toString(),
addresses = nodeInfo.addresses.map { NodeInfoSchemaV1.DBHostAndPort.fromHostAndPort(it) }, addresses = nodeInfo.addresses.map { NodeInfoSchemaV1.DBHostAndPort.fromHostAndPort(it) },
// TODO Another ugly hack with special first identity...
legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem -> legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem ->
NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0)
}, },

View File

@ -20,12 +20,11 @@ object ServiceIdentityGenerator {
* This method should be called *before* any of the nodes are started. * This method should be called *before* any of the nodes are started.
* *
* @param dirs List of node directories to place the generated identity and key pairs in. * @param dirs List of node directories to place the generated identity and key pairs in.
* @param serviceName The legal name of the distributed service. * @param serviceName The legal name of the distributed service, with service id as CN.
* @param threshold The threshold for the generated group [CompositeKey]. * @param threshold The threshold for the generated group [CompositeKey].
*/ */
fun generateToDisk(dirs: List<Path>, fun generateToDisk(dirs: List<Path>,
serviceName: CordaX500Name, serviceName: CordaX500Name,
serviceId: String,
threshold: Int = 1): Party { threshold: Int = 1): Party {
log.trace { "Generating a group identity \"serviceName\" for nodes: ${dirs.joinToString()}" } log.trace { "Generating a group identity \"serviceName\" for nodes: ${dirs.joinToString()}" }
val keyPairs = (1..dirs.size).map { generateKeyPair() } val keyPairs = (1..dirs.size).map { generateKeyPair() }
@ -40,6 +39,7 @@ object ServiceIdentityGenerator {
val compositeKeyCert = X509Utilities.createCertificate(CertificateType.CLIENT_CA, issuer.certificate, issuer.keyPair, serviceName, notaryKey) val compositeKeyCert = X509Utilities.createCertificate(CertificateType.CLIENT_CA, issuer.certificate, issuer.keyPair, serviceName, notaryKey)
val certPath = (dir / "certificates").createDirectories() / "distributedService.jks" val certPath = (dir / "certificates").createDirectories() / "distributedService.jks"
val keystore = loadOrCreateKeyStore(certPath, "cordacadevpass") val keystore = loadOrCreateKeyStore(certPath, "cordacadevpass")
val serviceId = serviceName.commonName
keystore.setCertificateEntry("$serviceId-composite-key", compositeKeyCert.cert) keystore.setCertificateEntry("$serviceId-composite-key", compositeKeyCert.cert)
keystore.setKeyEntry("$serviceId-private-key", keyPair.private, "cordacadevkeypass".toCharArray(), arrayOf(serviceKeyCert.cert, issuer.certificate.cert, rootCert)) keystore.setKeyEntry("$serviceId-private-key", keyPair.private, "cordacadevkeypass".toCharArray(), arrayOf(serviceKeyCert.cert, issuer.certificate.cert, rootCert))
keystore.save(certPath, "cordacadevpass") keystore.save(certPath, "cordacadevpass")

View File

@ -27,6 +27,10 @@ import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
class NotaryChangeTests { class NotaryChangeTests {
companion object {
private val DUMMY_NOTARY_SERVICE_NAME: CordaX500Name = DUMMY_NOTARY.name.copy(commonName = "corda.notary.validating")
}
private lateinit var mockNet: MockNetwork private lateinit var mockNet: MockNetwork
private lateinit var oldNotaryNode: StartedNode<MockNetwork.MockNode> private lateinit var oldNotaryNode: StartedNode<MockNetwork.MockNode>
private lateinit var clientNodeA: StartedNode<MockNetwork.MockNode> private lateinit var clientNodeA: StartedNode<MockNetwork.MockNode>
@ -36,7 +40,7 @@ class NotaryChangeTests {
@Before @Before
fun setUp() { fun setUp() {
val oldNotaryName = DUMMY_REGULATOR.name val oldNotaryName = DUMMY_NOTARY.name.copy(organisation = "Old Dummy Notary")
mockNet = MockNetwork( mockNet = MockNetwork(
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name), NotarySpec(oldNotaryName)), notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name), NotarySpec(oldNotaryName)),
cordappPackages = listOf("net.corda.testing.contracts") cordappPackages = listOf("net.corda.testing.contracts")
@ -44,8 +48,8 @@ class NotaryChangeTests {
clientNodeA = mockNet.createNode() clientNodeA = mockNet.createNode()
clientNodeB = mockNet.createNode() clientNodeB = mockNet.createNode()
oldNotaryNode = mockNet.notaryNodes[1] oldNotaryNode = mockNet.notaryNodes[1]
newNotaryParty = clientNodeA.services.networkMapCache.getNotary(DUMMY_NOTARY.name)!! newNotaryParty = clientNodeA.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME)!!
oldNotaryParty = clientNodeA.services.networkMapCache.getNotary(oldNotaryName)!! oldNotaryParty = clientNodeA.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME.copy(organisation = "Old Dummy Notary"))!!
} }
@After @After

View File

@ -80,7 +80,7 @@ class ArtemisMessagingTests {
LogHelper.setLevel(PersistentUniquenessProvider::class) LogHelper.setLevel(PersistentUniquenessProvider::class)
database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService) database = configureDatabase(makeTestDataSourceProperties(), makeTestDatabaseProperties(), ::makeTestIdentityService)
networkMapRegistrationFuture = doneFuture(Unit) networkMapRegistrationFuture = doneFuture(Unit)
networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, emptyList()), rigorousMock()) networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database), rigorousMock())
} }
@After @After

View File

@ -5,7 +5,6 @@ import net.corda.cordform.CordformDefinition
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.services.NotaryService
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.services.config.BFTSMaRtConfiguration import net.corda.node.services.config.BFTSMaRtConfiguration
import net.corda.node.services.config.NotaryConfig import net.corda.node.services.config.NotaryConfig
@ -63,10 +62,6 @@ class BFTNotaryCordform : CordformDefinition("build" / "notary-demo-nodes") {
} }
override fun setup(context: CordformContext) { override fun setup(context: CordformContext) {
ServiceIdentityGenerator.generateToDisk( ServiceIdentityGenerator.generateToDisk(notaryNames.map { context.baseDirectory(it.toString()) }, clusterName, threshold = minCorrectReplicas(clusterSize))
notaryNames.map { context.baseDirectory(it.toString()) },
clusterName,
NotaryService.constructId(validating = false, bft = true),
minCorrectReplicas(clusterSize))
} }
} }

View File

@ -5,7 +5,6 @@ import net.corda.cordform.CordformDefinition
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.services.NotaryService
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.services.config.NotaryConfig import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.config.RaftConfig import net.corda.node.services.config.RaftConfig
@ -59,9 +58,6 @@ class RaftNotaryCordform : CordformDefinition("build" / "notary-demo-nodes") {
} }
override fun setup(context: CordformContext) { override fun setup(context: CordformContext) {
ServiceIdentityGenerator.generateToDisk( ServiceIdentityGenerator.generateToDisk(notaryNames.map { context.baseDirectory(it.toString()) }, clusterName)
notaryNames.map { context.baseDirectory(it.toString()) },
clusterName,
NotaryService.constructId(validating = true, raft = true))
} }
} }

View File

@ -16,9 +16,7 @@ import net.corda.core.identity.Party
import net.corda.core.internal.* import net.corda.core.internal.*
import net.corda.core.internal.concurrent.* import net.corda.core.internal.concurrent.*
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.NetworkParameters
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.NotaryInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.node.services.NotaryService import net.corda.core.node.services.NotaryService
import net.corda.core.toFuture import net.corda.core.toFuture
@ -35,8 +33,6 @@ import net.corda.nodeapi.User
import net.corda.nodeapi.config.toConfig import net.corda.nodeapi.config.toConfig
import net.corda.nodeapi.internal.addShutdownHook import net.corda.nodeapi.internal.addShutdownHook
import net.corda.testing.* import net.corda.testing.*
import net.corda.testing.common.internal.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.internal.ProcessUtilities import net.corda.testing.internal.ProcessUtilities
import net.corda.testing.node.ClusterSpec import net.corda.testing.node.ClusterSpec
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
@ -585,7 +581,6 @@ class DriverDSL(
private val countObservables = mutableMapOf<CordaX500Name, Observable<Int>>() private val countObservables = mutableMapOf<CordaX500Name, Observable<Int>>()
private lateinit var _notaries: List<NotaryHandle> private lateinit var _notaries: List<NotaryHandle>
override val notaryHandles: List<NotaryHandle> get() = _notaries override val notaryHandles: List<NotaryHandle> get() = _notaries
private lateinit var networkParameters: NetworkParametersCopier
class State { class State {
val processes = ArrayList<Process>() val processes = ArrayList<Process>()
@ -713,33 +708,29 @@ class DriverDSL(
_shutdownManager = ShutdownManager(executorService) _shutdownManager = ShutdownManager(executorService)
shutdownManager.registerShutdown { nodeInfoFilesCopier.close() } shutdownManager.registerShutdown { nodeInfoFilesCopier.close() }
val notaryInfos = generateNotaryIdentities() val notaryInfos = generateNotaryIdentities()
// The network parameters must be serialised before starting any of the nodes
networkParameters = NetworkParametersCopier(testNetworkParameters(notaryInfos))
val nodeHandles = startNotaries() val nodeHandles = startNotaries()
_notaries = notaryInfos.zip(nodeHandles) { (identity, validating), nodes -> NotaryHandle(identity, validating, nodes) } _notaries = notaryInfos.zip(nodeHandles) { (identity, validating), nodes -> NotaryHandle(identity, validating, nodes) }
} }
private fun generateNotaryIdentities(): List<NotaryInfo> { private fun generateNotaryIdentities(): List<Pair<Party, Boolean>> {
return notarySpecs.map { spec -> return notarySpecs.map { spec ->
val identity = if (spec.cluster == null) { val identity = if (spec.cluster == null) {
ServiceIdentityGenerator.generateToDisk( ServiceIdentityGenerator.generateToDisk(
dirs = listOf(baseDirectory(spec.name)), dirs = listOf(baseDirectory(spec.name)),
serviceName = spec.name, serviceName = spec.name.copy(commonName = NotaryService.constructId(validating = spec.validating))
serviceId = "identity") )
} else { } else {
ServiceIdentityGenerator.generateToDisk( ServiceIdentityGenerator.generateToDisk(
dirs = generateNodeNames(spec).map { baseDirectory(it) }, dirs = generateNodeNames(spec).map { baseDirectory(it) },
serviceName = spec.name, serviceName = spec.name
serviceId = NotaryService.constructId( )
validating = spec.validating,
raft = spec.cluster is ClusterSpec.Raft))
} }
NotaryInfo(identity, spec.validating) Pair(identity, spec.validating)
} }
} }
private fun generateNodeNames(spec: NotarySpec): List<CordaX500Name> { private fun generateNodeNames(spec: NotarySpec): List<CordaX500Name> {
return (0 until spec.cluster!!.clusterSize).map { spec.name.copy(organisation = "${spec.name.organisation}-$it") } return (0 until spec.cluster!!.clusterSize).map { spec.name.copy(commonName = null, organisation = "${spec.name.organisation}-$it") }
} }
private fun startNotaries(): List<CordaFuture<List<NodeHandle>>> { private fun startNotaries(): List<CordaFuture<List<NodeHandle>>> {
@ -862,7 +853,6 @@ class DriverDSL(
maximumHeapSize: String): CordaFuture<NodeHandle> { maximumHeapSize: String): CordaFuture<NodeHandle> {
val configuration = config.parseAsNodeConfiguration() val configuration = config.parseAsNodeConfiguration()
val baseDirectory = configuration.baseDirectory.createDirectories() val baseDirectory = configuration.baseDirectory.createDirectories()
networkParameters.install(baseDirectory)
nodeInfoFilesCopier.addConfig(baseDirectory) nodeInfoFilesCopier.addConfig(baseDirectory)
val onNodeExit: () -> Unit = { val onNodeExit: () -> Unit = {
nodeInfoFilesCopier.removeConfig(baseDirectory) nodeInfoFilesCopier.removeConfig(baseDirectory)

View File

@ -16,14 +16,11 @@ import net.corda.node.services.config.parseAsNodeConfiguration
import net.corda.node.services.config.plus import net.corda.node.services.config.plus
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.SerializationEnvironmentRule
import net.corda.testing.common.internal.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.driver.addressMustNotBeBoundFuture import net.corda.testing.driver.addressMustNotBeBoundFuture
import net.corda.testing.getFreeLocalPorts import net.corda.testing.getFreeLocalPorts
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import org.apache.logging.log4j.Level import org.apache.logging.log4j.Level
import org.junit.After import org.junit.After
import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.rules.TemporaryFolder import org.junit.rules.TemporaryFolder
import java.nio.file.Path import java.nio.file.Path
@ -43,7 +40,6 @@ abstract class NodeBasedTest(private val cordappPackages: List<String> = emptyLi
@JvmField @JvmField
val tempFolder = TemporaryFolder() val tempFolder = TemporaryFolder()
private lateinit var defaultNetworkParameters: NetworkParametersCopier
private val nodes = mutableListOf<StartedNode<Node>>() private val nodes = mutableListOf<StartedNode<Node>>()
private val nodeInfos = mutableListOf<NodeInfo>() private val nodeInfos = mutableListOf<NodeInfo>()
@ -51,11 +47,6 @@ abstract class NodeBasedTest(private val cordappPackages: List<String> = emptyLi
System.setProperty("consoleLogLevel", Level.DEBUG.name().toLowerCase()) System.setProperty("consoleLogLevel", Level.DEBUG.name().toLowerCase())
} }
@Before
fun init() {
defaultNetworkParameters = NetworkParametersCopier(testNetworkParameters(emptyList()))
}
/** /**
* Stops the network map node and all the nodes started by [startNode]. This is called automatically after each test * Stops the network map node and all the nodes started by [startNode]. This is called automatically after each test
* but can also be called manually within a test. * but can also be called manually within a test.
@ -99,7 +90,6 @@ abstract class NodeBasedTest(private val cordappPackages: List<String> = emptyLi
) )
val parsedConfig = config.parseAsNodeConfiguration() val parsedConfig = config.parseAsNodeConfiguration()
defaultNetworkParameters.install(baseDirectory)
val node = Node( val node = Node(
parsedConfig, parsedConfig,
MockServices.MOCK_VERSION_INFO.copy(platformVersion = platformVersion), MockServices.MOCK_VERSION_INFO.copy(platformVersion = platformVersion),

View File

@ -15,7 +15,6 @@ fun CordformDefinition.clean() {
/** /**
* Creates and starts all nodes required for the demo. * Creates and starts all nodes required for the demo.
*/ */
// TODO add notaries to cordform!
fun CordformDefinition.runNodes() { fun CordformDefinition.runNodes() {
driver(isDebug = true, driverDirectory = driverDirectory, portAllocation = PortAllocation.Incremental(10001), waitForAllNodesToFinish = true) { driver(isDebug = true, driverDirectory = driverDirectory, portAllocation = PortAllocation.Incremental(10001), waitForAllNodesToFinish = true) {
setup(this) setup(this)

View File

@ -7,7 +7,6 @@ import net.corda.core.internal.concurrent.doneFuture
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.network.PersistentNetworkMapCache import net.corda.node.services.network.PersistentNetworkMapCache
import net.corda.node.utilities.CordaPersistence import net.corda.node.utilities.CordaPersistence
import net.corda.testing.getTestPartyAndCertificate import net.corda.testing.getTestPartyAndCertificate
@ -18,7 +17,7 @@ import java.math.BigInteger
/** /**
* Network map cache with no backing map service. * Network map cache with no backing map service.
*/ */
class MockNetworkMapCache(database: CordaPersistence) : PersistentNetworkMapCache(database, emptyList()) { class MockNetworkMapCache(database: CordaPersistence) : PersistentNetworkMapCache(database) {
private companion object { private companion object {
val BANK_C = getTestPartyAndCertificate(CordaX500Name(organisation = "Bank C", locality = "London", country = "GB"), entropyToKeyPair(BigInteger.valueOf(1000)).public) val BANK_C = getTestPartyAndCertificate(CordaX500Name(organisation = "Bank C", locality = "London", country = "GB"), entropyToKeyPair(BigInteger.valueOf(1000)).public)
val BANK_D = getTestPartyAndCertificate(CordaX500Name(organisation = "Bank D", locality = "London", country = "GB"), entropyToKeyPair(BigInteger.valueOf(2000)).public) val BANK_D = getTestPartyAndCertificate(CordaX500Name(organisation = "Bank D", locality = "London", country = "GB"), entropyToKeyPair(BigInteger.valueOf(2000)).public)

View File

@ -14,7 +14,6 @@ import net.corda.core.internal.uncheckedCast
import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.MessageRecipients
import net.corda.core.messaging.RPCOps import net.corda.core.messaging.RPCOps
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.NotaryInfo
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.KeyManagementService import net.corda.core.node.services.KeyManagementService
import net.corda.core.serialization.SerializationWhitelist import net.corda.core.serialization.SerializationWhitelist
@ -36,13 +35,10 @@ import net.corda.node.services.transactions.InMemoryTransactionVerifierService
import net.corda.node.utilities.AffinityExecutor import net.corda.node.utilities.AffinityExecutor
import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor
import net.corda.node.utilities.CordaPersistence import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.common.internal.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.setGlobalSerialization
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.setGlobalSerialization
import net.corda.testing.testNodeConfiguration import net.corda.testing.testNodeConfiguration
import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.activemq.artemis.utils.ReusableLatch
import org.slf4j.Logger import org.slf4j.Logger
@ -134,7 +130,6 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
val messagingNetwork = InMemoryMessagingNetwork(networkSendManuallyPumped, servicePeerAllocationStrategy, busyLatch) val messagingNetwork = InMemoryMessagingNetwork(networkSendManuallyPumped, servicePeerAllocationStrategy, busyLatch)
// A unique identifier for this network to segregate databases with the same nodeID but different networks. // A unique identifier for this network to segregate databases with the same nodeID but different networks.
private val networkId = random63BitValue() private val networkId = random63BitValue()
private val networkParameters: NetworkParametersCopier
private val _nodes = mutableListOf<MockNode>() private val _nodes = mutableListOf<MockNode>()
private val serializationEnv = setGlobalSerialization(initialiseSerialization) private val serializationEnv = setGlobalSerialization(initialiseSerialization)
private val sharedUserCount = AtomicInteger(0) private val sharedUserCount = AtomicInteger(0)
@ -164,7 +159,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
* @see defaultNotaryNode * @see defaultNotaryNode
*/ */
val defaultNotaryIdentity: Party get() { val defaultNotaryIdentity: Party get() {
return defaultNotaryNode.info.legalIdentities.singleOrNull() ?: throw IllegalStateException("Default notary has multiple identities") return defaultNotaryNode.info.legalIdentities[1] // TODO Resolve once network parameters is merged back in
} }
/** /**
@ -191,22 +186,9 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
init { init {
filesystem.getPath("/nodes").createDirectory() filesystem.getPath("/nodes").createDirectory()
val notaryInfos = generateNotaryIdentities()
// The network parameters must be serialised before starting any of the nodes
networkParameters = NetworkParametersCopier(testNetworkParameters(notaryInfos))
notaryNodes = createNotaries() notaryNodes = createNotaries()
} }
private fun generateNotaryIdentities(): List<NotaryInfo> {
return notarySpecs.mapIndexed { index, spec ->
val identity = ServiceIdentityGenerator.generateToDisk(
dirs = listOf(baseDirectory(nextNodeId + index)),
serviceName = spec.name,
serviceId = "identity")
NotaryInfo(identity, spec.validating)
}
}
private fun createNotaries(): List<StartedNode<MockNode>> { private fun createNotaries(): List<StartedNode<MockNode>> {
return notarySpecs.map { spec -> return notarySpecs.map { spec ->
createNode(MockNodeParameters(legalName = spec.name, configOverrides = { createNode(MockNodeParameters(legalName = spec.name, configOverrides = {
@ -240,7 +222,6 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
override val started: StartedNode<MockNode>? get() = uncheckedCast(super.started) override val started: StartedNode<MockNode>? get() = uncheckedCast(super.started)
override fun start(): StartedNode<MockNode> { override fun start(): StartedNode<MockNode> {
mockNet.networkParameters.install(configuration.baseDirectory)
val started: StartedNode<MockNode> = uncheckedCast(super.start()) val started: StartedNode<MockNode> = uncheckedCast(super.start())
advertiseNodeToNetwork(started) advertiseNodeToNetwork(started)
return started return started

View File

@ -2,6 +2,7 @@ package net.corda.testing.node
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.node.services.config.VerifierType import net.corda.node.services.config.VerifierType
import net.corda.node.services.transactions.RaftValidatingNotaryService
import net.corda.nodeapi.User import net.corda.nodeapi.User
data class NotarySpec( data class NotarySpec(
@ -10,7 +11,15 @@ data class NotarySpec(
val rpcUsers: List<User> = emptyList(), val rpcUsers: List<User> = emptyList(),
val verifierType: VerifierType = VerifierType.InMemory, val verifierType: VerifierType = VerifierType.InMemory,
val cluster: ClusterSpec? = null val cluster: ClusterSpec? = null
) ) {
init {
// TODO This will be removed once network parameters define the notaries
when (cluster) {
is ClusterSpec.Raft -> require(name.commonName == RaftValidatingNotaryService.id)
null -> require(name.commonName == null)
}
}
}
sealed class ClusterSpec { sealed class ClusterSpec {
abstract val clusterSize: Int abstract val clusterSize: Int

View File

@ -2,15 +2,11 @@ package net.corda.smoketesting
import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCConnection import net.corda.client.rpc.CordaRPCConnection
import net.corda.client.rpc.internal.KryoClientSerializationScheme
import net.corda.core.internal.copyTo import net.corda.core.internal.copyTo
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.testing.common.internal.NetworkParametersCopier
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.common.internal.asContextEnv
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.time.Instant import java.time.Instant
@ -53,14 +49,6 @@ class NodeProcess(
private companion object { private companion object {
val javaPath: Path = Paths.get(System.getProperty("java.home"), "bin", "java") val javaPath: Path = Paths.get(System.getProperty("java.home"), "bin", "java")
val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(systemDefault()) val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(systemDefault())
val defaultNetworkParameters = run {
KryoClientSerializationScheme.createSerializationEnv().asContextEnv {
// There are no notaries in the network parameters for smoke test nodes. If this is required then we would
// need to introduce the concept of a "network" which predefines the notaries, like the driver and MockNetwork
NetworkParametersCopier(testNetworkParameters(emptyList()))
}
}
init { init {
try { try {
Class.forName("net.corda.node.Corda") Class.forName("net.corda.node.Corda")
@ -80,7 +68,6 @@ class NodeProcess(
log.info("Node directory: {}", nodeDir) log.info("Node directory: {}", nodeDir)
config.toText().byteInputStream().copyTo(nodeDir / "node.conf") config.toText().byteInputStream().copyTo(nodeDir / "node.conf")
defaultNetworkParameters.install(nodeDir)
val process = startNode(nodeDir) val process = startNode(nodeDir)
val client = CordaRPCClient(NetworkHostAndPort("localhost", config.rpcPort)) val client = CordaRPCClient(NetworkHostAndPort("localhost", config.rpcPort))

View File

@ -1,32 +0,0 @@
package net.corda.testing.common.internal
import net.corda.core.crypto.SignedData
import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.sign
import net.corda.core.internal.copyTo
import net.corda.core.internal.div
import net.corda.core.node.NetworkParameters
import net.corda.core.serialization.serialize
import java.math.BigInteger
import java.nio.file.FileAlreadyExistsException
import java.nio.file.Path
class NetworkParametersCopier(networkParameters: NetworkParameters) {
private companion object {
val DUMMY_MAP_KEY = entropyToKeyPair(BigInteger.valueOf(123))
}
private val serializedNetworkParameters = networkParameters.let {
val serialize = it.serialize()
val signature = DUMMY_MAP_KEY.sign(serialize)
SignedData(serialize, signature).serialize()
}
fun install(dir: Path) {
try {
serializedNetworkParameters.open().copyTo(dir / "network-parameters")
} catch (e: FileAlreadyExistsException) {
// Leave the file untouched if it already exists
}
}
}

View File

@ -1,18 +0,0 @@
package net.corda.testing.common.internal
import net.corda.core.node.NetworkParameters
import net.corda.core.node.NotaryInfo
import net.corda.core.utilities.days
import java.time.Instant
fun testNetworkParameters(notaries: List<NotaryInfo>): NetworkParameters {
return NetworkParameters(
minimumPlatformVersion = 1,
notaries = notaries,
modifiedTime = Instant.now(),
eventHorizon = 10000.days,
maxMessageSize = 40000,
maxTransactionSize = 40000,
epoch = 1
)
}

View File

@ -24,7 +24,7 @@ val dummyNotarisationTest = LoadTest<NotariseCommand, Unit>(
val issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY) val issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY)
val generateTx = Generator.pickOne(simpleNodes).flatMap { node -> val generateTx = Generator.pickOne(simpleNodes).flatMap { node ->
Generator.int().map { Generator.int().map {
val issueBuilder = DummyContract.generateInitial(it, notary.info.legalIdentities[0], DUMMY_CASH_ISSUER) // TODO notary choice val issueBuilder = DummyContract.generateInitial(it, notary.info.legalIdentities[1], DUMMY_CASH_ISSUER) // TODO notary choice
val issueTx = issuerServices.signInitialTransaction(issueBuilder) val issueTx = issuerServices.signInitialTransaction(issueBuilder)
val asset = issueTx.tx.outRef<DummyContract.SingleOwnerState>(0) val asset = issueTx.tx.outRef<DummyContract.SingleOwnerState>(0)
val moveBuilder = DummyContract.move(asset, DUMMY_CASH_ISSUER.party) val moveBuilder = DummyContract.move(asset, DUMMY_CASH_ISSUER.party)