CORDA-3406: Modify DemoBench to make using the DJVM obvious and optional.

This commit is contained in:
Chris Rankin 2019-11-06 17:37:06 +00:00
parent 7708a3c28a
commit 6380feee41
8 changed files with 70 additions and 20 deletions

View File

@ -254,6 +254,7 @@ allprojects {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-Xlint:-options" << "-parameters"
options.compilerArgs << '-XDenableSunApiLintControl'
if (warnings_as_errors) {
// We cannot fail the build on compiler warnings because we have java warnings that you cannot disable:
// Signal is internal proprietary API and may be removed in a future release

View File

@ -36,16 +36,13 @@ data class NodeConfig(
/** Pass-through for generating node.conf with external DB */
val dataSourceProperties: Properties? = null,
val database: Properties? = null,
val systemProperties: Map<String, Any?>,
private val devMode: Boolean = true,
private val detectPublicIp: Boolean = false,
private val useTestClock: Boolean = true
) {
companion object {
val renderOptions: ConfigRenderOptions = ConfigRenderOptions.defaults().setOriginComments(false)
val systemProperties: Map<String, Any> = mapOf(
"net.corda.djvm" to true,
"co.paralleluniverse.fibers.verifyInstrumentation" to false
)
val defaultUser = user("guest")
const val CORDAPP_DIR_NAME = "cordapps"
}
@ -143,6 +140,7 @@ fun String.toKey() = filter { !it.isWhitespace() }.toLowerCase()
fun <T> valueFor(any: T): ConfigValue = ConfigValueFactory.fromAnyRef(any)
@Suppress("unused")
private fun Config.withOptionalValue(path: String, obj: ConfigObject): Config {
return if (obj.isEmpty()) this else this.withValue(path, obj)
return if (obj.isEmpty()) this else withValue(path, obj)
}

View File

@ -1,6 +1,8 @@
package net.corda.demobench.model
import javafx.application.Application.Parameters
import javafx.beans.binding.IntegerExpression
import javafx.beans.property.SimpleBooleanProperty
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.internal.*
@ -20,14 +22,37 @@ import java.time.Instant
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
import java.util.logging.Level
import kotlin.math.max
class NodeController(check: atRuntime = ::checkExists) : Controller() {
class NodeController(
djvmEnabled: Boolean = readDJVMEnabled(),
check: atRuntime = ::checkExists
) : Controller() {
companion object {
const val firstPort = 10000
const val minPort = 1024
const val maxPort = 65535
private const val MB = 1024 * 1024
const val maxMessageSize = 10 * MB
const val maxTransactionSize = 10 * MB
private fun readDJVMEnabled(): Boolean {
return FX.application.parameters?.let(::parseDJVMEnabled) ?: false
}
private fun parseDJVMEnabled(parameters: Parameters): Boolean {
val isEnabled = parameters.named["djvm"]
return if (isEnabled == null) {
parameters.unnamed.contains("--djvm")
} else {
java.lang.Boolean.parseBoolean(isEnabled)
}
}
}
val djvmEnabled = SimpleBooleanProperty(djvmEnabled)
private val jvm by inject<JVMConfig>()
private val cordappController by inject<CordappController>()
private val nodeInfoFilesCopier by inject<DemoBenchNodeInfoFilesCopier>()
@ -77,7 +102,11 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() {
webAddress = nodeData.webPort.toLocalAddress(),
notary = notary,
h2port = nodeData.h2Port.value,
issuableCurrencies = nodeData.extraServices.filterIsInstance<CurrencyIssuer>().map { it.currency.toString() }
issuableCurrencies = nodeData.extraServices.filterIsInstance<CurrencyIssuer>().map { it.currency.toString() },
systemProperties = mapOf(
"net.corda.djvm" to djvmEnabled.value,
"co.paralleluniverse.fibers.verifyInstrumentation" to false
)
)
val wrapper = NodeConfigWrapper(baseDir, nodeConfig)
@ -135,15 +164,14 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() {
}
}
@Suppress("MagicNumber") // initialising to max value
private fun makeNetworkParametersCopier(config: NodeConfigWrapper): NetworkParametersCopier {
val identity = getNotaryIdentity(config)
val parametersCopier = NetworkParametersCopier(NetworkParameters(
minimumPlatformVersion = 1,
notaries = listOf(NotaryInfo(identity, config.nodeConfig.notary!!.validating)),
modifiedTime = Instant.now(),
maxMessageSize = 10485760,
maxTransactionSize = 10485760,
maxMessageSize = maxMessageSize,
maxTransactionSize = maxTransactionSize,
epoch = 1,
whitelistedContractImplementations = emptyMap()
))
@ -203,7 +231,7 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() {
private fun updatePort(config: NodeConfig) {
val nextPort = 1 + arrayOf(config.p2pAddress.port, config.rpcSettings.address.port, config.webAddress.port, config.h2port).max() as Int
port.getAndUpdate { Math.max(nextPort, it) }
port.getAndUpdate { max(nextPort, it) }
}
private fun baseDirFor(time: Long): Path = jvm.dataHome.resolve(localFor(time))

View File

@ -28,7 +28,7 @@ object SuggestedDetails {
private var cursor = 0
fun nextBank(exists: (String) -> Boolean): Pair<String, String> {
for (i in 0 until banks.size) {
for (i in banks.indices) {
val bank = banks[cursor]
if (!exists(bank.first)) {
return bank

View File

@ -150,6 +150,11 @@ class NodeTabView : Fragment() {
val toggle = radiobutton(notaryType.toString(), notaryTypeToggleGroup, notaryType)
toggle.isSelected = index == 0
}
separator()
checkbox("Deterministic Contract Verification", nodeController.djvmEnabled).apply {
styleClass += "djvm"
}
}
}
}

View File

@ -52,6 +52,10 @@
-fx-spacing: 5px;
}
.services-panel .separator {
-fx-padding: 15px;
}
.cordapps-panel {
-fx-pref-width: 600px;
-fx-spacing: 5px;

View File

@ -41,12 +41,9 @@ class NodeConfigTest {
.withFallback(ConfigFactory.parseMap(mapOf("devMode" to true)))
.resolve()
val fullConfig = nodeConfig.parseAsNodeConfiguration().value()
val systemProperties = nodeConfig.getConfig("systemProperties").toProperties()
// No custom configuration is created by default.
assertFailsWith<ConfigException.Missing> { nodeConfig.getConfig("custom") }
assertEquals(true.toString(), systemProperties.getProperty("net.corda.djvm"))
assertEquals(false.toString(), systemProperties.getProperty("co.paralleluniverse.fibers.verifyInstrumentation"))
assertEquals(myLegalName, fullConfig.myLegalName)
assertEquals(localPort(40002), fullConfig.rpcOptions.address)
@ -133,6 +130,7 @@ class NodeConfigTest {
assertEquals("cordacadevpass", webConfig.keyStorePassword)
}
@Suppress("LongParameterList")
private fun createConfig(
legalName: CordaX500Name = CordaX500Name(organisation = "Unknown", locality = "Nowhere", country = "GB"),
p2pPort: Int = -1,
@ -142,7 +140,8 @@ class NodeConfigTest {
h2port: Int = -1,
notary: NotaryService?,
users: List<User> = listOf(user("guest")),
issuableCurrencies: List<String> = emptyList()
issuableCurrencies: List<String> = emptyList(),
systemProperties: Map<String, Any?> = emptyMap()
): NodeConfig {
return NodeConfig(
myLegalName = legalName,
@ -155,7 +154,8 @@ class NodeConfigTest {
h2port = h2port,
notary = notary,
rpcUsers = users,
issuableCurrencies = issuableCurrencies
issuableCurrencies = issuableCurrencies,
systemProperties = systemProperties
)
}

View File

@ -11,7 +11,7 @@ import kotlin.test.*
class NodeControllerTest {
private val baseDir: Path = Paths.get(".").toAbsolutePath()
private val controller = NodeController({ _, _ -> })
private val controller = NodeController(false) { _, _ -> }
private val node1Name = "Organisation 1"
private val organisation2Name = "Organisation 2"
@ -63,6 +63,17 @@ class NodeControllerTest {
assertTrue(controller.nameExists("organisation 1"))
}
@Test
fun `test node system properties`() {
val data = NodeData()
data.legalName.value = node1Name
val wrapper = controller.validate(data) ?: fail("No wrapped configuration!")
val systemProperties = wrapper.nodeConfig.systemProperties
assertFalse(systemProperties["net.corda.djvm"] as Boolean)
assertFalse(systemProperties["co.paralleluniverse.fibers.verifyInstrumentation"] as Boolean)
}
@Test
fun `test register unique nodes`() {
val config = createConfig(organisation = organisation2Name)
@ -146,6 +157,7 @@ class NodeControllerTest {
assertTrue(controller.keyExists("myname"))
}
@Suppress("LongParameterList")
private fun createConfig(
organisation: String = "Unknown",
p2pPort: Int = 0,
@ -154,7 +166,8 @@ class NodeControllerTest {
webPort: Int = 0,
h2port: Int = 0,
notary: NotaryService? = null,
users: List<User> = listOf(user("guest"))
users: List<User> = listOf(user("guest")),
systemProperties: Map<String, Any?> = emptyMap()
): NodeConfigWrapper {
val nodeConfig = NodeConfig(
myLegalName = CordaX500Name(
@ -170,7 +183,8 @@ class NodeControllerTest {
webAddress = localPort(webPort),
h2port = h2port,
notary = notary,
rpcUsers = users
rpcUsers = users,
systemProperties = systemProperties
)
return NodeConfigWrapper(baseDir, nodeConfig)
}