ENT-2188 fix H2 insecure default configuration (#3692)

Set the "h2.allowedClasses" system property, require database password when exposing H2 server on non-localhost address, samples start H2 server by default (reintroduces the behaviour before h2Settings.address configuration option was added)
This commit is contained in:
szymonsztuka 2018-08-01 11:50:42 +01:00 committed by GitHub
parent 7182542724
commit c23167f08e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 220 additions and 15 deletions

View File

@ -86,7 +86,7 @@ absolute path to the node's base directory.
:h2Port: Deprecated. Use ``h2Settings`` instead. :h2Port: Deprecated. Use ``h2Settings`` instead.
:h2Settings: Sets the H2 JDBC server port. See :doc:`node-database-access-h2`. :h2Settings: Sets the H2 JDBC server host and port. See :doc:`node-database-access-h2`. For non-localhost address the database passowrd needs to be set in ``dataSourceProperties``.
:messagingServerAddress: The address of the ArtemisMQ broker instance. If not provided the node will run one locally. :messagingServerAddress: The address of the ArtemisMQ broker instance. If not provided the node will run one locally.

View File

@ -86,6 +86,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
adminAddress "localhost:10013" adminAddress "localhost:10013"
} }
webPort 10004 webPort 10004
extraConfig = ['h2Settings.address' : 'localhost:10014']
cordapps = [] cordapps = []
} }
node { node {
@ -96,6 +97,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
adminAddress "localhost:10016" adminAddress "localhost:10016"
} }
webPort 10007 webPort 10007
extraConfig = ['h2Settings.address' : 'localhost:10017']
cordapps = [] cordapps = []
rpcUsers = [ rpcUsers = [
['username' : "user", ['username' : "user",

View File

@ -32,13 +32,17 @@ If you want H2 to auto-select a port (mimicking the old ``h2Port`` behaviour), y
address: "localhost:0" address: "localhost:0"
} }
If remote access is required, the address can be changed to ``0.0.0.0``. However it is recommended to change the default username and password before doing so. If remote access is required, the address can be changed to ``0.0.0.0``.
The node requires a database password to be set when the database is exposed on the network interface to listen on.
.. sourcecode:: groovy .. sourcecode:: groovy
h2Settings { h2Settings {
address: "0.0.0.0:12345" address: "0.0.0.0:12345"
} }
dataSourceProperties {
dataSource.password : "strongpassword"
}
The previous ``h2Port`` syntax is now deprecated. ``h2Port`` will continue to work but the database The previous ``h2Port`` syntax is now deprecated. ``h2Port`` will continue to work but the database
will only be accessible on localhost. will only be accessible on localhost.

View File

@ -3,7 +3,24 @@ Node database
Default in-memory database Default in-memory database
-------------------------- --------------------------
By default, nodes store their data in an H2 database. You can connect directly to a running node's database to see its By default, nodes store their data in an H2 database.
The database (a file persistence.mv.db) is created at the first node startup with the administrator user 'sa' and a blank password.
The user name and password can be changed in node configuration:
.. sourcecode:: groovy
dataSourceProperties = {
dataSource.user = [USER]
dataSource.password = [PASSWORD]
}
Note, changing user/password for the existing node in node.conf will not update them in the H2 database,
you need to login to the database first to create new user or change the user password.
The database password is required only when the H2 database is exposed on non-localhost address (which is disabled by default).
The node requires the user with administrator permissions in order to creates tables upon the first startup
or after deplying new CorDapps with own tables.
You can connect directly to a running node's database to see its
stored states, transactions and attachments as follows: stored states, transactions and attachments as follows:
* Enable the H2 database access in the node configuration using the following syntax: * Enable the H2 database access in the node configuration using the following syntax:
@ -35,7 +52,8 @@ interface for you to query them using SQL.
The default behaviour is to expose the H2 database on localhost. This can be overridden in the The default behaviour is to expose the H2 database on localhost. This can be overridden in the
node configuration using ``h2Settings.address`` and specifying the address of the network interface to listen on, node configuration using ``h2Settings.address`` and specifying the address of the network interface to listen on,
or simply using ``0.0.0.0:0`` to listen on all interfaces. or simply using ``0.0.0.0:0`` to listen on all interfaces. The node requires a database password to be set when
the database is exposed on the network interface to listen on.
PostgreSQL PostgreSQL
---------- ----------

View File

@ -28,7 +28,7 @@ class AddressBindingFailureTests {
fun `rpc admin address`() = assertBindExceptionForOverrides { address -> mapOf("rpcSettings" to mapOf("adminAddress" to address.toString())) } fun `rpc admin address`() = assertBindExceptionForOverrides { address -> mapOf("rpcSettings" to mapOf("adminAddress" to address.toString())) }
@Test @Test
fun `H2 address`() = assertBindExceptionForOverrides { address -> mapOf("h2Settings" to mapOf("address" to address.toString())) } fun `H2 address`() = assertBindExceptionForOverrides { address -> mapOf("h2Settings" to mapOf("address" to address.toString()), "dataSourceProperties.dataSource.password" to "password") }
private fun assertBindExceptionForOverrides(overrides: (NetworkHostAndPort) -> Map<String, Any?>) { private fun assertBindExceptionForOverrides(overrides: (NetworkHostAndPort) -> Map<String, Any?>) {

View File

@ -0,0 +1,136 @@
package net.corda.node.persistence
import co.paralleluniverse.fibers.Suspendable
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
import net.corda.core.messaging.startFlow
import net.corda.core.utilities.getOrThrow
import net.corda.node.services.Permissions
import net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.node.User
import org.junit.Test
import java.net.InetAddress
import java.sql.DriverManager
import kotlin.test.assertFailsWith
import kotlin.test.assertNull
import kotlin.test.assertTrue
class H2SecurityTests {
companion object {
private val port = PortAllocation.Incremental(21_000)
private fun getFreePort() = port.nextPort()
private const val h2AddressKey = "h2Settings.address"
private const val dbPasswordKey = "dataSourceProperties.dataSource.password"
}
@Test
fun `h2 server starts when h2Settings are set`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), notarySpecs = emptyList())) {
val port = getFreePort()
startNode(customOverrides = mapOf(h2AddressKey to "localhost:$port")).getOrThrow()
DriverManager.getConnection("jdbc:h2:tcp://localhost:$port/node", "sa", "").use {
assertTrue(it.createStatement().executeQuery("SELECT 1").next())
}
}
}
@Test
fun `h2 server on the host name requires non-default database password`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), notarySpecs = emptyList())) {
assertFailsWith(CouldNotCreateDataSourceException::class) {
startNode(customOverrides = mapOf(h2AddressKey to "${InetAddress.getLocalHost().hostName}:${getFreePort()}")).getOrThrow()
}
}
}
@Test
fun `h2 server on the external host IP requires non-default database password`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), notarySpecs = emptyList())) {
assertFailsWith(CouldNotCreateDataSourceException::class) {
startNode(customOverrides = mapOf(h2AddressKey to "${InetAddress.getLocalHost().hostAddress}:${getFreePort()}")).getOrThrow()
}
}
}
@Test
fun `h2 server on host name requires non-blank database password`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), notarySpecs = emptyList())) {
assertFailsWith(CouldNotCreateDataSourceException::class) {
startNode(customOverrides = mapOf(h2AddressKey to "${InetAddress.getLocalHost().hostName}:${getFreePort()}",
dbPasswordKey to " ")).getOrThrow()
}
}
}
@Test
fun `h2 server on external host IP requires non-blank database password`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), notarySpecs = emptyList())) {
assertFailsWith(CouldNotCreateDataSourceException::class) {
startNode(customOverrides = mapOf(h2AddressKey to "${InetAddress.getLocalHost().hostAddress}:${getFreePort()}",
dbPasswordKey to " ")).getOrThrow()
}
}
}
@Test
fun `h2 server on localhost runs with the default database password`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = false, notarySpecs = emptyList())) {
startNode(customOverrides = mapOf(h2AddressKey to "localhost:${getFreePort()}")).getOrThrow()
}
}
@Test
fun `h2 server to loopback IP runs with the default database password`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), notarySpecs = emptyList())) {
startNode(customOverrides = mapOf(h2AddressKey to "127.0.0.1:${getFreePort()}")).getOrThrow()
}
}
@Test
fun `remote code execution via h2 server is disabled`() {
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = false, notarySpecs = emptyList())) {
val port = getFreePort()
startNode(customOverrides = mapOf(h2AddressKey to "localhost:$port", dbPasswordKey to "x")).getOrThrow()
DriverManager.getConnection("jdbc:h2:tcp://localhost:$port/node", "sa", "x").use {
assertFailsWith(org.h2.jdbc.JdbcSQLException::class) {
it.createStatement().execute("CREATE ALIAS SET_PROPERTY FOR \"java.lang.System.setProperty\"")
it.createStatement().execute("CALL SET_PROPERTY('abc', '1')")
}
}
assertNull(System.getProperty("abc"))
}
}
@Test
fun `malicious flow tries to enable remote code execution via h2 server`() {
val user = User("mark", "dadada", setOf(Permissions.startFlow<MaliciousFlow>()))
driver(DriverParameters(inMemoryDB = false, startNodesInProcess = false, notarySpecs = emptyList())) {
val port = getFreePort()
val nodeHandle = startNode(rpcUsers = listOf(user), customOverrides = mapOf(h2AddressKey to "localhost:$port",
dbPasswordKey to "x")).getOrThrow()
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
it.proxy.startFlow(::MaliciousFlow).returnValue.getOrThrow()
}
DriverManager.getConnection("jdbc:h2:tcp://localhost:$port/node", "sa", "x").use {
assertFailsWith(org.h2.jdbc.JdbcSQLException::class) {
it.createStatement().execute("CREATE ALIAS SET_PROPERTY FOR \"java.lang.System.setProperty\"")
it.createStatement().execute("CALL SET_PROPERTY('abc', '1')")
}
}
assertNull(System.getProperty("abc"))
}
}
@StartableByRPC
class MaliciousFlow : FlowLogic<Boolean>() {
@Suspendable
override fun call(): Boolean {
System.clearProperty("h2.allowedClasses")
return true
}
}
}

View File

@ -54,6 +54,7 @@ import net.corda.nodeapi.internal.bridging.BridgeControlListener
import net.corda.nodeapi.internal.config.User import net.corda.nodeapi.internal.config.User
import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.serialization.internal.* import net.corda.serialization.internal.*
import net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException
import org.h2.jdbc.JdbcSQLException import org.h2.jdbc.JdbcSQLException
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -61,11 +62,13 @@ import rx.Observable
import rx.Scheduler import rx.Scheduler
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import java.net.BindException import java.net.BindException
import java.net.InetAddress
import java.nio.file.Path import java.nio.file.Path
import java.time.Clock import java.time.Clock
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import javax.management.ObjectName import javax.management.ObjectName
import kotlin.system.exitProcess import kotlin.system.exitProcess
import java.nio.file.Paths
class NodeWithInfo(val node: Node, val info: NodeInfo) { class NodeWithInfo(val node: Node, val info: NodeInfo) {
val services: StartedNodeServices = object : StartedNodeServices, ServiceHubInternal by node.services, FlowStarter by node.flowStarter {} val services: StartedNodeServices = object : StartedNodeServices, ServiceHubInternal by node.services, FlowStarter by node.flowStarter {}
@ -331,13 +334,20 @@ open class Node(configuration: NodeConfiguration,
if (databaseUrl != null && databaseUrl.startsWith(h2Prefix)) { if (databaseUrl != null && databaseUrl.startsWith(h2Prefix)) {
val effectiveH2Settings = configuration.effectiveH2Settings val effectiveH2Settings = configuration.effectiveH2Settings
//forbid execution of arbitrary code via SQL except those classes required by H2 itself
System.setProperty("h2.allowedClasses", "org.h2.mvstore.db.MVTableEngine,org.locationtech.jts.geom.Geometry,org.h2.server.TcpServer")
if (effectiveH2Settings?.address != null) { if (effectiveH2Settings?.address != null) {
if (!InetAddress.getByName(effectiveH2Settings.address.host).isLoopbackAddress
&& configuration.dataSourceProperties.getProperty("dataSource.password").isBlank()) {
throw CouldNotCreateDataSourceException("Database password is required for H2 server listening on ${InetAddress.getByName(effectiveH2Settings.address.host)}.")
}
val databaseName = databaseUrl.removePrefix(h2Prefix).substringBefore(';') val databaseName = databaseUrl.removePrefix(h2Prefix).substringBefore(';')
val baseDir = Paths.get(databaseName).parent.toString()
val server = org.h2.tools.Server.createTcpServer( val server = org.h2.tools.Server.createTcpServer(
"-tcpPort", effectiveH2Settings.address.port.toString(), "-tcpPort", effectiveH2Settings.address.port.toString(),
"-tcpAllowOthers", "-tcpAllowOthers",
"-tcpDaemon", "-tcpDaemon",
"-baseDir", baseDir,
"-key", "node", databaseName) "-key", "node", databaseName)
// override interface that createTcpServer listens on (which is always 0.0.0.0) // override interface that createTcpServer listens on (which is always 0.0.0.0)
System.setProperty("h2.bindAddress", effectiveH2Settings.address.host) System.setProperty("h2.bindAddress", effectiveH2Settings.address.host)

View File

@ -53,6 +53,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
address "localhost:10003" address "localhost:10003"
adminAddress "localhost:10004" adminAddress "localhost:10004"
} }
extraConfig = ['h2Settings.address' : 'localhost:10012']
} }
node { node {
name "O=Bank A,L=London,C=GB" name "O=Bank A,L=London,C=GB"
@ -63,6 +64,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
address "localhost:10006" address "localhost:10006"
adminAddress "localhost:10007" adminAddress "localhost:10007"
} }
extraConfig = ['h2Settings.address' : 'localhost:10013']
} }
node { node {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
@ -74,6 +76,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
webPort 10010 webPort 10010
cordapps = [] cordapps = []
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
extraConfig = ['h2Settings.address' : 'localhost:10014']
} }
} }

View File

@ -44,10 +44,12 @@ class BankOfCordaCordform : CordformDefinition() {
adminAddress("localhost:10004") adminAddress("localhost:10004")
} }
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:10016"))
} }
node { node {
name(BOC_NAME) name(BOC_NAME)
extraConfig = mapOf("custom" to mapOf("issuableCurrencies" to listOf("USD"))) extraConfig = mapOf("custom" to mapOf("issuableCurrencies" to listOf("USD")),
"h2Settings" to mapOf("address" to "localhost:10017"))
p2pPort(10005) p2pPort(10005)
rpcSettings { rpcSettings {
address("localhost:$BOC_RPC_PORT") address("localhost:$BOC_RPC_PORT")
@ -67,6 +69,7 @@ class BankOfCordaCordform : CordformDefinition() {
webPort(10010) webPort(10010)
rpcUsers(User(BIGCORP_RPC_USER, BIGCORP_RPC_PWD, setOf(all()))) rpcUsers(User(BIGCORP_RPC_USER, BIGCORP_RPC_PWD, setOf(all())))
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:10018"))
} }
} }

View File

@ -22,10 +22,11 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
port 10003 port 10003
adminPort 10004 adminPort 10004
} }
extraConfig = ['h2Settings.address' : 'localhost:10005']
} }
node { node {
name "O=Bank A,L=London,C=GB" name "O=Bank A,L=London,C=GB"
p2pPort 10005 p2pPort 10006
cordapps = [] cordapps = []
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
// This configures the default cordapp for this node // This configures the default cordapp for this node
@ -36,10 +37,11 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
port 10007 port 10007
adminPort 10008 adminPort 10008
} }
extraConfig = ['h2Settings.address' : 'localhost:10009']
} }
node { node {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
p2pPort 10009 p2pPort 10010
cordapps = [] cordapps = []
rpcUsers = ext.rpcUsers rpcUsers = ext.rpcUsers
// This configures the default cordapp for this node // This configures the default cordapp for this node
@ -50,5 +52,6 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
port 10011 port 10011
adminPort 10012 adminPort 10012
} }
extraConfig = ['h2Settings.address' : 'localhost:10013']
} }
} }

View File

@ -70,6 +70,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
cordapps = ["${project(":finance").group}:finance:$corda_release_version"] cordapps = ["${project(":finance").group}:finance:$corda_release_version"]
rpcUsers = rpcUsersList rpcUsers = rpcUsersList
useTestClock true useTestClock true
extraConfig = ['h2Settings.address' : 'localhost:10024']
} }
node { node {
name "O=Bank A,L=London,C=GB" name "O=Bank A,L=London,C=GB"
@ -81,6 +82,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
cordapps = ["${project(":finance").group}:finance:$corda_release_version"] cordapps = ["${project(":finance").group}:finance:$corda_release_version"]
rpcUsers = rpcUsersList rpcUsers = rpcUsersList
useTestClock true useTestClock true
extraConfig = ['h2Settings.address' : 'localhost:10027']
} }
node { node {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
@ -92,6 +94,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
cordapps = ["${project.group}:finance:$corda_release_version"] cordapps = ["${project.group}:finance:$corda_release_version"]
rpcUsers = rpcUsersList rpcUsers = rpcUsersList
useTestClock true useTestClock true
extraConfig = ['h2Settings.address' : 'localhost:10030']
} }
node { node {
name "O=Regulator,L=Moscow,C=RU" name "O=Regulator,L=Moscow,C=RU"
@ -104,6 +107,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
cordapps = ["${project(":finance").group}:finance:$corda_release_version"] cordapps = ["${project(":finance").group}:finance:$corda_release_version"]
rpcUsers = rpcUsersList rpcUsers = rpcUsersList
useTestClock true useTestClock true
extraConfig = ['h2Settings.address' : 'localhost:10033']
} }
} }

View File

@ -24,7 +24,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
port 10003 port 10003
adminPort 10004 adminPort 10004
} }
h2Port 20004 extraConfig = ['h2Settings.address' : 'localhost:20004']
} }
node { node {
name "O=Bank A,L=London,C=GB" name "O=Bank A,L=London,C=GB"
@ -35,6 +35,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
port 10007 port 10007
adminPort 10008 adminPort 10008
} }
extraConfig = ['h2Settings.address' : 'localhost:0']
} }
node { node {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
@ -45,5 +46,6 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
port 10011 port 10011
adminPort 10012 adminPort 10012
} }
extraConfig = ['h2Settings.address' : 'localhost:0']
} }
} }

View File

@ -52,7 +52,7 @@ by using the H2 web console:
Each node outputs its connection string in the terminal window as it starts up. In a terminal window where a **notary** node is running, Each node outputs its connection string in the terminal window as it starts up. In a terminal window where a **notary** node is running,
look for the following string: look for the following string:
``Database connection url is : jdbc:h2:tcp://10.18.0.150:56736/node`` ``Database connection url is : jdbc:h2:tcp://localhost:56736/node``
You can use the string on the right to connect to the h2 database: just paste it into the `JDBC URL` field and click *Connect*. You can use the string on the right to connect to the h2 database: just paste it into the `JDBC URL` field and click *Connect*.
You will be presented with a web application that enumerates all the available tables and provides an interface for you to query them using SQL You will be presented with a web application that enumerates all the available tables and provides an interface for you to query them using SQL

View File

@ -35,6 +35,7 @@ class BFTNotaryCordform : CordformDefinition() {
} }
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
@ -44,11 +45,13 @@ class BFTNotaryCordform : CordformDefinition() {
adminAddress("localhost:10106") adminAddress("localhost:10106")
} }
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
val clusterAddresses = (0 until clusterSize).map { NetworkHostAndPort("localhost", 11000 + it * 10) } val clusterAddresses = (0 until clusterSize).map { NetworkHostAndPort("localhost", 11000 + it * 10) }
fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node { fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node {
name(notaryNames[replicaId]) name(notaryNames[replicaId])
notary(NotaryConfig(validating = false, serviceLegalName = clusterName, bftSMaRt = BFTSMaRtConfiguration(replicaId, clusterAddresses))) notary(NotaryConfig(validating = false, serviceLegalName = clusterName, bftSMaRt = BFTSMaRtConfiguration(replicaId, clusterAddresses)))
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
configure() configure()
} }
notaryNode(0) { notaryNode(0) {

View File

@ -23,6 +23,7 @@ class CustomNotaryCordform : CordformDefinition() {
} }
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
@ -32,6 +33,7 @@ class CustomNotaryCordform : CordformDefinition() {
adminAddress("localhost:10106") adminAddress("localhost:10106")
} }
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
node { node {
name(DUMMY_NOTARY_NAME) name(DUMMY_NOTARY_NAME)
@ -42,6 +44,7 @@ class CustomNotaryCordform : CordformDefinition() {
} }
notary(NotaryConfig(validating = true, custom = true)) notary(NotaryConfig(validating = true, custom = true))
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
} }

View File

@ -35,6 +35,7 @@ class RaftNotaryCordform : CordformDefinition() {
} }
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
@ -44,11 +45,13 @@ class RaftNotaryCordform : CordformDefinition() {
adminAddress("localhost:10106") adminAddress("localhost:10106")
} }
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
fun notaryNode(index: Int, nodePort: Int, clusterPort: Int? = null, configure: CordformNode.() -> Unit) = node { fun notaryNode(index: Int, nodePort: Int, clusterPort: Int? = null, configure: CordformNode.() -> Unit) = node {
name(notaryNames[index]) name(notaryNames[index])
val clusterAddresses = if (clusterPort != null) listOf(NetworkHostAndPort("localhost", clusterPort)) else emptyList() val clusterAddresses = if (clusterPort != null) listOf(NetworkHostAndPort("localhost", clusterPort)) else emptyList()
notary(NotaryConfig(validating = true, serviceLegalName = clusterName, raft = RaftConfig(NetworkHostAndPort("localhost", nodePort), clusterAddresses))) notary(NotaryConfig(validating = true, serviceLegalName = clusterName, raft = RaftConfig(NetworkHostAndPort("localhost", nodePort), clusterAddresses)))
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
configure() configure()
devMode(true) devMode(true)
} }

View File

@ -29,6 +29,7 @@ class SingleNotaryCordform : CordformDefinition() {
} }
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
@ -38,6 +39,7 @@ class SingleNotaryCordform : CordformDefinition() {
adminAddress("localhost:10106") adminAddress("localhost:10106")
} }
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
node { node {
name(DUMMY_NOTARY_NAME) name(DUMMY_NOTARY_NAME)
@ -48,6 +50,7 @@ class SingleNotaryCordform : CordformDefinition() {
} }
notary(NotaryConfig(validating = true)) notary(NotaryConfig(validating = true))
devMode(true) devMode(true)
extraConfig = mapOf("h2Settings" to mapOf("address" to "localhost:0"))
} }
} }

View File

@ -80,7 +80,8 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
extraConfig = [ extraConfig = [
custom: [ custom: [
jvmArgs: ["-Xmx1g"] jvmArgs: ["-Xmx1g"]
] ],
'h2Settings.address' : 'localhost:10038'
] ]
} }
node { node {
@ -98,7 +99,8 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
extraConfig = [ extraConfig = [
custom: [ custom: [
jvmArgs: ["-Xmx1g"] jvmArgs: ["-Xmx1g"]
] ],
'h2Settings.address' : 'localhost:10039'
] ]
} }
node { node {
@ -116,7 +118,8 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
extraConfig = [ extraConfig = [
custom: [ custom: [
jvmArgs: ["-Xmx1g"] jvmArgs: ["-Xmx1g"]
] ],
'h2Settings.address' : 'localhost:10040'
] ]
} }
node { node {
@ -134,7 +137,8 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
extraConfig = [ extraConfig = [
custom: [ custom: [
jvmArgs: ["-Xmx1g"] jvmArgs: ["-Xmx1g"]
] ],
'h2Settings.address' : 'localhost:10041'
] ]
} }
} }

View File

@ -54,6 +54,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
address "localhost:10003" address "localhost:10003"
adminAddress "localhost:10004" adminAddress "localhost:10004"
} }
extraConfig = ['h2Settings.address' : 'localhost:10014']
cordapps = ["$project.group:finance:$corda_release_version"] cordapps = ["$project.group:finance:$corda_release_version"]
} }
node { node {
@ -65,6 +66,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
address "localhost:10006" address "localhost:10006"
adminAddress "localhost:10007" adminAddress "localhost:10007"
} }
extraConfig = ['h2Settings.address' : 'localhost:10015']
} }
node { node {
name "O=Bank B,L=New York,C=US" name "O=Bank B,L=New York,C=US"
@ -75,6 +77,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
address "localhost:10009" address "localhost:10009"
adminAddress "localhost:10010" adminAddress "localhost:10010"
} }
extraConfig = ['h2Settings.address' : 'localhost:10016']
} }
node { node {
name "O=BankOfCorda,L=New York,C=US" name "O=BankOfCorda,L=New York,C=US"
@ -85,6 +88,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
address "localhost:10012" address "localhost:10012"
adminAddress "localhost:10013" adminAddress "localhost:10013"
} }
extraConfig = ['h2Settings.address' : 'localhost:10017']
} }
} }