mirror of
https://github.com/corda/corda.git
synced 2025-06-20 16:10:26 +00:00
Merge remote-tracking branch 'remotes/open/master' into merges/27_11_2018_16_42
# Conflicts: # node/src/integration-test/kotlin/net/corda/node/AddressBindingFailureTests.kt # node/src/integration-test/kotlin/net/corda/node/amqp/AMQPBridgeTest.kt # node/src/integration-test/kotlin/net/corda/node/amqp/ProtonWrapperTests.kt # node/src/integration-test/kotlin/net/corda/node/modes/draining/FlowsDrainingModeContentionTest.kt # node/src/integration-test/kotlin/net/corda/node/modes/draining/P2PFlowsDrainingModeTest.kt # node/src/integration-test/kotlin/net/corda/node/modes/draining/RpcFlowsDrainingModeTest.kt # node/src/integration-test/kotlin/net/corda/node/persistence/H2SecurityTests.kt # node/src/integration-test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTest.kt # node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt # node/src/integration-test/kotlin/net/corda/services/messaging/AdditionP2PAddressModeTest.kt # node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt # samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt # testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/NodeBasedTest.kt
This commit is contained in:
@ -6081,7 +6081,7 @@ public abstract class net.corda.testing.driver.PortAllocation extends java.lang.
|
|||||||
public abstract int nextPort()
|
public abstract int nextPort()
|
||||||
##
|
##
|
||||||
@DoNotImplement
|
@DoNotImplement
|
||||||
public static final class net.corda.testing.driver.PortAllocation$Incremental extends net.corda.testing.driver.PortAllocation
|
public static class net.corda.testing.driver.PortAllocation$Incremental extends net.corda.testing.driver.PortAllocation
|
||||||
public <init>(int)
|
public <init>(int)
|
||||||
@NotNull
|
@NotNull
|
||||||
public final java.util.concurrent.atomic.AtomicInteger getPortCounter()
|
public final java.util.concurrent.atomic.AtomicInteger getPortCounter()
|
||||||
|
1
.idea/codeStyles/codeStyleConfig.xml
generated
1
.idea/codeStyles/codeStyleConfig.xml
generated
@ -1,5 +1,6 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
<state>
|
<state>
|
||||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Michele" />
|
||||||
</state>
|
</state>
|
||||||
</component>
|
</component>
|
@ -189,7 +189,8 @@ private class WireTransactionSerializer : JsonSerializer<WireTransaction>() {
|
|||||||
value.timeWindow,
|
value.timeWindow,
|
||||||
value.attachments,
|
value.attachments,
|
||||||
value.references,
|
value.references,
|
||||||
value.privacySalt
|
value.privacySalt,
|
||||||
|
value.networkParametersHash
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +205,8 @@ private class WireTransactionDeserializer : JsonDeserializer<WireTransaction>()
|
|||||||
wrapper.attachments,
|
wrapper.attachments,
|
||||||
wrapper.notary,
|
wrapper.notary,
|
||||||
wrapper.timeWindow,
|
wrapper.timeWindow,
|
||||||
wrapper.references
|
wrapper.references,
|
||||||
|
wrapper.networkParametersHash
|
||||||
)
|
)
|
||||||
return WireTransaction(componentGroups, wrapper.privacySalt)
|
return WireTransaction(componentGroups, wrapper.privacySalt)
|
||||||
}
|
}
|
||||||
@ -218,7 +220,8 @@ private class WireTransactionJson(val id: SecureHash,
|
|||||||
val timeWindow: TimeWindow?,
|
val timeWindow: TimeWindow?,
|
||||||
val attachments: List<SecureHash>,
|
val attachments: List<SecureHash>,
|
||||||
val references: List<StateRef>,
|
val references: List<StateRef>,
|
||||||
val privacySalt: PrivacySalt)
|
val privacySalt: PrivacySalt,
|
||||||
|
val networkParametersHash: SecureHash?)
|
||||||
|
|
||||||
private interface TransactionStateMixin {
|
private interface TransactionStateMixin {
|
||||||
@get:JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
|
@get:JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
|
||||||
|
@ -24,6 +24,7 @@ import net.corda.core.internal.DigitalSignatureWithCert
|
|||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
import net.corda.core.node.services.AttachmentStorage
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
|
import net.corda.core.node.services.NetworkParametersStorage
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
@ -92,8 +93,13 @@ class JacksonSupportTest(@Suppress("unused") private val name: String, factory:
|
|||||||
}
|
}
|
||||||
services = rigorousMock()
|
services = rigorousMock()
|
||||||
cordappProvider = rigorousMock()
|
cordappProvider = rigorousMock()
|
||||||
|
val networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
||||||
|
val networkParametersStorage = rigorousMock<NetworkParametersStorage>().also {
|
||||||
|
doReturn(networkParameters.serialize().hash).whenever(it).currentHash
|
||||||
|
}
|
||||||
|
doReturn(networkParametersStorage).whenever(services).networkParametersStorage
|
||||||
doReturn(cordappProvider).whenever(services).cordappProvider
|
doReturn(cordappProvider).whenever(services).cordappProvider
|
||||||
doReturn(testNetworkParameters(minimumPlatformVersion = 4)).whenever(services).networkParameters
|
doReturn(networkParameters).whenever(services).networkParameters
|
||||||
doReturn(attachments).whenever(services).attachments
|
doReturn(attachments).whenever(services).attachments
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +260,7 @@ class JacksonSupportTest(@Suppress("unused") private val name: String, factory:
|
|||||||
println(mapper.writeValueAsString(json))
|
println(mapper.writeValueAsString(json))
|
||||||
val (wtxJson, signaturesJson) = json.assertHasOnlyFields("wire", "signatures")
|
val (wtxJson, signaturesJson) = json.assertHasOnlyFields("wire", "signatures")
|
||||||
assertThat(signaturesJson.childrenAs<TransactionSignature>(mapper)).isEqualTo(stx.sigs)
|
assertThat(signaturesJson.childrenAs<TransactionSignature>(mapper)).isEqualTo(stx.sigs)
|
||||||
val wtxFields = wtxJson.assertHasOnlyFields("id", "notary", "inputs", "attachments", "outputs", "commands", "timeWindow", "references", "privacySalt")
|
val wtxFields = wtxJson.assertHasOnlyFields("id", "notary", "inputs", "attachments", "outputs", "commands", "timeWindow", "references", "privacySalt", "networkParametersHash")
|
||||||
assertThat(wtxFields[0].valueAs<SecureHash>(mapper)).isEqualTo(wtx.id)
|
assertThat(wtxFields[0].valueAs<SecureHash>(mapper)).isEqualTo(wtx.id)
|
||||||
assertThat(wtxFields[1].valueAs<Party>(mapper)).isEqualTo(wtx.notary)
|
assertThat(wtxFields[1].valueAs<Party>(mapper)).isEqualTo(wtx.notary)
|
||||||
assertThat(wtxFields[2].childrenAs<StateRef>(mapper)).isEqualTo(wtx.inputs)
|
assertThat(wtxFields[2].childrenAs<StateRef>(mapper)).isEqualTo(wtx.inputs)
|
||||||
|
@ -13,7 +13,7 @@ import net.corda.node.services.messaging.RPCServerConfiguration
|
|||||||
import net.corda.nodeapi.RPCApi
|
import net.corda.nodeapi.RPCApi
|
||||||
import net.corda.nodeapi.eventually
|
import net.corda.nodeapi.eventually
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.testThreadFactory
|
import net.corda.testing.internal.testThreadFactory
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.*
|
||||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration
|
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration
|
||||||
@ -39,7 +39,7 @@ class RPCStabilityTests {
|
|||||||
val testSerialization = SerializationEnvironmentRule(true)
|
val testSerialization = SerializationEnvironmentRule(true)
|
||||||
|
|
||||||
private val pool = Executors.newFixedThreadPool(10, testThreadFactory())
|
private val pool = Executors.newFixedThreadPool(10, testThreadFactory())
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
@After
|
@After
|
||||||
fun shutdown() {
|
fun shutdown() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.client.rpc.internal.serialization.amqp
|
package net.corda.client.rpc.internal.serialization.amqp
|
||||||
|
|
||||||
import net.corda.core.cordapp.Cordapp
|
import net.corda.core.cordapp.Cordapp
|
||||||
|
import net.corda.core.internal.toSynchronised
|
||||||
import net.corda.core.serialization.ClassWhitelist
|
import net.corda.core.serialization.ClassWhitelist
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.SerializationContext.UseCase
|
import net.corda.core.serialization.SerializationContext.UseCase
|
||||||
@ -19,19 +20,19 @@ class AMQPClientSerializationScheme(
|
|||||||
cordappCustomSerializers: Set<SerializationCustomSerializer<*,*>>,
|
cordappCustomSerializers: Set<SerializationCustomSerializer<*,*>>,
|
||||||
serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>
|
serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>
|
||||||
) : AbstractAMQPSerializationScheme(cordappCustomSerializers, serializerFactoriesForContexts) {
|
) : AbstractAMQPSerializationScheme(cordappCustomSerializers, serializerFactoriesForContexts) {
|
||||||
constructor(cordapps: List<Cordapp>) : this(cordapps.customSerializers, AccessOrderLinkedHashMap { 128 })
|
constructor(cordapps: List<Cordapp>) : this(cordapps.customSerializers, AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>(128).toSynchronised())
|
||||||
constructor(cordapps: List<Cordapp>, serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>) : this(cordapps.customSerializers, serializerFactoriesForContexts)
|
constructor(cordapps: List<Cordapp>, serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>) : this(cordapps.customSerializers, serializerFactoriesForContexts)
|
||||||
|
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
constructor() : this(emptySet(), AccessOrderLinkedHashMap { 128 })
|
constructor() : this(emptySet(), AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>(128).toSynchronised())
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/** Call from main only. */
|
/** Call from main only. */
|
||||||
fun initialiseSerialization(classLoader: ClassLoader? = null, serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory> = AccessOrderLinkedHashMap { 128 }) {
|
fun initialiseSerialization(classLoader: ClassLoader? = null, serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory> = AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>(128).toSynchronised()) {
|
||||||
nodeSerializationEnv = createSerializationEnv(classLoader, serializerFactoriesForContexts)
|
nodeSerializationEnv = createSerializationEnv(classLoader, serializerFactoriesForContexts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createSerializationEnv(classLoader: ClassLoader? = null, serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory> = AccessOrderLinkedHashMap { 128 }): SerializationEnvironment {
|
fun createSerializationEnv(classLoader: ClassLoader? = null, serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory> = AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>(128).toSynchronised()): SerializationEnvironment {
|
||||||
return SerializationEnvironment.with(
|
return SerializationEnvironment.with(
|
||||||
SerializationFactoryImpl().apply {
|
SerializationFactoryImpl().apply {
|
||||||
registerScheme(AMQPClientSerializationScheme(emptyList(), serializerFactoriesForContexts))
|
registerScheme(AMQPClientSerializationScheme(emptyList(), serializerFactoriesForContexts))
|
||||||
|
@ -71,7 +71,8 @@ object TransactionGenerator {
|
|||||||
TransactionVerificationRequest(
|
TransactionVerificationRequest(
|
||||||
wtx3.serialize(),
|
wtx3.serialize(),
|
||||||
arrayOf(wtx1.serialize(), wtx2.serialize()),
|
arrayOf(wtx1.serialize(), wtx2.serialize()),
|
||||||
arrayOf(contractAttachment.serialize().bytes))
|
arrayOf(contractAttachment.serialize().bytes),
|
||||||
|
ledgerServices.networkParameters.serialize())
|
||||||
.serialize()
|
.serialize()
|
||||||
.writeTo(output)
|
.writeTo(output)
|
||||||
}
|
}
|
||||||
@ -104,7 +105,8 @@ object TransactionGenerator {
|
|||||||
TransactionVerificationRequest(
|
TransactionVerificationRequest(
|
||||||
wtx3.serialize(),
|
wtx3.serialize(),
|
||||||
arrayOf(wtx1.serialize(), wtx2.serialize()),
|
arrayOf(wtx1.serialize(), wtx2.serialize()),
|
||||||
arrayOf(contractAttachment.serialize().bytes))
|
arrayOf(contractAttachment.serialize().bytes),
|
||||||
|
ledgerServices.networkParameters.serialize())
|
||||||
.serialize()
|
.serialize()
|
||||||
.writeTo(output)
|
.writeTo(output)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import net.corda.core.contracts.Attachment
|
|||||||
import net.corda.core.contracts.ContractAttachment
|
import net.corda.core.contracts.ContractAttachment
|
||||||
import net.corda.core.contracts.ContractClassName
|
import net.corda.core.contracts.ContractClassName
|
||||||
import net.corda.core.internal.DEPLOYED_CORDAPP_UPLOADER
|
import net.corda.core.internal.DEPLOYED_CORDAPP_UPLOADER
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
@ -14,7 +15,8 @@ import net.corda.core.transactions.WireTransaction
|
|||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
class TransactionVerificationRequest(val wtxToVerify: SerializedBytes<WireTransaction>,
|
class TransactionVerificationRequest(val wtxToVerify: SerializedBytes<WireTransaction>,
|
||||||
val dependencies: Array<SerializedBytes<WireTransaction>>,
|
val dependencies: Array<SerializedBytes<WireTransaction>>,
|
||||||
val attachments: Array<ByteArray>) {
|
val attachments: Array<ByteArray>,
|
||||||
|
val networkParameters: SerializedBytes<NetworkParameters>) {
|
||||||
fun toLedgerTransaction(): LedgerTransaction {
|
fun toLedgerTransaction(): LedgerTransaction {
|
||||||
val deps = dependencies.map { it.deserialize() }.associateBy(WireTransaction::id)
|
val deps = dependencies.map { it.deserialize() }.associateBy(WireTransaction::id)
|
||||||
val attachments = attachments.map { it.deserialize<Attachment>() }
|
val attachments = attachments.map { it.deserialize<Attachment>() }
|
||||||
@ -27,7 +29,8 @@ class TransactionVerificationRequest(val wtxToVerify: SerializedBytes<WireTransa
|
|||||||
resolveIdentity = { null },
|
resolveIdentity = { null },
|
||||||
resolveAttachment = { attachmentMap[it] },
|
resolveAttachment = { attachmentMap[it] },
|
||||||
resolveStateRef = { deps[it.txhash]?.outputs?.get(it.index) },
|
resolveStateRef = { deps[it.txhash]?.outputs?.get(it.index) },
|
||||||
resolveContractAttachment = { contractAttachmentMap[it.contract]?.id }
|
resolveContractAttachment = { contractAttachmentMap[it.contract]?.id },
|
||||||
|
resolveParameters = { networkParameters.deserialize() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,6 @@ enum class ComponentGroupEnum {
|
|||||||
NOTARY_GROUP, // ordinal = 4.
|
NOTARY_GROUP, // ordinal = 4.
|
||||||
TIMEWINDOW_GROUP, // ordinal = 5.
|
TIMEWINDOW_GROUP, // ordinal = 5.
|
||||||
SIGNERS_GROUP, // ordinal = 6.
|
SIGNERS_GROUP, // ordinal = 6.
|
||||||
REFERENCES_GROUP // ordinal = 7.
|
REFERENCES_GROUP, // ordinal = 7.
|
||||||
|
PARAMETERS_GROUP // ordinal = 8.
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,11 @@ abstract class SignTransactionFlow @JvmOverloads constructor(val otherSideSessio
|
|||||||
progressTracker.currentStep = RECEIVING
|
progressTracker.currentStep = RECEIVING
|
||||||
// Receive transaction and resolve dependencies, check sufficient signatures is disabled as we don't have all signatures.
|
// Receive transaction and resolve dependencies, check sufficient signatures is disabled as we don't have all signatures.
|
||||||
val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false))
|
val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false))
|
||||||
|
// TODO ENT-2666: Have time period for checking the parameters (because of the delay of propagation of new network data).
|
||||||
|
check(stx.networkParametersHash == serviceHub.networkParametersStorage.currentHash) {
|
||||||
|
"Received transaction for signing with invalid network parameters hash: ${stx.networkParametersHash}." +
|
||||||
|
"Node's parameters hash: ${serviceHub.networkParametersStorage.currentHash}"
|
||||||
|
}
|
||||||
// Receive the signing key that the party requesting the signature expects us to sign with. Having this provided
|
// Receive the signing key that the party requesting the signature expects us to sign with. Having this provided
|
||||||
// means we only have to check we own that one key, rather than matching all keys in the transaction against all
|
// means we only have to check we own that one key, rather than matching all keys in the transaction against all
|
||||||
// keys we own.
|
// keys we own.
|
||||||
|
@ -33,7 +33,8 @@ class NotaryChangeFlow<out T : ContractState>(
|
|||||||
val tx = NotaryChangeTransactionBuilder(
|
val tx = NotaryChangeTransactionBuilder(
|
||||||
inputs.map { it.ref },
|
inputs.map { it.ref },
|
||||||
originalState.state.notary,
|
originalState.state.notary,
|
||||||
modification
|
modification,
|
||||||
|
serviceHub.networkParametersStorage.currentHash
|
||||||
).build()
|
).build()
|
||||||
|
|
||||||
val participantKeys = inputs.flatMap { it.state.data.participants }.map { it.owningKey }.toSet()
|
val participantKeys = inputs.flatMap { it.state.data.participants }.map { it.owningKey }.toSet()
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.core.flows
|
|||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.DoNotImplement
|
import net.corda.core.DoNotImplement
|
||||||
|
import net.corda.core.contracts.ComponentGroupEnum
|
||||||
import net.corda.core.contracts.StateRef
|
import net.corda.core.contracts.StateRef
|
||||||
import net.corda.core.contracts.TimeWindow
|
import net.corda.core.contracts.TimeWindow
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
@ -12,10 +13,7 @@ import net.corda.core.internal.FetchDataFlow
|
|||||||
import net.corda.core.internal.notary.generateSignature
|
import net.corda.core.internal.notary.generateSignature
|
||||||
import net.corda.core.internal.notary.validateSignatures
|
import net.corda.core.internal.notary.validateSignatures
|
||||||
import net.corda.core.internal.pushToLoggingContext
|
import net.corda.core.internal.pushToLoggingContext
|
||||||
import net.corda.core.transactions.ContractUpgradeWireTransaction
|
import net.corda.core.transactions.*
|
||||||
import net.corda.core.transactions.ReferenceStateRef
|
|
||||||
import net.corda.core.transactions.SignedTransaction
|
|
||||||
import net.corda.core.transactions.WireTransaction
|
|
||||||
import net.corda.core.utilities.ProgressTracker
|
import net.corda.core.utilities.ProgressTracker
|
||||||
import net.corda.core.utilities.UntrustworthyData
|
import net.corda.core.utilities.UntrustworthyData
|
||||||
import net.corda.core.utilities.unwrap
|
import net.corda.core.utilities.unwrap
|
||||||
@ -30,7 +28,8 @@ class NotaryFlow {
|
|||||||
* signatures will be returned – one from each replica that accepted the input state commit.
|
* signatures will be returned – one from each replica that accepted the input state commit.
|
||||||
*
|
*
|
||||||
* @throws NotaryException in case the any of the inputs to the transaction have been consumed
|
* @throws NotaryException in case the any of the inputs to the transaction have been consumed
|
||||||
* by another transaction or the time-window is invalid.
|
* by another transaction or the time-window is invalid or
|
||||||
|
* the parameters used for this transaction are no longer in force in the network.
|
||||||
*/
|
*/
|
||||||
@DoNotImplement
|
@DoNotImplement
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
@ -99,7 +98,9 @@ class NotaryFlow {
|
|||||||
val ctx = stx.coreTransaction
|
val ctx = stx.coreTransaction
|
||||||
val tx = when (ctx) {
|
val tx = when (ctx) {
|
||||||
is ContractUpgradeWireTransaction -> ctx.buildFilteredTransaction()
|
is ContractUpgradeWireTransaction -> ctx.buildFilteredTransaction()
|
||||||
is WireTransaction -> ctx.buildFilteredTransaction(Predicate { it is StateRef || it is ReferenceStateRef || it is TimeWindow || it == notaryParty })
|
is WireTransaction -> ctx.buildFilteredTransaction(Predicate {
|
||||||
|
it is StateRef || it is ReferenceStateRef || it is TimeWindow || it == notaryParty || it is NetworkParametersHash
|
||||||
|
})
|
||||||
else -> ctx
|
else -> ctx
|
||||||
}
|
}
|
||||||
session.send(NotarisationPayload(tx, signature))
|
session.send(NotarisationPayload(tx, signature))
|
||||||
|
@ -21,6 +21,7 @@ object ContractUpgradeUtils {
|
|||||||
else -> getContractAttachmentId(stateAndRef.state.contract, services)
|
else -> getContractAttachmentId(stateAndRef.state.contract, services)
|
||||||
}
|
}
|
||||||
val upgradedContractAttachmentId = getContractAttachmentId(upgradedContractClass.name, services)
|
val upgradedContractAttachmentId = getContractAttachmentId(upgradedContractClass.name, services)
|
||||||
|
val networkParametersHash = services.networkParametersStorage.currentHash
|
||||||
|
|
||||||
val inputs = listOf(stateAndRef.ref)
|
val inputs = listOf(stateAndRef.ref)
|
||||||
return ContractUpgradeTransactionBuilder(
|
return ContractUpgradeTransactionBuilder(
|
||||||
@ -29,7 +30,8 @@ object ContractUpgradeUtils {
|
|||||||
legacyContractAttachmentId,
|
legacyContractAttachmentId,
|
||||||
upgradedContractClass.name,
|
upgradedContractClass.name,
|
||||||
upgradedContractAttachmentId,
|
upgradedContractAttachmentId,
|
||||||
privacySalt
|
privacySalt,
|
||||||
|
networkParametersHash
|
||||||
).build()
|
).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ class FetchAttachmentsFlow(requests: Set<SecureHash>,
|
|||||||
* [FetchDataFlow.DownloadedVsRequestedDataMismatch] being thrown.
|
* [FetchDataFlow.DownloadedVsRequestedDataMismatch] being thrown.
|
||||||
* If the remote peer doesn't have an entry, it results in a [FetchDataFlow.HashNotFound] exception.
|
* If the remote peer doesn't have an entry, it results in a [FetchDataFlow.HashNotFound] exception.
|
||||||
* If the remote peer is not authorized to request this transaction, it results in a [FetchDataFlow.IllegalTransactionRequest] exception.
|
* If the remote peer is not authorized to request this transaction, it results in a [FetchDataFlow.IllegalTransactionRequest] exception.
|
||||||
* Authorisation is accorded only on valid ancestors of the root transation.
|
* Authorisation is accorded only on valid ancestors of the root transaction.
|
||||||
* Note that returned transactions are not inserted into the database, because it's up to the caller to actually verify the transactions are valid.
|
* Note that returned transactions are not inserted into the database, because it's up to the caller to actually verify the transactions are valid.
|
||||||
*/
|
*/
|
||||||
class FetchTransactionsFlow(requests: Set<SecureHash>, otherSide: FlowSession) :
|
class FetchTransactionsFlow(requests: Set<SecureHash>, otherSide: FlowSession) :
|
||||||
|
@ -17,9 +17,10 @@ import kotlin.reflect.KClass
|
|||||||
/** Constructs a [NotaryChangeWireTransaction]. */
|
/** Constructs a [NotaryChangeWireTransaction]. */
|
||||||
class NotaryChangeTransactionBuilder(val inputs: List<StateRef>,
|
class NotaryChangeTransactionBuilder(val inputs: List<StateRef>,
|
||||||
val notary: Party,
|
val notary: Party,
|
||||||
val newNotary: Party) {
|
val newNotary: Party,
|
||||||
|
val networkParametersHash: SecureHash) {
|
||||||
fun build(): NotaryChangeWireTransaction {
|
fun build(): NotaryChangeWireTransaction {
|
||||||
val components = listOf(inputs, notary, newNotary).map { it.serialize() }
|
val components = listOf(inputs, notary, newNotary, networkParametersHash).map { it.serialize() }
|
||||||
return NotaryChangeWireTransaction(components)
|
return NotaryChangeWireTransaction(components)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,9 +32,10 @@ class ContractUpgradeTransactionBuilder(
|
|||||||
val legacyContractAttachmentId: SecureHash,
|
val legacyContractAttachmentId: SecureHash,
|
||||||
val upgradedContractClassName: ContractClassName,
|
val upgradedContractClassName: ContractClassName,
|
||||||
val upgradedContractAttachmentId: SecureHash,
|
val upgradedContractAttachmentId: SecureHash,
|
||||||
val privacySalt: PrivacySalt = PrivacySalt()) {
|
val privacySalt: PrivacySalt = PrivacySalt(),
|
||||||
|
val networkParametersHash: SecureHash) {
|
||||||
fun build(): ContractUpgradeWireTransaction {
|
fun build(): ContractUpgradeWireTransaction {
|
||||||
val components = listOf(inputs, notary, legacyContractAttachmentId, upgradedContractClassName, upgradedContractAttachmentId).map { it.serialize() }
|
val components = listOf(inputs, notary, legacyContractAttachmentId, upgradedContractClassName, upgradedContractAttachmentId, networkParametersHash).map { it.serialize() }
|
||||||
return ContractUpgradeWireTransaction(components, privacySalt)
|
return ContractUpgradeWireTransaction(components, privacySalt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +130,8 @@ fun createComponentGroups(inputs: List<StateRef>,
|
|||||||
attachments: List<SecureHash>,
|
attachments: List<SecureHash>,
|
||||||
notary: Party?,
|
notary: Party?,
|
||||||
timeWindow: TimeWindow?,
|
timeWindow: TimeWindow?,
|
||||||
references: List<StateRef>): List<ComponentGroup> {
|
references: List<StateRef>,
|
||||||
|
networkParametersHash: SecureHash?): List<ComponentGroup> {
|
||||||
val serialize = { value: Any, _: Int -> value.serialize() }
|
val serialize = { value: Any, _: Int -> value.serialize() }
|
||||||
val componentGroupMap: MutableList<ComponentGroup> = mutableListOf()
|
val componentGroupMap: MutableList<ComponentGroup> = mutableListOf()
|
||||||
if (inputs.isNotEmpty()) componentGroupMap.add(ComponentGroup(ComponentGroupEnum.INPUTS_GROUP.ordinal, inputs.lazyMapped(serialize)))
|
if (inputs.isNotEmpty()) componentGroupMap.add(ComponentGroup(ComponentGroupEnum.INPUTS_GROUP.ordinal, inputs.lazyMapped(serialize)))
|
||||||
@ -142,6 +145,7 @@ fun createComponentGroups(inputs: List<StateRef>,
|
|||||||
// Adding signers to their own group. This is required for command visibility purposes: a party receiving
|
// Adding signers to their own group. This is required for command visibility purposes: a party receiving
|
||||||
// a FilteredTransaction can now verify it sees all the commands it should sign.
|
// a FilteredTransaction can now verify it sees all the commands it should sign.
|
||||||
if (commands.isNotEmpty()) componentGroupMap.add(ComponentGroup(ComponentGroupEnum.SIGNERS_GROUP.ordinal, commands.map { it.signers }.lazyMapped(serialize)))
|
if (commands.isNotEmpty()) componentGroupMap.add(ComponentGroup(ComponentGroupEnum.SIGNERS_GROUP.ordinal, commands.map { it.signers }.lazyMapped(serialize)))
|
||||||
|
if (networkParametersHash != null) componentGroupMap.add(ComponentGroup(ComponentGroupEnum.PARAMETERS_GROUP.ordinal, listOf(networkParametersHash.serialize())))
|
||||||
return componentGroupMap
|
return componentGroupMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,6 @@ abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service:
|
|||||||
requestPayload.requestSignature,
|
requestPayload.requestSignature,
|
||||||
tx.timeWindow,
|
tx.timeWindow,
|
||||||
tx.references)
|
tx.references)
|
||||||
|
|
||||||
} catch (e: NotaryInternalException) {
|
} catch (e: NotaryInternalException) {
|
||||||
logError(e.error)
|
logError(e.error)
|
||||||
// Any exception that's not a NotaryInternalException is assumed to be an unexpected internal error
|
// Any exception that's not a NotaryInternalException is assumed to be an unexpected internal error
|
||||||
@ -96,6 +95,7 @@ abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service:
|
|||||||
val transaction = extractParts(requestPayload)
|
val transaction = extractParts(requestPayload)
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
checkNotary(transaction.notary)
|
checkNotary(transaction.notary)
|
||||||
|
checkParametersHash(transaction.networkParametersHash)
|
||||||
checkInputs(transaction.inputs + transaction.references)
|
checkInputs(transaction.inputs + transaction.references)
|
||||||
return transaction
|
return transaction
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -123,6 +123,21 @@ abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that network parameters hash on this transaction is the current hash for the network.
|
||||||
|
*/
|
||||||
|
// TODO ENT-2666 Implement network parameters fuzzy checking. By design in Corda network we have propagation time delay.
|
||||||
|
// We will never end up in perfect synchronization with all the nodes. However, network parameters update process
|
||||||
|
// lets us predict what is the reasonable time window for changing parameters on most of the nodes.
|
||||||
|
@Suspendable
|
||||||
|
protected fun checkParametersHash(networkParametersHash: SecureHash?) {
|
||||||
|
if (networkParametersHash == null && serviceHub.networkParameters.minimumPlatformVersion < 4) return
|
||||||
|
val notaryParametersHash = serviceHub.networkParametersStorage.currentHash
|
||||||
|
require (notaryParametersHash == networkParametersHash) {
|
||||||
|
"Transaction for notarisation was tagged with parameters with hash: $networkParametersHash, but current network parameters are: $notaryParametersHash"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Verifies that the correct notarisation request was signed by the counterparty. */
|
/** Verifies that the correct notarisation request was signed by the counterparty. */
|
||||||
private fun validateRequestSignature(request: NotarisationRequest, signature: NotarisationRequestSignature) {
|
private fun validateRequestSignature(request: NotarisationRequest, signature: NotarisationRequestSignature) {
|
||||||
val requestingParty = otherSideSession.counterparty
|
val requestingParty = otherSideSession.counterparty
|
||||||
@ -151,7 +166,8 @@ abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service:
|
|||||||
val inputs: List<StateRef>,
|
val inputs: List<StateRef>,
|
||||||
val timeWindow: TimeWindow?,
|
val timeWindow: TimeWindow?,
|
||||||
val notary: Party?,
|
val notary: Party?,
|
||||||
val references: List<StateRef> = emptyList()
|
val references: List<StateRef> = emptyList(),
|
||||||
|
val networkParametersHash: SecureHash?
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun logError(error: NotaryError) {
|
private fun logError(error: NotaryError) {
|
||||||
|
@ -5,10 +5,7 @@ import net.corda.core.DoNotImplement
|
|||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.*
|
||||||
import net.corda.core.cordapp.CordappContext
|
import net.corda.core.cordapp.CordappContext
|
||||||
import net.corda.core.cordapp.CordappProvider
|
import net.corda.core.cordapp.CordappProvider
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.*
|
||||||
import net.corda.core.crypto.SignableData
|
|
||||||
import net.corda.core.crypto.SignatureMetadata
|
|
||||||
import net.corda.core.crypto.TransactionSignature
|
|
||||||
import net.corda.core.flows.ContractUpgradeFlow
|
import net.corda.core.flows.ContractUpgradeFlow
|
||||||
import net.corda.core.node.services.*
|
import net.corda.core.node.services.*
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
@ -41,6 +38,9 @@ interface ServicesForResolution {
|
|||||||
/** Provides access to anything relating to cordapps including contract attachment resolution and app context */
|
/** Provides access to anything relating to cordapps including contract attachment resolution and app context */
|
||||||
val cordappProvider: CordappProvider
|
val cordappProvider: CordappProvider
|
||||||
|
|
||||||
|
/** Provides access to storage of historical network parameters that are used in transaction resolution */
|
||||||
|
val networkParametersStorage: NetworkParametersStorage
|
||||||
|
|
||||||
/** Returns the network parameters the node is operating under. */
|
/** Returns the network parameters the node is operating under. */
|
||||||
val networkParameters: NetworkParameters
|
val networkParameters: NetworkParameters
|
||||||
|
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package net.corda.core.node.services
|
||||||
|
|
||||||
|
import net.corda.core.CordaInternal
|
||||||
|
import net.corda.core.DoNotImplement
|
||||||
|
import net.corda.core.crypto.SecureHash
|
||||||
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for handling network parameters storage used for resolving transactions according to parameters that were
|
||||||
|
* historically in force in the network.
|
||||||
|
*/
|
||||||
|
@DoNotImplement
|
||||||
|
interface NetworkParametersStorage {
|
||||||
|
/**
|
||||||
|
* Hash of the current parameters for the network.
|
||||||
|
*/
|
||||||
|
val currentHash: SecureHash
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For backwards compatibility, this parameters hash will be used for resolving historical transactions in the chain.
|
||||||
|
*/
|
||||||
|
val defaultHash: SecureHash
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return network parameters for the given hash. Null if there are no parameters for this hash in the storage and we are unable to
|
||||||
|
* get them from network map.
|
||||||
|
*/
|
||||||
|
fun lookup(hash: SecureHash): NetworkParameters?
|
||||||
|
}
|
@ -3,6 +3,8 @@ package net.corda.core.transactions
|
|||||||
import net.corda.core.contracts.ContractState
|
import net.corda.core.contracts.ContractState
|
||||||
import net.corda.core.contracts.StateAndRef
|
import net.corda.core.contracts.StateAndRef
|
||||||
import net.corda.core.contracts.StateRef
|
import net.corda.core.contracts.StateRef
|
||||||
|
import net.corda.core.crypto.SecureHash
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,13 +18,24 @@ abstract class CoreTransaction : BaseTransaction() {
|
|||||||
abstract override val inputs: List<StateRef>
|
abstract override val inputs: List<StateRef>
|
||||||
/** The reference inputs of this transaction, containing the state references only. **/
|
/** The reference inputs of this transaction, containing the state references only. **/
|
||||||
abstract override val references: List<StateRef>
|
abstract override val references: List<StateRef>
|
||||||
|
/**
|
||||||
|
* Hash of the network parameters that were in force when the transaction was notarised. Null means, that the transaction
|
||||||
|
* was created on older version of Corda (before 4), resolution will default to initial parameters.
|
||||||
|
*/
|
||||||
|
abstract val networkParametersHash: SecureHash?
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A transaction with fully resolved components, such as input states. */
|
/** A transaction with fully resolved components, such as input states. */
|
||||||
abstract class FullTransaction : BaseTransaction() {
|
abstract class FullTransaction : BaseTransaction() {
|
||||||
abstract override val inputs: List<StateAndRef<ContractState>>
|
abstract override val inputs: List<StateAndRef<ContractState>>
|
||||||
abstract override val references: List<StateAndRef<ContractState>>
|
abstract override val references: List<StateAndRef<ContractState>>
|
||||||
|
// TODO NetworkParameters field is nullable only because of the API stability and the fact that our ledger transactions exposed constructors
|
||||||
|
// (they were data classes). This should be revisited.
|
||||||
|
/**
|
||||||
|
* Network parameters that were in force when this transaction was created. Resolved from the hash of network parameters on the corresponding
|
||||||
|
* wire transaction.
|
||||||
|
*/
|
||||||
|
abstract val networkParameters: NetworkParameters?
|
||||||
override fun checkBaseInvariants() {
|
override fun checkBaseInvariants() {
|
||||||
super.checkBaseInvariants()
|
super.checkBaseInvariants()
|
||||||
checkInputsAndReferencesHaveSameNotary()
|
checkInputsAndReferencesHaveSameNotary()
|
||||||
|
@ -69,6 +69,11 @@ data class ContractUpgradeWireTransaction(
|
|||||||
val legacyContractAttachmentId: SecureHash by lazy { serializedComponents[LEGACY_ATTACHMENT.ordinal].deserialize<SecureHash>() }
|
val legacyContractAttachmentId: SecureHash by lazy { serializedComponents[LEGACY_ATTACHMENT.ordinal].deserialize<SecureHash>() }
|
||||||
val upgradedContractClassName: ContractClassName by lazy { serializedComponents[UPGRADED_CONTRACT.ordinal].deserialize<ContractClassName>() }
|
val upgradedContractClassName: ContractClassName by lazy { serializedComponents[UPGRADED_CONTRACT.ordinal].deserialize<ContractClassName>() }
|
||||||
val upgradedContractAttachmentId: SecureHash by lazy { serializedComponents[UPGRADED_ATTACHMENT.ordinal].deserialize<SecureHash>() }
|
val upgradedContractAttachmentId: SecureHash by lazy { serializedComponents[UPGRADED_ATTACHMENT.ordinal].deserialize<SecureHash>() }
|
||||||
|
override val networkParametersHash: SecureHash? by lazy {
|
||||||
|
if (serializedComponents.size >= PARAMETERS_HASH.ordinal + 1) {
|
||||||
|
serializedComponents[PARAMETERS_HASH.ordinal].deserialize<SecureHash>()
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
check(inputs.isNotEmpty()) { "A contract upgrade transaction must have inputs" }
|
check(inputs.isNotEmpty()) { "A contract upgrade transaction must have inputs" }
|
||||||
@ -106,6 +111,8 @@ data class ContractUpgradeWireTransaction(
|
|||||||
?: throw AttachmentResolutionException(legacyContractAttachmentId)
|
?: throw AttachmentResolutionException(legacyContractAttachmentId)
|
||||||
val upgradedContractAttachment = services.attachments.openAttachment(upgradedContractAttachmentId)
|
val upgradedContractAttachment = services.attachments.openAttachment(upgradedContractAttachmentId)
|
||||||
?: throw AttachmentResolutionException(upgradedContractAttachmentId)
|
?: throw AttachmentResolutionException(upgradedContractAttachmentId)
|
||||||
|
val hashToResolve = networkParametersHash ?: services.networkParametersStorage.defaultHash
|
||||||
|
val resolvedNetworkParameters = services.networkParametersStorage.lookup(hashToResolve) ?: throw TransactionResolutionException(id)
|
||||||
return ContractUpgradeLedgerTransaction(
|
return ContractUpgradeLedgerTransaction(
|
||||||
resolvedInputs,
|
resolvedInputs,
|
||||||
notary,
|
notary,
|
||||||
@ -115,7 +122,7 @@ data class ContractUpgradeWireTransaction(
|
|||||||
id,
|
id,
|
||||||
privacySalt,
|
privacySalt,
|
||||||
sigs,
|
sigs,
|
||||||
services.networkParameters
|
resolvedNetworkParameters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,12 +152,13 @@ data class ContractUpgradeWireTransaction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs a filtered transaction: the inputs and the notary party are always visible, while the rest are hidden. */
|
/** Constructs a filtered transaction: the inputs, the notary party and network parameters hash are always visible, while the rest are hidden. */
|
||||||
fun buildFilteredTransaction(): ContractUpgradeFilteredTransaction {
|
fun buildFilteredTransaction(): ContractUpgradeFilteredTransaction {
|
||||||
val totalComponents = (0 until serializedComponents.size).toSet()
|
val totalComponents = (0 until serializedComponents.size).toSet()
|
||||||
val visibleComponents = mapOf(
|
val visibleComponents = mapOf(
|
||||||
INPUTS.ordinal to FilteredComponent(serializedComponents[INPUTS.ordinal], nonces[INPUTS.ordinal]),
|
INPUTS.ordinal to FilteredComponent(serializedComponents[INPUTS.ordinal], nonces[INPUTS.ordinal]),
|
||||||
NOTARY.ordinal to FilteredComponent(serializedComponents[NOTARY.ordinal], nonces[NOTARY.ordinal])
|
NOTARY.ordinal to FilteredComponent(serializedComponents[NOTARY.ordinal], nonces[NOTARY.ordinal]),
|
||||||
|
PARAMETERS_HASH.ordinal to FilteredComponent(serializedComponents[PARAMETERS_HASH.ordinal], nonces[PARAMETERS_HASH.ordinal])
|
||||||
)
|
)
|
||||||
val hiddenComponents = (totalComponents - visibleComponents.keys).map { index ->
|
val hiddenComponents = (totalComponents - visibleComponents.keys).map { index ->
|
||||||
val hash = componentHash(nonces[index], serializedComponents[index])
|
val hash = componentHash(nonces[index], serializedComponents[index])
|
||||||
@ -161,13 +169,13 @@ data class ContractUpgradeWireTransaction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class Component {
|
enum class Component {
|
||||||
INPUTS, NOTARY, LEGACY_ATTACHMENT, UPGRADED_CONTRACT, UPGRADED_ATTACHMENT
|
INPUTS, NOTARY, LEGACY_ATTACHMENT, UPGRADED_CONTRACT, UPGRADED_ATTACHMENT, PARAMETERS_HASH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A filtered version of the [ContractUpgradeWireTransaction]. In comparison with a regular [FilteredTransaction], there
|
* A filtered version of the [ContractUpgradeWireTransaction]. In comparison with a regular [FilteredTransaction], there
|
||||||
* is no flexibility on what parts of the transaction to reveal – the inputs and notary field are always visible and the
|
* is no flexibility on what parts of the transaction to reveal – the inputs, notary and network parameters hash fields are always visible and the
|
||||||
* rest of the transaction is always hidden. Its only purpose is to hide transaction data when using a non-validating notary.
|
* rest of the transaction is always hidden. Its only purpose is to hide transaction data when using a non-validating notary.
|
||||||
*/
|
*/
|
||||||
@KeepForDJVM
|
@KeepForDJVM
|
||||||
@ -189,6 +197,9 @@ data class ContractUpgradeFilteredTransaction(
|
|||||||
visibleComponents[NOTARY.ordinal]?.component?.deserialize<Party>()
|
visibleComponents[NOTARY.ordinal]?.component?.deserialize<Party>()
|
||||||
?: throw IllegalArgumentException("Notary not specified")
|
?: throw IllegalArgumentException("Notary not specified")
|
||||||
}
|
}
|
||||||
|
override val networkParametersHash: SecureHash? by lazy {
|
||||||
|
visibleComponents[PARAMETERS_HASH.ordinal]?.component?.deserialize<SecureHash>()
|
||||||
|
}
|
||||||
override val id: SecureHash by lazy {
|
override val id: SecureHash by lazy {
|
||||||
val totalComponents = visibleComponents.size + hiddenComponents.size
|
val totalComponents = visibleComponents.size + hiddenComponents.size
|
||||||
val hashList = (0 until totalComponents).map { i ->
|
val hashList = (0 until totalComponents).map { i ->
|
||||||
@ -230,9 +241,9 @@ data class ContractUpgradeLedgerTransaction(
|
|||||||
override val id: SecureHash,
|
override val id: SecureHash,
|
||||||
val privacySalt: PrivacySalt,
|
val privacySalt: PrivacySalt,
|
||||||
override val sigs: List<TransactionSignature>,
|
override val sigs: List<TransactionSignature>,
|
||||||
private val networkParameters: NetworkParameters
|
override val networkParameters: NetworkParameters
|
||||||
) : FullTransaction(), TransactionWithSignatures {
|
) : FullTransaction(), TransactionWithSignatures {
|
||||||
/** ContractUpgradeLEdgerTransactions do not contain reference input states. */
|
/** ContractUpgradeLedgerTransactions do not contain reference input states. */
|
||||||
override val references: List<StateAndRef<ContractState>> = emptyList()
|
override val references: List<StateAndRef<ContractState>> = emptyList()
|
||||||
/** The legacy contract class name is determined by the first input state. */
|
/** The legacy contract class name is determined by the first input state. */
|
||||||
private val legacyContractClassName = inputs.first().state.contract
|
private val legacyContractClassName = inputs.first().state.contract
|
||||||
|
@ -52,7 +52,10 @@ private constructor(
|
|||||||
override val notary: Party?,
|
override val notary: Party?,
|
||||||
val timeWindow: TimeWindow?,
|
val timeWindow: TimeWindow?,
|
||||||
val privacySalt: PrivacySalt,
|
val privacySalt: PrivacySalt,
|
||||||
val networkParameters: NetworkParameters?,
|
/** Network parameters that were in force when the transaction was notarised. */
|
||||||
|
// TODO Network parameters should never be null on LedgerTransaction, this is left only because of deprecated constructors. We should decide to
|
||||||
|
// get rid of them.
|
||||||
|
override val networkParameters: NetworkParameters?,
|
||||||
override val references: List<StateAndRef<ContractState>>
|
override val references: List<StateAndRef<ContractState>>
|
||||||
//DOCEND 1
|
//DOCEND 1
|
||||||
) : FullTransaction() {
|
) : FullTransaction() {
|
||||||
@ -81,7 +84,7 @@ private constructor(
|
|||||||
notary: Party?,
|
notary: Party?,
|
||||||
timeWindow: TimeWindow?,
|
timeWindow: TimeWindow?,
|
||||||
privacySalt: PrivacySalt,
|
privacySalt: PrivacySalt,
|
||||||
networkParameters: NetworkParameters?,
|
networkParameters: NetworkParameters,
|
||||||
references: List<StateAndRef<ContractState>>,
|
references: List<StateAndRef<ContractState>>,
|
||||||
componentGroups: List<ComponentGroup>? = null,
|
componentGroups: List<ComponentGroup>? = null,
|
||||||
serializedInputs: List<SerializedStateAndRef>? = null,
|
serializedInputs: List<SerializedStateAndRef>? = null,
|
||||||
@ -121,6 +124,11 @@ private constructor(
|
|||||||
*/
|
*/
|
||||||
@Throws(TransactionVerificationException::class)
|
@Throws(TransactionVerificationException::class)
|
||||||
fun verify() {
|
fun verify() {
|
||||||
|
if (networkParameters == null) {
|
||||||
|
// For backwards compatibility only.
|
||||||
|
logger.warn("Network parameters on the LedgerTransaction with id: $id are null. Please don't use deprecated constructors of the LedgerTransaction. " +
|
||||||
|
"Use WireTransaction.toLedgerTransaction instead. The result of the verify method might not be accurate.")
|
||||||
|
}
|
||||||
val contractAttachmentsByContract: Map<ContractClassName, ContractAttachment> = getUniqueContractAttachmentsByContract()
|
val contractAttachmentsByContract: Map<ContractClassName, ContractAttachment> = getUniqueContractAttachmentsByContract()
|
||||||
|
|
||||||
AttachmentsClassLoaderBuilder.withAttachmentsClassloaderContext(this.attachments) { transactionClassLoader ->
|
AttachmentsClassLoaderBuilder.withAttachmentsClassloaderContext(this.attachments) { transactionClassLoader ->
|
||||||
@ -169,14 +177,14 @@ private constructor(
|
|||||||
/**
|
/**
|
||||||
* Verify that for each contract the network wide package owner is respected.
|
* Verify that for each contract the network wide package owner is respected.
|
||||||
*
|
*
|
||||||
* TODO - revisit once transaction contains network parameters.
|
* TODO - revisit once transaction contains network parameters. - UPDATE: It contains them, but because of the API stability and the fact that
|
||||||
|
* LedgerTransaction was data class i.e. exposed constructors that shouldn't had been exposed, we still need to keep them nullable :/
|
||||||
*/
|
*/
|
||||||
private fun validatePackageOwnership(contractAttachmentsByContract: Map<ContractClassName, ContractAttachment>) {
|
private fun validatePackageOwnership(contractAttachmentsByContract: Map<ContractClassName, ContractAttachment>) {
|
||||||
// This should never happen once we have network parameters in the transaction.
|
// This should never happen once we have network parameters in the transaction.
|
||||||
if (networkParameters == null) {
|
if (networkParameters == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val contractsAndOwners = allStates.mapNotNull { transactionState ->
|
val contractsAndOwners = allStates.mapNotNull { transactionState ->
|
||||||
val contractClassName = transactionState.contract
|
val contractClassName = transactionState.contract
|
||||||
networkParameters.getOwnerOf(contractClassName)?.let { contractClassName to it }
|
networkParameters.getOwnerOf(contractClassName)?.let { contractClassName to it }
|
||||||
@ -243,7 +251,6 @@ private constructor(
|
|||||||
|
|
||||||
if (state.constraint is SignatureAttachmentConstraint)
|
if (state.constraint is SignatureAttachmentConstraint)
|
||||||
checkMinimumPlatformVersion(networkParameters?.minimumPlatformVersion ?: 1, 4, "Signature constraints")
|
checkMinimumPlatformVersion(networkParameters?.minimumPlatformVersion ?: 1, 4, "Signature constraints")
|
||||||
|
|
||||||
if (!state.constraint.isSatisfiedBy(constraintAttachment)) {
|
if (!state.constraint.isSatisfiedBy(constraintAttachment)) {
|
||||||
throw TransactionVerificationException.ContractConstraintRejection(id, state.contract)
|
throw TransactionVerificationException.ContractConstraintRejection(id, state.contract)
|
||||||
}
|
}
|
||||||
@ -806,11 +813,8 @@ private constructor(
|
|||||||
|)""".trimMargin()
|
|)""".trimMargin()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Stuff that we can't remove and so is deprecated instead
|
// Stuff that we can't remove and so is deprecated instead
|
||||||
//
|
//
|
||||||
|
|
||||||
@Deprecated("LedgerTransaction should not be created directly, use WireTransaction.toLedgerTransaction instead.")
|
@Deprecated("LedgerTransaction should not be created directly, use WireTransaction.toLedgerTransaction instead.")
|
||||||
constructor(
|
constructor(
|
||||||
inputs: List<StateAndRef<ContractState>>,
|
inputs: List<StateAndRef<ContractState>>,
|
||||||
@ -834,7 +838,7 @@ private constructor(
|
|||||||
notary: Party?,
|
notary: Party?,
|
||||||
timeWindow: TimeWindow?,
|
timeWindow: TimeWindow?,
|
||||||
privacySalt: PrivacySalt,
|
privacySalt: PrivacySalt,
|
||||||
networkParameters: NetworkParameters?
|
networkParameters: NetworkParameters
|
||||||
) : this(inputs, outputs, commands, attachments, id, notary, timeWindow, privacySalt, networkParameters, emptyList())
|
) : this(inputs, outputs, commands, attachments, id, notary, timeWindow, privacySalt, networkParameters, emptyList())
|
||||||
|
|
||||||
@Deprecated("LedgerTransactions should not be created directly, use WireTransaction.toLedgerTransaction instead.")
|
@Deprecated("LedgerTransactions should not be created directly, use WireTransaction.toLedgerTransaction instead.")
|
||||||
|
@ -48,6 +48,12 @@ abstract class TraversableTransaction(open val componentGroups: List<ComponentGr
|
|||||||
timeWindows.firstOrNull()
|
timeWindows.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val networkParametersHash: SecureHash? = let {
|
||||||
|
val parametersHashes = deserialiseComponentGroup(componentGroups, SecureHash::class, PARAMETERS_GROUP)
|
||||||
|
check(parametersHashes.size <= 1) { "Invalid Transaction. More than 1 network parameters hash detected." }
|
||||||
|
parametersHashes.firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all the component groups that are present in the transaction, excluding the privacySalt,
|
* Returns a list of all the component groups that are present in the transaction, excluding the privacySalt,
|
||||||
* in the following order (which is the same with the order in [ComponentGroupEnum]:
|
* in the following order (which is the same with the order in [ComponentGroupEnum]:
|
||||||
@ -58,12 +64,14 @@ abstract class TraversableTransaction(open val componentGroups: List<ComponentGr
|
|||||||
* - The notary [Party], if present (list with one element)
|
* - The notary [Party], if present (list with one element)
|
||||||
* - The time-window of the transaction, if present (list with one element)
|
* - The time-window of the transaction, if present (list with one element)
|
||||||
* - list of each reference input that is present
|
* - list of each reference input that is present
|
||||||
|
* - network parameters hash if present
|
||||||
*/
|
*/
|
||||||
val availableComponentGroups: List<List<Any>>
|
val availableComponentGroups: List<List<Any>>
|
||||||
get() {
|
get() {
|
||||||
val result = mutableListOf(inputs, outputs, commands, attachments, references)
|
val result = mutableListOf(inputs, outputs, commands, attachments, references)
|
||||||
notary?.let { result += listOf(it) }
|
notary?.let { result += listOf(it) }
|
||||||
timeWindow?.let { result += listOf(it) }
|
timeWindow?.let { result += listOf(it) }
|
||||||
|
networkParametersHash?.let { result += listOf(it) }
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,7 +157,9 @@ class FilteredTransaction internal constructor(
|
|||||||
if (wtx.timeWindow != null) filter(wtx.timeWindow, TIMEWINDOW_GROUP.ordinal, 0)
|
if (wtx.timeWindow != null) filter(wtx.timeWindow, TIMEWINDOW_GROUP.ordinal, 0)
|
||||||
// Note that because [inputs] and [references] share the same type [StateRef], we use a wrapper for references [ReferenceStateRef],
|
// Note that because [inputs] and [references] share the same type [StateRef], we use a wrapper for references [ReferenceStateRef],
|
||||||
// when filtering. Thus, to filter-in all [references] based on type, one should use the wrapper type [ReferenceStateRef] and not [StateRef].
|
// when filtering. Thus, to filter-in all [references] based on type, one should use the wrapper type [ReferenceStateRef] and not [StateRef].
|
||||||
|
// Similar situation is for network parameters hash and attachments, one should use wrapper [NetworkParametersHash] and not [SecureHash].
|
||||||
wtx.references.forEachIndexed { internalIndex, it -> filter(ReferenceStateRef(it), REFERENCES_GROUP.ordinal, internalIndex) }
|
wtx.references.forEachIndexed { internalIndex, it -> filter(ReferenceStateRef(it), REFERENCES_GROUP.ordinal, internalIndex) }
|
||||||
|
wtx.networkParametersHash?.let { filter(NetworkParametersHash(it), PARAMETERS_GROUP.ordinal, 0) }
|
||||||
// It is highlighted that because there is no a signers property in TraversableTransaction,
|
// It is highlighted that because there is no a signers property in TraversableTransaction,
|
||||||
// one cannot specifically filter them in or out.
|
// one cannot specifically filter them in or out.
|
||||||
// The above is very important to ensure someone won't filter out the signers component group if at least one
|
// The above is very important to ensure someone won't filter out the signers component group if at least one
|
||||||
@ -351,3 +361,8 @@ class FilteredTransactionVerificationException(val id: SecureHash, val reason: S
|
|||||||
@KeepForDJVM
|
@KeepForDJVM
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class ReferenceStateRef(val stateRef: StateRef)
|
data class ReferenceStateRef(val stateRef: StateRef)
|
||||||
|
|
||||||
|
/** Wrapper over [SecureHash] to be used when filtering network parameters hash. */
|
||||||
|
@KeepForDJVM
|
||||||
|
@CordaSerializable
|
||||||
|
data class NetworkParametersHash(val hash: SecureHash)
|
@ -8,6 +8,7 @@ import net.corda.core.crypto.SecureHash
|
|||||||
import net.corda.core.crypto.TransactionSignature
|
import net.corda.core.crypto.TransactionSignature
|
||||||
import net.corda.core.crypto.sha256
|
import net.corda.core.crypto.sha256
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
@ -37,9 +38,16 @@ data class NotaryChangeWireTransaction(
|
|||||||
override val inputs: List<StateRef> = serializedComponents[INPUTS.ordinal].deserialize()
|
override val inputs: List<StateRef> = serializedComponents[INPUTS.ordinal].deserialize()
|
||||||
override val references: List<StateRef> = emptyList()
|
override val references: List<StateRef> = emptyList()
|
||||||
override val notary: Party = serializedComponents[NOTARY.ordinal].deserialize()
|
override val notary: Party = serializedComponents[NOTARY.ordinal].deserialize()
|
||||||
|
|
||||||
/** Identity of the notary service to reassign the states to.*/
|
/** Identity of the notary service to reassign the states to.*/
|
||||||
val newNotary: Party = serializedComponents[NEW_NOTARY.ordinal].deserialize()
|
val newNotary: Party = serializedComponents[NEW_NOTARY.ordinal].deserialize()
|
||||||
|
|
||||||
|
override val networkParametersHash: SecureHash? by lazy {
|
||||||
|
if (serializedComponents.size >= PARAMETERS_HASH.ordinal + 1) {
|
||||||
|
serializedComponents[PARAMETERS_HASH.ordinal].deserialize<SecureHash>()
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This transaction does not contain any output states, outputs can be obtained by resolving a
|
* This transaction does not contain any output states, outputs can be obtained by resolving a
|
||||||
* [NotaryChangeLedgerTransaction] and applying the notary modification to inputs.
|
* [NotaryChangeLedgerTransaction] and applying the notary modification to inputs.
|
||||||
@ -66,11 +74,14 @@ data class NotaryChangeWireTransaction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolves input states and builds a [NotaryChangeLedgerTransaction]. */
|
/** Resolves input states and network parameters and builds a [NotaryChangeLedgerTransaction]. */
|
||||||
@DeleteForDJVM
|
@DeleteForDJVM
|
||||||
fun resolve(services: ServicesForResolution, sigs: List<TransactionSignature>): NotaryChangeLedgerTransaction {
|
fun resolve(services: ServicesForResolution, sigs: List<TransactionSignature>): NotaryChangeLedgerTransaction {
|
||||||
val resolvedInputs = services.loadStates(inputs.toSet()).toList()
|
val resolvedInputs = services.loadStates(inputs.toSet()).toList()
|
||||||
return NotaryChangeLedgerTransaction(resolvedInputs, notary, newNotary, id, sigs)
|
val hashToResolve = networkParametersHash ?: services.networkParametersStorage.defaultHash
|
||||||
|
val resolvedNetworkParameters = services.networkParametersStorage.lookup(hashToResolve)
|
||||||
|
?: throw TransactionResolutionException(id)
|
||||||
|
return NotaryChangeLedgerTransaction.create(resolvedInputs, notary, newNotary, id, sigs, resolvedNetworkParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolves input states and builds a [NotaryChangeLedgerTransaction]. */
|
/** Resolves input states and builds a [NotaryChangeLedgerTransaction]. */
|
||||||
@ -92,7 +103,7 @@ data class NotaryChangeWireTransaction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class Component {
|
enum class Component {
|
||||||
INPUTS, NOTARY, NEW_NOTARY
|
INPUTS, NOTARY, NEW_NOTARY, PARAMETERS_HASH
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Required only for backwards compatibility purposes. This type of transaction should not be constructed outside Corda code.", ReplaceWith("NotaryChangeTransactionBuilder"), DeprecationLevel.WARNING)
|
@Deprecated("Required only for backwards compatibility purposes. This type of transaction should not be constructed outside Corda code.", ReplaceWith("NotaryChangeTransactionBuilder"), DeprecationLevel.WARNING)
|
||||||
@ -105,13 +116,29 @@ data class NotaryChangeWireTransaction(
|
|||||||
* needed for signature verification.
|
* needed for signature verification.
|
||||||
*/
|
*/
|
||||||
@KeepForDJVM
|
@KeepForDJVM
|
||||||
data class NotaryChangeLedgerTransaction(
|
class NotaryChangeLedgerTransaction
|
||||||
|
private constructor(
|
||||||
override val inputs: List<StateAndRef<ContractState>>,
|
override val inputs: List<StateAndRef<ContractState>>,
|
||||||
override val notary: Party,
|
override val notary: Party,
|
||||||
val newNotary: Party,
|
val newNotary: Party,
|
||||||
override val id: SecureHash,
|
override val id: SecureHash,
|
||||||
override val sigs: List<TransactionSignature>
|
override val sigs: List<TransactionSignature>,
|
||||||
|
// TODO Network parameters should never be null on NotaryChangeLedgerTransaction, this is left only because of deprecated constructors. We should decide to
|
||||||
|
// get rid of them.
|
||||||
|
override val networkParameters: NetworkParameters?
|
||||||
) : FullTransaction(), TransactionWithSignatures {
|
) : FullTransaction(), TransactionWithSignatures {
|
||||||
|
companion object {
|
||||||
|
@CordaInternal
|
||||||
|
internal fun create(inputs: List<StateAndRef<ContractState>>,
|
||||||
|
notary: Party,
|
||||||
|
newNotary: Party,
|
||||||
|
id: SecureHash,
|
||||||
|
sigs: List<TransactionSignature>,
|
||||||
|
networkParameters: NetworkParameters): NotaryChangeLedgerTransaction {
|
||||||
|
return NotaryChangeLedgerTransaction(inputs, notary, newNotary, id, sigs, networkParameters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
checkEncumbrances()
|
checkEncumbrances()
|
||||||
}
|
}
|
||||||
@ -157,4 +184,54 @@ data class NotaryChangeLedgerTransaction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun component1(): List<StateAndRef<ContractState>> = inputs
|
||||||
|
operator fun component2(): Party = notary
|
||||||
|
operator fun component3(): Party = newNotary
|
||||||
|
operator fun component4(): SecureHash = id
|
||||||
|
operator fun component5(): List<TransactionSignature> = sigs
|
||||||
|
operator fun component6(): NetworkParameters? = networkParameters
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean = this === other || other is NotaryChangeLedgerTransaction && this.id == other.id
|
||||||
|
|
||||||
|
override fun hashCode(): Int = id.hashCode()
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return """NotaryChangeLedgerTransaction(
|
||||||
|
| id=$id
|
||||||
|
| inputs=$inputs
|
||||||
|
| notary=$notary
|
||||||
|
| newNotary=$newNotary
|
||||||
|
| sigs=$sigs
|
||||||
|
| networkParameters=$networkParameters
|
||||||
|
|)""".trimMargin()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Things that we can't remove after `data class` removal from this class, so it is deprecated instead.
|
||||||
|
//
|
||||||
|
@Deprecated("NotaryChangeLedgerTransaction should not be created directly, use NotaryChangeWireTransaction.resolve instead.")
|
||||||
|
constructor(
|
||||||
|
inputs: List<StateAndRef<ContractState>>,
|
||||||
|
notary: Party,
|
||||||
|
newNotary: Party,
|
||||||
|
id: SecureHash,
|
||||||
|
sigs: List<TransactionSignature>
|
||||||
|
) : this(inputs, notary, newNotary, id, sigs, null)
|
||||||
|
|
||||||
|
@Deprecated("NotaryChangeLedgerTransaction should not be created directly, use NotaryChangeWireTransaction.resolve instead.")
|
||||||
|
fun copy(inputs: List<StateAndRef<ContractState>> = this.inputs,
|
||||||
|
notary: Party = this.notary,
|
||||||
|
newNotary: Party = this.newNotary,
|
||||||
|
id: SecureHash = this.id,
|
||||||
|
sigs: List<TransactionSignature> = this.sigs
|
||||||
|
): NotaryChangeLedgerTransaction {
|
||||||
|
return NotaryChangeLedgerTransaction(
|
||||||
|
inputs,
|
||||||
|
notary,
|
||||||
|
newNotary,
|
||||||
|
id,
|
||||||
|
sigs,
|
||||||
|
this.networkParameters
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,8 @@ data class SignedTransaction(val txBits: SerializedBytes<CoreTransaction>,
|
|||||||
val references: List<StateRef> get() = coreTransaction.references
|
val references: List<StateRef> get() = coreTransaction.references
|
||||||
/** Helper to access the notary of the contained transaction. */
|
/** Helper to access the notary of the contained transaction. */
|
||||||
val notary: Party? get() = coreTransaction.notary
|
val notary: Party? get() = coreTransaction.notary
|
||||||
|
/** Helper to access the network parameters hash for the contained transaction. */
|
||||||
|
val networkParametersHash: SecureHash? get() = coreTransaction.networkParametersHash
|
||||||
|
|
||||||
override val requiredSigningKeys: Set<PublicKey> get() = tx.requiredSigningKeys
|
override val requiredSigningKeys: Set<PublicKey> get() = tx.requiredSigningKeys
|
||||||
|
|
||||||
|
@ -167,8 +167,8 @@ open class TransactionBuilder @JvmOverloads constructor(
|
|||||||
(allContractAttachments + attachments).toSortedSet().toList(), // Sort the attachments to ensure transaction builds are stable.
|
(allContractAttachments + attachments).toSortedSet().toList(), // Sort the attachments to ensure transaction builds are stable.
|
||||||
notary,
|
notary,
|
||||||
window,
|
window,
|
||||||
referenceStates
|
referenceStates,
|
||||||
),
|
services.networkParametersStorage.currentHash),
|
||||||
privacySalt
|
privacySalt
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
notary: Party?,
|
notary: Party?,
|
||||||
timeWindow: TimeWindow?,
|
timeWindow: TimeWindow?,
|
||||||
privacySalt: PrivacySalt = PrivacySalt()
|
privacySalt: PrivacySalt = PrivacySalt()
|
||||||
) : this(createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow, emptyList()), privacySalt)
|
) : this(createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow, emptyList(), null), privacySalt)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
check(componentGroups.all { it.components.isNotEmpty() }) { "Empty component groups are not allowed" }
|
check(componentGroups.all { it.components.isNotEmpty() }) { "Empty component groups are not allowed" }
|
||||||
@ -106,7 +106,10 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
resolveIdentity = { services.identityService.partyFromKey(it) },
|
resolveIdentity = { services.identityService.partyFromKey(it) },
|
||||||
resolveAttachment = { services.attachments.openAttachment(it) },
|
resolveAttachment = { services.attachments.openAttachment(it) },
|
||||||
resolveStateRefAsSerialized = { resolveStateRefBinaryComponent(it, services) },
|
resolveStateRefAsSerialized = { resolveStateRefBinaryComponent(it, services) },
|
||||||
networkParameters = services.networkParameters
|
resolveParameters = {
|
||||||
|
val hashToResolve = it ?: services.networkParametersStorage.defaultHash
|
||||||
|
services.networkParametersStorage.lookup(hashToResolve)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,21 +122,24 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
*/
|
*/
|
||||||
@Deprecated("Use toLedgerTransaction(ServicesForTransaction) instead")
|
@Deprecated("Use toLedgerTransaction(ServicesForTransaction) instead")
|
||||||
@Throws(AttachmentResolutionException::class, TransactionResolutionException::class)
|
@Throws(AttachmentResolutionException::class, TransactionResolutionException::class)
|
||||||
|
@JvmOverloads
|
||||||
fun toLedgerTransaction(
|
fun toLedgerTransaction(
|
||||||
resolveIdentity: (PublicKey) -> Party?,
|
resolveIdentity: (PublicKey) -> Party?,
|
||||||
resolveAttachment: (SecureHash) -> Attachment?,
|
resolveAttachment: (SecureHash) -> Attachment?,
|
||||||
resolveStateRef: (StateRef) -> TransactionState<*>?,
|
resolveStateRef: (StateRef) -> TransactionState<*>?,
|
||||||
@Suppress("UNUSED_PARAMETER") resolveContractAttachment: (TransactionState<ContractState>) -> AttachmentId?
|
@Suppress("UNUSED_PARAMETER") resolveContractAttachment: (TransactionState<ContractState>) -> AttachmentId?,
|
||||||
|
resolveParameters: (SecureHash?) -> NetworkParameters? = { null } // TODO This { null } is left here only because of API stability. It doesn't make much sense anymore as it will fail on transaction verification.
|
||||||
): LedgerTransaction {
|
): LedgerTransaction {
|
||||||
// This reverts to serializing the resolved transaction state.
|
// This reverts to serializing the resolved transaction state.
|
||||||
return toLedgerTransactionInternal(resolveIdentity, resolveAttachment, { stateRef -> resolveStateRef(stateRef)?.serialize() }, null)
|
return toLedgerTransactionInternal(resolveIdentity, resolveAttachment, { stateRef -> resolveStateRef(stateRef)?.serialize() }, resolveParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun toLedgerTransactionInternal(
|
private fun toLedgerTransactionInternal(
|
||||||
resolveIdentity: (PublicKey) -> Party?,
|
resolveIdentity: (PublicKey) -> Party?,
|
||||||
resolveAttachment: (SecureHash) -> Attachment?,
|
resolveAttachment: (SecureHash) -> Attachment?,
|
||||||
resolveStateRefAsSerialized: (StateRef) -> SerializedBytes<TransactionState<ContractState>>?,
|
resolveStateRefAsSerialized: (StateRef) -> SerializedBytes<TransactionState<ContractState>>?,
|
||||||
networkParameters: NetworkParameters?
|
resolveParameters: (SecureHash?) -> NetworkParameters?
|
||||||
): LedgerTransaction {
|
): LedgerTransaction {
|
||||||
// Look up public keys to authenticated identities.
|
// Look up public keys to authenticated identities.
|
||||||
val authenticatedCommands = commands.lazyMapped { cmd, _ ->
|
val authenticatedCommands = commands.lazyMapped { cmd, _ ->
|
||||||
@ -153,6 +159,8 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
|
|
||||||
val resolvedAttachments = attachments.lazyMapped { att, _ -> resolveAttachment(att) ?: throw AttachmentResolutionException(att) }
|
val resolvedAttachments = attachments.lazyMapped { att, _ -> resolveAttachment(att) ?: throw AttachmentResolutionException(att) }
|
||||||
|
|
||||||
|
val resolvedNetworkParameters = resolveParameters(networkParametersHash) ?: throw TransactionResolutionException(id)
|
||||||
|
|
||||||
val ltx = LedgerTransaction.create(
|
val ltx = LedgerTransaction.create(
|
||||||
resolvedInputs,
|
resolvedInputs,
|
||||||
outputs,
|
outputs,
|
||||||
@ -162,14 +170,14 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
notary,
|
notary,
|
||||||
timeWindow,
|
timeWindow,
|
||||||
privacySalt,
|
privacySalt,
|
||||||
networkParameters,
|
resolvedNetworkParameters,
|
||||||
resolvedReferences,
|
resolvedReferences,
|
||||||
componentGroups,
|
componentGroups,
|
||||||
serializedResolvedInputs,
|
serializedResolvedInputs,
|
||||||
serializedResolvedReferences
|
serializedResolvedReferences
|
||||||
)
|
)
|
||||||
|
|
||||||
checkTransactionSize(ltx, networkParameters?.maxTransactionSize ?: DEFAULT_MAX_TX_SIZE, serializedResolvedInputs, serializedResolvedReferences)
|
checkTransactionSize(ltx, resolvedNetworkParameters.maxTransactionSize, serializedResolvedInputs, serializedResolvedReferences)
|
||||||
|
|
||||||
return ltx
|
return ltx
|
||||||
}
|
}
|
||||||
@ -286,8 +294,6 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DEFAULT_MAX_TX_SIZE = 10485760
|
|
||||||
|
|
||||||
@CordaInternal
|
@CordaInternal
|
||||||
@Deprecated("Do not use, this is internal API")
|
@Deprecated("Do not use, this is internal API")
|
||||||
fun createComponentGroups(inputs: List<StateRef>,
|
fun createComponentGroups(inputs: List<StateRef>,
|
||||||
@ -296,7 +302,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
attachments: List<SecureHash>,
|
attachments: List<SecureHash>,
|
||||||
notary: Party?,
|
notary: Party?,
|
||||||
timeWindow: TimeWindow?): List<ComponentGroup> {
|
timeWindow: TimeWindow?): List<ComponentGroup> {
|
||||||
return createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow, emptyList())
|
return createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow, emptyList(), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -346,6 +352,9 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
|
|||||||
val emoji = Emoji.paperclip
|
val emoji = Emoji.paperclip
|
||||||
buf.appendln("${emoji}ATTACHMENT: $attachment")
|
buf.appendln("${emoji}ATTACHMENT: $attachment")
|
||||||
}
|
}
|
||||||
|
if (networkParametersHash != null) {
|
||||||
|
buf.appendln("PARAMETERS HASH: $networkParametersHash")
|
||||||
|
}
|
||||||
return buf.toString()
|
return buf.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,6 +162,7 @@ class PartialMerkleTreeTest {
|
|||||||
assertEquals(1, ftx.commands.size)
|
assertEquals(1, ftx.commands.size)
|
||||||
assertNull(ftx.notary)
|
assertNull(ftx.notary)
|
||||||
assertNotNull(ftx.timeWindow)
|
assertNotNull(ftx.timeWindow)
|
||||||
|
assertNull(ftx.networkParametersHash)
|
||||||
ftx.verify()
|
ftx.verify()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +187,7 @@ class PartialMerkleTreeTest {
|
|||||||
assertTrue(ftxNothing.outputs.isEmpty())
|
assertTrue(ftxNothing.outputs.isEmpty())
|
||||||
assertNull(ftxNothing.timeWindow)
|
assertNull(ftxNothing.timeWindow)
|
||||||
assertTrue(ftxNothing.availableComponentGroups.flatten().isEmpty())
|
assertTrue(ftxNothing.availableComponentGroups.flatten().isEmpty())
|
||||||
|
assertNull(ftxNothing.networkParametersHash)
|
||||||
ftxNothing.verify() // We allow empty ftx transactions (eg from a timestamp authority that blindly signs).
|
ftxNothing.verify() // We allow empty ftx transactions (eg from a timestamp authority that blindly signs).
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import net.corda.core.identity.Party
|
|||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.transactions.CoreTransaction
|
import net.corda.core.transactions.CoreTransaction
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
|
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 org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -31,6 +32,7 @@ class TopologicalSortTest {
|
|||||||
override val outputs: List<TransactionState<ContractState>> = (1..numberOfOutputs).map {
|
override val outputs: List<TransactionState<ContractState>> = (1..numberOfOutputs).map {
|
||||||
TransactionState(DummyState(), "", notary)
|
TransactionState(DummyState(), "", notary)
|
||||||
}
|
}
|
||||||
|
override val networkParametersHash: SecureHash? = testNetworkParameters().serialize().hash
|
||||||
}
|
}
|
||||||
|
|
||||||
class DummyState : ContractState {
|
class DummyState : ContractState {
|
||||||
|
@ -6,6 +6,7 @@ import net.corda.core.crypto.*
|
|||||||
import net.corda.core.internal.createComponentGroups
|
import net.corda.core.internal.createComponentGroups
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
import net.corda.testing.contracts.DummyState
|
import net.corda.testing.contracts.DummyState
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
@ -38,6 +39,7 @@ class CompatibleTransactionTests {
|
|||||||
private val notary = DUMMY_NOTARY
|
private val notary = DUMMY_NOTARY
|
||||||
private val timeWindow = TimeWindow.fromOnly(Instant.now())
|
private val timeWindow = TimeWindow.fromOnly(Instant.now())
|
||||||
private val privacySalt: PrivacySalt = PrivacySalt()
|
private val privacySalt: PrivacySalt = PrivacySalt()
|
||||||
|
private val paramsHash = SecureHash.randomSHA256()
|
||||||
|
|
||||||
private val inputGroup by lazy { ComponentGroup(INPUTS_GROUP.ordinal, inputs.map { it.serialize() }) }
|
private val inputGroup by lazy { ComponentGroup(INPUTS_GROUP.ordinal, inputs.map { it.serialize() }) }
|
||||||
private val outputGroup by lazy { ComponentGroup(OUTPUTS_GROUP.ordinal, outputs.map { it.serialize() }) }
|
private val outputGroup by lazy { ComponentGroup(OUTPUTS_GROUP.ordinal, outputs.map { it.serialize() }) }
|
||||||
@ -46,6 +48,7 @@ class CompatibleTransactionTests {
|
|||||||
private val notaryGroup by lazy { ComponentGroup(NOTARY_GROUP.ordinal, listOf(notary.serialize())) }
|
private val notaryGroup by lazy { ComponentGroup(NOTARY_GROUP.ordinal, listOf(notary.serialize())) }
|
||||||
private val timeWindowGroup by lazy { ComponentGroup(TIMEWINDOW_GROUP.ordinal, listOf(timeWindow.serialize())) }
|
private val timeWindowGroup by lazy { ComponentGroup(TIMEWINDOW_GROUP.ordinal, listOf(timeWindow.serialize())) }
|
||||||
private val signersGroup by lazy { ComponentGroup(SIGNERS_GROUP.ordinal, commands.map { it.signers.serialize() }) }
|
private val signersGroup by lazy { ComponentGroup(SIGNERS_GROUP.ordinal, commands.map { it.signers.serialize() }) }
|
||||||
|
private val networkParamsGroup by lazy { ComponentGroup(PARAMETERS_GROUP.ordinal, listOf(paramsHash.serialize())) }
|
||||||
|
|
||||||
private val newUnknownComponentGroup = ComponentGroup(100, listOf(OpaqueBytes(secureRandomBytes(4)), OpaqueBytes(secureRandomBytes(8))))
|
private val newUnknownComponentGroup = ComponentGroup(100, listOf(OpaqueBytes(secureRandomBytes(4)), OpaqueBytes(secureRandomBytes(8))))
|
||||||
private val newUnknownComponentEmptyGroup = ComponentGroup(101, emptyList())
|
private val newUnknownComponentEmptyGroup = ComponentGroup(101, emptyList())
|
||||||
@ -125,7 +128,7 @@ class CompatibleTransactionTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `WireTransaction constructors and compatibility`() {
|
fun `WireTransaction constructors and compatibility`() {
|
||||||
val groups = createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow, emptyList())
|
val groups = createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow, emptyList(), null)
|
||||||
val wireTransactionOldConstructor = WireTransaction(groups, privacySalt)
|
val wireTransactionOldConstructor = WireTransaction(groups, privacySalt)
|
||||||
assertEquals(wireTransactionA, wireTransactionOldConstructor)
|
assertEquals(wireTransactionA, wireTransactionOldConstructor)
|
||||||
|
|
||||||
@ -211,6 +214,7 @@ class CompatibleTransactionTests {
|
|||||||
ftxAll.checkAllComponentsVisible(NOTARY_GROUP)
|
ftxAll.checkAllComponentsVisible(NOTARY_GROUP)
|
||||||
ftxAll.checkAllComponentsVisible(TIMEWINDOW_GROUP)
|
ftxAll.checkAllComponentsVisible(TIMEWINDOW_GROUP)
|
||||||
ftxAll.checkAllComponentsVisible(SIGNERS_GROUP)
|
ftxAll.checkAllComponentsVisible(SIGNERS_GROUP)
|
||||||
|
ftxAll.checkAllComponentsVisible(PARAMETERS_GROUP)
|
||||||
|
|
||||||
// Filter inputs only.
|
// Filter inputs only.
|
||||||
fun filtering(elem: Any): Boolean {
|
fun filtering(elem: Any): Boolean {
|
||||||
@ -261,6 +265,8 @@ class CompatibleTransactionTests {
|
|||||||
assertEquals(3, ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.components.size)
|
assertEquals(3, ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.components.size)
|
||||||
assertEquals(3, ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.nonces.size)
|
assertEquals(3, ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.nonces.size)
|
||||||
assertNotNull(ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.partialMerkleTree)
|
assertNotNull(ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.partialMerkleTree)
|
||||||
|
assertNull(wireTransactionCompatibleA.networkParametersHash)
|
||||||
|
assertNull(ftxCompatible.networkParametersHash)
|
||||||
|
|
||||||
// Now, let's allow everything, including the new component type that we cannot process.
|
// Now, let's allow everything, including the new component type that we cannot process.
|
||||||
val ftxCompatibleAll = wireTransactionCompatibleA.buildFilteredTransaction(Predicate { true }) // All filtered, including the unknown component.
|
val ftxCompatibleAll = wireTransactionCompatibleA.buildFilteredTransaction(Predicate { true }) // All filtered, including the unknown component.
|
||||||
@ -547,5 +553,34 @@ class CompatibleTransactionTests {
|
|||||||
// Also, checkAllComponentsVisible() will not pass (top level Merkle tree cannot be verified against transaction's id).
|
// Also, checkAllComponentsVisible() will not pass (top level Merkle tree cannot be verified against transaction's id).
|
||||||
assertFailsWith<ComponentVisibilityException> { ftxAlterSignerB.checkCommandVisibility(DUMMY_KEY_1.public) }
|
assertFailsWith<ComponentVisibilityException> { ftxAlterSignerB.checkCommandVisibility(DUMMY_KEY_1.public) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `parameters hash visibility`() {
|
||||||
|
fun paramsFilter(elem: Any): Boolean = elem is NetworkParametersHash && elem.hash == paramsHash
|
||||||
|
fun attachmentFilter(elem: Any): Boolean = elem is SecureHash && elem == paramsHash
|
||||||
|
val attachments = ComponentGroup(ATTACHMENTS_GROUP.ordinal, listOf(paramsHash.serialize())) // Same hash as network parameters
|
||||||
|
val componentGroups = listOf(
|
||||||
|
inputGroup,
|
||||||
|
outputGroup,
|
||||||
|
attachments,
|
||||||
|
commandGroup,
|
||||||
|
notaryGroup,
|
||||||
|
timeWindowGroup,
|
||||||
|
signersGroup,
|
||||||
|
networkParamsGroup
|
||||||
|
)
|
||||||
|
val wtx = WireTransaction(componentGroups, privacySalt)
|
||||||
|
val ftx1 = wtx.buildFilteredTransaction(Predicate(::paramsFilter)) // Filter only network parameters hash.
|
||||||
|
ftx1.verify()
|
||||||
|
assertEquals(wtx.id, ftx1.id)
|
||||||
|
ftx1.checkAllComponentsVisible(PARAMETERS_GROUP)
|
||||||
|
assertFailsWith<ComponentVisibilityException> { ftx1.checkAllComponentsVisible(ATTACHMENTS_GROUP) }
|
||||||
|
// Filter only attachment.
|
||||||
|
val ftx2 = wtx.buildFilteredTransaction(Predicate(::attachmentFilter))
|
||||||
|
ftx2.verify()
|
||||||
|
assertEquals(wtx.id, ftx2.id)
|
||||||
|
ftx2.checkAllComponentsVisible(ATTACHMENTS_GROUP)
|
||||||
|
assertFailsWith<ComponentVisibilityException> { ftx2.checkAllComponentsVisible(PARAMETERS_GROUP) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ import net.corda.core.internal.PLATFORM_VERSION
|
|||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
import net.corda.core.node.ZoneVersionTooLowException
|
import net.corda.core.node.ZoneVersionTooLowException
|
||||||
import net.corda.core.node.services.AttachmentStorage
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
|
import net.corda.core.node.services.NetworkParametersStorage
|
||||||
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
import net.corda.testing.contracts.DummyState
|
import net.corda.testing.contracts.DummyState
|
||||||
@ -35,13 +37,17 @@ class TransactionBuilderTest {
|
|||||||
private val services = rigorousMock<ServicesForResolution>()
|
private val services = rigorousMock<ServicesForResolution>()
|
||||||
private val contractAttachmentId = SecureHash.randomSHA256()
|
private val contractAttachmentId = SecureHash.randomSHA256()
|
||||||
private val attachments = rigorousMock<AttachmentStorage>()
|
private val attachments = rigorousMock<AttachmentStorage>()
|
||||||
|
private val networkParametersStorage = rigorousMock<NetworkParametersStorage>()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
val cordappProvider = rigorousMock<CordappProvider>()
|
val cordappProvider = rigorousMock<CordappProvider>()
|
||||||
|
val networkParameters = testNetworkParameters(minimumPlatformVersion = PLATFORM_VERSION)
|
||||||
|
doReturn(networkParametersStorage).whenever(services).networkParametersStorage
|
||||||
|
doReturn(networkParameters.serialize().hash).whenever(networkParametersStorage).currentHash
|
||||||
doReturn(cordappProvider).whenever(services).cordappProvider
|
doReturn(cordappProvider).whenever(services).cordappProvider
|
||||||
doReturn(contractAttachmentId).whenever(cordappProvider).getContractAttachmentID(DummyContract.PROGRAM_ID)
|
doReturn(contractAttachmentId).whenever(cordappProvider).getContractAttachmentID(DummyContract.PROGRAM_ID)
|
||||||
doReturn(testNetworkParameters(minimumPlatformVersion = PLATFORM_VERSION)).whenever(services).networkParameters
|
doReturn(networkParameters).whenever(services).networkParameters
|
||||||
|
|
||||||
val attachmentStorage = rigorousMock<AttachmentStorage>()
|
val attachmentStorage = rigorousMock<AttachmentStorage>()
|
||||||
doReturn(attachmentStorage).whenever(services).attachments
|
doReturn(attachmentStorage).whenever(services).attachments
|
||||||
@ -67,6 +73,7 @@ class TransactionBuilderTest {
|
|||||||
val wtx = builder.toWireTransaction(services)
|
val wtx = builder.toWireTransaction(services)
|
||||||
assertThat(wtx.outputs).containsOnly(outputState)
|
assertThat(wtx.outputs).containsOnly(outputState)
|
||||||
assertThat(wtx.commands).containsOnly(Command(DummyCommandData, notary.owningKey))
|
assertThat(wtx.commands).containsOnly(Command(DummyCommandData, notary.owningKey))
|
||||||
|
assertThat(wtx.networkParametersHash).isEqualTo(networkParametersStorage.currentHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -176,7 +176,7 @@ class TransactionTests {
|
|||||||
notary,
|
notary,
|
||||||
timeWindow,
|
timeWindow,
|
||||||
privacySalt,
|
privacySalt,
|
||||||
null,
|
testNetworkParameters(),
|
||||||
emptyList()
|
emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
|||||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import net.corda.testing.node.internal.FINANCE_CORDAPP
|
import net.corda.testing.node.internal.FINANCE_CORDAPP
|
||||||
import net.corda.testing.node.internal.TestCordappDirectories
|
import net.corda.testing.node.internal.TestCordappDirectories
|
||||||
@ -54,7 +54,7 @@ class FlowWorkerStartStopTest {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val serializationEnvironment = SerializationEnvironmentRule(true)
|
val serializationEnvironment = SerializationEnvironmentRule(true)
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
|||||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import net.corda.testing.node.internal.FINANCE_CORDAPP
|
import net.corda.testing.node.internal.FINANCE_CORDAPP
|
||||||
import net.corda.testing.node.internal.TestCordappDirectories
|
import net.corda.testing.node.internal.TestCordappDirectories
|
||||||
@ -53,7 +53,7 @@ class FlowWorkerTest {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val serializationEnvironment = SerializationEnvironmentRule(true)
|
val serializationEnvironment = SerializationEnvironmentRule(true)
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val networkParameters = NetworkParameters(
|
private val networkParameters = NetworkParameters(
|
||||||
|
@ -15,8 +15,12 @@ import net.corda.finance.flows.CashIssueFlow
|
|||||||
import net.corda.finance.flows.CashPaymentFlow
|
import net.corda.finance.flows.CashPaymentFlow
|
||||||
import net.corda.node.services.Permissions.Companion.invokeRpc
|
import net.corda.node.services.Permissions.Companion.invokeRpc
|
||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.driver.*
|
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||||
|
import net.corda.testing.core.singleIdentity
|
||||||
|
import net.corda.testing.driver.NodeHandle
|
||||||
|
import net.corda.testing.driver.OutOfProcess
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
@ -67,7 +71,7 @@ class InstrumentationTest : IntegrationTest() {
|
|||||||
}
|
}
|
||||||
private fun setup(inMemoryDB: Boolean = true, testBlock: InternalDriverDSL.() -> Unit) {
|
private fun setup(inMemoryDB: Boolean = true, testBlock: InternalDriverDSL.() -> Unit) {
|
||||||
|
|
||||||
val portAllocation = PortAllocation.Incremental(10000)
|
val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
internalDriver(
|
internalDriver(
|
||||||
cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts", "net.corda.finance.schemas"),
|
cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts", "net.corda.finance.schemas"),
|
||||||
|
@ -7,7 +7,9 @@ import net.corda.core.contracts.withoutIssuer
|
|||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.*
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
|
import net.corda.core.utilities.contextLogger
|
||||||
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.finance.POUNDS
|
import net.corda.finance.POUNDS
|
||||||
import net.corda.finance.contracts.asset.Cash
|
import net.corda.finance.contracts.asset.Cash
|
||||||
import net.corda.finance.contracts.asset.OnLedgerAsset
|
import net.corda.finance.contracts.asset.OnLedgerAsset
|
||||||
@ -20,7 +22,7 @@ import net.corda.testing.core.ALICE_NAME
|
|||||||
import net.corda.testing.core.singleIdentity
|
import net.corda.testing.core.singleIdentity
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.OutOfProcess
|
import net.corda.testing.driver.OutOfProcess
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import net.corda.testing.node.internal.InternalDriverDSL
|
import net.corda.testing.node.internal.InternalDriverDSL
|
||||||
@ -101,7 +103,7 @@ class SystematicTerminationTest(private val terminationData: TerminationData) :
|
|||||||
|
|
||||||
private fun setup(testBlock: InternalDriverDSL.() -> Unit) {
|
private fun setup(testBlock: InternalDriverDSL.() -> Unit) {
|
||||||
|
|
||||||
val portAllocation = PortAllocation.Incremental(10000)
|
val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
internalDriver(
|
internalDriver(
|
||||||
cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts", "net.corda.finance.schemas"),
|
cordappsForAllNodes = cordappsForPackages("net.corda.finance.contracts", "net.corda.finance.schemas"),
|
||||||
|
@ -20,7 +20,7 @@ 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.ALICE_NAME
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.testing.internal.configureDatabase
|
import net.corda.testing.internal.configureDatabase
|
||||||
@ -45,7 +45,7 @@ class RaftTransactionCommitLogTests {
|
|||||||
val testSerialization = SerializationEnvironmentRule(true)
|
val testSerialization = SerializationEnvironmentRule(true)
|
||||||
|
|
||||||
private val databases: MutableList<CordaPersistence> = mutableListOf()
|
private val databases: MutableList<CordaPersistence> = mutableListOf()
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
private lateinit var cluster: List<Member>
|
private lateinit var cluster: List<Member>
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import java.nio.file.Path
|
|||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
import java.util.Collections.singleton
|
import java.util.Collections.singleton
|
||||||
|
|
||||||
// When scanning of the CorDapp Jar is performed without "corda-core.jar" being the in the classpath, there is no way to appreciate
|
// When scanning of the CorDapp Jar is performed without "corda-core.jar" being in the classpath, there is no way to appreciate
|
||||||
// relationships between those interfaces, therefore they have to be listed explicitly.
|
// relationships between those interfaces, therefore they have to be listed explicitly.
|
||||||
val coreContractClasses = setOf(Contract::class, UpgradedContractWithLegacyConstraint::class, UpgradedContract::class)
|
val coreContractClasses = setOf(Contract::class, UpgradedContractWithLegacyConstraint::class, UpgradedContract::class)
|
||||||
|
|
||||||
|
@ -4,13 +4,12 @@ import com.nhaarman.mockito_kotlin.any
|
|||||||
import com.nhaarman.mockito_kotlin.doReturn
|
import com.nhaarman.mockito_kotlin.doReturn
|
||||||
import com.nhaarman.mockito_kotlin.whenever
|
import com.nhaarman.mockito_kotlin.whenever
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.*
|
||||||
import net.corda.core.crypto.SecureHash
|
|
||||||
import net.corda.core.identity.AbstractParty
|
import net.corda.core.identity.AbstractParty
|
||||||
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.AbstractAttachment
|
|
||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
import net.corda.core.node.services.AttachmentStorage
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
|
import net.corda.core.node.services.NetworkParametersStorage
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.transactions.LedgerTransaction
|
import net.corda.core.transactions.LedgerTransaction
|
||||||
@ -67,19 +66,18 @@ class AttachmentsClassLoaderStaticContractTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val unsignedAttachment = object : AbstractAttachment({ byteArrayOf() }) {
|
private val networkParameters = testNetworkParameters()
|
||||||
override val id: SecureHash get() = throw UnsupportedOperationException()
|
|
||||||
|
private val networkParametersStorage get() = rigorousMock<NetworkParametersStorage>().also {
|
||||||
|
doReturn(networkParameters.serialize().hash).whenever(it).currentHash
|
||||||
}
|
}
|
||||||
|
|
||||||
private val attachments = rigorousMock<AttachmentStorage>().also {
|
private val serviceHub get() = rigorousMock<ServicesForResolution>().also {
|
||||||
doReturn(unsignedAttachment).whenever(it).openAttachment(any())
|
|
||||||
}
|
|
||||||
|
|
||||||
private val serviceHub = rigorousMock<ServicesForResolution>().also {
|
|
||||||
val cordappProviderImpl = CordappProviderImpl(cordappLoaderForPackages(listOf("net.corda.nodeapi.internal")), MockCordappConfigProvider(), MockAttachmentStorage())
|
val cordappProviderImpl = CordappProviderImpl(cordappLoaderForPackages(listOf("net.corda.nodeapi.internal")), MockCordappConfigProvider(), MockAttachmentStorage())
|
||||||
cordappProviderImpl.start(testNetworkParameters().whitelistedContractImplementations)
|
cordappProviderImpl.start(testNetworkParameters().whitelistedContractImplementations)
|
||||||
doReturn(cordappProviderImpl).whenever(it).cordappProvider
|
doReturn(cordappProviderImpl).whenever(it).cordappProvider
|
||||||
doReturn(testNetworkParameters()).whenever(it).networkParameters
|
doReturn(networkParametersStorage).whenever(it).networkParametersStorage
|
||||||
|
doReturn(networkParameters).whenever(it).networkParameters
|
||||||
val attachmentStorage = rigorousMock<AttachmentStorage>()
|
val attachmentStorage = rigorousMock<AttachmentStorage>()
|
||||||
doReturn(attachmentStorage).whenever(it).attachments
|
doReturn(attachmentStorage).whenever(it).attachments
|
||||||
val attachment = rigorousMock<ContractAttachment>()
|
val attachment = rigorousMock<ContractAttachment>()
|
||||||
|
@ -5,7 +5,6 @@ import io.netty.handler.ssl.ClientAuth
|
|||||||
import io.netty.handler.ssl.SslContextBuilder
|
import io.netty.handler.ssl.SslContextBuilder
|
||||||
import io.netty.handler.ssl.SslProvider
|
import io.netty.handler.ssl.SslProvider
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.*
|
|
||||||
import net.corda.core.crypto.Crypto.COMPOSITE_KEY
|
import net.corda.core.crypto.Crypto.COMPOSITE_KEY
|
||||||
import net.corda.core.crypto.Crypto.ECDSA_SECP256K1_SHA256
|
import net.corda.core.crypto.Crypto.ECDSA_SECP256K1_SHA256
|
||||||
import net.corda.core.crypto.Crypto.ECDSA_SECP256R1_SHA256
|
import net.corda.core.crypto.Crypto.ECDSA_SECP256R1_SHA256
|
||||||
@ -13,6 +12,8 @@ import net.corda.core.crypto.Crypto.EDDSA_ED25519_SHA512
|
|||||||
import net.corda.core.crypto.Crypto.RSA_SHA256
|
import net.corda.core.crypto.Crypto.RSA_SHA256
|
||||||
import net.corda.core.crypto.Crypto.SPHINCS256_SHA256
|
import net.corda.core.crypto.Crypto.SPHINCS256_SHA256
|
||||||
import net.corda.core.crypto.Crypto.generateKeyPair
|
import net.corda.core.crypto.Crypto.generateKeyPair
|
||||||
|
import net.corda.core.crypto.SignatureScheme
|
||||||
|
import net.corda.core.crypto.newSecureRandom
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
@ -33,7 +34,7 @@ import net.corda.serialization.internal.amqp.amqpMagic
|
|||||||
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
|
||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.NettyTestClient
|
import net.corda.testing.internal.NettyTestClient
|
||||||
import net.corda.testing.internal.NettyTestHandler
|
import net.corda.testing.internal.NettyTestHandler
|
||||||
import net.corda.testing.internal.NettyTestServer
|
import net.corda.testing.internal.NettyTestServer
|
||||||
@ -75,7 +76,7 @@ class X509UtilitiesTest {
|
|||||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||||
)
|
)
|
||||||
|
|
||||||
val portAllocation = PortAllocation.Incremental(10000)
|
val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
// We ensure that all of the algorithms are both used (at least once) as first and second in the following [Pair]s.
|
// We ensure that all of the algorithms are both used (at least once) as first and second in the following [Pair]s.
|
||||||
// We also add [DEFAULT_TLS_SIGNATURE_SCHEME] and [DEFAULT_IDENTITY_SIGNATURE_SCHEME] combinations for consistency.
|
// We also add [DEFAULT_TLS_SIGNATURE_SCHEME] and [DEFAULT_IDENTITY_SIGNATURE_SCHEME] combinations for consistency.
|
||||||
|
@ -8,8 +8,8 @@ import net.corda.testing.core.ALICE_NAME
|
|||||||
import net.corda.testing.core.BOB_NAME
|
import net.corda.testing.core.BOB_NAME
|
||||||
import net.corda.testing.core.DUMMY_BANK_A_NAME
|
import net.corda.testing.core.DUMMY_BANK_A_NAME
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
@ -29,7 +29,7 @@ class AddressBindingFailureTests: IntegrationTest() {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val databaseSchemas = IntegrationTestSchemas(ALICE_NAME.toDatabaseSchemaName(), BOB_NAME.toDatabaseSchemaName(), DUMMY_BANK_A_NAME.toDatabaseSchemaName())
|
val databaseSchemas = IntegrationTestSchemas(ALICE_NAME.toDatabaseSchemaName(), BOB_NAME.toDatabaseSchemaName(), DUMMY_BANK_A_NAME.toDatabaseSchemaName())
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(20_000)
|
private val portAllocation = incrementalPortAllocation(20_000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,15 +7,18 @@ import net.corda.client.rpc.RPCException
|
|||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.services.config.*
|
import net.corda.node.services.config.EnterpriseConfiguration
|
||||||
|
import net.corda.node.services.config.MutualExclusionConfiguration
|
||||||
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
|
import net.corda.node.services.config.configureWithDevSSLCertificate
|
||||||
import net.corda.node.services.messaging.ArtemisMessagingServer
|
import net.corda.node.services.messaging.ArtemisMessagingServer
|
||||||
import net.corda.nodeapi.internal.config.MessagingServerConnectionConfiguration
|
import net.corda.nodeapi.internal.config.MessagingServerConnectionConfiguration
|
||||||
import net.corda.testing.core.ALICE_NAME
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||||
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
@ -42,7 +45,7 @@ class ExternalBrokertests : IntegrationTest() {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val tempFolder = TemporaryFolder()
|
val tempFolder = TemporaryFolder()
|
||||||
|
|
||||||
private val portAllocator = PortAllocation.Incremental(10000)
|
private val portAllocator = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
private abstract class AbstractNodeConfiguration : NodeConfiguration
|
private abstract class AbstractNodeConfiguration : NodeConfiguration
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import net.corda.nodeapi.internal.bridging.BridgeManager
|
|||||||
import net.corda.nodeapi.internal.protonwrapper.netty.AMQPConfiguration
|
import net.corda.nodeapi.internal.protonwrapper.netty.AMQPConfiguration
|
||||||
import net.corda.nodeapi.internal.protonwrapper.netty.AMQPServer
|
import net.corda.nodeapi.internal.protonwrapper.netty.AMQPServer
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
||||||
import org.apache.activemq.artemis.api.core.Message.HDR_DUPLICATE_DETECTION_ID
|
import org.apache.activemq.artemis.api.core.Message.HDR_DUPLICATE_DETECTION_ID
|
||||||
@ -81,7 +81,7 @@ class AMQPBridgeTest(private val useOpenSsl: Boolean, private val enableSNI: Boo
|
|||||||
|
|
||||||
private val BOB = TestIdentity(BOB_NAME)
|
private val BOB = TestIdentity(BOB_NAME)
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
private val artemisAddress = portAllocation.nextHostAndPort()
|
private val artemisAddress = portAllocation.nextHostAndPort()
|
||||||
private val amqpAddress = portAllocation.nextHostAndPort()
|
private val amqpAddress = portAllocation.nextHostAndPort()
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import net.corda.testing.core.ALICE_NAME
|
|||||||
import net.corda.testing.core.BOB_NAME
|
import net.corda.testing.core.BOB_NAME
|
||||||
import net.corda.testing.core.CHARLIE_NAME
|
import net.corda.testing.core.CHARLIE_NAME
|
||||||
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.DEV_INTERMEDIATE_CA
|
import net.corda.testing.internal.DEV_INTERMEDIATE_CA
|
||||||
import net.corda.testing.internal.DEV_ROOT_CA
|
import net.corda.testing.internal.DEV_ROOT_CA
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
@ -72,7 +72,7 @@ class CertificateRevocationListNodeTests {
|
|||||||
private val ROOT_CA = DEV_ROOT_CA
|
private val ROOT_CA = DEV_ROOT_CA
|
||||||
private lateinit var INTERMEDIATE_CA: CertificateAndKeyPair
|
private lateinit var INTERMEDIATE_CA: CertificateAndKeyPair
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
private val serverPort = portAllocation.nextPort()
|
private val serverPort = portAllocation.nextPort()
|
||||||
|
|
||||||
private lateinit var server: CrlServer
|
private lateinit var server: CrlServer
|
||||||
|
@ -15,28 +15,30 @@ import net.corda.testing.core.ALICE_NAME
|
|||||||
import net.corda.testing.core.BOB_NAME
|
import net.corda.testing.core.BOB_NAME
|
||||||
import net.corda.testing.core.CHARLIE_NAME
|
import net.corda.testing.core.CHARLIE_NAME
|
||||||
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
||||||
import org.junit.*
|
|
||||||
import org.junit.rules.TemporaryFolder
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
import org.eclipse.jetty.proxy.ProxyServlet
|
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler.SESSIONS
|
|
||||||
import org.eclipse.jetty.proxy.ConnectHandler
|
import org.eclipse.jetty.proxy.ConnectHandler
|
||||||
|
import org.eclipse.jetty.proxy.ProxyServlet
|
||||||
import org.eclipse.jetty.server.Connector
|
import org.eclipse.jetty.server.Connector
|
||||||
import org.eclipse.jetty.server.Server
|
import org.eclipse.jetty.server.Server
|
||||||
import org.eclipse.jetty.server.ServerConnector
|
import org.eclipse.jetty.server.ServerConnector
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler.SESSIONS
|
||||||
import org.eclipse.jetty.servlet.ServletHolder
|
import org.eclipse.jetty.servlet.ServletHolder
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.rules.TemporaryFolder
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class HttpTests {
|
class HttpTests {
|
||||||
@Rule
|
@Rule
|
||||||
@JvmField
|
@JvmField
|
||||||
val temporaryFolder = TemporaryFolder()
|
val temporaryFolder = TemporaryFolder()
|
||||||
|
|
||||||
private val portAllocator = PortAllocation.Incremental(10000)
|
private val portAllocator = incrementalPortAllocation(10000)
|
||||||
private val httpProxyPort = portAllocator.nextPort()
|
private val httpProxyPort = portAllocator.nextPort()
|
||||||
private val serverPort = portAllocator.nextPort()
|
private val serverPort = portAllocator.nextPort()
|
||||||
private val serverPort2 = portAllocator.nextPort()
|
private val serverPort2 = portAllocator.nextPort()
|
||||||
|
@ -19,7 +19,7 @@ import net.corda.testing.core.ALICE_NAME
|
|||||||
import net.corda.testing.core.BOB_NAME
|
import net.corda.testing.core.BOB_NAME
|
||||||
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
||||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration
|
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration
|
||||||
@ -48,7 +48,7 @@ class LoopbackBridgeTest(private val useOpenSsl: Boolean) {
|
|||||||
val temporaryFolder = TemporaryFolder()
|
val temporaryFolder = TemporaryFolder()
|
||||||
private val log = loggerFor<LoopbackBridgeTest>()
|
private val log = loggerFor<LoopbackBridgeTest>()
|
||||||
private val BOB = TestIdentity(BOB_NAME)
|
private val BOB = TestIdentity(BOB_NAME)
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
private val artemisAddress = portAllocation.nextHostAndPort()
|
private val artemisAddress = portAllocation.nextHostAndPort()
|
||||||
private val amqpAddress = portAllocation.nextHostAndPort()
|
private val amqpAddress = portAllocation.nextHostAndPort()
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import net.corda.nodeapi.internal.protonwrapper.netty.init
|
|||||||
import net.corda.nodeapi.internal.registerDevP2pCertificates
|
import net.corda.nodeapi.internal.registerDevP2pCertificates
|
||||||
import net.corda.nodeapi.internal.registerDevSigningCertificates
|
import net.corda.nodeapi.internal.registerDevSigningCertificates
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.createDevIntermediateCaCertPath
|
import net.corda.testing.internal.createDevIntermediateCaCertPath
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
||||||
@ -68,7 +68,7 @@ class ProtonWrapperTests(val sslSetup: SslSetup) {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val temporaryFolder = TemporaryFolder()
|
val temporaryFolder = TemporaryFolder()
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
private val serverPort = portAllocation.nextPort()
|
private val serverPort = portAllocation.nextPort()
|
||||||
private val serverPort2 = portAllocation.nextPort()
|
private val serverPort2 = portAllocation.nextPort()
|
||||||
private val artemisPort = portAllocation.nextPort()
|
private val artemisPort = portAllocation.nextPort()
|
||||||
|
@ -23,8 +23,11 @@ import net.corda.nodeapi.internal.ArtemisMessagingClient
|
|||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.P2P_PREFIX
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.P2P_PREFIX
|
||||||
import net.corda.nodeapi.internal.protonwrapper.messages.MessageStatus
|
import net.corda.nodeapi.internal.protonwrapper.messages.MessageStatus
|
||||||
import net.corda.nodeapi.internal.protonwrapper.netty.*
|
import net.corda.nodeapi.internal.protonwrapper.netty.*
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.core.BOB_NAME
|
||||||
|
import net.corda.testing.core.CHARLIE_NAME
|
||||||
|
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
import net.corda.testing.internal.stubs.CertificateStoreStubs
|
||||||
import org.apache.activemq.artemis.api.core.RoutingType
|
import org.apache.activemq.artemis.api.core.RoutingType
|
||||||
@ -41,7 +44,7 @@ class SocksTests {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val temporaryFolder = TemporaryFolder()
|
val temporaryFolder = TemporaryFolder()
|
||||||
|
|
||||||
private val portAllocator = PortAllocation.Incremental(10000)
|
private val portAllocator = incrementalPortAllocation(10000)
|
||||||
private val socksPort = portAllocator.nextPort()
|
private val socksPort = portAllocator.nextPort()
|
||||||
private val serverPort = portAllocator.nextPort()
|
private val serverPort = portAllocator.nextPort()
|
||||||
private val serverPort2 = portAllocator.nextPort()
|
private val serverPort2 = portAllocator.nextPort()
|
||||||
|
@ -23,8 +23,8 @@ import net.corda.testing.core.BOB_NAME
|
|||||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||||
import net.corda.testing.core.singleIdentity
|
import net.corda.testing.core.singleIdentity
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
@ -43,7 +43,7 @@ class FlowsDrainingModeContentionTest : IntegrationTest() {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val databaseSchemas = IntegrationTestSchemas(ALICE_NAME.toDatabaseSchemaName(), BOB_NAME.toDatabaseSchemaName(), DUMMY_NOTARY_NAME.toDatabaseSchemaName())
|
val databaseSchemas = IntegrationTestSchemas(ALICE_NAME.toDatabaseSchemaName(), BOB_NAME.toDatabaseSchemaName(), DUMMY_NOTARY_NAME.toDatabaseSchemaName())
|
||||||
}
|
}
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
private val user = User("mark", "dadada", setOf(all()))
|
private val user = User("mark", "dadada", setOf(all()))
|
||||||
private val users = listOf(user)
|
private val users = listOf(user)
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ import net.corda.node.services.Permissions
|
|||||||
import net.corda.nodeapi.internal.hasCancelledDrainingShutdown
|
import net.corda.nodeapi.internal.hasCancelledDrainingShutdown
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
@ -45,7 +45,7 @@ class P2PFlowsDrainingModeTest : IntegrationTest() {
|
|||||||
private val logger = contextLogger()
|
private val logger = contextLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
private val user = User("mark", "dadada", setOf(Permissions.all()))
|
private val user = User("mark", "dadada", setOf(Permissions.all()))
|
||||||
private val users = listOf(user)
|
private val users = listOf(user)
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ import net.corda.node.services.Permissions
|
|||||||
import net.corda.nodeapi.exceptions.RejectedCommandException
|
import net.corda.nodeapi.exceptions.RejectedCommandException
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
@ -28,7 +28,7 @@ class RpcFlowsDrainingModeTest : IntegrationTest() {
|
|||||||
DUMMY_BANK_A_NAME.toDatabaseSchemaName(), DUMMY_NOTARY_NAME.toDatabaseSchemaName())
|
DUMMY_BANK_A_NAME.toDatabaseSchemaName(), DUMMY_NOTARY_NAME.toDatabaseSchemaName())
|
||||||
}
|
}
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
private val user = User("mark", "dadada", setOf(Permissions.all()))
|
private val user = User("mark", "dadada", setOf(Permissions.all()))
|
||||||
private val users = listOf(user)
|
private val users = listOf(user)
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ import net.corda.core.utilities.getOrThrow
|
|||||||
import net.corda.node.services.Permissions
|
import net.corda.node.services.Permissions
|
||||||
import net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException
|
import net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import org.junit.Assume.assumeTrue
|
import org.junit.Assume.assumeTrue
|
||||||
@ -23,7 +23,7 @@ import kotlin.test.assertTrue
|
|||||||
|
|
||||||
class H2SecurityTests {
|
class H2SecurityTests {
|
||||||
companion object {
|
companion object {
|
||||||
private val port = PortAllocation.Incremental(21_000)
|
private val port = incrementalPortAllocation(21_000)
|
||||||
private fun getFreePort() = port.nextPort()
|
private fun getFreePort() = port.nextPort()
|
||||||
private const val h2AddressKey = "h2Settings.address"
|
private const val h2AddressKey = "h2Settings.address"
|
||||||
private const val dbPasswordKey = "dataSourceProperties.dataSource.password"
|
private const val dbPasswordKey = "dataSourceProperties.dataSource.password"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.corda.node.services
|
package net.corda.node.services
|
||||||
|
|
||||||
|
import com.nhaarman.mockito_kotlin.any
|
||||||
import com.nhaarman.mockito_kotlin.doReturn
|
import com.nhaarman.mockito_kotlin.doReturn
|
||||||
import com.nhaarman.mockito_kotlin.whenever
|
import com.nhaarman.mockito_kotlin.whenever
|
||||||
import net.corda.core.CordaRuntimeException
|
import net.corda.core.CordaRuntimeException
|
||||||
@ -13,7 +14,9 @@ import net.corda.core.node.NetworkParameters
|
|||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
import net.corda.core.node.services.AttachmentStorage
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
import net.corda.core.node.services.IdentityService
|
import net.corda.core.node.services.IdentityService
|
||||||
|
import net.corda.core.node.services.NetworkParametersStorage
|
||||||
import net.corda.core.serialization.SerializationFactory
|
import net.corda.core.serialization.SerializationFactory
|
||||||
|
import net.corda.core.serialization.serialize
|
||||||
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.VersionInfo
|
import net.corda.node.VersionInfo
|
||||||
@ -69,6 +72,7 @@ class AttachmentLoadingTests : IntegrationTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val services = object : ServicesForResolution {
|
private val services = object : ServicesForResolution {
|
||||||
|
private val testNetworkParameters = testNetworkParameters()
|
||||||
override fun loadState(stateRef: StateRef): TransactionState<*> = throw NotImplementedError()
|
override fun loadState(stateRef: StateRef): TransactionState<*> = throw NotImplementedError()
|
||||||
override fun loadStates(stateRefs: Set<StateRef>): Set<StateAndRef<ContractState>> = throw NotImplementedError()
|
override fun loadStates(stateRefs: Set<StateRef>): Set<StateAndRef<ContractState>> = throw NotImplementedError()
|
||||||
override val identityService = rigorousMock<IdentityService>().apply {
|
override val identityService = rigorousMock<IdentityService>().apply {
|
||||||
@ -76,7 +80,11 @@ class AttachmentLoadingTests : IntegrationTest() {
|
|||||||
}
|
}
|
||||||
override val attachments: AttachmentStorage get() = this@AttachmentLoadingTests.attachments
|
override val attachments: AttachmentStorage get() = this@AttachmentLoadingTests.attachments
|
||||||
override val cordappProvider: CordappProvider get() = this@AttachmentLoadingTests.provider
|
override val cordappProvider: CordappProvider get() = this@AttachmentLoadingTests.provider
|
||||||
override val networkParameters: NetworkParameters = testNetworkParameters()
|
override val networkParameters: NetworkParameters = testNetworkParameters
|
||||||
|
override val networkParametersStorage: NetworkParametersStorage get() = rigorousMock<NetworkParametersStorage>().apply {
|
||||||
|
doReturn(testNetworkParameters.serialize().hash).whenever(this).currentHash
|
||||||
|
doReturn(testNetworkParameters).whenever(this).lookup(any())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -10,9 +10,9 @@ import net.corda.nodeapi.internal.crypto.X509Utilities
|
|||||||
import net.corda.nodeapi.internal.cryptoservice.CryptoServiceException
|
import net.corda.nodeapi.internal.cryptoservice.CryptoServiceException
|
||||||
import net.corda.testing.core.DUMMY_BANK_A_NAME
|
import net.corda.testing.core.DUMMY_BANK_A_NAME
|
||||||
import net.corda.testing.core.getTestPartyAndCertificate
|
import net.corda.testing.core.getTestPartyAndCertificate
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.ClassRule
|
import org.junit.ClassRule
|
||||||
|
import org.junit.Test
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -26,7 +26,7 @@ class UtimacoCryptoServiceIntegrationTest {
|
|||||||
companion object {
|
companion object {
|
||||||
@ClassRule
|
@ClassRule
|
||||||
@JvmField
|
@JvmField
|
||||||
val hsmSimulator: HsmSimulator = HsmSimulator(PortAllocation.Incremental(12300))
|
val hsmSimulator: HsmSimulator = HsmSimulator(incrementalPortAllocation(12300))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val config = testConfig(hsmSimulator.address.port)
|
private val config = testConfig(hsmSimulator.address.port)
|
||||||
|
@ -14,7 +14,7 @@ import net.corda.node.utilities.registration.TestDoorman
|
|||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.core.singleIdentity
|
import net.corda.testing.core.singleIdentity
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.DEV_ROOT_CA
|
import net.corda.testing.internal.DEV_ROOT_CA
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
@ -42,7 +42,7 @@ class UtimacoNodeRegistrationTest : IntegrationTest() {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val testSerialization = SerializationEnvironmentRule(true)
|
val testSerialization = SerializationEnvironmentRule(true)
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(13400)
|
private val portAllocation = incrementalPortAllocation(13400)
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
@JvmField
|
@JvmField
|
||||||
|
@ -17,7 +17,7 @@ import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
|||||||
import net.corda.testing.core.ALICE_NAME
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.testing.internal.configureDatabase
|
import net.corda.testing.internal.configureDatabase
|
||||||
@ -57,7 +57,7 @@ class ArtemisMessagingTest {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val temporaryFolder = TemporaryFolder()
|
val temporaryFolder = TemporaryFolder()
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
private val serverPort = portAllocation.nextPort()
|
private val serverPort = portAllocation.nextPort()
|
||||||
private val identity = generateKeyPair()
|
private val identity = generateKeyPair()
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
|||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.internal.NodeHandleInternal
|
import net.corda.testing.driver.internal.NodeHandleInternal
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
@ -41,7 +41,7 @@ class NetworkMapTest(var initFunc: (URL, NetworkMapServer) -> CompatibilityZoneP
|
|||||||
val testSerialization = SerializationEnvironmentRule(true)
|
val testSerialization = SerializationEnvironmentRule(true)
|
||||||
|
|
||||||
private val cacheTimeout = 1.seconds
|
private val cacheTimeout = 1.seconds
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
private lateinit var networkMapServer: NetworkMapServer
|
private lateinit var networkMapServer: NetworkMapServer
|
||||||
private lateinit var compatibilityZone: CompatibilityZoneParams
|
private lateinit var compatibilityZone: CompatibilityZoneParams
|
||||||
|
@ -23,6 +23,7 @@ import net.corda.nodeapi.internal.config.MutualSslConfiguration
|
|||||||
import net.corda.nodeapi.internal.config.User
|
import net.corda.nodeapi.internal.config.User
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.PortAllocation
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.testing.internal.fromUserList
|
import net.corda.testing.internal.fromUserList
|
||||||
import net.corda.testing.internal.p2pSslOptions
|
import net.corda.testing.internal.p2pSslOptions
|
||||||
@ -37,7 +38,7 @@ import java.nio.file.Path
|
|||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
|
||||||
class ArtemisRpcTests {
|
class ArtemisRpcTests {
|
||||||
private val ports: PortAllocation = PortAllocation.Incremental(10000)
|
private val ports: PortAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
private val user = User("mark", "dadada", setOf(all()))
|
private val user = User("mark", "dadada", setOf(all()))
|
||||||
private val users = listOf(user)
|
private val users = listOf(user)
|
||||||
|
@ -17,7 +17,7 @@ import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
|
|||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.core.singleIdentity
|
import net.corda.testing.core.singleIdentity
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.DEV_ROOT_CA
|
import net.corda.testing.internal.DEV_ROOT_CA
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
@ -60,7 +60,7 @@ class NodeRegistrationTest : IntegrationTest() {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val testSerialization = SerializationEnvironmentRule(true)
|
val testSerialization = SerializationEnvironmentRule(true)
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(13000)
|
private val portAllocation = incrementalPortAllocation(13000)
|
||||||
private val registrationHandler = RegistrationHandler(DEV_ROOT_CA)
|
private val registrationHandler = RegistrationHandler(DEV_ROOT_CA)
|
||||||
private lateinit var server: NetworkMapServer
|
private lateinit var server: NetworkMapServer
|
||||||
private lateinit var serverHostAndPort: NetworkHostAndPort
|
private lateinit var serverHostAndPort: NetworkHostAndPort
|
||||||
|
@ -14,8 +14,8 @@ import net.corda.finance.flows.CashIssueAndPaymentFlow
|
|||||||
import net.corda.node.services.Permissions.Companion.all
|
import net.corda.node.services.Permissions.Companion.all
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
@ -32,7 +32,7 @@ class AdditionP2PAddressModeTest : IntegrationTest() {
|
|||||||
DUMMY_NOTARY_NAME.toDatabaseSchemaName())
|
DUMMY_NOTARY_NAME.toDatabaseSchemaName())
|
||||||
}
|
}
|
||||||
|
|
||||||
private val portAllocation = PortAllocation.Incremental(27182)
|
private val portAllocation = incrementalPortAllocation(27182)
|
||||||
@Test
|
@Test
|
||||||
fun `runs nodes with one configured to use additionalP2PAddresses`() {
|
fun `runs nodes with one configured to use additionalP2PAddresses`() {
|
||||||
val testUser = User("test", "test", setOf(all()))
|
val testUser = User("test", "test", setOf(all()))
|
||||||
|
@ -165,16 +165,18 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
val networkMapClient: NetworkMapClient? = configuration.networkServices?.let { NetworkMapClient(it.networkMapURL, versionInfo) }
|
val networkMapClient: NetworkMapClient? = configuration.networkServices?.let { NetworkMapClient(it.networkMapURL, versionInfo) }
|
||||||
val attachments = NodeAttachmentService(metricRegistry, cacheFactory, database).tokenize()
|
val attachments = NodeAttachmentService(metricRegistry, cacheFactory, database).tokenize()
|
||||||
val cryptoService = configuration.makeCryptoService()
|
val cryptoService = configuration.makeCryptoService()
|
||||||
|
val networkParametersStorage = DBNetworkParametersStorage(cacheFactory, database, networkMapClient).tokenize()
|
||||||
val cordappProvider = CordappProviderImpl(cordappLoader, CordappConfigFileProvider(configuration.cordappDirectories), attachments).tokenize()
|
val cordappProvider = CordappProviderImpl(cordappLoader, CordappConfigFileProvider(configuration.cordappDirectories), attachments).tokenize()
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
val keyManagementService = makeKeyManagementService(identityService).tokenize()
|
val keyManagementService = makeKeyManagementService(identityService).tokenize()
|
||||||
val servicesForResolution = ServicesForResolutionImpl(identityService, attachments, cordappProvider, transactionStorage).also {
|
val servicesForResolution = ServicesForResolutionImpl(identityService, attachments, cordappProvider, networkParametersStorage, transactionStorage).also {
|
||||||
attachments.servicesForResolution = it
|
attachments.servicesForResolution = it
|
||||||
}
|
}
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
val vaultService = makeVaultService(keyManagementService, servicesForResolution, database).tokenize()
|
val vaultService = makeVaultService(keyManagementService, servicesForResolution, database).tokenize()
|
||||||
val nodeProperties = NodePropertiesPersistentStore(StubbedNodeUniqueIdProvider::value, database, cacheFactory)
|
val nodeProperties = NodePropertiesPersistentStore(StubbedNodeUniqueIdProvider::value, database, cacheFactory)
|
||||||
val flowLogicRefFactory = FlowLogicRefFactoryImpl(cordappLoader.appClassLoader)
|
val flowLogicRefFactory = FlowLogicRefFactoryImpl(cordappLoader.appClassLoader)
|
||||||
|
// TODO Cancelling parameters updates - if we do that, how we ensure that no one uses cancelled parameters in the transactions?
|
||||||
val networkMapUpdater = NetworkMapUpdater(
|
val networkMapUpdater = NetworkMapUpdater(
|
||||||
networkMapCache,
|
networkMapCache,
|
||||||
NodeInfoWatcher(
|
NodeInfoWatcher(
|
||||||
@ -185,7 +187,8 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
),
|
),
|
||||||
networkMapClient,
|
networkMapClient,
|
||||||
configuration.baseDirectory,
|
configuration.baseDirectory,
|
||||||
configuration.extraNetworkMapKeys
|
configuration.extraNetworkMapKeys,
|
||||||
|
networkParametersStorage
|
||||||
).closeOnStop()
|
).closeOnStop()
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
val transactionVerifierService = InMemoryTransactionVerifierService(transactionVerifierWorkerCount).tokenize()
|
val transactionVerifierService = InMemoryTransactionVerifierService(transactionVerifierWorkerCount).tokenize()
|
||||||
@ -323,7 +326,6 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
check(netParams.minimumPlatformVersion <= versionInfo.platformVersion) {
|
check(netParams.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"
|
||||||
}
|
}
|
||||||
servicesForResolution.start(netParams)
|
|
||||||
networkMapCache.start(netParams.notaries)
|
networkMapCache.start(netParams.notaries)
|
||||||
|
|
||||||
startDatabase()
|
startDatabase()
|
||||||
@ -366,6 +368,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
|
|
||||||
// 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.
|
||||||
return database.transaction {
|
return database.transaction {
|
||||||
|
networkParametersStorage.start(signedNetParams, trustRoot)
|
||||||
identityService.loadIdentities(nodeInfo.legalIdentitiesAndCerts)
|
identityService.loadIdentities(nodeInfo.legalIdentitiesAndCerts)
|
||||||
attachments.start()
|
attachments.start()
|
||||||
cordappProvider.start(netParams.whitelistedContractImplementations)
|
cordappProvider.start(netParams.whitelistedContractImplementations)
|
||||||
@ -1019,6 +1022,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
override val configuration: NodeConfiguration get() = this@AbstractNode.configuration
|
override val configuration: NodeConfiguration get() = this@AbstractNode.configuration
|
||||||
override val networkMapUpdater: NetworkMapUpdater get() = this@AbstractNode.networkMapUpdater
|
override val networkMapUpdater: NetworkMapUpdater get() = this@AbstractNode.networkMapUpdater
|
||||||
override val cacheFactory: NamedCacheFactory get() = this@AbstractNode.cacheFactory
|
override val cacheFactory: NamedCacheFactory get() = this@AbstractNode.cacheFactory
|
||||||
|
override val networkParametersStorage: NetworkParametersStorage get() = this@AbstractNode.networkParametersStorage
|
||||||
|
|
||||||
private lateinit var _myInfo: NodeInfo
|
private lateinit var _myInfo: NodeInfo
|
||||||
override val myInfo: NodeInfo get() = _myInfo
|
override val myInfo: NodeInfo get() = _myInfo
|
||||||
|
@ -0,0 +1,159 @@
|
|||||||
|
package net.corda.node.internal
|
||||||
|
|
||||||
|
import net.corda.core.crypto.SecureHash
|
||||||
|
import net.corda.core.internal.DigitalSignatureWithCert
|
||||||
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
|
import net.corda.core.node.services.NetworkParametersStorage
|
||||||
|
import net.corda.core.serialization.SerializedBytes
|
||||||
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
|
import net.corda.core.serialization.deserialize
|
||||||
|
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
|
||||||
|
import net.corda.core.utilities.contextLogger
|
||||||
|
import net.corda.core.utilities.trace
|
||||||
|
import net.corda.node.services.network.NetworkMapClient
|
||||||
|
import net.corda.node.utilities.AppendOnlyPersistentMap
|
||||||
|
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
||||||
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
|
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
||||||
|
import net.corda.nodeapi.internal.network.verifiedNetworkParametersCert
|
||||||
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
|
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
||||||
|
import org.apache.commons.lang.ArrayUtils
|
||||||
|
import java.security.cert.X509Certificate
|
||||||
|
import javax.persistence.*
|
||||||
|
|
||||||
|
interface NetworkParametersStorageInternal : NetworkParametersStorage {
|
||||||
|
/**
|
||||||
|
* Return parameters epoch for the given parameters hash. Null if there are no parameters for this hash in the storage and we are unable to
|
||||||
|
* get them from network map.
|
||||||
|
*/
|
||||||
|
fun getEpochFromHash(hash: SecureHash): Int?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save signed network parameters data. Internally network parameters bytes should be stored with the signature.
|
||||||
|
* It's because of ability of older nodes to function in network where parameters were extended with new fields.
|
||||||
|
* Hash should always be calculated over the serialized bytes.
|
||||||
|
*/
|
||||||
|
fun saveParameters(signedNetworkParameters: SignedDataWithCert<NetworkParameters>)
|
||||||
|
}
|
||||||
|
|
||||||
|
class DBNetworkParametersStorage(
|
||||||
|
cacheFactory: NamedCacheFactory,
|
||||||
|
private val database: CordaPersistence,
|
||||||
|
// TODO It's very inefficient solution (at least at the beginning when node joins without historical data)
|
||||||
|
// We could have historic parameters endpoint or always add parameters as an attachment to the transaction.
|
||||||
|
private val networkMapClient: NetworkMapClient?
|
||||||
|
) : NetworkParametersStorageInternal, SingletonSerializeAsToken() {
|
||||||
|
private lateinit var trustRoot: X509Certificate
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = contextLogger()
|
||||||
|
|
||||||
|
fun createParametersMap(cacheFactory: NamedCacheFactory): AppendOnlyPersistentMap<SecureHash, SignedDataWithCert<NetworkParameters>, PersistentNetworkParameters, String> {
|
||||||
|
return AppendOnlyPersistentMap(
|
||||||
|
cacheFactory = cacheFactory,
|
||||||
|
name = "NodeParametersStorage_networkParametersByHash",
|
||||||
|
toPersistentEntityKey = { it.toString() },
|
||||||
|
fromPersistentEntity = {
|
||||||
|
Pair(
|
||||||
|
SecureHash.parse(it.hash),
|
||||||
|
it.signedNetworkParameters
|
||||||
|
)
|
||||||
|
},
|
||||||
|
toPersistentEntity = { key: SecureHash, value: SignedDataWithCert<NetworkParameters> ->
|
||||||
|
PersistentNetworkParameters(key.toString(), value.verified().epoch, value.raw.bytes, value.sig.bytes, value.sig.by.encoded,
|
||||||
|
X509Utilities.buildCertPath(value.sig.parentCertsChain).encoded)
|
||||||
|
},
|
||||||
|
persistentEntityClass = PersistentNetworkParameters::class.java
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start(currentSignedParameters: SignedDataWithCert<NetworkParameters>, trustRoot: X509Certificate) {
|
||||||
|
this.trustRoot = trustRoot
|
||||||
|
saveParameters(currentSignedParameters)
|
||||||
|
_currentHash = currentSignedParameters.raw.hash
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var _currentHash: SecureHash
|
||||||
|
override val currentHash: SecureHash get() = _currentHash
|
||||||
|
// TODO Have network map serve special "starting" parameters as parameters for resolution for older transactions?
|
||||||
|
override val defaultHash: SecureHash get() = currentHash
|
||||||
|
|
||||||
|
private val hashToParameters = createParametersMap(cacheFactory)
|
||||||
|
|
||||||
|
override fun lookup(hash: SecureHash): NetworkParameters? {
|
||||||
|
return database.transaction { hashToParameters[hash]?.raw?.deserialize() } ?: tryDownloadUnknownParameters(hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getEpochFromHash(hash: SecureHash): Int? = lookup(hash)?.epoch
|
||||||
|
|
||||||
|
override fun saveParameters(signedNetworkParameters: SignedNetworkParameters) {
|
||||||
|
log.trace { "Saving new network parameters to network parameters storage." }
|
||||||
|
val networkParameters = signedNetworkParameters.verified()
|
||||||
|
val hash = signedNetworkParameters.raw.hash
|
||||||
|
log.trace { "Parameters to save $networkParameters with hash $hash" }
|
||||||
|
database.transaction {
|
||||||
|
hashToParameters.addWithDuplicatesAllowed(hash, signedNetworkParameters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO For the future we could get them also as signed (by network operator) attachments on transactions.
|
||||||
|
private fun tryDownloadUnknownParameters(parametersHash: SecureHash): NetworkParameters? {
|
||||||
|
return if (networkMapClient != null) {
|
||||||
|
try {
|
||||||
|
val signedParams = networkMapClient.getNetworkParameters(parametersHash)
|
||||||
|
val networkParameters = signedParams.verifiedNetworkParametersCert(trustRoot)
|
||||||
|
saveParameters(signedParams)
|
||||||
|
networkParameters
|
||||||
|
} catch (e: Exception) {
|
||||||
|
log.warn("Failed to download historical network parameters with hash $parametersHash", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("Tried to download historical network parameters with hash $parametersHash, but network map url isn't configured")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "${NODE_DATABASE_PREFIX}network_parameters")
|
||||||
|
class PersistentNetworkParameters(
|
||||||
|
@Id
|
||||||
|
@Column(name = "hash", length = MAX_HASH_HEX_SIZE, nullable = false)
|
||||||
|
val hash: String = "",
|
||||||
|
|
||||||
|
@Column(name = "epoch", nullable = false)
|
||||||
|
val epoch: Int = 0,
|
||||||
|
|
||||||
|
// Stored as serialized bytes because network parameters structure evolves over time.
|
||||||
|
@Lob
|
||||||
|
@Column(name = "parameters_bytes", nullable = false)
|
||||||
|
val networkParametersBytes: ByteArray = ArrayUtils.EMPTY_BYTE_ARRAY,
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
@Column(name = "signature_bytes", nullable = false)
|
||||||
|
private val signature: ByteArray = ArrayUtils.EMPTY_BYTE_ARRAY,
|
||||||
|
|
||||||
|
// First certificate in the certificate chain.
|
||||||
|
@Lob
|
||||||
|
@Column(name = "cert", nullable = false)
|
||||||
|
private val certificate: ByteArray = ArrayUtils.EMPTY_BYTE_ARRAY,
|
||||||
|
|
||||||
|
// Parent certificate path (the first one is stored separately), so node is agnostic to certificate hierarchy.
|
||||||
|
@Lob
|
||||||
|
@Column(name = "parent_cert_path", nullable = false)
|
||||||
|
private val certPath: ByteArray = ArrayUtils.EMPTY_BYTE_ARRAY
|
||||||
|
) {
|
||||||
|
val networkParameters: NetworkParameters get() = networkParametersBytes.deserialize()
|
||||||
|
val signedNetworkParameters: SignedDataWithCert<NetworkParameters>
|
||||||
|
get() {
|
||||||
|
val certChain = X509CertificateFactory().delegate.generateCertPath(certPath.inputStream())
|
||||||
|
.certificates.map { it as X509Certificate }
|
||||||
|
val signWithCert = DigitalSignatureWithCert(X509CertificateFactory().generateCertificate(certificate.inputStream()), certChain, signature)
|
||||||
|
return SignedDataWithCert(SerializedBytes(networkParametersBytes), signWithCert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,10 @@ import net.corda.core.node.NetworkParameters
|
|||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.node.services.network.NetworkMapClient
|
import net.corda.node.services.network.NetworkMapClient
|
||||||
import net.corda.nodeapi.internal.network.*
|
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME
|
||||||
|
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||||
|
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
||||||
|
import net.corda.nodeapi.internal.network.verifiedNetworkParametersCert
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
|
@ -5,6 +5,7 @@ import net.corda.core.cordapp.CordappProvider
|
|||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
import net.corda.core.node.services.AttachmentStorage
|
import net.corda.core.node.services.AttachmentStorage
|
||||||
|
import net.corda.core.node.services.NetworkParametersStorage
|
||||||
import net.corda.core.node.services.IdentityService
|
import net.corda.core.node.services.IdentityService
|
||||||
import net.corda.core.node.services.TransactionStorage
|
import net.corda.core.node.services.TransactionStorage
|
||||||
|
|
||||||
@ -12,14 +13,11 @@ data class ServicesForResolutionImpl(
|
|||||||
override val identityService: IdentityService,
|
override val identityService: IdentityService,
|
||||||
override val attachments: AttachmentStorage,
|
override val attachments: AttachmentStorage,
|
||||||
override val cordappProvider: CordappProvider,
|
override val cordappProvider: CordappProvider,
|
||||||
|
override val networkParametersStorage: NetworkParametersStorage,
|
||||||
private val validatedTransactions: TransactionStorage
|
private val validatedTransactions: TransactionStorage
|
||||||
) : ServicesForResolution {
|
) : ServicesForResolution {
|
||||||
private lateinit var _networkParameters: NetworkParameters
|
override val networkParameters: NetworkParameters get() = networkParametersStorage.lookup(networkParametersStorage.currentHash) ?:
|
||||||
override val networkParameters: NetworkParameters get() = _networkParameters
|
throw IllegalArgumentException("No current parameters in network parameters storage")
|
||||||
|
|
||||||
fun start(networkParameters: NetworkParameters) {
|
|
||||||
_networkParameters = networkParameters
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(TransactionResolutionException::class)
|
@Throws(TransactionResolutionException::class)
|
||||||
override fun loadState(stateRef: StateRef): TransactionState<*> {
|
override fun loadState(stateRef: StateRef): TransactionState<*> {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.node.serialization.amqp
|
package net.corda.node.serialization.amqp
|
||||||
|
|
||||||
import net.corda.core.cordapp.Cordapp
|
import net.corda.core.cordapp.Cordapp
|
||||||
|
import net.corda.core.internal.toSynchronised
|
||||||
import net.corda.core.serialization.ClassWhitelist
|
import net.corda.core.serialization.ClassWhitelist
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.SerializationCustomSerializer
|
import net.corda.core.serialization.SerializationCustomSerializer
|
||||||
@ -19,10 +20,10 @@ class AMQPServerSerializationScheme(
|
|||||||
cordappCustomSerializers: Set<SerializationCustomSerializer<*, *>>,
|
cordappCustomSerializers: Set<SerializationCustomSerializer<*, *>>,
|
||||||
serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>
|
serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>
|
||||||
) : AbstractAMQPSerializationScheme(cordappCustomSerializers, serializerFactoriesForContexts) {
|
) : AbstractAMQPSerializationScheme(cordappCustomSerializers, serializerFactoriesForContexts) {
|
||||||
constructor(cordapps: List<Cordapp>) : this(cordapps.customSerializers, AccessOrderLinkedHashMap { 128 })
|
constructor(cordapps: List<Cordapp>) : this(cordapps.customSerializers, AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>(128).toSynchronised())
|
||||||
constructor(cordapps: List<Cordapp>, serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>) : this(cordapps.customSerializers, serializerFactoriesForContexts)
|
constructor(cordapps: List<Cordapp>, serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>) : this(cordapps.customSerializers, serializerFactoriesForContexts)
|
||||||
|
|
||||||
constructor() : this(emptySet(), AccessOrderLinkedHashMap { 128 })
|
constructor() : this(emptySet(), AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>(128).toSynchronised() )
|
||||||
|
|
||||||
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
|
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
|
||||||
throw UnsupportedOperationException()
|
throw UnsupportedOperationException()
|
||||||
|
@ -12,6 +12,7 @@ import net.corda.core.node.services.KeyManagementService
|
|||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.minutes
|
import net.corda.core.utilities.minutes
|
||||||
|
import net.corda.node.internal.NetworkParametersStorageInternal
|
||||||
import net.corda.node.services.api.NetworkMapCacheInternal
|
import net.corda.node.services.api.NetworkMapCacheInternal
|
||||||
import net.corda.node.services.config.NetworkParameterAcceptanceSettings
|
import net.corda.node.services.config.NetworkParameterAcceptanceSettings
|
||||||
import net.corda.node.utilities.NamedThreadFactory
|
import net.corda.node.utilities.NamedThreadFactory
|
||||||
@ -33,7 +34,8 @@ class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal,
|
|||||||
private val nodeInfoWatcher: NodeInfoWatcher,
|
private val nodeInfoWatcher: NodeInfoWatcher,
|
||||||
private val networkMapClient: NetworkMapClient?,
|
private val networkMapClient: NetworkMapClient?,
|
||||||
private val baseDirectory: Path,
|
private val baseDirectory: Path,
|
||||||
private val extraNetworkMapKeys: List<UUID>
|
private val extraNetworkMapKeys: List<UUID>,
|
||||||
|
private val networkParametersStorage: NetworkParametersStorageInternal
|
||||||
) : AutoCloseable {
|
) : AutoCloseable {
|
||||||
companion object {
|
companion object {
|
||||||
private val logger = contextLogger()
|
private val logger = contextLogger()
|
||||||
@ -209,6 +211,7 @@ The node will shutdown now.""")
|
|||||||
}
|
}
|
||||||
val newSignedNetParams = networkMapClient.getNetworkParameters(update.newParametersHash)
|
val newSignedNetParams = networkMapClient.getNetworkParameters(update.newParametersHash)
|
||||||
val newNetParams = newSignedNetParams.verifiedNetworkParametersCert(trustRoot)
|
val newNetParams = newSignedNetParams.verifiedNetworkParametersCert(trustRoot)
|
||||||
|
networkParametersStorage.saveParameters(newSignedNetParams)
|
||||||
logger.info("Downloaded new network parameters: $newNetParams from the update: $update")
|
logger.info("Downloaded new network parameters: $newNetParams from the update: $update")
|
||||||
newNetworkParameters = Pair(update, newSignedNetParams)
|
newNetworkParameters = Pair(update, newSignedNetParams)
|
||||||
val updateInfo = ParametersUpdateInfo(
|
val updateInfo = ParametersUpdateInfo(
|
||||||
|
@ -7,6 +7,7 @@ import net.corda.core.contracts.LinearState
|
|||||||
import net.corda.core.schemas.*
|
import net.corda.core.schemas.*
|
||||||
import net.corda.core.schemas.MappedSchemaValidator.crossReferencesToOtherMappedSchema
|
import net.corda.core.schemas.MappedSchemaValidator.crossReferencesToOtherMappedSchema
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
|
import net.corda.node.internal.DBNetworkParametersStorage
|
||||||
import net.corda.node.internal.schemas.NodeInfoSchemaV1
|
import net.corda.node.internal.schemas.NodeInfoSchemaV1
|
||||||
import net.corda.node.services.api.SchemaService
|
import net.corda.node.services.api.SchemaService
|
||||||
import net.corda.node.services.api.SchemaService.SchemaOptions
|
import net.corda.node.services.api.SchemaService.SchemaOptions
|
||||||
@ -45,6 +46,7 @@ class NodeSchemaService(private val extraSchemas: Set<MappedSchema> = emptySet()
|
|||||||
PersistentIdentityService.PersistentIdentityNames::class.java,
|
PersistentIdentityService.PersistentIdentityNames::class.java,
|
||||||
ContractUpgradeServiceImpl.DBContractUpgrade::class.java,
|
ContractUpgradeServiceImpl.DBContractUpgrade::class.java,
|
||||||
RunOnceService.MutualExclusion::class.java,
|
RunOnceService.MutualExclusion::class.java,
|
||||||
|
DBNetworkParametersStorage.PersistentNetworkParameters::class.java,
|
||||||
PersistentKeyManagementService.PublicKeyHashToExternalId::class.java
|
PersistentKeyManagementService.PublicKeyHashToExternalId::class.java
|
||||||
)) {
|
)) {
|
||||||
override val migrationResource = "node-core.changelog-master"
|
override val migrationResource = "node-core.changelog-master"
|
||||||
|
@ -28,11 +28,12 @@ class NonValidatingNotaryFlow(otherSideSession: FlowSession, service: SinglePart
|
|||||||
checkAllComponentsVisible(ComponentGroupEnum.INPUTS_GROUP)
|
checkAllComponentsVisible(ComponentGroupEnum.INPUTS_GROUP)
|
||||||
checkAllComponentsVisible(ComponentGroupEnum.TIMEWINDOW_GROUP)
|
checkAllComponentsVisible(ComponentGroupEnum.TIMEWINDOW_GROUP)
|
||||||
checkAllComponentsVisible(ComponentGroupEnum.REFERENCES_GROUP)
|
checkAllComponentsVisible(ComponentGroupEnum.REFERENCES_GROUP)
|
||||||
|
if(serviceHub.networkParameters.minimumPlatformVersion >= 4) checkAllComponentsVisible(ComponentGroupEnum.PARAMETERS_GROUP)
|
||||||
}
|
}
|
||||||
TransactionParts(tx.id, tx.inputs, tx.timeWindow, tx.notary, tx.references)
|
TransactionParts(tx.id, tx.inputs, tx.timeWindow, tx.notary, tx.references, networkParametersHash = tx.networkParametersHash)
|
||||||
}
|
}
|
||||||
is ContractUpgradeFilteredTransaction,
|
is ContractUpgradeFilteredTransaction,
|
||||||
is NotaryChangeWireTransaction -> TransactionParts(tx.id, tx.inputs, null, tx.notary)
|
is NotaryChangeWireTransaction -> TransactionParts(tx.id, tx.inputs, null, tx.notary, networkParametersHash = tx.networkParametersHash)
|
||||||
else -> {
|
else -> {
|
||||||
throw IllegalArgumentException("Received unexpected transaction type: ${tx::class.java.simpleName}," +
|
throw IllegalArgumentException("Received unexpected transaction type: ${tx::class.java.simpleName}," +
|
||||||
"expected either ${FilteredTransaction::class.java.simpleName} or ${NotaryChangeWireTransaction::class.java.simpleName}")
|
"expected either ${FilteredTransaction::class.java.simpleName} or ${NotaryChangeWireTransaction::class.java.simpleName}")
|
||||||
|
@ -24,7 +24,7 @@ open class ValidatingNotaryFlow(otherSideSession: FlowSession, service: SinglePa
|
|||||||
override fun extractParts(requestPayload: NotarisationPayload): TransactionParts {
|
override fun extractParts(requestPayload: NotarisationPayload): TransactionParts {
|
||||||
val stx = requestPayload.signedTransaction
|
val stx = requestPayload.signedTransaction
|
||||||
val timeWindow: TimeWindow? = if (stx.coreTransaction is WireTransaction) stx.tx.timeWindow else null
|
val timeWindow: TimeWindow? = if (stx.coreTransaction is WireTransaction) stx.tx.timeWindow else null
|
||||||
return TransactionParts(stx.id, stx.inputs, timeWindow, stx.notary, stx.references)
|
return TransactionParts(stx.id, stx.inputs, timeWindow, stx.notary, stx.references, stx.networkParametersHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,6 +57,7 @@ open class DefaultNamedCacheFactory protected constructor(private val metricRegi
|
|||||||
name == "BFTNonValidatingNotaryService_transactions" -> caffeine.maximumSize(defaultCacheSize)
|
name == "BFTNonValidatingNotaryService_transactions" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
name == "RaftUniquenessProvider_transactions" -> caffeine.maximumSize(defaultCacheSize)
|
name == "RaftUniquenessProvider_transactions" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
name == "BasicHSMKeyManagementService_keys" -> caffeine.maximumSize(defaultCacheSize)
|
name == "BasicHSMKeyManagementService_keys" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
|
name == "NodeParametersStorage_networkParametersByHash" -> caffeine.maximumSize(defaultCacheSize)
|
||||||
else -> throw IllegalArgumentException("Unexpected cache name $name. Did you add a new cache?")
|
else -> throw IllegalArgumentException("Unexpected cache name $name. Did you add a new cache?")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ import com.nhaarman.mockito_kotlin.mock
|
|||||||
import net.corda.client.rpc.internal.serialization.amqp.RpcClientObservableDeSerializer
|
import net.corda.client.rpc.internal.serialization.amqp.RpcClientObservableDeSerializer
|
||||||
import net.corda.core.context.Trace
|
import net.corda.core.context.Trace
|
||||||
import net.corda.core.internal.ThreadBox
|
import net.corda.core.internal.ThreadBox
|
||||||
|
import net.corda.core.internal.toSynchronised
|
||||||
|
import net.corda.core.serialization.ClassWhitelist
|
||||||
import net.corda.node.internal.serialization.testutils.AMQPRoundTripRPCSerializationScheme
|
import net.corda.node.internal.serialization.testutils.AMQPRoundTripRPCSerializationScheme
|
||||||
import net.corda.node.internal.serialization.testutils.serializationContext
|
import net.corda.node.internal.serialization.testutils.serializationContext
|
||||||
import net.corda.node.serialization.amqp.RpcServerObservableSerializer
|
import net.corda.node.serialization.amqp.RpcServerObservableSerializer
|
||||||
@ -16,6 +18,7 @@ import net.corda.nodeapi.RPCApi
|
|||||||
import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap
|
import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap
|
||||||
import net.corda.serialization.internal.amqp.DeserializationInput
|
import net.corda.serialization.internal.amqp.DeserializationInput
|
||||||
import net.corda.serialization.internal.amqp.SerializationOutput
|
import net.corda.serialization.internal.amqp.SerializationOutput
|
||||||
|
import net.corda.serialization.internal.amqp.SerializerFactory
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import rx.Notification
|
import rx.Notification
|
||||||
@ -60,7 +63,7 @@ class RoundTripObservableSerializerTests {
|
|||||||
@Test
|
@Test
|
||||||
fun roundTripTest1() {
|
fun roundTripTest1() {
|
||||||
val serializationScheme = AMQPRoundTripRPCSerializationScheme(
|
val serializationScheme = AMQPRoundTripRPCSerializationScheme(
|
||||||
serializationContext, emptySet(), AccessOrderLinkedHashMap { 128 })
|
serializationContext, emptySet(), AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>(128).toSynchronised())
|
||||||
|
|
||||||
// Fake up a message ID, needs to be used on both "sides". The server setting it in the subscriptionMap,
|
// Fake up a message ID, needs to be used on both "sides". The server setting it in the subscriptionMap,
|
||||||
// the client as a property of the deserializer which, in the actual RPC client, is pulled off of
|
// the client as a property of the deserializer which, in the actual RPC client, is pulled off of
|
||||||
|
@ -24,7 +24,7 @@ import net.corda.client.rpc.internal.ObservableContext as ClientObservableContex
|
|||||||
class AMQPRoundTripRPCSerializationScheme(
|
class AMQPRoundTripRPCSerializationScheme(
|
||||||
private val serializationContext: SerializationContext,
|
private val serializationContext: SerializationContext,
|
||||||
cordappCustomSerializers: Set<SerializationCustomSerializer<*, *>>,
|
cordappCustomSerializers: Set<SerializationCustomSerializer<*, *>>,
|
||||||
serializerFactoriesForContexts: AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>)
|
serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>)
|
||||||
: AbstractAMQPSerializationScheme(
|
: AbstractAMQPSerializationScheme(
|
||||||
cordappCustomSerializers, serializerFactoriesForContexts
|
cordappCustomSerializers, serializerFactoriesForContexts
|
||||||
) {
|
) {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package net.corda.node.messaging
|
package net.corda.node.messaging
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import com.nhaarman.mockito_kotlin.doReturn
|
|
||||||
import com.nhaarman.mockito_kotlin.whenever
|
|
||||||
import net.corda.core.concurrent.CordaFuture
|
import net.corda.core.concurrent.CordaFuture
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.*
|
||||||
import net.corda.core.crypto.*
|
import net.corda.core.crypto.*
|
||||||
@ -34,7 +32,6 @@ import net.corda.finance.contracts.asset.CASH
|
|||||||
import net.corda.finance.contracts.asset.Cash
|
import net.corda.finance.contracts.asset.Cash
|
||||||
import net.corda.finance.flows.TwoPartyTradeFlow.Buyer
|
import net.corda.finance.flows.TwoPartyTradeFlow.Buyer
|
||||||
import net.corda.finance.flows.TwoPartyTradeFlow.Seller
|
import net.corda.finance.flows.TwoPartyTradeFlow.Seller
|
||||||
import net.corda.node.services.api.IdentityServiceInternal
|
|
||||||
import net.corda.node.services.api.WritableTransactionStorage
|
import net.corda.node.services.api.WritableTransactionStorage
|
||||||
import net.corda.node.services.persistence.DBTransactionStorage
|
import net.corda.node.services.persistence.DBTransactionStorage
|
||||||
import net.corda.node.services.persistence.checkpoints
|
import net.corda.node.services.persistence.checkpoints
|
||||||
@ -45,9 +42,7 @@ import net.corda.testing.dsl.TestLedgerDSLInterpreter
|
|||||||
import net.corda.testing.dsl.TestTransactionDSLInterpreter
|
import net.corda.testing.dsl.TestTransactionDSLInterpreter
|
||||||
import net.corda.testing.internal.LogHelper
|
import net.corda.testing.internal.LogHelper
|
||||||
import net.corda.testing.internal.TEST_TX_TIME
|
import net.corda.testing.internal.TEST_TX_TIME
|
||||||
import net.corda.testing.internal.rigorousMock
|
|
||||||
import net.corda.testing.internal.vault.VaultFiller
|
import net.corda.testing.internal.vault.VaultFiller
|
||||||
import net.corda.testing.node.MockServices
|
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.*
|
||||||
import net.corda.testing.node.ledger
|
import net.corda.testing.node.ledger
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
@ -71,6 +66,7 @@ import kotlin.test.assertTrue
|
|||||||
*
|
*
|
||||||
* We assume that Alice and Bob already found each other via some market, and have agreed the details already.
|
* We assume that Alice and Bob already found each other via some market, and have agreed the details already.
|
||||||
*/
|
*/
|
||||||
|
// TODO These tests need serious cleanup.
|
||||||
@RunWith(Parameterized::class)
|
@RunWith(Parameterized::class)
|
||||||
class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -80,7 +76,6 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
fun data(): Collection<Boolean> = listOf(true, false)
|
fun data(): Collection<Boolean> = listOf(true, false)
|
||||||
|
|
||||||
private val dummyNotary = TestIdentity(DUMMY_NOTARY_NAME, 20)
|
private val dummyNotary = TestIdentity(DUMMY_NOTARY_NAME, 20)
|
||||||
private val MEGA_CORP = TestIdentity(CordaX500Name("MegaCorp", "London", "GB")).party
|
|
||||||
private val DUMMY_NOTARY get() = dummyNotary.party
|
private val DUMMY_NOTARY get() = dummyNotary.party
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,17 +100,15 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
// we run in the unit test thread exclusively to speed things up, ensure deterministic results and
|
// we run in the unit test thread exclusively to speed things up, ensure deterministic results and
|
||||||
// allow interruption half way through.
|
// allow interruption half way through.
|
||||||
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages), threadPerNode = true)
|
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages), threadPerNode = true)
|
||||||
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
|
|
||||||
MockServices(cordappPackages, MEGA_CORP.name, ledgerIdentityService).ledger(DUMMY_NOTARY) {
|
|
||||||
val notaryNode = mockNet.defaultNotaryNode
|
val notaryNode = mockNet.defaultNotaryNode
|
||||||
|
val notary = mockNet.defaultNotaryIdentity
|
||||||
|
notaryNode.services.ledger(notary) {
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||||
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||||
val alice = aliceNode.info.singleIdentity()
|
val alice = aliceNode.info.singleIdentity()
|
||||||
val bank = bankNode.info.singleIdentity()
|
val bank = bankNode.info.singleIdentity()
|
||||||
doReturn(null).whenever(ledgerIdentityService).partyFromKey(bank.owningKey)
|
|
||||||
val bob = bobNode.info.singleIdentity()
|
val bob = bobNode.info.singleIdentity()
|
||||||
val notary = mockNet.defaultNotaryIdentity
|
|
||||||
val cashIssuer = bank.ref(1)
|
val cashIssuer = bank.ref(1)
|
||||||
val cpIssuer = bank.ref(1, 2, 3)
|
val cpIssuer = bank.ref(1, 2, 3)
|
||||||
|
|
||||||
@ -157,15 +150,13 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
@Test(expected = InsufficientBalanceException::class)
|
@Test(expected = InsufficientBalanceException::class)
|
||||||
fun `trade cash for commercial paper fails using soft locking`() {
|
fun `trade cash for commercial paper fails using soft locking`() {
|
||||||
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages), threadPerNode = true)
|
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages), threadPerNode = true)
|
||||||
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
|
|
||||||
MockServices(cordappPackages, MEGA_CORP.name, ledgerIdentityService).ledger(DUMMY_NOTARY) {
|
|
||||||
val notaryNode = mockNet.defaultNotaryNode
|
val notaryNode = mockNet.defaultNotaryNode
|
||||||
|
notaryNode.services.ledger(notaryNode.info.singleIdentity()) {
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||||
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||||
val alice = aliceNode.info.singleIdentity()
|
val alice = aliceNode.info.singleIdentity()
|
||||||
val bank = bankNode.info.singleIdentity()
|
val bank = bankNode.info.singleIdentity()
|
||||||
doReturn(null).whenever(ledgerIdentityService).partyFromKey(bank.owningKey)
|
|
||||||
val bob = bobNode.info.singleIdentity()
|
val bob = bobNode.info.singleIdentity()
|
||||||
val issuer = bank.ref(1)
|
val issuer = bank.ref(1)
|
||||||
val notary = mockNet.defaultNotaryIdentity
|
val notary = mockNet.defaultNotaryIdentity
|
||||||
@ -215,9 +206,9 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
@Test
|
@Test
|
||||||
fun `shutdown and restore`() {
|
fun `shutdown and restore`() {
|
||||||
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages))
|
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages))
|
||||||
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
|
|
||||||
MockServices(cordappPackages, MEGA_CORP.name, ledgerIdentityService).ledger(DUMMY_NOTARY) {
|
|
||||||
val notaryNode = mockNet.defaultNotaryNode
|
val notaryNode = mockNet.defaultNotaryNode
|
||||||
|
val notary = mockNet.defaultNotaryIdentity
|
||||||
|
notaryNode.services.ledger(notary) {
|
||||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||||
var bobNode = mockNet.createPartyNode(BOB_NAME)
|
var bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||||
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||||
@ -227,10 +218,8 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
val bobAddr = bobNode.network.myAddress
|
val bobAddr = bobNode.network.myAddress
|
||||||
mockNet.runNetwork() // Clear network map registration messages
|
mockNet.runNetwork() // Clear network map registration messages
|
||||||
|
|
||||||
val notary = mockNet.defaultNotaryIdentity
|
|
||||||
val alice = aliceNode.info.singleIdentity()
|
val alice = aliceNode.info.singleIdentity()
|
||||||
val bank = bankNode.info.singleIdentity()
|
val bank = bankNode.info.singleIdentity()
|
||||||
doReturn(null).whenever(ledgerIdentityService).partyFromKey(bank.owningKey)
|
|
||||||
val bob = bobNode.info.singleIdentity()
|
val bob = bobNode.info.singleIdentity()
|
||||||
val issuer = bank.ref(1, 2, 3)
|
val issuer = bank.ref(1, 2, 3)
|
||||||
|
|
||||||
@ -336,7 +325,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
val bob = bobNode.info.singleIdentity()
|
val bob = bobNode.info.singleIdentity()
|
||||||
val bank = bankNode.info.singleIdentity()
|
val bank = bankNode.info.singleIdentity()
|
||||||
val issuer = bank.ref(1, 2, 3)
|
val issuer = bank.ref(1, 2, 3)
|
||||||
aliceNode.services.ledger(DUMMY_NOTARY) {
|
aliceNode.services.ledger(notary) {
|
||||||
// Insert a prospectus type attachment into the commercial paper transaction.
|
// Insert a prospectus type attachment into the commercial paper transaction.
|
||||||
val stream = ByteArrayOutputStream()
|
val stream = ByteArrayOutputStream()
|
||||||
JarOutputStream(stream).use {
|
JarOutputStream(stream).use {
|
||||||
@ -440,7 +429,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
val bank: Party = bankNode.info.singleIdentity()
|
val bank: Party = bankNode.info.singleIdentity()
|
||||||
val bob = bobNode.info.singleIdentity()
|
val bob = bobNode.info.singleIdentity()
|
||||||
val issuer = bank.ref(1, 2, 3)
|
val issuer = bank.ref(1, 2, 3)
|
||||||
aliceNode.services.ledger(DUMMY_NOTARY) {
|
aliceNode.services.ledger(notary) {
|
||||||
// Insert a prospectus type attachment into the commercial paper transaction.
|
// Insert a prospectus type attachment into the commercial paper transaction.
|
||||||
val stream = ByteArrayOutputStream()
|
val stream = ByteArrayOutputStream()
|
||||||
JarOutputStream(stream).use {
|
JarOutputStream(stream).use {
|
||||||
@ -508,18 +497,16 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
@Test
|
@Test
|
||||||
fun `dependency with error on buyer side`() {
|
fun `dependency with error on buyer side`() {
|
||||||
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages))
|
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages))
|
||||||
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
|
mockNet.defaultNotaryNode.services.ledger(DUMMY_NOTARY) {
|
||||||
MockServices(cordappPackages, MEGA_CORP.name, ledgerIdentityService).ledger(DUMMY_NOTARY) {
|
runWithError(true, false, "at least one cash input")
|
||||||
runWithError(ledgerIdentityService, true, false, "at least one cash input")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `dependency with error on seller side`() {
|
fun `dependency with error on seller side`() {
|
||||||
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages))
|
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages(cordappPackages))
|
||||||
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
|
mockNet.defaultNotaryNode.services.ledger(DUMMY_NOTARY) {
|
||||||
MockServices(cordappPackages, MEGA_CORP.name, ledgerIdentityService).ledger(DUMMY_NOTARY) {
|
runWithError(false, true, "Issuances have a time-window")
|
||||||
runWithError(ledgerIdentityService, false, true, "Issuances have a time-window")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,7 +568,6 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
data class TestTx(val notaryIdentity: Party, val price: Amount<Currency>, val anonymous: Boolean)
|
data class TestTx(val notaryIdentity: Party, val price: Amount<Currency>, val anonymous: Boolean)
|
||||||
|
|
||||||
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.runWithError(
|
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.runWithError(
|
||||||
ledgerIdentityService: IdentityServiceInternal,
|
|
||||||
bobError: Boolean,
|
bobError: Boolean,
|
||||||
aliceError: Boolean,
|
aliceError: Boolean,
|
||||||
expectedMessageSubstring: String
|
expectedMessageSubstring: String
|
||||||
@ -595,7 +581,6 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
val alice = aliceNode.info.singleIdentity()
|
val alice = aliceNode.info.singleIdentity()
|
||||||
val bob = bobNode.info.singleIdentity()
|
val bob = bobNode.info.singleIdentity()
|
||||||
val bank = bankNode.info.singleIdentity()
|
val bank = bankNode.info.singleIdentity()
|
||||||
doReturn(null).whenever(ledgerIdentityService).partyFromKey(bank.owningKey)
|
|
||||||
val issuer = bank.ref(1, 2, 3)
|
val issuer = bank.ref(1, 2, 3)
|
||||||
|
|
||||||
val bobsBadCash = bobNode.database.transaction {
|
val bobsBadCash = bobNode.database.transaction {
|
||||||
@ -624,7 +609,6 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun insertFakeTransactions(
|
private fun insertFakeTransactions(
|
||||||
wtxToSign: List<WireTransaction>,
|
wtxToSign: List<WireTransaction>,
|
||||||
node: TestStartedNode,
|
node: TestStartedNode,
|
||||||
@ -736,7 +720,6 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
return Pair(vault, listOf(ap))
|
return Pair(vault, listOf(ap))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class RecordingTransactionStorage(
|
class RecordingTransactionStorage(
|
||||||
private val database: CordaPersistence,
|
private val database: CordaPersistence,
|
||||||
private val delegate: WritableTransactionStorage
|
private val delegate: WritableTransactionStorage
|
||||||
@ -777,5 +760,4 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
data class Add(val transaction: SignedTransaction) : TxRecord
|
data class Add(val transaction: SignedTransaction) : TxRecord
|
||||||
data class Get(val id: SecureHash) : TxRecord
|
data class Get(val id: SecureHash) : TxRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,132 @@
|
|||||||
|
package net.corda.node.services.network
|
||||||
|
|
||||||
|
import com.nhaarman.mockito_kotlin.any
|
||||||
|
import com.nhaarman.mockito_kotlin.mock
|
||||||
|
import com.nhaarman.mockito_kotlin.times
|
||||||
|
import com.nhaarman.mockito_kotlin.verify
|
||||||
|
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream
|
||||||
|
import net.corda.core.crypto.SecureHash
|
||||||
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
|
import net.corda.core.node.services.NetworkParametersStorage
|
||||||
|
import net.corda.node.internal.DBNetworkParametersStorage
|
||||||
|
import net.corda.nodeapi.internal.createDevNetworkMapCa
|
||||||
|
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
||||||
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
|
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||||
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
|
import net.corda.testing.internal.DEV_INTERMEDIATE_CA
|
||||||
|
import net.corda.testing.internal.DEV_ROOT_CA
|
||||||
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
|
import net.corda.testing.internal.configureDatabase
|
||||||
|
import net.corda.testing.node.MockServices
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import java.io.PrintStream
|
||||||
|
import kotlin.streams.toList
|
||||||
|
|
||||||
|
class DBNetworkParametersStorageTest {
|
||||||
|
@Rule
|
||||||
|
@JvmField
|
||||||
|
val testSerialization = SerializationEnvironmentRule(true)
|
||||||
|
|
||||||
|
private lateinit var networkMapClient: NetworkMapClient
|
||||||
|
private lateinit var nodeParametersStorage: NetworkParametersStorage
|
||||||
|
private lateinit var database: CordaPersistence
|
||||||
|
|
||||||
|
private val certKeyPair: CertificateAndKeyPair = createDevNetworkMapCa()
|
||||||
|
private lateinit var netParams1: SignedDataWithCert<NetworkParameters>
|
||||||
|
private lateinit var netParams2: SignedDataWithCert<NetworkParameters>
|
||||||
|
private lateinit var incorrectParams: SignedDataWithCert<NetworkParameters>
|
||||||
|
private lateinit var hash1: SecureHash
|
||||||
|
private lateinit var hash2: SecureHash
|
||||||
|
private lateinit var hash3: SecureHash
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
netParams1 = certKeyPair.sign(testNetworkParameters(minimumPlatformVersion = 1))
|
||||||
|
netParams2 = certKeyPair.sign(testNetworkParameters(minimumPlatformVersion = 2))
|
||||||
|
incorrectParams = createDevNetworkMapCa(DEV_INTERMEDIATE_CA).sign(testNetworkParameters(minimumPlatformVersion = 3))
|
||||||
|
hash1 = netParams1.raw.hash
|
||||||
|
hash2 = netParams2.raw.hash
|
||||||
|
hash3 = incorrectParams.raw.hash
|
||||||
|
database = configureDatabase(
|
||||||
|
MockServices.makeTestDataSourceProperties(),
|
||||||
|
DatabaseConfig(),
|
||||||
|
{ null },
|
||||||
|
{ null }
|
||||||
|
)
|
||||||
|
networkMapClient = createMockNetworkMapClient()
|
||||||
|
nodeParametersStorage = DBNetworkParametersStorage(TestingNamedCacheFactory(), database, networkMapClient).apply {
|
||||||
|
database.transaction {
|
||||||
|
start(netParams1, DEV_ROOT_CA.certificate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
database.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `set current parameters`() {
|
||||||
|
assertThat(nodeParametersStorage.currentHash).isEqualTo(hash1)
|
||||||
|
assertThat(nodeParametersStorage.lookup(hash1)).isEqualTo(netParams1.verified())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `get default parameters`() {
|
||||||
|
// TODO After implementing default endpoint on network map check it is correct, for now we set it to current.
|
||||||
|
assertThat(nodeParametersStorage.defaultHash).isEqualTo(hash1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `download parameters from network map server`() {
|
||||||
|
database.transaction {
|
||||||
|
val netParams = nodeParametersStorage.lookup(hash2)
|
||||||
|
assertThat(nodeParametersStorage.lookup(hash2)).isEqualTo(netParams)
|
||||||
|
verify(networkMapClient, times(1)).getNetworkParameters(hash2)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `try save parameters with incorrect signature`() {
|
||||||
|
database.transaction {
|
||||||
|
val consoleOutput = interceptConsoleOutput {
|
||||||
|
nodeParametersStorage.lookup(hash3)
|
||||||
|
}
|
||||||
|
assertThat(consoleOutput).anySatisfy {
|
||||||
|
it.contains("Caused by: java.security.cert.CertPathValidatorException: subject/issuer name chaining check failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun interceptConsoleOutput(block: () -> Unit): List<String> {
|
||||||
|
val oldOut = System.out
|
||||||
|
val out = ByteOutputStream()
|
||||||
|
System.setOut(PrintStream(out))
|
||||||
|
block()
|
||||||
|
System.setOut(oldOut)
|
||||||
|
return out.bytes.inputStream().bufferedReader().lines().toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createMockNetworkMapClient(): NetworkMapClient {
|
||||||
|
return mock {
|
||||||
|
on { getNetworkParameters(any()) }.then {
|
||||||
|
val hash = it.getArguments()[0]
|
||||||
|
when (hash) {
|
||||||
|
hash1 -> netParams1
|
||||||
|
hash2 -> netParams2
|
||||||
|
hash3 -> incorrectParams
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ import net.corda.node.VersionInfo
|
|||||||
import net.corda.node.services.api.NetworkMapCacheInternal
|
import net.corda.node.services.api.NetworkMapCacheInternal
|
||||||
import net.corda.node.services.config.NetworkParameterAcceptanceSettings
|
import net.corda.node.services.config.NetworkParameterAcceptanceSettings
|
||||||
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
||||||
|
import net.corda.node.internal.NetworkParametersStorageInternal
|
||||||
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
||||||
import net.corda.nodeapi.internal.SignedNodeInfo
|
import net.corda.nodeapi.internal.SignedNodeInfo
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
@ -64,6 +65,7 @@ class NetworkMapUpdaterTest {
|
|||||||
private val networkMapCache = createMockNetworkMapCache()
|
private val networkMapCache = createMockNetworkMapCache()
|
||||||
private lateinit var ourKeyPair: KeyPair
|
private lateinit var ourKeyPair: KeyPair
|
||||||
private lateinit var ourNodeInfo: SignedNodeInfo
|
private lateinit var ourNodeInfo: SignedNodeInfo
|
||||||
|
private val networkParametersStorage: NetworkParametersStorageInternal = mock()
|
||||||
private lateinit var server: NetworkMapServer
|
private lateinit var server: NetworkMapServer
|
||||||
private lateinit var networkMapClient: NetworkMapClient
|
private lateinit var networkMapClient: NetworkMapClient
|
||||||
private lateinit var updater: NetworkMapUpdater
|
private lateinit var updater: NetworkMapUpdater
|
||||||
@ -86,7 +88,7 @@ class NetworkMapUpdaterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpdater(extraNetworkMapKeys: List<UUID> = emptyList(), netMapClient: NetworkMapClient? = networkMapClient) {
|
private fun setUpdater(extraNetworkMapKeys: List<UUID> = emptyList(), netMapClient: NetworkMapClient? = networkMapClient) {
|
||||||
updater = NetworkMapUpdater(networkMapCache, fileWatcher, netMapClient, baseDir, extraNetworkMapKeys)
|
updater = NetworkMapUpdater(networkMapCache, fileWatcher, netMapClient, baseDir, extraNetworkMapKeys, networkParametersStorage)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startUpdater(ourNodeInfo: SignedNodeInfo = this.ourNodeInfo,
|
private fun startUpdater(ourNodeInfo: SignedNodeInfo = this.ourNodeInfo,
|
||||||
@ -236,6 +238,7 @@ class NetworkMapUpdaterTest {
|
|||||||
val updateFile = baseDir / NETWORK_PARAMS_UPDATE_FILE_NAME
|
val updateFile = baseDir / NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||||
assert(!updateFile.exists()) { "network parameters should not be auto accepted" }
|
assert(!updateFile.exists()) { "network parameters should not be auto accepted" }
|
||||||
updater.acceptNewNetworkParameters(newHash) { it.serialize().sign(ourKeyPair) }
|
updater.acceptNewNetworkParameters(newHash) { it.serialize().sign(ourKeyPair) }
|
||||||
|
verify(networkParametersStorage, times(1)).saveParameters(any())
|
||||||
val signedNetworkParams = updateFile.readObject<SignedNetworkParameters>()
|
val signedNetworkParams = updateFile.readObject<SignedNetworkParameters>()
|
||||||
val paramsFromFile = signedNetworkParams.verifiedNetworkParametersCert(DEV_ROOT_CA.certificate)
|
val paramsFromFile = signedNetworkParams.verifiedNetworkParametersCert(DEV_ROOT_CA.certificate)
|
||||||
assertEquals(newParameters, paramsFromFile)
|
assertEquals(newParameters, paramsFromFile)
|
||||||
|
@ -4,21 +4,18 @@ import co.paralleluniverse.fibers.Suspendable
|
|||||||
import com.esotericsoftware.kryo.KryoException
|
import com.esotericsoftware.kryo.KryoException
|
||||||
import net.corda.core.contracts.UniqueIdentifier
|
import net.corda.core.contracts.UniqueIdentifier
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.FlowLogic.Companion.sleep
|
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.schemas.MappedSchema
|
import net.corda.core.schemas.MappedSchema
|
||||||
import net.corda.core.serialization.CordaSerializable
|
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import net.corda.testing.node.makeTestIdentityService
|
import net.corda.testing.node.makeTestIdentityService
|
||||||
import org.junit.BeforeClass
|
import org.junit.After
|
||||||
import org.junit.ClassRule
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.time.Duration
|
|
||||||
import javax.persistence.Column
|
import javax.persistence.Column
|
||||||
import javax.persistence.Entity
|
import javax.persistence.Entity
|
||||||
import javax.persistence.Id
|
import javax.persistence.Id
|
||||||
@ -26,7 +23,6 @@ import javax.persistence.Table
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
|
|
||||||
class ExposeJpaToFlowsTests {
|
class ExposeJpaToFlowsTests {
|
||||||
|
|
||||||
object FooSchema
|
object FooSchema
|
||||||
@ -39,15 +35,28 @@ class ExposeJpaToFlowsTests {
|
|||||||
|
|
||||||
val myself = TestIdentity(CordaX500Name("Me", "London", "GB"))
|
val myself = TestIdentity(CordaX500Name("Me", "London", "GB"))
|
||||||
val cordapps = listOf("net.corda.node.services.persistence")
|
val cordapps = listOf("net.corda.node.services.persistence")
|
||||||
val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(
|
lateinit var mockNet: MockNetwork
|
||||||
|
lateinit var services: MockServices
|
||||||
|
lateinit var database: CordaPersistence
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
mockNet = MockNetwork(cordapps)
|
||||||
|
val (db, mockServices) = MockServices.makeTestDatabaseAndMockServices(
|
||||||
cordappPackages = cordapps,
|
cordappPackages = cordapps,
|
||||||
identityService = makeTestIdentityService(myself.identity),
|
identityService = makeTestIdentityService(myself.identity),
|
||||||
initialIdentity = myself,
|
initialIdentity = myself,
|
||||||
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
||||||
)
|
)
|
||||||
|
|
||||||
val services: MockServices = databaseAndServices.second
|
services = mockServices
|
||||||
val database: CordaPersistence = databaseAndServices.first
|
database = db
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun cleanUp() {
|
||||||
|
mockNet.stopNodes()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `can persist and query custom entities`() {
|
fun `can persist and query custom entities`() {
|
||||||
@ -71,7 +80,6 @@ class ExposeJpaToFlowsTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `can't perform suspendable operations inside withEntityManager`() {
|
fun `can't perform suspendable operations inside withEntityManager`() {
|
||||||
val mockNet = MockNetwork(cordapps)
|
|
||||||
val mockNode = mockNet.createNode()
|
val mockNode = mockNet.createNode()
|
||||||
assertFailsWith(KryoException::class) {
|
assertFailsWith(KryoException::class) {
|
||||||
mockNode.startFlow(object : FlowLogic<Unit>() {
|
mockNode.startFlow(object : FlowLogic<Unit>() {
|
||||||
@ -84,6 +92,5 @@ class ExposeJpaToFlowsTests {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
mockNet.stopNodes()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,8 +4,6 @@ import co.paralleluniverse.fibers.Suspendable
|
|||||||
import com.codahale.metrics.MetricRegistry
|
import com.codahale.metrics.MetricRegistry
|
||||||
import com.google.common.jimfs.Configuration
|
import com.google.common.jimfs.Configuration
|
||||||
import com.google.common.jimfs.Jimfs
|
import com.google.common.jimfs.Jimfs
|
||||||
import com.nhaarman.mockito_kotlin.doReturn
|
|
||||||
import com.nhaarman.mockito_kotlin.whenever
|
|
||||||
import net.corda.core.contracts.ContractAttachment
|
import net.corda.core.contracts.ContractAttachment
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.sha256
|
import net.corda.core.crypto.sha256
|
||||||
@ -20,7 +18,6 @@ import net.corda.core.utilities.getOrThrow
|
|||||||
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
||||||
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.common.internal.testNetworkParameters
|
|
||||||
import net.corda.testing.core.ALICE_NAME
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.core.JarSignatureTestUtils.createJar
|
import net.corda.testing.core.JarSignatureTestUtils.createJar
|
||||||
import net.corda.testing.core.JarSignatureTestUtils.generateKey
|
import net.corda.testing.core.JarSignatureTestUtils.generateKey
|
||||||
@ -33,7 +30,10 @@ import net.corda.testing.node.MockServices.Companion.makeTestDataSourcePropertie
|
|||||||
import net.corda.testing.node.internal.InternalMockNetwork
|
import net.corda.testing.node.internal.InternalMockNetwork
|
||||||
import net.corda.testing.node.internal.startFlow
|
import net.corda.testing.node.internal.startFlow
|
||||||
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||||
import org.junit.*
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Ignore
|
||||||
|
import org.junit.Test
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
@ -52,7 +52,6 @@ import kotlin.test.assertFailsWith
|
|||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
|
|
||||||
class NodeAttachmentServiceTest {
|
class NodeAttachmentServiceTest {
|
||||||
|
|
||||||
// Use an in memory file system for testing attachment storage.
|
// Use an in memory file system for testing attachment storage.
|
||||||
@ -69,8 +68,6 @@ class NodeAttachmentServiceTest {
|
|||||||
database = configureDatabase(dataSourceProperties, DatabaseConfig(runMigration = true), { null }, { null })
|
database = configureDatabase(dataSourceProperties, DatabaseConfig(runMigration = true), { null }, { null })
|
||||||
fs = Jimfs.newFileSystem(Configuration.unix())
|
fs = Jimfs.newFileSystem(Configuration.unix())
|
||||||
|
|
||||||
doReturn(testNetworkParameters()).whenever(services).networkParameters
|
|
||||||
|
|
||||||
storage = NodeAttachmentService(MetricRegistry(), TestingNamedCacheFactory(), database).also {
|
storage = NodeAttachmentService(MetricRegistry(), TestingNamedCacheFactory(), database).also {
|
||||||
database.transaction {
|
database.transaction {
|
||||||
it.start()
|
it.start()
|
||||||
@ -427,5 +424,4 @@ class NodeAttachmentServiceTest {
|
|||||||
return Paths.get(fileManager.list(StandardLocation.CLASS_OUTPUT, "", setOf(JavaFileObject.Kind.CLASS), true).single().name)
|
return Paths.get(fileManager.list(StandardLocation.CLASS_OUTPUT, "", setOf(JavaFileObject.Kind.CLASS), true).single().name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ class MaxTransactionSizeTests {
|
|||||||
mockNet = MockNetwork(listOf("net.corda.testing.contracts"), networkParameters = testNetworkParameters(maxTransactionSize = 3_000_000))
|
mockNet = MockNetwork(listOf("net.corda.testing.contracts"), networkParameters = testNetworkParameters(maxTransactionSize = 3_000_000))
|
||||||
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
||||||
bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
|
bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
|
||||||
|
bobNode.registerInitiatedFlow(ReceiveLargeTransactionFlow::class.java)
|
||||||
notaryNode = mockNet.defaultNotaryNode
|
notaryNode = mockNet.defaultNotaryNode
|
||||||
notary = mockNet.defaultNotaryIdentity
|
notary = mockNet.defaultNotaryIdentity
|
||||||
alice = aliceNode.info.singleIdentity()
|
alice = aliceNode.info.singleIdentity()
|
||||||
|
@ -3,18 +3,23 @@ package net.corda.node.services.transactions
|
|||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.contracts.StateRef
|
import net.corda.core.contracts.StateRef
|
||||||
import net.corda.core.crypto.*
|
import net.corda.core.crypto.*
|
||||||
|
import net.corda.core.flows.NotaryError
|
||||||
import net.corda.core.flows.NotaryException
|
import net.corda.core.flows.NotaryException
|
||||||
import net.corda.core.flows.NotaryFlow
|
import net.corda.core.flows.NotaryFlow
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.NotaryChangeTransactionBuilder
|
import net.corda.core.internal.NotaryChangeTransactionBuilder
|
||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
|
import net.corda.core.serialization.serialize
|
||||||
|
import net.corda.core.transactions.NotaryChangeWireTransaction
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
|
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.DUMMY_NOTARY_NAME
|
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||||
import net.corda.testing.core.singleIdentity
|
import net.corda.testing.core.singleIdentity
|
||||||
import net.corda.testing.node.MockNetworkNotarySpec
|
import net.corda.testing.node.MockNetworkNotarySpec
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.*
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -31,7 +36,8 @@ class NotaryServiceTests {
|
|||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = InternalMockNetwork(
|
mockNet = InternalMockNetwork(
|
||||||
cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts"),
|
cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts"),
|
||||||
notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME, validating = false))
|
notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME, validating = false)),
|
||||||
|
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
||||||
)
|
)
|
||||||
aliceNode = mockNet.createNode(InternalMockNodeParameters(legalName = ALICE_NAME))
|
aliceNode = mockNet.createNode(InternalMockNodeParameters(legalName = ALICE_NAME))
|
||||||
notaryServices = mockNet.defaultNotaryNode.services //TODO get rid of that
|
notaryServices = mockNet.defaultNotaryNode.services //TODO get rid of that
|
||||||
@ -49,6 +55,28 @@ class NotaryServiceTests {
|
|||||||
notariseWithTooManyInputs(aliceNode, alice, notary, mockNet)
|
notariseWithTooManyInputs(aliceNode, alice, notary, mockNet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should reject when network parameters component is not visible`() {
|
||||||
|
val stx = generateTransaction(aliceNode, alice, notary, null, 13)
|
||||||
|
val future = aliceNode.services.startFlow(DummyClientFlow(stx, notary)).resultFuture
|
||||||
|
mockNet.runNetwork()
|
||||||
|
val ex = assertFailsWith<NotaryException> { future.getOrThrow() }
|
||||||
|
val notaryError = ex.error as NotaryError.TransactionInvalid
|
||||||
|
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation was tagged with parameters with hash: null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should reject when parameters not current`() {
|
||||||
|
val hash = SecureHash.randomSHA256()
|
||||||
|
val stx = generateTransaction(aliceNode, alice, notary, hash, 13)
|
||||||
|
val future = aliceNode.services.startFlow(DummyClientFlow(stx, notary)).resultFuture
|
||||||
|
mockNet.runNetwork()
|
||||||
|
val ex = assertFailsWith<NotaryException> { future.getOrThrow() }
|
||||||
|
val notaryError = ex.error as NotaryError.TransactionInvalid
|
||||||
|
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation was tagged with parameters with hash: $hash, " +
|
||||||
|
"but current network parameters are: ${notaryServices.networkParametersStorage.currentHash}")
|
||||||
|
}
|
||||||
|
|
||||||
internal companion object {
|
internal companion object {
|
||||||
/** This is used by both [NotaryServiceTests] and [ValidatingNotaryServiceTests]. */
|
/** This is used by both [NotaryServiceTests] and [ValidatingNotaryServiceTests]. */
|
||||||
fun notariseWithTooManyInputs(node: TestStartedNode, party: Party, notary: Party, network: InternalMockNetwork) {
|
fun notariseWithTooManyInputs(node: TestStartedNode, party: Party, notary: Party, network: InternalMockNetwork) {
|
||||||
@ -59,10 +87,17 @@ class NotaryServiceTests {
|
|||||||
assertFailsWith<NotaryException> { future.getOrThrow() }
|
assertFailsWith<NotaryException> { future.getOrThrow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateTransaction(node: TestStartedNode, party: Party, notary: Party): SignedTransaction {
|
private fun generateTransaction(node: TestStartedNode,
|
||||||
|
party: Party, notary: Party,
|
||||||
|
paramsHash: SecureHash? = node.services.networkParametersStorage.currentHash,
|
||||||
|
numberOfInputs: Int = 10_005): SignedTransaction {
|
||||||
val txHash = SecureHash.randomSHA256()
|
val txHash = SecureHash.randomSHA256()
|
||||||
val inputs = (1..10_005).map { StateRef(txHash, it) }
|
val inputs = (1..numberOfInputs).map { StateRef(txHash, it) }
|
||||||
val tx = NotaryChangeTransactionBuilder(inputs, notary, party).build()
|
val tx = if (paramsHash != null) {
|
||||||
|
NotaryChangeTransactionBuilder(inputs, notary, party, paramsHash).build()
|
||||||
|
} else {
|
||||||
|
NotaryChangeWireTransaction(listOf(inputs, notary, party).map { it.serialize() })
|
||||||
|
}
|
||||||
|
|
||||||
return node.services.run {
|
return node.services.run {
|
||||||
val myKey = myInfo.legalIdentities.first().owningKey
|
val myKey = myInfo.legalIdentities.first().owningKey
|
||||||
|
@ -11,6 +11,7 @@ import net.corda.testing.core.SerializationEnvironmentRule
|
|||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import net.corda.testing.node.makeTestIdentityService
|
import net.corda.testing.node.makeTestIdentityService
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
@ -25,14 +26,7 @@ class ResolveStatePointersTest {
|
|||||||
private val myself = TestIdentity(CordaX500Name("Me", "London", "GB"))
|
private val myself = TestIdentity(CordaX500Name("Me", "London", "GB"))
|
||||||
private val notary = TestIdentity(DUMMY_NOTARY_NAME, 20)
|
private val notary = TestIdentity(DUMMY_NOTARY_NAME, 20)
|
||||||
private val cordapps = listOf("net.corda.testing.contracts")
|
private val cordapps = listOf("net.corda.testing.contracts")
|
||||||
private val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(
|
private lateinit var services: MockServices
|
||||||
cordappPackages = cordapps,
|
|
||||||
identityService = makeTestIdentityService(notary.identity, myself.identity),
|
|
||||||
initialIdentity = myself,
|
|
||||||
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
|
||||||
)
|
|
||||||
|
|
||||||
private val services = databaseAndServices.second
|
|
||||||
|
|
||||||
private data class Bar(
|
private data class Bar(
|
||||||
override val participants: List<AbstractParty> = listOf(),
|
override val participants: List<AbstractParty> = listOf(),
|
||||||
@ -58,6 +52,17 @@ class ResolveStatePointersTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(
|
||||||
|
cordappPackages = cordapps,
|
||||||
|
identityService = makeTestIdentityService(notary.identity, myself.identity),
|
||||||
|
initialIdentity = myself,
|
||||||
|
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
||||||
|
)
|
||||||
|
services = databaseAndServices.second
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `resolve state pointers and check reference state is added to transaction`() {
|
fun `resolve state pointers and check reference state is added to transaction`() {
|
||||||
val stateAndRef = createPointedToState(barOne)
|
val stateAndRef = createPointedToState(barOne)
|
||||||
@ -154,5 +159,4 @@ class ResolveStatePointersTest {
|
|||||||
val foo = ltx.outputs.single().data as Foo<Bar>
|
val foo = ltx.outputs.single().data as Foo<Bar>
|
||||||
assertEquals(stateAndRef, foo.baz.resolve(ltx))
|
assertEquals(stateAndRef, foo.baz.resolve(ltx))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package net.corda.node.services.transactions
|
|||||||
|
|
||||||
import net.corda.core.concurrent.CordaFuture
|
import net.corda.core.concurrent.CordaFuture
|
||||||
import net.corda.core.contracts.Command
|
import net.corda.core.contracts.Command
|
||||||
|
import net.corda.core.contracts.PrivacySalt
|
||||||
import net.corda.core.contracts.StateAndRef
|
import net.corda.core.contracts.StateAndRef
|
||||||
import net.corda.core.contracts.StateRef
|
import net.corda.core.contracts.StateRef
|
||||||
import net.corda.core.crypto.*
|
import net.corda.core.crypto.*
|
||||||
@ -14,16 +15,19 @@ import net.corda.core.serialization.deserialize
|
|||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
|
import net.corda.core.transactions.WireTransaction
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
import net.corda.node.services.issueInvalidState
|
import net.corda.node.services.issueInvalidState
|
||||||
import net.corda.node.services.messaging.Message
|
import net.corda.node.services.messaging.Message
|
||||||
import net.corda.node.services.statemachine.InitialSessionMessage
|
import net.corda.node.services.statemachine.InitialSessionMessage
|
||||||
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
import net.corda.testing.core.ALICE_NAME
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.core.dummyCommand
|
import net.corda.testing.core.dummyCommand
|
||||||
import net.corda.testing.core.singleIdentity
|
import net.corda.testing.core.singleIdentity
|
||||||
|
import net.corda.testing.internal.createWireTransaction
|
||||||
import net.corda.testing.node.TestClock
|
import net.corda.testing.node.TestClock
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.*
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
@ -46,7 +50,8 @@ class ValidatingNotaryServiceTests {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts"))
|
mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.testing.contracts"),
|
||||||
|
networkParameters = testNetworkParameters(minimumPlatformVersion = 4))
|
||||||
aliceNode = mockNet.createNode(InternalMockNodeParameters(legalName = ALICE_NAME))
|
aliceNode = mockNet.createNode(InternalMockNodeParameters(legalName = ALICE_NAME))
|
||||||
notaryNode = mockNet.defaultNotaryNode
|
notaryNode = mockNet.defaultNotaryNode
|
||||||
notary = mockNet.defaultNotaryIdentity
|
notary = mockNet.defaultNotaryIdentity
|
||||||
@ -96,6 +101,27 @@ class ValidatingNotaryServiceTests {
|
|||||||
assertEquals(setOf(expectedMissingKey), missingKeys)
|
assertEquals(setOf(expectedMissingKey), missingKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should reject transaction without network parameters`() {
|
||||||
|
val inputState = issueState(aliceNode.services, alice).ref
|
||||||
|
val wtx = createWireTransaction(inputs = listOf(inputState),
|
||||||
|
attachments = emptyList(),
|
||||||
|
outputs = emptyList(),
|
||||||
|
commands = listOf(dummyCommand(alice.owningKey)),
|
||||||
|
notary = notary,
|
||||||
|
timeWindow = null)
|
||||||
|
assertThat(wtx.networkParametersHash).isNull()
|
||||||
|
val sig = aliceNode.services.keyManagementService.sign(
|
||||||
|
SignableData(wtx.id, SignatureMetadata(1, Crypto.findSignatureScheme(alice.owningKey).schemeNumberID)), alice.owningKey
|
||||||
|
)
|
||||||
|
val stx = SignedTransaction(wtx, listOf(sig))
|
||||||
|
assertThat(stx.networkParametersHash).isNull()
|
||||||
|
val future = runNotaryClient(stx)
|
||||||
|
val ex = assertFailsWith(NotaryException::class) { future.getOrThrow() }
|
||||||
|
val notaryError = ex.error as NotaryError.TransactionInvalid
|
||||||
|
assertThat(notaryError.cause).hasMessageContaining("Transaction for notarisation was tagged with parameters with hash: null")
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `should sign a unique transaction with a valid time-window`() {
|
fun `should sign a unique transaction with a valid time-window`() {
|
||||||
val stx = run {
|
val stx = run {
|
||||||
|
@ -19,6 +19,7 @@ import net.corda.testing.core.SerializationEnvironmentRule
|
|||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -37,7 +38,13 @@ class ExternalIdMappingTest {
|
|||||||
|
|
||||||
private val myself = TestIdentity(CordaX500Name("Me", "London", "GB"))
|
private val myself = TestIdentity(CordaX500Name("Me", "London", "GB"))
|
||||||
private val notary = TestIdentity(CordaX500Name("NotaryService", "London", "GB"), 1337L)
|
private val notary = TestIdentity(CordaX500Name("NotaryService", "London", "GB"), 1337L)
|
||||||
private val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(
|
|
||||||
|
lateinit var services: MockServices
|
||||||
|
lateinit var database: CordaPersistence
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
val (db, mockServices) = MockServices.makeTestDatabaseAndMockServices(
|
||||||
cordappPackages = cordapps,
|
cordappPackages = cordapps,
|
||||||
identityService = rigorousMock<IdentityServiceInternal>().also {
|
identityService = rigorousMock<IdentityServiceInternal>().also {
|
||||||
doReturn(notary.party).whenever(it).partyFromKey(notary.publicKey)
|
doReturn(notary.party).whenever(it).partyFromKey(notary.publicKey)
|
||||||
@ -47,9 +54,9 @@ class ExternalIdMappingTest {
|
|||||||
initialIdentity = myself,
|
initialIdentity = myself,
|
||||||
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
||||||
)
|
)
|
||||||
|
services = mockServices
|
||||||
private val services: MockServices = databaseAndServices.second
|
database = db
|
||||||
private val database: CordaPersistence = databaseAndServices.first
|
}
|
||||||
|
|
||||||
private fun freshKeyForExternalId(externalId: UUID): AnonymousParty {
|
private fun freshKeyForExternalId(externalId: UUID): AnonymousParty {
|
||||||
val anonymousParty = freshKey()
|
val anonymousParty = freshKey()
|
||||||
|
@ -29,6 +29,7 @@ import net.corda.finance.utils.sumCash
|
|||||||
import net.corda.node.services.api.IdentityServiceInternal
|
import net.corda.node.services.api.IdentityServiceInternal
|
||||||
import net.corda.node.services.api.WritableTransactionStorage
|
import net.corda.node.services.api.WritableTransactionStorage
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
import net.corda.testing.contracts.DummyState
|
import net.corda.testing.contracts.DummyState
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
@ -90,17 +91,19 @@ class NodeVaultServiceTest {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
LogHelper.setLevel(NodeVaultService::class)
|
LogHelper.setLevel(NodeVaultService::class)
|
||||||
|
val parameters = testNetworkParameters()
|
||||||
val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(
|
val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(
|
||||||
cordappPackages,
|
cordappPackages,
|
||||||
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY),
|
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY),
|
||||||
megaCorp)
|
megaCorp,
|
||||||
|
parameters)
|
||||||
database = databaseAndServices.first
|
database = databaseAndServices.first
|
||||||
services = databaseAndServices.second
|
services = databaseAndServices.second
|
||||||
vaultFiller = VaultFiller(services, dummyNotary)
|
vaultFiller = VaultFiller(services, dummyNotary)
|
||||||
// This is safe because MockServices only ever have a single identity
|
// This is safe because MockServices only ever have a single identity
|
||||||
identity = services.myInfo.singleIdentityAndCert()
|
identity = services.myInfo.singleIdentityAndCert()
|
||||||
issuerServices = MockServices(cordappPackages, dummyCashIssuer, rigorousMock<IdentityService>())
|
issuerServices = MockServices(cordappPackages, dummyCashIssuer, rigorousMock<IdentityService>(), parameters)
|
||||||
bocServices = MockServices(cordappPackages, bankOfCorda, rigorousMock<IdentityService>())
|
bocServices = MockServices(cordappPackages, bankOfCorda, rigorousMock<IdentityService>(), parameters)
|
||||||
services.identityService.verifyAndRegisterIdentity(DUMMY_CASH_ISSUER_IDENTITY)
|
services.identityService.verifyAndRegisterIdentity(DUMMY_CASH_ISSUER_IDENTITY)
|
||||||
services.identityService.verifyAndRegisterIdentity(BOC_IDENTITY)
|
services.identityService.verifyAndRegisterIdentity(BOC_IDENTITY)
|
||||||
}
|
}
|
||||||
@ -571,7 +574,6 @@ class NodeVaultServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Unit test linear state relevancy checks
|
// TODO: Unit test linear state relevancy checks
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `correct updates are generated for general transactions`() {
|
fun `correct updates are generated for general transactions`() {
|
||||||
val notary = identity.party
|
val notary = identity.party
|
||||||
@ -647,7 +649,7 @@ class NodeVaultServiceTest {
|
|||||||
// Change notary
|
// Change notary
|
||||||
services.identityService.verifyAndRegisterIdentity(DUMMY_NOTARY_IDENTITY)
|
services.identityService.verifyAndRegisterIdentity(DUMMY_NOTARY_IDENTITY)
|
||||||
val newNotary = DUMMY_NOTARY
|
val newNotary = DUMMY_NOTARY
|
||||||
val changeNotaryTx = NotaryChangeTransactionBuilder(listOf(initialCashState.ref), issueStx.notary!!, newNotary).build()
|
val changeNotaryTx = NotaryChangeTransactionBuilder(listOf(initialCashState.ref), issueStx.notary!!, newNotary, services.networkParametersStorage.currentHash).build()
|
||||||
val cashStateWithNewNotary = StateAndRef(initialCashState.state.copy(notary = newNotary), StateRef(changeNotaryTx.id, 0))
|
val cashStateWithNewNotary = StateAndRef(initialCashState.state.copy(notary = newNotary), StateRef(changeNotaryTx.id, 0))
|
||||||
|
|
||||||
database.transaction {
|
database.transaction {
|
||||||
|
@ -16,6 +16,10 @@ import org.junit.rules.ExpectedException
|
|||||||
class VaultQueryExceptionsTests : VaultQueryParties by rule {
|
class VaultQueryExceptionsTests : VaultQueryParties by rule {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ClassRule
|
||||||
|
@JvmField
|
||||||
|
val testSerialization = SerializationEnvironmentRule()
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule
|
||||||
@JvmField
|
@JvmField
|
||||||
val rule = object : VaultQueryTestRule() {
|
val rule = object : VaultQueryTestRule() {
|
||||||
@ -26,10 +30,6 @@ class VaultQueryExceptionsTests : VaultQueryParties by rule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Rule
|
|
||||||
@JvmField
|
|
||||||
val testSerialization = SerializationEnvironmentRule()
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
@JvmField
|
@JvmField
|
||||||
val expectedEx: ExpectedException = ExpectedException.none()
|
val expectedEx: ExpectedException = ExpectedException.none()
|
||||||
|
@ -99,7 +99,6 @@ interface VaultQueryParties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class VaultQueryTestRule : ExternalResource(), VaultQueryParties {
|
open class VaultQueryTestRule : ExternalResource(), VaultQueryParties {
|
||||||
|
|
||||||
override val alice = TestIdentity(ALICE_NAME, 70)
|
override val alice = TestIdentity(ALICE_NAME, 70)
|
||||||
override val bankOfCorda = TestIdentity(BOC_NAME)
|
override val bankOfCorda = TestIdentity(BOC_NAME)
|
||||||
override val bigCorp = TestIdentity(CordaX500Name("BigCorporation", "New York", "US"))
|
override val bigCorp = TestIdentity(CordaX500Name("BigCorporation", "New York", "US"))
|
||||||
|
@ -9,7 +9,7 @@ import net.corda.core.crypto.SignatureScheme
|
|||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.nodeapi.internal.crypto.*
|
import net.corda.nodeapi.internal.crypto.*
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.NettyTestClient
|
import net.corda.testing.internal.NettyTestClient
|
||||||
import net.corda.testing.internal.NettyTestHandler
|
import net.corda.testing.internal.NettyTestHandler
|
||||||
import net.corda.testing.internal.NettyTestServer
|
import net.corda.testing.internal.NettyTestServer
|
||||||
@ -52,7 +52,7 @@ class NettyEngineBasedTlsAuthenticationTests(val sslSetup: SslSetup) {
|
|||||||
private fun tempFile(name: String): Path = tempFolder.root.toPath() / name
|
private fun tempFile(name: String): Path = tempFolder.root.toPath() / name
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
data class SslSetup(val clientNative: Boolean, val serverNative: Boolean) {
|
data class SslSetup(val clientNative: Boolean, val serverNative: Boolean) {
|
||||||
override fun toString(): String = "Client: ${if (clientNative) "openSsl" else "javaSsl"} Server: ${if (serverNative) "openSsl" else "javaSsl"} "
|
override fun toString(): String = "Client: ${if (clientNative) "openSsl" else "javaSsl"} Server: ${if (serverNative) "openSsl" else "javaSsl"} "
|
||||||
|
@ -15,8 +15,8 @@ import net.corda.node.services.Permissions.Companion.startFlow
|
|||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.InProcess
|
import net.corda.testing.driver.InProcess
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.driver.internal.internalServices
|
import net.corda.testing.driver.internal.internalServices
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
@ -127,7 +127,7 @@ class NodePerformanceTests : IntegrationTest() {
|
|||||||
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = listOf(user))),
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = listOf(user))),
|
||||||
startNodesInProcess = true,
|
startNodesInProcess = true,
|
||||||
extraCordappPackagesToScan = listOf("net.corda.finance", "com.r3.corda.enterprise.perftestcordapp"),
|
extraCordappPackagesToScan = listOf("net.corda.finance", "com.r3.corda.enterprise.perftestcordapp"),
|
||||||
portAllocation = PortAllocation.Incremental(20000)
|
portAllocation = incrementalPortAllocation(20000)
|
||||||
)) {
|
)) {
|
||||||
val notary = defaultNotaryNode.getOrThrow() as InProcess
|
val notary = defaultNotaryNode.getOrThrow() as InProcess
|
||||||
val metricRegistry = startReporter((this as InternalDriverDSL).shutdownManager, notary.internalServices.monitoringService.metrics)
|
val metricRegistry = startReporter((this as InternalDriverDSL).shutdownManager, notary.internalServices.monitoringService.metrics)
|
||||||
@ -151,7 +151,7 @@ class NodePerformanceTests : IntegrationTest() {
|
|||||||
driver(DriverParameters(
|
driver(DriverParameters(
|
||||||
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
|
||||||
startNodesInProcess = true,
|
startNodesInProcess = true,
|
||||||
portAllocation = PortAllocation.Incremental(20000)
|
portAllocation = incrementalPortAllocation(20000)
|
||||||
)) {
|
)) {
|
||||||
val aliceFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user), startInSameProcess = true)
|
val aliceFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user), startInSameProcess = true)
|
||||||
val alice = aliceFuture.getOrThrow() as InProcess
|
val alice = aliceFuture.getOrThrow() as InProcess
|
||||||
@ -176,7 +176,7 @@ class NodePerformanceTests : IntegrationTest() {
|
|||||||
driver(DriverParameters(
|
driver(DriverParameters(
|
||||||
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
|
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
|
||||||
startNodesInProcess = true,
|
startNodesInProcess = true,
|
||||||
portAllocation = PortAllocation.Incremental(20000)
|
portAllocation = incrementalPortAllocation(20000)
|
||||||
)) {
|
)) {
|
||||||
val aliceFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user))
|
val aliceFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user))
|
||||||
val bobFuture = startNode(providedName = BOB_NAME, rpcUsers = listOf(user))
|
val bobFuture = startNode(providedName = BOB_NAME, rpcUsers = listOf(user))
|
||||||
|
@ -9,7 +9,7 @@ import net.corda.finance.DOLLARS
|
|||||||
import net.corda.node.services.Permissions
|
import net.corda.node.services.Permissions
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.setGlobalSerialization
|
import net.corda.testing.internal.setGlobalSerialization
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import net.corda.testing.node.internal.DriverDSLImpl
|
import net.corda.testing.node.internal.DriverDSLImpl
|
||||||
@ -31,7 +31,7 @@ class CheckAllTheTestFlows {
|
|||||||
val driverParameters = DriverParameters(
|
val driverParameters = DriverParameters(
|
||||||
startNodesInProcess = true,
|
startNodesInProcess = true,
|
||||||
extraCordappPackagesToScan = listOf("com.r3.corda.enterprise.perftestcordapp"),
|
extraCordappPackagesToScan = listOf("com.r3.corda.enterprise.perftestcordapp"),
|
||||||
portAllocation = PortAllocation.Incremental(20000)
|
portAllocation = incrementalPortAllocation(20000)
|
||||||
)
|
)
|
||||||
val driver = DriverDSLImpl(
|
val driver = DriverDSLImpl(
|
||||||
portAllocation = driverParameters.portAllocation,
|
portAllocation = driverParameters.portAllocation,
|
||||||
|
@ -7,8 +7,8 @@ import net.corda.testing.core.DUMMY_BANK_A_NAME
|
|||||||
import net.corda.testing.core.DUMMY_BANK_B_NAME
|
import net.corda.testing.core.DUMMY_BANK_B_NAME
|
||||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||||
import net.corda.testing.driver.DriverParameters
|
import net.corda.testing.driver.DriverParameters
|
||||||
import net.corda.testing.driver.PortAllocation
|
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.internal.toDatabaseSchemaName
|
import net.corda.testing.internal.toDatabaseSchemaName
|
||||||
@ -28,7 +28,7 @@ class AttachmentDemoTest : IntegrationTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `attachment demo using a 10MB zip file`() {
|
fun `attachment demo using a 10MB zip file`() {
|
||||||
val numOfExpectedBytes = 10_000_000
|
val numOfExpectedBytes = 10_000_000
|
||||||
driver(DriverParameters(portAllocation = PortAllocation.Incremental(20000), startNodesInProcess = true)) {
|
driver(DriverParameters(portAllocation = incrementalPortAllocation(20000), startNodesInProcess = true)) {
|
||||||
val demoUser = listOf(User("demo", "demo", setOf(all())))
|
val demoUser = listOf(User("demo", "demo", setOf(all())))
|
||||||
val (nodeA, nodeB) = listOf(
|
val (nodeA, nodeB) = listOf(
|
||||||
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser, maximumHeapSize = "1g"),
|
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser, maximumHeapSize = "1g"),
|
||||||
|
@ -9,6 +9,7 @@ import net.corda.core.StubOutForDJVM
|
|||||||
import net.corda.core.cordapp.Cordapp
|
import net.corda.core.cordapp.Cordapp
|
||||||
import net.corda.core.internal.isAbstractClass
|
import net.corda.core.internal.isAbstractClass
|
||||||
import net.corda.core.internal.objectOrNewInstance
|
import net.corda.core.internal.objectOrNewInstance
|
||||||
|
import net.corda.core.internal.toSynchronised
|
||||||
import net.corda.core.internal.uncheckedCast
|
import net.corda.core.internal.uncheckedCast
|
||||||
import net.corda.core.serialization.*
|
import net.corda.core.serialization.*
|
||||||
import net.corda.core.utilities.ByteSequence
|
import net.corda.core.utilities.ByteSequence
|
||||||
@ -44,7 +45,7 @@ abstract class AbstractAMQPSerializationScheme(
|
|||||||
val sff: SerializerFactoryFactory = createSerializerFactoryFactory()
|
val sff: SerializerFactoryFactory = createSerializerFactoryFactory()
|
||||||
) : SerializationScheme {
|
) : SerializationScheme {
|
||||||
@DeleteForDJVM
|
@DeleteForDJVM
|
||||||
constructor(cordapps: List<Cordapp>) : this(cordapps.customSerializers, AccessOrderLinkedHashMap(128))
|
constructor(cordapps: List<Cordapp>) : this(cordapps.customSerializers, AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>(128).toSynchronised())
|
||||||
|
|
||||||
// This is a bit gross but a broader check for ConcurrentMap is not allowed inside DJVM.
|
// This is a bit gross but a broader check for ConcurrentMap is not allowed inside DJVM.
|
||||||
private val serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory> = if (maybeNotConcurrentSerializerFactoriesForContexts is AccessOrderLinkedHashMap<*, *>) {
|
private val serializerFactoriesForContexts: MutableMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory> = if (maybeNotConcurrentSerializerFactoriesForContexts is AccessOrderLinkedHashMap<*, *>) {
|
||||||
@ -189,20 +190,24 @@ abstract class AbstractAMQPSerializationScheme(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : Any> deserialize(byteSequence: ByteSequence, clazz: Class<T>, context: SerializationContext): T {
|
override fun <T : Any> deserialize(byteSequence: ByteSequence, clazz: Class<T>, context: SerializationContext): T {
|
||||||
var contextToUse = context
|
// This is a hack introduced in version 3 to fix a spring boot issue - CORDA-1747.
|
||||||
if (context.useCase == SerializationContext.UseCase.RPCClient) {
|
// It breaks the shell because it overwrites the CordappClassloader with the system classloader that doesn't know about any CorDapps.
|
||||||
contextToUse = context.withClassLoader(getContextClassLoader())
|
// In case a spring boot serialization issue with generics is found, a better solution needs to be found to address it.
|
||||||
}
|
// var contextToUse = context
|
||||||
val serializerFactory = getSerializerFactory(contextToUse)
|
// if (context.useCase == SerializationContext.UseCase.RPCClient) {
|
||||||
|
// contextToUse = context.withClassLoader(getContextClassLoader())
|
||||||
|
// }
|
||||||
|
val serializerFactory = getSerializerFactory(context)
|
||||||
return DeserializationInput(serializerFactory).deserialize(byteSequence, clazz, context)
|
return DeserializationInput(serializerFactory).deserialize(byteSequence, clazz, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : Any> serialize(obj: T, context: SerializationContext): SerializedBytes<T> {
|
override fun <T : Any> serialize(obj: T, context: SerializationContext): SerializedBytes<T> {
|
||||||
var contextToUse = context
|
// See the above comment.
|
||||||
if (context.useCase == SerializationContext.UseCase.RPCClient) {
|
// var contextToUse = context
|
||||||
contextToUse = context.withClassLoader(getContextClassLoader())
|
// if (context.useCase == SerializationContext.UseCase.RPCClient) {
|
||||||
}
|
// contextToUse = context.withClassLoader(getContextClassLoader())
|
||||||
val serializerFactory = getSerializerFactory(contextToUse)
|
// }
|
||||||
|
val serializerFactory = getSerializerFactory(context)
|
||||||
return SerializationOutput(serializerFactory).serialize(obj, context)
|
return SerializationOutput(serializerFactory).serialize(obj, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.corda.serialization.internal.amqp
|
package net.corda.serialization.internal.amqp
|
||||||
|
|
||||||
|
import net.corda.core.internal.toSynchronised
|
||||||
import net.corda.core.serialization.ClassWhitelist
|
import net.corda.core.serialization.ClassWhitelist
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
@ -39,7 +40,7 @@ class AbstractAMQPSerializationSchemeTest {
|
|||||||
|
|
||||||
val factory = SerializerFactoryBuilder.build(TESTING_CONTEXT.whitelist, TESTING_CONTEXT.deserializationClassLoader)
|
val factory = SerializerFactoryBuilder.build(TESTING_CONTEXT.whitelist, TESTING_CONTEXT.deserializationClassLoader)
|
||||||
val maxFactories = 512
|
val maxFactories = 512
|
||||||
val backingMap = AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>({ maxFactories })
|
val backingMap = AccessOrderLinkedHashMap<Pair<ClassWhitelist, ClassLoader>, SerializerFactory>({ maxFactories }).toSynchronised()
|
||||||
val scheme = object : AbstractAMQPSerializationScheme(emptySet(), backingMap, createSerializerFactoryFactory()) {
|
val scheme = object : AbstractAMQPSerializationScheme(emptySet(), backingMap, createSerializerFactoryFactory()) {
|
||||||
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
|
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
|
||||||
return factory
|
return factory
|
||||||
|
@ -16,7 +16,7 @@ import net.corda.core.utilities.getOrThrow
|
|||||||
import net.corda.node.internal.Node
|
import net.corda.node.internal.Node
|
||||||
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.DUMMY_NOTARY_NAME
|
||||||
import net.corda.testing.driver.PortAllocation.Incremental
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.driver.internal.internalServices
|
import net.corda.testing.driver.internal.internalServices
|
||||||
import net.corda.testing.node.NotarySpec
|
import net.corda.testing.node.NotarySpec
|
||||||
import net.corda.testing.node.TestCordapp
|
import net.corda.testing.node.TestCordapp
|
||||||
@ -114,7 +114,7 @@ abstract class PortAllocation {
|
|||||||
/**
|
/**
|
||||||
* An implementation of [PortAllocation] which allocates ports sequentially
|
* An implementation of [PortAllocation] which allocates ports sequentially
|
||||||
*/
|
*/
|
||||||
class Incremental(startingPort: Int) : PortAllocation() {
|
open class Incremental(startingPort: Int) : PortAllocation() {
|
||||||
/** The backing [AtomicInteger] used to keep track of the currently allocated port */
|
/** The backing [AtomicInteger] used to keep track of the currently allocated port */
|
||||||
val portCounter = AtomicInteger(startingPort)
|
val portCounter = AtomicInteger(startingPort)
|
||||||
|
|
||||||
@ -307,7 +307,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) incrementalPortAllocation(7005) else null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [driver] allows one to start up nodes like this:
|
* [driver] allows one to start up nodes like this:
|
||||||
@ -389,8 +389,8 @@ fun <A> driver(defaultParameters: DriverParameters = DriverParameters(), dsl: Dr
|
|||||||
data class DriverParameters(
|
data class DriverParameters(
|
||||||
val isDebug: Boolean = false,
|
val isDebug: Boolean = false,
|
||||||
val driverDirectory: Path = Paths.get("build", getTimestampAsDirectoryName()),
|
val driverDirectory: Path = Paths.get("build", getTimestampAsDirectoryName()),
|
||||||
val portAllocation: PortAllocation = PortAllocation.Incremental(10000),
|
val portAllocation: PortAllocation = incrementalPortAllocation(10000),
|
||||||
val debugPortAllocation: PortAllocation = PortAllocation.Incremental(5005),
|
val debugPortAllocation: PortAllocation = incrementalPortAllocation(5005),
|
||||||
val systemProperties: Map<String, String> = emptyMap(),
|
val systemProperties: Map<String, String> = emptyMap(),
|
||||||
val useTestClock: Boolean = false,
|
val useTestClock: Boolean = false,
|
||||||
val startNodesInProcess: Boolean = false,
|
val startNodesInProcess: Boolean = false,
|
||||||
@ -408,8 +408,8 @@ data class DriverParameters(
|
|||||||
constructor(
|
constructor(
|
||||||
isDebug: Boolean = false,
|
isDebug: Boolean = false,
|
||||||
driverDirectory: Path = Paths.get("build", getTimestampAsDirectoryName()),
|
driverDirectory: Path = Paths.get("build", getTimestampAsDirectoryName()),
|
||||||
portAllocation: PortAllocation = PortAllocation.Incremental(10000),
|
portAllocation: PortAllocation = incrementalPortAllocation(10000),
|
||||||
debugPortAllocation: PortAllocation = PortAllocation.Incremental(5005),
|
debugPortAllocation: PortAllocation = incrementalPortAllocation(5005),
|
||||||
systemProperties: Map<String, String> = emptyMap(),
|
systemProperties: Map<String, String> = emptyMap(),
|
||||||
useTestClock: Boolean = false,
|
useTestClock: Boolean = false,
|
||||||
startNodesInProcess: Boolean = false,
|
startNodesInProcess: Boolean = false,
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package net.corda.testing.driver.internal
|
||||||
|
|
||||||
|
import net.corda.testing.driver.PortAllocation
|
||||||
|
|
||||||
|
fun incrementalPortAllocation(startingPortIfNoEnv: Int): PortAllocation {
|
||||||
|
|
||||||
|
return when {
|
||||||
|
System.getenv(GlobalTestPortAllocation.enablingEnvVar)?.toBoolean() == true -> GlobalTestPortAllocation
|
||||||
|
else -> PortAllocation.Incremental(startingPortIfNoEnv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object GlobalTestPortAllocation : PortAllocation.Incremental(startingPort = startingPort) {
|
||||||
|
|
||||||
|
const val enablingEnvVar = "CORDA_TEST_GLOBAL_PORT_ALLOCATION_ENABLED"
|
||||||
|
const val startingPortEnvVariable = "CORDA_TEST_GLOBAL_PORT_ALLOCATION_STARTING_PORT"
|
||||||
|
const val startingPortDefaultValue = 5000
|
||||||
|
}
|
||||||
|
|
||||||
|
private val startingPort: Int = System.getenv(GlobalTestPortAllocation.startingPortEnvVariable)?.toIntOrNull() ?: GlobalTestPortAllocation.startingPortDefaultValue
|
@ -9,6 +9,7 @@ import net.corda.core.flows.FlowLogic
|
|||||||
import net.corda.core.flows.StateMachineRunId
|
import net.corda.core.flows.StateMachineRunId
|
||||||
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.SignedDataWithCert
|
||||||
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
|
||||||
@ -16,10 +17,12 @@ import net.corda.core.messaging.StateMachineTransactionMapping
|
|||||||
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.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
|
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.node.VersionInfo
|
import net.corda.node.VersionInfo
|
||||||
import net.corda.node.cordapp.CordappLoader
|
import net.corda.node.cordapp.CordappLoader
|
||||||
|
import net.corda.node.internal.NetworkParametersStorageInternal
|
||||||
import net.corda.node.internal.ServicesForResolutionImpl
|
import net.corda.node.internal.ServicesForResolutionImpl
|
||||||
import net.corda.node.internal.cordapp.JarScanningCordappLoader
|
import net.corda.node.internal.cordapp.JarScanningCordappLoader
|
||||||
import net.corda.node.services.api.*
|
import net.corda.node.services.api.*
|
||||||
@ -40,9 +43,11 @@ import net.corda.testing.services.MockAttachmentStorage
|
|||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.time.Clock
|
import java.time.Clock
|
||||||
|
import java.time.Instant
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import javax.persistence.EntityManager
|
import javax.persistence.EntityManager
|
||||||
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a simple [InMemoryIdentityService] containing the supplied [identities].
|
* Returns a simple [InMemoryIdentityService] containing the supplied [identities].
|
||||||
@ -101,7 +106,7 @@ open class MockServices private constructor(
|
|||||||
fun makeTestDatabaseAndMockServices(cordappPackages: List<String>,
|
fun makeTestDatabaseAndMockServices(cordappPackages: List<String>,
|
||||||
identityService: IdentityService,
|
identityService: IdentityService,
|
||||||
initialIdentity: TestIdentity,
|
initialIdentity: TestIdentity,
|
||||||
networkParameters: NetworkParameters = testNetworkParameters(),
|
networkParameters: NetworkParameters = testNetworkParameters(modifiedTime = Instant.MIN),
|
||||||
vararg moreKeys: KeyPair): Pair<CordaPersistence, MockServices> {
|
vararg moreKeys: KeyPair): Pair<CordaPersistence, MockServices> {
|
||||||
|
|
||||||
val cordappLoader = cordappLoaderForPackages(cordappPackages)
|
val cordappLoader = cordappLoaderForPackages(cordappPackages)
|
||||||
@ -111,7 +116,7 @@ open class MockServices private constructor(
|
|||||||
val mockService = database.transaction {
|
val mockService = database.transaction {
|
||||||
object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) {
|
object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) {
|
||||||
override val vaultService: VaultService = makeVaultService(schemaService, database)
|
override val vaultService: VaultService = makeVaultService(schemaService, database)
|
||||||
|
override val networkParametersStorage: NetworkParametersStorage get() = MockNetworkParametersStorage(networkParameters)
|
||||||
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
|
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
|
||||||
ServiceHubInternal.recordTransactions(statesToRecord, txs,
|
ServiceHubInternal.recordTransactions(statesToRecord, txs,
|
||||||
validatedTransactions as WritableTransactionStorage,
|
validatedTransactions as WritableTransactionStorage,
|
||||||
@ -161,7 +166,7 @@ open class MockServices private constructor(
|
|||||||
initialIdentity: TestIdentity,
|
initialIdentity: TestIdentity,
|
||||||
identityService: IdentityService = makeTestIdentityService(),
|
identityService: IdentityService = makeTestIdentityService(),
|
||||||
vararg moreKeys: KeyPair) :
|
vararg moreKeys: KeyPair) :
|
||||||
this(cordappLoaderForPackages(cordappPackages), identityService, testNetworkParameters(), initialIdentity, moreKeys)
|
this(cordappLoaderForPackages(cordappPackages), identityService, testNetworkParameters(modifiedTime = Instant.MIN), initialIdentity, moreKeys)
|
||||||
|
|
||||||
constructor(cordappPackages: Iterable<String>,
|
constructor(cordappPackages: Iterable<String>,
|
||||||
initialIdentity: TestIdentity,
|
initialIdentity: TestIdentity,
|
||||||
@ -252,12 +257,11 @@ open class MockServices private constructor(
|
|||||||
it.start(networkParameters.whitelistedContractImplementations)
|
it.start(networkParameters.whitelistedContractImplementations)
|
||||||
}
|
}
|
||||||
override val cordappProvider: CordappProvider get() = mockCordappProvider
|
override val cordappProvider: CordappProvider get() = mockCordappProvider
|
||||||
|
override val networkParametersStorage: NetworkParametersStorage get() = MockNetworkParametersStorage(networkParameters)
|
||||||
|
|
||||||
protected val servicesForResolution: ServicesForResolution
|
protected val servicesForResolution: ServicesForResolution
|
||||||
get() {
|
get() {
|
||||||
return ServicesForResolutionImpl(identityService, attachments, cordappProvider, validatedTransactions).also {
|
return ServicesForResolutionImpl(identityService, attachments, cordappProvider, networkParametersStorage, validatedTransactions)
|
||||||
it.start(networkParameters)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun makeVaultService(schemaService: SchemaService, database: CordaPersistence): VaultServiceInternal {
|
internal fun makeVaultService(schemaService: SchemaService, database: CordaPersistence): VaultServiceInternal {
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package net.corda.testing.node.internal
|
||||||
|
|
||||||
|
import net.corda.core.crypto.SecureHash
|
||||||
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
|
import net.corda.core.node.NetworkParameters
|
||||||
|
import net.corda.core.serialization.serialize
|
||||||
|
import net.corda.node.internal.NetworkParametersStorageInternal
|
||||||
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
class MockNetworkParametersStorage(val currentParameters: NetworkParameters = testNetworkParameters(modifiedTime = Instant.MIN)) : NetworkParametersStorageInternal {
|
||||||
|
private val hashToParametersMap: HashMap<SecureHash, NetworkParameters> = HashMap()
|
||||||
|
|
||||||
|
init {
|
||||||
|
hashToParametersMap[currentHash] = currentParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
override val currentHash: SecureHash get() = currentParameters.serialize().hash
|
||||||
|
override val defaultHash: SecureHash get() = currentHash
|
||||||
|
override fun getEpochFromHash(hash: SecureHash): Int? = lookup(hash)?.epoch
|
||||||
|
override fun lookup(hash: SecureHash): NetworkParameters? = hashToParametersMap[hash]
|
||||||
|
override fun saveParameters(signedNetworkParameters: SignedDataWithCert<NetworkParameters>) {
|
||||||
|
val networkParameters = signedNetworkParameters.verified()
|
||||||
|
val hash = signedNetworkParameters.raw.hash
|
||||||
|
hashToParametersMap[hash] = networkParameters
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ import net.corda.nodeapi.internal.config.toConfig
|
|||||||
import net.corda.nodeapi.internal.network.NetworkParametersCopier
|
import net.corda.nodeapi.internal.network.NetworkParametersCopier
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.testThreadFactory
|
import net.corda.testing.internal.testThreadFactory
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
@ -54,7 +54,7 @@ abstract class NodeBasedTest(private val cordappPackages: List<String> = emptyLi
|
|||||||
|
|
||||||
private val nodes = mutableListOf<NodeWithInfo>()
|
private val nodes = mutableListOf<NodeWithInfo>()
|
||||||
private val nodeInfos = mutableListOf<NodeInfo>()
|
private val nodeInfos = mutableListOf<NodeInfo>()
|
||||||
private val portAllocation = PortAllocation.Incremental(10000)
|
private val portAllocation = incrementalPortAllocation(10000)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
System.setProperty("consoleLogLevel", Level.DEBUG.name().toLowerCase())
|
System.setProperty("consoleLogLevel", Level.DEBUG.name().toLowerCase())
|
||||||
|
@ -28,6 +28,7 @@ import net.corda.testing.common.internal.testNetworkParameters
|
|||||||
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
import net.corda.testing.core.MAX_MESSAGE_SIZE
|
||||||
import net.corda.testing.driver.JmxPolicy
|
import net.corda.testing.driver.JmxPolicy
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.PortAllocation
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.testing.internal.fromUserList
|
import net.corda.testing.internal.fromUserList
|
||||||
import net.corda.testing.node.NotarySpec
|
import net.corda.testing.node.NotarySpec
|
||||||
@ -102,8 +103,8 @@ val rpcTestUser = User("user1", "test", permissions = emptySet())
|
|||||||
val fakeNodeLegalName = CordaX500Name(organisation = "Not:a:real:name", locality = "Nowhere", country = "GB")
|
val fakeNodeLegalName = CordaX500Name(organisation = "Not:a:real:name", locality = "Nowhere", country = "GB")
|
||||||
|
|
||||||
// Use a global pool so that we can run RPC tests in parallel
|
// Use a global pool so that we can run RPC tests in parallel
|
||||||
private val globalPortAllocation = PortAllocation.Incremental(10000)
|
private val globalPortAllocation = incrementalPortAllocation(10000)
|
||||||
private val globalDebugPortAllocation = PortAllocation.Incremental(5005)
|
private val globalDebugPortAllocation = incrementalPortAllocation(5005)
|
||||||
|
|
||||||
fun <A> rpcDriver(
|
fun <A> rpcDriver(
|
||||||
isDebug: Boolean = false,
|
isDebug: Boolean = false,
|
||||||
|
@ -155,7 +155,7 @@ fun createWireTransaction(inputs: List<StateRef>,
|
|||||||
notary: Party?,
|
notary: Party?,
|
||||||
timeWindow: TimeWindow?,
|
timeWindow: TimeWindow?,
|
||||||
privacySalt: PrivacySalt = PrivacySalt()): WireTransaction {
|
privacySalt: PrivacySalt = PrivacySalt()): WireTransaction {
|
||||||
val componentGroups = createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow, emptyList())
|
val componentGroups = createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow, emptyList(), null)
|
||||||
return WireTransaction(componentGroups, privacySalt)
|
return WireTransaction(componentGroups, privacySalt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import net.corda.sample.businessnetwork.membership.flow.ObtainMembershipListCont
|
|||||||
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
|
||||||
import net.corda.testing.driver.*
|
import net.corda.testing.driver.*
|
||||||
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import net.corda.testing.node.internal.FINANCE_CORDAPP
|
import net.corda.testing.node.internal.FINANCE_CORDAPP
|
||||||
import net.corda.testing.node.internal.BUSINESS_NETWORK_CORDAPP
|
import net.corda.testing.node.internal.BUSINESS_NETWORK_CORDAPP
|
||||||
@ -77,7 +78,7 @@ class ExplorerSimulation(private val options: OptionSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun startDemoNodes() {
|
private fun startDemoNodes() {
|
||||||
val portAllocation = PortAllocation.Incremental(20000)
|
val portAllocation = incrementalPortAllocation(20000)
|
||||||
driver(DriverParameters(
|
driver(DriverParameters(
|
||||||
portAllocation = portAllocation,
|
portAllocation = portAllocation,
|
||||||
cordappsForAllNodes = listOf(FINANCE_CORDAPP, BUSINESS_NETWORK_CORDAPP),
|
cordappsForAllNodes = listOf(FINANCE_CORDAPP, BUSINESS_NETWORK_CORDAPP),
|
||||||
|
@ -4,7 +4,7 @@ import com.google.common.util.concurrent.RateLimiter
|
|||||||
import net.corda.client.mock.Generator
|
import net.corda.client.mock.Generator
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.core.utilities.toBase58String
|
import net.corda.core.utilities.toBase58String
|
||||||
import net.corda.testing.driver.PortAllocation
|
import net.corda.testing.driver.internal.incrementalPortAllocation
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@ -170,7 +170,7 @@ fun runLoadTests(configuration: LoadTestConfiguration, tests: List<Pair<LoadTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connectToNodes(remoteNodes, PortAllocation.Incremental(configuration.localTunnelStartingPort)) { connections ->
|
connectToNodes(remoteNodes, incrementalPortAllocation(configuration.localTunnelStartingPort)) { connections ->
|
||||||
log.info("Connected to all nodes!")
|
log.info("Connected to all nodes!")
|
||||||
val hostNodeMap = ConcurrentHashMap<String, NodeConnection>()
|
val hostNodeMap = ConcurrentHashMap<String, NodeConnection>()
|
||||||
connections.parallelStream().forEach { connection ->
|
connections.parallelStream().forEach { connection ->
|
||||||
|
Reference in New Issue
Block a user