mirror of
https://github.com/corda/corda.git
synced 2025-06-01 23:20:54 +00:00
ENT-11155: Remove internal Kotlin utilities which have since been added after 1.2 (#7585)
This is mostly the `Path` extension functions in `PathUtils.kt`.
This commit is contained in:
parent
10e005b072
commit
61a05a90eb
@ -4,7 +4,8 @@ import co.paralleluniverse.fibers.Suspendable
|
|||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.StartableByRPC
|
import net.corda.core.flows.StartableByRPC
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.PLATFORM_VERSION
|
||||||
|
import net.corda.core.internal.copyToDirectory
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.nodeapi.internal.config.User
|
import net.corda.nodeapi.internal.config.User
|
||||||
@ -14,9 +15,12 @@ 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
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
|
|
||||||
class NodeVersioningTest {
|
class NodeVersioningTest {
|
||||||
private companion object {
|
private companion object {
|
||||||
@ -66,9 +70,7 @@ class NodeVersioningTest {
|
|||||||
fun `platform version from RPC`() {
|
fun `platform version from RPC`() {
|
||||||
val cordappsDir = (factory.baseDirectory(aliceConfig) / NodeProcess.CORDAPPS_DIR_NAME).createDirectories()
|
val cordappsDir = (factory.baseDirectory(aliceConfig) / NodeProcess.CORDAPPS_DIR_NAME).createDirectories()
|
||||||
// Find the jar file for the smoke tests of this module
|
// Find the jar file for the smoke tests of this module
|
||||||
val selfCordapp = Paths.get("build", "libs").list {
|
val selfCordapp = Path("build", "libs").listDirectoryEntries("*-smokeTests*").single()
|
||||||
it.filter { "-smokeTests" in it.toString() }.toList().single()
|
|
||||||
}
|
|
||||||
selfCordapp.copyToDirectory(cordappsDir)
|
selfCordapp.copyToDirectory(cordappsDir)
|
||||||
|
|
||||||
factory.create(aliceConfig).use { alice ->
|
factory.create(aliceConfig).use { alice ->
|
||||||
|
@ -3,11 +3,16 @@ package net.corda.coretests.cordapp
|
|||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.crypto.Crypto.generateKeyPair
|
import net.corda.core.crypto.Crypto.generateKeyPair
|
||||||
import net.corda.core.crypto.sign
|
import net.corda.core.crypto.sign
|
||||||
import net.corda.core.flows.*
|
import net.corda.core.flows.FlowInfo
|
||||||
|
import net.corda.core.flows.FlowLogic
|
||||||
|
import net.corda.core.flows.FlowSession
|
||||||
|
import net.corda.core.flows.InitiatedBy
|
||||||
|
import net.corda.core.flows.InitiatingFlow
|
||||||
|
import net.corda.core.flows.StartableByRPC
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.copyToDirectory
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
@ -29,11 +34,16 @@ import org.junit.After
|
|||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.security.PrivateKey
|
import java.security.PrivateKey
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
|
import kotlin.io.path.writeBytes
|
||||||
|
|
||||||
class CordappSmokeTest {
|
class CordappSmokeTest {
|
||||||
private companion object {
|
private companion object {
|
||||||
@ -78,9 +88,7 @@ class CordappSmokeTest {
|
|||||||
val baseDir = factory.baseDirectory(aliceConfig)
|
val baseDir = factory.baseDirectory(aliceConfig)
|
||||||
val cordappsDir = (baseDir / CORDAPPS_DIR_NAME).createDirectories()
|
val cordappsDir = (baseDir / CORDAPPS_DIR_NAME).createDirectories()
|
||||||
// Find the jar file for the smoke tests of this module
|
// Find the jar file for the smoke tests of this module
|
||||||
val selfCordapp = Paths.get("build", "libs").list {
|
val selfCordapp = Path("build", "libs").useDirectoryEntries { it.single { "-smokeTests" in it.toString() } }
|
||||||
it.filter { "-smokeTests" in it.toString() }.toList().single()
|
|
||||||
}
|
|
||||||
selfCordapp.copyToDirectory(cordappsDir)
|
selfCordapp.copyToDirectory(cordappsDir)
|
||||||
|
|
||||||
// The `nodeReadyFuture` in the persistent network map cache will not complete unless there is at least one other
|
// The `nodeReadyFuture` in the persistent network map cache will not complete unless there is at least one other
|
||||||
@ -95,7 +103,7 @@ class CordappSmokeTest {
|
|||||||
val aliceIdentity = connectionToAlice.proxy.nodeInfo().legalIdentitiesAndCerts.first().party
|
val aliceIdentity = connectionToAlice.proxy.nodeInfo().legalIdentitiesAndCerts.first().party
|
||||||
val future = connectionToAlice.proxy.startFlow(CordappSmokeTest::GatherContextsFlow, aliceIdentity).returnValue
|
val future = connectionToAlice.proxy.startFlow(CordappSmokeTest::GatherContextsFlow, aliceIdentity).returnValue
|
||||||
val (sessionInitContext, sessionConfirmContext) = future.getOrThrow()
|
val (sessionInitContext, sessionConfirmContext) = future.getOrThrow()
|
||||||
val selfCordappName = selfCordapp.fileName.toString().removeSuffix(".jar")
|
val selfCordappName = selfCordapp.name.removeSuffix(".jar")
|
||||||
assertThat(sessionInitContext.appName).isEqualTo(selfCordappName)
|
assertThat(sessionInitContext.appName).isEqualTo(selfCordappName)
|
||||||
assertThat(sessionConfirmContext.appName).isEqualTo(selfCordappName)
|
assertThat(sessionConfirmContext.appName).isEqualTo(selfCordappName)
|
||||||
}
|
}
|
||||||
@ -138,7 +146,7 @@ class CordappSmokeTest {
|
|||||||
val dummyKeyPair = generateKeyPair()
|
val dummyKeyPair = generateKeyPair()
|
||||||
val nodeInfo = createNodeInfoWithSingleIdentity(CordaX500Name(organisation = "Bob Corp", locality = "Madrid", country = "ES"), dummyKeyPair, dummyKeyPair.public)
|
val nodeInfo = createNodeInfoWithSingleIdentity(CordaX500Name(organisation = "Bob Corp", locality = "Madrid", country = "ES"), dummyKeyPair, dummyKeyPair.public)
|
||||||
val signedNodeInfo = signWith(nodeInfo, listOf(dummyKeyPair.private))
|
val signedNodeInfo = signWith(nodeInfo, listOf(dummyKeyPair.private))
|
||||||
(additionalNodeInfoDir / "nodeInfo-41408E093F95EAD51F6892C34DEB65AE1A3569A4B0E5744769A1B485AF8E04B5").write(signedNodeInfo.serialize().bytes)
|
(additionalNodeInfoDir / "nodeInfo-41408E093F95EAD51F6892C34DEB65AE1A3569A4B0E5744769A1B485AF8E04B5").writeBytes(signedNodeInfo.serialize().bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNodeInfoWithSingleIdentity(name: CordaX500Name, nodeKeyPair: KeyPair, identityCertPublicKey: PublicKey): NodeInfo {
|
private fun createNodeInfoWithSingleIdentity(name: CordaX500Name, nodeKeyPair: KeyPair, identityCertPublicKey: PublicKey): NodeInfo {
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
package net.corda.coretests.contracts
|
package net.corda.coretests.contracts
|
||||||
|
|
||||||
import org.mockito.kotlin.doReturn
|
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
|
||||||
import org.mockito.kotlin.mock
|
import net.corda.core.contracts.AutomaticPlaceholderConstraint
|
||||||
import org.mockito.kotlin.whenever
|
import net.corda.core.contracts.BelongsToContract
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.CommandData
|
||||||
|
import net.corda.core.contracts.Contract
|
||||||
|
import net.corda.core.contracts.ContractAttachment
|
||||||
|
import net.corda.core.contracts.ContractState
|
||||||
|
import net.corda.core.contracts.HashAttachmentConstraint
|
||||||
|
import net.corda.core.contracts.NoConstraintPropagation
|
||||||
|
import net.corda.core.contracts.SignatureAttachmentConstraint
|
||||||
|
import net.corda.core.contracts.StateRef
|
||||||
|
import net.corda.core.contracts.WhitelistedByZoneAttachmentConstraint
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.SecureHash.Companion.allOnesHash
|
import net.corda.core.crypto.SecureHash.Companion.allOnesHash
|
||||||
@ -14,17 +22,16 @@ import net.corda.core.crypto.sign
|
|||||||
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.internal.canBeTransitionedFrom
|
import net.corda.core.internal.canBeTransitionedFrom
|
||||||
import net.corda.core.internal.inputStream
|
import net.corda.core.internal.read
|
||||||
import net.corda.core.internal.requireSupportedHashType
|
import net.corda.core.internal.requireSupportedHashType
|
||||||
import net.corda.core.internal.toPath
|
|
||||||
import net.corda.core.node.NotaryInfo
|
import net.corda.core.node.NotaryInfo
|
||||||
import net.corda.core.node.services.IdentityService
|
import net.corda.core.node.services.IdentityService
|
||||||
import net.corda.core.transactions.LedgerTransaction
|
import net.corda.core.transactions.LedgerTransaction
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.core.transactions.WireTransaction
|
import net.corda.core.transactions.WireTransaction
|
||||||
import net.corda.finance.POUNDS
|
import net.corda.finance.POUNDS
|
||||||
import net.corda.finance.`issued by`
|
|
||||||
import net.corda.finance.contracts.asset.Cash
|
import net.corda.finance.contracts.asset.Cash
|
||||||
|
import net.corda.finance.`issued by`
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.core.ALICE_NAME
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||||
@ -36,7 +43,15 @@ import net.corda.testing.core.internal.SelfCleaningDir
|
|||||||
import net.corda.testing.internal.MockCordappProvider
|
import net.corda.testing.internal.MockCordappProvider
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import net.corda.testing.node.ledger
|
import net.corda.testing.node.ledger
|
||||||
import org.junit.*
|
import org.junit.AfterClass
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.BeforeClass
|
||||||
|
import org.junit.Ignore
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.util.jar.Attributes
|
import java.util.jar.Attributes
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
@ -91,8 +106,8 @@ class ConstraintsPropagationTests {
|
|||||||
},
|
},
|
||||||
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
networkParameters = testNetworkParameters(minimumPlatformVersion = 4)
|
||||||
.copy(whitelistedContractImplementations = mapOf(
|
.copy(whitelistedContractImplementations = mapOf(
|
||||||
Cash.PROGRAM_ID to listOf(SecureHash.zeroHash, SecureHash.allOnesHash),
|
Cash.PROGRAM_ID to listOf(zeroHash, allOnesHash),
|
||||||
noPropagationContractClassName to listOf(SecureHash.zeroHash)),
|
noPropagationContractClassName to listOf(zeroHash)),
|
||||||
notaries = listOf(NotaryInfo(DUMMY_NOTARY, true)))
|
notaries = listOf(NotaryInfo(DUMMY_NOTARY, true)))
|
||||||
) {
|
) {
|
||||||
override fun loadContractAttachment(stateRef: StateRef) = servicesForResolution.loadContractAttachment(stateRef)
|
override fun loadContractAttachment(stateRef: StateRef) = servicesForResolution.loadContractAttachment(stateRef)
|
||||||
@ -103,13 +118,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Happy path with the HashConstraint`() {
|
fun `Happy path with the HashConstraint`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash)
|
attachment(Cash.PROGRAM_ID, allOnesHash)
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash)
|
attachment(Cash.PROGRAM_ID, allOnesHash)
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -125,13 +140,13 @@ class ConstraintsPropagationTests {
|
|||||||
val cordappAttachmentIds =
|
val cordappAttachmentIds =
|
||||||
cordapps.map { cordapp ->
|
cordapps.map { cordapp ->
|
||||||
val unsignedAttId =
|
val unsignedAttId =
|
||||||
cordapp.jarPath.toPath().inputStream().use { unsignedJarStream ->
|
cordapp.jarPath.openStream().use { unsignedJarStream ->
|
||||||
ledgerServices.attachments.importContractAttachment(cordapp.contractClassNames, "rpc", unsignedJarStream, null)
|
ledgerServices.attachments.importContractAttachment(cordapp.contractClassNames, "rpc", unsignedJarStream, null)
|
||||||
}
|
}
|
||||||
val jarAndSigner = ContractJarTestUtils.signContractJar(cordapp.jarPath, copyFirst = true, keyStoreDir = keyStoreDir.path)
|
val jarAndSigner = ContractJarTestUtils.signContractJar(cordapp.jarPath, copyFirst = true, keyStoreDir = keyStoreDir.path)
|
||||||
val signedJar = jarAndSigner.first
|
val signedJar = jarAndSigner.first
|
||||||
val signedAttId =
|
val signedAttId =
|
||||||
signedJar.inputStream().use { signedJarStream ->
|
signedJar.read { signedJarStream ->
|
||||||
ledgerServices.attachments.importContractAttachment(cordapp.contractClassNames, "rpc", signedJarStream, null, listOf(jarAndSigner.second))
|
ledgerServices.attachments.importContractAttachment(cordapp.contractClassNames, "rpc", signedJarStream, null, listOf(jarAndSigner.second))
|
||||||
}
|
}
|
||||||
Pair(unsignedAttId, signedAttId)
|
Pair(unsignedAttId, signedAttId)
|
||||||
@ -163,14 +178,14 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Fail early in the TransactionBuilder when attempting to change the hash of the HashConstraint on the spending transaction`() {
|
fun `Fail early in the TransactionBuilder when attempting to change the hash of the HashConstraint on the spending transaction`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
}
|
}
|
||||||
assertFailsWith<IllegalArgumentException> {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash)
|
attachment(Cash.PROGRAM_ID, allOnesHash)
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(allOnesHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -184,27 +199,27 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Transaction validation fails, when constraints do not propagate correctly`() {
|
fun `Transaction validation fails, when constraints do not propagate correctly`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
failsWith("are not propagated correctly")
|
failsWith("are not propagated correctly")
|
||||||
})
|
})
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c3", DUMMY_NOTARY, null, SignatureAttachmentConstraint(ALICE_PUBKEY), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c3", DUMMY_NOTARY, null, SignatureAttachmentConstraint(ALICE_PUBKEY), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
fails()
|
fails()
|
||||||
})
|
})
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c4", DUMMY_NOTARY, null, AlwaysAcceptAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c4", DUMMY_NOTARY, null, AlwaysAcceptAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -217,13 +232,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `When the constraint of the output state is a valid transition from the input state, transaction validation works`() {
|
fun `When the constraint of the output state is a valid transition from the input state, transaction validation works`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -237,7 +252,7 @@ class ConstraintsPropagationTests {
|
|||||||
|
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
output(Cash.PROGRAM_ID, "w1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "w1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
@ -245,7 +260,7 @@ class ConstraintsPropagationTests {
|
|||||||
|
|
||||||
// the attachment is signed
|
// the attachment is signed
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey))
|
attachment(Cash.PROGRAM_ID, allOnesHash, listOf(hashToSignatureConstraintsKey))
|
||||||
input("w1")
|
input("w1")
|
||||||
output(Cash.PROGRAM_ID, "w2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "w2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -258,14 +273,14 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Switching from the WhitelistConstraint to the Signature Constraint fails if the signature constraint does not inherit all jar signatures`() {
|
fun `Switching from the WhitelistConstraint to the Signature Constraint fails if the signature constraint does not inherit all jar signatures`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
output(Cash.PROGRAM_ID, "w1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "w1", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
// the attachment is not signed
|
// the attachment is not signed
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash)
|
attachment(Cash.PROGRAM_ID, zeroHash)
|
||||||
input("w1")
|
input("w1")
|
||||||
output(Cash.PROGRAM_ID, "w2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(ALICE_PUBKEY), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "w2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(ALICE_PUBKEY), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -279,13 +294,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `On contract annotated with NoConstraintPropagation there is no platform check for propagation, but the transaction builder can't use the AutomaticPlaceholderConstraint`() {
|
fun `On contract annotated with NoConstraintPropagation there is no platform check for propagation, but the transaction builder can't use the AutomaticPlaceholderConstraint`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(noPropagationContractClassName, SecureHash.zeroHash)
|
attachment(noPropagationContractClassName, zeroHash)
|
||||||
output(noPropagationContractClassName, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), NoPropagationContractState())
|
output(noPropagationContractClassName, "c1", DUMMY_NOTARY, null, HashAttachmentConstraint(zeroHash), NoPropagationContractState())
|
||||||
command(ALICE_PUBKEY, NoPropagationContract.Create())
|
command(ALICE_PUBKEY, NoPropagationContract.Create())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(noPropagationContractClassName, SecureHash.zeroHash)
|
attachment(noPropagationContractClassName, zeroHash)
|
||||||
input("c1")
|
input("c1")
|
||||||
output(noPropagationContractClassName, "c2", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, NoPropagationContractState())
|
output(noPropagationContractClassName, "c2", DUMMY_NOTARY, null, WhitelistedByZoneAttachmentConstraint, NoPropagationContractState())
|
||||||
command(ALICE_PUBKEY, NoPropagationContract.Create())
|
command(ALICE_PUBKEY, NoPropagationContract.Create())
|
||||||
@ -293,7 +308,7 @@ class ConstraintsPropagationTests {
|
|||||||
})
|
})
|
||||||
assertFailsWith<IllegalArgumentException> {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
transaction {
|
transaction {
|
||||||
attachment(noPropagationContractClassName, SecureHash.zeroHash)
|
attachment(noPropagationContractClassName, zeroHash)
|
||||||
input("c1")
|
input("c1")
|
||||||
output(noPropagationContractClassName, "c3", DUMMY_NOTARY, null, AutomaticPlaceholderConstraint, NoPropagationContractState())
|
output(noPropagationContractClassName, "c3", DUMMY_NOTARY, null, AutomaticPlaceholderConstraint, NoPropagationContractState())
|
||||||
command(ALICE_PUBKEY, NoPropagationContract.Create())
|
command(ALICE_PUBKEY, NoPropagationContract.Create())
|
||||||
@ -387,13 +402,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Input state contract version may be incompatible with lower version`() {
|
fun `Input state contract version may be incompatible with lower version`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
attachment(Cash.PROGRAM_ID, allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
attachment(Cash.PROGRAM_ID, zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -406,13 +421,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Input state contract version is compatible with the same version`() {
|
fun `Input state contract version is compatible with the same version`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "3"))
|
attachment(Cash.PROGRAM_ID, allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "3"))
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "3"))
|
attachment(Cash.PROGRAM_ID, zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "3"))
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -425,13 +440,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Input state contract version is compatible with higher version`() {
|
fun `Input state contract version is compatible with higher version`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
attachment(Cash.PROGRAM_ID, allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
attachment(Cash.PROGRAM_ID, zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -444,13 +459,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Input states contract version may be lower that current contract version`() {
|
fun `Input states contract version may be lower that current contract version`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
attachment(Cash.PROGRAM_ID, allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "1"))
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
attachment(Cash.PROGRAM_ID, zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
@ -469,13 +484,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Input state with contract version can be downgraded to no version`() {
|
fun `Input state with contract version can be downgraded to no version`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
attachment(Cash.PROGRAM_ID, allOnesHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), emptyMap())
|
attachment(Cash.PROGRAM_ID, zeroHash, listOf(hashToSignatureConstraintsKey), emptyMap())
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
@ -488,13 +503,13 @@ class ConstraintsPropagationTests {
|
|||||||
fun `Input state without contract version is compatible with any version`() {
|
fun `Input state without contract version is compatible with any version`() {
|
||||||
ledgerServices.ledger(DUMMY_NOTARY) {
|
ledgerServices.ledger(DUMMY_NOTARY) {
|
||||||
ledgerServices.recordTransaction(transaction {
|
ledgerServices.recordTransaction(transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.allOnesHash, listOf(hashToSignatureConstraintsKey), emptyMap())
|
attachment(Cash.PROGRAM_ID, allOnesHash, listOf(hashToSignatureConstraintsKey), emptyMap())
|
||||||
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
output(Cash.PROGRAM_ID, "c1", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), ALICE_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
verifies()
|
verifies()
|
||||||
})
|
})
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID, SecureHash.zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
attachment(Cash.PROGRAM_ID, zeroHash, listOf(hashToSignatureConstraintsKey), mapOf(Attributes.Name.IMPLEMENTATION_VERSION.toString() to "2"))
|
||||||
input("c1")
|
input("c1")
|
||||||
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
output(Cash.PROGRAM_ID, "c2", DUMMY_NOTARY, null, SignatureAttachmentConstraint(hashToSignatureConstraintsKey), Cash.State(1000.POUNDS `issued by` ALICE_PARTY.ref(1), BOB_PARTY))
|
||||||
command(ALICE_PUBKEY, Cash.Commands.Move())
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
|
@ -3,7 +3,6 @@ package net.corda.coretests.crypto
|
|||||||
import net.corda.core.crypto.*
|
import net.corda.core.crypto.*
|
||||||
import net.corda.core.crypto.CompositeKey.NodeAndWeight
|
import net.corda.core.crypto.CompositeKey.NodeAndWeight
|
||||||
import net.corda.core.internal.declaredField
|
import net.corda.core.internal.declaredField
|
||||||
import net.corda.core.internal.div
|
|
||||||
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.core.utilities.toBase58String
|
import net.corda.core.utilities.toBase58String
|
||||||
@ -19,6 +18,7 @@ import org.junit.Test
|
|||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
|
@ -19,7 +19,6 @@ import net.corda.core.internal.AttachmentTrustCalculator
|
|||||||
import net.corda.core.internal.createLedgerTransaction
|
import net.corda.core.internal.createLedgerTransaction
|
||||||
import net.corda.core.internal.declaredField
|
import net.corda.core.internal.declaredField
|
||||||
import net.corda.core.internal.hash
|
import net.corda.core.internal.hash
|
||||||
import net.corda.core.internal.inputStream
|
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.services.AttachmentId
|
import net.corda.core.node.services.AttachmentId
|
||||||
import net.corda.core.serialization.internal.AttachmentsClassLoader
|
import net.corda.core.serialization.internal.AttachmentsClassLoader
|
||||||
@ -44,7 +43,6 @@ import org.apache.commons.io.IOUtils
|
|||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Assert.assertArrayEquals
|
import org.junit.Assert.assertArrayEquals
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertNull
|
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -55,14 +53,16 @@ import java.io.InputStream
|
|||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
|
import kotlin.io.path.inputStream
|
||||||
|
import kotlin.io.path.readBytes
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.fail
|
import kotlin.test.fail
|
||||||
|
|
||||||
class AttachmentsClassLoaderTests {
|
class AttachmentsClassLoaderTests {
|
||||||
companion object {
|
companion object {
|
||||||
// TODO Update this test to use the new isolated.jar
|
// TODO Update this test to use the new isolated.jar
|
||||||
val ISOLATED_CONTRACTS_JAR_PATH: URL = AttachmentsClassLoaderTests::class.java.getResource("old-isolated.jar")
|
val ISOLATED_CONTRACTS_JAR_PATH: URL = AttachmentsClassLoaderTests::class.java.getResource("old-isolated.jar")!!
|
||||||
val ISOLATED_CONTRACTS_JAR_PATH_V4: URL = AttachmentsClassLoaderTests::class.java.getResource("isolated-4.0.jar")
|
val ISOLATED_CONTRACTS_JAR_PATH_V4: URL = AttachmentsClassLoaderTests::class.java.getResource("isolated-4.0.jar")!!
|
||||||
private const val ISOLATED_CONTRACT_CLASS_NAME = "net.corda.finance.contracts.isolated.AnotherDummyContract"
|
private const val ISOLATED_CONTRACT_CLASS_NAME = "net.corda.finance.contracts.isolated.AnotherDummyContract"
|
||||||
|
|
||||||
private fun readAttachment(attachment: Attachment, filepath: String): ByteArray {
|
private fun readAttachment(attachment: Attachment, filepath: String): ByteArray {
|
||||||
@ -128,8 +128,6 @@ class AttachmentsClassLoaderTests {
|
|||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `test contracts have no permissions for protection domain`() {
|
fun `test contracts have no permissions for protection domain`() {
|
||||||
val isolatedId = importAttachment(ISOLATED_CONTRACTS_JAR_PATH.openStream(), "app", "isolated.jar")
|
val isolatedId = importAttachment(ISOLATED_CONTRACTS_JAR_PATH.openStream(), "app", "isolated.jar")
|
||||||
assertNull(System.getSecurityManager())
|
|
||||||
|
|
||||||
createClassloader(isolatedId).use { classLoader ->
|
createClassloader(isolatedId).use { classLoader ->
|
||||||
val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, classLoader)
|
val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, classLoader)
|
||||||
val protectionDomain = contractClass.protectionDomain ?: fail("Protection Domain missing")
|
val protectionDomain = contractClass.protectionDomain ?: fail("Protection Domain missing")
|
||||||
@ -614,7 +612,7 @@ class AttachmentsClassLoaderTests {
|
|||||||
|
|
||||||
private fun createAttachments(contractJarPath: Path) : List<Attachment> {
|
private fun createAttachments(contractJarPath: Path) : List<Attachment> {
|
||||||
|
|
||||||
val attachment = object : AbstractAttachment({contractJarPath.inputStream().readBytes()}, uploader = "app") {
|
val attachment = object : AbstractAttachment(contractJarPath::readBytes, uploader = "app") {
|
||||||
@Suppress("OverridingDeprecatedMember")
|
@Suppress("OverridingDeprecatedMember")
|
||||||
@Deprecated("Use signerKeys. There is no requirement that attachment signers are Corda parties.")
|
@Deprecated("Use signerKeys. There is no requirement that attachment signers are Corda parties.")
|
||||||
override val signers: List<Party> = emptyList()
|
override val signers: List<Party> = emptyList()
|
||||||
|
@ -573,7 +573,7 @@ abstract class FlowLogic<out T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun <R> associateSessionsToReceiveType(receiveType: Class<R>, sessions: List<FlowSession>): Map<FlowSession, Class<R>> {
|
private fun <R> associateSessionsToReceiveType(receiveType: Class<R>, sessions: List<FlowSession>): Map<FlowSession, Class<R>> {
|
||||||
return sessions.associateByTo(LinkedHashMap(), { it }, { receiveType })
|
return sessions.associateWithTo(LinkedHashMap()) { receiveType }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <R> castMapValuesToKnownType(map: Map<FlowSession, UntrustworthyData<Any>>): List<UntrustworthyData<R>> {
|
private fun <R> castMapValuesToKnownType(map: Map<FlowSession, UntrustworthyData<Any>>): List<UntrustworthyData<R>> {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
@file:JvmName("InternalUtils")
|
|
||||||
package net.corda.core.internal
|
package net.corda.core.internal
|
||||||
|
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
@ -26,18 +25,15 @@ import java.io.InputStream
|
|||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.lang.reflect.Member
|
import java.lang.reflect.Member
|
||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
import java.math.BigDecimal
|
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.HttpURLConnection.HTTP_MOVED_PERM
|
import java.net.HttpURLConnection.HTTP_MOVED_PERM
|
||||||
import java.net.HttpURLConnection.HTTP_OK
|
import java.net.HttpURLConnection.HTTP_OK
|
||||||
import java.net.Proxy
|
import java.net.Proxy
|
||||||
import java.net.URI
|
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.file.CopyOption
|
import java.nio.file.CopyOption
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.security.PrivateKey
|
import java.security.PrivateKey
|
||||||
@ -72,6 +68,7 @@ import java.util.stream.StreamSupport
|
|||||||
import java.util.zip.Deflater
|
import java.util.zip.Deflater
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
import kotlin.io.path.toPath
|
||||||
import kotlin.math.roundToLong
|
import kotlin.math.roundToLong
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.full.createInstance
|
import kotlin.reflect.full.createInstance
|
||||||
@ -94,8 +91,8 @@ infix fun Temporal.until(endExclusive: Temporal): Duration = Duration.between(th
|
|||||||
operator fun Duration.div(divider: Long): Duration = dividedBy(divider)
|
operator fun Duration.div(divider: Long): Duration = dividedBy(divider)
|
||||||
operator fun Duration.times(multiplicand: Long): Duration = multipliedBy(multiplicand)
|
operator fun Duration.times(multiplicand: Long): Duration = multipliedBy(multiplicand)
|
||||||
operator fun Duration.times(multiplicand: Double): Duration = Duration.ofNanos((toNanos() * multiplicand).roundToLong())
|
operator fun Duration.times(multiplicand: Double): Duration = Duration.ofNanos((toNanos() * multiplicand).roundToLong())
|
||||||
fun min(d1: Duration, d2: Duration): Duration = if (d1 <= d2) d1 else d2
|
|
||||||
|
|
||||||
|
fun min(d1: Duration, d2: Duration): Duration = if (d1 <= d2) d1 else d2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the single element matching the given [predicate], or `null` if the collection is empty, or throws exception
|
* Returns the single element matching the given [predicate], or `null` if the collection is empty, or throws exception
|
||||||
@ -125,15 +122,6 @@ fun <T> List<T>.noneOrSingle(): T? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a random element in the list, or `null` if empty */
|
|
||||||
fun <T> List<T>.randomOrNull(): T? {
|
|
||||||
return when (size) {
|
|
||||||
0 -> null
|
|
||||||
1 -> this[0]
|
|
||||||
else -> this[(Math.random() * size).toInt()]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the index of the given item or throws [IllegalArgumentException] if not found. */
|
/** Returns the index of the given item or throws [IllegalArgumentException] if not found. */
|
||||||
fun <T> List<T>.indexOfOrThrow(item: T): Int {
|
fun <T> List<T>.indexOfOrThrow(item: T): Int {
|
||||||
val i = indexOf(item)
|
val i = indexOf(item)
|
||||||
@ -188,10 +176,7 @@ fun InputStream.hash(): SecureHash {
|
|||||||
|
|
||||||
inline fun <reified T : Any> InputStream.readObject(): T = readFully().deserialize()
|
inline fun <reified T : Any> InputStream.readObject(): T = readFully().deserialize()
|
||||||
|
|
||||||
fun String.abbreviate(maxWidth: Int): String = if (length <= maxWidth) this else take(maxWidth - 1) + "…"
|
fun String.abbreviate(maxWidth: Int): String = if (length <= maxWidth) this else "${take(maxWidth - 1)}…"
|
||||||
|
|
||||||
/** Return the sum of an Iterable of [BigDecimal]s. */
|
|
||||||
fun Iterable<BigDecimal>.sum(): BigDecimal = fold(BigDecimal.ZERO) { a, b -> a + b }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an Observable that buffers events until subscribed.
|
* Returns an Observable that buffers events until subscribed.
|
||||||
@ -451,8 +436,6 @@ inline val Member.isStatic: Boolean get() = Modifier.isStatic(modifiers)
|
|||||||
|
|
||||||
inline val Member.isFinal: Boolean get() = Modifier.isFinal(modifiers)
|
inline val Member.isFinal: Boolean get() = Modifier.isFinal(modifiers)
|
||||||
|
|
||||||
fun URI.toPath(): Path = Paths.get(this)
|
|
||||||
|
|
||||||
fun URL.toPath(): Path = toURI().toPath()
|
fun URL.toPath(): Path = toURI().toPath()
|
||||||
|
|
||||||
val DEFAULT_HTTP_CONNECT_TIMEOUT = 30.seconds.toMillis()
|
val DEFAULT_HTTP_CONNECT_TIMEOUT = 30.seconds.toMillis()
|
||||||
|
@ -2,41 +2,28 @@ package net.corda.core.internal
|
|||||||
|
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import java.io.*
|
import java.io.IOException
|
||||||
import java.nio.charset.Charset
|
import java.io.InputStream
|
||||||
import java.nio.charset.StandardCharsets.UTF_8
|
import java.io.OutputStream
|
||||||
import java.nio.file.*
|
import java.nio.file.CopyOption
|
||||||
|
import java.nio.file.FileVisitResult
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.LinkOption
|
||||||
|
import java.nio.file.OpenOption
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.SimpleFileVisitor
|
||||||
import java.nio.file.attribute.BasicFileAttributes
|
import java.nio.file.attribute.BasicFileAttributes
|
||||||
import java.nio.file.attribute.FileAttribute
|
import kotlin.io.path.createDirectories
|
||||||
import java.nio.file.attribute.FileTime
|
import kotlin.io.path.deleteIfExists
|
||||||
import java.util.stream.Stream
|
import kotlin.io.path.div
|
||||||
import kotlin.streams.toList
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.inputStream
|
||||||
/**
|
import kotlin.io.path.isDirectory
|
||||||
* Allows you to write code like: Paths.get("someDir") / "subdir" / "filename" but using the Paths API to avoid platform
|
import kotlin.io.path.isSymbolicLink
|
||||||
* separator problems.
|
import kotlin.io.path.name
|
||||||
* @see Path.resolve
|
import kotlin.io.path.outputStream
|
||||||
*/
|
import kotlin.io.path.readBytes
|
||||||
operator fun Path.div(other: String): Path = resolve(other)
|
import kotlin.io.path.readSymbolicLink
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows you to write code like: "someDir" / "subdir" / "filename" but using the Paths API to avoid platform
|
|
||||||
* separator problems.
|
|
||||||
* @see Path.resolve
|
|
||||||
*/
|
|
||||||
operator fun String.div(other: String): Path = Paths.get(this) / other
|
|
||||||
|
|
||||||
/** @see Files.createFile */
|
|
||||||
fun Path.createFile(vararg attrs: FileAttribute<*>): Path = Files.createFile(this, *attrs)
|
|
||||||
|
|
||||||
/** @see Files.createDirectory */
|
|
||||||
fun Path.createDirectory(vararg attrs: FileAttribute<*>): Path = Files.createDirectory(this, *attrs)
|
|
||||||
|
|
||||||
/** @see Files.createDirectories */
|
|
||||||
fun Path.createDirectories(vararg attrs: FileAttribute<*>): Path = Files.createDirectories(this, *attrs)
|
|
||||||
|
|
||||||
/** @see Files.exists */
|
|
||||||
fun Path.exists(vararg options: LinkOption): Boolean = Files.exists(this, *options)
|
|
||||||
|
|
||||||
/** Copy the file into the target directory using [Files.copy]. */
|
/** Copy the file into the target directory using [Files.copy]. */
|
||||||
fun Path.copyToDirectory(targetDir: Path, vararg options: CopyOption): Path {
|
fun Path.copyToDirectory(targetDir: Path, vararg options: CopyOption): Path {
|
||||||
@ -50,107 +37,32 @@ fun Path.copyToDirectory(targetDir: Path, vararg options: CopyOption): Path {
|
|||||||
* Path.toString() is assumed safe because fileName should
|
* Path.toString() is assumed safe because fileName should
|
||||||
* not include any path separator characters.
|
* not include any path separator characters.
|
||||||
*/
|
*/
|
||||||
val targetFile = targetDir.resolve(fileName.toString())
|
val targetFile = targetDir / name
|
||||||
Files.copy(this, targetFile, *options)
|
Files.copy(this, targetFile, *options)
|
||||||
return targetFile
|
return targetFile
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see Files.copy */
|
|
||||||
fun Path.copyTo(target: Path, vararg options: CopyOption): Path = Files.copy(this, target, *options)
|
|
||||||
|
|
||||||
/** @see Files.move */
|
|
||||||
fun Path.moveTo(target: Path, vararg options: CopyOption): Path = Files.move(this, target, *options)
|
|
||||||
|
|
||||||
/** @see Files.move */
|
|
||||||
fun Path.renameTo(fileName: String, vararg options: CopyOption): Path = moveTo(parent / fileName, *options)
|
|
||||||
|
|
||||||
/** See overload of [Files.copy] which takes in an [InputStream]. */
|
/** See overload of [Files.copy] which takes in an [InputStream]. */
|
||||||
fun Path.copyTo(out: OutputStream): Long = Files.copy(this, out)
|
fun Path.copyTo(out: OutputStream): Long = Files.copy(this, out)
|
||||||
|
|
||||||
/** @see Files.isRegularFile */
|
|
||||||
fun Path.isRegularFile(vararg options: LinkOption): Boolean = Files.isRegularFile(this, *options)
|
|
||||||
|
|
||||||
/** @see Files.isReadable */
|
|
||||||
inline val Path.isReadable: Boolean get() = Files.isReadable(this)
|
|
||||||
|
|
||||||
/** @see Files.size */
|
|
||||||
inline val Path.size: Long get() = Files.size(this)
|
|
||||||
|
|
||||||
/** @see Files.readAttributes */
|
/** @see Files.readAttributes */
|
||||||
fun Path.attributes(vararg options: LinkOption): BasicFileAttributes = Files.readAttributes(this, BasicFileAttributes::class.java, *options)
|
fun Path.attributes(vararg options: LinkOption): BasicFileAttributes = Files.readAttributes(this, BasicFileAttributes::class.java, *options)
|
||||||
|
|
||||||
/** @see Files.getLastModifiedTime */
|
|
||||||
fun Path.lastModifiedTime(vararg options: LinkOption): FileTime = Files.getLastModifiedTime(this, *options)
|
|
||||||
|
|
||||||
/** @see Files.isDirectory */
|
|
||||||
fun Path.isDirectory(vararg options: LinkOption): Boolean = Files.isDirectory(this, *options)
|
|
||||||
|
|
||||||
/** @see Files.isSameFile */
|
|
||||||
fun Path.isSameAs(other: Path): Boolean = Files.isSameFile(this, other)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as [Files.list] except it also closes the [Stream].
|
|
||||||
* @return the output of [block]
|
|
||||||
*/
|
|
||||||
inline fun <R> Path.list(block: (Stream<Path>) -> R): R = Files.list(this).use(block)
|
|
||||||
|
|
||||||
/** Same as [list] but materialises all the entiries into a list. */
|
|
||||||
fun Path.list(): List<Path> = list { it.toList() }
|
|
||||||
|
|
||||||
/** @see Files.walk */
|
|
||||||
inline fun <R> Path.walk(maxDepth: Int = Int.MAX_VALUE, vararg options: FileVisitOption, block: (Stream<Path>) -> R): R {
|
|
||||||
return Files.walk(this, maxDepth, *options).use(block)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @see Files.delete */
|
|
||||||
fun Path.delete(): Unit = Files.delete(this)
|
|
||||||
|
|
||||||
/** @see Files.deleteIfExists */
|
|
||||||
fun Path.deleteIfExists(): Boolean = Files.deleteIfExists(this)
|
|
||||||
|
|
||||||
/** Deletes this path (if it exists) and if it's a directory, all its child paths recursively. */
|
/** Deletes this path (if it exists) and if it's a directory, all its child paths recursively. */
|
||||||
fun Path.deleteRecursively() {
|
fun Path.deleteRecursively() {
|
||||||
if (!exists()) return
|
if (!exists()) return
|
||||||
Files.walkFileTree(this, object : SimpleFileVisitor<Path>() {
|
Files.walkFileTree(this, object : SimpleFileVisitor<Path>() {
|
||||||
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
|
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
|
||||||
file.delete()
|
file.deleteIfExists()
|
||||||
return FileVisitResult.CONTINUE
|
return FileVisitResult.CONTINUE
|
||||||
}
|
}
|
||||||
override fun postVisitDirectory(dir: Path, exception: IOException?): FileVisitResult {
|
override fun postVisitDirectory(dir: Path, exception: IOException?): FileVisitResult {
|
||||||
dir.delete()
|
dir.deleteIfExists()
|
||||||
return FileVisitResult.CONTINUE
|
return FileVisitResult.CONTINUE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see Files.newOutputStream */
|
|
||||||
fun Path.outputStream(vararg options: OpenOption): OutputStream = Files.newOutputStream(this, *options)
|
|
||||||
|
|
||||||
/** @see Files.newInputStream */
|
|
||||||
fun Path.inputStream(vararg options: OpenOption): InputStream = Files.newInputStream(this, *options)
|
|
||||||
|
|
||||||
/** @see Files.newBufferedReader */
|
|
||||||
fun Path.reader(charset: Charset = UTF_8): BufferedReader = Files.newBufferedReader(this, charset)
|
|
||||||
|
|
||||||
/** @see Files.newBufferedWriter */
|
|
||||||
fun Path.writer(charset: Charset = UTF_8, vararg options: OpenOption): BufferedWriter {
|
|
||||||
return Files.newBufferedWriter(this, charset, *options)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @see Files.readAllBytes */
|
|
||||||
fun Path.readAll(): ByteArray = Files.readAllBytes(this)
|
|
||||||
|
|
||||||
/** Read in this entire file as a string using the given encoding. */
|
|
||||||
fun Path.readText(charset: Charset = UTF_8): String = reader(charset).use(Reader::readText)
|
|
||||||
|
|
||||||
/** @see Files.write */
|
|
||||||
fun Path.write(bytes: ByteArray, vararg options: OpenOption): Path = Files.write(this, bytes, *options)
|
|
||||||
|
|
||||||
/** Write the given string to this file. */
|
|
||||||
fun Path.writeText(text: String, charset: Charset = UTF_8, vararg options: OpenOption) {
|
|
||||||
writer(charset, *options).use { it.write(text) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as [inputStream] except it also closes the [InputStream].
|
* Same as [inputStream] except it also closes the [InputStream].
|
||||||
* @return the output of [block]
|
* @return the output of [block]
|
||||||
@ -169,35 +81,14 @@ inline fun Path.write(createDirs: Boolean = false, vararg options: OpenOption =
|
|||||||
outputStream(*options).use(block)
|
outputStream(*options).use(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as [Files.lines] except it also closes the [Stream]
|
|
||||||
* @return the output of [block]
|
|
||||||
*/
|
|
||||||
inline fun <R> Path.readLines(charset: Charset = UTF_8, block: (Stream<String>) -> R): R {
|
|
||||||
return Files.lines(this, charset).use(block)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @see Files.readAllLines */
|
|
||||||
fun Path.readAllLines(charset: Charset = UTF_8): List<String> = Files.readAllLines(this, charset)
|
|
||||||
|
|
||||||
fun Path.writeLines(lines: Iterable<CharSequence>, charset: Charset = UTF_8, vararg options: OpenOption): Path {
|
|
||||||
return Files.write(this, lines, charset, *options)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read in this file as an AMQP serialised blob of type [T].
|
* Read in this file as an AMQP serialised blob of type [T].
|
||||||
* @see [deserialize]
|
* @see [deserialize]
|
||||||
*/
|
*/
|
||||||
inline fun <reified T : Any> Path.readObject(): T = readAll().deserialize()
|
inline fun <reified T : Any> Path.readObject(): T = readBytes().deserialize()
|
||||||
|
|
||||||
/** Calculate the hash of the contents of this file. */
|
/** Calculate the hash of the contents of this file. */
|
||||||
inline val Path.hash: SecureHash get() = read { it.hash() }
|
inline val Path.hash: SecureHash get() = read { it.hash() }
|
||||||
|
|
||||||
/* Check if the Path is symbolic link */
|
/* Check if the Path is symbolic link */
|
||||||
fun Path.safeSymbolicRead(): Path {
|
fun Path.safeSymbolicRead(): Path = if (isSymbolicLink()) readSymbolicLink() else this
|
||||||
if (Files.isSymbolicLink(this)) {
|
|
||||||
return (Files.readSymbolicLink(this))
|
|
||||||
} else {
|
|
||||||
return (this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -15,6 +15,7 @@ import net.corda.core.serialization.SerializationWhitelist
|
|||||||
import net.corda.core.serialization.SerializeAsToken
|
import net.corda.core.serialization.SerializeAsToken
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.name
|
||||||
|
|
||||||
data class CordappImpl(
|
data class CordappImpl(
|
||||||
override val contractClassNames: List<String>,
|
override val contractClassNames: List<String>,
|
||||||
@ -49,7 +50,7 @@ data class CordappImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun jarName(url: URL): String = (url.toPath().fileName ?: "").toString().removeSuffix(".jar")
|
fun jarName(url: URL): String = url.toPath().name.removeSuffix(".jar")
|
||||||
|
|
||||||
/** CorDapp manifest entries */
|
/** CorDapp manifest entries */
|
||||||
const val CORDAPP_CONTRACT_NAME = "Cordapp-Contract-Name"
|
const val CORDAPP_CONTRACT_NAME = "Cordapp-Contract-Name"
|
||||||
|
@ -6,6 +6,7 @@ import java.nio.file.Files
|
|||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
|
||||||
object TestResourceWriter {
|
object TestResourceWriter {
|
||||||
|
|
||||||
@ -18,13 +19,13 @@ object TestResourceWriter {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Suppress("NestedBlockDepth", "MagicNumber")
|
@Suppress("NestedBlockDepth", "MagicNumber")
|
||||||
fun main(vararg args : String) {
|
fun main(vararg args : String) {
|
||||||
for(arg in args) {
|
for (arg in args) {
|
||||||
/**
|
/**
|
||||||
* Download zip bombs
|
* Download zip bombs
|
||||||
*/
|
*/
|
||||||
for(url in externalZipBombUrls) {
|
for(url in externalZipBombUrls) {
|
||||||
url.openStream().use { inputStream ->
|
url.openStream().use { inputStream ->
|
||||||
val destination = Paths.get(arg).resolve(Paths.get(url.path + ".xor").fileName)
|
val destination = Path(arg).resolve(Paths.get("${url.path}.xor").fileName)
|
||||||
Files.newOutputStream(destination).buffered().let(::XorOutputStream).use { outputStream ->
|
Files.newOutputStream(destination).buffered().let(::XorOutputStream).use { outputStream ->
|
||||||
inputStream.copyTo(outputStream)
|
inputStream.copyTo(outputStream)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,9 @@ import org.junit.rules.TemporaryFolder
|
|||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.file.FileSystems
|
import java.nio.file.FileSystems
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.createFile
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
class PathUtilsTest {
|
class PathUtilsTest {
|
||||||
@Rule
|
@Rule
|
||||||
|
@ -4,8 +4,6 @@ import net.corda.cliutils.CordaCliWrapper
|
|||||||
import net.corda.cliutils.start
|
import net.corda.cliutils.start
|
||||||
import net.corda.core.crypto.sign
|
import net.corda.core.crypto.sign
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.readAll
|
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
@ -26,6 +24,8 @@ import picocli.CommandLine.Option
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.security.cert.CertificateFactory
|
import java.security.cert.CertificateFactory
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.readBytes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NodeInfo signing tool for Corda
|
* NodeInfo signing tool for Corda
|
||||||
@ -66,7 +66,7 @@ class NodeInfoSigner : CordaCliWrapper("nodeinfo-signer", "Display and generate
|
|||||||
private var displayPath: Path? = null
|
private var displayPath: Path? = null
|
||||||
|
|
||||||
@Option(names = ["--address"], paramLabel = "host:port", description = ["Public address of node"], converter = [NetworkHostAndPortConverter::class])
|
@Option(names = ["--address"], paramLabel = "host:port", description = ["Public address of node"], converter = [NetworkHostAndPortConverter::class])
|
||||||
private var addressList: MutableList<NetworkHostAndPort> = mutableListOf<NetworkHostAndPort>()
|
private var addressList: MutableList<NetworkHostAndPort> = mutableListOf()
|
||||||
|
|
||||||
@Option(names = ["--platform-version"], paramLabel = "int", description = ["Platform version that this node supports"])
|
@Option(names = ["--platform-version"], paramLabel = "int", description = ["Platform version that this node supports"])
|
||||||
private var platformVersion: Int = 4
|
private var platformVersion: Int = 4
|
||||||
@ -93,10 +93,7 @@ class NodeInfoSigner : CordaCliWrapper("nodeinfo-signer", "Display and generate
|
|||||||
print(prompt)
|
print(prompt)
|
||||||
System.out.flush()
|
System.out.flush()
|
||||||
val console = System.console()
|
val console = System.console()
|
||||||
if(console != null)
|
return console?.readPassword()?.toString() ?: readln()
|
||||||
return console.readPassword().toString()
|
|
||||||
else
|
|
||||||
return readLine()!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private object AMQPInspectorSerializationScheme : AbstractAMQPSerializationScheme(emptyList()) {
|
private object AMQPInspectorSerializationScheme : AbstractAMQPSerializationScheme(emptyList()) {
|
||||||
@ -147,7 +144,7 @@ class NodeInfoSigner : CordaCliWrapper("nodeinfo-signer", "Display and generate
|
|||||||
println("address: " + nodeInfo.addresses[0])
|
println("address: " + nodeInfo.addresses[0])
|
||||||
println("platformVersion: " + nodeInfo.platformVersion)
|
println("platformVersion: " + nodeInfo.platformVersion)
|
||||||
println("serial " + nodeInfo.serial)
|
println("serial " + nodeInfo.serial)
|
||||||
return 0;
|
return 0
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
require(addressList.size > 0){ "At least one --address must be specified" }
|
require(addressList.size > 0){ "At least one --address must be specified" }
|
||||||
@ -165,7 +162,7 @@ class NodeInfoSigner : CordaCliWrapper("nodeinfo-signer", "Display and generate
|
|||||||
val nodeInfoSigned = generateNodeInfo()
|
val nodeInfoSigned = generateNodeInfo()
|
||||||
val fileNameHash = nodeInfoSigned.nodeInfo.legalIdentities[0].name.serialize().hash
|
val fileNameHash = nodeInfoSigned.nodeInfo.legalIdentities[0].name.serialize().hash
|
||||||
|
|
||||||
val outputFile = outputDirectory!!.toString() / "nodeinfo-${fileNameHash.toString()}"
|
val outputFile = outputDirectory!! / "nodeinfo-$fileNameHash"
|
||||||
|
|
||||||
println(outputFile)
|
println(outputFile)
|
||||||
|
|
||||||
@ -174,8 +171,8 @@ class NodeInfoSigner : CordaCliWrapper("nodeinfo-signer", "Display and generate
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun nodeInfoFromFile(nodeInfoPath: File) : NodeInfo {
|
fun nodeInfoFromFile(nodeInfoPath: File) : NodeInfo {
|
||||||
var serializedNodeInfo = SerializedBytes<SignedNodeInfo>(nodeInfoPath.toPath().readAll())
|
val serializedNodeInfo = SerializedBytes<SignedNodeInfo>(nodeInfoPath.toPath().readBytes())
|
||||||
var signedNodeInfo = serializedNodeInfo.deserialize()
|
val signedNodeInfo = serializedNodeInfo.deserialize()
|
||||||
return signedNodeInfo.verified()
|
return signedNodeInfo.verified()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ import net.corda.core.crypto.Crypto.generateKeyPair
|
|||||||
import net.corda.core.crypto.SignatureScheme
|
import net.corda.core.crypto.SignatureScheme
|
||||||
import net.corda.core.crypto.newSecureRandom
|
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.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
@ -85,6 +84,7 @@ import javax.net.ssl.SSLServerSocket
|
|||||||
import javax.net.ssl.SSLSocket
|
import javax.net.ssl.SSLSocket
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
@ -231,7 +231,7 @@ class X509UtilitiesTest {
|
|||||||
val certCrlDistPoint = CRLDistPoint.getInstance(getExtension(Extension.cRLDistributionPoints).parsedValue)
|
val certCrlDistPoint = CRLDistPoint.getInstance(getExtension(Extension.cRLDistributionPoints).parsedValue)
|
||||||
assertTrue(certCrlDistPoint.distributionPoints.first().distributionPoint.toString().contains(crlDistPoint))
|
assertTrue(certCrlDistPoint.distributionPoints.first().distributionPoint.toString().contains(crlDistPoint))
|
||||||
val certCaAuthorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(getExtension(Extension.authorityKeyIdentifier).parsedValue)
|
val certCaAuthorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(getExtension(Extension.authorityKeyIdentifier).parsedValue)
|
||||||
assertTrue(Arrays.equals(caSubjectKeyIdentifier.keyIdentifier, certCaAuthorityKeyIdentifier.keyIdentifier))
|
assertThat(caSubjectKeyIdentifier.keyIdentifier).isEqualTo(certCaAuthorityKeyIdentifier.keyIdentifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ class X509UtilitiesTest {
|
|||||||
val testName = X500Principal("CN=Test,O=R3 Ltd,L=London,C=GB")
|
val testName = X500Principal("CN=Test,O=R3 Ltd,L=London,C=GB")
|
||||||
val selfSignCert = X509Utilities.createSelfSignedCACertificate(testName, keyPair)
|
val selfSignCert = X509Utilities.createSelfSignedCACertificate(testName, keyPair)
|
||||||
|
|
||||||
assertTrue(Arrays.equals(selfSignCert.publicKey.encoded, keyPair.public.encoded))
|
assertThat(selfSignCert.publicKey.encoded).isEqualTo(keyPair.public.encoded)
|
||||||
|
|
||||||
// Save the private key with self sign cert in the keystore.
|
// Save the private key with self sign cert in the keystore.
|
||||||
val keyStore = loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
val keyStore = loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||||
@ -296,8 +296,8 @@ class X509UtilitiesTest {
|
|||||||
|
|
||||||
// Now sign something with private key and verify against certificate public key
|
// Now sign something with private key and verify against certificate public key
|
||||||
val testData = "123456".toByteArray()
|
val testData = "123456".toByteArray()
|
||||||
val signature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, serverKeyPair.private, testData)
|
val signature = Crypto.doSign(DEFAULT_TLS_SIGNATURE_SCHEME, serverKeyPair.private, testData)
|
||||||
assertTrue { Crypto.isValid(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, serverCert.publicKey, signature, testData) }
|
assertTrue { Crypto.isValid(DEFAULT_TLS_SIGNATURE_SCHEME, serverCert.publicKey, signature, testData) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
|
@ -4,34 +4,36 @@ import com.typesafe.config.ConfigFactory
|
|||||||
import net.corda.core.crypto.secureRandomBytes
|
import net.corda.core.crypto.secureRandomBytes
|
||||||
import net.corda.core.crypto.sha256
|
import net.corda.core.crypto.sha256
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
||||||
|
import net.corda.core.internal.PLATFORM_VERSION
|
||||||
|
import net.corda.core.internal.copyTo
|
||||||
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
|
import net.corda.core.utilities.days
|
||||||
|
import net.corda.coretesting.internal.createNodeInfoAndSigned
|
||||||
import net.corda.node.services.config.NotaryConfig
|
import net.corda.node.services.config.NotaryConfig
|
||||||
import net.corda.nodeapi.internal.DEV_ROOT_CA
|
import net.corda.nodeapi.internal.DEV_ROOT_CA
|
||||||
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
|
||||||
import net.corda.core.utilities.days
|
|
||||||
import net.corda.nodeapi.internal.SignedNodeInfo
|
import net.corda.nodeapi.internal.SignedNodeInfo
|
||||||
import net.corda.nodeapi.internal.config.parseAs
|
import net.corda.nodeapi.internal.config.parseAs
|
||||||
import net.corda.nodeapi.internal.config.toConfig
|
import net.corda.nodeapi.internal.config.toConfig
|
||||||
|
import net.corda.nodeapi.internal.network.CopyCordapps
|
||||||
|
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME
|
||||||
|
import net.corda.nodeapi.internal.network.NetworkBootstrapper
|
||||||
import net.corda.nodeapi.internal.network.NetworkBootstrapper.Companion.DEFAULT_MAX_MESSAGE_SIZE
|
import net.corda.nodeapi.internal.network.NetworkBootstrapper.Companion.DEFAULT_MAX_MESSAGE_SIZE
|
||||||
import net.corda.nodeapi.internal.network.NetworkBootstrapper.Companion.DEFAULT_MAX_TRANSACTION_SIZE
|
import net.corda.nodeapi.internal.network.NetworkBootstrapper.Companion.DEFAULT_MAX_TRANSACTION_SIZE
|
||||||
|
import net.corda.nodeapi.internal.network.NetworkParametersOverrides
|
||||||
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier.Companion.NODE_INFO_FILE_NAME_PREFIX
|
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier.Companion.NODE_INFO_FILE_NAME_PREFIX
|
||||||
|
import net.corda.nodeapi.internal.network.PackageOwner
|
||||||
|
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
||||||
|
import net.corda.nodeapi.internal.network.TestContractsJar
|
||||||
|
import net.corda.nodeapi.internal.network.verifiedNetworkParametersCert
|
||||||
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.DUMMY_NOTARY_NAME
|
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.coretesting.internal.createNodeInfoAndSigned
|
|
||||||
import net.corda.nodeapi.internal.network.CopyCordapps
|
|
||||||
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME
|
|
||||||
import net.corda.nodeapi.internal.network.NetworkBootstrapper
|
|
||||||
import net.corda.nodeapi.internal.network.NetworkParametersOverrides
|
|
||||||
import net.corda.nodeapi.internal.network.PackageOwner
|
|
||||||
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
|
||||||
import net.corda.nodeapi.internal.network.TestContractsJar
|
|
||||||
import net.corda.nodeapi.internal.network.verifiedNetworkParametersCert
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@ -44,6 +46,14 @@ import java.nio.file.Files
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.readBytes
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
|
import kotlin.io.path.writeBytes
|
||||||
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
class NetworkBootstrapperTest {
|
class NetworkBootstrapperTest {
|
||||||
@Rule
|
@Rule
|
||||||
@ -60,11 +70,11 @@ class NetworkBootstrapperTest {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val fakeEmbeddedCorda = fakeFileBytes()
|
private val fakeEmbeddedCorda = fakeFileBytes()
|
||||||
private val fakeEmbeddedCordaJar = Files.createTempFile("corda", ".jar").write(fakeEmbeddedCorda)
|
private val fakeEmbeddedCordaJar = Files.createTempFile("corda", ".jar").apply { writeBytes(fakeEmbeddedCorda) }
|
||||||
|
|
||||||
private fun fakeFileBytes(writeToFile: Path? = null): ByteArray {
|
private fun fakeFileBytes(writeToFile: Path? = null): ByteArray {
|
||||||
val bytes = secureRandomBytes(128)
|
val bytes = secureRandomBytes(128)
|
||||||
writeToFile?.write(bytes)
|
writeToFile?.writeBytes(bytes)
|
||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,8 +272,8 @@ class NetworkBootstrapperTest {
|
|||||||
assertThat(networkParameters.eventHorizon).isEqualTo(eventHorizon)
|
assertThat(networkParameters.eventHorizon).isEqualTo(eventHorizon)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val ALICE = TestIdentity(ALICE_NAME, 70)
|
private val alice = TestIdentity(ALICE_NAME, 70)
|
||||||
private val BOB = TestIdentity(BOB_NAME, 80)
|
private val bob = TestIdentity(BOB_NAME, 80)
|
||||||
|
|
||||||
private val alicePackageName = "com.example.alice"
|
private val alicePackageName = "com.example.alice"
|
||||||
private val bobPackageName = "com.example.bob"
|
private val bobPackageName = "com.example.bob"
|
||||||
@ -271,39 +281,39 @@ class NetworkBootstrapperTest {
|
|||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `register new package namespace in existing network`() {
|
fun `register new package namespace in existing network`() {
|
||||||
createNodeConfFile("alice", aliceConfig)
|
createNodeConfFile("alice", aliceConfig)
|
||||||
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, ALICE.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, alice.publicKey)))
|
||||||
assertContainsPackageOwner("alice", mapOf(Pair(alicePackageName, ALICE.publicKey)))
|
assertContainsPackageOwner("alice", mapOf(Pair(alicePackageName, alice.publicKey)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `register additional package namespace in existing network`() {
|
fun `register additional package namespace in existing network`() {
|
||||||
createNodeConfFile("alice", aliceConfig)
|
createNodeConfFile("alice", aliceConfig)
|
||||||
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, ALICE.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, alice.publicKey)))
|
||||||
assertContainsPackageOwner("alice", mapOf(Pair(alicePackageName, ALICE.publicKey)))
|
assertContainsPackageOwner("alice", mapOf(Pair(alicePackageName, alice.publicKey)))
|
||||||
// register additional package name
|
// register additional package name
|
||||||
createNodeConfFile("bob", bobConfig)
|
createNodeConfFile("bob", bobConfig)
|
||||||
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, ALICE.publicKey), Pair(bobPackageName, BOB.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, alice.publicKey), Pair(bobPackageName, bob.publicKey)))
|
||||||
assertContainsPackageOwner("bob", mapOf(Pair(alicePackageName, ALICE.publicKey), Pair(bobPackageName, BOB.publicKey)))
|
assertContainsPackageOwner("bob", mapOf(Pair(alicePackageName, alice.publicKey), Pair(bobPackageName, bob.publicKey)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `attempt to register overlapping namespaces in existing network`() {
|
fun `attempt to register overlapping namespaces in existing network`() {
|
||||||
createNodeConfFile("alice", aliceConfig)
|
createNodeConfFile("alice", aliceConfig)
|
||||||
val greedyNamespace = "com.example"
|
val greedyNamespace = "com.example"
|
||||||
bootstrap(packageOwnership = mapOf(Pair(greedyNamespace, ALICE.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(greedyNamespace, alice.publicKey)))
|
||||||
assertContainsPackageOwner("alice", mapOf(Pair(greedyNamespace, ALICE.publicKey)))
|
assertContainsPackageOwner("alice", mapOf(Pair(greedyNamespace, alice.publicKey)))
|
||||||
// register overlapping package name
|
// register overlapping package name
|
||||||
createNodeConfFile("bob", bobConfig)
|
createNodeConfFile("bob", bobConfig)
|
||||||
expectedEx.expect(IllegalArgumentException::class.java)
|
expectedEx.expect(IllegalArgumentException::class.java)
|
||||||
expectedEx.expectMessage("Multiple packages added to the packageOwnership overlap.")
|
expectedEx.expectMessage("Multiple packages added to the packageOwnership overlap.")
|
||||||
bootstrap(packageOwnership = mapOf(Pair(greedyNamespace, ALICE.publicKey), Pair(bobPackageName, BOB.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(greedyNamespace, alice.publicKey), Pair(bobPackageName, bob.publicKey)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `unregister single package namespace in network of one`() {
|
fun `unregister single package namespace in network of one`() {
|
||||||
createNodeConfFile("alice", aliceConfig)
|
createNodeConfFile("alice", aliceConfig)
|
||||||
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, ALICE.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, alice.publicKey)))
|
||||||
assertContainsPackageOwner("alice", mapOf(Pair(alicePackageName, ALICE.publicKey)))
|
assertContainsPackageOwner("alice", mapOf(Pair(alicePackageName, alice.publicKey)))
|
||||||
// unregister package name
|
// unregister package name
|
||||||
bootstrap(packageOwnership = emptyMap())
|
bootstrap(packageOwnership = emptyMap())
|
||||||
assertContainsPackageOwner("alice", emptyMap())
|
assertContainsPackageOwner("alice", emptyMap())
|
||||||
@ -312,16 +322,16 @@ class NetworkBootstrapperTest {
|
|||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `unregister single package namespace in network of many`() {
|
fun `unregister single package namespace in network of many`() {
|
||||||
createNodeConfFile("alice", aliceConfig)
|
createNodeConfFile("alice", aliceConfig)
|
||||||
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, ALICE.publicKey), Pair(bobPackageName, BOB.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, alice.publicKey), Pair(bobPackageName, bob.publicKey)))
|
||||||
// unregister package name
|
// unregister package name
|
||||||
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, ALICE.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, alice.publicKey)))
|
||||||
assertContainsPackageOwner("alice", mapOf(Pair(alicePackageName, ALICE.publicKey)))
|
assertContainsPackageOwner("alice", mapOf(Pair(alicePackageName, alice.publicKey)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `unregister all package namespaces in existing network`() {
|
fun `unregister all package namespaces in existing network`() {
|
||||||
createNodeConfFile("alice", aliceConfig)
|
createNodeConfFile("alice", aliceConfig)
|
||||||
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, ALICE.publicKey), Pair(bobPackageName, BOB.publicKey)))
|
bootstrap(packageOwnership = mapOf(Pair(alicePackageName, alice.publicKey), Pair(bobPackageName, bob.publicKey)))
|
||||||
// unregister all package names
|
// unregister all package names
|
||||||
bootstrap(packageOwnership = emptyMap())
|
bootstrap(packageOwnership = emptyMap())
|
||||||
assertContainsPackageOwner("alice", emptyMap())
|
assertContainsPackageOwner("alice", emptyMap())
|
||||||
@ -335,7 +345,7 @@ class NetworkBootstrapperTest {
|
|||||||
maxMessageSize: Int? = DEFAULT_MAX_MESSAGE_SIZE,
|
maxMessageSize: Int? = DEFAULT_MAX_MESSAGE_SIZE,
|
||||||
maxTransactionSize: Int? = DEFAULT_MAX_TRANSACTION_SIZE,
|
maxTransactionSize: Int? = DEFAULT_MAX_TRANSACTION_SIZE,
|
||||||
eventHorizon: Duration? = 30.days) {
|
eventHorizon: Duration? = 30.days) {
|
||||||
providedCordaJar = (rootDir / "corda.jar").let { if (it.exists()) it.readAll() else null }
|
providedCordaJar = (rootDir / "corda.jar").let { if (it.exists()) it.readBytes() else null }
|
||||||
bootstrapper.bootstrap(rootDir, copyCordapps, NetworkParametersOverrides(
|
bootstrapper.bootstrap(rootDir, copyCordapps, NetworkParametersOverrides(
|
||||||
minimumPlatformVersion = minimumPlatformVerison,
|
minimumPlatformVersion = minimumPlatformVerison,
|
||||||
maxMessageSize = maxMessageSize,
|
maxMessageSize = maxMessageSize,
|
||||||
@ -375,9 +385,7 @@ class NetworkBootstrapperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val Path.nodeInfoFile: Path
|
private val Path.nodeInfoFile: Path
|
||||||
get() {
|
get() = useDirectoryEntries { it.single { it.name.startsWith(NODE_INFO_FILE_NAME_PREFIX) } }
|
||||||
return list { it.filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) }.toList() }.single()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val Path.nodeInfo: NodeInfo get() = nodeInfoFile.readObject<SignedNodeInfo>().verified()
|
private val Path.nodeInfo: NodeInfo get() = nodeInfoFile.readObject<SignedNodeInfo>().verified()
|
||||||
|
|
||||||
@ -388,7 +396,7 @@ class NetworkBootstrapperTest {
|
|||||||
|
|
||||||
private fun assertBootstrappedNetwork(cordaJar: ByteArray, vararg nodes: Pair<String, FakeNodeConfig>): NetworkParameters {
|
private fun assertBootstrappedNetwork(cordaJar: ByteArray, vararg nodes: Pair<String, FakeNodeConfig>): NetworkParameters {
|
||||||
val networkParameters = (rootDir / nodes[0].first).networkParameters
|
val networkParameters = (rootDir / nodes[0].first).networkParameters
|
||||||
val allNodeInfoFiles = nodes.map { (rootDir / it.first).nodeInfoFile }.associateBy({ it }, Path::readAll)
|
val allNodeInfoFiles = nodes.map { (rootDir / it.first).nodeInfoFile }.associateWith(Path::readBytes)
|
||||||
|
|
||||||
for ((nodeDirName, config) in nodes) {
|
for ((nodeDirName, config) in nodes) {
|
||||||
val nodeDir = rootDir / nodeDirName
|
val nodeDir = rootDir / nodeDirName
|
||||||
@ -397,7 +405,7 @@ class NetworkBootstrapperTest {
|
|||||||
assertThat(nodeDir.networkParameters).isEqualTo(networkParameters)
|
assertThat(nodeDir.networkParameters).isEqualTo(networkParameters)
|
||||||
// Make sure all the nodes have all of each others' node-info files
|
// Make sure all the nodes have all of each others' node-info files
|
||||||
allNodeInfoFiles.forEach { nodeInfoFile, bytes ->
|
allNodeInfoFiles.forEach { nodeInfoFile, bytes ->
|
||||||
assertThat(nodeDir / NODE_INFO_DIRECTORY / nodeInfoFile.fileName.toString()).hasBinaryContent(bytes)
|
assertThat(nodeDir / NODE_INFO_DIRECTORY / nodeInfoFile.name).hasBinaryContent(bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import java.nio.file.Files
|
|||||||
import java.nio.file.Path
|
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
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
|
|
||||||
// When scanning of the CorDapp Jar is performed without "corda-core.jar" being 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.
|
||||||
|
@ -4,8 +4,6 @@ import net.corda.core.crypto.CompositeKey
|
|||||||
import net.corda.core.crypto.generateKeyPair
|
import net.corda.core.crypto.generateKeyPair
|
||||||
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.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.trace
|
import net.corda.core.utilities.trace
|
||||||
import net.corda.nodeapi.internal.config.FileBasedCertificateStoreSupplier
|
import net.corda.nodeapi.internal.config.FileBasedCertificateStoreSupplier
|
||||||
import net.corda.nodeapi.internal.config.SslConfiguration
|
import net.corda.nodeapi.internal.config.SslConfiguration
|
||||||
@ -21,6 +19,8 @@ import java.security.KeyPair
|
|||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains utility methods for generating identities for a node.
|
* Contains utility methods for generating identities for a node.
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
package net.corda.nodeapi.internal.config
|
package net.corda.nodeapi.internal.config
|
||||||
|
|
||||||
import net.corda.core.crypto.internal.AliasPrivateKey
|
import net.corda.core.crypto.internal.AliasPrivateKey
|
||||||
import net.corda.core.internal.outputStream
|
|
||||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||||
import net.corda.nodeapi.internal.crypto.addOrReplaceCertificate
|
import net.corda.nodeapi.internal.crypto.addOrReplaceCertificate
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
|
||||||
import java.nio.file.OpenOption
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.security.PrivateKey
|
import java.security.PrivateKey
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
@ -21,17 +18,18 @@ interface CertificateStore : Iterable<Pair<String, X509Certificate>> {
|
|||||||
|
|
||||||
fun fromInputStream(stream: InputStream, password: String, entryPassword: String): CertificateStore = DelegatingCertificateStore(X509KeyStore.fromInputStream(stream, password), password, entryPassword)
|
fun fromInputStream(stream: InputStream, password: String, entryPassword: String): CertificateStore = DelegatingCertificateStore(X509KeyStore.fromInputStream(stream, password), password, entryPassword)
|
||||||
|
|
||||||
fun fromResource(storeResourceName: String, password: String, entryPassword: String, classLoader: ClassLoader = Thread.currentThread().contextClassLoader): CertificateStore = fromInputStream(classLoader.getResourceAsStream(storeResourceName), password, entryPassword)
|
fun fromResource(storeResourceName: String,
|
||||||
|
password: String,
|
||||||
|
entryPassword: String,
|
||||||
|
classLoader: ClassLoader = Thread.currentThread().contextClassLoader): CertificateStore {
|
||||||
|
return fromInputStream(classLoader.getResourceAsStream(storeResourceName)!!, password, entryPassword)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val value: X509KeyStore
|
val value: X509KeyStore
|
||||||
val password: String
|
val password: String
|
||||||
val entryPassword: String
|
val entryPassword: String
|
||||||
|
|
||||||
fun writeTo(stream: OutputStream) = value.internal.store(stream, password.toCharArray())
|
|
||||||
|
|
||||||
fun writeTo(path: Path, vararg options: OpenOption) = path.outputStream(*options)
|
|
||||||
|
|
||||||
fun update(action: X509KeyStore.() -> Unit) {
|
fun update(action: X509KeyStore.() -> Unit) {
|
||||||
val result = action.invoke(value)
|
val result = action.invoke(value)
|
||||||
value.save()
|
value.save()
|
||||||
|
@ -3,7 +3,13 @@
|
|||||||
|
|
||||||
package net.corda.nodeapi.internal.config
|
package net.corda.nodeapi.internal.config
|
||||||
|
|
||||||
import com.typesafe.config.*
|
import com.typesafe.config.Config
|
||||||
|
import com.typesafe.config.ConfigException
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
import com.typesafe.config.ConfigUtil
|
||||||
|
import com.typesafe.config.ConfigValue
|
||||||
|
import com.typesafe.config.ConfigValueFactory
|
||||||
|
import com.typesafe.config.ConfigValueType
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.isStatic
|
import net.corda.core.internal.isStatic
|
||||||
import net.corda.core.internal.noneOrSingle
|
import net.corda.core.internal.noneOrSingle
|
||||||
@ -22,7 +28,8 @@ import java.time.Duration
|
|||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.temporal.Temporal
|
import java.time.temporal.Temporal
|
||||||
import java.util.*
|
import java.util.Properties
|
||||||
|
import java.util.UUID
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
@ -99,7 +106,7 @@ fun <T : Any> Config.parseAs(
|
|||||||
.toSortedSet()
|
.toSortedSet()
|
||||||
onUnknownKeys.invoke(unknownConfigurationKeys, logger)
|
onUnknownKeys.invoke(unknownConfigurationKeys, logger)
|
||||||
|
|
||||||
val args = parameters.filterNot { it.isOptional && !hasPath(it.name!!) }.associateBy({ it }) { param ->
|
val args = parameters.filterNot { it.isOptional && !hasPath(it.name!!) }.associateWith { param ->
|
||||||
// Get the matching property for this parameter
|
// Get the matching property for this parameter
|
||||||
val property = clazz.memberProperties.first { it.name == param.name }
|
val property = clazz.memberProperties.first { it.name == param.name }
|
||||||
val path = defaultToOldPath(property)
|
val path = defaultToOldPath(property)
|
||||||
|
@ -3,13 +3,22 @@
|
|||||||
package net.corda.nodeapi.internal.crypto
|
package net.corda.nodeapi.internal.crypto
|
||||||
|
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.read
|
||||||
|
import net.corda.core.internal.safeSymbolicRead
|
||||||
|
import net.corda.core.internal.write
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.security.*
|
import java.security.Key
|
||||||
|
import java.security.KeyPair
|
||||||
|
import java.security.KeyStore
|
||||||
|
import java.security.KeyStoreException
|
||||||
|
import java.security.PrivateKey
|
||||||
|
import java.security.Provider
|
||||||
import java.security.cert.Certificate
|
import java.security.cert.Certificate
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
const val KEYSTORE_TYPE = "JKS"
|
const val KEYSTORE_TYPE = "JKS"
|
||||||
|
|
||||||
@ -144,8 +153,8 @@ fun KeyStore.getX509Certificate(alias: String): X509Certificate {
|
|||||||
* @param keyPassword Password to unlock the private key entries.
|
* @param keyPassword Password to unlock the private key entries.
|
||||||
* @return the requested private key in supported type.
|
* @return the requested private key in supported type.
|
||||||
* @throws KeyStoreException if the keystore has not been initialized.
|
* @throws KeyStoreException if the keystore has not been initialized.
|
||||||
* @throws NoSuchAlgorithmException if the algorithm for recovering the key cannot be found (not supported from the Keystore provider).
|
* @throws java.security.NoSuchAlgorithmException if the algorithm for recovering the key cannot be found (not supported from the Keystore provider).
|
||||||
* @throws UnrecoverableKeyException if the key cannot be recovered (e.g., the given password is wrong).
|
* @throws java.security.UnrecoverableKeyException if the key cannot be recovered (e.g., the given password is wrong).
|
||||||
* @throws IllegalArgumentException on not supported scheme or if the given key specification
|
* @throws IllegalArgumentException on not supported scheme or if the given key specification
|
||||||
* is inappropriate for a supported key factory to produce a private key.
|
* is inappropriate for a supported key factory to produce a private key.
|
||||||
*/
|
*/
|
||||||
|
@ -7,10 +7,8 @@ import net.corda.core.crypto.Crypto
|
|||||||
import net.corda.core.crypto.newSecureRandom
|
import net.corda.core.crypto.newSecureRandom
|
||||||
import net.corda.core.internal.CertRole
|
import net.corda.core.internal.CertRole
|
||||||
import net.corda.core.internal.SignedDataWithCert
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
import net.corda.core.internal.reader
|
|
||||||
import net.corda.core.internal.signWithCert
|
import net.corda.core.internal.signWithCert
|
||||||
import net.corda.core.internal.validate
|
import net.corda.core.internal.validate
|
||||||
import net.corda.core.internal.writer
|
|
||||||
import net.corda.core.utilities.days
|
import net.corda.core.utilities.days
|
||||||
import net.corda.core.utilities.millis
|
import net.corda.core.utilities.millis
|
||||||
import net.corda.core.utilities.toHex
|
import net.corda.core.utilities.toHex
|
||||||
@ -62,11 +60,12 @@ import java.security.cert.X509Certificate
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
import kotlin.experimental.and
|
import kotlin.experimental.and
|
||||||
import kotlin.experimental.or
|
import kotlin.experimental.or
|
||||||
|
import kotlin.io.path.reader
|
||||||
|
import kotlin.io.path.writer
|
||||||
|
|
||||||
object X509Utilities {
|
object X509Utilities {
|
||||||
// Note that this default value only applies to BCCryptoService. Other implementations of CryptoService may have to use different
|
// Note that this default value only applies to BCCryptoService. Other implementations of CryptoService may have to use different
|
||||||
|
@ -6,9 +6,20 @@ import com.typesafe.config.ConfigFactory
|
|||||||
import net.corda.common.configuration.parsing.internal.Configuration
|
import net.corda.common.configuration.parsing.internal.Configuration
|
||||||
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.*
|
import net.corda.core.internal.JarSignatureCollector
|
||||||
|
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
||||||
|
import net.corda.core.internal.PLATFORM_VERSION
|
||||||
|
import net.corda.core.internal.VisibleForTesting
|
||||||
import net.corda.core.internal.concurrent.fork
|
import net.corda.core.internal.concurrent.fork
|
||||||
import net.corda.core.internal.concurrent.transpose
|
import net.corda.core.internal.concurrent.transpose
|
||||||
|
import net.corda.core.internal.copyTo
|
||||||
|
import net.corda.core.internal.copyToDirectory
|
||||||
|
import net.corda.core.internal.div
|
||||||
|
import net.corda.core.internal.location
|
||||||
|
import net.corda.core.internal.read
|
||||||
|
import net.corda.core.internal.readObject
|
||||||
|
import net.corda.core.internal.times
|
||||||
|
import net.corda.core.internal.toPath
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.node.NotaryInfo
|
import net.corda.core.node.NotaryInfo
|
||||||
@ -21,7 +32,11 @@ import net.corda.core.serialization.internal._contextSerializationEnv
|
|||||||
import net.corda.core.utilities.days
|
import net.corda.core.utilities.days
|
||||||
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.nodeapi.internal.*
|
import net.corda.nodeapi.internal.ContractsJar
|
||||||
|
import net.corda.nodeapi.internal.ContractsJarFile
|
||||||
|
import net.corda.nodeapi.internal.DEV_ROOT_CA
|
||||||
|
import net.corda.nodeapi.internal.DevIdentityGenerator
|
||||||
|
import net.corda.nodeapi.internal.SignedNodeInfo
|
||||||
import net.corda.nodeapi.internal.config.getBooleanCaseInsensitive
|
import net.corda.nodeapi.internal.config.getBooleanCaseInsensitive
|
||||||
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier.Companion.NODE_INFO_FILE_NAME_PREFIX
|
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier.Companion.NODE_INFO_FILE_NAME_PREFIX
|
||||||
import net.corda.serialization.internal.AMQP_P2P_CONTEXT
|
import net.corda.serialization.internal.AMQP_P2P_CONTEXT
|
||||||
@ -29,7 +44,6 @@ import net.corda.serialization.internal.CordaSerializationMagic
|
|||||||
import net.corda.serialization.internal.SerializationFactoryImpl
|
import net.corda.serialization.internal.SerializationFactoryImpl
|
||||||
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
|
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
|
||||||
import net.corda.serialization.internal.amqp.amqpMagic
|
import net.corda.serialization.internal.amqp.amqpMagic
|
||||||
import java.io.File
|
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.FileAlreadyExistsException
|
import java.nio.file.FileAlreadyExistsException
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -38,7 +52,7 @@ import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
|||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.*
|
import java.util.Timer
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.jar.JarInputStream
|
import java.util.jar.JarInputStream
|
||||||
@ -46,6 +60,16 @@ import kotlin.collections.component1
|
|||||||
import kotlin.collections.component2
|
import kotlin.collections.component2
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
import kotlin.concurrent.schedule
|
import kotlin.concurrent.schedule
|
||||||
|
import kotlin.io.path.copyTo
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.deleteExisting
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.isSameFileAs
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.readBytes
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to bootstrap a local network of Corda nodes on the same filesystem.
|
* Class to bootstrap a local network of Corda nodes on the same filesystem.
|
||||||
@ -88,7 +112,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
private val jarsThatArentCordapps = setOf("corda.jar", "runnodes.jar")
|
private val jarsThatArentCordapps = setOf("corda.jar", "runnodes.jar")
|
||||||
|
|
||||||
private fun extractEmbeddedCordaJar(): URL {
|
private fun extractEmbeddedCordaJar(): URL {
|
||||||
return Thread.currentThread().contextClassLoader.getResource("corda.jar")
|
return Thread.currentThread().contextClassLoader.getResource("corda.jar")!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateNodeInfos(nodeDirs: List<Path>): List<Path> {
|
private fun generateNodeInfos(nodeDirs: List<Path>): List<Path> {
|
||||||
@ -111,9 +135,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
|
|
||||||
private fun generateNodeInfo(nodeDir: Path): Path {
|
private fun generateNodeInfo(nodeDir: Path): Path {
|
||||||
runNodeJob(nodeInfoGenCmd, nodeDir, "node-info-gen.log")
|
runNodeJob(nodeInfoGenCmd, nodeDir, "node-info-gen.log")
|
||||||
return nodeDir.list { paths ->
|
return nodeDir.useDirectoryEntries { paths -> paths.single { it.name.startsWith(NODE_INFO_FILE_NAME_PREFIX) } }
|
||||||
paths.filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) }.findFirst().get()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDbSchemas(nodeDir: Path) {
|
private fun createDbSchemas(nodeDir: Path) {
|
||||||
@ -122,11 +144,11 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
|
|
||||||
private fun runNodeJob(command: List<String>, nodeDir: Path, logfileName: String) {
|
private fun runNodeJob(command: List<String>, nodeDir: Path, logfileName: String) {
|
||||||
val logsDir = (nodeDir / LOGS_DIR_NAME).createDirectories()
|
val logsDir = (nodeDir / LOGS_DIR_NAME).createDirectories()
|
||||||
val nodeRedirectFile = (logsDir / logfileName).toFile()
|
val nodeRedirectFile = logsDir / logfileName
|
||||||
val process = ProcessBuilder(command)
|
val process = ProcessBuilder(command)
|
||||||
.directory(nodeDir.toFile())
|
.directory(nodeDir.toFile())
|
||||||
.redirectErrorStream(true)
|
.redirectErrorStream(true)
|
||||||
.redirectOutput(nodeRedirectFile)
|
.redirectOutput(nodeRedirectFile.toFile())
|
||||||
.apply { environment()["CAPSULE_CACHE_DIR"] = "../.cache" }
|
.apply { environment()["CAPSULE_CACHE_DIR"] = "../.cache" }
|
||||||
.start()
|
.start()
|
||||||
try {
|
try {
|
||||||
@ -142,7 +164,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun printNodeOutputToConsoleAndThrow(stdoutFile: File) {
|
private fun printNodeOutputToConsoleAndThrow(stdoutFile: Path) {
|
||||||
val nodeDir = stdoutFile.parent
|
val nodeDir = stdoutFile.parent
|
||||||
val nodeIdentifier = try {
|
val nodeIdentifier = try {
|
||||||
ConfigFactory.parseFile((nodeDir / "node.conf").toFile()).getString("myLegalName")
|
ConfigFactory.parseFile((nodeDir / "node.conf").toFile()).getString("myLegalName")
|
||||||
@ -150,7 +172,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
nodeDir
|
nodeDir
|
||||||
}
|
}
|
||||||
System.err.println("#### Error while generating node info file $nodeIdentifier ####")
|
System.err.println("#### Error while generating node info file $nodeIdentifier ####")
|
||||||
stdoutFile.inputStream().copyTo(System.err)
|
stdoutFile.copyTo(System.err)
|
||||||
throw IllegalStateException("Error while generating node info file. Please check the logs in $nodeDir.")
|
throw IllegalStateException("Error while generating node info file. Please check the logs in $nodeDir.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,9 +260,8 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
require(networkParameterOverrides.minimumPlatformVersion == null || networkParameterOverrides.minimumPlatformVersion <= PLATFORM_VERSION) { "Minimum platform version cannot be greater than $PLATFORM_VERSION" }
|
require(networkParameterOverrides.minimumPlatformVersion == null || networkParameterOverrides.minimumPlatformVersion <= PLATFORM_VERSION) { "Minimum platform version cannot be greater than $PLATFORM_VERSION" }
|
||||||
// Don't accidentally include the bootstrapper jar as a CorDapp!
|
// Don't accidentally include the bootstrapper jar as a CorDapp!
|
||||||
val bootstrapperJar = javaClass.location.toPath()
|
val bootstrapperJar = javaClass.location.toPath()
|
||||||
val cordappJars = directory.list { paths ->
|
val cordappJars = directory.useDirectoryEntries("*.jar") { jars ->
|
||||||
paths.filter { it.toString().endsWith(".jar") && !it.isSameAs(bootstrapperJar) && !jarsThatArentCordapps.contains(it.fileName.toString().toLowerCase()) }
|
jars.filter { !it.isSameFileAs(bootstrapperJar) && it.name.lowercase() !in jarsThatArentCordapps }.toList()
|
||||||
.toList()
|
|
||||||
}
|
}
|
||||||
bootstrap(directory, cordappJars, copyCordapps, fromCordform = false, networkParametersOverrides = networkParameterOverrides)
|
bootstrap(directory, cordappJars, copyCordapps, fromCordform = false, networkParametersOverrides = networkParameterOverrides)
|
||||||
}
|
}
|
||||||
@ -262,7 +283,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
println("Nodes found in the following sub-directories: ${nodeDirs.map { it.fileName }}")
|
println("Nodes found in the following sub-directories: ${nodeDirs.map { it.fileName }}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val configs = nodeDirs.associateBy({ it }, { ConfigFactory.parseFile((it / "node.conf").toFile()) })
|
val configs = nodeDirs.associateWith { ConfigFactory.parseFile((it / "node.conf").toFile()) }
|
||||||
checkForDuplicateLegalNames(configs.values)
|
checkForDuplicateLegalNames(configs.values)
|
||||||
|
|
||||||
copyCordapps.copy(cordappJars, nodeDirs, networkAlreadyExists, fromCordform)
|
copyCordapps.copy(cordappJars, nodeDirs, networkAlreadyExists, fromCordform)
|
||||||
@ -300,9 +321,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Path.listEndingWith(suffix: String): List<Path> {
|
private fun Path.listEndingWith(suffix: String): List<Path> = listDirectoryEntries("*$suffix")
|
||||||
return list { file -> file.filter { it.toString().endsWith(suffix) }.toList() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createNodeDirectoriesIfNeeded(directory: Path, fromCordform: Boolean): Boolean {
|
private fun createNodeDirectoriesIfNeeded(directory: Path, fromCordform: Boolean): Boolean {
|
||||||
var networkAlreadyExists = false
|
var networkAlreadyExists = false
|
||||||
@ -319,7 +338,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
val webServerConfFiles = directory.listEndingWith("_web-server.conf")
|
val webServerConfFiles = directory.listEndingWith("_web-server.conf")
|
||||||
|
|
||||||
for (confFile in confFiles) {
|
for (confFile in confFiles) {
|
||||||
val nodeName = confFile.fileName.toString().removeSuffix("_node.conf")
|
val nodeName = confFile.name.removeSuffix("_node.conf")
|
||||||
println("Generating node directory for $nodeName")
|
println("Generating node directory for $nodeName")
|
||||||
if ((directory / nodeName).exists()) {
|
if ((directory / nodeName).exists()) {
|
||||||
//directory already exists, so assume this network has been bootstrapped before
|
//directory already exists, so assume this network has been bootstrapped before
|
||||||
@ -332,25 +351,28 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
cordaJar.copyToDirectory(nodeDir, REPLACE_EXISTING)
|
cordaJar.copyToDirectory(nodeDir, REPLACE_EXISTING)
|
||||||
}
|
}
|
||||||
|
|
||||||
val nodeDirs = directory.list { subDir -> subDir.filter { (it / "node.conf").exists() && !(it / "corda.jar").exists() }.toList() }
|
directory.useDirectoryEntries { subDir ->
|
||||||
for (nodeDir in nodeDirs) {
|
subDir
|
||||||
println("Copying corda.jar into node directory ${nodeDir.fileName}")
|
.filter { (it / "node.conf").exists() && !(it / "corda.jar").exists() }
|
||||||
cordaJar.copyToDirectory(nodeDir)
|
.forEach { nodeDir ->
|
||||||
|
println("Copying corda.jar into node directory ${nodeDir.fileName}")
|
||||||
|
cordaJar.copyToDirectory(nodeDir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromCordform) {
|
if (fromCordform) {
|
||||||
confFiles.forEach(Path::delete)
|
confFiles.forEach(Path::deleteExisting)
|
||||||
webServerConfFiles.forEach(Path::delete)
|
webServerConfFiles.forEach(Path::deleteExisting)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromCordform || usingEmbedded) {
|
if (fromCordform || usingEmbedded) {
|
||||||
cordaJar.delete()
|
cordaJar.deleteExisting()
|
||||||
}
|
}
|
||||||
return networkAlreadyExists
|
return networkAlreadyExists
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun gatherNodeDirectories(directory: Path): List<Path> {
|
private fun gatherNodeDirectories(directory: Path): List<Path> {
|
||||||
val nodeDirs = directory.list { subDir -> subDir.filter { (it / "corda.jar").exists() }.toList() }
|
val nodeDirs = directory.useDirectoryEntries { subDir -> subDir.filter { (it / "corda.jar").exists() }.toList() }
|
||||||
for (nodeDir in nodeDirs) {
|
for (nodeDir in nodeDirs) {
|
||||||
require((nodeDir / "node.conf").exists()) { "Missing node.conf in node directory ${nodeDir.fileName}" }
|
require((nodeDir / "node.conf").exists()) { "Missing node.conf in node directory ${nodeDir.fileName}" }
|
||||||
}
|
}
|
||||||
@ -394,7 +416,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
val netParamsFilesGrouped = nodeDirs.mapNotNull {
|
val netParamsFilesGrouped = nodeDirs.mapNotNull {
|
||||||
val netParamsFile = it / NETWORK_PARAMS_FILE_NAME
|
val netParamsFile = it / NETWORK_PARAMS_FILE_NAME
|
||||||
if (netParamsFile.exists()) netParamsFile else null
|
if (netParamsFile.exists()) netParamsFile else null
|
||||||
}.groupBy { SerializedBytes<SignedNetworkParameters>(it.readAll()) }
|
}.groupBy { SerializedBytes<SignedNetworkParameters>(it.readBytes()) }
|
||||||
|
|
||||||
when (netParamsFilesGrouped.size) {
|
when (netParamsFilesGrouped.size) {
|
||||||
0 -> return null
|
0 -> return null
|
||||||
@ -492,9 +514,7 @@ constructor(private val initSerEnv: Boolean,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isSigned(file: Path): Boolean = file.read {
|
private fun isSigned(file: Path): Boolean = file.read {
|
||||||
JarInputStream(it).use {
|
JarInputStream(it).use(JarSignatureCollector::collectSigningParties).isNotEmpty()
|
||||||
JarSignatureCollector.collectSigningParties(it).isNotEmpty()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,8 +524,7 @@ fun NetworkParameters.overrideWith(override: NetworkParametersOverrides): Networ
|
|||||||
maxMessageSize = override.maxMessageSize ?: this.maxMessageSize,
|
maxMessageSize = override.maxMessageSize ?: this.maxMessageSize,
|
||||||
maxTransactionSize = override.maxTransactionSize ?: this.maxTransactionSize,
|
maxTransactionSize = override.maxTransactionSize ?: this.maxTransactionSize,
|
||||||
eventHorizon = override.eventHorizon ?: this.eventHorizon,
|
eventHorizon = override.eventHorizon ?: this.eventHorizon,
|
||||||
packageOwnership = override.packageOwnership?.map { it.javaPackageName to it.publicKey }?.toMap()
|
packageOwnership = override.packageOwnership?.associate { it.javaPackageName to it.publicKey } ?: this.packageOwnership
|
||||||
?: this.packageOwnership
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package net.corda.nodeapi.internal.network
|
|||||||
import net.corda.core.internal.SignedDataWithCert
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
import net.corda.core.internal.VisibleForTesting
|
import net.corda.core.internal.VisibleForTesting
|
||||||
import net.corda.core.internal.copyTo
|
import net.corda.core.internal.copyTo
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
@ -12,6 +11,7 @@ import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
|||||||
import java.nio.file.FileAlreadyExistsException
|
import java.nio.file.FileAlreadyExistsException
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
class NetworkParametersCopier(
|
class NetworkParametersCopier(
|
||||||
networkParameters: NetworkParameters,
|
networkParameters: NetworkParameters,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.nodeapi.internal.network
|
package net.corda.nodeapi.internal.network
|
||||||
|
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
||||||
|
import net.corda.core.internal.ThreadBox
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.debug
|
import net.corda.core.utilities.debug
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -14,6 +15,14 @@ import java.nio.file.StandardCopyOption.COPY_ATTRIBUTES
|
|||||||
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
||||||
import java.nio.file.attribute.FileTime
|
import java.nio.file.attribute.FileTime
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.io.path.copyTo
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
|
import kotlin.io.path.getLastModifiedTime
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
import kotlin.io.path.moveTo
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class which copies nodeInfo files across a set of running nodes.
|
* Utility class which copies nodeInfo files across a set of running nodes.
|
||||||
@ -96,10 +105,10 @@ class NodeInfoFilesCopier(private val scheduler: Scheduler = Schedulers.io()) :
|
|||||||
private fun poll() {
|
private fun poll() {
|
||||||
nodeDataMapBox.locked {
|
nodeDataMapBox.locked {
|
||||||
for (nodeData in values) {
|
for (nodeData in values) {
|
||||||
nodeData.nodeDir.list { paths ->
|
nodeData.nodeDir.useDirectoryEntries { paths ->
|
||||||
paths
|
paths
|
||||||
.filter { it.isRegularFile() }
|
.filter { it.isRegularFile() }
|
||||||
.filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) }
|
.filter { it.name.startsWith(NODE_INFO_FILE_NAME_PREFIX) }
|
||||||
.forEach { processPath(nodeData, it) }
|
.forEach { processPath(nodeData, it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +119,7 @@ class NodeInfoFilesCopier(private val scheduler: Scheduler = Schedulers.io()) :
|
|||||||
// be copied.
|
// be copied.
|
||||||
private fun processPath(nodeData: NodeData, path: Path) {
|
private fun processPath(nodeData: NodeData, path: Path) {
|
||||||
nodeDataMapBox.alreadyLocked {
|
nodeDataMapBox.alreadyLocked {
|
||||||
val newTimestamp = path.lastModifiedTime()
|
val newTimestamp = path.getLastModifiedTime()
|
||||||
val previousTimestamp = nodeData.previouslySeenFiles.put(path, newTimestamp) ?: FileTime.fromMillis(-1)
|
val previousTimestamp = nodeData.previouslySeenFiles.put(path, newTimestamp) ?: FileTime.fromMillis(-1)
|
||||||
if (newTimestamp > previousTimestamp) {
|
if (newTimestamp > previousTimestamp) {
|
||||||
for (destination in this.values.filter { it.nodeDir != nodeData.nodeDir }.map { it.additionalNodeInfoDirectory }) {
|
for (destination in this.values.filter { it.nodeDir != nodeData.nodeDir }.map { it.additionalNodeInfoDirectory }) {
|
||||||
@ -134,15 +143,15 @@ class NodeInfoFilesCopier(private val scheduler: Scheduler = Schedulers.io()) :
|
|||||||
source.copyTo(tempDestination, COPY_ATTRIBUTES, REPLACE_EXISTING)
|
source.copyTo(tempDestination, COPY_ATTRIBUTES, REPLACE_EXISTING)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
log.warn("Couldn't copy $source to $tempDestination.", exception)
|
log.warn("Couldn't copy $source to $tempDestination.", exception)
|
||||||
tempDestination.delete()
|
tempDestination.deleteIfExists()
|
||||||
throw exception
|
throw exception
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// Then rename it to the desired name. This way the file 'appears' on the filesystem as an atomic operation.
|
// Then rename it to the desired name. This way the file 'appears' on the filesystem as an atomic operation.
|
||||||
tempDestination.moveTo(destination, REPLACE_EXISTING)
|
tempDestination.moveTo(destination, overwrite = true)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
log.warn("Couldn't move $tempDestination to $destination.", exception)
|
log.warn("Couldn't move $tempDestination to $destination.", exception)
|
||||||
tempDestination.delete()
|
tempDestination.deleteIfExists()
|
||||||
throw exception
|
throw exception
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package net.corda.nodeapi.internal.network
|
package net.corda.nodeapi.internal.network
|
||||||
|
|
||||||
import net.corda.core.contracts.ContractClassName
|
import net.corda.core.contracts.ContractClassName
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.toMultiMap
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.services.AttachmentId
|
import net.corda.core.node.services.AttachmentId
|
||||||
import net.corda.nodeapi.internal.ContractsJar
|
import net.corda.nodeapi.internal.ContractsJar
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.readLines
|
||||||
|
|
||||||
private const val EXCLUDE_WHITELIST_FILE_NAME = "exclude_whitelist.txt"
|
private const val EXCLUDE_WHITELIST_FILE_NAME = "exclude_whitelist.txt"
|
||||||
private const val INCLUDE_WHITELIST_FILE_NAME = "include_whitelist.txt"
|
private const val INCLUDE_WHITELIST_FILE_NAME = "include_whitelist.txt"
|
||||||
@ -37,7 +40,7 @@ fun generateWhitelist(networkParameters: NetworkParameters?,
|
|||||||
.flatMap { jar -> (jar.scan()).filter { includeContracts.contains(it) }.map { it to jar.hash } }
|
.flatMap { jar -> (jar.scan()).filter { includeContracts.contains(it) }.map { it to jar.hash } }
|
||||||
.toMultiMap()
|
.toMultiMap()
|
||||||
|
|
||||||
return (newWhiteList.keys + existingWhitelist.keys + newSignedJarsWhiteList.keys).associateBy({ it }) {
|
return (newWhiteList.keys + existingWhitelist.keys + newSignedJarsWhiteList.keys).associateWith {
|
||||||
val existingHashes = existingWhitelist[it] ?: emptyList()
|
val existingHashes = existingWhitelist[it] ?: emptyList()
|
||||||
val newHashes = newWhiteList[it] ?: emptyList()
|
val newHashes = newWhiteList[it] ?: emptyList()
|
||||||
val newHashesFormSignedJar = newSignedJarsWhiteList[it] ?: emptyList()
|
val newHashesFormSignedJar = newSignedJarsWhiteList[it] ?: emptyList()
|
||||||
@ -49,4 +52,4 @@ fun readExcludeWhitelist(directory: Path): List<String> = readAllLines(directory
|
|||||||
|
|
||||||
fun readIncludeWhitelist(directory: Path): List<String> = readAllLines(directory / INCLUDE_WHITELIST_FILE_NAME)
|
fun readIncludeWhitelist(directory: Path): List<String> = readAllLines(directory / INCLUDE_WHITELIST_FILE_NAME)
|
||||||
|
|
||||||
private fun readAllLines(path: Path) : List<String> = if (path.exists()) path.readAllLines().map(String::trim) else emptyList()
|
private fun readAllLines(path: Path): List<String> = if (path.exists()) path.readLines().map(String::trim) else emptyList()
|
||||||
|
@ -5,7 +5,6 @@ import liquibase.database.Database
|
|||||||
import liquibase.database.jvm.JdbcConnection
|
import liquibase.database.jvm.JdbcConnection
|
||||||
import liquibase.exception.ValidationErrors
|
import liquibase.exception.ValidationErrors
|
||||||
import liquibase.resource.ResourceAccessor
|
import liquibase.resource.ResourceAccessor
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.readObject
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
@ -15,6 +14,7 @@ import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
|||||||
import net.corda.nodeapi.internal.persistence.SchemaMigration.Companion.NODE_BASE_DIR_KEY
|
import net.corda.nodeapi.internal.persistence.SchemaMigration.Companion.NODE_BASE_DIR_KEY
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
class AttachmentVersionNumberMigration : CustomTaskChange {
|
class AttachmentVersionNumberMigration : CustomTaskChange {
|
||||||
companion object {
|
companion object {
|
||||||
@ -27,8 +27,8 @@ class AttachmentVersionNumberMigration : CustomTaskChange {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info("Start executing...")
|
logger.info("Start executing...")
|
||||||
var networkParameters: NetworkParameters?
|
val networkParameters: NetworkParameters?
|
||||||
val baseDir = System.getProperty(SchemaMigration.NODE_BASE_DIR_KEY)
|
val baseDir = System.getProperty(NODE_BASE_DIR_KEY)
|
||||||
val availableAttachments = getAttachmentsWithDefaultVersion(connection)
|
val availableAttachments = getAttachmentsWithDefaultVersion(connection)
|
||||||
if (baseDir != null) {
|
if (baseDir != null) {
|
||||||
val path = Paths.get(baseDir) / NETWORK_PARAMS_FILE_NAME
|
val path = Paths.get(baseDir) / NETWORK_PARAMS_FILE_NAME
|
||||||
|
@ -13,7 +13,6 @@ import com.esotericsoftware.kryo.util.DefaultClassResolver
|
|||||||
import com.esotericsoftware.kryo.util.Util
|
import com.esotericsoftware.kryo.util.Util
|
||||||
import net.corda.core.internal.kotlinObjectInstance
|
import net.corda.core.internal.kotlinObjectInstance
|
||||||
import net.corda.core.internal.utilities.PrivateInterner
|
import net.corda.core.internal.utilities.PrivateInterner
|
||||||
import net.corda.core.internal.writer
|
|
||||||
import net.corda.core.serialization.ClassWhitelist
|
import net.corda.core.serialization.ClassWhitelist
|
||||||
import net.corda.core.serialization.internal.AttachmentsClassLoader
|
import net.corda.core.serialization.internal.AttachmentsClassLoader
|
||||||
import net.corda.core.serialization.internal.CheckpointSerializationContext
|
import net.corda.core.serialization.internal.CheckpointSerializationContext
|
||||||
@ -28,8 +27,8 @@ import java.nio.file.Paths
|
|||||||
import java.nio.file.StandardOpenOption.APPEND
|
import java.nio.file.StandardOpenOption.APPEND
|
||||||
import java.nio.file.StandardOpenOption.CREATE
|
import java.nio.file.StandardOpenOption.CREATE
|
||||||
import java.nio.file.StandardOpenOption.WRITE
|
import java.nio.file.StandardOpenOption.WRITE
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
import kotlin.io.path.writer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Corda specific class resolver which enables extra customisation for the purposes of serialization using Kryo
|
* Corda specific class resolver which enables extra customisation for the purposes of serialization using Kryo
|
||||||
|
@ -6,17 +6,20 @@ import com.typesafe.config.ConfigFactory.empty
|
|||||||
import com.typesafe.config.ConfigRenderOptions.defaults
|
import com.typesafe.config.ConfigRenderOptions.defaults
|
||||||
import com.typesafe.config.ConfigValueFactory
|
import com.typesafe.config.ConfigValueFactory
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import org.assertj.core.api.Assertions.*
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||||
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.util.*
|
import java.util.Properties
|
||||||
|
import java.util.UUID
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.reflect.full.primaryConstructor
|
import kotlin.reflect.full.primaryConstructor
|
||||||
|
|
||||||
class ConfigParsingTest {
|
class ConfigParsingTest {
|
||||||
@ -86,7 +89,7 @@ class ConfigParsingTest {
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun Path() {
|
fun Path() {
|
||||||
val path = "tmp" / "test"
|
val path = Path.of("tmp", "test")
|
||||||
testPropertyType<PathData, PathListData, Path>(path, path / "file", valuesToString = true)
|
testPropertyType<PathData, PathListData, Path>(path, path / "file", valuesToString = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package net.corda.nodeapi.internal.cryptoservice.bouncycastle
|
|||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.SignatureScheme
|
import net.corda.core.crypto.SignatureScheme
|
||||||
import net.corda.core.crypto.internal.cordaBouncyCastleProvider
|
import net.corda.core.crypto.internal.cordaBouncyCastleProvider
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.days
|
import net.corda.core.utilities.days
|
||||||
import net.corda.nodeapi.internal.config.CertificateStoreSupplier
|
import net.corda.nodeapi.internal.config.CertificateStoreSupplier
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||||
@ -31,6 +30,7 @@ import java.time.Duration
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.crypto.Cipher
|
import javax.crypto.Cipher
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -49,8 +49,8 @@ class BCCryptoServiceTests {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val temporaryKeystoreFolder = TemporaryFolder()
|
val temporaryKeystoreFolder = TemporaryFolder()
|
||||||
|
|
||||||
lateinit var certificatesDirectory: Path
|
private lateinit var certificatesDirectory: Path
|
||||||
lateinit var wrappingKeyStorePath: Path
|
private lateinit var wrappingKeyStorePath: Path
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package net.corda.nodeapi.internal.network
|
package net.corda.nodeapi.internal.network
|
||||||
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.list
|
|
||||||
import net.corda.core.internal.write
|
|
||||||
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
||||||
import net.corda.testing.common.internal.eventually
|
import net.corda.testing.common.internal.eventually
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
@ -14,6 +11,10 @@ import rx.schedulers.TestScheduler
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.writeBytes
|
||||||
|
|
||||||
class NodeInfoFilesCopierTest {
|
class NodeInfoFilesCopierTest {
|
||||||
companion object {
|
companion object {
|
||||||
@ -34,7 +35,7 @@ class NodeInfoFilesCopierTest {
|
|||||||
private val rootPath get() = folder.root.toPath()
|
private val rootPath get() = folder.root.toPath()
|
||||||
private val scheduler = TestScheduler()
|
private val scheduler = TestScheduler()
|
||||||
|
|
||||||
private fun nodeDir(nodeBaseDir: String) = rootPath.resolve(nodeBaseDir).resolve(ORGANIZATION.toLowerCase())
|
private fun nodeDir(nodeBaseDir: String): Path = rootPath / nodeBaseDir / ORGANIZATION.lowercase()
|
||||||
|
|
||||||
private val node1RootPath by lazy { nodeDir(NODE_1_PATH) }
|
private val node1RootPath by lazy { nodeDir(NODE_1_PATH) }
|
||||||
private val node2RootPath by lazy { nodeDir(NODE_2_PATH) }
|
private val node2RootPath by lazy { nodeDir(NODE_2_PATH) }
|
||||||
@ -56,8 +57,8 @@ class NodeInfoFilesCopierTest {
|
|||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
// Create 2 files, a nodeInfo and another file in node1 folder.
|
// Create 2 files, a nodeInfo and another file in node1 folder.
|
||||||
(node1RootPath / GOOD_NODE_INFO_NAME).write(content)
|
(node1RootPath / GOOD_NODE_INFO_NAME).writeBytes(content)
|
||||||
(node1RootPath / BAD_NODE_INFO_NAME).write(content)
|
(node1RootPath / BAD_NODE_INFO_NAME).writeBytes(content)
|
||||||
|
|
||||||
// Configure the second node.
|
// Configure the second node.
|
||||||
nodeInfoFilesCopier.addConfig(node2RootPath)
|
nodeInfoFilesCopier.addConfig(node2RootPath)
|
||||||
@ -77,8 +78,8 @@ class NodeInfoFilesCopierTest {
|
|||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
// Create 2 files, one of which to be copied, in a node root path.
|
// Create 2 files, one of which to be copied, in a node root path.
|
||||||
(node2RootPath / GOOD_NODE_INFO_NAME).write(content)
|
(node2RootPath / GOOD_NODE_INFO_NAME).writeBytes(content)
|
||||||
(node2RootPath / BAD_NODE_INFO_NAME).write(content)
|
(node2RootPath / BAD_NODE_INFO_NAME).writeBytes(content)
|
||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
eventually(Duration.ofMinutes(1)) {
|
eventually(Duration.ofMinutes(1)) {
|
||||||
@ -95,14 +96,14 @@ class NodeInfoFilesCopierTest {
|
|||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
// Create a file, in node 2 root path.
|
// Create a file, in node 2 root path.
|
||||||
(node2RootPath / GOOD_NODE_INFO_NAME).write(content)
|
(node2RootPath / GOOD_NODE_INFO_NAME).writeBytes(content)
|
||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
// Remove node 2
|
// Remove node 2
|
||||||
nodeInfoFilesCopier.removeConfig(node2RootPath)
|
nodeInfoFilesCopier.removeConfig(node2RootPath)
|
||||||
|
|
||||||
// Create another file in node 2 directory.
|
// Create another file in node 2 directory.
|
||||||
(node2RootPath / GOOD_NODE_INFO_NAME).write(content)
|
(node2RootPath / GOOD_NODE_INFO_NAME).writeBytes(content)
|
||||||
advanceTime()
|
advanceTime()
|
||||||
|
|
||||||
eventually(Duration.ofMinutes(1)) {
|
eventually(Duration.ofMinutes(1)) {
|
||||||
@ -121,11 +122,11 @@ class NodeInfoFilesCopierTest {
|
|||||||
nodeInfoFilesCopier.reset()
|
nodeInfoFilesCopier.reset()
|
||||||
|
|
||||||
advanceTime()
|
advanceTime()
|
||||||
(node2RootPath / GOOD_NODE_INFO_NAME_2).write(content)
|
(node2RootPath / GOOD_NODE_INFO_NAME_2).writeBytes(content)
|
||||||
|
|
||||||
// Give some time to the filesystem to report the change.
|
// Give some time to the filesystem to report the change.
|
||||||
eventually {
|
eventually {
|
||||||
assertThat(node1AdditionalNodeInfoPath.list()).isEmpty()
|
assertThat(node1AdditionalNodeInfoPath.listDirectoryEntries()).isEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +135,8 @@ class NodeInfoFilesCopierTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkDirectoryContainsSingleFile(path: Path, filename: String) {
|
private fun checkDirectoryContainsSingleFile(path: Path, filename: String) {
|
||||||
val files = path.list()
|
val files = path.listDirectoryEntries()
|
||||||
assertThat(files).hasSize(1)
|
assertThat(files).hasSize(1)
|
||||||
assertThat(files[0].fileName.toString()).isEqualTo(filename)
|
assertThat(files[0].name).isEqualTo(filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -35,7 +35,7 @@ class SSLHelperTest {
|
|||||||
trustManagerFactory,
|
trustManagerFactory,
|
||||||
ImmediateExecutor.INSTANCE
|
ImmediateExecutor.INSTANCE
|
||||||
)
|
)
|
||||||
val legalNameHash = SecureHash.sha256(legalName.toString()).toString().take(32).toLowerCase()
|
val legalNameHash = SecureHash.sha256(legalName.toString()).toString().take(32).lowercase()
|
||||||
|
|
||||||
// These hardcoded values must not be changed, something is broken if you have to change these hardcoded values.
|
// These hardcoded values must not be changed, something is broken if you have to change these hardcoded values.
|
||||||
assertEquals("O=Test, L=London, C=GB", legalName.toString())
|
assertEquals("O=Test, L=London, C=GB", legalName.toString())
|
||||||
|
@ -2,10 +2,18 @@ package net.corda.node.flows
|
|||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.CordaException
|
import net.corda.core.CordaException
|
||||||
import net.corda.core.flows.*
|
import net.corda.core.flows.FlowLogic
|
||||||
|
import net.corda.core.flows.FlowSession
|
||||||
|
import net.corda.core.flows.InitiatedBy
|
||||||
|
import net.corda.core.flows.InitiatingFlow
|
||||||
|
import net.corda.core.flows.StartableByRPC
|
||||||
|
import net.corda.core.flows.StateMachineRunId
|
||||||
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.*
|
import net.corda.core.internal.attributes
|
||||||
|
import net.corda.core.internal.copyToDirectory
|
||||||
|
import net.corda.core.internal.deleteRecursively
|
||||||
|
import net.corda.core.internal.hash
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.unwrap
|
import net.corda.core.utilities.unwrap
|
||||||
@ -25,6 +33,10 @@ import org.assertj.core.api.Assertions.assertThat
|
|||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
|
import kotlin.io.path.readText
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
// TraderDemoTest already has a test which checks the node can resume a flow from a checkpoint
|
// TraderDemoTest already has a test which checks the node can resume a flow from a checkpoint
|
||||||
@ -80,7 +92,7 @@ class FlowCheckpointVersionNodeStartupCheckTest {
|
|||||||
return Pair(bob, flowId)
|
return Pair(bob, flowId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DriverDSL.restartBobWithMismatchedCorDapp() {
|
private fun DriverDSL.restartBobWithMismatchedCorDapp() {
|
||||||
val cordappsDir = baseDirectory(BOB_NAME) / "cordapps"
|
val cordappsDir = baseDirectory(BOB_NAME) / "cordapps"
|
||||||
|
|
||||||
// Test the scenerio where the CorDapp no longer exists
|
// Test the scenerio where the CorDapp no longer exists
|
||||||
@ -115,7 +127,7 @@ class FlowCheckpointVersionNodeStartupCheckTest {
|
|||||||
|
|
||||||
private fun DriverDSL.stdOutLogFile(name: CordaX500Name): Path {
|
private fun DriverDSL.stdOutLogFile(name: CordaX500Name): Path {
|
||||||
return baseDirectory(name)
|
return baseDirectory(name)
|
||||||
.list { it.filter { it.toString().endsWith("stdout.log") }.toList() }
|
.listDirectoryEntries("*stdout.log")
|
||||||
.sortedBy { it.attributes().creationTime() }
|
.sortedBy { it.attributes().creationTime() }
|
||||||
.last()
|
.last()
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.corda.node.logging
|
package net.corda.node.logging
|
||||||
|
|
||||||
import net.corda.core.internal.concurrent.transpose
|
import net.corda.core.internal.concurrent.transpose
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
@ -16,6 +15,7 @@ import net.corda.testing.node.internal.FINANCE_CORDAPPS
|
|||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
class IssueCashLoggingTests {
|
class IssueCashLoggingTests {
|
||||||
|
|
||||||
|
@ -9,8 +9,6 @@ import net.corda.core.flows.InitiatingFlow
|
|||||||
import net.corda.core.flows.StartableByRPC
|
import net.corda.core.flows.StartableByRPC
|
||||||
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.list
|
|
||||||
import net.corda.core.internal.readAllLines
|
|
||||||
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.node.AppServiceHub
|
import net.corda.core.node.AppServiceHub
|
||||||
@ -37,6 +35,8 @@ import org.jboss.byteman.agent.submit.Submit
|
|||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
|
import kotlin.io.path.readLines
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
abstract class StateMachineErrorHandlingTest {
|
abstract class StateMachineErrorHandlingTest {
|
||||||
@ -116,9 +116,9 @@ abstract class StateMachineErrorHandlingTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun NodeHandle.getBytemanOutput(): List<String> {
|
private fun NodeHandle.getBytemanOutput(): List<String> {
|
||||||
return baseDirectory.list()
|
return baseDirectory.listDirectoryEntries()
|
||||||
.filter { "net.corda.node.Corda" in it.toString() && "stdout.log" in it.toString() }
|
.filter { "net.corda.node.Corda" in it.toString() && "stdout.log" in it.toString() }
|
||||||
.flatMap { it.readAllLines() }
|
.flatMap { it.readLines() }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun OutOfProcessImpl.stop(timeout: Duration): Boolean {
|
internal fun OutOfProcessImpl.stop(timeout: Duration): Boolean {
|
||||||
|
@ -5,7 +5,6 @@ import net.corda.core.contracts.HashAttachmentConstraint
|
|||||||
import net.corda.core.contracts.SignatureAttachmentConstraint
|
import net.corda.core.contracts.SignatureAttachmentConstraint
|
||||||
import net.corda.core.contracts.StateAndRef
|
import net.corda.core.contracts.StateAndRef
|
||||||
import net.corda.core.internal.deleteRecursively
|
import net.corda.core.internal.deleteRecursively
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
@ -15,6 +14,7 @@ import net.corda.testing.node.internal.internalDriver
|
|||||||
import org.junit.Assume.assumeFalse
|
import org.junit.Assume.assumeFalse
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -23,14 +23,14 @@ open class SignatureConstraintMigrationFromHashConstraintsTests : SignatureConst
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `can evolve from lower contract class version to higher one`() {
|
fun `can evolve from lower contract class version to higher one`() {
|
||||||
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
|
|
||||||
val stateAndRef: StateAndRef<MessageState>? = internalDriver(
|
val stateAndRef: StateAndRef<MessageState>? = internalDriver(
|
||||||
inMemoryDB = false,
|
inMemoryDB = false,
|
||||||
networkParameters = testNetworkParameters(notaries = emptyList(), minimumPlatformVersion = 4),
|
networkParameters = testNetworkParameters(notaries = emptyList(), minimumPlatformVersion = 4),
|
||||||
systemProperties = mapOf("net.corda.recordtransaction.signature.verification.disabled" to true.toString())
|
systemProperties = mapOf("net.corda.recordtransaction.signature.verification.disabled" to true.toString())
|
||||||
) {
|
) {
|
||||||
val nodeName = {
|
val nodeName = run {
|
||||||
val nodeHandle = startNode(NodeParameters(rpcUsers = listOf(user), additionalCordapps = listOf(oldCordapp))).getOrThrow()
|
val nodeHandle = startNode(NodeParameters(rpcUsers = listOf(user), additionalCordapps = listOf(oldCordapp))).getOrThrow()
|
||||||
val nodeName = nodeHandle.nodeInfo.singleIdentity().name
|
val nodeName = nodeHandle.nodeInfo.singleIdentity().name
|
||||||
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
||||||
@ -38,39 +38,36 @@ open class SignatureConstraintMigrationFromHashConstraintsTests : SignatureConst
|
|||||||
}
|
}
|
||||||
nodeHandle.stop()
|
nodeHandle.stop()
|
||||||
nodeName
|
nodeName
|
||||||
}()
|
}
|
||||||
val result = {
|
(baseDirectory(nodeName) / "cordapps").deleteRecursively()
|
||||||
(baseDirectory(nodeName) / "cordapps").deleteRecursively()
|
val nodeHandle = startNode(
|
||||||
val nodeHandle = startNode(
|
NodeParameters(
|
||||||
NodeParameters(
|
providedName = nodeName,
|
||||||
providedName = nodeName,
|
rpcUsers = listOf(user),
|
||||||
rpcUsers = listOf(user),
|
additionalCordapps = listOf(newCordapp)
|
||||||
additionalCordapps = listOf(newCordapp)
|
)
|
||||||
)
|
).getOrThrow()
|
||||||
).getOrThrow()
|
var result: StateAndRef<MessageState>? = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
||||||
var result: StateAndRef<MessageState>? = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
val page = it.proxy.vaultQuery(MessageState::class.java)
|
||||||
val page = it.proxy.vaultQuery(MessageState::class.java)
|
page.states.singleOrNull()
|
||||||
page.states.singleOrNull()
|
}
|
||||||
}
|
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
||||||
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
it.proxy.startFlow(::ConsumeMessage, result!!, defaultNotaryIdentity, false, false).returnValue.getOrThrow()
|
||||||
it.proxy.startFlow(::ConsumeMessage, result!!, defaultNotaryIdentity, false, false).returnValue.getOrThrow()
|
}
|
||||||
}
|
result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
||||||
result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
val page = it.proxy.vaultQuery(MessageState::class.java)
|
||||||
val page = it.proxy.vaultQuery(MessageState::class.java)
|
page.states.singleOrNull()
|
||||||
page.states.singleOrNull()
|
}
|
||||||
}
|
nodeHandle.stop()
|
||||||
nodeHandle.stop()
|
|
||||||
result
|
|
||||||
}()
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
assertNotNull(stateAndRef)
|
assertNotNull(stateAndRef)
|
||||||
assertEquals(transformedMessage, stateAndRef!!.state.data.message)
|
assertEquals(transformedMessage, stateAndRef.state.data.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `auto migration from HashConstraint to SignatureConstraint`() {
|
fun `auto migration from HashConstraint to SignatureConstraint`() {
|
||||||
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
newCordapp = newCordapp,
|
newCordapp = newCordapp,
|
||||||
@ -86,7 +83,7 @@ open class SignatureConstraintMigrationFromHashConstraintsTests : SignatureConst
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `HashConstraint cannot be migrated if 'disableHashConstraints' system property is not set to true`() {
|
fun `HashConstraint cannot be migrated if 'disableHashConstraints' system property is not set to true`() {
|
||||||
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
newCordapp = newCordapp,
|
newCordapp = newCordapp,
|
||||||
@ -102,7 +99,7 @@ open class SignatureConstraintMigrationFromHashConstraintsTests : SignatureConst
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `HashConstraint cannot be migrated to SignatureConstraint if new jar is not signed`() {
|
fun `HashConstraint cannot be migrated to SignatureConstraint if new jar is not signed`() {
|
||||||
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
newCordapp = newUnsignedCordapp,
|
newCordapp = newUnsignedCordapp,
|
||||||
@ -118,7 +115,7 @@ open class SignatureConstraintMigrationFromHashConstraintsTests : SignatureConst
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `HashConstraint cannot be migrated to SignatureConstraint if platform version is not 4 or greater`() {
|
fun `HashConstraint cannot be migrated to SignatureConstraint if platform version is not 4 or greater`() {
|
||||||
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
newCordapp = newCordapp,
|
newCordapp = newCordapp,
|
||||||
@ -136,7 +133,7 @@ open class SignatureConstraintMigrationFromHashConstraintsTests : SignatureConst
|
|||||||
@Ignore("ENT-5676: Disabling to isolate Gradle process death cause")
|
@Ignore("ENT-5676: Disabling to isolate Gradle process death cause")
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `HashConstraint cannot be migrated to SignatureConstraint if a HashConstraint is specified for one state and another uses an AutomaticPlaceholderConstraint`() {
|
fun `HashConstraint cannot be migrated to SignatureConstraint if a HashConstraint is specified for one state and another uses an AutomaticPlaceholderConstraint`() {
|
||||||
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
newCordapp = newCordapp,
|
newCordapp = newCordapp,
|
||||||
|
@ -6,7 +6,6 @@ import net.corda.core.contracts.SignatureAttachmentConstraint
|
|||||||
import net.corda.core.contracts.StateAndRef
|
import net.corda.core.contracts.StateAndRef
|
||||||
import net.corda.core.contracts.WhitelistedByZoneAttachmentConstraint
|
import net.corda.core.contracts.WhitelistedByZoneAttachmentConstraint
|
||||||
import net.corda.core.internal.deleteRecursively
|
import net.corda.core.internal.deleteRecursively
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
@ -14,8 +13,9 @@ import net.corda.testing.core.singleIdentity
|
|||||||
import net.corda.testing.driver.NodeParameters
|
import net.corda.testing.driver.NodeParameters
|
||||||
import net.corda.testing.node.internal.internalDriver
|
import net.corda.testing.node.internal.internalDriver
|
||||||
import org.assertj.core.api.Assertions
|
import org.assertj.core.api.Assertions
|
||||||
import org.junit.Assume
|
import org.junit.Assume.assumeFalse
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -25,14 +25,14 @@ open class SignatureConstraintMigrationFromWhitelistConstraintTests : Signature
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `can evolve from lower contract class version to higher one`() {
|
fun `can evolve from lower contract class version to higher one`() {
|
||||||
Assume.assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
|
|
||||||
val stateAndRef: StateAndRef<MessageState>? = internalDriver(
|
val stateAndRef: StateAndRef<MessageState>? = internalDriver(
|
||||||
inMemoryDB = false,
|
inMemoryDB = false,
|
||||||
networkParameters = testNetworkParameters(notaries = emptyList(), minimumPlatformVersion = 4),
|
networkParameters = testNetworkParameters(notaries = emptyList(), minimumPlatformVersion = 4),
|
||||||
systemProperties = mapOf("net.corda.recordtransaction.signature.verification.disabled" to true.toString())
|
systemProperties = mapOf("net.corda.recordtransaction.signature.verification.disabled" to true.toString())
|
||||||
) {
|
) {
|
||||||
val nodeName = {
|
val nodeName = run {
|
||||||
val nodeHandle = startNode(NodeParameters(rpcUsers = listOf(user), additionalCordapps = listOf(oldCordapp))).getOrThrow()
|
val nodeHandle = startNode(NodeParameters(rpcUsers = listOf(user), additionalCordapps = listOf(oldCordapp))).getOrThrow()
|
||||||
val nodeName = nodeHandle.nodeInfo.singleIdentity().name
|
val nodeName = nodeHandle.nodeInfo.singleIdentity().name
|
||||||
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
||||||
@ -40,39 +40,36 @@ open class SignatureConstraintMigrationFromWhitelistConstraintTests : Signature
|
|||||||
}
|
}
|
||||||
nodeHandle.stop()
|
nodeHandle.stop()
|
||||||
nodeName
|
nodeName
|
||||||
}()
|
}
|
||||||
val result = {
|
(baseDirectory(nodeName) / "cordapps").deleteRecursively()
|
||||||
(baseDirectory(nodeName) / "cordapps").deleteRecursively()
|
val nodeHandle = startNode(
|
||||||
val nodeHandle = startNode(
|
NodeParameters(
|
||||||
NodeParameters(
|
providedName = nodeName,
|
||||||
providedName = nodeName,
|
rpcUsers = listOf(user),
|
||||||
rpcUsers = listOf(user),
|
additionalCordapps = listOf(newCordapp)
|
||||||
additionalCordapps = listOf(newCordapp)
|
)
|
||||||
)
|
).getOrThrow()
|
||||||
).getOrThrow()
|
var result: StateAndRef<MessageState>? = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
||||||
var result: StateAndRef<MessageState>? = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
val page = it.proxy.vaultQuery(MessageState::class.java)
|
||||||
val page = it.proxy.vaultQuery(MessageState::class.java)
|
page.states.singleOrNull()
|
||||||
page.states.singleOrNull()
|
}
|
||||||
}
|
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
||||||
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
it.proxy.startFlow(::ConsumeMessage, result!!, defaultNotaryIdentity, false, false).returnValue.getOrThrow()
|
||||||
it.proxy.startFlow(::ConsumeMessage, result!!, defaultNotaryIdentity, false, false).returnValue.getOrThrow()
|
}
|
||||||
}
|
result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
||||||
result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
|
val page = it.proxy.vaultQuery(MessageState::class.java)
|
||||||
val page = it.proxy.vaultQuery(MessageState::class.java)
|
page.states.singleOrNull()
|
||||||
page.states.singleOrNull()
|
}
|
||||||
}
|
nodeHandle.stop()
|
||||||
nodeHandle.stop()
|
|
||||||
result
|
|
||||||
}()
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
assertNotNull(stateAndRef)
|
assertNotNull(stateAndRef)
|
||||||
assertEquals(transformedMessage, stateAndRef!!.state.data.message)
|
assertEquals(transformedMessage, stateAndRef.state.data.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `auto migration from WhitelistConstraint to SignatureConstraint`() {
|
fun `auto migration from WhitelistConstraint to SignatureConstraint`() {
|
||||||
Assume.assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
newCordapp = newCordapp,
|
newCordapp = newCordapp,
|
||||||
@ -93,7 +90,7 @@ open class SignatureConstraintMigrationFromWhitelistConstraintTests : Signature
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `WhitelistConstraint cannot be migrated to SignatureConstraint if platform version is not 4 or greater`() {
|
fun `WhitelistConstraint cannot be migrated to SignatureConstraint if platform version is not 4 or greater`() {
|
||||||
Assume.assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
newCordapp = newCordapp,
|
newCordapp = newCordapp,
|
||||||
@ -115,7 +112,7 @@ open class SignatureConstraintMigrationFromWhitelistConstraintTests : Signature
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `WhitelistConstraint cannot be migrated to SignatureConstraint if signed JAR is not whitelisted`() {
|
fun `WhitelistConstraint cannot be migrated to SignatureConstraint if signed JAR is not whitelisted`() {
|
||||||
Assume.assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
Assertions.assertThatExceptionOfType(CordaRuntimeException::class.java).isThrownBy {
|
Assertions.assertThatExceptionOfType(CordaRuntimeException::class.java).isThrownBy {
|
||||||
upgradeCorDappBetweenTransactions(
|
upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
@ -130,7 +127,7 @@ open class SignatureConstraintMigrationFromWhitelistConstraintTests : Signature
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `auto migration from WhitelistConstraint to SignatureConstraint will only transition states that do not have a constraint specified`() {
|
fun `auto migration from WhitelistConstraint to SignatureConstraint will only transition states that do not have a constraint specified`() {
|
||||||
Assume.assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
assumeFalse(System.getProperty("os.name").lowercase().startsWith("win")) // See NodeStatePersistenceTests.kt.
|
||||||
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
val (issuanceTransaction, consumingTransaction) = upgradeCorDappBetweenTransactions(
|
||||||
cordapp = oldUnsignedCordapp,
|
cordapp = oldUnsignedCordapp,
|
||||||
newCordapp = newCordapp,
|
newCordapp = newCordapp,
|
||||||
|
@ -9,7 +9,6 @@ import net.corda.core.flows.StartableByRPC
|
|||||||
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.delete
|
|
||||||
import net.corda.core.internal.packageName
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.internal.readFully
|
import net.corda.core.internal.readFully
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
@ -32,6 +31,7 @@ import net.corda.testing.node.internal.internalDriver
|
|||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.deleteExisting
|
||||||
|
|
||||||
open class SignatureConstraintVersioningTests {
|
open class SignatureConstraintVersioningTests {
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ open class SignatureConstraintVersioningTests {
|
|||||||
private fun deleteCorDapp(baseDirectory: Path, cordapp: CustomCordapp) {
|
private fun deleteCorDapp(baseDirectory: Path, cordapp: CustomCordapp) {
|
||||||
val cordappPath =
|
val cordappPath =
|
||||||
baseDirectory.resolve(Paths.get("cordapps")).resolve(cordapp.jarFile.fileName)
|
baseDirectory.resolve(Paths.get("cordapps")).resolve(cordapp.jarFile.fileName)
|
||||||
cordappPath.delete()
|
cordappPath.deleteExisting()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DriverDSL.createConsumingTransaction(
|
private fun DriverDSL.createConsumingTransaction(
|
||||||
|
@ -7,6 +7,7 @@ import net.corda.client.rpc.RPCException
|
|||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.InitiatingFlow
|
import net.corda.core.flows.InitiatingFlow
|
||||||
import net.corda.core.flows.StartableByRPC
|
import net.corda.core.flows.StartableByRPC
|
||||||
|
import net.corda.core.internal.mapToSet
|
||||||
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.finance.flows.CashIssueFlow
|
import net.corda.finance.flows.CashIssueFlow
|
||||||
@ -28,7 +29,7 @@ import org.junit.runner.RunWith
|
|||||||
import org.junit.runners.Parameterized
|
import org.junit.runners.Parameterized
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.sql.Statement
|
import java.sql.Statement
|
||||||
import java.util.*
|
import java.util.Properties
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -286,7 +287,7 @@ private class UsersDB(name: String, users: List<UserAndRoles> = emptyList(), rol
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
require(users.map { it.username }.toSet().size == users.size) {
|
require(users.mapToSet { it.username }.size == users.size) {
|
||||||
"Duplicate username in input"
|
"Duplicate username in input"
|
||||||
}
|
}
|
||||||
connection = DataSourceFactory.createDataSource(Properties().apply {
|
connection = DataSourceFactory.createDataSource(Properties().apply {
|
||||||
|
@ -5,9 +5,9 @@ import net.corda.client.rpc.CordaRPCClient
|
|||||||
import net.corda.core.CordaRuntimeException
|
import net.corda.core.CordaRuntimeException
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.StartableByRPC
|
import net.corda.core.flows.StartableByRPC
|
||||||
import net.corda.core.internal.*
|
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
|
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
||||||
import net.corda.node.internal.NodeStartup
|
import net.corda.node.internal.NodeStartup
|
||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities.NODE_IDENTITY_KEY_ALIAS
|
import net.corda.nodeapi.internal.crypto.X509Utilities.NODE_IDENTITY_KEY_ALIAS
|
||||||
@ -18,18 +18,24 @@ import net.corda.testing.driver.DriverParameters
|
|||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
import net.corda.testing.driver.NodeParameters
|
import net.corda.testing.driver.NodeParameters
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import net.corda.testing.node.internal.enclosedCordapp
|
import net.corda.testing.node.internal.enclosedCordapp
|
||||||
import net.corda.testing.node.internal.startNode
|
import net.corda.testing.node.internal.startNode
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.ObjectInputStream
|
import java.io.ObjectInputStream
|
||||||
import java.io.ObjectOutputStream
|
import java.io.ObjectOutputStream
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
import kotlin.io.path.deleteExisting
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.readLines
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
|
import kotlin.io.path.useLines
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class BootTests {
|
class BootTests {
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
@ -58,13 +64,13 @@ class BootTests {
|
|||||||
driver(DriverParameters(notarySpecs = emptyList(), cordappsForAllNodes = emptyList())) {
|
driver(DriverParameters(notarySpecs = emptyList(), cordappsForAllNodes = emptyList())) {
|
||||||
val alice = startNode(providedName = ALICE_NAME).get()
|
val alice = startNode(providedName = ALICE_NAME).get()
|
||||||
val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
|
val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
|
||||||
val logFile = logFolder.list { it.filter { a -> a.isRegularFile() && a.fileName.toString().startsWith("node") }.findFirst().get() }
|
val logFile = logFolder.useDirectoryEntries { it.single { a -> a.isRegularFile() && a.name.startsWith("node") } }
|
||||||
// Start second Alice, should fail
|
// Start second Alice, should fail
|
||||||
assertThatThrownBy {
|
assertThatThrownBy {
|
||||||
startNode(providedName = ALICE_NAME).getOrThrow()
|
startNode(providedName = ALICE_NAME).getOrThrow()
|
||||||
}
|
}
|
||||||
// We count the number of nodes that wrote into the logfile by counting "Logs can be found in"
|
// We count the number of nodes that wrote into the logfile by counting "Logs can be found in"
|
||||||
val numberOfNodesThatLogged = logFile.readLines { it.filter { NodeStartup.LOGS_CAN_BE_FOUND_IN_STRING in it }.count() }
|
val numberOfNodesThatLogged = logFile.useLines { lines -> lines.count { NodeStartup.LOGS_CAN_BE_FOUND_IN_STRING in it } }
|
||||||
assertEquals(1, numberOfNodesThatLogged)
|
assertEquals(1, numberOfNodesThatLogged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,7 +85,7 @@ class BootTests {
|
|||||||
)) {
|
)) {
|
||||||
val alice = startNode(providedName = ALICE_NAME).getOrThrow()
|
val alice = startNode(providedName = ALICE_NAME).getOrThrow()
|
||||||
val aliceCertDir = alice.baseDirectory / "certificates"
|
val aliceCertDir = alice.baseDirectory / "certificates"
|
||||||
(aliceCertDir / "nodekeystore.jks").delete()
|
(aliceCertDir / "nodekeystore.jks").deleteExisting()
|
||||||
val cert = CertificateStoreStubs.Signing.withCertificatesDirectory(aliceCertDir).get(true)
|
val cert = CertificateStoreStubs.Signing.withCertificatesDirectory(aliceCertDir).get(true)
|
||||||
// Creating a new certificate store does not populate that store with the node certificate path. If the node certificate path is
|
// Creating a new certificate store does not populate that store with the node certificate path. If the node certificate path is
|
||||||
// missing, the node will fail to start but not because the legal identity is missing. To test that a missing legal identity
|
// missing, the node will fail to start but not because the legal identity is missing. To test that a missing legal identity
|
||||||
@ -91,9 +97,9 @@ class BootTests {
|
|||||||
startNode(providedName = ALICE_NAME).getOrThrow()
|
startNode(providedName = ALICE_NAME).getOrThrow()
|
||||||
}
|
}
|
||||||
val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
|
val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
|
||||||
val logFile = logFolder.list { it.filter { a -> a.isRegularFile() && a.fileName.toString().startsWith("node") }.findFirst().get() }
|
val logFile = logFolder.useDirectoryEntries { it.single { a -> a.isRegularFile() && a.name.startsWith("node") } }
|
||||||
val lines = logFile.readLines { lines -> lines.filter { NODE_IDENTITY_KEY_ALIAS in it }.toArray() }
|
val lines = logFile.readLines().filter { NODE_IDENTITY_KEY_ALIAS in it }
|
||||||
assertTrue(lines.count() > 0)
|
assertThat(lines).hasSizeGreaterThan(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import net.corda.core.CordaRuntimeException
|
|||||||
import net.corda.core.contracts.TransactionVerificationException.BrokenTransactionException
|
import net.corda.core.contracts.TransactionVerificationException.BrokenTransactionException
|
||||||
import net.corda.core.contracts.TransactionVerificationException.ContractRejection
|
import net.corda.core.contracts.TransactionVerificationException.ContractRejection
|
||||||
import net.corda.core.internal.hash
|
import net.corda.core.internal.hash
|
||||||
import net.corda.core.internal.inputStream
|
import net.corda.core.internal.read
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.flows.serialization.missing.MissingSerializerBuilderFlow
|
import net.corda.flows.serialization.missing.MissingSerializerBuilderFlow
|
||||||
@ -77,7 +77,7 @@ class ContractWithMissingCustomSerializerTest(private val runInProcess: Boolean)
|
|||||||
.start(user.username, user.password)
|
.start(user.username, user.password)
|
||||||
.use { client ->
|
.use { client ->
|
||||||
with(client.proxy) {
|
with(client.proxy) {
|
||||||
uploadAttachment(flowCorDapp.jarFile.inputStream())
|
flowCorDapp.jarFile.read { uploadAttachment(it) }
|
||||||
startFlow(::MissingSerializerFlow, BOBBINS).returnValue.getOrThrow()
|
startFlow(::MissingSerializerFlow, BOBBINS).returnValue.getOrThrow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import net.corda.core.contracts.SignatureAttachmentConstraint
|
|||||||
import net.corda.core.contracts.StateAndRef
|
import net.corda.core.contracts.StateAndRef
|
||||||
import net.corda.core.contracts.withoutIssuer
|
import net.corda.core.contracts.withoutIssuer
|
||||||
import net.corda.core.internal.deleteRecursively
|
import net.corda.core.internal.deleteRecursively
|
||||||
import net.corda.core.internal.div
|
|
||||||
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.messaging.vaultQueryBy
|
import net.corda.core.messaging.vaultQueryBy
|
||||||
@ -33,6 +32,7 @@ import net.corda.testing.node.internal.cordappWithPackages
|
|||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
class CordappConstraintsTests {
|
class CordappConstraintsTests {
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ class CordappConstraintsTests {
|
|||||||
packageOwnership = mapOf("net.corda.finance.contracts.asset" to packageOwnerKey)
|
packageOwnership = mapOf("net.corda.finance.contracts.asset" to packageOwnerKey)
|
||||||
)
|
)
|
||||||
listOf(alice, bob, notary).forEach { node ->
|
listOf(alice, bob, notary).forEach { node ->
|
||||||
println("Shutting down the node for ${node} ... ")
|
println("Shutting down the node for $node ... ")
|
||||||
(node as OutOfProcess).process.destroyForcibly()
|
(node as OutOfProcess).process.destroyForcibly()
|
||||||
node.stop()
|
node.stop()
|
||||||
NetworkParametersCopier(newParams, overwriteFile = true).install(node.baseDirectory)
|
NetworkParametersCopier(newParams, overwriteFile = true).install(node.baseDirectory)
|
||||||
|
@ -7,7 +7,6 @@ import junit.framework.TestCase.assertTrue
|
|||||||
import net.corda.core.flows.UnexpectedFlowEndException
|
import net.corda.core.flows.UnexpectedFlowEndException
|
||||||
import net.corda.core.internal.InputStreamAndHash
|
import net.corda.core.internal.InputStreamAndHash
|
||||||
import net.corda.core.internal.deleteRecursively
|
import net.corda.core.internal.deleteRecursively
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.messaging.vaultQueryBy
|
import net.corda.core.messaging.vaultQueryBy
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
@ -29,6 +28,7 @@ import net.corda.testing.node.TestCordapp
|
|||||||
import net.corda.testing.node.internal.cordappWithPackages
|
import net.corda.testing.node.internal.cordappWithPackages
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.concurrent.TimeoutException
|
import java.util.concurrent.TimeoutException
|
||||||
|
import kotlin.io.path.div
|
||||||
import net.corda.contracts.incompatible.version1.AttachmentContract as AttachmentContractV1
|
import net.corda.contracts.incompatible.version1.AttachmentContract as AttachmentContractV1
|
||||||
import net.corda.flows.incompatible.version1.AttachmentFlow as AttachmentFlowV1
|
import net.corda.flows.incompatible.version1.AttachmentFlow as AttachmentFlowV1
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package net.corda.node.amqp
|
|||||||
import org.mockito.kotlin.doReturn
|
import org.mockito.kotlin.doReturn
|
||||||
import org.mockito.kotlin.whenever
|
import org.mockito.kotlin.whenever
|
||||||
import net.corda.core.crypto.toStringShort
|
import net.corda.core.crypto.toStringShort
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.toFuture
|
import net.corda.core.toFuture
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
@ -32,6 +31,7 @@ import org.junit.Rule
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class AMQPBridgeTest {
|
class AMQPBridgeTest {
|
||||||
@ -41,7 +41,7 @@ class AMQPBridgeTest {
|
|||||||
|
|
||||||
private val log = loggerFor<AMQPBridgeTest>()
|
private val log = loggerFor<AMQPBridgeTest>()
|
||||||
|
|
||||||
private val BOB = TestIdentity(BOB_NAME)
|
private val bob = TestIdentity(BOB_NAME)
|
||||||
|
|
||||||
private val portAllocation = incrementalPortAllocation()
|
private val portAllocation = incrementalPortAllocation()
|
||||||
private val artemisAddress = portAllocation.nextHostAndPort()
|
private val artemisAddress = portAllocation.nextHostAndPort()
|
||||||
@ -52,7 +52,7 @@ class AMQPBridgeTest {
|
|||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `test acked and nacked messages`() {
|
fun `test acked and nacked messages`() {
|
||||||
// Create local queue
|
// Create local queue
|
||||||
val sourceQueueName = "internal.peers." + BOB.publicKey.toStringShort()
|
val sourceQueueName = "internal.peers." + bob.publicKey.toStringShort()
|
||||||
val (artemisServer, artemisClient, bridgeManager) = createArtemis(sourceQueueName)
|
val (artemisServer, artemisClient, bridgeManager) = createArtemis(sourceQueueName)
|
||||||
|
|
||||||
// Pre-populate local queue with 3 messages
|
// Pre-populate local queue with 3 messages
|
||||||
@ -174,7 +174,7 @@ class AMQPBridgeTest {
|
|||||||
fun `bridge with strict CRL checking does not connect to server with invalid certificates`() {
|
fun `bridge with strict CRL checking does not connect to server with invalid certificates`() {
|
||||||
// Note that the opposite of this test (that a connection is established if strict checking is disabled) is carried out by the
|
// Note that the opposite of this test (that a connection is established if strict checking is disabled) is carried out by the
|
||||||
// ack/nack test above. "Strict CRL checking" means that soft fail mode is disabled.
|
// ack/nack test above. "Strict CRL checking" means that soft fail mode is disabled.
|
||||||
val sourceQueueName = "internal.peers." + BOB.publicKey.toStringShort()
|
val sourceQueueName = "internal.peers." + bob.publicKey.toStringShort()
|
||||||
val (artemisServer, artemisClient, bridge) = createArtemis(sourceQueueName, crlCheckSoftFail = false)
|
val (artemisServer, artemisClient, bridge) = createArtemis(sourceQueueName, crlCheckSoftFail = false)
|
||||||
|
|
||||||
createAMQPServer().use {
|
createAMQPServer().use {
|
||||||
@ -225,7 +225,7 @@ class AMQPBridgeTest {
|
|||||||
// Local queue for outgoing messages
|
// Local queue for outgoing messages
|
||||||
artemis.session.createQueue(
|
artemis.session.createQueue(
|
||||||
QueueConfiguration(sourceQueueName).setRoutingType(RoutingType.ANYCAST).setAddress(sourceQueueName).setDurable(true))
|
QueueConfiguration(sourceQueueName).setRoutingType(RoutingType.ANYCAST).setAddress(sourceQueueName).setDurable(true))
|
||||||
bridgeManager.deployBridge(ALICE_NAME.toString(), sourceQueueName, listOf(amqpAddress), setOf(BOB.name))
|
bridgeManager.deployBridge(ALICE_NAME.toString(), sourceQueueName, listOf(amqpAddress), setOf(bob.name))
|
||||||
}
|
}
|
||||||
return Triple(artemisServer, artemisClient, bridgeManager)
|
return Triple(artemisServer, artemisClient, bridgeManager)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import org.mockito.kotlin.doReturn
|
|||||||
import org.mockito.kotlin.mock
|
import org.mockito.kotlin.mock
|
||||||
import org.mockito.kotlin.whenever
|
import org.mockito.kotlin.whenever
|
||||||
import net.corda.core.internal.JavaVersion
|
import net.corda.core.internal.JavaVersion
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.toFuture
|
import net.corda.core.toFuture
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
@ -34,6 +33,7 @@ import org.junit.runners.Parameterized
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import javax.net.ssl.KeyManagerFactory
|
import javax.net.ssl.KeyManagerFactory
|
||||||
import javax.net.ssl.TrustManagerFactory
|
import javax.net.ssl.TrustManagerFactory
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
package net.corda.node.amqp
|
package net.corda.node.amqp
|
||||||
|
|
||||||
import org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
@ -46,6 +44,8 @@ import org.junit.Before
|
|||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
@ -54,6 +54,7 @@ import java.util.concurrent.LinkedBlockingQueue
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import java.util.stream.IntStream
|
import java.util.stream.IntStream
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
abstract class AbstractServerRevocationTest {
|
abstract class AbstractServerRevocationTest {
|
||||||
@Rule
|
@Rule
|
||||||
|
@ -7,7 +7,6 @@ import io.netty.channel.nio.NioEventLoopGroup
|
|||||||
import io.netty.util.concurrent.DefaultThreadFactory
|
import io.netty.util.concurrent.DefaultThreadFactory
|
||||||
import net.corda.core.crypto.newSecureRandom
|
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.toFuture
|
import net.corda.core.toFuture
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
@ -56,6 +55,7 @@ import javax.net.ssl.SSLServerSocket
|
|||||||
import javax.net.ssl.SSLSocket
|
import javax.net.ssl.SSLSocket
|
||||||
import javax.net.ssl.TrustManagerFactory
|
import javax.net.ssl.TrustManagerFactory
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import net.corda.core.internal.FlowIORequest
|
|||||||
import net.corda.core.internal.IdempotentFlow
|
import net.corda.core.internal.IdempotentFlow
|
||||||
import net.corda.core.internal.TimedFlow
|
import net.corda.core.internal.TimedFlow
|
||||||
import net.corda.core.internal.concurrent.transpose
|
import net.corda.core.internal.concurrent.transpose
|
||||||
|
import net.corda.core.internal.mapToSet
|
||||||
import net.corda.core.messaging.StateMachineTransactionMapping
|
import net.corda.core.messaging.StateMachineTransactionMapping
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
@ -69,8 +70,8 @@ class FlowReloadAfterCheckpointTest {
|
|||||||
val handle = alice.rpc.startFlow(::ReloadFromCheckpointFlow, bob.nodeInfo.singleIdentity(), false, false, false)
|
val handle = alice.rpc.startFlow(::ReloadFromCheckpointFlow, bob.nodeInfo.singleIdentity(), false, false, false)
|
||||||
val flowStartedByAlice = handle.id
|
val flowStartedByAlice = handle.id
|
||||||
handle.returnValue.getOrThrow()
|
handle.returnValue.getOrThrow()
|
||||||
assertEquals(5, reloads.filter { it == flowStartedByAlice }.count())
|
assertEquals(5, reloads.count { it == flowStartedByAlice })
|
||||||
assertEquals(6, reloads.filter { it == ReloadFromCheckpointResponder.flowId }.count())
|
assertEquals(6, reloads.count { it == ReloadFromCheckpointResponder.flowId })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,8 +128,8 @@ class FlowReloadAfterCheckpointTest {
|
|||||||
observations.await(DEFAULT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS)
|
observations.await(DEFAULT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS)
|
||||||
reloads.await(DEFAULT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS)
|
reloads.await(DEFAULT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS)
|
||||||
assertEquals(flowStartedByAlice, observations.singleOrNull())
|
assertEquals(flowStartedByAlice, observations.singleOrNull())
|
||||||
assertEquals(4, reloads.filter { it == flowStartedByAlice }.count())
|
assertEquals(4, reloads.count { it == flowStartedByAlice })
|
||||||
assertEquals(4, reloads.filter { it == ReloadFromCheckpointResponder.flowId }.count())
|
assertEquals(4, reloads.count { it == ReloadFromCheckpointResponder.flowId })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,8 +155,8 @@ class FlowReloadAfterCheckpointTest {
|
|||||||
val flowStartedByAlice = handle.id
|
val flowStartedByAlice = handle.id
|
||||||
handle.returnValue.getOrThrow()
|
handle.returnValue.getOrThrow()
|
||||||
reloads.await(DEFAULT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS)
|
reloads.await(DEFAULT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS)
|
||||||
assertEquals(5, reloads.filter { it == flowStartedByAlice }.count())
|
assertEquals(5, reloads.count { it == flowStartedByAlice })
|
||||||
assertEquals(6, reloads.filter { it == ReloadFromCheckpointResponder.flowId }.count())
|
assertEquals(6, reloads.count { it == ReloadFromCheckpointResponder.flowId })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,8 +333,7 @@ class FlowReloadAfterCheckpointTest {
|
|||||||
val flowStartedByAlice = handle.id
|
val flowStartedByAlice = handle.id
|
||||||
handle.returnValue.getOrThrow(30.seconds)
|
handle.returnValue.getOrThrow(30.seconds)
|
||||||
val flowStartedByBob = bob.rpc.stateMachineRecordedTransactionMappingSnapshot()
|
val flowStartedByBob = bob.rpc.stateMachineRecordedTransactionMappingSnapshot()
|
||||||
.map(StateMachineTransactionMapping::stateMachineRunId)
|
.mapToSet(StateMachineTransactionMapping::stateMachineRunId)
|
||||||
.toSet()
|
|
||||||
.single()
|
.single()
|
||||||
reloads.await(DEFAULT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS)
|
reloads.await(DEFAULT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS)
|
||||||
assertEquals(8, reloads.filter { it == flowStartedByAlice }.size)
|
assertEquals(8, reloads.filter { it == flowStartedByAlice }.size)
|
||||||
@ -522,6 +522,6 @@ class FlowReloadAfterCheckpointTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class BrokenMap<K, V>(delegate: MutableMap<K, V> = mutableMapOf()) : MutableMap<K, V> by delegate {
|
internal class BrokenMap<K, V>(delegate: MutableMap<K, V> = mutableMapOf()) : MutableMap<K, V> by delegate {
|
||||||
override fun put(key: K, value: V): V? = throw IllegalStateException("Broken on purpose")
|
override fun put(key: K, value: V): V = throw IllegalStateException("Broken on purpose")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,10 +27,12 @@ import org.assertj.core.api.Assertions.assertThatThrownBy
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
class AttachmentLoadingTests {
|
class AttachmentLoadingTests {
|
||||||
private companion object {
|
private companion object {
|
||||||
val isolatedJar: URL = AttachmentLoadingTests::class.java.getResource("/isolated.jar")
|
val isolatedJar: URL = AttachmentLoadingTests::class.java.getResource("/isolated.jar")!!
|
||||||
val isolatedClassLoader = URLClassLoader(arrayOf(isolatedJar))
|
val isolatedClassLoader = URLClassLoader(arrayOf(isolatedJar))
|
||||||
val issuanceFlowClass: Class<FlowLogic<StateRef>> = uncheckedCast(loadFromIsolated("net.corda.isolated.workflows.IsolatedIssuanceFlow"))
|
val issuanceFlowClass: Class<FlowLogic<StateRef>> = uncheckedCast(loadFromIsolated("net.corda.isolated.workflows.IsolatedIssuanceFlow"))
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.corda.node.services.identity
|
package net.corda.node.services.identity
|
||||||
|
|
||||||
import net.corda.core.internal.PLATFORM_VERSION
|
import net.corda.core.internal.PLATFORM_VERSION
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
||||||
import net.corda.finance.DOLLARS
|
import net.corda.finance.DOLLARS
|
||||||
@ -28,6 +27,7 @@ import org.junit.After
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
|
@ -2,7 +2,6 @@ package net.corda.node.services.identity
|
|||||||
|
|
||||||
import org.mockito.kotlin.doReturn
|
import org.mockito.kotlin.doReturn
|
||||||
import org.mockito.kotlin.whenever
|
import org.mockito.kotlin.whenever
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.finance.DOLLARS
|
import net.corda.finance.DOLLARS
|
||||||
import net.corda.finance.USD
|
import net.corda.finance.USD
|
||||||
@ -30,6 +29,7 @@ import org.junit.After
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.junit.runners.Parameterized
|
import org.junit.runners.Parameterized
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@RunWith(Parameterized::class)
|
@RunWith(Parameterized::class)
|
||||||
|
@ -4,7 +4,6 @@ import org.mockito.kotlin.doReturn
|
|||||||
import org.mockito.kotlin.whenever
|
import org.mockito.kotlin.whenever
|
||||||
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.div
|
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
||||||
import net.corda.finance.DOLLARS
|
import net.corda.finance.DOLLARS
|
||||||
@ -36,6 +35,7 @@ import net.corda.testing.node.internal.startFlow
|
|||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class TrustRootTest {
|
class TrustRootTest {
|
||||||
|
@ -4,7 +4,6 @@ import com.codahale.metrics.MetricRegistry
|
|||||||
import org.mockito.kotlin.doReturn
|
import org.mockito.kotlin.doReturn
|
||||||
import org.mockito.kotlin.whenever
|
import org.mockito.kotlin.whenever
|
||||||
import net.corda.core.crypto.generateKeyPair
|
import net.corda.core.crypto.generateKeyPair
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
import net.corda.coretesting.internal.rigorousMock
|
import net.corda.coretesting.internal.rigorousMock
|
||||||
@ -40,6 +39,7 @@ import java.util.concurrent.BlockingQueue
|
|||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -233,7 +233,7 @@ class ArtemisMessagingTest {
|
|||||||
MetricRegistry(),
|
MetricRegistry(),
|
||||||
TestingNamedCacheFactory(),
|
TestingNamedCacheFactory(),
|
||||||
isDrainingModeOn = { false },
|
isDrainingModeOn = { false },
|
||||||
drainingModeWasChangedEvents = PublishSubject.create<Pair<Boolean, Boolean>>(),
|
drainingModeWasChangedEvents = PublishSubject.create(),
|
||||||
terminateOnConnectionError = false,
|
terminateOnConnectionError = false,
|
||||||
timeoutConfig = P2PMessagingClient.TimeoutConfig(10.seconds, 10.seconds, 10.seconds)).apply {
|
timeoutConfig = P2PMessagingClient.TimeoutConfig(10.seconds, 10.seconds, 10.seconds)).apply {
|
||||||
config.configureWithDevSSLCertificate()
|
config.configureWithDevSSLCertificate()
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
package net.corda.node.services.messaging
|
package net.corda.node.services.messaging
|
||||||
|
|
||||||
import net.corda.client.rpc.ext.MultiRPCClient
|
import net.corda.client.rpc.ext.MultiRPCClient
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.isRegularFile
|
|
||||||
import net.corda.core.internal.list
|
|
||||||
import net.corda.core.messaging.flows.FlowManagerRPCOps
|
import net.corda.core.messaging.flows.FlowManagerRPCOps
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
@ -16,6 +12,10 @@ import net.corda.testing.driver.DriverParameters
|
|||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import net.corda.testing.node.User
|
import net.corda.testing.node.User
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
import net.corda.core.internal.messaging.FlowManagerRPCOps as InternalFlowManagerRPCOps
|
import net.corda.core.internal.messaging.FlowManagerRPCOps as InternalFlowManagerRPCOps
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ class FlowManagerRPCOpsTest {
|
|||||||
it.stop()
|
it.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNotNull(logDirPath.list().singleOrNull { it.isRegularFile() })
|
assertNotNull(logDirPath.listDirectoryEntries().singleOrNull { it.isRegularFile() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ class FlowManagerRPCOpsTest {
|
|||||||
it.stop()
|
it.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNotNull(logDirPath.list().singleOrNull { it.isRegularFile() })
|
assertNotNull(logDirPath.listDirectoryEntries().singleOrNull { it.isRegularFile() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,9 @@ package net.corda.node.services.network
|
|||||||
|
|
||||||
import net.corda.core.crypto.random63BitValue
|
import net.corda.core.crypto.random63BitValue
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
||||||
|
import net.corda.core.internal.bufferUntilSubscribed
|
||||||
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.messaging.ParametersUpdateInfo
|
import net.corda.core.messaging.ParametersUpdateInfo
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
@ -17,23 +19,34 @@ import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
|||||||
import net.corda.testing.common.internal.addNotary
|
import net.corda.testing.common.internal.addNotary
|
||||||
import net.corda.testing.common.internal.eventually
|
import net.corda.testing.common.internal.eventually
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.ALICE_NAME
|
||||||
|
import net.corda.testing.core.BOB_NAME
|
||||||
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
|
import net.corda.testing.core.TestIdentity
|
||||||
|
import net.corda.testing.core.expect
|
||||||
|
import net.corda.testing.core.expectEvents
|
||||||
|
import net.corda.testing.core.sequence
|
||||||
import net.corda.testing.driver.NodeHandle
|
import net.corda.testing.driver.NodeHandle
|
||||||
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.driver.internal.incrementalPortAllocation
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.CompatibilityZoneParams
|
||||||
|
import net.corda.testing.node.internal.DriverDSLImpl
|
||||||
|
import net.corda.testing.node.internal.SplitCompatibilityZoneParams
|
||||||
|
import net.corda.testing.node.internal.internalDriver
|
||||||
import net.corda.testing.node.internal.network.NetworkMapServer
|
import net.corda.testing.node.internal.network.NetworkMapServer
|
||||||
|
import net.corda.testing.node.internal.startNode
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
import org.hamcrest.CoreMatchers.`is`
|
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertThat
|
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
|
|
||||||
class NetworkMapTest {
|
class NetworkMapTest {
|
||||||
@Rule
|
@Rule
|
||||||
@ -280,9 +293,10 @@ class NetworkMapTest {
|
|||||||
// Make sure the nodes aren't getting the node infos from their additional-node-infos directories
|
// Make sure the nodes aren't getting the node infos from their additional-node-infos directories
|
||||||
val nodeInfosDir = baseDirectory / NODE_INFO_DIRECTORY
|
val nodeInfosDir = baseDirectory / NODE_INFO_DIRECTORY
|
||||||
if (nodeInfosDir.exists()) {
|
if (nodeInfosDir.exists()) {
|
||||||
assertThat(nodeInfosDir.list().size, `is`(1))
|
val nodeInfos = nodeInfosDir.listDirectoryEntries()
|
||||||
assertThat(nodeInfosDir.list().single().readObject<SignedNodeInfo>()
|
assertThat(nodeInfos).hasSize(1)
|
||||||
.verified().legalIdentities.first(), `is`(this.nodeInfo.legalIdentities.first()))
|
assertThat(nodeInfos.single().readObject<SignedNodeInfo>().verified().legalIdentities.first())
|
||||||
|
.isEqualTo(nodeInfo.legalIdentities.first())
|
||||||
}
|
}
|
||||||
assertThat(rpc.networkMapSnapshot()).containsOnly(*nodes)
|
assertThat(rpc.networkMapSnapshot()).containsOnly(*nodes)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import net.corda.client.rpc.RPCException
|
|||||||
import net.corda.client.rpc.internal.RPCClient
|
import net.corda.client.rpc.internal.RPCClient
|
||||||
import net.corda.core.context.AuthServiceId
|
import net.corda.core.context.AuthServiceId
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.messaging.ClientRpcSslOptions
|
import net.corda.core.messaging.ClientRpcSslOptions
|
||||||
import net.corda.core.messaging.RPCOps
|
import net.corda.core.messaging.RPCOps
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
@ -34,6 +33,7 @@ import org.junit.Test
|
|||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
class ArtemisRpcTests {
|
class ArtemisRpcTests {
|
||||||
private val ports: PortAllocation = incrementalPortAllocation()
|
private val ports: PortAllocation = incrementalPortAllocation()
|
||||||
|
@ -6,11 +6,6 @@ import com.natpryce.hamkrest.containsSubstring
|
|||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.StartableByRPC
|
import net.corda.core.flows.StartableByRPC
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.inputStream
|
|
||||||
import net.corda.core.internal.isRegularFile
|
|
||||||
import net.corda.core.internal.list
|
|
||||||
import net.corda.core.internal.readFully
|
import net.corda.core.internal.readFully
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
@ -30,6 +25,11 @@ import org.junit.Test
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.inputStream
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
import kotlin.io.path.listDirectoryEntries
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class DumpCheckpointsTest {
|
class DumpCheckpointsTest {
|
||||||
@ -88,10 +88,10 @@ class DumpCheckpointsTest {
|
|||||||
|
|
||||||
private fun checkDumpFile(dir: Path, containsClass: Class<out FlowLogic<*>>, flowStatus: Checkpoint.FlowStatus) {
|
private fun checkDumpFile(dir: Path, containsClass: Class<out FlowLogic<*>>, flowStatus: Checkpoint.FlowStatus) {
|
||||||
// The directory supposed to contain a single ZIP file
|
// The directory supposed to contain a single ZIP file
|
||||||
val file = dir.list().single { it.isRegularFile() }
|
val file = dir.listDirectoryEntries().single { it.isRegularFile() }
|
||||||
|
|
||||||
ZipInputStream(file.inputStream()).use { zip ->
|
ZipInputStream(file.inputStream()).use { zip ->
|
||||||
val entry = zip.nextEntry
|
val entry = zip.nextEntry!!
|
||||||
assertThat(entry.name, containsSubstring("json"))
|
assertThat(entry.name, containsSubstring("json"))
|
||||||
val content = String(zip.readFully())
|
val content = String(zip.readFully())
|
||||||
assertThat(content, containsSubstring(containsClass.name))
|
assertThat(content, containsSubstring(containsClass.name))
|
||||||
|
@ -2,7 +2,6 @@ package net.corda.node.services.rpc
|
|||||||
|
|
||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
import net.corda.client.rpc.RPCException
|
import net.corda.client.rpc.RPCException
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.messaging.ClientRpcSslOptions
|
import net.corda.core.messaging.ClientRpcSslOptions
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.node.services.Permissions.Companion.all
|
import net.corda.node.services.Permissions.Companion.all
|
||||||
@ -23,6 +22,7 @@ import org.junit.Rule
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
class RpcSslTest {
|
class RpcSslTest {
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import net.corda.core.flows.*
|
|||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.concurrent.fork
|
import net.corda.core.internal.concurrent.fork
|
||||||
import net.corda.core.internal.concurrent.transpose
|
import net.corda.core.internal.concurrent.transpose
|
||||||
import net.corda.core.internal.div
|
|
||||||
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.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
@ -27,6 +26,7 @@ import java.util.*
|
|||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class HardRestartTest {
|
class HardRestartTest {
|
||||||
@ -184,17 +184,17 @@ class HardRestartTest {
|
|||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
@InitiatedBy(RecursiveB::class)
|
@InitiatedBy(RecursiveB::class)
|
||||||
class RecursiveA(val mode: RecursiveMode) : FlowLogic<String>() {
|
class RecursiveA(private val mode: RecursiveMode) : FlowLogic<String>() {
|
||||||
constructor(otherSession: FlowSession) : this(RecursiveMode.Recursive(otherSession))
|
constructor(otherSession: FlowSession) : this(RecursiveMode.Recursive(otherSession))
|
||||||
constructor(otherParty: Party, initialDepth: Int) : this(RecursiveMode.Top(otherParty, initialDepth))
|
constructor(otherParty: Party, initialDepth: Int) : this(RecursiveMode.Top(otherParty, initialDepth))
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): String {
|
override fun call(): String {
|
||||||
return when (mode) {
|
return when (mode) {
|
||||||
is HardRestartTest.RecursiveMode.Top -> {
|
is RecursiveMode.Top -> {
|
||||||
val session = initiateFlow(mode.otherParty)
|
val session = initiateFlow(mode.otherParty)
|
||||||
session.sendAndReceive<String>(mode.initialDepth).unwrap { it }
|
session.sendAndReceive<String>(mode.initialDepth).unwrap { it }
|
||||||
}
|
}
|
||||||
is HardRestartTest.RecursiveMode.Recursive -> {
|
is RecursiveMode.Recursive -> {
|
||||||
val depth = mode.otherSession.receive<Int>().unwrap { it }
|
val depth = mode.otherSession.receive<Int>().unwrap { it }
|
||||||
val string = if (depth > 0) {
|
val string = if (depth > 0) {
|
||||||
val newSession = initiateFlow(mode.otherSession.counterparty)
|
val newSession = initiateFlow(mode.otherSession.counterparty)
|
||||||
|
@ -3,22 +3,19 @@ package net.corda.services.messaging
|
|||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.toStringShort
|
import net.corda.core.crypto.toStringShort
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.toX500Name
|
import net.corda.core.internal.toX500Name
|
||||||
import net.corda.coretesting.internal.configureTestSSL
|
import net.corda.coretesting.internal.configureTestSSL
|
||||||
|
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
||||||
import net.corda.nodeapi.RPCApi
|
import net.corda.nodeapi.RPCApi
|
||||||
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.NODE_P2P_USER
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.NODE_P2P_USER
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.PEER_USER
|
import net.corda.nodeapi.internal.ArtemisMessagingComponent.Companion.PEER_USER
|
||||||
import net.corda.nodeapi.internal.DEV_INTERMEDIATE_CA
|
import net.corda.nodeapi.internal.DEV_INTERMEDIATE_CA
|
||||||
import net.corda.nodeapi.internal.DEV_ROOT_CA
|
import net.corda.nodeapi.internal.DEV_ROOT_CA
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
import net.corda.nodeapi.internal.loadDevCaTrustStore
|
|
||||||
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
|
||||||
import net.corda.nodeapi.internal.ArtemisMessagingComponent
|
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
|
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
|
||||||
|
import net.corda.nodeapi.internal.loadDevCaTrustStore
|
||||||
import net.corda.nodeapi.internal.registerDevP2pCertificates
|
import net.corda.nodeapi.internal.registerDevP2pCertificates
|
||||||
import net.corda.services.messaging.SimpleAMQPClient.Companion.sendAndVerify
|
import net.corda.services.messaging.SimpleAMQPClient.Companion.sendAndVerify
|
||||||
import net.corda.testing.core.BOB_NAME
|
import net.corda.testing.core.BOB_NAME
|
||||||
@ -38,6 +35,9 @@ import org.junit.Test
|
|||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import javax.jms.JMSSecurityException
|
import javax.jms.JMSSecurityException
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,7 +8,6 @@ import net.corda.common.configuration.parsing.internal.Configuration
|
|||||||
import net.corda.common.validation.internal.Validated
|
import net.corda.common.validation.internal.Validated
|
||||||
import net.corda.common.validation.internal.Validated.Companion.invalid
|
import net.corda.common.validation.internal.Validated.Companion.invalid
|
||||||
import net.corda.common.validation.internal.Validated.Companion.valid
|
import net.corda.common.validation.internal.Validated.Companion.valid
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.node.services.config.ConfigHelper
|
import net.corda.node.services.config.ConfigHelper
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
@ -18,6 +17,7 @@ import net.corda.nodeapi.internal.config.UnknownConfigKeysPolicy
|
|||||||
import picocli.CommandLine.Option
|
import picocli.CommandLine.Option
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
open class SharedNodeCmdLineOptions {
|
open class SharedNodeCmdLineOptions {
|
||||||
private companion object {
|
private companion object {
|
||||||
@ -34,7 +34,7 @@ open class SharedNodeCmdLineOptions {
|
|||||||
description = ["The path to the config file. By default this is node.conf in the base directory."]
|
description = ["The path to the config file. By default this is node.conf in the base directory."]
|
||||||
)
|
)
|
||||||
private var _configFile: Path? = null
|
private var _configFile: Path? = null
|
||||||
val configFile: Path get() = if (_configFile != null) baseDirectory.resolve(_configFile) else (baseDirectory / "node.conf")
|
val configFile: Path get() = _configFile?.let(baseDirectory::resolve) ?: (baseDirectory / "node.conf")
|
||||||
|
|
||||||
@Option(
|
@Option(
|
||||||
names = ["--on-unknown-config-keys"],
|
names = ["--on-unknown-config-keys"],
|
||||||
|
@ -39,7 +39,6 @@ import net.corda.core.internal.concurrent.flatMap
|
|||||||
import net.corda.core.internal.concurrent.map
|
import net.corda.core.internal.concurrent.map
|
||||||
import net.corda.core.internal.concurrent.openFuture
|
import net.corda.core.internal.concurrent.openFuture
|
||||||
import net.corda.core.internal.cordapp.CordappProviderInternal
|
import net.corda.core.internal.cordapp.CordappProviderInternal
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.messaging.AttachmentTrustInfoRPCOps
|
import net.corda.core.internal.messaging.AttachmentTrustInfoRPCOps
|
||||||
import net.corda.core.internal.notary.NotaryService
|
import net.corda.core.internal.notary.NotaryService
|
||||||
import net.corda.core.internal.rootMessage
|
import net.corda.core.internal.rootMessage
|
||||||
@ -187,6 +186,7 @@ import java.util.concurrent.TimeUnit.SECONDS
|
|||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import javax.persistence.EntityManager
|
import javax.persistence.EntityManager
|
||||||
import javax.sql.DataSource
|
import javax.sql.DataSource
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base node implementation that can be customised either for production (with real implementations that do real
|
* A base node implementation that can be customised either for production (with real implementations that do real
|
||||||
@ -338,7 +338,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
* Completes once the node has successfully registered with the network map service
|
* Completes once the node has successfully registered with the network map service
|
||||||
* or has loaded network map data from local database.
|
* or has loaded network map data from local database.
|
||||||
*/
|
*/
|
||||||
val nodeReadyFuture: CordaFuture<Unit> get() = networkMapCache.nodeReady.map { Unit }
|
val nodeReadyFuture: CordaFuture<*> get() = networkMapCache.nodeReady
|
||||||
|
|
||||||
open val serializationWhitelists: List<SerializationWhitelist> by lazy {
|
open val serializationWhitelists: List<SerializationWhitelist> by lazy {
|
||||||
cordappLoader.cordapps.flatMap { it.serializationWhitelists }
|
cordappLoader.cordapps.flatMap { it.serializationWhitelists }
|
||||||
|
@ -2,9 +2,6 @@ package net.corda.node.internal
|
|||||||
|
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.internal.copyTo
|
import net.corda.core.internal.copyTo
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.moveTo
|
|
||||||
import net.corda.core.internal.readObject
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
@ -15,8 +12,10 @@ import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME
|
|||||||
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
||||||
import net.corda.nodeapi.internal.network.verifiedNetworkParametersCert
|
import net.corda.nodeapi.internal.network.verifiedNetworkParametersCert
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardCopyOption
|
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.moveTo
|
||||||
|
|
||||||
class NetworkParametersReader(private val trustRoots: Set<X509Certificate>,
|
class NetworkParametersReader(private val trustRoots: Set<X509Certificate>,
|
||||||
private val networkMapClient: NetworkMapClient?,
|
private val networkMapClient: NetworkMapClient?,
|
||||||
@ -80,7 +79,7 @@ class NetworkParametersReader(private val trustRoots: Set<X509Certificate>,
|
|||||||
if (signedUpdatedParameters.raw.hash != advertisedParametersHash) {
|
if (signedUpdatedParameters.raw.hash != advertisedParametersHash) {
|
||||||
throw Error.OldParamsAndUpdate()
|
throw Error.OldParamsAndUpdate()
|
||||||
}
|
}
|
||||||
parametersUpdateFile.moveTo(networkParamsFile, StandardCopyOption.REPLACE_EXISTING)
|
parametersUpdateFile.moveTo(networkParamsFile, overwrite = true)
|
||||||
logger.info("Scheduled update to network parameters has occurred - node now updated to these new parameters.")
|
logger.info("Scheduled update to network parameters has occurred - node now updated to these new parameters.")
|
||||||
return signedUpdatedParameters
|
return signedUpdatedParameters
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ import net.corda.core.identity.PartyAndCertificate
|
|||||||
import net.corda.core.internal.Emoji
|
import net.corda.core.internal.Emoji
|
||||||
import net.corda.core.internal.concurrent.openFuture
|
import net.corda.core.internal.concurrent.openFuture
|
||||||
import net.corda.core.internal.concurrent.thenMatch
|
import net.corda.core.internal.concurrent.thenMatch
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.errors.AddressBindingException
|
import net.corda.core.internal.errors.AddressBindingException
|
||||||
import net.corda.core.internal.getJavaUpdateVersion
|
import net.corda.core.internal.getJavaUpdateVersion
|
||||||
import net.corda.core.internal.notary.NotaryService
|
import net.corda.core.internal.notary.NotaryService
|
||||||
@ -99,6 +98,7 @@ import java.time.Clock
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import javax.management.ObjectName
|
import javax.management.ObjectName
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class NodeWithInfo(val node: Node, val info: NodeInfo) {
|
class NodeWithInfo(val node: Node, val info: NodeInfo) {
|
||||||
|
@ -17,13 +17,8 @@ import net.corda.core.internal.HashAgility
|
|||||||
import net.corda.core.internal.PLATFORM_VERSION
|
import net.corda.core.internal.PLATFORM_VERSION
|
||||||
import net.corda.core.internal.concurrent.thenMatch
|
import net.corda.core.internal.concurrent.thenMatch
|
||||||
import net.corda.core.internal.cordapp.CordappImpl
|
import net.corda.core.internal.cordapp.CordappImpl
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.errors.AddressBindingException
|
import net.corda.core.internal.errors.AddressBindingException
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.isDirectory
|
|
||||||
import net.corda.core.internal.location
|
import net.corda.core.internal.location
|
||||||
import net.corda.core.internal.randomOrNull
|
|
||||||
import net.corda.core.internal.safeSymbolicRead
|
import net.corda.core.internal.safeSymbolicRead
|
||||||
import net.corda.core.utilities.Try
|
import net.corda.core.utilities.Try
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
@ -64,6 +59,10 @@ import java.nio.file.Path
|
|||||||
import java.time.DayOfWeek
|
import java.time.DayOfWeek
|
||||||
import java.time.ZonedDateTime
|
import java.time.ZonedDateTime
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.isDirectory
|
||||||
|
|
||||||
/** An interface that can be implemented to tell the node what to do once it's intitiated. */
|
/** An interface that can be implemented to tell the node what to do once it's intitiated. */
|
||||||
interface RunAfterNodeInitialisation {
|
interface RunAfterNodeInitialisation {
|
||||||
|
@ -2,12 +2,12 @@ package net.corda.node.internal.cordapp
|
|||||||
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.noneOrSingle
|
import net.corda.core.internal.noneOrSingle
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
class CordappConfigFileProvider(cordappDirectories: List<Path>) : CordappConfigProvider {
|
class CordappConfigFileProvider(cordappDirectories: List<Path>) : CordappConfigProvider {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -21,10 +21,8 @@ import net.corda.core.internal.PlatformVersionSwitches
|
|||||||
import net.corda.core.internal.cordapp.CordappImpl
|
import net.corda.core.internal.cordapp.CordappImpl
|
||||||
import net.corda.core.internal.cordapp.CordappImpl.Companion.UNKNOWN_INFO
|
import net.corda.core.internal.cordapp.CordappImpl.Companion.UNKNOWN_INFO
|
||||||
import net.corda.core.internal.cordapp.get
|
import net.corda.core.internal.cordapp.get
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.hash
|
import net.corda.core.internal.hash
|
||||||
import net.corda.core.internal.isAbstractClass
|
import net.corda.core.internal.isAbstractClass
|
||||||
import net.corda.core.internal.list
|
|
||||||
import net.corda.core.internal.loadClassOfType
|
import net.corda.core.internal.loadClassOfType
|
||||||
import net.corda.core.internal.location
|
import net.corda.core.internal.location
|
||||||
import net.corda.core.internal.notary.NotaryService
|
import net.corda.core.internal.notary.NotaryService
|
||||||
@ -57,6 +55,8 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
import java.util.jar.JarInputStream
|
import java.util.jar.JarInputStream
|
||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,10 +116,7 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
|
|||||||
return if (!directory.exists()) {
|
return if (!directory.exists()) {
|
||||||
emptyList()
|
emptyList()
|
||||||
} else {
|
} else {
|
||||||
directory.list { paths ->
|
directory.useDirectoryEntries("*.jar") { jars -> jars.map { it.toUri().toURL() }.toList() }
|
||||||
// `toFile()` can't be used here...
|
|
||||||
paths.filter { it.toString().endsWith(".jar") }.map { it.toUri().toURL() }.toList()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package net.corda.node.internal.subcommands
|
package net.corda.node.internal.subcommands
|
||||||
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.node.internal.Node
|
import net.corda.node.internal.Node
|
||||||
import net.corda.node.internal.NodeCliCommand
|
import net.corda.node.internal.NodeCliCommand
|
||||||
import net.corda.node.internal.NodeStartup
|
import net.corda.node.internal.NodeStartup
|
||||||
@ -11,6 +9,8 @@ import net.corda.node.utilities.createKeyPairAndSelfSignedTLSCertificate
|
|||||||
import net.corda.node.utilities.saveToKeyStore
|
import net.corda.node.utilities.saveToKeyStore
|
||||||
import net.corda.node.utilities.saveToTrustStore
|
import net.corda.node.utilities.saveToTrustStore
|
||||||
import java.io.Console
|
import java.io.Console
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class GenerateRpcSslCertsCli(startup: NodeStartup): NodeCliCommand("generate-rpc-ssl-settings", "Generate the SSL key and trust stores for a secure RPC connection.", startup) {
|
class GenerateRpcSslCertsCli(startup: NodeStartup): NodeCliCommand("generate-rpc-ssl-settings", "Generate the SSL key and trust stores for a secure RPC connection.", startup) {
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package net.corda.node.internal.subcommands
|
package net.corda.node.internal.subcommands
|
||||||
|
|
||||||
import net.corda.cliutils.CliWrapperBase
|
import net.corda.cliutils.CliWrapperBase
|
||||||
import net.corda.core.internal.createFile
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.node.InitialRegistrationCmdLineOptions
|
import net.corda.node.InitialRegistrationCmdLineOptions
|
||||||
import net.corda.node.NodeRegistrationOption
|
import net.corda.node.NodeRegistrationOption
|
||||||
import net.corda.node.internal.*
|
import net.corda.node.internal.Node
|
||||||
|
import net.corda.node.internal.NodeStartup
|
||||||
|
import net.corda.node.internal.NodeStartupLogging
|
||||||
import net.corda.node.internal.NodeStartupLogging.Companion.logger
|
import net.corda.node.internal.NodeStartupLogging.Companion.logger
|
||||||
|
import net.corda.node.internal.RunAfterNodeInitialisation
|
||||||
|
import net.corda.node.internal.initLogging
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
|
import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
|
||||||
import net.corda.node.utilities.registration.NodeRegistrationConfiguration
|
import net.corda.node.utilities.registration.NodeRegistrationConfiguration
|
||||||
@ -17,6 +18,9 @@ import picocli.CommandLine.Option
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
import kotlin.io.path.createFile
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
class InitialRegistrationCli(val startup: NodeStartup): CliWrapperBase("initial-registration", "Start initial node registration with Corda network to obtain certificate from the permissioning server.") {
|
class InitialRegistrationCli(val startup: NodeStartup): CliWrapperBase("initial-registration", "Start initial node registration with Corda network to obtain certificate from the permissioning server.") {
|
||||||
@Option(names = ["-t", "--network-root-truststore"], description = ["Network root trust store obtained from network operator."])
|
@Option(names = ["-t", "--network-root-truststore"], description = ["Network root trust store obtained from network operator."])
|
||||||
@ -29,7 +33,8 @@ class InitialRegistrationCli(val startup: NodeStartup): CliWrapperBase("initial-
|
|||||||
var skipSchemaCreation: Boolean = false
|
var skipSchemaCreation: Boolean = false
|
||||||
|
|
||||||
override fun runProgram() : Int {
|
override fun runProgram() : Int {
|
||||||
val networkRootTrustStorePath: Path = networkRootTrustStorePathParameter ?: cmdLineOptions.baseDirectory / "certificates" / "network-root-truststore.jks"
|
val networkRootTrustStorePath: Path = networkRootTrustStorePathParameter
|
||||||
|
?: (cmdLineOptions.baseDirectory / "certificates" / "network-root-truststore.jks")
|
||||||
return startup.initialiseAndRun(cmdLineOptions, InitialRegistration(cmdLineOptions.baseDirectory, networkRootTrustStorePath, networkRootTrustStorePassword, skipSchemaCreation, startup))
|
return startup.initialiseAndRun(cmdLineOptions, InitialRegistration(cmdLineOptions.baseDirectory, networkRootTrustStorePath, networkRootTrustStorePassword, skipSchemaCreation, startup))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,6 @@ import net.corda.common.configuration.parsing.internal.Configuration
|
|||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.VisibleForTesting
|
import net.corda.core.internal.VisibleForTesting
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.node.internal.Node
|
import net.corda.node.internal.Node
|
||||||
import net.corda.node.services.config.schema.v1.V1NodeConfigurationSpec
|
import net.corda.node.services.config.schema.v1.V1NodeConfigurationSpec
|
||||||
import net.corda.nodeapi.internal.DEV_CA_KEY_STORE_PASS
|
import net.corda.nodeapi.internal.DEV_CA_KEY_STORE_PASS
|
||||||
@ -28,6 +25,9 @@ import net.corda.nodeapi.internal.storeLegalIdentity
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
fun configOf(vararg pairs: Pair<String, Any?>): Config = ConfigFactory.parseMap(mapOf(*pairs))
|
fun configOf(vararg pairs: Pair<String, Any?>): Config = ConfigFactory.parseMap(mapOf(*pairs))
|
||||||
@ -42,7 +42,7 @@ object ConfigHelper {
|
|||||||
|
|
||||||
private val log = LoggerFactory.getLogger(javaClass)
|
private val log = LoggerFactory.getLogger(javaClass)
|
||||||
|
|
||||||
val DEFAULT_CONFIG_FILENAME = "node.conf"
|
const val DEFAULT_CONFIG_FILENAME = "node.conf"
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
fun loadConfig(baseDirectory: Path,
|
fun loadConfig(baseDirectory: Path,
|
||||||
@ -74,7 +74,7 @@ object ConfigHelper {
|
|||||||
val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig))
|
val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig))
|
||||||
|
|
||||||
// Detect the underlying OS. If mac or windows non-server then we assume we're running in devMode. Unless specified otherwise.
|
// Detect the underlying OS. If mac or windows non-server then we assume we're running in devMode. Unless specified otherwise.
|
||||||
val smartDevMode = CordaSystemUtils.isOsMac() || (CordaSystemUtils.isOsWindows() && !CordaSystemUtils.getOsName().toLowerCase().contains("server"))
|
val smartDevMode = CordaSystemUtils.isOsMac() || (CordaSystemUtils.isOsWindows() && "server" !in CordaSystemUtils.getOsName().lowercase())
|
||||||
val devModeConfig = ConfigFactory.parseMap(mapOf("devMode" to smartDevMode))
|
val devModeConfig = ConfigFactory.parseMap(mapOf("devMode" to smartDevMode))
|
||||||
|
|
||||||
// Detect the number of cores
|
// Detect the number of cores
|
||||||
@ -121,7 +121,7 @@ object ConfigHelper {
|
|||||||
|
|
||||||
// Reject environment variable that are in all caps
|
// Reject environment variable that are in all caps
|
||||||
// since these cannot be properties.
|
// since these cannot be properties.
|
||||||
if (original == original.toUpperCase()){
|
if (original == original.uppercase()){
|
||||||
return@mapKeys original
|
return@mapKeys original
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package net.corda.node.services.config
|
|||||||
import com.typesafe.config.ConfigException
|
import com.typesafe.config.ConfigException
|
||||||
import net.corda.common.configuration.parsing.internal.ConfigurationWithOptions
|
import net.corda.common.configuration.parsing.internal.ConfigurationWithOptions
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
@ -22,6 +21,7 @@ import java.time.Duration
|
|||||||
import java.util.Properties
|
import java.util.Properties
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
data class NodeConfigurationImpl(
|
data class NodeConfigurationImpl(
|
||||||
/** This is not retrieved from the config file but rather from a command line argument. */
|
/** This is not retrieved from the config file but rather from a command line argument. */
|
||||||
@ -34,6 +34,7 @@ data class NodeConfigurationImpl(
|
|||||||
override val crlCheckSoftFail: Boolean,
|
override val crlCheckSoftFail: Boolean,
|
||||||
override val crlCheckArtemisServer: Boolean = Defaults.crlCheckArtemisServer,
|
override val crlCheckArtemisServer: Boolean = Defaults.crlCheckArtemisServer,
|
||||||
override val dataSourceProperties: Properties,
|
override val dataSourceProperties: Properties,
|
||||||
|
@Deprecated("Use of single compatibility zone URL is deprecated", replaceWith = ReplaceWith("networkServices.networkMapURL"))
|
||||||
override val compatibilityZoneURL: URL? = Defaults.compatibilityZoneURL,
|
override val compatibilityZoneURL: URL? = Defaults.compatibilityZoneURL,
|
||||||
override var networkServices: NetworkServicesConfig? = Defaults.networkServices,
|
override var networkServices: NetworkServicesConfig? = Defaults.networkServices,
|
||||||
override val tlsCertCrlDistPoint: URL? = Defaults.tlsCertCrlDistPoint,
|
override val tlsCertCrlDistPoint: URL? = Defaults.tlsCertCrlDistPoint,
|
||||||
@ -229,11 +230,11 @@ data class NodeConfigurationImpl(
|
|||||||
private fun validateTlsCertCrlConfig(): List<String> {
|
private fun validateTlsCertCrlConfig(): List<String> {
|
||||||
val errors = mutableListOf<String>()
|
val errors = mutableListOf<String>()
|
||||||
if (tlsCertCrlIssuer != null) {
|
if (tlsCertCrlIssuer != null) {
|
||||||
if (tlsCertCrlDistPoint == null) {
|
if (tlsCertCrlDistPoint === null) {
|
||||||
errors += "'tlsCertCrlDistPoint' is mandatory when 'tlsCertCrlIssuer' is specified"
|
errors += "'tlsCertCrlDistPoint' is mandatory when 'tlsCertCrlIssuer' is specified"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!crlCheckSoftFail && tlsCertCrlDistPoint == null) {
|
if (!crlCheckSoftFail && tlsCertCrlDistPoint === null) {
|
||||||
errors += "'tlsCertCrlDistPoint' is mandatory when 'crlCheckSoftFail' is false"
|
errors += "'tlsCertCrlDistPoint' is mandatory when 'crlCheckSoftFail' is false"
|
||||||
}
|
}
|
||||||
return errors
|
return errors
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package net.corda.node.services.config.shell
|
package net.corda.node.services.config.shell
|
||||||
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.node.internal.clientSslOptionsCompatibleWith
|
import net.corda.node.internal.clientSslOptionsCompatibleWith
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
private const val COMMANDS_DIR = "shell-commands"
|
private const val COMMANDS_DIR = "shell-commands"
|
||||||
private const val CORDAPPS_DIR = "cordapps"
|
private const val CORDAPPS_DIR = "cordapps"
|
||||||
@ -11,7 +11,7 @@ private const val SSHD_HOSTKEY_DIR = "ssh"
|
|||||||
//re-packs data to Shell specific classes
|
//re-packs data to Shell specific classes
|
||||||
fun NodeConfiguration.toShellConfigMap() = mapOf(
|
fun NodeConfiguration.toShellConfigMap() = mapOf(
|
||||||
"commandsDirectory" to this.baseDirectory / COMMANDS_DIR,
|
"commandsDirectory" to this.baseDirectory / COMMANDS_DIR,
|
||||||
"cordappsDirectory" to this.baseDirectory.toString() / CORDAPPS_DIR,
|
"cordappsDirectory" to this.baseDirectory / CORDAPPS_DIR,
|
||||||
"user" to INTERNAL_SHELL_USER,
|
"user" to INTERNAL_SHELL_USER,
|
||||||
"password" to internalShellPassword,
|
"password" to internalShellPassword,
|
||||||
"permissions" to internalShellPermissions(!this.localShellUnsafe),
|
"permissions" to internalShellPermissions(!this.localShellUnsafe),
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.corda.node.services.messaging
|
package net.corda.node.services.messaging
|
||||||
|
|
||||||
import net.corda.core.internal.ThreadBox
|
import net.corda.core.internal.ThreadBox
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.errors.AddressBindingException
|
import net.corda.core.internal.errors.AddressBindingException
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
@ -46,6 +45,7 @@ import java.lang.Long.max
|
|||||||
import javax.annotation.concurrent.ThreadSafe
|
import javax.annotation.concurrent.ThreadSafe
|
||||||
import javax.security.auth.login.AppConfigurationEntry
|
import javax.security.auth.login.AppConfigurationEntry
|
||||||
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.REQUIRED
|
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.REQUIRED
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
// TODO: Verify that nobody can connect to us and fiddle with our config over the socket due to the secman.
|
// TODO: Verify that nobody can connect to us and fiddle with our config over the socket due to the secman.
|
||||||
// TODO: Implement a discovery engine that can trigger builds of new connections when another node registers? (later)
|
// TODO: Implement a discovery engine that can trigger builds of new connections when another node registers? (later)
|
||||||
|
@ -9,15 +9,12 @@ import net.corda.core.crypto.sha256
|
|||||||
import net.corda.core.internal.NetworkParametersStorage
|
import net.corda.core.internal.NetworkParametersStorage
|
||||||
import net.corda.core.internal.VisibleForTesting
|
import net.corda.core.internal.VisibleForTesting
|
||||||
import net.corda.core.internal.copyTo
|
import net.corda.core.internal.copyTo
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.readObject
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.internal.sign
|
import net.corda.core.internal.sign
|
||||||
import net.corda.core.messaging.DataFeed
|
import net.corda.core.messaging.DataFeed
|
||||||
import net.corda.core.messaging.ParametersUpdateInfo
|
import net.corda.core.messaging.ParametersUpdateInfo
|
||||||
import net.corda.core.node.AutoAcceptable
|
import net.corda.core.node.AutoAcceptable
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.NodeInfo
|
|
||||||
import net.corda.core.node.services.KeyManagementService
|
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
|
||||||
@ -44,15 +41,15 @@ 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
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor
|
import java.util.concurrent.ScheduledThreadPoolExecutor
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
import java.util.function.Consumer
|
import kotlin.io.path.div
|
||||||
import java.util.function.Supplier
|
import kotlin.io.path.exists
|
||||||
import kotlin.reflect.KProperty1
|
import kotlin.reflect.KProperty1
|
||||||
import kotlin.reflect.full.declaredMemberProperties
|
import kotlin.reflect.full.declaredMemberProperties
|
||||||
import kotlin.reflect.full.findAnnotation
|
import kotlin.reflect.full.findAnnotation
|
||||||
@ -247,7 +244,7 @@ class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal,
|
|||||||
networkMapClient!!.getNodeInfos()
|
networkMapClient!!.getNodeInfos()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logger.warn("Error encountered when downloading node infos", e)
|
logger.warn("Error encountered when downloading node infos", e)
|
||||||
emptyList<NodeInfo>()
|
emptyList()
|
||||||
}
|
}
|
||||||
(allHashesFromNetworkMap - nodeInfos.map { it.serialize().sha256() }).forEach {
|
(allHashesFromNetworkMap - nodeInfos.map { it.serialize().sha256() }).forEach {
|
||||||
logger.warn("Error encountered when downloading node info '$it', skipping...")
|
logger.warn("Error encountered when downloading node info '$it', skipping...")
|
||||||
@ -273,7 +270,7 @@ class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal,
|
|||||||
val networkMapDownloadFutures = hashesToFetch.chunked(max(hashesToFetch.size / threadsToUseForNetworkMapDownload, 1))
|
val networkMapDownloadFutures = hashesToFetch.chunked(max(hashesToFetch.size / threadsToUseForNetworkMapDownload, 1))
|
||||||
.map { nodeInfosToGet ->
|
.map { nodeInfosToGet ->
|
||||||
//for a set of chunked hashes, get the nodeInfo for each hash
|
//for a set of chunked hashes, get the nodeInfo for each hash
|
||||||
CompletableFuture.supplyAsync(Supplier<List<NodeInfo>> {
|
CompletableFuture.supplyAsync({
|
||||||
nodeInfosToGet.mapNotNull { nodeInfo ->
|
nodeInfosToGet.mapNotNull { nodeInfo ->
|
||||||
try {
|
try {
|
||||||
networkMapClient.getNodeInfo(nodeInfo)
|
networkMapClient.getNodeInfo(nodeInfo)
|
||||||
@ -283,7 +280,7 @@ class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal,
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, executorToUseForDownloadingNodeInfos).thenAcceptAsync(Consumer { retrievedNodeInfos ->
|
}, executorToUseForDownloadingNodeInfos).thenAcceptAsync({ retrievedNodeInfos ->
|
||||||
// Add new node info to the network map cache, these could be new node info or modification of node info for existing nodes.
|
// Add new node info to the network map cache, these could be new node info or modification of node info for existing nodes.
|
||||||
networkMapCache.addOrUpdateNodes(retrievedNodeInfos)
|
networkMapCache.addOrUpdateNodes(retrievedNodeInfos)
|
||||||
}, executorToUseForInsertionIntoDB)
|
}, executorToUseForInsertionIntoDB)
|
||||||
@ -309,7 +306,7 @@ class NetworkMapUpdater(private val networkMapCache: NetworkMapCacheInternal,
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// Failure to retrieve one network map using UUID shouldn't stop the whole update.
|
// Failure to retrieve one network map using UUID shouldn't stop the whole update.
|
||||||
logger.warn("Error encountered when downloading network map with uuid '$it', skipping...", e)
|
logger.warn("Error encountered when downloading network map with uuid '$it', skipping...", e)
|
||||||
emptyList<SecureHash>()
|
emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package net.corda.node.services.network
|
package net.corda.node.services.network
|
||||||
|
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
||||||
|
import net.corda.core.internal.copyTo
|
||||||
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
@ -16,6 +18,11 @@ import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
|||||||
import java.nio.file.attribute.FileTime
|
import java.nio.file.attribute.FileTime
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.getLastModifiedTime
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
|
|
||||||
sealed class NodeInfoUpdate {
|
sealed class NodeInfoUpdate {
|
||||||
data class Add(val nodeInfo: NodeInfo) : NodeInfoUpdate()
|
data class Add(val nodeInfo: NodeInfo) : NodeInfoUpdate()
|
||||||
@ -81,7 +88,7 @@ class NodeInfoWatcher(private val nodePath: Path,
|
|||||||
private fun pollDirectory(): List<NodeInfoUpdate> {
|
private fun pollDirectory(): List<NodeInfoUpdate> {
|
||||||
logger.debug { "pollDirectory $nodeInfosDir" }
|
logger.debug { "pollDirectory $nodeInfosDir" }
|
||||||
val processedPaths = HashSet<Path>()
|
val processedPaths = HashSet<Path>()
|
||||||
val result = nodeInfosDir.list { paths ->
|
val result = nodeInfosDir.useDirectoryEntries { paths ->
|
||||||
paths
|
paths
|
||||||
.filter {
|
.filter {
|
||||||
logger.debug { "Examining $it" }
|
logger.debug { "Examining $it" }
|
||||||
@ -90,7 +97,7 @@ class NodeInfoWatcher(private val nodePath: Path,
|
|||||||
.filter { !it.toString().endsWith(".tmp") }
|
.filter { !it.toString().endsWith(".tmp") }
|
||||||
.filter { it.isRegularFile() }
|
.filter { it.isRegularFile() }
|
||||||
.filter { file ->
|
.filter { file ->
|
||||||
val lastModifiedTime = file.lastModifiedTime()
|
val lastModifiedTime = file.getLastModifiedTime()
|
||||||
val previousLastModifiedTime = nodeInfoFilesMap[file]?.lastModified
|
val previousLastModifiedTime = nodeInfoFilesMap[file]?.lastModified
|
||||||
val newOrChangedFile = previousLastModifiedTime == null || lastModifiedTime > previousLastModifiedTime
|
val newOrChangedFile = previousLastModifiedTime == null || lastModifiedTime > previousLastModifiedTime
|
||||||
processedPaths.add(file)
|
processedPaths.add(file)
|
||||||
@ -100,7 +107,7 @@ class NodeInfoWatcher(private val nodePath: Path,
|
|||||||
logger.debug { "Reading SignedNodeInfo from $file" }
|
logger.debug { "Reading SignedNodeInfo from $file" }
|
||||||
try {
|
try {
|
||||||
val nodeInfoSigned = NodeInfoAndSigned(file.readObject())
|
val nodeInfoSigned = NodeInfoAndSigned(file.readObject())
|
||||||
nodeInfoFilesMap[file] = NodeInfoFromFile(nodeInfoSigned.signed.raw.hash, file.lastModifiedTime())
|
nodeInfoFilesMap[file] = NodeInfoFromFile(nodeInfoSigned.signed.raw.hash, file.getLastModifiedTime())
|
||||||
nodeInfoSigned
|
nodeInfoSigned
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logger.warn("Unable to read SignedNodeInfo from $file", e)
|
logger.warn("Unable to read SignedNodeInfo from $file", e)
|
||||||
|
@ -37,10 +37,7 @@ import net.corda.core.internal.FlowAsyncOperation
|
|||||||
import net.corda.core.internal.FlowIORequest
|
import net.corda.core.internal.FlowIORequest
|
||||||
import net.corda.core.internal.WaitForStateConsumption
|
import net.corda.core.internal.WaitForStateConsumption
|
||||||
import net.corda.core.internal.declaredField
|
import net.corda.core.internal.declaredField
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.objectOrNewInstance
|
import net.corda.core.internal.objectOrNewInstance
|
||||||
import net.corda.core.internal.outputStream
|
|
||||||
import net.corda.core.internal.uncheckedCast
|
import net.corda.core.internal.uncheckedCast
|
||||||
import net.corda.core.node.AppServiceHub.Companion.SERVICE_PRIORITY_NORMAL
|
import net.corda.core.node.AppServiceHub.Companion.SERVICE_PRIORITY_NORMAL
|
||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
@ -80,12 +77,16 @@ import java.time.Duration
|
|||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.ZoneOffset.UTC
|
import java.time.ZoneOffset.UTC
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import java.util.zip.CRC32
|
import java.util.zip.CRC32
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.outputStream
|
||||||
import kotlin.reflect.KProperty1
|
import kotlin.reflect.KProperty1
|
||||||
import kotlin.reflect.full.companionObject
|
import kotlin.reflect.full.companionObject
|
||||||
import kotlin.reflect.full.memberProperties
|
import kotlin.reflect.full.memberProperties
|
||||||
@ -270,9 +271,9 @@ class CheckpointDumperImpl(private val checkpointStorage: CheckpointStorage, pri
|
|||||||
if(flowState is FlowState.Started) writeFiber2Zip(zip, checkpointSerializationContext, runId, flowState)
|
if(flowState is FlowState.Started) writeFiber2Zip(zip, checkpointSerializationContext, runId, flowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
val jarFilter = { directoryEntry : Path -> directoryEntry.fileName.toString().endsWith(".jar") }
|
val jarFilter = { directoryEntry : Path -> directoryEntry.name.endsWith(".jar") }
|
||||||
//Dump cordApps jar in the "cordapp" folder
|
//Dump cordApps jar in the "cordapp" folder
|
||||||
for(cordappDirectory in cordappDirectories) {
|
for (cordappDirectory in cordappDirectories) {
|
||||||
val corDappJars = Files.list(cordappDirectory).filter(jarFilter).asSequence()
|
val corDappJars = Files.list(cordappDirectory).filter(jarFilter).asSequence()
|
||||||
corDappJars.forEach { corDappJar ->
|
corDappJars.forEach { corDappJar ->
|
||||||
//Jar files are already compressed, so they are stored in the zip as they are
|
//Jar files are already compressed, so they are stored in the zip as they are
|
||||||
@ -318,7 +319,7 @@ class CheckpointDumperImpl(private val checkpointStorage: CheckpointStorage, pri
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note that this method dynamically uses [net.corda.tools.CheckpointAgent.running], make sure to keep it up to date with
|
* Note that this method dynamically uses `net.corda.tools.CheckpointAgent.running`, make sure to keep it up to date with
|
||||||
* the checkpoint agent source code
|
* the checkpoint agent source code
|
||||||
*/
|
*/
|
||||||
private fun checkpointAgentRunning() = try {
|
private fun checkpointAgentRunning() = try {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package net.corda.node.services.rpc
|
package net.corda.node.services.rpc
|
||||||
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.node.internal.artemis.BrokerJaasLoginModule
|
import net.corda.node.internal.artemis.BrokerJaasLoginModule
|
||||||
import net.corda.node.internal.artemis.SecureArtemisConfiguration
|
import net.corda.node.internal.artemis.SecureArtemisConfiguration
|
||||||
@ -18,6 +17,7 @@ import org.apache.activemq.artemis.core.security.Role
|
|||||||
import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy
|
import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy
|
||||||
import org.apache.activemq.artemis.core.settings.impl.AddressSettings
|
import org.apache.activemq.artemis.core.settings.impl.AddressSettings
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
internal class RpcBrokerConfiguration(baseDirectory: Path, maxMessageSize: Int, journalBufferTimeout: Int?, jmxEnabled: Boolean,
|
internal class RpcBrokerConfiguration(baseDirectory: Path, maxMessageSize: Int, journalBufferTimeout: Int?, jmxEnabled: Boolean,
|
||||||
address: NetworkHostAndPort, adminAddress: NetworkHostAndPort?, sslOptions: BrokerRpcSslOptions?,
|
address: NetworkHostAndPort, adminAddress: NetworkHostAndPort?, sslOptions: BrokerRpcSslOptions?,
|
||||||
|
@ -31,7 +31,6 @@ import net.corda.core.internal.IdempotentFlow
|
|||||||
import net.corda.core.internal.VisibleForTesting
|
import net.corda.core.internal.VisibleForTesting
|
||||||
import net.corda.core.internal.concurrent.OpenFuture
|
import net.corda.core.internal.concurrent.OpenFuture
|
||||||
import net.corda.core.internal.isIdempotentFlow
|
import net.corda.core.internal.isIdempotentFlow
|
||||||
import net.corda.core.internal.isRegularFile
|
|
||||||
import net.corda.core.internal.location
|
import net.corda.core.internal.location
|
||||||
import net.corda.core.internal.toPath
|
import net.corda.core.internal.toPath
|
||||||
import net.corda.core.internal.uncheckedCast
|
import net.corda.core.internal.uncheckedCast
|
||||||
@ -65,6 +64,7 @@ import org.slf4j.Logger
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.slf4j.MDC
|
import org.slf4j.MDC
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
|
||||||
class FlowPermissionException(message: String) : FlowException(message)
|
class FlowPermissionException(message: String) : FlowException(message)
|
||||||
|
|
||||||
|
@ -3,7 +3,10 @@ package net.corda.node.utilities.registration
|
|||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.internal.AliasPrivateKey
|
import net.corda.core.crypto.internal.AliasPrivateKey
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.CertRole
|
||||||
|
import net.corda.core.internal.isEquivalentTo
|
||||||
|
import net.corda.core.internal.safeSymbolicRead
|
||||||
|
import net.corda.core.internal.toX500Name
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.node.NodeRegistrationOption
|
import net.corda.node.NodeRegistrationOption
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
@ -26,7 +29,6 @@ import org.bouncycastle.operator.ContentSigner
|
|||||||
import org.bouncycastle.util.io.pem.PemObject
|
import org.bouncycastle.util.io.pem.PemObject
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
import java.lang.IllegalStateException
|
|
||||||
import java.net.ConnectException
|
import java.net.ConnectException
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -35,6 +37,12 @@ import java.security.cert.X509Certificate
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import javax.naming.ServiceUnavailableException
|
import javax.naming.ServiceUnavailableException
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.useLines
|
||||||
|
import kotlin.io.path.writeLines
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper for managing the node registration process, which checks for any existing certificates and requests them if
|
* Helper for managing the node registration process, which checks for any existing certificates and requests them if
|
||||||
@ -330,7 +338,7 @@ open class NetworkRegistrationHelper(
|
|||||||
logProgress("Successfully submitted request to Corda certificate signing server, request ID: $requestId.")
|
logProgress("Successfully submitted request to Corda certificate signing server, request ID: $requestId.")
|
||||||
requestId
|
requestId
|
||||||
} else {
|
} else {
|
||||||
val requestId = requestIdStore.readLines { it.findFirst().get() }
|
val requestId = requestIdStore.useLines { it.first() }
|
||||||
logProgress("Resuming from previous certificate signing request, request ID: $requestId.")
|
logProgress("Resuming from previous certificate signing request, request ID: $requestId.")
|
||||||
requestId
|
requestId
|
||||||
}
|
}
|
||||||
@ -380,7 +388,7 @@ class NodeRegistrationConfiguration(
|
|||||||
require(it.serviceLegalName != config.myLegalName) {
|
require(it.serviceLegalName != config.myLegalName) {
|
||||||
"The notary service legal name must be different from the node legal name"
|
"The notary service legal name must be different from the node legal name"
|
||||||
}
|
}
|
||||||
NotaryServiceConfig(X509Utilities.DISTRIBUTED_NOTARY_KEY_ALIAS, it.serviceLegalName!!)
|
NotaryServiceConfig(X509Utilities.DISTRIBUTED_NOTARY_KEY_ALIAS, it.serviceLegalName)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -511,7 +519,7 @@ private class FixedPeriodLimitedRetrialStrategy(times: Int, private val period:
|
|||||||
|
|
||||||
private var counter = times
|
private var counter = times
|
||||||
|
|
||||||
override fun invoke(@Suppress("UNUSED_PARAMETER") previousPeriod: Duration?): Duration? {
|
override fun invoke(previousPeriod: Duration?): Duration? {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
return if (counter-- > 0) period else null
|
return if (counter-- > 0) period else null
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package net.corda.node.verification
|
|||||||
import net.corda.core.contracts.Attachment
|
import net.corda.core.contracts.Attachment
|
||||||
import net.corda.core.internal.AbstractAttachment
|
import net.corda.core.internal.AbstractAttachment
|
||||||
import net.corda.core.internal.copyTo
|
import net.corda.core.internal.copyTo
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.mapToSet
|
import net.corda.core.internal.mapToSet
|
||||||
import net.corda.core.internal.readFully
|
import net.corda.core.internal.readFully
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
@ -42,7 +41,9 @@ import java.net.Socket
|
|||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
||||||
|
import kotlin.io.path.Path
|
||||||
import kotlin.io.path.createDirectories
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle to the node's external verifier. The verifier process is started lazily on the first verification request.
|
* Handle to the node's external verifier. The verifier process is started lazily on the first verification request.
|
||||||
@ -180,7 +181,7 @@ class ExternalVerifierHandle(private val serviceHub: ServiceHubInternal) : AutoC
|
|||||||
init {
|
init {
|
||||||
val logsDirectory = (serviceHub.configuration.baseDirectory / "logs").createDirectories()
|
val logsDirectory = (serviceHub.configuration.baseDirectory / "logs").createDirectories()
|
||||||
val command = listOf(
|
val command = listOf(
|
||||||
"${System.getProperty("java.home") / "bin" / "java"}",
|
"${Path(System.getProperty("java.home"), "bin", "java")}",
|
||||||
"-jar",
|
"-jar",
|
||||||
"$verifierJar",
|
"$verifierJar",
|
||||||
"${server.localPort}",
|
"${server.localPort}",
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package net.corda.notary.experimental.bftsmart
|
package net.corda.notary.experimental.bftsmart
|
||||||
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.writer
|
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.debug
|
import net.corda.core.utilities.debug
|
||||||
@ -12,6 +10,8 @@ import java.net.Socket
|
|||||||
import java.net.SocketException
|
import java.net.SocketException
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.writer
|
||||||
|
|
||||||
data class BFTSmartConfig(
|
data class BFTSmartConfig(
|
||||||
/** The zero-based index of the current replica. All replicas must specify a unique replica id. */
|
/** The zero-based index of the current replica. All replicas must specify a unique replica id. */
|
||||||
@ -59,7 +59,13 @@ class BFTSmartConfigInternal(private val replicaAddresses: List<NetworkHostAndPo
|
|||||||
println("$index ${InetAddress.getByName(host).hostAddress} $port")
|
println("$index ${InetAddress.getByName(host).hostAddress} $port")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val systemConfig = String.format(javaClass.getResource("system.config.printf").readText(), n, maxFaultyReplicas(n), if (debug) 1 else 0, (0 until n).joinToString(","))
|
val systemConfig = String.format(
|
||||||
|
javaClass.getResource("system.config.printf")!!.readText(),
|
||||||
|
n,
|
||||||
|
maxFaultyReplicas(n),
|
||||||
|
if (debug) 1 else 0,
|
||||||
|
(0 until n).joinToString(",")
|
||||||
|
)
|
||||||
configWriter("system.config") {
|
configWriter("system.config") {
|
||||||
print(systemConfig)
|
print(systemConfig)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import net.corda.core.identity.CordaX500Name
|
|||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.concurrent.OpenFuture
|
import net.corda.core.internal.concurrent.OpenFuture
|
||||||
import net.corda.core.internal.concurrent.openFuture
|
import net.corda.core.internal.concurrent.openFuture
|
||||||
import net.corda.notary.common.BatchSigningFunction
|
import net.corda.core.internal.mapToSet
|
||||||
import net.corda.core.internal.notary.NotaryInternalException
|
import net.corda.core.internal.notary.NotaryInternalException
|
||||||
import net.corda.core.internal.notary.UniquenessProvider
|
import net.corda.core.internal.notary.UniquenessProvider
|
||||||
import net.corda.core.internal.notary.isConsumedByTheSameTx
|
import net.corda.core.internal.notary.isConsumedByTheSameTx
|
||||||
@ -27,13 +27,15 @@ import net.corda.core.utilities.debug
|
|||||||
import net.corda.node.services.vault.toStateRef
|
import net.corda.node.services.vault.toStateRef
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
||||||
|
import net.corda.notary.common.BatchSigningFunction
|
||||||
import net.corda.notary.common.InternalResult
|
import net.corda.notary.common.InternalResult
|
||||||
import net.corda.serialization.internal.CordaSerializationEncoding
|
import net.corda.serialization.internal.CordaSerializationEncoding
|
||||||
import org.hibernate.Session
|
import org.hibernate.Session
|
||||||
import java.sql.SQLException
|
import java.sql.SQLException
|
||||||
import java.time.Clock
|
import java.time.Clock
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.*
|
import java.util.LinkedList
|
||||||
|
import java.util.UUID
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.annotation.concurrent.ThreadSafe
|
import javax.annotation.concurrent.ThreadSafe
|
||||||
@ -200,7 +202,7 @@ class JPAUniquenessProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findAlreadyCommitted(session: Session, states: List<StateRef>, references: List<StateRef>): Map<StateRef, StateConsumptionDetails> {
|
private fun findAlreadyCommitted(session: Session, states: List<StateRef>, references: List<StateRef>): Map<StateRef, StateConsumptionDetails> {
|
||||||
val persistentStateRefs = (states + references).map { encodeStateRef(it) }.toSet()
|
val persistentStateRefs = (states + references).mapToSet(::encodeStateRef)
|
||||||
val committedStates = mutableListOf<CommittedState>()
|
val committedStates = mutableListOf<CommittedState>()
|
||||||
|
|
||||||
for (idsBatch in persistentStateRefs.chunked(config.maxInputStates)) {
|
for (idsBatch in persistentStateRefs.chunked(config.maxInputStates)) {
|
||||||
|
@ -5,7 +5,6 @@ import org.mockito.kotlin.whenever
|
|||||||
import net.corda.core.crypto.CompositeKey
|
import net.corda.core.crypto.CompositeKey
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.coretesting.internal.rigorousMock
|
import net.corda.coretesting.internal.rigorousMock
|
||||||
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
@ -36,6 +35,7 @@ import org.junit.Test
|
|||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
|
import kotlin.io.path.div
|
||||||
|
|
||||||
@Ignore("TODO JDK17: Fixme")
|
@Ignore("TODO JDK17: Fixme")
|
||||||
class KeyStoreHandlerTest {
|
class KeyStoreHandlerTest {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package net.corda.node.internal
|
package net.corda.node.internal
|
||||||
|
|
||||||
import net.corda.cliutils.CommonCliConstants
|
import net.corda.cliutils.CommonCliConstants
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.nodeapi.internal.config.UnknownConfigKeysPolicy
|
import net.corda.nodeapi.internal.config.UnknownConfigKeysPolicy
|
||||||
import org.assertj.core.api.Assertions
|
import org.assertj.core.api.Assertions
|
||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
@ -14,6 +12,8 @@ import picocli.CommandLine
|
|||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
package net.corda.node.internal
|
package net.corda.node.internal
|
||||||
|
|
||||||
import org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.mock
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.delete
|
|
||||||
import net.corda.core.internal.getJavaUpdateVersion
|
import net.corda.core.internal.getJavaUpdateVersion
|
||||||
import net.corda.core.internal.list
|
|
||||||
import net.corda.core.internal.readObject
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
|
import net.corda.coretesting.internal.createNodeInfoAndSigned
|
||||||
|
import net.corda.coretesting.internal.rigorousMock
|
||||||
import net.corda.node.VersionInfo
|
import net.corda.node.VersionInfo
|
||||||
import net.corda.node.internal.schemas.NodeInfoSchemaV1
|
import net.corda.node.internal.schemas.NodeInfoSchemaV1
|
||||||
import net.corda.node.services.config.*
|
import net.corda.node.services.config.FlowOverrideConfig
|
||||||
|
import net.corda.node.services.config.FlowTimeoutConfiguration
|
||||||
|
import net.corda.node.services.config.NodeConfigurationImpl
|
||||||
|
import net.corda.node.services.config.NodeRpcSettings
|
||||||
|
import net.corda.node.services.config.TelemetryConfiguration
|
||||||
|
import net.corda.node.services.config.VerifierType
|
||||||
import net.corda.nodeapi.internal.SignedNodeInfo
|
import net.corda.nodeapi.internal.SignedNodeInfo
|
||||||
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier.Companion.NODE_INFO_FILE_NAME_PREFIX
|
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier.Companion.NODE_INFO_FILE_NAME_PREFIX
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
@ -21,22 +23,23 @@ 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.internal.configureDatabase
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.coretesting.internal.createNodeInfoAndSigned
|
|
||||||
import net.corda.coretesting.internal.rigorousMock
|
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import org.apache.commons.lang3.JavaVersion
|
|
||||||
import org.apache.commons.lang3.SystemUtils
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
import kotlin.io.path.deleteExisting
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class NodeTest {
|
class NodeTest {
|
||||||
@Rule
|
@Rule
|
||||||
@ -47,8 +50,8 @@ class NodeTest {
|
|||||||
val testSerialization = SerializationEnvironmentRule()
|
val testSerialization = SerializationEnvironmentRule()
|
||||||
|
|
||||||
private fun nodeInfoFile(): Path? {
|
private fun nodeInfoFile(): Path? {
|
||||||
return temporaryFolder.root.toPath().list { paths ->
|
return temporaryFolder.root.toPath().useDirectoryEntries { paths ->
|
||||||
paths.filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) }.findAny().orElse(null)
|
paths.find { it.name.startsWith(NODE_INFO_FILE_NAME_PREFIX) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +62,7 @@ class NodeTest {
|
|||||||
try {
|
try {
|
||||||
return path.readObject<SignedNodeInfo>().verified()
|
return path.readObject<SignedNodeInfo>().verified()
|
||||||
} finally {
|
} finally {
|
||||||
path.delete()
|
path.deleteExisting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +94,7 @@ class NodeTest {
|
|||||||
val persistentNodeInfo = NodeInfoSchemaV1.PersistentNodeInfo(
|
val persistentNodeInfo = NodeInfoSchemaV1.PersistentNodeInfo(
|
||||||
id = 0,
|
id = 0,
|
||||||
hash = nodeInfo.serialize().hash.toString(),
|
hash = nodeInfo.serialize().hash.toString(),
|
||||||
addresses = nodeInfo.addresses.map { NodeInfoSchemaV1.DBHostAndPort.fromHostAndPort(it) },
|
addresses = nodeInfo.addresses.map(NodeInfoSchemaV1.DBHostAndPort::fromHostAndPort),
|
||||||
legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem ->
|
legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem ->
|
||||||
NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0)
|
NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0)
|
||||||
},
|
},
|
||||||
@ -157,12 +160,6 @@ class NodeTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// JDK 11 check
|
|
||||||
@Test(timeout=300_000)
|
|
||||||
fun `test getJavaRuntimeVersion`() {
|
|
||||||
assertTrue(SystemUtils.IS_JAVA_1_8 || SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_11))
|
|
||||||
}
|
|
||||||
|
|
||||||
// JDK11: revisit (JDK 9+ uses different numbering scheme: see https://docs.oracle.com/javase/9/docs/api/java/lang/Runtime.Version.html)
|
// JDK11: revisit (JDK 9+ uses different numbering scheme: see https://docs.oracle.com/javase/9/docs/api/java/lang/Runtime.Version.html)
|
||||||
@Ignore
|
@Ignore
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
|
@ -4,12 +4,12 @@ import com.typesafe.config.Config
|
|||||||
import com.typesafe.config.ConfigException
|
import com.typesafe.config.ConfigException
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import com.typesafe.config.ConfigRenderOptions
|
import com.typesafe.config.ConfigRenderOptions
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.writeText
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
class CordappConfigFileProviderTests {
|
class CordappConfigFileProviderTests {
|
||||||
private companion object {
|
private companion object {
|
||||||
|
@ -10,12 +10,13 @@ import net.corda.testing.core.internal.SelfCleaningDir
|
|||||||
import net.corda.testing.internal.MockCordappConfigProvider
|
import net.corda.testing.internal.MockCordappConfigProvider
|
||||||
import net.corda.testing.services.MockAttachmentStorage
|
import net.corda.testing.services.MockAttachmentStorage
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertNotNull
|
||||||
|
import org.junit.Assert.assertNull
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.lang.IllegalStateException
|
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.util.Arrays.asList
|
import java.util.Arrays.asList
|
||||||
@ -198,7 +199,7 @@ class CordappProviderImplTests {
|
|||||||
SelfCleaningDir().use { file ->
|
SelfCleaningDir().use { file ->
|
||||||
val jarAndSigner = ContractJarTestUtils.makeTestSignedContractJar(file.path, "com.example.MyContract")
|
val jarAndSigner = ContractJarTestUtils.makeTestSignedContractJar(file.path, "com.example.MyContract")
|
||||||
val signedJarPath = jarAndSigner.first
|
val signedJarPath = jarAndSigner.first
|
||||||
val duplicateJarPath = signedJarPath.parent.resolve("duplicate-" + signedJarPath.fileName)
|
val duplicateJarPath = signedJarPath.parent.resolve("duplicate-${signedJarPath.fileName}")
|
||||||
|
|
||||||
Files.copy(signedJarPath, duplicateJarPath)
|
Files.copy(signedJarPath, duplicateJarPath)
|
||||||
val urls = asList(signedJarPath.toUri().toURL(), duplicateJarPath.toUri().toURL())
|
val urls = asList(signedJarPath.toUri().toURL(), duplicateJarPath.toUri().toURL())
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package net.corda.node.services.attachments
|
package net.corda.node.services.attachments
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry
|
import com.codahale.metrics.MetricRegistry
|
||||||
import org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.sha256
|
import net.corda.core.internal.AttachmentTrustCalculator
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.AttachmentTrustInfo
|
||||||
|
import net.corda.core.internal.hash
|
||||||
|
import net.corda.core.internal.read
|
||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
|
import net.corda.coretesting.internal.rigorousMock
|
||||||
import net.corda.node.services.persistence.NodeAttachmentService
|
import net.corda.node.services.persistence.NodeAttachmentService
|
||||||
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
|
||||||
@ -17,7 +18,6 @@ import net.corda.testing.core.internal.JarSignatureTestUtils.signJar
|
|||||||
import net.corda.testing.core.internal.SelfCleaningDir
|
import net.corda.testing.core.internal.SelfCleaningDir
|
||||||
import net.corda.testing.internal.TestingNamedCacheFactory
|
import net.corda.testing.internal.TestingNamedCacheFactory
|
||||||
import net.corda.testing.internal.configureDatabase
|
import net.corda.testing.internal.configureDatabase
|
||||||
import net.corda.coretesting.internal.rigorousMock
|
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@ -25,9 +25,14 @@ import org.junit.Before
|
|||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.deleteExisting
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.outputStream
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
@ -271,8 +276,8 @@ class AttachmentTrustCalculatorTest {
|
|||||||
val jarV1 = ContractJarTestUtils.makeTestContractJar(path, "foo.bar.DummyContract")
|
val jarV1 = ContractJarTestUtils.makeTestContractJar(path, "foo.bar.DummyContract")
|
||||||
path.generateKey(alias, password)
|
path.generateKey(alias, password)
|
||||||
val key1 = path.signJar(jarV1.toAbsolutePath().toString(), alias, password)
|
val key1 = path.signJar(jarV1.toAbsolutePath().toString(), alias, password)
|
||||||
(path / "_shredder").delete()
|
(path / "_shredder").deleteExisting()
|
||||||
(path / "_teststore").delete()
|
(path / "_teststore").deleteExisting()
|
||||||
path.generateKey(alias, password)
|
path.generateKey(alias, password)
|
||||||
val jarV2 = ContractJarTestUtils.makeTestContractJar(
|
val jarV2 = ContractJarTestUtils.makeTestContractJar(
|
||||||
path,
|
path,
|
||||||
@ -624,6 +629,6 @@ class AttachmentTrustCalculatorTest {
|
|||||||
counter++
|
counter++
|
||||||
val file = Paths.get((tempFolder.root.toPath() / "$counter.jar").toString())
|
val file = Paths.get((tempFolder.root.toPath() / "$counter.jar").toString())
|
||||||
ContractJarTestUtils.makeTestJar(Files.newOutputStream(file), entries)
|
ContractJarTestUtils.makeTestJar(Files.newOutputStream(file), entries)
|
||||||
return Pair(file, file.readAll().sha256())
|
return Pair(file, file.hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ package net.corda.node.services.config
|
|||||||
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import net.corda.core.internal.delete
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.node.internal.Node
|
import net.corda.node.internal.Node
|
||||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@ -19,6 +17,8 @@ import java.lang.reflect.Field
|
|||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.deleteExisting
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
|
|
||||||
class ConfigHelperTests {
|
class ConfigHelperTests {
|
||||||
@ -31,7 +31,7 @@ class ConfigHelperTests {
|
|||||||
|
|
||||||
@After
|
@After
|
||||||
fun cleanup() {
|
fun cleanup() {
|
||||||
baseDir?.delete()
|
baseDir?.deleteExisting()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 300_000)
|
@Test(timeout = 300_000)
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package net.corda.node.services.config
|
package net.corda.node.services.config
|
||||||
|
|
||||||
import org.mockito.kotlin.mock
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import com.typesafe.config.ConfigParseOptions
|
import com.typesafe.config.ConfigParseOptions
|
||||||
import com.typesafe.config.ConfigValueFactory
|
import com.typesafe.config.ConfigValueFactory
|
||||||
import net.corda.common.configuration.parsing.internal.Configuration
|
import net.corda.common.configuration.parsing.internal.Configuration
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.toPath
|
import net.corda.core.internal.toPath
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
@ -21,11 +19,13 @@ import org.junit.Assert.assertNotNull
|
|||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ class NodeConfigurationImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getConfig(cfgName: String, overrides: Config = ConfigFactory.empty()): Config {
|
private fun getConfig(cfgName: String, overrides: Config = ConfigFactory.empty()): Config {
|
||||||
val path = this::class.java.classLoader.getResource(cfgName).toPath()
|
val path = this::class.java.classLoader.getResource(cfgName)!!.toPath()
|
||||||
return ConfigHelper.loadConfig(
|
return ConfigHelper.loadConfig(
|
||||||
baseDirectory = path.parent,
|
baseDirectory = path.parent,
|
||||||
configFile = path,
|
configFile = path,
|
||||||
@ -226,36 +226,34 @@ class NodeConfigurationImplTest {
|
|||||||
|
|
||||||
@Test(timeout=6_000)
|
@Test(timeout=6_000)
|
||||||
fun `relative base dir leads to correct cordapp directories`() {
|
fun `relative base dir leads to correct cordapp directories`() {
|
||||||
val path = tempFolder.root.relativeTo(tempFolder.root.parentFile).toString()
|
val path = tempFolder.root.relativeTo(tempFolder.root.parentFile).toPath()
|
||||||
val fullPath = File(".").resolve(path).toString()
|
|
||||||
// Override base directory to have predictable experience on diff OSes
|
// Override base directory to have predictable experience on diff OSes
|
||||||
val finalConfig = configOf(
|
val finalConfig = configOf(
|
||||||
// Add substitution values here
|
// Add substitution values here
|
||||||
"baseDirectory" to fullPath)
|
"baseDirectory" to path.toString())
|
||||||
.withFallback(rawConfig)
|
.withFallback(rawConfig)
|
||||||
.resolve()
|
.resolve()
|
||||||
|
|
||||||
val nodeConfiguration = finalConfig.parseAsNodeConfiguration()
|
val nodeConfiguration = finalConfig.parseAsNodeConfiguration()
|
||||||
assertTrue(nodeConfiguration.isValid)
|
assertTrue(nodeConfiguration.isValid)
|
||||||
|
|
||||||
assertEquals(listOf(fullPath / "./myCorDapps1", fullPath / "./myCorDapps2"), nodeConfiguration.value().cordappDirectories)
|
assertEquals(listOf(path / "./myCorDapps1", path / "./myCorDapps2"), nodeConfiguration.value().cordappDirectories)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=6_000)
|
@Test(timeout=6_000)
|
||||||
fun `relative base dir leads to correct default cordapp directory`() {
|
fun `relative base dir leads to correct default cordapp directory`() {
|
||||||
val path = tempFolder.root.relativeTo(tempFolder.root.parentFile).toString()
|
val path = tempFolder.root.relativeTo(tempFolder.root.parentFile).toPath()
|
||||||
val fullPath = File(".").resolve(path).toString()
|
|
||||||
// Override base directory to have predictable experience on diff OSes
|
// Override base directory to have predictable experience on diff OSes
|
||||||
val finalConfig = configOf(
|
val finalConfig = configOf(
|
||||||
// Add substitution values here
|
// Add substitution values here
|
||||||
"baseDirectory" to fullPath)
|
"baseDirectory" to path.toString())
|
||||||
.withFallback(rawConfigNoCordapps)
|
.withFallback(rawConfigNoCordapps)
|
||||||
.resolve()
|
.resolve()
|
||||||
|
|
||||||
val nodeConfiguration = finalConfig.parseAsNodeConfiguration()
|
val nodeConfiguration = finalConfig.parseAsNodeConfiguration()
|
||||||
assertTrue(nodeConfiguration.isValid)
|
assertTrue(nodeConfiguration.isValid)
|
||||||
|
|
||||||
assertEquals(listOf(fullPath / "cordapps"), nodeConfiguration.value().cordappDirectories)
|
assertEquals(listOf(path / "cordapps"), nodeConfiguration.value().cordappDirectories)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=6_000)
|
@Test(timeout=6_000)
|
||||||
|
@ -2,12 +2,6 @@ package net.corda.node.services.network
|
|||||||
|
|
||||||
import com.google.common.jimfs.Configuration.unix
|
import com.google.common.jimfs.Configuration.unix
|
||||||
import com.google.common.jimfs.Jimfs
|
import com.google.common.jimfs.Jimfs
|
||||||
import org.mockito.kotlin.any
|
|
||||||
import org.mockito.kotlin.atLeast
|
|
||||||
import org.mockito.kotlin.mock
|
|
||||||
import org.mockito.kotlin.never
|
|
||||||
import org.mockito.kotlin.times
|
|
||||||
import org.mockito.kotlin.verify
|
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.generateKeyPair
|
import net.corda.core.crypto.generateKeyPair
|
||||||
@ -19,10 +13,6 @@ import net.corda.core.internal.NODE_INFO_DIRECTORY
|
|||||||
import net.corda.core.internal.NetworkParametersStorage
|
import net.corda.core.internal.NetworkParametersStorage
|
||||||
import net.corda.core.internal.bufferUntilSubscribed
|
import net.corda.core.internal.bufferUntilSubscribed
|
||||||
import net.corda.core.internal.concurrent.openFuture
|
import net.corda.core.internal.concurrent.openFuture
|
||||||
import net.corda.core.internal.createDirectory
|
|
||||||
import net.corda.core.internal.delete
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.readObject
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.internal.sign
|
import net.corda.core.internal.sign
|
||||||
import net.corda.core.messaging.ParametersUpdateInfo
|
import net.corda.core.messaging.ParametersUpdateInfo
|
||||||
@ -62,6 +52,12 @@ import org.junit.Assert
|
|||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.mockito.kotlin.any
|
||||||
|
import org.mockito.kotlin.atLeast
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
import org.mockito.kotlin.never
|
||||||
|
import org.mockito.kotlin.times
|
||||||
|
import org.mockito.kotlin.verify
|
||||||
import rx.schedulers.TestScheduler
|
import rx.schedulers.TestScheduler
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
@ -70,9 +66,13 @@ import java.nio.file.Path
|
|||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.io.path.createDirectory
|
||||||
|
import kotlin.io.path.deleteExisting
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -300,7 +300,7 @@ class NetworkMapUpdaterTest {
|
|||||||
// Not subscribed yet
|
// Not subscribed yet
|
||||||
verify(networkMapCache, times(0)).addOrUpdateNode(any())
|
verify(networkMapCache, times(0)).addOrUpdateNode(any())
|
||||||
|
|
||||||
nodeInfoDir.delete()
|
nodeInfoDir.deleteExisting()
|
||||||
assertFalse(nodeInfoDir.exists())
|
assertFalse(nodeInfoDir.exists())
|
||||||
|
|
||||||
// Observable will get a NoSuchFileException and log it
|
// Observable will get a NoSuchFileException and log it
|
||||||
@ -516,7 +516,7 @@ class NetworkMapUpdaterTest {
|
|||||||
assertThat(networkMapCache.allNodeHashes).containsExactlyInAnyOrder(fileNodeInfoAndSigned1.signed.raw.hash, fileNodeInfoAndSigned2.signed.raw.hash)
|
assertThat(networkMapCache.allNodeHashes).containsExactlyInAnyOrder(fileNodeInfoAndSigned1.signed.raw.hash, fileNodeInfoAndSigned2.signed.raw.hash)
|
||||||
//Remove one of the nodes
|
//Remove one of the nodes
|
||||||
val fileName1 = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}${fileNodeInfoAndSigned1.nodeInfo.legalIdentities[0].name.serialize().hash}"
|
val fileName1 = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}${fileNodeInfoAndSigned1.nodeInfo.legalIdentities[0].name.serialize().hash}"
|
||||||
(nodeInfoDir / fileName1).delete()
|
(nodeInfoDir / fileName1).deleteExisting()
|
||||||
advanceTime()
|
advanceTime()
|
||||||
verify(networkMapCache, times(1)).removeNode(any())
|
verify(networkMapCache, times(1)).removeNode(any())
|
||||||
verify(networkMapCache, times(1)).removeNode(fileNodeInfoAndSigned1.nodeInfo)
|
verify(networkMapCache, times(1)).removeNode(fileNodeInfoAndSigned1.nodeInfo)
|
||||||
@ -545,7 +545,7 @@ class NetworkMapUpdaterTest {
|
|||||||
//Node from file has higher serial than the one from NetworkMapServer
|
//Node from file has higher serial than the one from NetworkMapServer
|
||||||
assertThat(networkMapCache.allNodeHashes).containsOnly(localSignedNodeInfo.signed.raw.hash)
|
assertThat(networkMapCache.allNodeHashes).containsOnly(localSignedNodeInfo.signed.raw.hash)
|
||||||
val fileName = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}${localNodeInfo.legalIdentities[0].name.serialize().hash}"
|
val fileName = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}${localNodeInfo.legalIdentities[0].name.serialize().hash}"
|
||||||
(nodeInfoDir / fileName).delete()
|
(nodeInfoDir / fileName).deleteExisting()
|
||||||
advanceTime()
|
advanceTime()
|
||||||
verify(networkMapCache, times(1)).removeNode(any())
|
verify(networkMapCache, times(1)).removeNode(any())
|
||||||
verify(networkMapCache).removeNode(localNodeInfo)
|
verify(networkMapCache).removeNode(localNodeInfo)
|
||||||
|
@ -2,23 +2,27 @@ package net.corda.node.services.network
|
|||||||
|
|
||||||
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 net.corda.core.identity.CordaX500Name
|
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.core.internal.readObject
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import net.corda.core.utilities.days
|
import net.corda.core.utilities.days
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
import net.corda.coretesting.internal.DEV_INTERMEDIATE_CA
|
import net.corda.coretesting.internal.DEV_INTERMEDIATE_CA
|
||||||
|
import net.corda.coretesting.internal.DEV_ROOT_CA
|
||||||
import net.corda.node.VersionInfo
|
import net.corda.node.VersionInfo
|
||||||
import net.corda.node.internal.NetworkParametersReader
|
import net.corda.node.internal.NetworkParametersReader
|
||||||
import net.corda.nodeapi.internal.network.*
|
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
|
||||||
import net.corda.coretesting.internal.DEV_ROOT_CA
|
|
||||||
import net.corda.nodeapi.internal.createDevNetworkMapCa
|
import net.corda.nodeapi.internal.createDevNetworkMapCa
|
||||||
import net.corda.nodeapi.internal.createDevNetworkParametersCa
|
import net.corda.nodeapi.internal.createDevNetworkParametersCa
|
||||||
import net.corda.nodeapi.internal.createDevNodeCa
|
import net.corda.nodeapi.internal.createDevNodeCa
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
||||||
|
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.NetworkParametersCopier
|
||||||
|
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
||||||
|
import net.corda.nodeapi.internal.network.verifiedNetworkParametersCert
|
||||||
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.node.internal.network.NetworkMapServer
|
import net.corda.testing.node.internal.network.NetworkMapServer
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
@ -28,6 +32,9 @@ import org.junit.Rule
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.FileSystem
|
import java.nio.file.FileSystem
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.exists
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
|
@ -4,13 +4,10 @@ import com.google.common.jimfs.Configuration
|
|||||||
import com.google.common.jimfs.Jimfs
|
import com.google.common.jimfs.Jimfs
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
import net.corda.core.internal.NODE_INFO_DIRECTORY
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.size
|
|
||||||
import net.corda.core.node.services.KeyManagementService
|
import net.corda.core.node.services.KeyManagementService
|
||||||
import net.corda.coretesting.internal.createNodeInfoAndSigned
|
import net.corda.coretesting.internal.createNodeInfoAndSigned
|
||||||
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
||||||
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier
|
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier.Companion.NODE_INFO_FILE_NAME_PREFIX
|
||||||
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.node.internal.MockKeyManagementService
|
import net.corda.testing.node.internal.MockKeyManagementService
|
||||||
@ -26,8 +23,12 @@ import java.nio.file.Files
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.fileSize
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.useDirectoryEntries
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class NodeInfoWatcherTest {
|
class NodeInfoWatcherTest {
|
||||||
@Rule
|
@Rule
|
||||||
@ -63,17 +64,20 @@ class NodeInfoWatcherTest {
|
|||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `save a NodeInfo`() {
|
fun `save a NodeInfo`() {
|
||||||
assertEquals(0,
|
assertThat(nodeInfoFiles()).isEmpty()
|
||||||
tempFolder.root.list().filter { it.startsWith(NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX) }.size)
|
|
||||||
NodeInfoWatcher.saveToFile(tempFolder.root.toPath(), nodeInfoAndSigned)
|
NodeInfoWatcher.saveToFile(tempFolder.root.toPath(), nodeInfoAndSigned)
|
||||||
|
|
||||||
val nodeInfoFiles = tempFolder.root.list().filter { it.startsWith(NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX) }
|
val nodeInfoFiles = nodeInfoFiles()
|
||||||
assertEquals(1, nodeInfoFiles.size)
|
assertThat(nodeInfoFiles).hasSize(1)
|
||||||
val fileName = nodeInfoFiles.first()
|
|
||||||
assertTrue(fileName.startsWith(NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX))
|
|
||||||
val file = (tempFolder.root.path / fileName)
|
|
||||||
// Just check that something is written, another tests verifies that the written value can be read back.
|
// Just check that something is written, another tests verifies that the written value can be read back.
|
||||||
assertThat(file.size).isGreaterThan(0)
|
assertThat(nodeInfoFiles[0].fileSize()).isGreaterThan(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun nodeInfoFiles(): List<Path> {
|
||||||
|
return tempFolder.root.toPath().useDirectoryEntries { paths ->
|
||||||
|
paths.filter { it.name.startsWith(NODE_INFO_FILE_NAME_PREFIX) }.toList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
|
@ -4,17 +4,21 @@ 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 org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
import net.corda.core.contracts.ContractAttachment
|
import net.corda.core.contracts.ContractAttachment
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.DigestService
|
import net.corda.core.crypto.DigestService
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.randomHash
|
import net.corda.core.crypto.randomHash
|
||||||
import net.corda.core.crypto.sha256
|
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.DEPLOYED_CORDAPP_UPLOADER
|
||||||
|
import net.corda.core.internal.P2P_UPLOADER
|
||||||
|
import net.corda.core.internal.RPC_UPLOADER
|
||||||
|
import net.corda.core.internal.TRUSTED_UPLOADERS
|
||||||
|
import net.corda.core.internal.UNKNOWN_UPLOADER
|
||||||
import net.corda.core.internal.cordapp.CordappImpl.Companion.DEFAULT_CORDAPP_VERSION
|
import net.corda.core.internal.cordapp.CordappImpl.Companion.DEFAULT_CORDAPP_VERSION
|
||||||
|
import net.corda.core.internal.hash
|
||||||
|
import net.corda.core.internal.read
|
||||||
|
import net.corda.core.internal.readFully
|
||||||
import net.corda.core.node.ServicesForResolution
|
import net.corda.core.node.ServicesForResolution
|
||||||
import net.corda.core.node.services.AttachmentId
|
import net.corda.core.node.services.AttachmentId
|
||||||
import net.corda.core.node.services.vault.AttachmentQueryCriteria.AttachmentsQueryCriteria
|
import net.corda.core.node.services.vault.AttachmentQueryCriteria.AttachmentsQueryCriteria
|
||||||
@ -22,6 +26,7 @@ import net.corda.core.node.services.vault.AttachmentSort
|
|||||||
import net.corda.core.node.services.vault.Builder
|
import net.corda.core.node.services.vault.Builder
|
||||||
import net.corda.core.node.services.vault.Sort
|
import net.corda.core.node.services.vault.Sort
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
|
import net.corda.coretesting.internal.rigorousMock
|
||||||
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
||||||
import net.corda.nodeapi.exceptions.DuplicateAttachmentException
|
import net.corda.nodeapi.exceptions.DuplicateAttachmentException
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
@ -36,16 +41,20 @@ import net.corda.testing.core.internal.SelfCleaningDir
|
|||||||
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
|
||||||
import net.corda.coretesting.internal.rigorousMock
|
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
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.*
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||||
|
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||||
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
@ -54,12 +63,19 @@ import java.nio.charset.StandardCharsets
|
|||||||
import java.nio.file.FileAlreadyExistsException
|
import java.nio.file.FileAlreadyExistsException
|
||||||
import java.nio.file.FileSystem
|
import java.nio.file.FileSystem
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.*
|
import java.util.Random
|
||||||
import java.util.jar.JarEntry
|
import java.util.jar.JarEntry
|
||||||
import java.util.jar.JarInputStream
|
import java.util.jar.JarInputStream
|
||||||
import java.util.jar.JarOutputStream
|
import java.util.jar.JarOutputStream
|
||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
import kotlin.test.*
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.outputStream
|
||||||
|
import kotlin.io.path.readBytes
|
||||||
|
import kotlin.io.path.writeLines
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
class NodeAttachmentServiceTest {
|
class NodeAttachmentServiceTest {
|
||||||
|
|
||||||
@ -109,7 +125,7 @@ class NodeAttachmentServiceTest {
|
|||||||
SelfCleaningDir().use { file ->
|
SelfCleaningDir().use { file ->
|
||||||
val jarAndSigner = makeTestSignedContractJar(file.path, "com.example.MyContract")
|
val jarAndSigner = makeTestSignedContractJar(file.path, "com.example.MyContract")
|
||||||
val signedJar = jarAndSigner.first
|
val signedJar = jarAndSigner.first
|
||||||
signedJar.inputStream().use { jarStream ->
|
signedJar.read { jarStream ->
|
||||||
val attachmentId = storage.importAttachment(jarStream, "test", null)
|
val attachmentId = storage.importAttachment(jarStream, "test", null)
|
||||||
assertEquals(listOf(jarAndSigner.second.hash), storage.openAttachment(attachmentId)!!.signerKeys.map { it.hash })
|
assertEquals(listOf(jarAndSigner.second.hash), storage.openAttachment(attachmentId)!!.signerKeys.map { it.hash })
|
||||||
}
|
}
|
||||||
@ -120,7 +136,7 @@ class NodeAttachmentServiceTest {
|
|||||||
fun `importing a non-signed jar will save no signers`() {
|
fun `importing a non-signed jar will save no signers`() {
|
||||||
SelfCleaningDir().use {
|
SelfCleaningDir().use {
|
||||||
val jarName = makeTestContractJar(it.path, "com.example.MyContract")
|
val jarName = makeTestContractJar(it.path, "com.example.MyContract")
|
||||||
it.path.resolve(jarName).inputStream().use { jarStream ->
|
(it.path / jarName).read { jarStream ->
|
||||||
val attachmentId = storage.importAttachment(jarStream, "test", null)
|
val attachmentId = storage.importAttachment(jarStream, "test", null)
|
||||||
assertEquals(0, storage.openAttachment(attachmentId)!!.signerKeys.size)
|
assertEquals(0, storage.openAttachment(attachmentId)!!.signerKeys.size)
|
||||||
}
|
}
|
||||||
@ -156,7 +172,7 @@ class NodeAttachmentServiceTest {
|
|||||||
SelfCleaningDir().use { file ->
|
SelfCleaningDir().use { file ->
|
||||||
val contractJarName = makeTestContractJar(file.path, "com.example.MyContract")
|
val contractJarName = makeTestContractJar(file.path, "com.example.MyContract")
|
||||||
val attachment = file.path.resolve(contractJarName)
|
val attachment = file.path.resolve(contractJarName)
|
||||||
val expectedAttachmentId = attachment.readAll().sha256()
|
val expectedAttachmentId = attachment.hash
|
||||||
|
|
||||||
val initialUploader = "test"
|
val initialUploader = "test"
|
||||||
val attachmentId = attachment.read { storage.privilegedImportAttachment(it, initialUploader, null) }
|
val attachmentId = attachment.read { storage.privilegedImportAttachment(it, initialUploader, null) }
|
||||||
@ -176,7 +192,7 @@ class NodeAttachmentServiceTest {
|
|||||||
SelfCleaningDir().use { file ->
|
SelfCleaningDir().use { file ->
|
||||||
val contractJarName = makeTestContractJar(file.path, "com.example.MyContract")
|
val contractJarName = makeTestContractJar(file.path, "com.example.MyContract")
|
||||||
val attachment = file.path.resolve(contractJarName)
|
val attachment = file.path.resolve(contractJarName)
|
||||||
val expectedAttachmentId = attachment.readAll().sha256()
|
val expectedAttachmentId = attachment.hash
|
||||||
|
|
||||||
val trustedUploader = TRUSTED_UPLOADERS.randomOrNull()!!
|
val trustedUploader = TRUSTED_UPLOADERS.randomOrNull()!!
|
||||||
val attachmentId = attachment.read { storage.privilegedImportAttachment(it, trustedUploader, null) }
|
val attachmentId = attachment.read { storage.privilegedImportAttachment(it, trustedUploader, null) }
|
||||||
@ -193,7 +209,7 @@ class NodeAttachmentServiceTest {
|
|||||||
SelfCleaningDir().use { file ->
|
SelfCleaningDir().use { file ->
|
||||||
val contractJarName = makeTestContractJar(file.path, "com.example.MyContract")
|
val contractJarName = makeTestContractJar(file.path, "com.example.MyContract")
|
||||||
val testJar = file.path.resolve(contractJarName)
|
val testJar = file.path.resolve(contractJarName)
|
||||||
val expectedHash = testJar.readAll().sha256()
|
val expectedHash = testJar.hash
|
||||||
|
|
||||||
// PRIVILEGED_UPLOADERS = listOf(DEPLOYED_CORDAPP_UPLOADER, RPC_UPLOADER, P2P_UPLOADER, UNKNOWN_UPLOADER)
|
// PRIVILEGED_UPLOADERS = listOf(DEPLOYED_CORDAPP_UPLOADER, RPC_UPLOADER, P2P_UPLOADER, UNKNOWN_UPLOADER)
|
||||||
// TRUSTED_UPLOADERS = listOf(DEPLOYED_CORDAPP_UPLOADER, RPC_UPLOADER)
|
// TRUSTED_UPLOADERS = listOf(DEPLOYED_CORDAPP_UPLOADER, RPC_UPLOADER)
|
||||||
@ -559,7 +575,7 @@ class NodeAttachmentServiceTest {
|
|||||||
val id = testJar.read { storage.importAttachment(it, "test", null) }
|
val id = testJar.read { storage.importAttachment(it, "test", null) }
|
||||||
|
|
||||||
// Corrupt the file in the store.
|
// Corrupt the file in the store.
|
||||||
val bytes = testJar.readAll()
|
val bytes = testJar.readBytes()
|
||||||
val corruptBytes = "arggghhhh".toByteArray()
|
val corruptBytes = "arggghhhh".toByteArray()
|
||||||
System.arraycopy(corruptBytes, 0, bytes, 0, corruptBytes.size)
|
System.arraycopy(corruptBytes, 0, bytes, 0, corruptBytes.size)
|
||||||
val corruptAttachment = NodeAttachmentService.DBAttachment(attId = id.toString(), content = bytes, version = DEFAULT_CORDAPP_VERSION)
|
val corruptAttachment = NodeAttachmentService.DBAttachment(attId = id.toString(), content = bytes, version = DEFAULT_CORDAPP_VERSION)
|
||||||
@ -750,16 +766,16 @@ class NodeAttachmentServiceTest {
|
|||||||
fun `The strict JAR verification function fails signed JARs with removed or extra files that are valid according to the usual jarsigner`() {
|
fun `The strict JAR verification function fails signed JARs with removed or extra files that are valid according to the usual jarsigner`() {
|
||||||
|
|
||||||
// Signed jar that has a modified file.
|
// Signed jar that has a modified file.
|
||||||
val changedFileJAR = this::class.java.getResource("/changed-file-signed-jar.jar")
|
val changedFileJAR = this::class.java.getResource("/changed-file-signed-jar.jar")!!
|
||||||
|
|
||||||
// Signed jar with removed files.
|
// Signed jar with removed files.
|
||||||
val removedFilesJAR = this::class.java.getResource("/removed-files-signed-jar.jar")
|
val removedFilesJAR = this::class.java.getResource("/removed-files-signed-jar.jar")!!
|
||||||
|
|
||||||
// Signed jar with extra files.
|
// Signed jar with extra files.
|
||||||
val extraFilesJAR = this::class.java.getResource("/extra-files-signed-jar.jar")
|
val extraFilesJAR = this::class.java.getResource("/extra-files-signed-jar.jar")!!
|
||||||
|
|
||||||
// Valid signed jar with all files.
|
// Valid signed jar with all files.
|
||||||
val legalJAR = this::class.java.getResource("/legal-signed-jar.jar")
|
val legalJAR = this::class.java.getResource("/legal-signed-jar.jar")!!
|
||||||
|
|
||||||
fun URL.standardVerifyJar() = JarInputStream(this.openStream(), true).use { jar ->
|
fun URL.standardVerifyJar() = JarInputStream(this.openStream(), true).use { jar ->
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -1059,6 +1075,6 @@ class NodeAttachmentServiceTest {
|
|||||||
counter++
|
counter++
|
||||||
val file = fs.getPath("$counter.jar")
|
val file = fs.getPath("$counter.jar")
|
||||||
makeTestJar(file.outputStream(), entries)
|
makeTestJar(file.outputStream(), entries)
|
||||||
return Pair(file, file.readAll().sha256())
|
return Pair(file, file.hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,14 @@ package net.corda.node.services.rpc
|
|||||||
|
|
||||||
import com.natpryce.hamkrest.assertion.assertThat
|
import com.natpryce.hamkrest.assertion.assertThat
|
||||||
import com.natpryce.hamkrest.containsSubstring
|
import com.natpryce.hamkrest.containsSubstring
|
||||||
import org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.mock
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
import junit.framework.TestCase.assertNull
|
import junit.framework.TestCase.assertNull
|
||||||
import net.corda.core.context.InvocationContext
|
import net.corda.core.context.InvocationContext
|
||||||
import net.corda.core.flows.FlowLogic
|
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.internal.createDirectories
|
|
||||||
import net.corda.core.internal.deleteIfExists
|
|
||||||
import net.corda.core.internal.deleteRecursively
|
import net.corda.core.internal.deleteRecursively
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.inputStream
|
|
||||||
import net.corda.core.internal.readFully
|
import net.corda.core.internal.readFully
|
||||||
import net.corda.core.node.ServiceHub
|
import net.corda.core.node.ServiceHub
|
||||||
import net.corda.core.serialization.SerializeAsToken
|
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.serialization.internal.CheckpointSerializationDefaults
|
import net.corda.core.serialization.internal.CheckpointSerializationDefaults
|
||||||
import net.corda.core.serialization.internal.checkpointSerialize
|
import net.corda.core.serialization.internal.checkpointSerialize
|
||||||
@ -40,11 +32,18 @@ import org.junit.After
|
|||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.time.Clock
|
import java.time.Clock
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
|
import kotlin.io.path.div
|
||||||
|
import kotlin.io.path.inputStream
|
||||||
|
|
||||||
class CheckpointDumperImplTest {
|
class CheckpointDumperImplTest {
|
||||||
|
|
||||||
@ -64,13 +63,13 @@ class CheckpointDumperImplTest {
|
|||||||
private lateinit var services: ServiceHub
|
private lateinit var services: ServiceHub
|
||||||
private lateinit var checkpointStorage: DBCheckpointStorage
|
private lateinit var checkpointStorage: DBCheckpointStorage
|
||||||
|
|
||||||
private val mockAfterStartEvent = {
|
private val mockAfterStartEvent = run {
|
||||||
val nodeServicesContextMock = mock<NodeServicesContext>()
|
val nodeServicesContextMock = mock<NodeServicesContext>()
|
||||||
whenever(nodeServicesContextMock.tokenizableServices).doReturn(emptyList<SerializeAsToken>())
|
whenever(nodeServicesContextMock.tokenizableServices).doReturn(emptyList())
|
||||||
val eventMock = mock<NodeLifecycleEvent.AfterNodeStart<*>>()
|
val eventMock = mock<NodeLifecycleEvent.AfterNodeStart<*>>()
|
||||||
whenever(eventMock.nodeServicesContext).doReturn(nodeServicesContextMock)
|
whenever(eventMock.nodeServicesContext).doReturn(nodeServicesContextMock)
|
||||||
eventMock
|
eventMock
|
||||||
}()
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
@ -140,7 +139,7 @@ class CheckpointDumperImplTest {
|
|||||||
|
|
||||||
private fun checkDumpFile() {
|
private fun checkDumpFile() {
|
||||||
ZipInputStream(file.inputStream()).use { zip ->
|
ZipInputStream(file.inputStream()).use { zip ->
|
||||||
val entry = zip.nextEntry
|
val entry = zip.nextEntry!!
|
||||||
assertThat(entry.name, containsSubstring("json"))
|
assertThat(entry.name, containsSubstring("json"))
|
||||||
val content = zip.readFully()
|
val content = zip.readFully()
|
||||||
assertThat(String(content), containsSubstring(organisation))
|
assertThat(String(content), containsSubstring(organisation))
|
||||||
|
@ -11,6 +11,7 @@ import net.corda.core.flows.StartableByRPC
|
|||||||
import net.corda.core.flows.UnexpectedFlowEndException
|
import net.corda.core.flows.UnexpectedFlowEndException
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.identity.PartyAndCertificate
|
import net.corda.core.identity.PartyAndCertificate
|
||||||
|
import net.corda.core.internal.mapToSet
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.unwrap
|
import net.corda.core.utilities.unwrap
|
||||||
@ -160,10 +161,10 @@ class FlowParallelMessagingTests {
|
|||||||
class SenderFlow(private val parties: Map<out Destination, MessageType>): FlowLogic<String>() {
|
class SenderFlow(private val parties: Map<out Destination, MessageType>): FlowLogic<String>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): String {
|
override fun call(): String {
|
||||||
val messagesPerSession = parties.toList().map { (party, messageType) ->
|
val messagesPerSession = parties.toList().associate { (party, messageType) ->
|
||||||
val session = initiateFlow(party)
|
val session = initiateFlow(party)
|
||||||
Pair(session, messageType)
|
Pair(session, messageType)
|
||||||
}.toMap()
|
}
|
||||||
|
|
||||||
sendAllMap(messagesPerSession)
|
sendAllMap(messagesPerSession)
|
||||||
val messages = receiveAll(String::class.java, messagesPerSession.keys.toList())
|
val messages = receiveAll(String::class.java, messagesPerSession.keys.toList())
|
||||||
@ -199,7 +200,7 @@ class FlowParallelMessagingTests {
|
|||||||
throw IllegalArgumentException("at least two parties required for staged execution")
|
throw IllegalArgumentException("at least two parties required for staged execution")
|
||||||
}
|
}
|
||||||
|
|
||||||
val sessions = parties.map { initiateFlow(it) }.toSet()
|
val sessions = parties.mapToSet(::initiateFlow)
|
||||||
|
|
||||||
sessions.first().send(StagedMessageType.INITIAL_RECIPIENT)
|
sessions.first().send(StagedMessageType.INITIAL_RECIPIENT)
|
||||||
sessions.first().receive<String>().unwrap{ payload -> assertEquals("pong", payload) }
|
sessions.first().receive<String>().unwrap{ payload -> assertEquals("pong", payload) }
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package net.corda.node.services.transactions
|
package net.corda.node.services.transactions
|
||||||
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
import kotlin.io.path.exists
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
@ -4,8 +4,11 @@ import net.corda.core.crypto.Crypto
|
|||||||
import net.corda.core.crypto.SignatureScheme
|
import net.corda.core.crypto.SignatureScheme
|
||||||
import net.corda.core.crypto.newSecureRandom
|
import net.corda.core.crypto.newSecureRandom
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.*
|
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||||
import net.corda.nodeapi.internal.crypto.*
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
|
import net.corda.nodeapi.internal.crypto.addOrReplaceCertificate
|
||||||
|
import net.corda.nodeapi.internal.crypto.addOrReplaceKey
|
||||||
|
import net.corda.nodeapi.internal.crypto.loadOrCreateKeyStore
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
@ -17,10 +20,20 @@ import java.net.InetSocketAddress
|
|||||||
import java.net.ServerSocket
|
import java.net.ServerSocket
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
import javax.net.ssl.*
|
import javax.net.ssl.KeyManagerFactory
|
||||||
|
import javax.net.ssl.SSLContext
|
||||||
|
import javax.net.ssl.SSLParameters
|
||||||
|
import javax.net.ssl.SSLServerSocket
|
||||||
|
import javax.net.ssl.SSLServerSocketFactory
|
||||||
|
import javax.net.ssl.SSLSocket
|
||||||
|
import javax.net.ssl.SSLSocketFactory
|
||||||
|
import javax.net.ssl.TrustManagerFactory
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
import kotlin.test.*
|
import kotlin.io.path.div
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Various tests for mixed-scheme mutual TLS authentication, such as:
|
* Various tests for mixed-scheme mutual TLS authentication, such as:
|
||||||
|
@ -2,35 +2,34 @@ package net.corda.node.utilities.registration
|
|||||||
|
|
||||||
import com.google.common.jimfs.Configuration.unix
|
import com.google.common.jimfs.Configuration.unix
|
||||||
import com.google.common.jimfs.Jimfs
|
import com.google.common.jimfs.Jimfs
|
||||||
import org.mockito.kotlin.any
|
|
||||||
import org.mockito.kotlin.doAnswer
|
|
||||||
import org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.CertRole
|
import net.corda.core.internal.CertRole
|
||||||
import net.corda.core.internal.createDirectories
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.safeSymbolicRead
|
import net.corda.core.internal.safeSymbolicRead
|
||||||
import net.corda.core.internal.toX500Name
|
import net.corda.core.internal.toX500Name
|
||||||
import net.corda.core.utilities.seconds
|
import net.corda.core.utilities.seconds
|
||||||
|
import net.corda.coretesting.internal.rigorousMock
|
||||||
|
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
||||||
import net.corda.node.NodeRegistrationOption
|
import net.corda.node.NodeRegistrationOption
|
||||||
import net.corda.node.services.config.NodeConfiguration
|
import net.corda.node.services.config.NodeConfiguration
|
||||||
|
import net.corda.node.services.config.NotaryConfig
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
|
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_CLIENT_CA
|
||||||
|
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_CLIENT_TLS
|
||||||
|
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_INTERMEDIATE_CA
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
|
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities.DISTRIBUTED_NOTARY_KEY_ALIAS
|
import net.corda.nodeapi.internal.crypto.X509Utilities.DISTRIBUTED_NOTARY_KEY_ALIAS
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities.createSelfSignedCACertificate
|
import net.corda.nodeapi.internal.crypto.X509Utilities.createSelfSignedCACertificate
|
||||||
import net.corda.testing.core.ALICE_NAME
|
import net.corda.testing.core.ALICE_NAME
|
||||||
import net.corda.testing.internal.createDevIntermediateCaCertPath
|
|
||||||
import net.corda.coretesting.internal.rigorousMock
|
|
||||||
import net.corda.coretesting.internal.stubs.CertificateStoreStubs
|
|
||||||
import net.corda.node.services.config.NotaryConfig
|
|
||||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||||
import org.assertj.core.api.Assertions.*
|
import net.corda.testing.internal.createDevIntermediateCaCertPath
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||||
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
import org.bouncycastle.asn1.x509.GeneralName
|
import org.bouncycastle.asn1.x509.GeneralName
|
||||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||||
import org.bouncycastle.asn1.x509.NameConstraints
|
import org.bouncycastle.asn1.x509.NameConstraints
|
||||||
@ -39,13 +38,18 @@ import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
|
|||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.lang.IllegalStateException
|
import org.mockito.kotlin.any
|
||||||
import java.nio.file.Files
|
import org.mockito.kotlin.doAnswer
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
import java.nio.file.FileSystem
|
import java.nio.file.FileSystem
|
||||||
|
import java.nio.file.Files
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.security.cert.CertPathValidatorException
|
import java.security.cert.CertPathValidatorException
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -104,17 +108,17 @@ class NetworkRegistrationHelperTest {
|
|||||||
val trustStore = config.p2pSslOptions.trustStore.get()
|
val trustStore = config.p2pSslOptions.trustStore.get()
|
||||||
|
|
||||||
nodeKeystore.run {
|
nodeKeystore.run {
|
||||||
assertFalse(contains(X509Utilities.CORDA_INTERMEDIATE_CA))
|
assertFalse(contains(CORDA_INTERMEDIATE_CA))
|
||||||
assertFalse(contains(X509Utilities.CORDA_ROOT_CA))
|
assertFalse(contains(CORDA_ROOT_CA))
|
||||||
assertFalse(contains(X509Utilities.CORDA_CLIENT_TLS))
|
assertFalse(contains(CORDA_CLIENT_TLS))
|
||||||
assertThat(CertRole.extract(this[X509Utilities.CORDA_CLIENT_CA])).isEqualTo(CertRole.NODE_CA)
|
assertThat(CertRole.extract(this[CORDA_CLIENT_CA])).isEqualTo(CertRole.NODE_CA)
|
||||||
}
|
}
|
||||||
|
|
||||||
sslKeystore.run {
|
sslKeystore.run {
|
||||||
assertFalse(contains(X509Utilities.CORDA_CLIENT_CA))
|
assertFalse(contains(CORDA_CLIENT_CA))
|
||||||
assertFalse(contains(X509Utilities.CORDA_INTERMEDIATE_CA))
|
assertFalse(contains(CORDA_INTERMEDIATE_CA))
|
||||||
assertFalse(contains(X509Utilities.CORDA_ROOT_CA))
|
assertFalse(contains(CORDA_ROOT_CA))
|
||||||
val nodeTlsCertChain = query { getCertificateChain(X509Utilities.CORDA_CLIENT_TLS) }
|
val nodeTlsCertChain = query { getCertificateChain(CORDA_CLIENT_TLS) }
|
||||||
assertThat(nodeTlsCertChain).hasSize(4)
|
assertThat(nodeTlsCertChain).hasSize(4)
|
||||||
// The TLS cert has the same subject as the node CA cert
|
// The TLS cert has the same subject as the node CA cert
|
||||||
assertThat(CordaX500Name.build(nodeTlsCertChain[0].subjectX500Principal)).isEqualTo(nodeLegalName)
|
assertThat(CordaX500Name.build(nodeTlsCertChain[0].subjectX500Principal)).isEqualTo(nodeLegalName)
|
||||||
@ -122,9 +126,9 @@ class NetworkRegistrationHelperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trustStore.run {
|
trustStore.run {
|
||||||
assertFalse(contains(X509Utilities.CORDA_CLIENT_CA))
|
assertFalse(contains(CORDA_CLIENT_CA))
|
||||||
assertFalse(contains(X509Utilities.CORDA_INTERMEDIATE_CA))
|
assertFalse(contains(CORDA_INTERMEDIATE_CA))
|
||||||
assertThat(this[X509Utilities.CORDA_ROOT_CA]).isEqualTo(rootAndIntermediateCA.first.certificate)
|
assertThat(this[CORDA_ROOT_CA]).isEqualTo(rootAndIntermediateCA.first.certificate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,10 +212,10 @@ class NetworkRegistrationHelperTest {
|
|||||||
val serviceIdentityAlias = DISTRIBUTED_NOTARY_KEY_ALIAS
|
val serviceIdentityAlias = DISTRIBUTED_NOTARY_KEY_ALIAS
|
||||||
|
|
||||||
nodeKeystore.run {
|
nodeKeystore.run {
|
||||||
assertFalse(contains(X509Utilities.CORDA_INTERMEDIATE_CA))
|
assertFalse(contains(CORDA_INTERMEDIATE_CA))
|
||||||
assertFalse(contains(X509Utilities.CORDA_ROOT_CA))
|
assertFalse(contains(CORDA_ROOT_CA))
|
||||||
assertFalse(contains(X509Utilities.CORDA_CLIENT_TLS))
|
assertFalse(contains(CORDA_CLIENT_TLS))
|
||||||
assertFalse(contains(X509Utilities.CORDA_CLIENT_CA))
|
assertFalse(contains(CORDA_CLIENT_CA))
|
||||||
assertThat(CertRole.extract(this[serviceIdentityAlias])).isEqualTo(CertRole.SERVICE_IDENTITY)
|
assertThat(CertRole.extract(this[serviceIdentityAlias])).isEqualTo(CertRole.SERVICE_IDENTITY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,12 +246,12 @@ class NetworkRegistrationHelperTest {
|
|||||||
|
|
||||||
// Mock out the registration service to ensure notary service registration is handled correctly
|
// Mock out the registration service to ensure notary service registration is handled correctly
|
||||||
createRegistrationHelper(CertRole.NODE_CA, notaryNodeConfig) {
|
createRegistrationHelper(CertRole.NODE_CA, notaryNodeConfig) {
|
||||||
when {
|
when (it.subject) {
|
||||||
it.subject == nodeLegalName.toX500Name() -> {
|
nodeLegalName.toX500Name() -> {
|
||||||
val certType = CertificateType.values().first { it.role == CertRole.NODE_CA }
|
val certType = CertificateType.values().first { it.role == CertRole.NODE_CA }
|
||||||
createCertPath(rootAndIntermediateCA = rootAndIntermediateCA, publicKey = it.publicKey, type = certType)
|
createCertPath(rootAndIntermediateCA = rootAndIntermediateCA, publicKey = it.publicKey, type = certType)
|
||||||
}
|
}
|
||||||
it.subject == notaryServiceLegalName.toX500Name() -> {
|
notaryServiceLegalName.toX500Name() -> {
|
||||||
val certType = CertificateType.values().first { it.role == CertRole.SERVICE_IDENTITY }
|
val certType = CertificateType.values().first { it.role == CertRole.SERVICE_IDENTITY }
|
||||||
createCertPath(rootAndIntermediateCA = rootAndIntermediateCA, publicKey = it.publicKey, type = certType, legalName = notaryServiceLegalName)
|
createCertPath(rootAndIntermediateCA = rootAndIntermediateCA, publicKey = it.publicKey, type = certType, legalName = notaryServiceLegalName)
|
||||||
}
|
}
|
||||||
@ -258,10 +262,10 @@ class NetworkRegistrationHelperTest {
|
|||||||
val nodeKeystore = config.signingCertificateStore.get()
|
val nodeKeystore = config.signingCertificateStore.get()
|
||||||
|
|
||||||
nodeKeystore.run {
|
nodeKeystore.run {
|
||||||
assertFalse(contains(X509Utilities.CORDA_INTERMEDIATE_CA))
|
assertFalse(contains(CORDA_INTERMEDIATE_CA))
|
||||||
assertFalse(contains(CORDA_ROOT_CA))
|
assertFalse(contains(CORDA_ROOT_CA))
|
||||||
assertFalse(contains(X509Utilities.CORDA_CLIENT_TLS))
|
assertFalse(contains(CORDA_CLIENT_TLS))
|
||||||
assertThat(CertRole.extract(this[X509Utilities.CORDA_CLIENT_CA])).isEqualTo(CertRole.NODE_CA)
|
assertThat(CertRole.extract(this[CORDA_CLIENT_CA])).isEqualTo(CertRole.NODE_CA)
|
||||||
assertThat(CertRole.extract(this[DISTRIBUTED_NOTARY_KEY_ALIAS])).isEqualTo(CertRole.SERVICE_IDENTITY)
|
assertThat(CertRole.extract(this[DISTRIBUTED_NOTARY_KEY_ALIAS])).isEqualTo(CertRole.SERVICE_IDENTITY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
package net.corda.notary.experimental.bftsmart
|
package net.corda.notary.experimental.bftsmart
|
||||||
|
|
||||||
import org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
|
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
|
||||||
import net.corda.core.contracts.ContractState
|
import net.corda.core.contracts.ContractState
|
||||||
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.*
|
import net.corda.core.crypto.CompositeKey
|
||||||
|
import net.corda.core.crypto.SecureHash
|
||||||
|
import net.corda.core.crypto.TransactionSignature
|
||||||
|
import net.corda.core.crypto.isFulfilledBy
|
||||||
import net.corda.core.flows.NotaryError
|
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.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.deleteIfExists
|
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.node.NotaryInfo
|
import net.corda.core.node.NotaryInfo
|
||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
@ -29,19 +28,26 @@ import net.corda.testing.contracts.DummyContract
|
|||||||
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.node.TestClock
|
import net.corda.testing.node.TestClock
|
||||||
import net.corda.testing.node.internal.*
|
import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP
|
||||||
import org.hamcrest.Matchers.instanceOf
|
import net.corda.testing.node.internal.InternalMockNetwork
|
||||||
|
import net.corda.testing.node.internal.InternalMockNodeParameters
|
||||||
|
import net.corda.testing.node.internal.TestStartedNode
|
||||||
|
import net.corda.testing.node.internal.startFlow
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.AfterClass
|
import org.junit.AfterClass
|
||||||
import org.junit.Assert.assertThat
|
|
||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.concurrent.ExecutionException
|
import java.util.concurrent.ExecutionException
|
||||||
import kotlin.collections.component1
|
import kotlin.collections.component1
|
||||||
import kotlin.collections.component2
|
import kotlin.collections.component2
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -70,7 +76,7 @@ class BFTNotaryServiceTests {
|
|||||||
mockNet.stopNodes()
|
mockNet.stopNodes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startBftClusterAndNode(clusterSize: Int, mockNet: InternalMockNetwork, exposeRaces: Boolean = false): Pair<Party, TestStartedNode> {
|
private fun startBftClusterAndNode(clusterSize: Int, mockNet: InternalMockNetwork, exposeRaces: Boolean = false): Pair<Party, TestStartedNode> {
|
||||||
(Paths.get("config") / "currentView").deleteIfExists() // XXX: Make config object warn if this exists?
|
(Paths.get("config") / "currentView").deleteIfExists() // XXX: Make config object warn if this exists?
|
||||||
val replicaIds = (0 until clusterSize)
|
val replicaIds = (0 until clusterSize)
|
||||||
val serviceLegalName = CordaX500Name("BFT", "Zurich", "CH")
|
val serviceLegalName = CordaX500Name("BFT", "Zurich", "CH")
|
||||||
@ -162,9 +168,9 @@ class BFTNotaryServiceTests {
|
|||||||
val resultFuture = services.startFlow(flow).resultFuture
|
val resultFuture = services.startFlow(flow).resultFuture
|
||||||
mockNet.runNetwork()
|
mockNet.runNetwork()
|
||||||
val exception = assertFailsWith<ExecutionException> { resultFuture.get() }
|
val exception = assertFailsWith<ExecutionException> { resultFuture.get() }
|
||||||
assertThat(exception.cause, instanceOf(NotaryException::class.java))
|
assertThat(exception.cause).isInstanceOf(NotaryException::class.java)
|
||||||
val error = (exception.cause as NotaryException).error
|
val error = (exception.cause as NotaryException).error
|
||||||
assertThat(error, instanceOf(NotaryError.TimeWindowInvalid::class.java))
|
assertThat(error).isInstanceOf(NotaryError.TimeWindowInvalid::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +32,11 @@ import com.opengamma.strata.product.common.BuySell
|
|||||||
import com.opengamma.strata.product.swap.type.FixedIborSwapConventions
|
import com.opengamma.strata.product.swap.type.FixedIborSwapConventions
|
||||||
import com.opengamma.strata.report.ReportCalculationResults
|
import com.opengamma.strata.report.ReportCalculationResults
|
||||||
import com.opengamma.strata.report.trade.TradeReport
|
import com.opengamma.strata.report.trade.TradeReport
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.internal.exists
|
|
||||||
import net.corda.core.internal.toPath
|
import net.corda.core.internal.toPath
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example to illustrate using the engine to price a swap.
|
* Example to illustrate using the engine to price a swap.
|
||||||
@ -65,8 +65,8 @@ class SwapPricingCcpExample {
|
|||||||
*/
|
*/
|
||||||
private val resourcesUri = run {
|
private val resourcesUri = run {
|
||||||
// Find src/main/resources by walking up the directory tree starting at a classpath root:
|
// Find src/main/resources by walking up the directory tree starting at a classpath root:
|
||||||
var module = javaClass.getResource("/").toPath()
|
var module = javaClass.getResource("/")!!.toPath()
|
||||||
val relative = "src" / "main" / "resources"
|
val relative = Path("src", "main", "resources")
|
||||||
var path: Path
|
var path: Path
|
||||||
while (true) {
|
while (true) {
|
||||||
path = module.resolve(relative)
|
path = module.resolve(relative)
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package net.corda.vega.portfolio
|
package net.corda.vega.portfolio
|
||||||
|
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.ContractState
|
||||||
|
import net.corda.core.contracts.StateAndRef
|
||||||
|
import net.corda.core.contracts.StateRef
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.sum
|
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
import net.corda.core.messaging.vaultQueryBy
|
import net.corda.core.messaging.vaultQueryBy
|
||||||
import net.corda.core.node.services.vault.QueryCriteria
|
import net.corda.core.node.services.vault.QueryCriteria
|
||||||
@ -23,7 +24,7 @@ data class Portfolio(private val tradeStateAndRefs: List<StateAndRef<IRSState>>,
|
|||||||
val swaps: List<SwapData> by lazy { trades.map { it.swap } }
|
val swaps: List<SwapData> by lazy { trades.map { it.swap } }
|
||||||
val refs: List<StateRef> by lazy { tradeStateAndRefs.map { it.ref } }
|
val refs: List<StateRef> by lazy { tradeStateAndRefs.map { it.ref } }
|
||||||
|
|
||||||
fun getNotionalForParty(party: Party): BigDecimal = trades.map { it.swap.getLegForParty(party).notional }.sum()
|
fun getNotionalForParty(party: Party): BigDecimal = trades.sumOf { it.swap.getLegForParty(party).notional }
|
||||||
|
|
||||||
fun update(curTrades: List<StateAndRef<IRSState>>): Portfolio {
|
fun update(curTrades: List<StateAndRef<IRSState>>): Portfolio {
|
||||||
return copy(tradeStateAndRefs = curTrades)
|
return copy(tradeStateAndRefs = curTrades)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user