CORDA-1593 Extracting the whitelist logic and making it public (#3317)

* CORDA-1539 Extracting the whitelist logic and making it public

* Addressing review comments
This commit is contained in:
Michal Kit 2018-06-12 09:31:06 +01:00 committed by GitHub
parent 8087f3c5d3
commit 02884e6c81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 32 deletions

View File

@ -3,7 +3,6 @@ package net.corda.nodeapi.internal.network
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import net.corda.cordform.CordformNode
import net.corda.core.contracts.ContractClassName
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.internal.*
@ -55,7 +54,6 @@ class NetworkBootstrapper {
)
private const val LOGS_DIR_NAME = "logs"
private const val EXCLUDE_WHITELIST_FILE_NAME = "exclude_whitelist.txt"
@JvmStatic
fun main(args: Array<String>) {
@ -291,35 +289,6 @@ class NetworkBootstrapper {
return networkParameters
}
@VisibleForTesting
internal fun generateWhitelist(networkParameters: NetworkParameters?,
excludeContracts: List<ContractClassName>,
cordappJars: List<ContractsJar>): Map<ContractClassName, List<AttachmentId>> {
val existingWhitelist = networkParameters?.whitelistedContractImplementations ?: emptyMap()
if (excludeContracts.isNotEmpty()) {
println("Exclude contracts from whitelist: ${excludeContracts.joinToString()}")
existingWhitelist.keys.forEach {
require(it !in excludeContracts) { "$it is already part of the existing whitelist and cannot be excluded." }
}
}
val newWhiteList = cordappJars
.flatMap { jar -> (jar.scan() - excludeContracts).map { it to jar.hash } }
.toMultiMap()
return (newWhiteList.keys + existingWhitelist.keys).associateBy({ it }) {
val existingHashes = existingWhitelist[it] ?: emptyList()
val newHashes = newWhiteList[it] ?: emptyList()
(existingHashes + newHashes).distinct()
}
}
private fun readExcludeWhitelist(directory: Path): List<String> {
val file = directory / EXCLUDE_WHITELIST_FILE_NAME
return if (file.exists()) file.readAllLines().map(String::trim) else emptyList()
}
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

View File

@ -0,0 +1,43 @@
package net.corda.nodeapi.internal.network
import net.corda.core.contracts.ContractClassName
import net.corda.core.internal.div
import net.corda.core.internal.exists
import net.corda.core.internal.readAllLines
import net.corda.core.internal.toMultiMap
import net.corda.core.node.NetworkParameters
import net.corda.core.node.services.AttachmentId
import net.corda.nodeapi.internal.ContractsJar
import org.slf4j.LoggerFactory
import java.nio.file.Path
private const val EXCLUDE_WHITELIST_FILE_NAME = "exclude_whitelist.txt"
private val logger = LoggerFactory.getLogger("net.corda.nodeapi.internal.network.WhitelistGenerator")
fun generateWhitelist(networkParameters: NetworkParameters?,
excludeContracts: List<ContractClassName>,
cordappJars: List<ContractsJar>): Map<ContractClassName, List<AttachmentId>> {
val existingWhitelist = networkParameters?.whitelistedContractImplementations ?: emptyMap()
if (excludeContracts.isNotEmpty()) {
logger.info("Exclude contracts from whitelist: ${excludeContracts.joinToString()}")
existingWhitelist.keys.forEach {
require(it !in excludeContracts) { "$it is already part of the existing whitelist and cannot be excluded." }
}
}
val newWhiteList = cordappJars
.flatMap { jar -> (jar.scan() - excludeContracts).map { it to jar.hash } }
.toMultiMap()
return (newWhiteList.keys + existingWhitelist.keys).associateBy({ it }) {
val existingHashes = existingWhitelist[it] ?: emptyList()
val newHashes = newWhiteList[it] ?: emptyList()
(existingHashes + newHashes).distinct()
}
}
fun readExcludeWhitelist(directory: Path): List<String> {
val file = directory / EXCLUDE_WHITELIST_FILE_NAME
return if (file.exists()) file.readAllLines().map(String::trim) else emptyList()
}

View File

@ -127,7 +127,7 @@ class NetworkBootstrapperTest {
private fun generateWhitelist(existingWhitelist: Map<String, List<AttachmentId>>,
excludeContracts: List<ContractClassName>,
contractJars: List<TestContractsJar>): Map<String, List<AttachmentId>> {
return NetworkBootstrapper().generateWhitelist(
return generateWhitelist(
testNetworkParameters(whitelistedContractImplementations = existingWhitelist),
excludeContracts,
contractJars

View File

@ -0,0 +1,41 @@
package net.corda.nodeapi.internal.network
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.verify
import net.corda.core.crypto.SecureHash
import net.corda.nodeapi.internal.ContractsJar
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class WhitelistGeneratorTest {
@Test
fun `whitelist generator builds the correct whitelist map`() {
// given
val jars = (0..9).map {
val index = it
mock<ContractsJar> {
val secureHash = SecureHash.randomSHA256()
on { scan() }.then {
listOf(index.toString())
}
on { hash }.then {
secureHash
}
}
}
// when
val result = generateWhitelist(null, emptyList(), jars)
// then
jars.forEachIndexed { index, item ->
verify(item).scan()
val attachmentIds = requireNotNull(result[index.toString()])
assertEquals(1, attachmentIds.size)
assertTrue { attachmentIds.contains(item.hash) }
}
}
}