CORDA-961 Wire up and enforce max transaction size (#2465) (#2493)

* wire up and enforce max transaction size

* fixup after rebase
moved network parameter from AbstractNode to NodeProperties

* removed TODO

* fix broken import

* address PR issues

* remove API breaking change
address PR issue

* added max transaction size to driver and mock network.
address PR issues

* fix failing test

* added TODO

* fix verifier test

* fix spring driver build error

(cherry picked from commit c8cf46c)
This commit is contained in:
Patrick Kuo 2018-02-09 17:24:15 +00:00 committed by Katelyn Baker
parent af4aba2bfa
commit c18bc8758f
23 changed files with 245 additions and 31 deletions

View File

@ -272,6 +272,7 @@ public static final class net.corda.core.contracts.AmountTransfer$Companion exte
@net.corda.core.serialization.CordaSerializable public interface net.corda.core.contracts.Attachment extends net.corda.core.contracts.NamedByHash @net.corda.core.serialization.CordaSerializable public interface net.corda.core.contracts.Attachment extends net.corda.core.contracts.NamedByHash
public abstract void extractFile(String, java.io.OutputStream) public abstract void extractFile(String, java.io.OutputStream)
@org.jetbrains.annotations.NotNull public abstract List getSigners() @org.jetbrains.annotations.NotNull public abstract List getSigners()
public abstract int getSize()
@org.jetbrains.annotations.NotNull public abstract java.io.InputStream open() @org.jetbrains.annotations.NotNull public abstract java.io.InputStream open()
@org.jetbrains.annotations.NotNull public abstract jar.JarInputStream openAsJAR() @org.jetbrains.annotations.NotNull public abstract jar.JarInputStream openAsJAR()
## ##
@ -339,6 +340,7 @@ public final class net.corda.core.contracts.ComponentGroupEnum extends java.lang
@org.jetbrains.annotations.NotNull public final String getContract() @org.jetbrains.annotations.NotNull public final String getContract()
@org.jetbrains.annotations.NotNull public net.corda.core.crypto.SecureHash getId() @org.jetbrains.annotations.NotNull public net.corda.core.crypto.SecureHash getId()
@org.jetbrains.annotations.NotNull public List getSigners() @org.jetbrains.annotations.NotNull public List getSigners()
public int getSize()
@org.jetbrains.annotations.NotNull public java.io.InputStream open() @org.jetbrains.annotations.NotNull public java.io.InputStream open()
@org.jetbrains.annotations.NotNull public jar.JarInputStream openAsJAR() @org.jetbrains.annotations.NotNull public jar.JarInputStream openAsJAR()
## ##

View File

@ -50,4 +50,9 @@ interface Attachment : NamedByHash {
* Can be empty, for example non-contract attachments won't be necessarily be signed. * Can be empty, for example non-contract attachments won't be necessarily be signed.
*/ */
val signers: List<Party> val signers: List<Party>
/**
* Attachment size in bytes.
*/
val size: Int
} }

View File

@ -27,6 +27,10 @@ abstract class AbstractAttachment(dataLoader: () -> ByteArray) : Attachment {
} }
protected val attachmentData: ByteArray by lazy(dataLoader) protected val attachmentData: ByteArray by lazy(dataLoader)
// TODO: read file size information from metadata instead of loading the data.
override val size: Int get() = attachmentData.size
override fun open(): InputStream = attachmentData.inputStream() override fun open(): InputStream = attachmentData.inputStream()
override val signers by lazy { override val signers by lazy {
// Can't start with empty set if we're doing intersections. Logically the null means "all possible signers": // Can't start with empty set if we're doing intersections. Logically the null means "all possible signers":

View File

@ -0,0 +1,14 @@
package net.corda.core.internal
import net.corda.core.node.NetworkParameters
// TODO: This will cause problems when we run tests in parallel, make each node have its own properties.
object GlobalProperties {
private var _networkParameters: NetworkParameters? = null
var networkParameters: NetworkParameters
get() = checkNotNull(_networkParameters) { "Property 'networkParameters' has not been initialised." }
set(value) {
_networkParameters = value
}
}

View File

@ -17,7 +17,6 @@ import java.time.Instant
*/ */
// TODO Add eventHorizon - how many days a node can be offline before being automatically ejected from the network. // TODO Add eventHorizon - how many days a node can be offline before being automatically ejected from the network.
// It needs separate design. // It needs separate design.
// TODO Currently maxTransactionSize is not wired.
@CordaSerializable @CordaSerializable
data class NetworkParameters( data class NetworkParameters(
val minimumPlatformVersion: Int, val minimumPlatformVersion: Int,

View File

@ -5,6 +5,7 @@ import net.corda.core.contracts.ComponentGroupEnum.*
import net.corda.core.crypto.* import net.corda.core.crypto.*
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.Emoji import net.corda.core.internal.Emoji
import net.corda.core.internal.GlobalProperties
import net.corda.core.node.ServicesForResolution import net.corda.core.node.ServicesForResolution
import net.corda.core.node.services.AttachmentId import net.corda.core.node.services.AttachmentId
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
@ -118,7 +119,24 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
val contractAttachments = findAttachmentContracts(resolvedInputs, resolveContractAttachment, resolveAttachment) val contractAttachments = findAttachmentContracts(resolvedInputs, resolveContractAttachment, resolveAttachment)
// Order of attachments is important since contracts may refer to indexes so only append automatic attachments // Order of attachments is important since contracts may refer to indexes so only append automatic attachments
val attachments = (attachments.map { resolveAttachment(it) ?: throw AttachmentResolutionException(it) } + contractAttachments).distinct() val attachments = (attachments.map { resolveAttachment(it) ?: throw AttachmentResolutionException(it) } + contractAttachments).distinct()
return LedgerTransaction(resolvedInputs, outputs, authenticatedArgs, attachments, id, notary, timeWindow, privacySalt) val ltx = LedgerTransaction(resolvedInputs, outputs, authenticatedArgs, attachments, id, notary, timeWindow, privacySalt)
checkTransactionSize(ltx)
return ltx
}
private fun checkTransactionSize(ltx: LedgerTransaction) {
var remainingTransactionSize = GlobalProperties.networkParameters.maxTransactionSize
fun minus(size: Int) {
require(remainingTransactionSize > size) { "Transaction exceeded network's maximum transaction size limit : ${GlobalProperties.networkParameters.maxTransactionSize} bytes." }
remainingTransactionSize -= size
}
// Check attachment size first as they are most likely to go over the limit.
ltx.attachments.forEach { minus(it.size) }
minus(ltx.inputs.serialize().size)
minus(ltx.commands.serialize().size)
minus(ltx.outputs.serialize().size)
} }
/** /**

View File

@ -31,6 +31,7 @@ class AttachmentTest {
override val id get() = throw UnsupportedOperationException() override val id get() = throw UnsupportedOperationException()
override fun open() = inputStream override fun open() = inputStream
override val signers get() = throw UnsupportedOperationException() override val signers get() = throw UnsupportedOperationException()
override val size: Int = 512
} }
try { try {
attachment.openAsJAR() attachment.openAsJAR()

View File

@ -114,6 +114,7 @@ class AttachmentSerializationTest {
private class CustomAttachment(override val id: SecureHash, internal val customContent: String) : Attachment { private class CustomAttachment(override val id: SecureHash, internal val customContent: String) : Attachment {
override fun open() = throw UnsupportedOperationException("Not implemented.") override fun open() = throw UnsupportedOperationException("Not implemented.")
override val signers get() = throw UnsupportedOperationException() override val signers get() = throw UnsupportedOperationException()
override val size get() = throw UnsupportedOperationException()
} }
private class CustomAttachmentLogic(serverIdentity: Party, private val attachmentId: SecureHash, private val customContent: String) : ClientLogic(serverIdentity) { private class CustomAttachmentLogic(serverIdentity: Party, private val attachmentId: SecureHash, private val customContent: String) : ClientLogic(serverIdentity) {

View File

@ -75,6 +75,9 @@ UNRELEASED
* Moved ``NodeInfoSchema`` to internal package as the node info's database schema is not part of the public API. This * Moved ``NodeInfoSchema`` to internal package as the node info's database schema is not part of the public API. This
was needed to allow changes to the schema. was needed to allow changes to the schema.
* Introduced max transaction size limit on transactions. The max transaction size parameter is set by the compatibility zone
operator. The parameter is distributed to Corda nodes by network map service as part of the ``NetworkParameters``.
* Support for external user credentials data source and password encryption [CORDA-827]. * Support for external user credentials data source and password encryption [CORDA-827].
* Exporting additional JMX metrics (artemis, hibernate statistics) and loading Jolokia agent at JVM startup when using * Exporting additional JMX metrics (artemis, hibernate statistics) and loading Jolokia agent at JVM startup when using

View File

@ -71,6 +71,7 @@ The current set of network parameters:
:maxMessageSize: Maximum allowed size in bytes of an individual message sent over the wire. Note that attachments are :maxMessageSize: Maximum allowed size in bytes of an individual message sent over the wire. Note that attachments are
a special case and may be fragmented for streaming transfer, however, an individual transaction or flow message a special case and may be fragmented for streaming transfer, however, an individual transaction or flow message
may not be larger than this value. may not be larger than this value.
:maxTransactionSize: Maximum allowed size in bytes of a transaction. This is the size of the transaction object and its attachments.
:modifiedTime: The time when the network parameters were last modified by the compatibility zone operator. :modifiedTime: The time when the network parameters were last modified by the compatibility zone operator.
:epoch: Version number of the network parameters. Starting from 1, this will always increment whenever any of the :epoch: Version number of the network parameters. Starting from 1, this will always increment whenever any of the
parameters change. parameters change.

View File

@ -13,13 +13,19 @@ import net.corda.core.flows.*
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.* import net.corda.core.internal.FlowStateMachine
import net.corda.core.internal.GlobalProperties
import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.concurrent.map import net.corda.core.internal.concurrent.map
import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.uncheckedCast
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.node.* import net.corda.core.node.*
import net.corda.core.node.services.* import net.corda.core.node.services.*
import net.corda.core.serialization.* import net.corda.core.serialization.SerializationWhitelist
import net.corda.core.serialization.SerializeAsToken
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.serialization.serialize
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.debug import net.corda.core.utilities.debug
@ -121,7 +127,6 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
// low-performance prototyping period. // low-performance prototyping period.
protected abstract val serverThread: AffinityExecutor protected abstract val serverThread: AffinityExecutor
protected lateinit var networkParameters: NetworkParameters
private val cordappServices = MutableClassToInstanceMap.create<SerializeAsToken>() private val cordappServices = MutableClassToInstanceMap.create<SerializeAsToken>()
private val flowFactories = ConcurrentHashMap<Class<out FlowLogic<*>>, InitiatedFlowFactory<*>>() private val flowFactories = ConcurrentHashMap<Class<out FlowLogic<*>>, InitiatedFlowFactory<*>>()
@ -169,7 +174,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
initCertificate() initCertificate()
val schemaService = NodeSchemaService(cordappLoader.cordappSchemas) val schemaService = NodeSchemaService(cordappLoader.cordappSchemas)
val (identity, identityKeyPair) = obtainIdentity(notaryConfig = null) val (identity, identityKeyPair) = obtainIdentity(notaryConfig = null)
return initialiseDatabasePersistence(schemaService, makeIdentityService(identity.certificate)) { database -> return initialiseDatabasePersistence(schemaService, makeIdentityService(identity.certificate)) { database ->
// TODO The fact that we need to specify an empty list of notaries just to generate our node info looks like // TODO The fact that we need to specify an empty list of notaries just to generate our node info looks like
// a code smell. // a code smell.
val persistentNetworkMapCache = PersistentNetworkMapCache(database, notaries = emptyList()) val persistentNetworkMapCache = PersistentNetworkMapCache(database, notaries = emptyList())
@ -192,13 +197,13 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
val (identity, identityKeyPair) = obtainIdentity(notaryConfig = null) val (identity, identityKeyPair) = obtainIdentity(notaryConfig = null)
val identityService = makeIdentityService(identity.certificate) val identityService = makeIdentityService(identity.certificate)
networkMapClient = configuration.compatibilityZoneURL?.let { NetworkMapClient(it, identityService.trustRoot) } networkMapClient = configuration.compatibilityZoneURL?.let { NetworkMapClient(it, identityService.trustRoot) }
networkParameters = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory).networkParameters GlobalProperties.networkParameters = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory).networkParameters
check(networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) { check(GlobalProperties.networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) {
"Node's platform version is lower than network's required minimumPlatformVersion" "Node's platform version is lower than network's required minimumPlatformVersion"
} }
// Do all of this in a database transaction so anything that might need a connection has one. // Do all of this in a database transaction so anything that might need a connection has one.
val (startedImpl, schedulerService) = initialiseDatabasePersistence(schemaService, identityService) { database -> val (startedImpl, schedulerService) = initialiseDatabasePersistence(schemaService, identityService) { database ->
val networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, networkParameters.notaries).start(), identityService) val networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, GlobalProperties.networkParameters.notaries).start(), identityService)
val (keyPairs, info) = initNodeInfo(networkMapCache, identity, identityKeyPair) val (keyPairs, info) = initNodeInfo(networkMapCache, identity, identityKeyPair)
identityService.loadIdentities(info.legalIdentitiesAndCerts) identityService.loadIdentities(info.legalIdentitiesAndCerts)
val transactionStorage = makeTransactionStorage(database, configuration.transactionCacheSizeBytes) val transactionStorage = makeTransactionStorage(database, configuration.transactionCacheSizeBytes)
@ -237,7 +242,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
networkMapUpdater = NetworkMapUpdater(services.networkMapCache, networkMapUpdater = NetworkMapUpdater(services.networkMapCache,
NodeInfoWatcher(configuration.baseDirectory, getRxIoScheduler(), Duration.ofMillis(configuration.additionalNodeInfoPollingFrequencyMsec)), NodeInfoWatcher(configuration.baseDirectory, getRxIoScheduler(), Duration.ofMillis(configuration.additionalNodeInfoPollingFrequencyMsec)),
networkMapClient, networkMapClient,
networkParameters.serialize().hash, GlobalProperties.networkParameters.serialize().hash,
configuration.baseDirectory) configuration.baseDirectory)
runOnStop += networkMapUpdater::close runOnStop += networkMapUpdater::close
@ -521,7 +526,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
* Builds node internal, advertised, and plugin services. * Builds node internal, advertised, and plugin services.
* Returns a list of tokenizable services to be added to the serialisation context. * Returns a list of tokenizable services to be added to the serialisation context.
*/ */
private fun makeServices(keyPairs: Set<KeyPair>, schemaService: SchemaService, transactionStorage: WritableTransactionStorage, database: CordaPersistence, info: NodeInfo, identityService: IdentityServiceInternal, networkMapCache: NetworkMapCacheInternal): MutableList<Any> { private fun makeServices(keyPairs: Set<KeyPair>, schemaService: SchemaService, transactionStorage: WritableTransactionStorage, database: CordaPersistence, info: NodeInfo, identityService: IdentityServiceInternal, networkMapCache: NetworkMapCacheInternal): MutableList<Any> {
checkpointStorage = DBCheckpointStorage() checkpointStorage = DBCheckpointStorage()
val metrics = MetricRegistry() val metrics = MetricRegistry()
attachments = NodeAttachmentService(metrics, configuration.attachmentContentCacheSizeBytes, configuration.attachmentCacheBound) attachments = NodeAttachmentService(metrics, configuration.attachmentContentCacheSizeBytes, configuration.attachmentCacheBound)

View File

@ -2,6 +2,7 @@ package net.corda.node.internal
import com.codahale.metrics.JmxReporter import com.codahale.metrics.JmxReporter
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.internal.GlobalProperties.networkParameters
import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.concurrent.thenMatch import net.corda.core.internal.concurrent.thenMatch
import net.corda.core.internal.div import net.corda.core.internal.div

View File

@ -0,0 +1,135 @@
package net.corda.node.services.transactions
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.crypto.SecureHash
import net.corda.core.flows.*
import net.corda.core.identity.Party
import net.corda.core.internal.InputStreamAndHash
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow
import net.corda.node.services.api.StartedNodeServices
import net.corda.testing.contracts.DummyContract
import net.corda.testing.contracts.DummyState
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.dummyCommand
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.startFlow
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class MaxTransactionSizeTests {
private lateinit var mockNet: MockNetwork
private lateinit var notaryServices: StartedNodeServices
private lateinit var aliceServices: StartedNodeServices
private lateinit var notary: Party
private lateinit var alice: Party
private lateinit var bob: Party
@Before
fun setup() {
mockNet = MockNetwork(listOf("net.corda.testing.contracts", "net.corda.node.services.transactions"), maxTransactionSize = 3_000_000)
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
notaryServices = mockNet.defaultNotaryNode.services
aliceServices = aliceNode.services
notary = mockNet.defaultNotaryIdentity
alice = aliceNode.info.singleIdentity()
bob = bobNode.info.singleIdentity()
}
@After
fun cleanUp() {
mockNet.stopNodes()
}
@Test
fun `check transaction will fail when exceed max transaction size limit`() {
// These 4 attachments yield a transaction that's got ~ 4mb, which will exceed the 3mb max transaction size limit
val bigFile1 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 0)
val bigFile2 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 1)
val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 2)
val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 3)
val flow = aliceServices.database.transaction {
val hash1 = aliceServices.attachments.importAttachment(bigFile1.inputStream)
val hash2 = aliceServices.attachments.importAttachment(bigFile2.inputStream)
val hash3 = aliceServices.attachments.importAttachment(bigFile3.inputStream)
val hash4 = aliceServices.attachments.importAttachment(bigFile4.inputStream)
assertEquals(hash1, bigFile1.sha256)
SendLargeTransactionFlow(notary, bob, hash1, hash2, hash3, hash4)
}
val exception = assertFailsWith<IllegalArgumentException> {
val future = aliceServices.startFlow(flow)
mockNet.runNetwork()
future.getOrThrow()
}
assertThat(exception).hasMessageContaining("Transaction exceeded network's maximum transaction size limit")
}
@Test
fun `check transaction will be rejected by counterparty when exceed max transaction size limit`() {
// These 4 attachments yield a transaction that's got ~ 4mb, which will exceed the 3mb max transaction size limit
val bigFile1 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 0)
val bigFile2 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 1)
val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 2)
val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024, 3)
val flow = aliceServices.database.transaction {
val hash1 = aliceServices.attachments.importAttachment(bigFile1.inputStream)
val hash2 = aliceServices.attachments.importAttachment(bigFile2.inputStream)
val hash3 = aliceServices.attachments.importAttachment(bigFile3.inputStream)
val hash4 = aliceServices.attachments.importAttachment(bigFile4.inputStream)
assertEquals(hash1, bigFile1.sha256)
SendLargeTransactionFlow(notary, bob, hash1, hash2, hash3, hash4, verify = false)
}
val ex = assertFailsWith<UnexpectedFlowEndException> {
val future = aliceServices.startFlow(flow)
mockNet.runNetwork()
future.getOrThrow()
}
assertThat(ex).hasMessageContaining("Counterparty flow on O=Bob Plc, L=Rome, C=IT had an internal error and has terminated")
}
@StartableByRPC
@InitiatingFlow
class SendLargeTransactionFlow(private val notary: Party,
private val otherSide: Party,
private val hash1: SecureHash,
private val hash2: SecureHash,
private val hash3: SecureHash,
private val hash4: SecureHash,
private val verify: Boolean = true) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
val tx = TransactionBuilder(notary = notary)
.addOutputState(DummyState(), DummyContract.PROGRAM_ID)
.addCommand(dummyCommand(ourIdentity.owningKey))
.addAttachment(hash1)
.addAttachment(hash2)
.addAttachment(hash3)
.addAttachment(hash4)
val stx = serviceHub.signInitialTransaction(tx, ourIdentity.owningKey)
if (verify) stx.verify(serviceHub, checkSufficientSignatures = false)
// Send to the other side and wait for it to trigger resolution from us.
val otherSideSession = initiateFlow(otherSide)
subFlow(SendTransactionFlow(otherSideSession, stx))
otherSideSession.receive<Unit>()
}
}
@InitiatedBy(SendLargeTransactionFlow::class)
@Suppress("UNUSED")
class ReceiveLargeTransactionFlow(private val otherSide: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
subFlow(ReceiveTransactionFlow(otherSide))
// Unblock the other side by sending some dummy object (Unit is fine here as it's a singleton).
otherSide.send(Unit)
}
}
}

View File

@ -29,6 +29,7 @@ fun <A> springDriver(
startNodesInProcess: Boolean = defaultParameters.startNodesInProcess, startNodesInProcess: Boolean = defaultParameters.startNodesInProcess,
notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs, notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs,
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan, extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
maxTransactionSize: Int = defaultParameters.maxTransactionSize,
dsl: SpringBootDriverDSL.() -> A dsl: SpringBootDriverDSL.() -> A
): A { ): A {
return genericDriver( return genericDriver(
@ -44,6 +45,7 @@ fun <A> springDriver(
extraCordappPackagesToScan = extraCordappPackagesToScan, extraCordappPackagesToScan = extraCordappPackagesToScan,
notarySpecs = notarySpecs, notarySpecs = notarySpecs,
driverDslWrapper = { driverDSL: DriverDSLImpl -> SpringBootDriverDSL(driverDSL) }, driverDslWrapper = { driverDSL: DriverDSLImpl -> SpringBootDriverDSL(driverDSL) },
maxTransactionSize = maxTransactionSize,
coerce = { it }, dsl = dsl coerce = { it }, dsl = dsl
) )
} }

View File

@ -147,7 +147,7 @@ data class NodeParameters(
data class JmxPolicy(val startJmxHttpServer: Boolean = false, data class JmxPolicy(val startJmxHttpServer: Boolean = false,
val jmxHttpServerPortAllocation: PortAllocation? = val jmxHttpServerPortAllocation: PortAllocation? =
if (startJmxHttpServer) PortAllocation.Incremental(7005) else null) if (startJmxHttpServer) PortAllocation.Incremental(7005) else null)
/** /**
* [driver] allows one to start up nodes like this: * [driver] allows one to start up nodes like this:
@ -198,6 +198,7 @@ fun <A> driver(
notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs, notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs,
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan, extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
jmxPolicy: JmxPolicy = defaultParameters.jmxPolicy, jmxPolicy: JmxPolicy = defaultParameters.jmxPolicy,
maxTransactionSize: Int = defaultParameters.maxTransactionSize,
dsl: DriverDSL.() -> A dsl: DriverDSL.() -> A
): A { ): A {
return genericDriver( return genericDriver(
@ -213,7 +214,8 @@ fun <A> driver(
notarySpecs = notarySpecs, notarySpecs = notarySpecs,
extraCordappPackagesToScan = extraCordappPackagesToScan, extraCordappPackagesToScan = extraCordappPackagesToScan,
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
compatibilityZone = null compatibilityZone = null,
maxTransactionSize = maxTransactionSize
), ),
coerce = { it }, coerce = { it },
dsl = dsl, dsl = dsl,
@ -249,7 +251,8 @@ data class DriverParameters(
val waitForAllNodesToFinish: Boolean = false, val waitForAllNodesToFinish: Boolean = false,
val notarySpecs: List<NotarySpec> = listOf(NotarySpec(DUMMY_NOTARY_NAME)), val notarySpecs: List<NotarySpec> = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
val extraCordappPackagesToScan: List<String> = emptyList(), val extraCordappPackagesToScan: List<String> = emptyList(),
val jmxPolicy: JmxPolicy = JmxPolicy() val jmxPolicy: JmxPolicy = JmxPolicy(),
val maxTransactionSize: Int = Int.MAX_VALUE
) { ) {
fun setIsDebug(isDebug: Boolean) = copy(isDebug = isDebug) fun setIsDebug(isDebug: Boolean) = copy(isDebug = isDebug)
fun setDriverDirectory(driverDirectory: Path) = copy(driverDirectory = driverDirectory) fun setDriverDirectory(driverDirectory: Path) = copy(driverDirectory = driverDirectory)

View File

@ -19,6 +19,7 @@ import net.corda.core.messaging.MessageRecipients
import net.corda.core.messaging.RPCOps import net.corda.core.messaging.RPCOps
import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.NotaryInfo
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.KeyManagementService import net.corda.core.node.services.KeyManagementService
import net.corda.core.serialization.SerializationWhitelist import net.corda.core.serialization.SerializationWhitelist
@ -42,16 +43,15 @@ import net.corda.node.utilities.AffinityExecutor.ServiceAffinityExecutor
import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.DevIdentityGenerator
import net.corda.nodeapi.internal.config.User import net.corda.nodeapi.internal.config.User
import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.nodeapi.internal.network.NetworkParametersCopier
import net.corda.core.node.NotaryInfo
import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.setGlobalSerialization
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.testThreadFactory import net.corda.testing.internal.testThreadFactory
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.core.setGlobalSerialization
import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.activemq.artemis.utils.ReusableLatch
import org.apache.sshd.common.util.security.SecurityUtils import org.apache.sshd.common.util.security.SecurityUtils
import rx.internal.schedulers.CachedThreadScheduler import rx.internal.schedulers.CachedThreadScheduler
@ -133,7 +133,8 @@ open class MockNetwork(private val cordappPackages: List<String>,
servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy, servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy,
private val defaultFactory: (MockNodeArgs) -> MockNode = defaultParameters.defaultFactory, private val defaultFactory: (MockNodeArgs) -> MockNode = defaultParameters.defaultFactory,
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization, initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
private val notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs) { private val notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs,
maxTransactionSize: Int = Int.MAX_VALUE) {
/** Helper constructor for creating a [MockNetwork] with custom parameters from Java. */ /** Helper constructor for creating a [MockNetwork] with custom parameters from Java. */
@JvmOverloads @JvmOverloads
constructor(cordappPackages: List<String>, parameters: MockNetworkParameters = MockNetworkParameters()) : this(cordappPackages, defaultParameters = parameters) constructor(cordappPackages: List<String>, parameters: MockNetworkParameters = MockNetworkParameters()) : this(cordappPackages, defaultParameters = parameters)
@ -228,7 +229,7 @@ open class MockNetwork(private val cordappPackages: List<String>,
filesystem.getPath("/nodes").createDirectory() filesystem.getPath("/nodes").createDirectory()
val notaryInfos = generateNotaryIdentities() val notaryInfos = generateNotaryIdentities()
// The network parameters must be serialised before starting any of the nodes // The network parameters must be serialised before starting any of the nodes
networkParameters = NetworkParametersCopier(testNetworkParameters(notaryInfos)) networkParameters = NetworkParametersCopier(testNetworkParameters(notaryInfos, maxTransactionSize = maxTransactionSize))
@Suppress("LeakingThis") @Suppress("LeakingThis")
notaryNodes = createNotaries() notaryNodes = createNotaries()
} catch (t: Throwable) { } catch (t: Throwable) {

View File

@ -6,6 +6,7 @@ import net.corda.core.crypto.*
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.GlobalProperties
import net.corda.core.messaging.DataFeed import net.corda.core.messaging.DataFeed
import net.corda.core.messaging.FlowHandle import net.corda.core.messaging.FlowHandle
import net.corda.core.messaging.FlowProgressHandle import net.corda.core.messaging.FlowProgressHandle
@ -31,6 +32,7 @@ import net.corda.node.services.vault.NodeVaultService
import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.core.DEV_ROOT_CA import net.corda.testing.core.DEV_ROOT_CA
import net.corda.testing.core.TestIdentity import net.corda.testing.core.TestIdentity
import net.corda.testing.services.MockAttachmentStorage import net.corda.testing.services.MockAttachmentStorage

View File

@ -10,12 +10,14 @@ import net.corda.core.context.Origin
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.GlobalProperties
import net.corda.core.internal.FlowStateMachine import net.corda.core.internal.FlowStateMachine
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.serialization.internal.effectiveSerializationEnv import net.corda.core.serialization.internal.effectiveSerializationEnv
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.api.StartedNodeServices
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity import net.corda.testing.core.TestIdentity
import net.corda.testing.core.chooseIdentity import net.corda.testing.core.chooseIdentity
@ -36,6 +38,7 @@ fun ServiceHub.ledger(
false false
} }
return LedgerDSL(TestLedgerDSLInterpreter(this), notary).apply { return LedgerDSL(TestLedgerDSLInterpreter(this), notary).apply {
GlobalProperties.networkParameters = testNetworkParameters(emptyList())
if (serializationExists) { if (serializationExists) {
script() script()
} else { } else {

View File

@ -14,6 +14,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.* import net.corda.core.internal.*
import net.corda.core.internal.concurrent.* import net.corda.core.internal.concurrent.*
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.NotaryInfo
import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.NetworkMapCache
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.toFuture import net.corda.core.toFuture
@ -37,7 +38,6 @@ import net.corda.nodeapi.internal.crypto.X509KeyStore
import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.nodeapi.internal.network.NetworkParametersCopier
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier import net.corda.nodeapi.internal.network.NodeInfoFilesCopier
import net.corda.core.node.NotaryInfo
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME import net.corda.testing.core.BOB_NAME
@ -87,7 +87,8 @@ class DriverDSLImpl(
extraCordappPackagesToScan: List<String>, extraCordappPackagesToScan: List<String>,
val jmxPolicy: JmxPolicy, val jmxPolicy: JmxPolicy,
val notarySpecs: List<NotarySpec>, val notarySpecs: List<NotarySpec>,
val compatibilityZone: CompatibilityZoneParams? val compatibilityZone: CompatibilityZoneParams?,
val maxTransactionSize: Int
) : InternalDriverDSL { ) : InternalDriverDSL {
private var _executorService: ScheduledExecutorService? = null private var _executorService: ScheduledExecutorService? = null
val executorService get() = _executorService!! val executorService get() = _executorService!!
@ -699,7 +700,7 @@ class DriverDSLImpl(
* The local version of the network map, which is a bunch of classes that copy the relevant files to the node directories. * The local version of the network map, which is a bunch of classes that copy the relevant files to the node directories.
*/ */
private inner class LocalNetworkMap(notaryInfos: List<NotaryInfo>) { private inner class LocalNetworkMap(notaryInfos: List<NotaryInfo>) {
val networkParametersCopier = NetworkParametersCopier(testNetworkParameters(notaryInfos)) val networkParametersCopier = NetworkParametersCopier(testNetworkParameters(notaryInfos, maxTransactionSize = maxTransactionSize))
// TODO: this object will copy NodeInfo files from started nodes to other nodes additional-node-infos/ // TODO: this object will copy NodeInfo files from started nodes to other nodes additional-node-infos/
// This uses the FileSystem and adds a delay (~5 seconds) given by the time we wait before polling the file system. // This uses the FileSystem and adds a delay (~5 seconds) given by the time we wait before polling the file system.
// Investigate whether we can avoid that. // Investigate whether we can avoid that.
@ -955,6 +956,7 @@ fun <DI : DriverDSL, D : InternalDriverDSL, A> genericDriver(
notarySpecs: List<NotarySpec>, notarySpecs: List<NotarySpec>,
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan, extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
jmxPolicy: JmxPolicy = JmxPolicy(), jmxPolicy: JmxPolicy = JmxPolicy(),
maxTransactionSize: Int,
driverDslWrapper: (DriverDSLImpl) -> D, driverDslWrapper: (DriverDSLImpl) -> D,
coerce: (D) -> DI, dsl: DI.() -> A coerce: (D) -> DI, dsl: DI.() -> A
): A { ): A {
@ -972,7 +974,8 @@ fun <DI : DriverDSL, D : InternalDriverDSL, A> genericDriver(
extraCordappPackagesToScan = extraCordappPackagesToScan, extraCordappPackagesToScan = extraCordappPackagesToScan,
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
notarySpecs = notarySpecs, notarySpecs = notarySpecs,
compatibilityZone = null compatibilityZone = null,
maxTransactionSize = maxTransactionSize
) )
) )
val shutdownHook = addShutdownHook(driverDsl::shutdown) val shutdownHook = addShutdownHook(driverDsl::shutdown)
@ -1014,6 +1017,7 @@ fun <A> internalDriver(
notarySpecs: List<NotarySpec> = DriverParameters().notarySpecs, notarySpecs: List<NotarySpec> = DriverParameters().notarySpecs,
extraCordappPackagesToScan: List<String> = DriverParameters().extraCordappPackagesToScan, extraCordappPackagesToScan: List<String> = DriverParameters().extraCordappPackagesToScan,
jmxPolicy: JmxPolicy = DriverParameters().jmxPolicy, jmxPolicy: JmxPolicy = DriverParameters().jmxPolicy,
maxTransactionSize: Int = DriverParameters().maxTransactionSize,
compatibilityZone: CompatibilityZoneParams? = null, compatibilityZone: CompatibilityZoneParams? = null,
dsl: DriverDSLImpl.() -> A dsl: DriverDSLImpl.() -> A
): A { ): A {
@ -1030,7 +1034,8 @@ fun <A> internalDriver(
notarySpecs = notarySpecs, notarySpecs = notarySpecs,
extraCordappPackagesToScan = extraCordappPackagesToScan, extraCordappPackagesToScan = extraCordappPackagesToScan,
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
compatibilityZone = compatibilityZone compatibilityZone = compatibilityZone,
maxTransactionSize = maxTransactionSize
), ),
coerce = { it }, coerce = { it },
dsl = dsl, dsl = dsl,

View File

@ -106,8 +106,9 @@ fun <A> rpcDriver(
notarySpecs: List<NotarySpec> = emptyList(), notarySpecs: List<NotarySpec> = emptyList(),
externalTrace: Trace? = null, externalTrace: Trace? = null,
jmxPolicy: JmxPolicy = JmxPolicy(), jmxPolicy: JmxPolicy = JmxPolicy(),
maxTransactionSize: Int = Int.MAX_VALUE,
dsl: RPCDriverDSL.() -> A dsl: RPCDriverDSL.() -> A
) : A { ): A {
return genericDriver( return genericDriver(
driverDsl = RPCDriverDSL( driverDsl = RPCDriverDSL(
DriverDSLImpl( DriverDSLImpl(
@ -122,7 +123,8 @@ fun <A> rpcDriver(
extraCordappPackagesToScan = extraCordappPackagesToScan, extraCordappPackagesToScan = extraCordappPackagesToScan,
notarySpecs = notarySpecs, notarySpecs = notarySpecs,
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
compatibilityZone = null compatibilityZone = null,
maxTransactionSize = maxTransactionSize
), externalTrace ), externalTrace
), ),
coerce = { it }, coerce = { it },
@ -434,7 +436,7 @@ data class RPCDriverDSL(
minLargeMessageSize = MAX_MESSAGE_SIZE minLargeMessageSize = MAX_MESSAGE_SIZE
isUseGlobalPools = false isUseGlobalPools = false
} }
val rpcSecurityManager = RPCSecurityManagerImpl.fromUserList(users = listOf(InternalUser(rpcUser.username, rpcUser.password, rpcUser.permissions)) , id = AuthServiceId("TEST_SECURITY_MANAGER")) val rpcSecurityManager = RPCSecurityManagerImpl.fromUserList(users = listOf(InternalUser(rpcUser.username, rpcUser.password, rpcUser.permissions)), id = AuthServiceId("TEST_SECURITY_MANAGER"))
val rpcServer = RPCServer( val rpcServer = RPCServer(
ops, ops,
rpcUser.username, rpcUser.username,

View File

@ -9,7 +9,8 @@ fun testNetworkParameters(
minimumPlatformVersion: Int = 1, minimumPlatformVersion: Int = 1,
modifiedTime: Instant = Instant.now(), modifiedTime: Instant = Instant.now(),
maxMessageSize: Int = 10485760, maxMessageSize: Int = 10485760,
maxTransactionSize: Int = 40000, // TODO: Make this configurable and consistence across driver, bootstrapper, demobench and NetworkMapServer
maxTransactionSize: Int = Int.MAX_VALUE,
epoch: Int = 1 epoch: Int = 1
): NetworkParameters { ): NetworkParameters {
return NetworkParameters( return NetworkParameters(

View File

@ -143,7 +143,7 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() {
notaries = listOf(NotaryInfo(identity, config.nodeConfig.notary!!.validating)), notaries = listOf(NotaryInfo(identity, config.nodeConfig.notary!!.validating)),
modifiedTime = Instant.now(), modifiedTime = Instant.now(),
maxMessageSize = 10485760, maxMessageSize = 10485760,
maxTransactionSize = 40000, maxTransactionSize = Int.MAX_VALUE,
epoch = 1 epoch = 1
)) ))
notaryIdentity = identity notaryIdentity = identity

View File

@ -5,6 +5,7 @@ import com.typesafe.config.ConfigFactory
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.random63BitValue import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.GlobalProperties
import net.corda.core.internal.concurrent.OpenFuture import net.corda.core.internal.concurrent.OpenFuture
import net.corda.core.internal.concurrent.doneFuture import net.corda.core.internal.concurrent.doneFuture
import net.corda.core.internal.concurrent.fork import net.corda.core.internal.concurrent.fork
@ -22,6 +23,7 @@ import net.corda.nodeapi.VerifierApi
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.NODE_USER import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.NODE_USER
import net.corda.nodeapi.internal.config.NodeSSLConfiguration import net.corda.nodeapi.internal.config.NodeSSLConfiguration
import net.corda.nodeapi.internal.config.SSLConfiguration import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.driver.JmxPolicy import net.corda.testing.driver.JmxPolicy
import net.corda.testing.driver.NodeHandle import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.PortAllocation import net.corda.testing.driver.PortAllocation
@ -61,6 +63,7 @@ fun <A> verifierDriver(
extraCordappPackagesToScan: List<String> = emptyList(), extraCordappPackagesToScan: List<String> = emptyList(),
notarySpecs: List<NotarySpec> = emptyList(), notarySpecs: List<NotarySpec> = emptyList(),
jmxPolicy: JmxPolicy = JmxPolicy(), jmxPolicy: JmxPolicy = JmxPolicy(),
maxTransactionSize: Int = Int.MAX_VALUE,
dsl: VerifierDriverDSL.() -> A dsl: VerifierDriverDSL.() -> A
) = genericDriver( ) = genericDriver(
driverDsl = VerifierDriverDSL( driverDsl = VerifierDriverDSL(
@ -76,7 +79,8 @@ fun <A> verifierDriver(
extraCordappPackagesToScan = extraCordappPackagesToScan, extraCordappPackagesToScan = extraCordappPackagesToScan,
notarySpecs = notarySpecs, notarySpecs = notarySpecs,
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
compatibilityZone = null compatibilityZone = null,
maxTransactionSize = maxTransactionSize
) )
), ),
coerce = { it }, coerce = { it },
@ -162,6 +166,7 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri
/** Starts a lightweight verification requestor that implements the Node's Verifier API */ /** Starts a lightweight verification requestor that implements the Node's Verifier API */
fun startVerificationRequestor(name: CordaX500Name): CordaFuture<VerificationRequestorHandle> { fun startVerificationRequestor(name: CordaX500Name): CordaFuture<VerificationRequestorHandle> {
val hostAndPort = driverDSL.portAllocation.nextHostAndPort() val hostAndPort = driverDSL.portAllocation.nextHostAndPort()
GlobalProperties.networkParameters = testNetworkParameters(emptyList(), maxTransactionSize = driverDSL.maxTransactionSize)
return driverDSL.executorService.fork { return driverDSL.executorService.fork {
startVerificationRequestorInternal(name, hostAndPort) startVerificationRequestorInternal(name, hostAndPort)
} }
@ -184,6 +189,7 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri
val securityManager = object : ActiveMQSecurityManager { val securityManager = object : ActiveMQSecurityManager {
// We don't need auth, SSL is good enough // We don't need auth, SSL is good enough
override fun validateUser(user: String?, password: String?) = true override fun validateUser(user: String?, password: String?) = true
override fun validateUserAndRole(user: String?, password: String?, roles: MutableSet<Role>?, checkType: CheckType?) = true override fun validateUserAndRole(user: String?, password: String?, roles: MutableSet<Role>?, checkType: CheckType?) = true
} }