mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
Removing NetworkParametersGenerator as an interface
This commit is contained in:
parent
cb11379d98
commit
4a677815ef
@ -1,4 +1,4 @@
|
|||||||
gradlePluginsVersion=3.0.1-NETWORKMAP
|
gradlePluginsVersion=3.0.2-NETWORKMAP
|
||||||
kotlinVersion=1.1.60
|
kotlinVersion=1.1.60
|
||||||
platformVersion=2
|
platformVersion=2
|
||||||
guavaVersion=21.0
|
guavaVersion=21.0
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
package net.corda.cordform;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface NetworkParametersGenerator {
|
|
||||||
/**
|
|
||||||
* Run generation of network parameters for [Cordformation]. Nodes need to have already their own [NodeInfo] files in their
|
|
||||||
* base directories, these files will be used to extract notary identities.
|
|
||||||
*
|
|
||||||
* @param nodesDirs - nodes directories that will be used for network parameters generation. Network parameters
|
|
||||||
* file will be dropped into each directory on this list.
|
|
||||||
*/
|
|
||||||
void run(List<Path> nodesDirs);
|
|
||||||
}
|
|
@ -3,7 +3,6 @@ package net.corda.plugins
|
|||||||
import groovy.lang.Closure
|
import groovy.lang.Closure
|
||||||
import net.corda.cordform.CordformDefinition
|
import net.corda.cordform.CordformDefinition
|
||||||
import net.corda.cordform.CordformNode
|
import net.corda.cordform.CordformNode
|
||||||
import net.corda.cordform.NetworkParametersGenerator
|
|
||||||
import org.apache.tools.ant.filters.FixCrLfFilter
|
import org.apache.tools.ant.filters.FixCrLfFilter
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
@ -33,7 +32,6 @@ open class Cordform : DefaultTask() {
|
|||||||
*/
|
*/
|
||||||
@Suppress("MemberVisibilityCanPrivate")
|
@Suppress("MemberVisibilityCanPrivate")
|
||||||
var definitionClass: String? = null
|
var definitionClass: String? = null
|
||||||
private val networkParametersGenClass: String = "net.corda.nodeapi.internal.TestNetworkParametersGenerator"
|
|
||||||
private var directory = defaultDirectory
|
private var directory = defaultDirectory
|
||||||
private val nodes = mutableListOf<Node>()
|
private val nodes = mutableListOf<Node>()
|
||||||
|
|
||||||
@ -122,14 +120,11 @@ open class Cordform : DefaultTask() {
|
|||||||
/**
|
/**
|
||||||
* The parametersGenerator needn't be compiled until just before our build method, so we load it manually via sourceSets.main.runtimeClasspath.
|
* The parametersGenerator needn't be compiled until just before our build method, so we load it manually via sourceSets.main.runtimeClasspath.
|
||||||
*/
|
*/
|
||||||
private fun loadParametersGenerator(): NetworkParametersGenerator {
|
private fun loadNetworkParamsGenClass(): Class<*> {
|
||||||
val plugin = project.convention.getPlugin(JavaPluginConvention::class.java)
|
val plugin = project.convention.getPlugin(JavaPluginConvention::class.java)
|
||||||
val classpath = plugin.sourceSets.getByName(MAIN_SOURCE_SET_NAME).runtimeClasspath
|
val classpath = plugin.sourceSets.getByName(MAIN_SOURCE_SET_NAME).runtimeClasspath
|
||||||
val urls = classpath.files.map { it.toURI().toURL() }.toTypedArray()
|
val urls = classpath.files.map { it.toURI().toURL() }.toTypedArray()
|
||||||
return URLClassLoader(urls, NetworkParametersGenerator::class.java.classLoader)
|
return URLClassLoader(urls, javaClass.classLoader).loadClass("net.corda.nodeapi.internal.NetworkParametersGenerator")
|
||||||
.loadClass(networkParametersGenClass)
|
|
||||||
.asSubclass(NetworkParametersGenerator::class.java)
|
|
||||||
.newInstance()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,8 +166,12 @@ open class Cordform : DefaultTask() {
|
|||||||
|
|
||||||
private fun generateAndInstallNetworkParameters() {
|
private fun generateAndInstallNetworkParameters() {
|
||||||
project.logger.info("Generating and installing network parameters")
|
project.logger.info("Generating and installing network parameters")
|
||||||
val networkParamsGenerator = loadParametersGenerator()
|
val networkParamsGenClass = loadNetworkParamsGenClass()
|
||||||
networkParamsGenerator.run(nodes.map { it.fullPath() })
|
val nodeDirs = nodes.map(Node::fullPath)
|
||||||
|
val networkParamsGenObject = networkParamsGenClass.newInstance()
|
||||||
|
val runMethod = networkParamsGenClass.getMethod("run", List::class.java).apply { isAccessible = true }
|
||||||
|
// Call NetworkParametersGenerator.run
|
||||||
|
runMethod.invoke(networkParamsGenObject, nodeDirs)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CordformDefinition.getMatchingCordapps(): List<File> {
|
private fun CordformDefinition.getMatchingCordapps(): List<File> {
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package net.corda.nodeapi.internal
|
package net.corda.nodeapi.internal
|
||||||
|
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import net.corda.cordform.CordformNode
|
|
||||||
import net.corda.cordform.NetworkParametersGenerator
|
|
||||||
import net.corda.core.crypto.SignedData
|
import net.corda.core.crypto.SignedData
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.internal.list
|
import net.corda.core.internal.list
|
||||||
import net.corda.core.internal.readAll
|
import net.corda.core.internal.readAll
|
||||||
@ -16,26 +14,30 @@ import net.corda.core.serialization.internal._contextSerializationEnv
|
|||||||
import net.corda.core.utilities.ByteSequence
|
import net.corda.core.utilities.ByteSequence
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.days
|
import net.corda.core.utilities.days
|
||||||
import net.corda.nodeapi.internal.serialization.*
|
import net.corda.nodeapi.internal.serialization.AMQP_P2P_CONTEXT
|
||||||
|
import net.corda.nodeapi.internal.serialization.KRYO_P2P_CONTEXT
|
||||||
|
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
|
||||||
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
|
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
|
||||||
import net.corda.nodeapi.internal.serialization.kryo.AbstractKryoSerializationScheme
|
import net.corda.nodeapi.internal.serialization.kryo.AbstractKryoSerializationScheme
|
||||||
import net.corda.nodeapi.internal.serialization.kryo.KryoHeaderV0_1
|
import net.corda.nodeapi.internal.serialization.kryo.KryoHeaderV0_1
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import kotlin.streams.toList
|
|
||||||
|
|
||||||
// This class is used by deployNodes task to generate NetworkParameters in [Cordformation].
|
/**
|
||||||
|
* This class is loaded by Cordform using reflection to generate the network parameters. It is assumed that Cordform has
|
||||||
|
* already asked each node to generate its node info file.
|
||||||
|
*/
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
class TestNetworkParametersGenerator : NetworkParametersGenerator {
|
class NetworkParametersGenerator {
|
||||||
companion object {
|
companion object {
|
||||||
private val logger = contextLogger()
|
private val logger = contextLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun run(nodesDirs: List<Path>) {
|
fun run(nodesDirs: List<Path>) {
|
||||||
logger.info("NetworkParameters generation using node directories: $nodesDirs")
|
logger.info("NetworkParameters generation using node directories: $nodesDirs")
|
||||||
try {
|
try {
|
||||||
initialiseSerialization()
|
initialiseSerialization()
|
||||||
val notaryInfos = loadAndGatherNotaryIdentities(nodesDirs)
|
val notaryInfos = gatherNotaryIdentities(nodesDirs)
|
||||||
val copier = NetworkParametersCopier(NetworkParameters(
|
val copier = NetworkParametersCopier(NetworkParameters(
|
||||||
minimumPlatformVersion = 1,
|
minimumPlatformVersion = 1,
|
||||||
notaries = notaryInfos,
|
notaries = notaryInfos,
|
||||||
@ -45,40 +47,34 @@ class TestNetworkParametersGenerator : NetworkParametersGenerator {
|
|||||||
maxTransactionSize = 40000,
|
maxTransactionSize = 40000,
|
||||||
epoch = 1
|
epoch = 1
|
||||||
))
|
))
|
||||||
nodesDirs.forEach { copier.install(it) }
|
nodesDirs.forEach(copier::install)
|
||||||
} finally {
|
} finally {
|
||||||
_contextSerializationEnv.set(null)
|
_contextSerializationEnv.set(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAndGatherNotaryIdentities(nodesDirs: List<Path>): List<NotaryInfo> {
|
private fun gatherNotaryIdentities(nodesDirs: List<Path>): List<NotaryInfo> {
|
||||||
val infos = getAllNodeInfos(nodesDirs)
|
return nodesDirs.mapNotNull { nodeDir ->
|
||||||
val configs = nodesDirs.map { ConfigFactory.parseFile((it / "node.conf").toFile()) }
|
val nodeConfig = ConfigFactory.parseFile((nodeDir / "node.conf").toFile())
|
||||||
val notaryConfigs = configs.filter { it.hasPath("notary") }
|
if (nodeConfig.hasPath("notary")) {
|
||||||
val notaries = notaryConfigs.associateBy(
|
val validating = nodeConfig.getConfig("notary").getBoolean("validating")
|
||||||
{ CordaX500Name.parse(it.getString("myLegalName")) },
|
val nodeInfoFile = nodeDir.list { paths -> paths.filter { it.fileName.toString().startsWith("nodeInfo-") }.findFirst().get() }
|
||||||
{ it.getConfig("notary").getBoolean("validating") }
|
processFile(nodeInfoFile)?.let { NotaryInfo(it.notaryIdentity(), validating) }
|
||||||
)
|
} else {
|
||||||
// Now get the notary identities based on names passed from configs. There is one problem, for distributed notaries
|
null
|
||||||
// in config we specify only node's main name, the notary identity isn't passed there. It's read from keystore on
|
}
|
||||||
// node startup, so we have to look it up from node info as a second identity, which is ugly.
|
}.distinct() // We need distinct as nodes part of a distributed notary share the same notary identity
|
||||||
return infos.mapNotNull {
|
|
||||||
info -> notaries[info.legalIdentities[0].name]?.let { NotaryInfo(info.notaryIdentity(), it) }
|
|
||||||
}.distinct()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private fun NodeInfo.notaryIdentity(): Party {
|
||||||
* Loads latest NodeInfo files stored in node's base directory.
|
return when (legalIdentities.size) {
|
||||||
* Scans main directory and [CordformNode.NODE_INFO_DIRECTORY].
|
// Single node notaries have just one identity like all other nodes. This identity is the notary identity
|
||||||
* Signatures are checked before returning a value. The latest value stored for a given name is returned.
|
1 -> legalIdentities[0]
|
||||||
*
|
// Nodes which are part of a distributed notary have a second identity which is the composite identity of the
|
||||||
* @return list of latest [NodeInfo]s
|
// cluster and is shared by all the other members. This is the notary identity.
|
||||||
*/
|
2 -> legalIdentities[1]
|
||||||
private fun getAllNodeInfos(nodesDirs: List<Path>): List<NodeInfo> {
|
else -> throw IllegalArgumentException("Not sure how to get the notary identity in this scenerio: $this")
|
||||||
val nodeInfoFiles = nodesDirs.map { dir ->
|
|
||||||
dir.list { it.filter { "nodeInfo-" in it.toString() }.findFirst().get() }
|
|
||||||
}
|
}
|
||||||
return nodeInfoFiles.mapNotNull { processFile(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processFile(file: Path): NodeInfo? {
|
private fun processFile(file: Path): NodeInfo? {
|
||||||
@ -92,8 +88,6 @@ class TestNetworkParametersGenerator : NetworkParametersGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun NodeInfo.notaryIdentity() = if (legalIdentities.size == 2) legalIdentities[1] else legalIdentities[0]
|
|
||||||
|
|
||||||
// We need to to set serialization env, because generation of parameters is run from Cordform.
|
// We need to to set serialization env, because generation of parameters is run from Cordform.
|
||||||
// KryoServerSerializationScheme is not accessible from nodeapi.
|
// KryoServerSerializationScheme is not accessible from nodeapi.
|
||||||
private fun initialiseSerialization() {
|
private fun initialiseSerialization() {
|
||||||
@ -103,14 +97,14 @@ class TestNetworkParametersGenerator : NetworkParametersGenerator {
|
|||||||
registerScheme(KryoParametersSerializationScheme)
|
registerScheme(KryoParametersSerializationScheme)
|
||||||
registerScheme(AMQPServerSerializationScheme())
|
registerScheme(AMQPServerSerializationScheme())
|
||||||
},
|
},
|
||||||
context))
|
context)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private object KryoParametersSerializationScheme : AbstractKryoSerializationScheme() {
|
private object KryoParametersSerializationScheme : AbstractKryoSerializationScheme() {
|
||||||
override fun canDeserializeVersion(byteSequence: ByteSequence, target: SerializationContext.UseCase): Boolean {
|
override fun canDeserializeVersion(byteSequence: ByteSequence, target: SerializationContext.UseCase): Boolean {
|
||||||
return byteSequence == KryoHeaderV0_1 && target == SerializationContext.UseCase.P2P
|
return byteSequence == KryoHeaderV0_1 && target == SerializationContext.UseCase.P2P
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun rpcClientKryoPool(context: SerializationContext) = throw UnsupportedOperationException()
|
override fun rpcClientKryoPool(context: SerializationContext) = throw UnsupportedOperationException()
|
||||||
override fun rpcServerKryoPool(context: SerializationContext) = throw UnsupportedOperationException()
|
override fun rpcServerKryoPool(context: SerializationContext) = throw UnsupportedOperationException()
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user