CORDA-1048: Making it simpler to move an existing local deployment of nodes to across different machines. (#2672)

This was achieved by having the hash in the node-info file to be just of the node's X.500 name. This also solves existing duplicate node-info file issues that we've been having.

Also updated the docsite.
This commit is contained in:
Shams Asari
2018-03-01 21:24:10 +00:00
committed by GitHub
parent 14cafee66e
commit 8616f24523
13 changed files with 162 additions and 122 deletions

View File

@ -53,3 +53,13 @@ inline fun NodeInfo.sign(signer: (PublicKey, SerializedBytes<NodeInfo>) -> Digit
val signatures = owningKeys.map { signer(it, serialised) }
return SignedNodeInfo(serialised, signatures)
}
/**
* A container for a [SignedNodeInfo] and its cached [NodeInfo].
*/
class NodeInfoAndSigned private constructor(val nodeInfo: NodeInfo, val signed: SignedNodeInfo) {
constructor(nodeInfo: NodeInfo, signer: (PublicKey, SerializedBytes<NodeInfo>) -> DigitalSignature) : this(nodeInfo, nodeInfo.sign(signer))
constructor(signedNodeInfo: SignedNodeInfo) : this(signedNodeInfo.verified(), signedNodeInfo)
operator fun component1(): NodeInfo = nodeInfo
operator fun component2(): SignedNodeInfo = signed
}

View File

@ -4,6 +4,7 @@ import com.google.common.hash.Hashing
import com.google.common.hash.HashingInputStream
import com.typesafe.config.ConfigFactory
import net.corda.cordform.CordformNode
import net.corda.core.contracts.ContractClassName
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.SecureHash.Companion.parse
import net.corda.core.identity.Party
@ -77,9 +78,9 @@ class NetworkBootstrapper {
distributeNodeInfos(nodeDirs, nodeInfoFiles)
println("Gathering notary identities")
val notaryInfos = gatherNotaryInfos(nodeInfoFiles)
println("Notary identities to be used in network-parameters file: ${notaryInfos.joinToString("; ") { it.prettyPrint() }}")
println("Notary identities to be used in network parameters: ${notaryInfos.joinToString("; ") { it.prettyPrint() }}")
val mergedWhiteList = generateWhitelist(directory / WHITELIST_FILE_NAME, cordapps?.distinct())
println("Updating whitelist.")
println("Updating whitelist")
overwriteWhitelist(directory / WHITELIST_FILE_NAME, mergedWhiteList)
installNetworkParameters(notaryInfos, nodeDirs, mergedWhiteList)
println("Bootstrapping complete!")
@ -189,16 +190,18 @@ class NetworkBootstrapper {
private fun generateWhitelist(whitelistFile: Path, cordapps: List<String>?): Map<String, List<AttachmentId>> {
val existingWhitelist = if (whitelistFile.exists()) readContractWhitelist(whitelistFile) else emptyMap()
println("Found existing whitelist: $existingWhitelist")
println("Found existing whitelist:")
existingWhitelist.forEach { println(it.outputString()) }
val newWhiteList = cordapps?.flatMap { cordappJarPath ->
val newWhiteList: Map<ContractClassName, AttachmentId> = cordapps?.flatMap { cordappJarPath ->
val jarHash = getJarHash(cordappJarPath)
scanJarForContracts(cordappJarPath).map { contract ->
contract to jarHash
}
}?.toMap() ?: emptyMap()
println("Calculating whitelist for current cordapps: $newWhiteList")
println("Calculating whitelist for current CorDapps:")
newWhiteList.forEach { (contract, attachment) -> println("$contract:$attachment") }
val merged = (newWhiteList.keys + existingWhitelist.keys).map { contractClassName ->
val existing = existingWhitelist[contractClassName] ?: emptyList()
@ -206,16 +209,15 @@ class NetworkBootstrapper {
contractClassName to (if (newHash == null || newHash in existing) existing else existing + newHash)
}.toMap()
println("Final whitelist: $merged")
println("Final whitelist:")
merged.forEach { println(it.outputString()) }
return merged
}
private fun overwriteWhitelist(whitelistFile: Path, mergedWhiteList: Map<String, List<AttachmentId>>) {
PrintStream(whitelistFile.toFile().outputStream()).use { out ->
mergedWhiteList.forEach { (contract, attachments )->
out.println("${contract}:${attachments.joinToString(",")}")
}
mergedWhiteList.forEach { out.println(it.outputString()) }
}
}
@ -235,15 +237,17 @@ class NetworkBootstrapper {
private fun NodeInfo.notaryIdentity(): Party {
return when (legalIdentities.size) {
// Single node notaries have just one identity like all other nodes. This identity is the notary identity
// Single node notaries have just one identity like all other nodes. This identity is the notary identity
1 -> legalIdentities[0]
// Nodes which are part of a distributed notary have a second identity which is the composite identity of the
// cluster and is shared by all the other members. This is the notary identity.
// Nodes which are part of a distributed notary have a second identity which is the composite identity of the
// cluster and is shared by all the other members. This is the notary identity.
2 -> legalIdentities[1]
else -> throw IllegalArgumentException("Not sure how to get the notary identity in this scenerio: $this")
}
}
private fun Map.Entry<ContractClassName, List<AttachmentId>>.outputString() = "$key:${value.joinToString(",")}"
// We need to to set serialization env, because generation of parameters is run from Cordform.
// KryoServerSerializationScheme is not accessible from nodeapi.
private fun initialiseSerialization() {