mirror of
https://github.com/corda/corda.git
synced 2024-12-22 06:17:55 +00:00
* 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:
parent
af4aba2bfa
commit
c18bc8758f
@ -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()
|
||||||
##
|
##
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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":
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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,
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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()
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
@ -174,7 +174,7 @@ data class JmxPolicy(val startJmxHttpServer: Boolean = false,
|
|||||||
* @param useTestClock If true the test clock will be used in Node.
|
* @param useTestClock If true the test clock will be used in Node.
|
||||||
* @param startNodesInProcess Provides the default behaviour of whether new nodes should start inside this process or
|
* @param startNodesInProcess Provides the default behaviour of whether new nodes should start inside this process or
|
||||||
* not. Note that this may be overridden in [DriverDSL.startNode].
|
* not. Note that this may be overridden in [DriverDSL.startNode].
|
||||||
* @param waitForAllNodesToFinish If true, the nodes will not shut down automatically after executing the code in the driver DSL block.
|
* @param waitForAllNodesToFinish If true, the nodes will not shut down automatically after executing the code in the driver DSL block.
|
||||||
* It will wait for them to be shut down externally instead.
|
* It will wait for them to be shut down externally instead.
|
||||||
* @param notarySpecs The notaries advertised for this network. These nodes will be started automatically and will be
|
* @param notarySpecs The notaries advertised for this network. These nodes will be started automatically and will be
|
||||||
* available from [DriverDSL.notaryHandles]. Defaults to a simple validating notary.
|
* available from [DriverDSL.notaryHandles]. Defaults to a simple validating notary.
|
||||||
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user