Merge pull request #412 from corda/shams-os-merge-250118

O/S merge 250118
This commit is contained in:
Shams Asari 2018-01-26 15:30:57 +00:00 committed by GitHub
commit d3cd2f92a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
340 changed files with 4451 additions and 3271 deletions

4
.idea/compiler.xml generated
View File

@ -121,6 +121,8 @@
<module name="node_test" target="1.8" /> <module name="node_test" target="1.8" />
<module name="notary-demo_main" target="1.8" /> <module name="notary-demo_main" target="1.8" />
<module name="notary-demo_test" target="1.8" /> <module name="notary-demo_test" target="1.8" />
<module name="notaryhealthcheck_main" target="1.8" />
<module name="notaryhealthcheck_test" target="1.8" />
<module name="perftestcordapp_integrationTest" target="1.8" /> <module name="perftestcordapp_integrationTest" target="1.8" />
<module name="perftestcordapp_main" target="1.8" /> <module name="perftestcordapp_main" target="1.8" />
<module name="perftestcordapp_test" target="1.8" /> <module name="perftestcordapp_test" target="1.8" />
@ -186,4 +188,4 @@
<component name="JavacSettings"> <component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_STRING" value="-parameters" /> <option name="ADDITIONAL_OPTIONS_STRING" value="-parameters" />
</component> </component>
</project> </project>

View File

@ -1,15 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Explorer - demo nodes" type="JetRunConfigurationType" factoryName="Kotlin" singleton="true">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="net.corda.explorer.MainKt" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="1.8" />
<option name="PASS_PARENT_ENVS" value="true" />
<module name="explorer_main" />
<envs />
<method />
</configuration>
</component>

View File

@ -1,15 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Explorer - demo nodes (simulation)" type="JetRunConfigurationType" factoryName="Kotlin" singleton="true">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="net.corda.explorer.MainKt" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="-S" />
<option name="WORKING_DIRECTORY" value="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="1.8" />
<option name="PASS_PARENT_ENVS" value="true" />
<module name="explorer_main" />
<envs />
<method />
</configuration>
</component>

View File

@ -58,7 +58,7 @@ buildscript {
ext.h2_version = '1.4.194' // Update docs if renamed or removed. ext.h2_version = '1.4.194' // Update docs if renamed or removed.
ext.postgresql_version = '42.1.4' ext.postgresql_version = '42.1.4'
ext.rxjava_version = '1.2.4' ext.rxjava_version = '1.2.4'
ext.dokka_version = '0.9.14' ext.dokka_version = '0.9.16-eap-2'
ext.eddsa_version = '0.2.0' ext.eddsa_version = '0.2.0'
ext.dependency_checker_version = '3.0.1' ext.dependency_checker_version = '3.0.1'
ext.commons_collections_version = '4.1' ext.commons_collections_version = '4.1'
@ -79,6 +79,9 @@ buildscript {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
jcenter() jcenter()
maven {
url 'https://dl.bintray.com/kotlin/kotlin-eap/'
}
} }
dependencies { dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

View File

@ -10,8 +10,11 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.SignedTransaction
import net.corda.finance.USD import net.corda.finance.USD
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule

View File

@ -28,7 +28,7 @@ import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.node.services.Permissions.Companion.startFlow import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.* import net.corda.testing.core.*
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 net.corda.testing.internal.IntegrationTest import net.corda.testing.internal.IntegrationTest
@ -85,7 +85,7 @@ class NodeMonitorModelTest : IntegrationTest() {
vaultUpdates = monitor.vaultUpdates.bufferUntilSubscribed() vaultUpdates = monitor.vaultUpdates.bufferUntilSubscribed()
networkMapUpdates = monitor.networkMap.bufferUntilSubscribed() networkMapUpdates = monitor.networkMap.bufferUntilSubscribed()
monitor.register(aliceNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password) monitor.register(aliceNodeHandle.configuration.rpcOptions.address!!, cashUser.username, cashUser.password)
rpc = monitor.proxyObservable.value!! rpc = monitor.proxyObservable.value!!
notaryParty = defaultNotaryIdentity notaryParty = defaultNotaryIdentity
@ -93,7 +93,7 @@ class NodeMonitorModelTest : IntegrationTest() {
bobNode = bobNodeHandle.nodeInfo bobNode = bobNodeHandle.nodeInfo
val monitorBob = NodeMonitorModel() val monitorBob = NodeMonitorModel()
stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed() stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed()
monitorBob.register(bobNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password) monitorBob.register(bobNodeHandle.configuration.rpcOptions.address!!, cashUser.username, cashUser.password)
rpcBob = monitorBob.proxyObservable.value!! rpcBob = monitorBob.proxyObservable.value!!
runTest() runTest()
} }

View File

@ -10,7 +10,7 @@ import net.corda.finance.flows.CashPaymentFlow;
import net.corda.finance.schemas.CashSchemaV1; import net.corda.finance.schemas.CashSchemaV1;
import net.corda.node.internal.Node; import net.corda.node.internal.Node;
import net.corda.node.internal.StartedNode; import net.corda.node.internal.StartedNode;
import net.corda.testing.CoreTestUtils; import net.corda.testing.core.TestUtils;
import net.corda.testing.node.User; import net.corda.testing.node.User;
import net.corda.testing.internal.IntegrationTestKt; import net.corda.testing.internal.IntegrationTestKt;
import net.corda.testing.internal.IntegrationTestSchemas; import net.corda.testing.internal.IntegrationTestSchemas;
@ -31,7 +31,7 @@ import static net.corda.finance.Currencies.DOLLARS;
import static net.corda.finance.contracts.GetBalances.getCashBalance; import static net.corda.finance.contracts.GetBalances.getCashBalance;
import static net.corda.node.services.Permissions.invokeRpc; import static net.corda.node.services.Permissions.invokeRpc;
import static net.corda.node.services.Permissions.startFlow; import static net.corda.node.services.Permissions.startFlow;
import static net.corda.testing.TestConstants.ALICE_NAME; import static net.corda.testing.core.TestConstants.ALICE_NAME;
public class CordaRPCJavaClientTest extends NodeBasedTest { public class CordaRPCJavaClientTest extends NodeBasedTest {
public CordaRPCJavaClientTest() { public CordaRPCJavaClientTest() {
@ -64,7 +64,7 @@ public class CordaRPCJavaClientTest extends NodeBasedTest {
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
node = startNode(ALICE_NAME, 1, singletonList(rpcUser)); node = startNode(ALICE_NAME, 1, singletonList(rpcUser));
client = new CordaRPCClient(requireNonNull(node.getInternals().getConfiguration().getRpcAddress())); client = new CordaRPCClient(requireNonNull(node.getInternals().getConfiguration().getRpcOptions().getAddress()));
} }
@After @After
@ -83,7 +83,7 @@ public class CordaRPCJavaClientTest extends NodeBasedTest {
FlowHandle<AbstractCashFlow.Result> flowHandle = rpcProxy.startFlowDynamic(CashIssueFlow.class, FlowHandle<AbstractCashFlow.Result> flowHandle = rpcProxy.startFlowDynamic(CashIssueFlow.class,
DOLLARS(123), OpaqueBytes.of((byte)0), DOLLARS(123), OpaqueBytes.of((byte)0),
CoreTestUtils.chooseIdentity(node.getInfo())); TestUtils.chooseIdentity(node.getInfo()));
System.out.println("Started issuing cash, waiting on result"); System.out.println("Started issuing cash, waiting on result");
flowHandle.getReturnValue().get(); flowHandle.getReturnValue().get();

View File

@ -7,7 +7,8 @@ import net.corda.core.flows.StartableByRPC
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
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.testing.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas import net.corda.testing.internal.IntegrationTestSchemas

View File

@ -20,7 +20,7 @@ import net.corda.node.internal.Node
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.node.services.Permissions.Companion.startFlow import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.* import net.corda.testing.core.*
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.internal.IntegrationTestSchemas import net.corda.testing.internal.IntegrationTestSchemas
import net.corda.testing.internal.toDatabaseSchemaName import net.corda.testing.internal.toDatabaseSchemaName
@ -61,7 +61,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
node = startNode(ALICE_NAME, rpcUsers = listOf(rpcUser)) node = startNode(ALICE_NAME, rpcUsers = listOf(rpcUser))
client = CordaRPCClient(node.internals.configuration.rpcAddress!!) client = CordaRPCClient(node.internals.configuration.rpcOptions.address!!)
identity = node.info.identityFromX500Name(ALICE_NAME) identity = node.info.identityFromX500Name(ALICE_NAME)
} }

View File

@ -12,7 +12,10 @@ import net.corda.core.serialization.serialize
import net.corda.core.utilities.* import net.corda.core.utilities.*
import net.corda.node.services.messaging.RPCServerConfiguration import net.corda.node.services.messaging.RPCServerConfiguration
import net.corda.nodeapi.RPCApi import net.corda.nodeapi.RPCApi
import net.corda.testing.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.internal.IntegrationTest import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas import net.corda.testing.internal.IntegrationTestSchemas
import net.corda.testing.internal.testThreadFactory import net.corda.testing.internal.testThreadFactory

View File

@ -10,6 +10,7 @@ import net.corda.core.serialization.internal.effectiveSerializationEnv
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.ArtemisTcpTransport.Companion.tcpTransport import net.corda.nodeapi.ArtemisTcpTransport.Companion.tcpTransport
import net.corda.nodeapi.ConnectionDirection import net.corda.nodeapi.ConnectionDirection
import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT import net.corda.nodeapi.internal.serialization.KRYO_RPC_CLIENT_CONTEXT
import java.time.Duration import java.time.Duration
@ -67,10 +68,12 @@ data class CordaRPCClientConfiguration(val connectionMaxRetryInterval: Duration)
* *
* @param hostAndPort The network address to connect to. * @param hostAndPort The network address to connect to.
* @param configuration An optional configuration used to tweak client behaviour. * @param configuration An optional configuration used to tweak client behaviour.
* @param sslConfiguration An optional [SSLConfiguration] used to enable secure communication with the server.
*/ */
class CordaRPCClient @JvmOverloads constructor( class CordaRPCClient @JvmOverloads constructor(
hostAndPort: NetworkHostAndPort, hostAndPort: NetworkHostAndPort,
configuration: CordaRPCClientConfiguration = CordaRPCClientConfiguration.DEFAULT configuration: CordaRPCClientConfiguration = CordaRPCClientConfiguration.DEFAULT,
sslConfiguration: SSLConfiguration? = null
) { ) {
init { init {
try { try {
@ -85,7 +88,7 @@ class CordaRPCClient @JvmOverloads constructor(
} }
private val rpcClient = RPCClient<CordaRPCOps>( private val rpcClient = RPCClient<CordaRPCOps>(
tcpTransport(ConnectionDirection.Outbound(), hostAndPort, config = null), tcpTransport(ConnectionDirection.Outbound(), hostAndPort, config = sslConfiguration),
configuration.toRpcClientConfiguration(), configuration.toRpcClientConfiguration(),
KRYO_RPC_CLIENT_CONTEXT KRYO_RPC_CLIENT_CONTEXT
) )

View File

@ -47,6 +47,7 @@ public class StandaloneCordaRPCJavaClientTest {
port.getAndIncrement(), port.getAndIncrement(),
port.getAndIncrement(), port.getAndIncrement(),
port.getAndIncrement(), port.getAndIncrement(),
port.getAndIncrement(),
true, true,
Collections.singletonList(rpcUser), Collections.singletonList(rpcUser),
true, true,

View File

@ -60,6 +60,7 @@ class StandaloneCordaRPClientTest {
legalName = CordaX500Name(organisation = "Notary Service", locality = "Zurich", country = "CH"), legalName = CordaX500Name(organisation = "Notary Service", locality = "Zurich", country = "CH"),
p2pPort = port.andIncrement, p2pPort = port.andIncrement,
rpcPort = port.andIncrement, rpcPort = port.andIncrement,
rpcAdminPort = port.andIncrement,
webPort = port.andIncrement, webPort = port.andIncrement,
isNotary = true, isNotary = true,
users = listOf(user) users = listOf(user)

View File

@ -5,7 +5,7 @@ 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.messaging.RPCOps import net.corda.core.messaging.RPCOps
import net.corda.node.services.messaging.RPCServerConfiguration import net.corda.node.services.messaging.RPCServerConfiguration
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.node.internal.RPCDriverDSL import net.corda.testing.node.internal.RPCDriverDSL
import net.corda.testing.node.internal.rpcTestUser import net.corda.testing.node.internal.rpcTestUser

View File

@ -5,7 +5,7 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.openFuture
import net.corda.core.messaging.* import net.corda.core.messaging.*
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.node.internal.rpcDriver import net.corda.testing.node.internal.rpcDriver
import net.corda.testing.node.internal.startRpcClient import net.corda.testing.node.internal.startRpcClient
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy

View File

@ -14,7 +14,10 @@ import net.corda.finance.DOLLARS
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashIssueAndPaymentFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.testing.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.junit.After import org.junit.After

View File

@ -2,7 +2,7 @@ package net.corda.confidential
import net.corda.core.identity.* import net.corda.core.identity.*
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.testing.* import net.corda.testing.core.*
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import org.junit.Before import org.junit.Before
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow

View File

@ -1,4 +1,4 @@
gradlePluginsVersion=3.0.3 gradlePluginsVersion=3.0.5
kotlinVersion=1.1.60 kotlinVersion=1.1.60
platformVersion=3 platformVersion=3
guavaVersion=21.0 guavaVersion=21.0

View File

@ -497,6 +497,7 @@ object Crypto {
* It returns true if it succeeds, but it always throws an exception if verification fails. * It returns true if it succeeds, but it always throws an exception if verification fails.
* Strategy on identifying the actual signing scheme is based on the [PublicKey] type, but if the schemeCodeName is known, * Strategy on identifying the actual signing scheme is based on the [PublicKey] type, but if the schemeCodeName is known,
* then better use doVerify(schemeCodeName: String, publicKey: PublicKey, signatureData: ByteArray, clearData: ByteArray). * then better use doVerify(schemeCodeName: String, publicKey: PublicKey, signatureData: ByteArray, clearData: ByteArray).
*
* @param publicKey the signer's [PublicKey]. * @param publicKey the signer's [PublicKey].
* @param signatureData the signatureData on a message. * @param signatureData the signatureData on a message.
* @param clearData the clear data/message that was signed (usually the Merkle root). * @param clearData the clear data/message that was signed (usually the Merkle root).

View File

@ -244,7 +244,9 @@ abstract class SignTransactionFlow(val otherSideSession: FlowSession,
} }
@Suspendable private fun checkSignatures(stx: SignedTransaction) { @Suspendable private fun checkSignatures(stx: SignedTransaction) {
val signingWellKnownIdentities = groupPublicKeysByWellKnownParty(serviceHub, stx.sigs.map(TransactionSignature::by)) // We set `ignoreUnrecognisedParties` to `true` in `groupPublicKeysByWellKnownParty`. This is because we don't
// need to recognise all keys, but just the initiator's.
val signingWellKnownIdentities = groupPublicKeysByWellKnownParty(serviceHub, stx.sigs.map(TransactionSignature::by), true)
require(otherSideSession.counterparty in signingWellKnownIdentities) { require(otherSideSession.counterparty in signingWellKnownIdentities) {
"The Initiator of CollectSignaturesFlow must have signed the transaction. Found ${signingWellKnownIdentities}, expected ${otherSideSession}" "The Initiator of CollectSignaturesFlow must have signed the transaction. Found ${signingWellKnownIdentities}, expected ${otherSideSession}"
} }

View File

@ -1,6 +1,7 @@
package net.corda.core.identity package net.corda.core.identity
import net.corda.core.internal.CertRole import net.corda.core.internal.CertRole
import net.corda.core.internal.uncheckedCast
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import java.security.PublicKey import java.security.PublicKey
import java.security.cert.* import java.security.cert.*
@ -45,15 +46,16 @@ class PartyAndCertificate(val certPath: CertPath) {
// Apply Corda-specific validity rules to the chain. This only applies to chains with any roles present, so // Apply Corda-specific validity rules to the chain. This only applies to chains with any roles present, so
// an all-null chain is in theory valid. // an all-null chain is in theory valid.
var parentRole: CertRole? = CertRole.extract(result.trustAnchor.trustedCert) var parentRole: CertRole? = CertRole.extract(result.trustAnchor.trustedCert)
for (certIdx in (0 until certPath.certificates.size).reversed()) { val certChain: List<X509Certificate> = uncheckedCast(certPath.certificates)
val certificate = certPath.certificates[certIdx] for (certIdx in (0 until certChain.size).reversed()) {
val certificate = certChain[certIdx]
val role = CertRole.extract(certificate) val role = CertRole.extract(certificate)
if (parentRole != null) { if (parentRole != null) {
if (role == null) { if (role == null) {
throw CertPathValidatorException("Child certificate whose issuer includes a Corda role, must also specify Corda role") throw CertPathValidatorException("Child certificate whose issuer includes a Corda role, must also specify Corda role")
} }
if (!role.isValidParent(parentRole)) { if (!role.isValidParent(parentRole)) {
val certificateString = (certificate as? X509Certificate)?.subjectDN?.toString() ?: certificate.toString() val certificateString = certificate.subjectDN.toString()
throw CertPathValidatorException("The issuing certificate for $certificateString has role $parentRole, expected one of ${role.validParents}") throw CertPathValidatorException("The issuing certificate for $certificateString has role $parentRole, expected one of ${role.validParents}")
} }
} }

View File

@ -1,12 +1,12 @@
package net.corda.core.internal package net.corda.core.internal
import net.corda.core.CordaOID import net.corda.core.CordaOID
import net.corda.core.utilities.NonEmptySet
import org.bouncycastle.asn1.ASN1Encodable import org.bouncycastle.asn1.ASN1Encodable
import org.bouncycastle.asn1.ASN1Integer import org.bouncycastle.asn1.ASN1Integer
import org.bouncycastle.asn1.ASN1Primitive import org.bouncycastle.asn1.ASN1Primitive
import org.bouncycastle.asn1.DEROctetString import org.bouncycastle.asn1.DEROctetString
import java.math.BigInteger import java.math.BigInteger
import java.security.cert.Certificate
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
/** /**
@ -23,40 +23,38 @@ import java.security.cert.X509Certificate
// NOTE: The order of the entries in the enum MUST NOT be changed, as their ordinality is used as an identifier. Please // NOTE: The order of the entries in the enum MUST NOT be changed, as their ordinality is used as an identifier. Please
// also note that IDs are numbered from 1 upwards, matching numbering of other enum types in ASN.1 specifications. // also note that IDs are numbered from 1 upwards, matching numbering of other enum types in ASN.1 specifications.
// TODO: Link to the specification once it has a permanent URL // TODO: Link to the specification once it has a permanent URL
enum class CertRole(val validParents: Set<CertRole?>, val isIdentity: Boolean, val isWellKnown: Boolean) : ASN1Encodable { enum class CertRole(val validParents: NonEmptySet<CertRole?>, val isIdentity: Boolean, val isWellKnown: Boolean) : ASN1Encodable {
/** /**
* Intermediate CA (Doorman service). * Intermediate CA (Doorman service).
*/ */
INTERMEDIATE_CA(setOf(null), false, false), INTERMEDIATE_CA(NonEmptySet.of(null), false, false),
/** Signing certificate for the network map. */ /** Signing certificate for the network map. */
NETWORK_MAP(setOf(null), false, false), NETWORK_MAP(NonEmptySet.of(null), false, false),
/** Well known (publicly visible) identity of a service (such as notary). */ /** Well known (publicly visible) identity of a service (such as notary). */
SERVICE_IDENTITY(setOf(INTERMEDIATE_CA), true, true), SERVICE_IDENTITY(NonEmptySet.of(INTERMEDIATE_CA), true, true),
/** Node level CA from which the TLS and well known identity certificates are issued. */ /** Node level CA from which the TLS and well known identity certificates are issued. */
NODE_CA(setOf(INTERMEDIATE_CA), false, false), NODE_CA(NonEmptySet.of(INTERMEDIATE_CA), false, false),
/** Transport layer security certificate for a node. */ /** Transport layer security certificate for a node. */
TLS(setOf(NODE_CA), false, false), TLS(NonEmptySet.of(NODE_CA), false, false),
/** Well known (publicly visible) identity of a legal entity. */ /** Well known (publicly visible) identity of a legal entity. */
LEGAL_IDENTITY(setOf(INTERMEDIATE_CA, NODE_CA), true, true), LEGAL_IDENTITY(NonEmptySet.of(INTERMEDIATE_CA, NODE_CA), true, true),
/** Confidential (limited visibility) identity of a legal entity. */ /** Confidential (limited visibility) identity of a legal entity. */
CONFIDENTIAL_LEGAL_IDENTITY(setOf(LEGAL_IDENTITY), true, false); CONFIDENTIAL_LEGAL_IDENTITY(NonEmptySet.of(LEGAL_IDENTITY), true, false);
companion object { companion object {
private var cachedRoles: Array<CertRole>? = null private val values by lazy(LazyThreadSafetyMode.NONE, CertRole::values)
/** /**
* Get a role from its ASN.1 encoded form. * Get a role from its ASN.1 encoded form.
* *
* @throws IllegalArgumentException if the encoded data is not a valid role. * @throws IllegalArgumentException if the encoded data is not a valid role.
*/ */
fun getInstance(id: ASN1Integer): CertRole { fun getInstance(id: ASN1Integer): CertRole {
if (cachedRoles == null) {
cachedRoles = CertRole.values()
}
val idVal = id.value val idVal = id.value
require(idVal.compareTo(BigInteger.ZERO) > 0) { "Invalid role ID" } require(idVal > BigInteger.ZERO) { "Invalid role ID" }
return try { return try {
val ordinal = idVal.intValueExact() - 1 val ordinal = idVal.intValueExact() - 1
cachedRoles!![ordinal] values[ordinal]
} catch (ex: ArithmeticException) { } catch (ex: ArithmeticException) {
throw IllegalArgumentException("Invalid role ID") throw IllegalArgumentException("Invalid role ID")
} catch (ex: ArrayIndexOutOfBoundsException) { } catch (ex: ArrayIndexOutOfBoundsException) {
@ -71,21 +69,6 @@ enum class CertRole(val validParents: Set<CertRole?>, val isIdentity: Boolean, v
*/ */
fun getInstance(data: ByteArray): CertRole = getInstance(ASN1Integer.getInstance(data)) fun getInstance(data: ByteArray): CertRole = getInstance(ASN1Integer.getInstance(data))
/**
* Get a role from a certificate.
*
* @return the role if the extension is present, or null otherwise.
* @throws IllegalArgumentException if the extension is present but is invalid.
*/
fun extract(cert: Certificate): CertRole? {
val x509Cert = cert as? X509Certificate
return if (x509Cert != null) {
extract(x509Cert)
} else {
null
}
}
/** /**
* Get a role from a certificate. * Get a role from a certificate.
* *
@ -93,12 +76,9 @@ enum class CertRole(val validParents: Set<CertRole?>, val isIdentity: Boolean, v
* @throws IllegalArgumentException if the extension is present but is invalid. * @throws IllegalArgumentException if the extension is present but is invalid.
*/ */
fun extract(cert: X509Certificate): CertRole? { fun extract(cert: X509Certificate): CertRole? {
val extensionData: ByteArray? = cert.getExtensionValue(CordaOID.X509_EXTENSION_CORDA_ROLE) return cert.getExtensionValue(CordaOID.X509_EXTENSION_CORDA_ROLE)?.let {
return if (extensionData != null) { val extensionString = DEROctetString.getInstance(it)
val extensionString = DEROctetString.getInstance(extensionData)
getInstance(extensionString.octets) getInstance(extensionString.octets)
} else {
null
} }
} }
} }

View File

@ -242,14 +242,10 @@ private fun IntProgression.toSpliterator(): Spliterator.OfInt {
} }
fun IntProgression.stream(parallel: Boolean = false): IntStream = StreamSupport.intStream(toSpliterator(), parallel) fun IntProgression.stream(parallel: Boolean = false): IntStream = StreamSupport.intStream(toSpliterator(), parallel)
inline fun <reified T> Stream<out T>.toTypedArray() = toTypedArray(T::class.java)
// When toArray has filled in the array, the component type is no longer T? but T (that may itself be nullable):
fun <T> Stream<out T>.toTypedArray(componentType: Class<T>): Array<T> = toArray { size ->
uncheckedCast<Any, Array<T?>>(java.lang.reflect.Array.newInstance(componentType, size))
}
fun <T> Stream<out T?>.filterNotNull(): Stream<T> = uncheckedCast(filter(Objects::nonNull)) // When toArray has filled in the array, the component type is no longer T? but T (that may itself be nullable):
fun <K, V> Stream<out Pair<K, V>>.toMap(): Map<K, V> = collect<LinkedHashMap<K, V>>(::LinkedHashMap, { m, (k, v) -> m.put(k, v) }, { m, t -> m.putAll(t) }) inline fun <reified T> Stream<out T>.toTypedArray(): Array<T> = uncheckedCast(toArray { size -> arrayOfNulls<T>(size) })
fun <T> Class<T>.castIfPossible(obj: Any): T? = if (isInstance(obj)) cast(obj) else null fun <T> Class<T>.castIfPossible(obj: Any): T? = if (isInstance(obj)) cast(obj) else null
/** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [Class]. */ /** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [Class]. */
@ -258,13 +254,12 @@ fun <T> Class<*>.staticField(name: String): DeclaredField<T> = DeclaredField(thi
/** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [KClass]. */ /** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [KClass]. */
fun <T> KClass<*>.staticField(name: String): DeclaredField<T> = DeclaredField(java, name, null) fun <T> KClass<*>.staticField(name: String): DeclaredField<T> = DeclaredField(java, name, null)
/** @suppress Returns a [DeclaredField] wrapper around the declared (possibly non-public) instance field of the receiver object. */ /** Returns a [DeclaredField] wrapper around the declared (possibly non-public) instance field of the receiver object. */
fun <T> Any.declaredField(name: String): DeclaredField<T> = DeclaredField(javaClass, name, this) fun <T> Any.declaredField(name: String): DeclaredField<T> = DeclaredField(javaClass, name, this)
/** /**
* Returns a [DeclaredField] wrapper around the (possibly non-public) instance field of the receiver object, but declared * Returns a [DeclaredField] wrapper around the (possibly non-public) instance field of the receiver object, but declared
* in its superclass [clazz]. * in its superclass [clazz].
* @suppress
*/ */
fun <T> Any.declaredField(clazz: KClass<*>, name: String): DeclaredField<T> = DeclaredField(clazz.java, name, this) fun <T> Any.declaredField(clazz: KClass<*>, name: String): DeclaredField<T> = DeclaredField(clazz.java, name, this)
@ -299,18 +294,12 @@ fun <T, U : T> uncheckedCast(obj: T) = obj as U
fun <K, V> Iterable<Pair<K, V>>.toMultiMap(): Map<K, List<V>> = this.groupBy({ it.first }) { it.second } fun <K, V> Iterable<Pair<K, V>>.toMultiMap(): Map<K, List<V>> = this.groupBy({ it.first }) { it.second }
/** /** Provide access to internal method for AttachmentClassLoaderTests */
* Provide access to internal method for AttachmentClassLoaderTests
* @suppress
*/
fun TransactionBuilder.toWireTransaction(cordappProvider: CordappProvider, serializationContext: SerializationContext): WireTransaction { fun TransactionBuilder.toWireTransaction(cordappProvider: CordappProvider, serializationContext: SerializationContext): WireTransaction {
return toWireTransactionWithContext(cordappProvider, serializationContext) return toWireTransactionWithContext(cordappProvider, serializationContext)
} }
/** /** Provide access to internal method for AttachmentClassLoaderTests */
* Provide access to internal method for AttachmentClassLoaderTests
* @suppress
*/
fun TransactionBuilder.toLedgerTransaction(services: ServicesForResolution, serializationContext: SerializationContext) = toLedgerTransactionWithContext(services, serializationContext) fun TransactionBuilder.toLedgerTransaction(services: ServicesForResolution, serializationContext: SerializationContext) = toLedgerTransactionWithContext(services, serializationContext)
/** Convenience method to get the package name of a class literal. */ /** Convenience method to get the package name of a class literal. */

View File

@ -354,4 +354,19 @@ interface ServiceHub : ServicesForResolution {
* @return A new [Connection] * @return A new [Connection]
*/ */
fun jdbcSession(): Connection fun jdbcSession(): Connection
/**
* Allows the registration of a callback that may inform services when the app is shutting down.
*
* The intent is to allow the cleaning up of resources - e.g. releasing ports.
*
* You should not rely on this to clean up executing flows - that's what quasar is for.
*
* Please note that the shutdown handler is not guaranteed to be called. In production the node process may crash,
* be killed by the operating system and other forms of fatal termination may occur that result in this code never
* running. So you should use this functionality only for unit/integration testing or for code that can optimise
* this shutdown e.g. by cleaning up things that would otherwise trigger a slow recovery process next time the
* node starts.
*/
fun registerUnloadHandler(runOnStop: () -> Unit)
} }

View File

@ -37,6 +37,7 @@ class NodeVersioningTest {
legalName = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"), legalName = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"),
p2pPort = port.andIncrement, p2pPort = port.andIncrement,
rpcPort = port.andIncrement, rpcPort = port.andIncrement,
rpcAdminPort = port.andIncrement,
webPort = port.andIncrement, webPort = port.andIncrement,
isNotary = false, isNotary = false,
users = listOf(user) users = listOf(user)

View File

@ -32,6 +32,7 @@ class PluginRegistrationTest {
p2pPort = 30100, p2pPort = 30100,
rpcPort = 30101, rpcPort = 30101,
webPort = 30102, webPort = 30102,
rpcAdminPort = 30103,
isNotary = false, isNotary = false,
users = listOf(User("_", "_", setOf("ALL"))), users = listOf(User("_", "_", setOf("ALL"))),
jarDirs = listOf(jarDir)) jarDirs = listOf(jarDir))

View File

@ -33,6 +33,7 @@ class CordappSmokeTest {
legalName = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"), legalName = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"),
p2pPort = port.andIncrement, p2pPort = port.andIncrement,
rpcPort = port.andIncrement, rpcPort = port.andIncrement,
rpcAdminPort = port.andIncrement,
webPort = port.andIncrement, webPort = port.andIncrement,
isNotary = false, isNotary = false,
users = listOf(user) users = listOf(user)

View File

@ -4,7 +4,7 @@ import co.paralleluniverse.fibers.Suspendable;
import com.google.common.primitives.Primitives; import com.google.common.primitives.Primitives;
import net.corda.core.identity.Party; import net.corda.core.identity.Party;
import net.corda.node.internal.StartedNode; import net.corda.node.internal.StartedNode;
import net.corda.testing.TestConstants; import net.corda.testing.core.TestConstants;
import net.corda.testing.node.MockNetwork; import net.corda.testing.node.MockNetwork;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -14,7 +14,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import static net.corda.testing.CoreTestUtils.singleIdentity; import static net.corda.testing.core.TestUtils.singleIdentity;
import static net.corda.testing.node.NodeTestUtils.startFlow; import static net.corda.testing.node.NodeTestUtils.startFlow;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;

View File

@ -2,7 +2,7 @@ package net.corda.core.flows;
import net.corda.core.serialization.SerializationDefaults; import net.corda.core.serialization.SerializationDefaults;
import net.corda.core.serialization.SerializationFactory; import net.corda.core.serialization.SerializationFactory;
import net.corda.testing.SerializationEnvironmentRule; import net.corda.testing.core.SerializationEnvironmentRule;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;

View File

@ -3,7 +3,7 @@ package net.corda.core.contracts
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.testing.TestIdentity import net.corda.testing.core.TestIdentity
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith

View File

@ -6,9 +6,12 @@ import net.corda.core.cordapp.CordappProvider
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.internal.UpgradeCommand import net.corda.core.internal.UpgradeCommand
import net.corda.core.node.ServicesForResolution import net.corda.core.node.ServicesForResolution
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.contracts.DummyContractV2 import net.corda.testing.contracts.DummyContractV2
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -6,9 +6,13 @@ 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
import net.corda.nodeapi.internal.crypto.* import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.testing.SerializationEnvironmentRule import net.corda.nodeapi.internal.crypto.X509KeyStore
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.crypto.loadKeyStore
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.internal.kryoSpecific import net.corda.testing.internal.kryoSpecific
import org.assertj.core.api.Assertions.assertThat
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
@ -341,9 +345,9 @@ class CompositeKeyTests {
// Store certificate to keystore. // Store certificate to keystore.
val keystorePath = tempFolder.root.toPath() / "keystore.jks" val keystorePath = tempFolder.root.toPath() / "keystore.jks"
val keystore = loadOrCreateKeyStore(keystorePath, "password") X509KeyStore.fromFile(keystorePath, "password", createNew = true).update {
keystore.setCertificateEntry("CompositeKey", compositeKeyCert) setCertificate("CompositeKey", compositeKeyCert)
keystore.save(keystorePath, "password") }
// Load keystore from disk. // Load keystore from disk.
val keystore2 = loadKeyStore(keystorePath, "password") val keystore2 = loadKeyStore(keystorePath, "password")
@ -352,7 +356,7 @@ class CompositeKeyTests {
val key = keystore2.getCertificate("CompositeKey").publicKey val key = keystore2.getCertificate("CompositeKey").publicKey
// Convert sun public key to Composite key. // Convert sun public key to Composite key.
val compositeKey2 = Crypto.toSupportedPublicKey(key) val compositeKey2 = Crypto.toSupportedPublicKey(key)
assertTrue { compositeKey2 is CompositeKey } assertThat(compositeKey2).isInstanceOf(CompositeKey::class.java)
// Run the same composite key test again. // Run the same composite key test again.
assertTrue { compositeKey2.isFulfilledBy(signatures.byKeys()) } assertTrue { compositeKey2.isFulfilledBy(signatures.byKeys()) }

View File

@ -13,7 +13,10 @@ import net.corda.finance.DOLLARS
import net.corda.finance.`issued by` import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.node.services.api.IdentityServiceInternal import net.corda.node.services.api.IdentityServiceInternal
import net.corda.testing.* import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TEST_TX_TIME
import net.corda.testing.core.TestIdentity
import net.corda.testing.dsl.LedgerDSL import net.corda.testing.dsl.LedgerDSL
import net.corda.testing.dsl.TestLedgerDSLInterpreter import net.corda.testing.dsl.TestLedgerDSLInterpreter
import net.corda.testing.dsl.TestTransactionDSLInterpreter import net.corda.testing.dsl.TestTransactionDSLInterpreter

View File

@ -2,7 +2,7 @@ package net.corda.core.crypto
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -1,6 +1,6 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.security.SignatureException import java.security.SignatureException

View File

@ -1,7 +1,9 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.nodeapi.internal.crypto.* import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509KeyStore
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.testing.internal.createDevIntermediateCaCertPath import net.corda.testing.internal.createDevIntermediateCaCertPath
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x509.GeneralName import org.bouncycastle.asn1.x509.GeneralName
@ -9,7 +11,6 @@ import org.bouncycastle.asn1.x509.GeneralSubtree
import org.bouncycastle.asn1.x509.NameConstraints import org.bouncycastle.asn1.x509.NameConstraints
import org.bouncycastle.jce.provider.BouncyCastleProvider import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.Test import org.junit.Test
import java.security.KeyStore
import java.security.cert.CertPathValidator import java.security.cert.CertPathValidator
import java.security.cert.CertPathValidatorException import java.security.cert.CertPathValidatorException
import java.security.cert.PKIXParameters import java.security.cert.PKIXParameters
@ -19,37 +20,32 @@ import kotlin.test.assertTrue
class X509NameConstraintsTest { class X509NameConstraintsTest {
private fun makeKeyStores(subjectName: X500Name, nameConstraints: NameConstraints): Pair<KeyStore, KeyStore> { private fun makeKeyStores(subjectName: X500Name, nameConstraints: NameConstraints): Pair<X509KeyStore, X509KeyStore> {
val (rootCa, intermediateCa) = createDevIntermediateCaCertPath() val (rootCa, intermediateCa) = createDevIntermediateCaCertPath()
val nodeCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val nodeCaCert = X509Utilities.createCertificate(
CertificateType.NODE_CA,
intermediateCa.certificate,
intermediateCa.keyPair,
CordaX500Name("Corda Client CA", "R3 Ltd", "London", "GB").x500Principal,
nodeCaKeyPair.public,
nameConstraints = nameConstraints)
val keyPass = "password" val trustStore = X509KeyStore("password").apply {
val trustStore = KeyStore.getInstance(KEYSTORE_TYPE) setCertificate(X509Utilities.CORDA_ROOT_CA, rootCa.certificate)
trustStore.load(null, keyPass.toCharArray()) }
trustStore.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCa.certificate)
val tlsKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val keyStore = X509KeyStore("password").apply {
val tlsCert = X509Utilities.createCertificate( val nodeCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
CertificateType.TLS, val nodeCaCert = X509Utilities.createCertificate(
nodeCaCert, CertificateType.NODE_CA,
nodeCaKeyPair, intermediateCa.certificate,
X500Principal(subjectName.encoded), intermediateCa.keyPair,
tlsKeyPair.public) CordaX500Name("Corda Client CA", "R3 Ltd", "London", "GB").x500Principal,
nodeCaKeyPair.public,
nameConstraints = nameConstraints)
val tlsKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val tlsCert = X509Utilities.createCertificate(
CertificateType.TLS,
nodeCaCert,
nodeCaKeyPair,
X500Principal(subjectName.encoded),
tlsKeyPair.public)
setPrivateKey(X509Utilities.CORDA_CLIENT_TLS, tlsKeyPair.private, listOf(tlsCert, nodeCaCert, intermediateCa.certificate, rootCa.certificate))
}
val keyStore = KeyStore.getInstance(KEYSTORE_TYPE)
keyStore.load(null, keyPass.toCharArray())
keyStore.addOrReplaceKey(
X509Utilities.CORDA_CLIENT_TLS,
tlsKeyPair.private,
keyPass.toCharArray(),
arrayOf(tlsCert, nodeCaCert, intermediateCa.certificate, rootCa.certificate))
return Pair(keyStore, trustStore) return Pair(keyStore, trustStore)
} }
@ -60,30 +56,29 @@ class X509NameConstraintsTest {
val nameConstraints = NameConstraints(acceptableNames, arrayOf()) val nameConstraints = NameConstraints(acceptableNames, arrayOf())
val pathValidator = CertPathValidator.getInstance("PKIX") val pathValidator = CertPathValidator.getInstance("PKIX")
val certFactory = X509CertificateFactory()
assertFailsWith(CertPathValidatorException::class) { assertFailsWith(CertPathValidatorException::class) {
val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank B"), nameConstraints) val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank B"), nameConstraints)
val params = PKIXParameters(trustStore) val params = PKIXParameters(trustStore.internal)
params.isRevocationEnabled = false params.isRevocationEnabled = false
val certPath = certFactory.generateCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).asList()) val certPath = X509Utilities.buildCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS))
pathValidator.validate(certPath, params) pathValidator.validate(certPath, params)
} }
assertTrue { assertTrue {
val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A TLS, O=Bank A"), nameConstraints) val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A TLS, O=Bank A"), nameConstraints)
val params = PKIXParameters(trustStore) val params = PKIXParameters(trustStore.internal)
params.isRevocationEnabled = false params.isRevocationEnabled = false
val certPath = certFactory.generateCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).asList()) val certPath = X509Utilities.buildCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS))
pathValidator.validate(certPath, params) pathValidator.validate(certPath, params)
true true
} }
assertTrue { assertTrue {
val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A"), nameConstraints) val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A"), nameConstraints)
val params = PKIXParameters(trustStore) val params = PKIXParameters(trustStore.internal)
params.isRevocationEnabled = false params.isRevocationEnabled = false
val certPath = certFactory.generateCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).asList()) val certPath = X509Utilities.buildCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS))
pathValidator.validate(certPath, params) pathValidator.validate(certPath, params)
true true
} }
@ -95,40 +90,39 @@ class X509NameConstraintsTest {
.map { GeneralSubtree(GeneralName(X500Name(it))) }.toTypedArray() .map { GeneralSubtree(GeneralName(X500Name(it))) }.toTypedArray()
val nameConstraints = NameConstraints(acceptableNames, arrayOf()) val nameConstraints = NameConstraints(acceptableNames, arrayOf())
val certFactory = X509CertificateFactory().delegate
Crypto.ECDSA_SECP256R1_SHA256 Crypto.ECDSA_SECP256R1_SHA256
val pathValidator = CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME) val pathValidator = CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME)
assertFailsWith(CertPathValidatorException::class) { assertFailsWith(CertPathValidatorException::class) {
val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A"), nameConstraints) val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A"), nameConstraints)
val params = PKIXParameters(trustStore) val params = PKIXParameters(trustStore.internal)
params.isRevocationEnabled = false params.isRevocationEnabled = false
val certPath = certFactory.generateCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).asList()) val certPath = X509Utilities.buildCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS))
pathValidator.validate(certPath, params) pathValidator.validate(certPath, params)
} }
assertFailsWith(CertPathValidatorException::class) { assertFailsWith(CertPathValidatorException::class) {
val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A, UID=12345"), nameConstraints) val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A, UID=12345"), nameConstraints)
val params = PKIXParameters(trustStore) val params = PKIXParameters(trustStore.internal)
params.isRevocationEnabled = false params.isRevocationEnabled = false
val certPath = certFactory.generateCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).asList()) val certPath = X509Utilities.buildCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS))
pathValidator.validate(certPath, params) pathValidator.validate(certPath, params)
} }
assertTrue { assertTrue {
val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A TLS, UID=, E=me@email.com, C=GB"), nameConstraints) val (keystore, trustStore) = makeKeyStores(X500Name("CN=Bank A TLS, UID=, E=me@email.com, C=GB"), nameConstraints)
val params = PKIXParameters(trustStore) val params = PKIXParameters(trustStore.internal)
params.isRevocationEnabled = false params.isRevocationEnabled = false
val certPath = certFactory.generateCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).asList()) val certPath = X509Utilities.buildCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS))
pathValidator.validate(certPath, params) pathValidator.validate(certPath, params)
true true
} }
assertTrue { assertTrue {
val (keystore, trustStore) = makeKeyStores(X500Name("O=Bank A, UID=, E=me@email.com, C=GB"), nameConstraints) val (keystore, trustStore) = makeKeyStores(X500Name("O=Bank A, UID=, E=me@email.com, C=GB"), nameConstraints)
val params = PKIXParameters(trustStore) val params = PKIXParameters(trustStore.internal)
params.isRevocationEnabled = false params.isRevocationEnabled = false
val certPath = certFactory.generateCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).asList()) val certPath = X509Utilities.buildCertPath(keystore.getCertificateChain(X509Utilities.CORDA_CLIENT_TLS))
pathValidator.validate(certPath, params) pathValidator.validate(certPath, params)
true true
} }

View File

@ -10,7 +10,9 @@ import net.corda.core.internal.FetchDataFlow
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.testing.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow

View File

@ -12,8 +12,8 @@ import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices

View File

@ -19,8 +19,8 @@ import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.SecureCordaRPCOps import net.corda.node.internal.SecureCordaRPCOps
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.Permissions.Companion.startFlow import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.BOB_NAME import net.corda.testing.core.BOB_NAME
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.contracts.DummyContractV2 import net.corda.testing.contracts.DummyContractV2
@ -29,7 +29,7 @@ import net.corda.testing.node.internal.rpcDriver
import net.corda.testing.node.internal.rpcTestUser import net.corda.testing.node.internal.rpcTestUser
import net.corda.testing.node.internal.startRpcClient import net.corda.testing.node.internal.startRpcClient
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before

View File

@ -7,7 +7,7 @@ import net.corda.finance.POUNDS
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.issuedBy import net.corda.finance.issuedBy
import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.api.StartedNodeServices
import net.corda.testing.* import net.corda.testing.core.*
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.junit.After import org.junit.After

View File

@ -6,7 +6,7 @@ import net.corda.core.utilities.UntrustworthyData
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After

View File

@ -1,21 +1,19 @@
package net.corda.core.identity package net.corda.core.identity
import com.google.common.jimfs.Configuration.unix
import com.google.common.jimfs.Jimfs
import net.corda.core.crypto.entropyToKeyPair import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.internal.read
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.nodeapi.internal.crypto.KEYSTORE_TYPE import net.corda.nodeapi.internal.crypto.X509KeyStore
import net.corda.nodeapi.internal.crypto.X509CertificateFactory import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.crypto.save import net.corda.testing.core.DEV_ROOT_CA
import net.corda.testing.DEV_ROOT_CA import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.getTestPartyAndCertificate
import net.corda.testing.getTestPartyAndCertificate
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.io.File
import java.math.BigInteger import java.math.BigInteger
import java.security.KeyStore
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
class PartyAndCertificateTest { class PartyAndCertificateTest {
@ -25,7 +23,7 @@ class PartyAndCertificateTest {
@Test @Test
fun `reject a path with no roles`() { fun `reject a path with no roles`() {
val path = X509CertificateFactory().generateCertPath(DEV_ROOT_CA.certificate) val path = X509Utilities.buildCertPath(DEV_ROOT_CA.certificate)
assertFailsWith<IllegalArgumentException> { PartyAndCertificate(path) } assertFailsWith<IllegalArgumentException> { PartyAndCertificate(path) }
} }
@ -46,17 +44,18 @@ class PartyAndCertificateTest {
CordaX500Name(organisation = "Test Corp", locality = "Madrid", country = "ES"), CordaX500Name(organisation = "Test Corp", locality = "Madrid", country = "ES"),
entropyToKeyPair(BigInteger.valueOf(83)).public)) entropyToKeyPair(BigInteger.valueOf(83)).public))
val original = identity.certificate val original = identity.certificate
val alias = identity.name.toString()
val storePassword = "test" val storePassword = "test"
val keyStoreFilePath = File.createTempFile("serialization_test", "jks").toPath() Jimfs.newFileSystem(unix()).use {
var keyStore = KeyStore.getInstance(KEYSTORE_TYPE) val keyStoreFile = it.getPath("/serialization_test.jks")
keyStore.load(null, storePassword.toCharArray())
keyStore.setCertificateEntry(identity.name.toString(), original)
keyStore.save(keyStoreFilePath, storePassword)
// Load the key store back in again X509KeyStore.fromFile(keyStoreFile, storePassword, createNew = true).update {
keyStore = KeyStore.getInstance(KEYSTORE_TYPE) setCertificate(alias, original)
keyStoreFilePath.read { keyStore.load(it, storePassword.toCharArray()) } }
val copy = keyStore.getCertificate(identity.name.toString())
assertThat(copy).isEqualTo(original) // .isNotSameAs(original) // Load the key store back in again
val copy = X509KeyStore.fromFile(keyStoreFile, storePassword).getCertificate(alias)
assertThat(copy).isEqualTo(original)
}
} }
} }

View File

@ -1,7 +1,7 @@
package net.corda.core.identity package net.corda.core.identity
import net.corda.core.crypto.entropyToKeyPair import net.corda.core.crypto.entropyToKeyPair
import net.corda.testing.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import org.junit.Test import org.junit.Test
import java.math.BigInteger import java.math.BigInteger
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@ -1,7 +1,7 @@
package net.corda.core.internal package net.corda.core.internal
import net.corda.testing.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.BOB_NAME import net.corda.testing.core.BOB_NAME
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.After import org.junit.After
import org.junit.AfterClass import org.junit.AfterClass

View File

@ -3,7 +3,6 @@ package net.corda.core.internal
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertArrayEquals
import org.junit.Test import org.junit.Test
import java.io.Serializable
import java.util.stream.IntStream import java.util.stream.IntStream
import java.util.stream.Stream import java.util.stream.Stream
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -88,17 +87,5 @@ class InternalUtilsTest {
val b: Array<String?> = Stream.of("one", "two", null).toTypedArray() val b: Array<String?> = Stream.of("one", "two", null).toTypedArray()
assertEquals(Array<String?>::class.java, b.javaClass) assertEquals(Array<String?>::class.java, b.javaClass)
assertArrayEquals(arrayOf("one", "two", null), b) assertArrayEquals(arrayOf("one", "two", null), b)
val c: Array<CharSequence> = Stream.of("x", "y").toTypedArray(CharSequence::class.java)
assertEquals(Array<CharSequence>::class.java, c.javaClass)
assertArrayEquals(arrayOf("x", "y"), c)
val d: Array<CharSequence?> = Stream.of("x", "y", null).toTypedArray(uncheckedCast(CharSequence::class.java))
assertEquals(Array<CharSequence?>::class.java, d.javaClass)
assertArrayEquals(arrayOf("x", "y", null), d)
}
@Test
fun `Stream of Pairs toMap works`() {
val m: Map<Comparable<*>, Serializable> = Stream.of<Pair<Comparable<*>, Serializable>>("x" to "y", 0 to 1, "x" to '2').toMap()
assertEquals<Map<*, *>>(mapOf("x" to '2', 0 to 1), m)
} }
} }

View File

@ -11,7 +11,7 @@ import net.corda.core.utilities.sequence
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before

View File

@ -5,8 +5,8 @@ import net.corda.core.crypto.SecureHash
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.node.services.Vault import net.corda.core.node.services.Vault
import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.LedgerTransaction
import net.corda.testing.DUMMY_NOTARY_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.TestIdentity import net.corda.testing.core.TestIdentity
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith

View File

@ -16,11 +16,11 @@ import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.nodeapi.internal.persistence.currentDBSession import net.corda.nodeapi.internal.persistence.currentDBSession
import net.corda.testing.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.BOB_NAME import net.corda.testing.core.BOB_NAME
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters import net.corda.testing.node.MockNodeParameters
import net.corda.testing.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before

View File

@ -2,7 +2,7 @@ package net.corda.core.serialization
import net.corda.finance.contracts.CommercialPaper import net.corda.finance.contracts.CommercialPaper
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@ -8,7 +8,7 @@ import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.finance.POUNDS import net.corda.finance.POUNDS
import net.corda.testing.* import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import org.junit.Before import org.junit.Before

View File

@ -7,7 +7,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.services.UniquenessException import net.corda.core.node.services.UniquenessException
import net.corda.core.node.services.UniquenessProvider import net.corda.core.node.services.UniquenessProvider
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@ -5,9 +5,9 @@ import net.corda.core.contracts.ComponentGroupEnum.*
import net.corda.core.crypto.* import net.corda.core.crypto.*
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.contracts.DummyState import net.corda.testing.contracts.DummyState
import net.corda.testing.core.*
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.time.Instant import java.time.Instant
@ -287,7 +287,7 @@ class CompatibleTransactionTests {
@Test @Test
fun `Command visibility tests`() { fun `Command visibility tests`() {
// 1st and 3rd commands require a signature from KEY_1. // 1st and 3rd commands require a signature from KEY_1.
val twoCommandsforKey1 = listOf(dummyCommand(DUMMY_KEY_1.public, DUMMY_KEY_2.public), dummyCommand(DUMMY_KEY_2.public), dummyCommand(DUMMY_KEY_1.public)) val twoCommandsforKey1 = listOf(dummyCommand(DUMMY_KEY_1.public, DUMMY_KEY_2.public), dummyCommand(DUMMY_KEY_2.public), dummyCommand(DUMMY_KEY_1.public))
val componentGroups = listOf( val componentGroups = listOf(
inputGroup, inputGroup,
outputGroup, outputGroup,
@ -409,7 +409,7 @@ class CompatibleTransactionTests {
val ftxConstructor = ::FilteredTransaction val ftxConstructor = ::FilteredTransaction
// 1st and 3rd commands require a signature from KEY_1. // 1st and 3rd commands require a signature from KEY_1.
val twoCommandsforKey1 = listOf(dummyCommand(DUMMY_KEY_1.public, DUMMY_KEY_2.public), dummyCommand(DUMMY_KEY_2.public), dummyCommand(DUMMY_KEY_1.public)) val twoCommandsforKey1 = listOf(dummyCommand(DUMMY_KEY_1.public, DUMMY_KEY_2.public), dummyCommand(DUMMY_KEY_2.public), dummyCommand(DUMMY_KEY_1.public))
val componentGroups = listOf( val componentGroups = listOf(
inputGroup, inputGroup,
outputGroup, outputGroup,

View File

@ -8,8 +8,8 @@ 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.node.services.api.IdentityServiceInternal import net.corda.node.services.api.IdentityServiceInternal
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import org.junit.Before import org.junit.Before

View File

@ -11,7 +11,9 @@ import net.corda.finance.DOLLARS
import net.corda.finance.`issued by` import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.node.services.api.IdentityServiceInternal import net.corda.node.services.api.IdentityServiceInternal
import net.corda.testing.* import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger import net.corda.testing.node.ledger

View File

@ -4,8 +4,8 @@ import net.corda.core.contracts.*
import net.corda.core.crypto.* import net.corda.core.crypto.*
import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.CompositeKey
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.testing.*
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -7,7 +7,7 @@ import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.nodeapi.internal.serialization.KRYO_CHECKPOINT_CONTEXT import net.corda.nodeapi.internal.serialization.KRYO_CHECKPOINT_CONTEXT
import net.corda.nodeapi.internal.serialization.KRYO_P2P_CONTEXT import net.corda.nodeapi.internal.serialization.KRYO_P2P_CONTEXT
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -7,7 +7,7 @@ import com.google.common.collect.testing.features.CollectionSize
import junit.framework.TestSuite import junit.framework.TestSuite
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
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.Rule import org.junit.Rule

View File

@ -5,48 +5,57 @@ dependencies {
compile rootProject compile rootProject
} }
def internalPackagePrefixes(sourceDirs) {
def prefixes = []
// Kotlin allows packages to deviate from the directory structure, but let's assume they don't:
sourceDirs.collect { sourceDir ->
sourceDir.traverse(type: groovy.io.FileType.DIRECTORIES) {
if (it.name == 'internal') {
prefixes.add sourceDir.toPath().relativize(it.toPath()).toString().replace(File.separator, '.')
}
}
}
prefixes
}
ext { ext {
// TODO: Add '../client/jfx/src/main/kotlin' and '../client/mock/src/main/kotlin' if we decide to make them into public API // TODO: Add '../client/jfx/src/main/kotlin' and '../client/mock/src/main/kotlin' if we decide to make them into public API
dokkaSourceDirs = files('../core/src/main/kotlin', '../client/rpc/src/main/kotlin', '../finance/src/main/kotlin', '../client/jackson/src/main/kotlin', dokkaSourceDirs = files('../core/src/main/kotlin', '../client/rpc/src/main/kotlin', '../finance/src/main/kotlin', '../client/jackson/src/main/kotlin',
'../testing/test-utils/src/main/kotlin', '../testing/node-driver/src/main/kotlin') '../testing/test-utils/src/main/kotlin', '../testing/node-driver/src/main/kotlin')
internalPackagePrefixes = internalPackagePrefixes(dokkaSourceDirs)
} }
dokka { dokka {
moduleName = 'corda'
outputDirectory = file("${rootProject.rootDir}/docs/build/html/api/kotlin") outputDirectory = file("${rootProject.rootDir}/docs/build/html/api/kotlin")
processConfigurations = ['compile']
sourceDirs = dokkaSourceDirs
includes = ['packages.md']
jdkVersion = 8
externalDocumentationLink {
url = new URL("http://fasterxml.github.io/jackson-core/javadoc/2.8/")
}
externalDocumentationLink {
url = new URL("https://docs.oracle.com/javafx/2/api/")
}
externalDocumentationLink {
url = new URL("http://www.bouncycastle.org/docs/docs1.5on/")
}
} }
task dokkaJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) { task dokkaJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) {
moduleName = 'corda'
outputFormat = "javadoc" outputFormat = "javadoc"
outputDirectory = file("${rootProject.rootDir}/docs/build/html/api/javadoc") outputDirectory = file("${rootProject.rootDir}/docs/build/html/api/javadoc")
processConfigurations = ['compile'] }
sourceDirs = dokkaSourceDirs
includes = ['packages.md']
jdkVersion = 8
externalDocumentationLink { [dokka, dokkaJavadoc].collect {
url = new URL("http://fasterxml.github.io/jackson-core/javadoc/2.8/") it.configure {
} moduleName = 'corda'
externalDocumentationLink { processConfigurations = ['compile']
url = new URL("https://docs.oracle.com/javafx/2/api/") sourceDirs = dokkaSourceDirs
} includes = ['packages.md']
externalDocumentationLink { jdkVersion = 8
url = new URL("http://www.bouncycastle.org/docs/docs1.5on/") externalDocumentationLink {
url = new URL("http://fasterxml.github.io/jackson-core/javadoc/2.8/")
}
externalDocumentationLink {
url = new URL("https://docs.oracle.com/javafx/2/api/")
}
externalDocumentationLink {
url = new URL("http://www.bouncycastle.org/docs/docs1.5on/")
}
internalPackagePrefixes.collect { packagePrefix ->
packageOptions {
prefix = packagePrefix
suppress = true
}
}
} }
} }

View File

@ -23,7 +23,7 @@ is complete.
# Package net.corda.core.contracts # Package net.corda.core.contracts
This package contains the base data types for smarts contracts implemented in Corda. To implement a new contract start This package contains the base data types for smarts contracts implemented in Corda. To implement a new contract start
with [Contract], or see the examples in [net.corda.finance.contracts]. with [Contract], or see the examples in `net.corda.finance.contracts`.
Corda smart contracts are a combination of state held on the distributed ledger, and verification logic which defines Corda smart contracts are a combination of state held on the distributed ledger, and verification logic which defines
which transformations of state are valid. which transformations of state are valid.

View File

@ -1,67 +0,0 @@
CLI vs IDE
==========
We have tried to make every example, tutorial and sample usable via both the command line and the IntelliJ IDE.
Most developers will find writing, editing and debugging code more easy with tools such as an IDE. But when a production node
is deployed, it will be controlled via the command line - no organisation allows their systems to be running via
a developer environment.
IDE - IntelliJ
--------------
IntelliJ (the preferred IDE for Corda) integrates well with gradle (Corda's default build, deployment and CLI tool).
IntelliJ understands gradle tasks and dependencies, automatically loading them in the background when a project is
first opened or the gradle project changes. Occasionally, however, you may need to refresh the gradle project manually
- but this is hinted to you by the IDE. It's a good idea to do this before carrying on with other work (and in fact you
may find it is essential to pick up new libraries, etc.).
There are some great resources about how to get started using IntelliJ. As opposed to trying to repeat them here, we advise
you to go to the `IntelliJ docs here <https://www.jetbrains.com/idea/documentation/>`_.
Command Line
------------
Windows vs Mac / Unix
*********************
Due to the nature of their respective command interfaces, gradle is typically ran in windows with the command ``gradle.bat``
(or ``gradlew.bat`` if using the wrapper) and in Mac / Unix environments it is ran via ``./gradlew``. For brevity, the
simple windows syntax ``gradle`` is used for the majority of the documentation.
As well as including the most significant run and build configurations in the IDE, we also provide gradle tasks to build, install
and run significant parts of Corda demos and tools. Gradle is highly extensible and we use it for downloading required resources,
building components, installing those built components into shared areas, configuring the scripts that run nodes, starting
up demonstration API calls amongst other things. It is exceptionally good at deriving dependency maps and therefore performing
the preceding tasks required in order to do the requested task. However, when confusing build errors manifest, then sometimes
a ``gradle clean`` may be required in order to clear out any build areas that have an inconsistent state. The total build time
from downloading / cloning the repo to a complete build should be only a few minutes, obviously slightly longer if the
unit tests are run.
Frequently Used Gradle Tasks
****************************
Note that the list of tasks can be ran for any gradle project can be displayed by running the task ``tasks``. Also, note that
gradle is hierarchical and therefore tasks in child directories can be run using a colon separator. For example, if you want to run
the sample attachment demo run configuration ``runSender``, you would use the command ``gradle samples:attachment-demo:runSender``
The most frequent gradle tasks you will probably be running are ``build`` and ``install``. The ``build`` command also executes the
unit tests as well. If you want to build without this level of verification, then use the ``assemble`` command - but we do
not recommend this. After running build, the ``install`` tasks copies over the built jars into the local maven repository
which will then make these available for either the sample code or use with the CorDapp template.
Debugging
---------
Tasks and processes that are run directly via the IDE (including via the usage of the ``driver`` DSL) can be remotely debugged.
We do not have java debugging currently enabled in the ``runnodes`` scripts generated by a process we refer to as 'cordformation'
but we will be implementing that shortly.
Via the IDE
***********
To debug: From the IDE, configure the debug connectivity option by the "Edit Configurations" and choosing "+" and then "Remote".
The debug port start at 5005 and increments for each additional node that starts, the order given by the list in the main
driver configuration (which is primarily listed in the ``main`` function of ``Main.kt`` for each sample. Look for the string
``Listening for transport dt_socket at address:5xxx`` in the log output to determine the exact port for that node. If the log
messages are mixed from several nodes to the same console, then (as earlier stated), the port numbers increment in the order
they are listed in the driver DSL configuration.

72
docs/source/aws-vm.rst Normal file
View File

@ -0,0 +1,72 @@
Building a Corda VM from the AWS Marketplace
============================================
To help you design, build and test applications on Corda, called CorDapps, a Corda network AMI can be deployed from the `AWS Marketplace <https://aws.amazon.com/marketplace/pp/B077PG9SP5>`_. Instructions on running Corda nodes can be found `here <https://docs.corda.net/deploying-a-node.html>`_.
This Corda network offering builds a pre-configured network of Corda nodes as Ubuntu virtual machines (VM). The network consists of a Notary node and three Corda nodes using version 1 of Corda. The following guide will also show you how to load one of four `Corda Sample apps <https://www.corda.net/samples>`_ which demonstrates the basic principles of Corda. When you are ready to go further with developing on Corda and start making contributions to the project head over to the `Corda.net <https://www.corda.net/>`_.
Pre-requisites
--------------
* Ensure you have a registered AWS account which can create virtual machines under your subscription(s) and you are logged on to the `AWS portal <https://console.aws.amazon.com>`_
* It is recommended you generate a private-public SSH key pair (see `here <https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2/>`_)
Deploying a Corda Network
---------------------------
Browse to the `AWS Marketplace <https://aws.amazon.com/marketplace>`_ and search for Corda.
Follow the instructions to deploy the AMI to an instance of EC2 which is in a region near to your location.
Build and Run a Sample CorDapp
------------------------------
Once the instance is running ssh into the instance using your keypair
.. sourcecode:: shell
cd ~/dev
There are 4 sample apps available by default
.. sourcecode:: shell
ubuntu@ip-xxx-xxx-xxx-xxx:~/dev$ ls -la
total 24
drwxrwxr-x 6 ubuntu ubuntu 4096 Nov 13 21:48 .
drwxr-xr-x 8 ubuntu ubuntu 4096 Nov 21 16:34 ..
drwxrwxr-x 11 ubuntu ubuntu 4096 Oct 31 19:02 cordapp-example
drwxrwxr-x 9 ubuntu ubuntu 4096 Nov 13 21:48 obligation-cordapp
drwxrwxr-x 11 ubuntu ubuntu 4096 Nov 13 21:48 oracle-example
drwxrwxr-x 8 ubuntu ubuntu 4096 Nov 13 21:48 yo-cordapp
cd into the Corda sample you would like to run. For example:
.. sourcecode:: shell
cd cordapp-example/
Follow instructions for the specific sample at https://www.corda.net/samples to build and run the Corda sample
For example: with cordapp-example (IOU app) the following commands would be run:
.. sourcecode:: shell
./gradlew deployNodes
./kotlin-source/build/nodes/runnodes
Then start the Corda webserver
.. sourcecode:: shell
find ~/dev/cordapp-example/kotlin-source/ -name corda-webserver.jar -execdir sh -c 'java -jar {} &' \;
You can now interact with your running CorDapp. See the instructions `here <https://docs.corda.net/tutorial-cordapp.html#via-http>`_
Next Steps
----------
Now you have built a Corda network and used a basic Corda Cordapp do go and visit the `dedicated Corda website <https://www.corda.net>`_
Additional support is available on `Stack Overflow <https://stackoverflow.com/questions/tagged/corda>`_ and the `Corda Slack channel <https://slack.corda.net/>`_.
You can build and run any other `Corda samples <https://www.corda.net/samples>`_ or your own custom CorDapp here.
Or to join the growing Corda community and get straight into the Corda open source codebase, head over to the `Github Corda repo <https://www.github.com/corda>`_

View File

@ -11,6 +11,7 @@ CorDapps
cordapp-build-systems cordapp-build-systems
building-against-master building-against-master
corda-api corda-api
secure-coding-guidelines
flow-cookbook flow-cookbook
cheat-sheet cheat-sheet
building-a-cordapp-samples building-a-cordapp-samples

View File

@ -1,20 +1,19 @@
Building against Master Building against Master
======================= =======================
When developing a CorDapp, it is advisable to use the most recent Corda Milestone release, which has been extensively It is advisable to develop CorDapps against the most recent Corda stable release. However you may need to build
tested. However, if you need to use a very recent feature of the codebase, you may need to work against the unstable against the unstable Master branch if you are using a very recent feature, or are testing a PR on the main codebase.
Master branch.
To work against the Master branch, proceed as follows: To work against the Master branch, proceed as follows:
* Open a terminal window in the folder where you cloned the Corda repository 1. Open a terminal window in the folder where you cloned the Corda repository
(available `here <https://github.com/corda/corda>`_) (available `here <https://github.com/corda/corda>`_)
* Use the following command to check out the latest master branch: 2. Use the following command to check out the latest master branch:
``git fetch; git checkout master`` ``git checkout master; git pull``
* Publish Corda to your local Maven repository using the following commands: 3. Publish Corda to your local Maven repository using the following commands:
* Unix/Mac OSX: ``./gradlew install`` * Unix/Mac OSX: ``./gradlew install``
* Windows: ``gradlew.bat install`` * Windows: ``gradlew.bat install``
@ -24,11 +23,14 @@ To work against the Master branch, proceed as follows:
* ``~/.m2/repository`` on Unix/Mac OS X * ``~/.m2/repository`` on Unix/Mac OS X
* ``%HOMEPATH%\.m2`` on Windows * ``%HOMEPATH%\.m2`` on Windows
This step is not necessary when using a Milestone releases, as the Milestone releases are published online This step is not necessary when using a stable releases, as the stable releases are published online
.. warning:: If you do modify your local Corda repository after having published it to Maven local, then you must .. warning:: If you do modify your local Corda repository after having published it to Maven local, then you must
re-publish it to Maven local for the local installation to reflect the changes you have made. re-publish it to Maven local for the local installation to reflect the changes you have made.
.. warning:: As the Corda repository evolves on a daily basis, two clones of the Master branch at different points in .. warning:: As the Corda repository evolves on a daily basis, two clones of the Master branch at different points in
time may differ. If you are using a Master release and need help debugging an error, then please let us know the time may differ. If you are using a Master release and need help debugging an error, then please let us know the
**commit** you are working from. This will help us ascertain the issue. **commit** you are working from. This will help us ascertain the issue.
4. Update the ``ext.corda_release_version`` property in your CorDapp's root ``build.gradle`` file to match the version
here: https://github.com/corda/corda/blob/master/build.gradle#L7

View File

@ -6,6 +6,20 @@ from previous releases. Please refer to :doc:`upgrade-notes` for detailed instru
UNRELEASED UNRELEASED
---------- ----------
* Separated our pre-existing Artemis broker into an RPC broker and a P2P broker.
* Refactored ``NodeConfiguration`` to expose ``NodeRpcOptions`` (using top-level "rpcAddress" property still works with warning).
* Modified ``CordaRPCClient`` constructor to take a ``SSLConfiguration?`` additional parameter, defaulted to ``null``.
* Introduced ``CertificateChainCheckPolicy.UsernameMustMatchCommonName`` sub-type, allowing customers to optionally enforce username == CN condition on RPC SSL certificates.
* Modified ``DriverDSL`` and sub-types to allow specifying RPC settings for the Node.
* Modified the ``DriverDSL`` to start Cordformation nodes allowing automatic generation of "rpcSettings.adminAddress" in case "rcpSettings.useSsl" is ``false`` (the default).
* Introduced ``UnsafeCertificatesFactory`` allowing programmatic generation of X509 certificates for test purposes.
* JPA Mapping annotations for States extending ``CommonSchemaV1.LinearState`` and ``CommonSchemaV1.FungibleState`` on the * JPA Mapping annotations for States extending ``CommonSchemaV1.LinearState`` and ``CommonSchemaV1.FungibleState`` on the
`participants` collection need to be moved to the actual class. This allows to properly specify the unique table name per a collection. `participants` collection need to be moved to the actual class. This allows to properly specify the unique table name per a collection.
See: DummyDealStateSchemaV1.PersistentDummyDealState See: DummyDealStateSchemaV1.PersistentDummyDealState
@ -168,6 +182,9 @@ R3 Corda 3.0 Developer Preview
However, assuming a clean reset of the artemis data and that the nodes are consistent versions, However, assuming a clean reset of the artemis data and that the nodes are consistent versions,
data persisted via the AMQP serializer will be forward compatible. data persisted via the AMQP serializer will be forward compatible.
* The ability for CordaServices to register callbacks so they can be notified of shutdown and clean up resource such as
open ports.
* Enterprise Corda only: Compatibility with SQL Server 2017 and SQL Azure databases. * Enterprise Corda only: Compatibility with SQL Server 2017 and SQL Azure databases.
* Enterprise Corda only: node configuration property ``database.schema`` and documented existing database properties. * Enterprise Corda only: node configuration property ``database.schema`` and documented existing database properties.

View File

@ -249,6 +249,11 @@ Wire protocol
------------- -------------
The client RPC wire protocol is defined and documented in ``net/corda/client/rpc/RPCApi.kt``. The client RPC wire protocol is defined and documented in ``net/corda/client/rpc/RPCApi.kt``.
Wire security
-------------
``CordaRPCClient`` has an optional constructor parameter of type ``SSLConfiguration``, defaulted to ``null``, which allows
communication with the node using SSL. Default ``null`` value means no SSL used in the context of RPC.
Whitelisting classes with the Corda node Whitelisting classes with the Corda node
---------------------------------------- ----------------------------------------
CorDapps must whitelist any classes used over RPC with Corda's serialization framework, unless they are whitelisted by CorDapps must whitelist any classes used over RPC with Corda's serialization framework, unless they are whitelisted by

View File

@ -0,0 +1,64 @@
Contributing
============
Corda is an open-source project and we welcome contributions. This guide explains how to contribute back to Corda.
.. contents::
Identifying an area to contribute
---------------------------------
There are several ways to identify an area where you can contribute to Corda:
* Browse issues labelled as ``HelpWanted`` on the
`Corda JIRA board <https://r3-cev.atlassian.net/issues/?jql=labels%20%3D%20HelpWanted>`_
* Any issue with a ``HelpWanted`` label is considered ideal for open-source contributions
* If there is a feature you would like to add and there isn't a corresponding issue labelled as ``HelpWanted``, that
doesn't mean your contribution isn't welcome. Please reach out on the Corda Slack channel (see below) to clarify
* Check the `Corda GitHub issues <https://github.com/corda/corda/issues>`_
* It's always worth checking in the Corda Slack channel (see below) whether a given issue is a good target for your
contribution. Someone else may already be working on it, or it may be blocked by an on-going piece of work
* Ask in the `Corda Slack channel <http://slack.corda.net/>`_
Making the required changes
---------------------------
1. Create a fork of the master branch of the `Corda repo <https://github.com/corda/corda>`_
2. Clone the fork to your local machine
3. Make the changes, in accordance with the :doc:`code style guide </codestyle>`
Testing the changes
-------------------
Running the tests
^^^^^^^^^^^^^^^^^
Your changes must pass the tests described :doc:`here </testing>`.
Building against the master branch
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You may also want to test your changes against a CorDapp defined outside of the Corda repo. To do so, please follow the
instructions :doc:`here </building-against-master>`.
Merging the changes back into Corda
-----------------------------------
1. Create a pull request from your fork to the master branch of the Corda repo
2. Complete the pull-request checklist in the comments box:
* State that you have run the tests
* State that you have included JavaDocs for any new public APIs
* State that you have included the change in the :doc:`changelog </changelog>` and
:doc:`release notes </release-notes>` where applicable
* State that you are in agreement with the terms of
`CONTRIBUTING.md <https://github.com/corda/corda/blob/master/CONTRIBUTING.md>`_
3. Request a review from a member of the Corda platform team via the `Corda Slack channel <http://slack.corda.net/>`_
4. Wait for your PR to pass all four types of continuous integration tests (integration, API stability, build and unit)
* Currently, external contributors cannot see the output of these tests. If your PR fails a test that passed
locally, ask the reviewer for further details
5. Once a reviewer has approved the PR and the tests have passed, squash-and-merge the PR as a single commit

View File

@ -47,6 +47,12 @@ The following modules have a stable API we commit not to break in following rele
* **Core (net.corda.core)**: core Corda libraries such as crypto functions, types for Corda's building blocks: states, contracts, transactions, attachments, etc. and some interfaces for nodes and protocols * **Core (net.corda.core)**: core Corda libraries such as crypto functions, types for Corda's building blocks: states, contracts, transactions, attachments, etc. and some interfaces for nodes and protocols
* **Client RPC (net.corda.client.rpc)**: client RPC * **Client RPC (net.corda.client.rpc)**: client RPC
* **Client Jackson (net.corda.client.jackson)**: JSON support for client applications * **Client Jackson (net.corda.client.jackson)**: JSON support for client applications
* **Test Utils (net.corda.testing.core)**: generic test utilities
* **Test Node Driver (net.corda.testing.node, net.corda.testing.driver)**: test utilities to run nodes programmatically
* **Http Test Utils (net.corda.testing.http)**: a small set of utilities for making HttpCalls, aimed at demos and tests.
* **DSL Test Utils (net.corda.testing.dsl)**: a simple DSL for building pseudo-transactions (not the same as the wire protocol) for testing purposes.
* **Dummy Contracts (net.corda.testing.contracts)**: dummy state and contracts for testing purposes
* **Mock Services (net.corda.testing.services)**: mock service implementations for testing purposes
Corda incubating modules Corda incubating modules
------------------------ ------------------------
@ -54,9 +60,7 @@ Corda incubating modules
The following modules don't yet have a completely stable API, but we will do our best to minimise disruption to The following modules don't yet have a completely stable API, but we will do our best to minimise disruption to
developers using them until we are able to graduate them into the public API: developers using them until we are able to graduate them into the public API:
* **net.corda.node.driver**: test utilities to run nodes programmatically
* **net.corda.confidential.identities**: experimental support for confidential identities on the ledger * **net.corda.confidential.identities**: experimental support for confidential identities on the ledger
* **net.corda.node.test.utils**: generic test utilities
* **net.corda.finance**: a range of elementary contracts (and associated schemas) and protocols, such as abstract fungible assets, cash, obligation and commercial paper * **net.corda.finance**: a range of elementary contracts (and associated schemas) and protocols, such as abstract fungible assets, cash, obligation and commercial paper
* **net.corda.client.jfx**: support for Java FX UI * **net.corda.client.jfx**: support for Java FX UI
* **net.corda.client.mock**: client mock utilities * **net.corda.client.mock**: client mock utilities

View File

@ -38,7 +38,12 @@ Simple Notary configuration file.
keyStorePassword : "cordacadevpass" keyStorePassword : "cordacadevpass"
trustStorePassword : "trustpass" trustStorePassword : "trustpass"
p2pAddress : "localhost:12345" p2pAddress : "localhost:12345"
rpcAddress : "localhost:12346" rpcSettings = {
useSsl = false
standAloneBroker = false
address : "my-corda-node:10003"
adminAddress : "my-corda-node:10004"
}
webAddress : "localhost:12347" webAddress : "localhost:12347"
notary : { notary : {
validating : false validating : false
@ -94,7 +99,21 @@ path to the node's base directory.
here must be externally accessible when running nodes across a cluster of machines. If the provided host is unreachable, here must be externally accessible when running nodes across a cluster of machines. If the provided host is unreachable,
the node will try to auto-discover its public one. the node will try to auto-discover its public one.
:rpcAddress: The address of the RPC system on which RPC requests can be made to the node. If not provided then the node will run without RPC. :rpcAddress: The address of the RPC system on which RPC requests can be made to the node. If not provided then the node will run without RPC. This is now deprecated in favour of the ``rpcSettings`` block.
:rpcSettings: Options for the RPC server.
:useSsl: (optional) boolean, indicates whether the node should require clients to use SSL for RPC connections, defaulted to ``false``.
:standAloneBroker: (optional) boolean, indicates whether the node will connect to a standalone broker for RPC, defaulted to ``false``.
:address: (optional) host and port for the RPC server binding, if any.
:adminAddress: (optional) host and port for the RPC admin binding (only required when ``useSsl`` is ``false``, because the node connects to Artemis using SSL to ensure admin privileges are not accessible outside the node).
:ssl: (optional) SSL settings for the RPC server.
:keyStorePassword: password for the key store.
:trustStorePassword: password for the trust store.
:certificatesDirectory: directory in which the stores will be searched, unless absolute paths are provided.
:sslKeystore: absolute path to the ssl key store, defaulted to ``certificatesDirectory / "sslkeystore.jks"``.
:trustStoreFile: absolute path to the trust store, defaulted to ``certificatesDirectory / "truststore.jks"``.
:security: Contains various nested fields controlling user authentication/authorization, in particular for RPC accesses. See :security: Contains various nested fields controlling user authentication/authorization, in particular for RPC accesses. See
:doc:`clientrpc` for details. :doc:`clientrpc` for details.
@ -192,6 +211,15 @@ path to the node's base directory.
:useAMQPBridges: Optionally can be set to ``false`` to use Artemis CORE Bridges for peer-to-peer communications. :useAMQPBridges: Optionally can be set to ``false`` to use Artemis CORE Bridges for peer-to-peer communications.
Otherwise, defaults to ``true`` and the AMQP 1.0 protocol will be used for message transfer between nodes. Otherwise, defaults to ``true`` and the AMQP 1.0 protocol will be used for message transfer between nodes.
:transactionCacheSizeMegaBytes: Optionally specify how much memory should be used for caching of ledger transactions in memory.
Otherwise defaults to 8MB plus 5% of all heap memory above 300MB.
:attachmentContentCacheSizeMegaBytes: Optionally specify how much memory should be used to cache attachment contents in memory.
Otherwise defaults to 10MB
:attachmentCacheBound: Optionally specify how many attachments should be cached locally. Note that this includes only the key and
metadata, the content is cached separately and can be loaded lazily. Defaults to 1024.
:graphiteOptions: Optionally export metrics to a graphite server. When specified, the node will push out all JMX :graphiteOptions: Optionally export metrics to a graphite server. When specified, the node will push out all JMX
metrics to the specified Graphite server at regular intervals. metrics to the specified Graphite server at regular intervals.

View File

@ -13,7 +13,7 @@ import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.node.services.Permissions.Companion.startFlow import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.* import net.corda.testing.core.*
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 net.corda.testing.internal.IntegrationTest import net.corda.testing.internal.IntegrationTest

View File

@ -17,7 +17,7 @@ import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.node.services.Permissions.Companion.startFlow import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import org.graphstream.graph.Edge import org.graphstream.graph.Edge

View File

@ -16,7 +16,7 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.unwrap import net.corda.core.utilities.unwrap
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.testing.chooseIdentity import net.corda.testing.core.chooseIdentity
import java.util.* import java.util.*
@CordaSerializable @CordaSerializable

View File

@ -10,7 +10,7 @@ import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.utils.sumCashBy import net.corda.finance.utils.sumCashBy
import net.corda.testing.chooseIdentityAndCert import net.corda.testing.core.chooseIdentityAndCert
import java.time.Instant import java.time.Instant
import java.util.* import java.util.*

View File

@ -8,7 +8,12 @@ dataSourceProperties : {
"dataSource.password" : "" "dataSource.password" : ""
} }
p2pAddress : "my-corda-node:10002" p2pAddress : "my-corda-node:10002"
rpcAddress : "my-corda-node:10003" rpcSettings = {
useSsl = false
standAloneBroker = false
address : "my-corda-node:10003"
adminAddress : "my-corda-node:10004"
}
webAddress : "localhost:10004" webAddress : "localhost:10004"
rpcUsers : [ rpcUsers : [
{ username=user1, password=letmein, permissions=[ StartFlow.net.corda.protocols.CashProtocol ] } { username=user1, password=letmein, permissions=[ StartFlow.net.corda.protocols.CashProtocol ] }

View File

@ -8,7 +8,7 @@ import net.corda.finance.contracts.ICommercialPaperState;
import net.corda.finance.contracts.JavaCommercialPaper; import net.corda.finance.contracts.JavaCommercialPaper;
import net.corda.finance.contracts.asset.Cash; import net.corda.finance.contracts.asset.Cash;
import net.corda.testing.node.MockServices; import net.corda.testing.node.MockServices;
import net.corda.testing.TestIdentity; import net.corda.testing.core.TestIdentity;
import org.junit.Test; import org.junit.Test;
import java.security.PublicKey; import java.security.PublicKey;
@ -22,7 +22,9 @@ import static net.corda.finance.contracts.JavaCommercialPaper.JCP_PROGRAM_ID;
import static net.corda.testing.node.MockServicesKt.makeTestIdentityService; import static net.corda.testing.node.MockServicesKt.makeTestIdentityService;
import static net.corda.testing.node.NodeTestUtils.ledger; import static net.corda.testing.node.NodeTestUtils.ledger;
import static net.corda.testing.node.NodeTestUtils.transaction; import static net.corda.testing.node.NodeTestUtils.transaction;
import static net.corda.testing.TestConstants.*; import static net.corda.testing.core.TestConstants.ALICE_NAME;
import static net.corda.testing.core.TestConstants.BOB_NAME;
import static net.corda.testing.core.TestConstants.TEST_TX_TIME;
public class CommercialPaperTest { public class CommercialPaperTest {
private static final TestIdentity ALICE = new TestIdentity(ALICE_NAME, 70L); private static final TestIdentity ALICE = new TestIdentity(ALICE_NAME, 70L);
@ -30,7 +32,7 @@ public class CommercialPaperTest {
private static final TestIdentity BOB = new TestIdentity(BOB_NAME, 80L); private static final TestIdentity BOB = new TestIdentity(BOB_NAME, 80L);
private static final TestIdentity MEGA_CORP = new TestIdentity(new CordaX500Name("MegaCorp", "London", "GB")); private static final TestIdentity MEGA_CORP = new TestIdentity(new CordaX500Name("MegaCorp", "London", "GB"));
private final byte[] defaultRef = {123}; private final byte[] defaultRef = {123};
private final MockServices ledgerServices = new MockServices(emptyList(), makeTestIdentityService(MEGA_CORP.getIdentity())); private final MockServices ledgerServices = new MockServices(MEGA_CORP);
// DOCSTART 1 // DOCSTART 1
private ICommercialPaperState getPaper() { private ICommercialPaperState getPaper() {

View File

@ -8,7 +8,7 @@ import net.corda.finance.*
import net.corda.finance.contracts.getCashBalances import net.corda.finance.contracts.getCashBalances
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.chooseIdentity import net.corda.testing.core.chooseIdentity
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.junit.After import org.junit.After

View File

@ -1,12 +1,15 @@
package net.corda.docs package net.corda.docs
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.parseAsNodeConfiguration import net.corda.node.services.config.parseAsNodeConfiguration
import net.corda.verifier.Verifier import net.corda.verifier.Verifier
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.nio.file.Paths
import kotlin.reflect.KVisibility
import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.jvm.isAccessible
class ExampleConfigTest { class ExampleConfigTest {
@ -17,14 +20,16 @@ class ExampleConfigTest {
val config = loadConfig(Paths.get(configFileResource.toURI())) val config = loadConfig(Paths.get(configFileResource.toURI()))
// Force the config fields as they are resolved lazily // Force the config fields as they are resolved lazily
config.javaClass.kotlin.declaredMemberProperties.forEach { member -> config.javaClass.kotlin.declaredMemberProperties.forEach { member ->
member.get(config) if (member.visibility == KVisibility.PUBLIC) {
member.get(config)
}
} }
} }
} }
@Test @Test
fun `example node_confs parses fine`() { fun `example node_confs parses fine`() {
readAndCheckConfigurations( readAndCheckConfigurations<NodeConfiguration>(
"example-node.conf", "example-node.conf",
"example-out-of-process-verifier-node.conf", "example-out-of-process-verifier-node.conf",
"example-network-map-node.conf" "example-network-map-node.conf"

View File

@ -8,7 +8,7 @@ import net.corda.finance.*
import net.corda.finance.contracts.getCashBalances import net.corda.finance.contracts.getCashBalances
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.chooseIdentity import net.corda.testing.core.chooseIdentity
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.junit.After import org.junit.After

View File

@ -10,7 +10,8 @@ import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.toFuture import net.corda.core.toFuture
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.api.StartedNodeServices
import net.corda.testing.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.startFlow import net.corda.testing.node.startFlow
import org.junit.After import org.junit.After

View File

@ -14,7 +14,7 @@ import net.corda.finance.contracts.ICommercialPaperState
import net.corda.finance.contracts.asset.CASH import net.corda.finance.contracts.asset.CASH
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.node.services.api.IdentityServiceInternal import net.corda.node.services.api.IdentityServiceInternal
import net.corda.testing.* import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger import net.corda.testing.node.ledger

View File

@ -78,9 +78,9 @@ nodes. Here is an example ``Cordform`` task called ``deployNodes`` that creates
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
directory "./build/nodes" directory "./build/nodes"
networkMap "O=Controller,L=London,C=GB" networkMap "O=NetworkMapAndNotary,L=London,C=GB"
node { node {
name "O=Controller,L=London,C=GB" name "O=NetworkMapAndNotary,L=London,C=GB"
// The notary will offer a validating notary service. // The notary will offer a validating notary service.
notary = [validating : true] notary = [validating : true]
p2pPort 10002 p2pPort 10002
@ -114,7 +114,7 @@ nodes. Here is an example ``Cordform`` task called ``deployNodes`` that creates
Running this task will create three nodes in the ``build/nodes`` folder: Running this task will create three nodes in the ``build/nodes`` folder:
* A ``Controller`` node that: * A ``NetworkMapAndNotary`` node that:
* Serves as the network map * Serves as the network map
* Offers a validating notary service * Offers a validating notary service
@ -123,7 +123,7 @@ Running this task will create three nodes in the ``build/nodes`` folder:
* ``PartyA`` and ``PartyB`` nodes that: * ``PartyA`` and ``PartyB`` nodes that:
* Are pointing at the ``Controller`` as the network map service * Are pointing at the ``NetworkMapAndNotary`` as the network map service
* Are not offering any services * Are not offering any services
* Will have a webserver (since ``webPort`` is defined) * Will have a webserver (since ``webPort`` is defined)
* Are running the ``corda-finance`` CorDapp * Are running the ``corda-finance`` CorDapp

View File

@ -13,7 +13,7 @@ Deploying our CorDapp
--------------------- ---------------------
Let's take a look at the nodes we're going to deploy. Open the project's ``build.gradle`` file and scroll down to the Let's take a look at the nodes we're going to deploy. Open the project's ``build.gradle`` file and scroll down to the
``task deployNodes`` section. This section defines three nodes. There are two standard nodes (``PartyA`` and ``task deployNodes`` section. This section defines three nodes. There are two standard nodes (``PartyA`` and
``PartyB``), plus a special Controller node that is running the network map service and advertises a validating notary ``PartyB``), plus a special network map/notary node that is running the network map service and advertises a validating notary
service. service.
.. code:: bash .. code:: bash
@ -21,7 +21,7 @@ service.
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
directory "./build/nodes" directory "./build/nodes"
node { node {
name "O=Controller,L=London,C=GB" name "O=NetworkMapAndNotary,L=London,C=GB"
notary = [validating : true] notary = [validating : true]
p2pPort 10002 p2pPort 10002
rpcPort 10003 rpcPort 10003
@ -142,7 +142,7 @@ The vaults of PartyA and PartyB should both display the following output:
- "C=GB,L=London,O=PartyA" - "C=GB,L=London,O=PartyA"
- "C=US,L=New York,O=PartyB" - "C=US,L=New York,O=PartyB"
contract: "com.template.contract.IOUContract" contract: "com.template.contract.IOUContract"
notary: "C=GB,L=London,O=Controller,CN=corda.notary.validating" notary: "C=GB,L=London,O=NetworkMapAndNotary,CN=corda.notary.validating"
encumbrance: null encumbrance: null
constraint: constraint:
attachmentId: "F578320232CAB87BB1E919F3E5DB9D81B7346F9D7EA6D9155DC0F7BA8E472552" attachmentId: "F578320232CAB87BB1E919F3E5DB9D81B7346F9D7EA6D9155DC0F7BA8E472552"
@ -157,7 +157,7 @@ The vaults of PartyA and PartyB should both display the following output:
recordedTime: 1506415268.875000000 recordedTime: 1506415268.875000000
consumedTime: null consumedTime: null
status: "UNCONSUMED" status: "UNCONSUMED"
notary: "C=GB,L=London,O=Controller,CN=corda.notary.validating" notary: "C=GB,L=London,O=NetworkMapAndNotary,CN=corda.notary.validating"
lockId: null lockId: null
lockUpdateTime: 1506415269.548000000 lockUpdateTime: 1506415269.548000000
totalStatesAvailable: -1 totalStatesAvailable: -1

View File

@ -1,9 +1,8 @@
Node administration Node administration
=================== ===================
When a node is running, it exposes an RPC interface that lets you monitor it, When a node is running, it exposes an RPC interface that lets you monitor it, upload and download attachments, and so
you can upload and download attachments, access a REST API and so on. A bundled on.
Jetty web server exposes the same interface over HTTP.
Logging Logging
------- -------

View File

@ -4,8 +4,6 @@ Other
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
json
secure-coding-guidelines
corda-repo-layout corda-repo-layout
building-the-docs building-the-docs
codestyle json

View File

@ -6,6 +6,5 @@ Quickstart
getting-set-up getting-set-up
tutorial-cordapp tutorial-cordapp
Sample CorDapps <https://www.corda.net/samples/> Other CorDapps <https://www.corda.net/samples/>
building-against-master Utilities <https://www.corda.net/utilities/>
CLI-vs-IDE

View File

@ -6,5 +6,6 @@ Release process
release-notes release-notes
changelog changelog
contributing
codestyle codestyle
testing testing

View File

@ -8,4 +8,5 @@ Tools
demobench demobench
node-explorer node-explorer
azure-vm azure-vm
aws-vm
loadtesting loadtesting

View File

@ -17,7 +17,7 @@ if:
We will deploy the CorDapp on 4 test nodes: We will deploy the CorDapp on 4 test nodes:
* **Controller**, which hosts a validating notary service * **NetworkMapAndNotary**, which hosts a validating notary service
* **PartyA** * **PartyA**
* **PartyB** * **PartyB**
* **PartyC** * **PartyC**
@ -252,7 +252,7 @@ For each node, the ``runnodes`` script creates a node tab/window:
Fri Jul 07 10:33:47 BST 2017>>> Fri Jul 07 10:33:47 BST 2017>>>
For every node except the controller, the script also creates a webserver terminal tab/window: For every node except the network map/notary, the script also creates a webserver terminal tab/window:
.. sourcecode:: none .. sourcecode:: none
@ -276,7 +276,7 @@ IntelliJ
The node driver defined in ``/src/test/kotlin/com/example/Main.kt`` allows you to specify how many nodes you would like The node driver defined in ``/src/test/kotlin/com/example/Main.kt`` allows you to specify how many nodes you would like
to run and the configuration settings for each node. For the example CorDapp, the driver starts up four nodes to run and the configuration settings for each node. For the example CorDapp, the driver starts up four nodes
and adds an RPC user for all but the "Controller" node (which serves as the notary): and adds an RPC user for all but the network map/notary node:
.. sourcecode:: kotlin .. sourcecode:: kotlin
@ -284,7 +284,7 @@ IntelliJ
// No permissions required as we are not invoking flows. // No permissions required as we are not invoking flows.
val user = User("user1", "test", permissions = setOf()) val user = User("user1", "test", permissions = setOf())
driver(isDebug = true, waitForNodesToFinish = true) { driver(isDebug = true, waitForNodesToFinish = true) {
startNode(getX500Name(O="Controller",L="London",C='GB"), setOf(ServiceInfo(ValidatingNotaryService.type))) startNode(getX500Name(O="NetworkMapAndNotary",L="London",C='GB"), setOf(ServiceInfo(ValidatingNotaryService.type)))
val (nodeA, nodeB, nodeC) = Futures.allAsList( val (nodeA, nodeB, nodeC) = Futures.allAsList(
startNode(getX500Name(O="PartyA",L="London",C="GB"), rpcUsers = listOf(user)), startNode(getX500Name(O="PartyA",L="London",C="GB"), rpcUsers = listOf(user)),
startNode(getX500Name(O="PartyB",L="New York",C="US"), rpcUsers = listOf(user)), startNode(getX500Name(O="PartyB",L="New York",C="US"), rpcUsers = listOf(user)),
@ -475,15 +475,15 @@ The nodes can be split across machines and configured to communicate across the
After deploying the nodes, navigate to the build folder (``kotlin-source/build/nodes``) and move some of the individual After deploying the nodes, navigate to the build folder (``kotlin-source/build/nodes``) and move some of the individual
node folders to a different machine (e.g. using a USB key). It is important that none of the nodes - including the node folders to a different machine (e.g. using a USB key). It is important that none of the nodes - including the
controller node - end up on more than one machine. Each computer should also have a copy of ``runnodes`` and network map/notary node - end up on more than one machine. Each computer should also have a copy of ``runnodes`` and
``runnodes.bat``. ``runnodes.bat``.
For example, you may end up with the following layout: For example, you may end up with the following layout:
* Machine 1: ``controller``, ``nodea``, ``runnodes``, ``runnodes.bat`` * Machine 1: ``NetworkMapAndNotary``, ``PartyA``, ``runnodes``, ``runnodes.bat``
* Machine 2: ``nodeb``, ``nodec``, ``runnodes``, ``runnodes.bat`` * Machine 2: ``PartyB``, ``PartyC``, ``runnodes``, ``runnodes.bat``
You must now edit the configuration file for each node, including the controller. Open each node's config file, You must now edit the configuration file for each node, including the network map/notary. Open each node's config file,
and make the following changes: and make the following changes:
* Change the Artemis messaging address to the machine's IP address (e.g. ``p2pAddress="10.18.0.166:10006"``) * Change the Artemis messaging address to the machine's IP address (e.g. ``p2pAddress="10.18.0.166:10006"``)
@ -504,7 +504,7 @@ Debugging is done via IntelliJ as follows:
// No permissions required as we are not invoking flows. // No permissions required as we are not invoking flows.
val user = User("user1", "test", permissions = setOf()) val user = User("user1", "test", permissions = setOf())
driver(isDebug = true, waitForNodesToFinish = true) { driver(isDebug = true, waitForNodesToFinish = true) {
startNode(getX500Name(O="Controller",L="London",C="GB"), setOf(ServiceInfo(ValidatingNotaryService.type))) startNode(getX500Name(O="NetworkMapAndNotary",L="London",C="GB"), setOf(ServiceInfo(ValidatingNotaryService.type)))
val (nodeA, nodeB, nodeC) = Futures.allAsList( val (nodeA, nodeB, nodeC) = Futures.allAsList(
startNode(getX500Name(O="PartyA",L=London,C=GB"), rpcUsers = listOf(user)), startNode(getX500Name(O="PartyA",L=London,C=GB"), rpcUsers = listOf(user)),
startNode(getX500Name(O="PartyB",L=New York,C=US"), rpcUsers = listOf(user)), startNode(getX500Name(O="PartyB",L=New York,C=US"), rpcUsers = listOf(user)),

View File

@ -140,25 +140,28 @@ Applies to both gradle deployNodes tasks and/or corda node configuration (node.c
notary = [validating : true] notary = [validating : true]
* For existing contract ORM schemas that extend from `CommonSchemaV1.LinearState` or `CommonSchemaV1.FungibleState`, * For existing contract ORM schemas that extend from ``CommonSchemaV1.LinearState`` or ``CommonSchemaV1.FungibleState``,
you will need to explicitly map the `participants` collection to a database table. Previously this mapping was done in the you will need to explicitly map the ``participants`` collection to a database table. Previously this mapping was done
superclass, but that makes it impossible to properly configure the table name. in the superclass, but that makes it impossible to properly configure the table name. The required changes are to:
The required change is to add the ``override var participants: MutableSet<AbstractParty>? = null`` field to your class, and
add JPA mappings. For ex., see this example:
.. sourcecode:: kotlin * Add the ``override var participants: MutableSet<AbstractParty>? = null`` field to your class, and
* Add JPA mappings
@Entity For example:
@Table(name = "cash_states_v2",
indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code")))
class PersistentCashState(
@ElementCollection .. sourcecode:: kotlin
@Column(name = "participants")
@CollectionTable(name="cash_states_v2_participants", joinColumns = arrayOf( @Entity
JoinColumn(name = "output_index", referencedColumnName = "output_index"), @Table(name = "cash_states_v2",
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))) indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code")))
override var participants: MutableSet<AbstractParty>? = null, class PersistentCashState(
@ElementCollection
@Column(name = "participants")
@CollectionTable(name="cash_states_v2_participants", joinColumns = arrayOf(
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")))
override var participants: MutableSet<AbstractParty>? = null,
Testing Testing
^^^^^^^ ^^^^^^^
@ -236,11 +239,13 @@ Contract tests
Flow tests Flow tests
~~~~~~~~~~ ~~~~~~~~~~
* The registration mechanism for CorDapps in ``MockNetwork`` unit tests has changed. * The registration mechanism for CorDapps in ``MockNetwork`` unit tests has changed:
It is now done via the ``cordappPackages`` constructor parameter of MockNetwork. This takes a list of ``String`` * CorDapp registration is now done via the ``cordappPackages`` constructor parameter of MockNetwork.
values which should be the package names of the CorDapps containing the contract verification code you wish to load. This parameter
The ``unsetCordappPackages`` method is now redundant and has been removed. is a list of ``String`` values which should be the
package names of the CorDapps containing the contract verification code you wish to load
*The ``unsetCordappPackages`` method is now redundant and has been removed
* Creation of Notaries in ``MockNetwork`` unit tests has changed. * Creation of Notaries in ``MockNetwork`` unit tests has changed.
@ -395,13 +400,13 @@ Finance
V1.0 to V2.0 V1.0 to V2.0
------------ ------------
You only need to update the ``corda_release_version`` identifier in your project gradle file. The * You need to update the ``corda_release_version`` identifier in your project gradle file. The
corda_gradle_plugins_version should remain at 1.0.0: corda_gradle_plugins_version should remain at 1.0.0:
.. sourcecode:: shell .. sourcecode:: shell
ext.corda_release_version = '2.0.0' ext.corda_release_version = '2.0.0'
ext.corda_gradle_plugins_version = '1.0.0' ext.corda_gradle_plugins_version = '1.0.0'
Public Beta (M12) to V1.0 Public Beta (M12) to V1.0
------------------------- -------------------------
@ -417,143 +422,145 @@ Build
A new test driver module dependency needs to be including in your project: ``corda-node-driver``. To continue using the A new test driver module dependency needs to be including in your project: ``corda-node-driver``. To continue using the
mock network for testing, add the following entry to your gradle build file: mock network for testing, add the following entry to your gradle build file:
.. sourcecode:: shell .. sourcecode:: shell
testCompile "$corda_release_distribution:corda-node-driver:$corda_release_version" testCompile "$corda_release_distribution:corda-node-driver:$corda_release_version"
.. note:: you may only need `testCompile "$corda_release_distribution:corda-test-utils:$corda_release_version"` if not using the Driver DSL. .. note:: You may only need ``testCompile "$corda_release_distribution:corda-test-utils:$corda_release_version"`` if not using the Driver
DSL
Configuration Configuration
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
* ``CordaPluginRegistry`` has been removed. * ``CordaPluginRegistry`` has been removed:
The one remaining configuration item ``customizeSerialisation``, which defined a optional whitelist of types for use in
object serialization, has been replaced with the ``SerializationWhitelist`` interface which should be implemented to * The one remaining configuration item ``customizeSerialisation``, which defined a optional whitelist of types for
define a list of equivalent whitelisted classes. use in object serialization, has been replaced with the ``SerializationWhitelist`` interface which should be
You will need to rename your services resource file to the new class name: implemented to define a list of equivalent whitelisted classes
'resources/META-INF/services/net.corda.core.node.CordaPluginRegistry' becomes 'resources/META-INF/services/net.corda.core.serialization.SerializationWhitelist'
An associated property on ``MockNode`` was renamed from ``testPluginRegistries`` to ``testSerializationWhitelists``. * You will need to rename your services resource file. 'resources/META-INF/services/net.corda.core.node.CordaPluginRegistry'
In general, the ``@CordaSerializable`` annotation is the preferred method for whitelisting as described in :doc:`serialization` becomes 'resources/META-INF/services/net.corda.core.serialization.SerializationWhitelist'
* ``MockNode.testPluginRegistries`` was renamed to ``MockNode.testSerializationWhitelists``
* In general, the ``@CordaSerializable`` annotation is the preferred method for whitelisting, as described in
:doc:`serialization`
Missing imports Missing imports
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
Use the automatic imports feature of IntelliJ to intelligently resolve the new imports. Use IntelliJ's automatic imports feature to intelligently resolve the new imports:
* Missing imports for contract types. * Missing imports for contract types:
* CommercialPaper and Cash are now contained within the ``finance`` module, as are associated helpers functions. For
example:
CommercialPaper and Cash are now contained within the ``finance`` module, as are associated helpers functions. CommercialPaper and Cash are now contained within the ``finance`` module, as are associated helpers functions.
For example: For example:
``import net.corda.contracts.ICommercialPaperState`` becomes ``import net.corda.finance.contracts.ICommercialPaperState`` ``import net.corda.contracts.ICommercialPaperState`` becomes ``import net.corda.finance.contracts.ICommercialPaperState``
``import net.corda.contracts.asset.sumCashBy`` becomes ``import net.corda.finance.utils.sumCashBy`` * ``import net.corda.contracts.asset.sumCashBy`` becomes ``import net.corda.finance.utils.sumCashBy``
``import net.corda.core.contracts.DOLLARS`` becomes ``import net.corda.finance.DOLLARS`` * ``import net.corda.core.contracts.DOLLARS`` becomes ``import net.corda.finance.DOLLARS``
``import net.corda.core.contracts.issued by`` becomes ``import net.corda.finance.issued by`` * ``import net.corda.core.contracts.issued by`` becomes ``import net.corda.finance.issued by``
``import net.corda.contracts.asset.Cash`` becomes ``import net.corda.finance.contracts.asset.Cash`` * ``import net.corda.contracts.asset.Cash`` becomes ``import net.corda.finance.contracts.asset.Cash``
* Missing imports for utility functions. * Missing imports for utility functions:
Many common types and helper methods have been consolidated into ``net.corda.core.utilities`` package. * Many common types and helper methods have been consolidated into ``net.corda.core.utilities`` package. For example:
For example:
``import net.corda.core.crypto.commonName`` becomes ``import net.corda.core.utilities.commonName``
``import net.corda.core.crypto.toBase58String`` becomes ``import net.corda.core.utilities.toBase58String`` * ``import net.corda.core.crypto.commonName`` becomes ``import net.corda.core.utilities.commonName``
``import net.corda.core.getOrThrow`` becomes ``import net.corda.core.utilities.getOrThrow`` * ``import net.corda.core.crypto.toBase58String`` becomes ``import net.corda.core.utilities.toBase58String``
* Missing flow imports. * ``import net.corda.core.getOrThrow`` becomes ``import net.corda.core.utilities.getOrThrow``
In general all reusable library flows are contained within the **core** API `net.corda.core.flows` package. * Missing flow imports:
Financial domain library flows are contained within the **finance** module `net.corda.finance.flows` package.
Other flows that have moved include:
``import net.corda.core.flows.ResolveTransactionsFlow`` becomes ``import net.corda.core.internal.ResolveTransactionsFlow`` * In general, all reusable library flows are contained within the **core** API ``net.corda.core.flows`` package
* Financial domain library flows are contained within the **finance** module ``net.corda.finance.flows`` package
* Other flows that have moved include ``import net.corda.core.flows.ResolveTransactionsFlow``, which becomes
``import net.corda.core.internal.ResolveTransactionsFlow``
Core data structures Core data structures
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
* Missing Contract override. * Missing ``Contract`` override:
The contract interace attribute ``legalContractReference`` has been removed, and replaced by * ``Contract.legalContractReference`` has been removed, and replaced by the optional annotation
the optional annotation ``@LegalProseReference(uri = "<URI>")`` ``@LegalProseReference(uri = "<URI>")``
* Unresolved reference. * Unresolved reference:
Calls to ``AuthenticatedObject`` are replaced by ``CommandWithParties`` * ``AuthenticatedObject`` was renamed to ``CommandWithParties``
* Overrides nothing: ``isRelevant`` in ``LinearState``. * Overrides nothing:
Removed the concept of relevancy from ``LinearState``. A ``ContractState``'s relevance to the vault is now resolved * ``LinearState.isRelevant`` was removed. Whether a node stores a ``LinearState`` in its vault depends on whether the
internally; the vault will process any transaction from a flow which is not derived from transaction resolution verification. node is one of the state's ``participants``
The notion of relevancy is subject to further improvements to enable a developer to control what state the vault thinks
are relevant.
* Calls to ``txBuilder.toLedgerTransaction()`` now requires a serviceHub parameter. * ``txBuilder.toLedgerTransaction`` now requires a ``ServiceHub`` parameter. This is used by the new Contract
Constraints functionality to validate and resolve attachments
Used by the new Contract Constraints functionality to validate and resolve attachments.
Flow framework Flow framework
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
* Flow session deprecations * ``FlowLogic`` communication has been upgraded to use explicit ``FlowSession`` instances to communicate between nodes:
``FlowLogic`` communication has been upgraded to use functions on ``FlowSession`` as the base for communication * ``FlowLogic.send``/``FlowLogic.receive``/``FlowLogic.sendAndReceive`` has been replaced by ``FlowSession.send``/
between nodes. ``FlowSession.receive``/``FlowSession.sendAndReceive``. The replacement functions do not take a destination
parameter, as this is defined implictly by the session used
* Calls to ``send()``, ``receive()`` and ``sendAndReceive()`` on FlowLogic should be replaced with calls
to the function of the same name on ``FlowSession``. Note that the replacement functions do not take in a destination
parameter, as this is defined in the session.
* Initiated flows now take in a ``FlowSession`` instead of ``Party`` in their constructor. If you need to access the * Initiated flows now take in a ``FlowSession`` instead of ``Party`` in their constructor. If you need to access the
counterparty identity, it is in the ``counterparty`` property of the flow session. counterparty identity, it is in the ``counterparty`` property of the flow session
See ``FlowSession`` for step by step instructions on porting existing flows to use the new mechanism.
* ``FinalityFlow`` now returns a single ``SignedTransaction``, instead of a ``List<SignedTransaction>`` * ``FinalityFlow`` now returns a single ``SignedTransaction``, instead of a ``List<SignedTransaction>``
* ``TransactionKeyFlow`` renamed to ``SwapIdentitiesFlow`` * ``TransactionKeyFlow`` was renamed to ``SwapIdentitiesFlow``
Note that ``SwapIdentitiesFlow`` must be imported from the *confidential-identities** package ''net.corda.confidential'' * ``SwapIdentitiesFlow`` must be imported from the *confidential-identities* package ``net.corda.confidential``
Node services (ServiceHub) Node services (ServiceHub)
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
* VaultQueryService: unresolved reference to ``vaultQueryService``. * VaultQueryService: unresolved reference to ``vaultQueryService``.
Replace all references to ``<services>.vaultQueryService`` with ``<services>.vaultService``. * Replace all references to ``<services>.vaultQueryService`` with ``<services>.vaultService``
Previously there were two vault APIs. Now there is a single unified API with the same functions: ``VaultService``.
* ``serviceHub.myInfo.legalIdentity`` no longer exists; use the ``ourIdentity`` property of the flow instead. * Previously there were two vault APIs. Now there is a single unified API with the same functions: ``VaultService``.
``FlowLogic.ourIdentity`` has been introduced as a shortcut for retrieving our identity in a flow * ``FlowLogic.ourIdentity`` has been introduced as a shortcut for retrieving our identity in a flow
* ``getAnyNotary`` is gone - use ``serviceHub.networkMapCache.notaryIdentities[0]`` instead * ``serviceHub.myInfo.legalIdentity`` no longer exists
Note: ongoing work to support multiple notary identities is still in progress. * ``getAnyNotary`` has been removed. Use ``serviceHub.networkMapCache.notaryIdentities[0]`` instead
* ``ServiceHub.networkMapUpdates`` is replaced by ``ServiceHub.networkMapFeed`` * ``ServiceHub.networkMapUpdates`` is replaced by ``ServiceHub.networkMapFeed``
* ``ServiceHub.partyFromX500Name`` is replaced by ``ServiceHub.wellKnownPartyFromX500Name`` * ``ServiceHub.partyFromX500Name`` is replaced by ``ServiceHub.wellKnownPartyFromX500Name``
Note: A "well known" party is one that isn't anonymous and this change was motivated by the confidential identities work.
* A "well known" party is one that isn't anonymous. This change was motivated by the confidential identities work
RPC Client RPC Client
^^^^^^^^^^ ^^^^^^^^^^
* Missing API methods on ``CordaRPCOps`` interface. * Missing API methods on the ``CordaRPCOps`` interface:
* Calls to ``verifiedTransactionsFeed()`` and ``verifiedTransactions()`` have been replaced with: * ``verifiedTransactionsFeed`` has been replaced by ``internalVerifiedTransactionsFeed``
``internalVerifiedTransactionsSnapshot()`` and ``internalVerifiedTransactionsFeed()`` respectively
This is in preparation for the planned integration of Intel SGX™, which will encrypt the transactions feed. * ``verifiedTransactions`` has been replaced by ``internalVerifiedTransactionsSnapshot``
Apps that use this API will not work on encrypted ledgers: you should probably be using the vault query API instead.
* Accessing the ``networkMapCache`` via ``services.nodeInfo().legalIdentities`` returns a list of identities. * Accessing the ``networkMapCache`` via ``services.nodeInfo().legalIdentities`` returns a list of identities.
The first element in the list is the Party object referring to a node's single identity. The first element in the list is the Party object referring to a node's single identity.
This is in preparation for allowing a node to host multiple separate identities in future. * Accessing the ``networkMapCache`` via ``services.nodeInfo().legalIdentities`` returns a list of identities
* This change is in preparation for allowing a node to host multiple separate identities in the future
Testing Testing
^^^^^^^ ^^^^^^^
@ -561,26 +568,22 @@ Testing
Please note that ``Clauses`` have been removed completely as of V1.0. Please note that ``Clauses`` have been removed completely as of V1.0.
We will be revisiting this capability in a future release. We will be revisiting this capability in a future release.
* CorDapps must be explicitly registered in ``MockNetwork`` unit tests. * CorDapps must be explicitly registered in ``MockNetwork`` unit tests:
This is done by calling ``setCordappPackages``, an extension helper function in the ``net.corda.testing`` package, This is done by calling ``setCordappPackages``, an extension helper function in the ``net.corda.testing`` package,
on the first line of your ``@Before`` method. This takes a variable number of ``String`` arguments which should be the on the first line of your ``@Before`` method. This takes a variable number of ``String`` arguments which should be the
package names of the CorDapps containing the contract verification code you wish to load. package names of the CorDapps containing the contract verification code you wish to load.
You should unset CorDapp packages in your ``@After`` method by using ``unsetCordappPackages()`` after ``stopNodes()``. You should unset CorDapp packages in your ``@After`` method by using ``unsetCordappPackages()`` after ``stopNodes()``.
* CorDapps must be explicitly registered in ``DriverDSL`` and ``RPCDriverDSL`` integration tests. * CorDapps must be explicitly registered in ``DriverDSL`` and ``RPCDriverDSL`` integration tests:
Similarly, you must also register package names of the CorDapps containing the contract verification code you wish to load * You must register package names of the CorDapps containing the contract verification code you wish to load using
using the ``extraCordappPackagesToScan: List<String>`` constructor parameter of the driver DSL. the ``extraCordappPackagesToScan: List<String>`` constructor parameter of the driver DSL
Finance Finance
^^^^^^^ ^^^^^^^
* ``FungibleAsset`` interface simplification. * ``FungibleAsset`` interface simplification:
The ``FungibleAsset`` interface has been made simpler. The ``Commands`` grouping interface
that included the ``Move``, ``Issue`` and ``Exit`` interfaces have all been removed, while the ``move`` function has
been renamed to ``withNewOwnerAndAmount`` to be consistent with the ``withNewOwner`` function of the ``OwnableState``.
The following errors may be reported: The following errors may be reported:
@ -595,20 +598,20 @@ Miscellaneous
* ``args[0].parseNetworkHostAndPort()`` becomes ``NetworkHostAndPort.parse(args[0])`` * ``args[0].parseNetworkHostAndPort()`` becomes ``NetworkHostAndPort.parse(args[0])``
* There is no longer a ``NodeInfo.advertisedServices`` property. * There is no longer a ``NodeInfo.advertisedServices`` property
The concept of advertised services has been removed from Corda. This is because it was vaguely defined and real world * The concept of advertised services has been removed from Corda. This is because it was vaguely defined and
apps would not typically select random, unknown counterparties from the network map based on self-declared capabilities. real-world apps would not typically select random, unknown counterparties from the network map based on
We will introduce a replacement for this functionality, business networks, in a future release. self-declared capabilities
* We will introduce a replacement for this functionality, business networks, in a future release
For now, your should retrieve the service by legal name using ``NetworkMapCache.getNodeByLegalName``. * For now, services should be retrieved by legal name using ``NetworkMapCache.getNodeByLegalName``
Gotchas Gotchas
^^^^^^^ ^^^^^^^
* Beware to use the correct identity when issuing cash: * Be sure to use the correct identity when issuing cash:
The 3rd parameter to ``CashIssueFlow`` should be the ** notary ** (not the ** node identity **) * The third parameter to ``CashIssueFlow`` should be the *notary* (and not the *node identity*)
:ref:`From Milestone 13 <changelog_m13>` :ref:`From Milestone 13 <changelog_m13>`
@ -617,67 +620,71 @@ Gotchas
Core data structures Core data structures
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
* ``TransactionBuilder`` changes. * ``TransactionBuilder`` changes:
Use convenience class ``StateAndContract`` instead of ``TransactionBuilder.withItems()`` for passing * Use convenience class ``StateAndContract`` instead of ``TransactionBuilder.withItems`` for passing
around a state and its contract. around a state and its contract.
* Transaction building DSL changes: * Transaction builder DSL changes:
* now need to explicitly pass the ContractClassName into all inputs and outputs. * now need to explicitly pass the ContractClassName into all inputs and outputs.
* ``ContractClassName`` refers to the class containing the “verifier” method. * ``ContractClassName`` refers to the class containing the “verifier” method.
* Contract verify method signature change. * ``ContractClassName`` is the name of the ``Contract`` subclass used to verify the transaction
``override fun verify(tx: TransactionForContract)`` becomes ``override fun verify(tx: LedgerTransaction)`` * Contract verify method signature change:
* No longer need to override Contract ``contract()`` function. * ``override fun verify(tx: TransactionForContract)`` becomes ``override fun verify(tx: LedgerTransaction)``
* You no longer need to override ``ContractState.contract`` function
Node services (ServiceHub) Node services (ServiceHub)
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
* ServiceHub API method changes. * ServiceHub API method changes:
``services.networkMapUpdates().justSnapshot`` becomes ``services.networkMapSnapshot()`` * ``services.networkMapUpdates().justSnapshot`` becomes ``services.networkMapSnapshot()``
Configuration Configuration
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
* No longer need to define ``CordaPluginRegistry`` and configure ``requiredSchemas`` * No longer need to define ``CordaPluginRegistry`` and configure ``requiredSchemas``:
Custom contract schemas are automatically detected at startup time by class path scanning. * Custom contract schemas are automatically detected at startup time by class path scanning
For testing purposes, use the ``SchemaService`` method to register new custom schemas:
eg. ``services.schemaService.registerCustomSchemas(setOf(YoSchemaV1))`` * For testing purposes, use the ``SchemaService`` method to register new custom schemas (e.g.
``services.schemaService.registerCustomSchemas(setOf(YoSchemaV1))``)
Identity Identity
^^^^^^^^ ^^^^^^^^
* Party names are now ``CordaX500Name``, not ``X500Name`` * Party names are now ``CordaX500Name``, not ``X500Name``:
``CordaX500Name`` specifies a predefined set of mandatory (organisation, locality, country) * ``CordaX500Name`` specifies a predefined set of mandatory (organisation, locality, country) and optional fields
and optional fields (commonName, organisationUnit, state) with validation checking. (common name, organisation unit, state) with validation checking
Use new builder CordaX500Name.build(X500Name(target)) or, preferably, explicitly define X500Name parameters using * Use new builder ``CordaX500Name.build(X500Name(target))`` or explicitly define the X500Name parameters using the
``CordaX500Name`` constructor. ``CordaX500Name`` constructors
Testing Testing
^^^^^^^ ^^^^^^^
* MockNetwork Testing. * MockNetwork testing:
Mock nodes in node tests are now of type ``StartedNode<MockNode>``, rather than ``MockNode`` * Mock nodes in node tests are now of type ``StartedNode<MockNode>``, rather than ``MockNode``
MockNetwork now returns a BasketOf(<StartedNode<MockNode>>)
Must call internals on StartedNode to get MockNode:
a = nodes.partyNodes[0].internals
b = nodes.partyNodes[1].internals
* Host and Port change. * ``MockNetwork`` now returns a ``BasketOf(<StartedNode<MockNode>>)``
Use string helper function ``parseNetworkHostAndPort()`` to parse a URL on startup. * You must call internals on ``StartedNode`` to get ``MockNode`` (e.g. ``a = nodes.partyNodes[0].internals``)
eg. ``val hostAndPort = args[0].parseNetworkHostAndPort()``
* The node driver parameters for starting a node have been reordered, and the nodes name needs to be given as an * Host and port changes:
``CordaX500Name``, instead of using ``getX509Name``
* Use string helper function ``parseNetworkHostAndPort`` to parse a URL on startup (e.g.
``val hostAndPort = args[0].parseNetworkHostAndPort()``)
* Node driver parameter changes:
* The node driver parameters for starting a node have been reordered
* The nodes name needs to be given as an ``CordaX500Name``, instead of using ``getX509Name``
:ref:`From Milestone 12 (First Public Beta) <changelog_m12>` :ref:`From Milestone 12 (First Public Beta) <changelog_m12>`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -685,17 +692,17 @@ Testing
Core data structures Core data structures
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
* Transaction building * Transaction building:
You no longer need to specify the type of a ``TransactionBuilder`` as ``TransactionType.General`` * You no longer need to specify the type of a ``TransactionBuilder`` as ``TransactionType.General``
``TransactionType.General.Builder(notary)`` becomes ``TransactionBuilder(notary)`` * ``TransactionType.General.Builder(notary)`` becomes ``TransactionBuilder(notary)``
Build Build
^^^^^ ^^^^^
* Gradle dependency reference changes. * Gradle dependency reference changes:
Module name has changed to include ``corda`` in the artifacts jar name: * Module names have changed to include ``corda`` in the artifacts' JAR names:
.. sourcecode:: shell .. sourcecode:: shell
@ -708,25 +715,32 @@ Build
Node services (ServiceHub) Node services (ServiceHub)
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
* ServiceHub API changes. * ``ServiceHub`` API changes:
``services.networkMapUpdates()`` becomes ``services.networkMapFeed()`` * ``services.networkMapUpdates`` becomes ``services.networkMapFeed``
``services.getCashBalances()`` becomes a helper method within the **finance** module contracts package: ``net.corda.finance.contracts.getCashBalances``
* ``services.getCashBalances`` becomes a helper method in the *finance* module contracts package
(``net.corda.finance.contracts.getCashBalances``)
Finance Finance
^^^^^^^ ^^^^^^^
* Financial asset contracts (Cash, CommercialPaper, Obligations) are now a standalone CorDapp within the **finance** module. * Financial asset contracts (``Cash``, ``CommercialPaper``, ``Obligations``) are now a standalone CorDapp within the
``finance`` module:
Need to import from respective package within ``finance`` module: * You need to import them from their respective packages within the ``finance`` module (e.g.
eg. ``net.corda.finance.contracts.asset.Cash`` ``net.corda.finance.contracts.asset.Cash``)
Likewise, need to import associated asset flows from respective package within ``finance`` module: * You need to import the associated asset flows from their respective packages within ``finance`` module. For
eg. ``net.corda.finance.flows.CashIssueFlow`` example:
``net.corda.finance.flows.CashIssueAndPaymentFlow``
``net.corda.finance.flows.CashExitFlow``
* Moved ``finance`` gradle project files into a ``net.corda.finance`` package namespace. * ``net.corda.finance.flows.CashIssueFlow``
* ``net.corda.finance.flows.CashIssueAndPaymentFlow``
* ``net.corda.finance.flows.CashExitFlow``
This may require adjusting imports of Cash flow references and also of ``StartFlow`` permission in ``gradle.build`` files. This may require adjusting imports of Cash flow references and also of ``StartFlow`` permission in ``gradle.build`` files.
Associated flows (``Cash*Flow``, ``TwoPartyTradeFlow``, ``TwoPartyDealFlow``) must now be imported from this package. Associated flows (``Cash*Flow``, ``TwoPartyTradeFlow``, ``TwoPartyDealFlow``) must now be imported from this package.
* Adjust imports of Cash flow references
* Adjust the ``StartFlow`` permission in ``gradle.build`` files
* Adjust imports of the associated flows (``Cash*Flow``, ``TwoPartyTradeFlow``, ``TwoPartyDealFlow``)

View File

@ -8,7 +8,9 @@ import net.corda.finance.contracts.FixOf
import net.corda.finance.contracts.Frequency import net.corda.finance.contracts.Frequency
import net.corda.finance.contracts.Tenor import net.corda.finance.contracts.Tenor
import net.corda.node.services.api.IdentityServiceInternal import net.corda.node.services.api.IdentityServiceInternal
import net.corda.testing.* import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity
import net.corda.testing.dsl.EnforceVerifyOrFail import net.corda.testing.dsl.EnforceVerifyOrFail
import net.corda.testing.dsl.TransactionDSL import net.corda.testing.dsl.TransactionDSL
import net.corda.testing.dsl.TransactionDSLInterpreter import net.corda.testing.dsl.TransactionDSLInterpreter

View File

@ -2,7 +2,7 @@ package net.corda.finance.contracts.universal
import net.corda.finance.contracts.FixOf import net.corda.finance.contracts.FixOf
import net.corda.finance.contracts.Tenor import net.corda.finance.contracts.Tenor
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Ignore import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -2,7 +2,7 @@ package net.corda.finance.contracts.universal
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.testing.TestIdentity import net.corda.testing.core.TestIdentity
import org.junit.Test import org.junit.Test
import java.util.* import java.util.*
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@ -1,6 +1,6 @@
package net.corda.finance.contracts.universal package net.corda.finance.contracts.universal
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Ignore import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -1,6 +1,6 @@
package net.corda.finance.contracts.universal package net.corda.finance.contracts.universal
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Ignore import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -3,7 +3,7 @@ package net.corda.finance.contracts.universal
import net.corda.finance.contracts.FixOf import net.corda.finance.contracts.FixOf
import net.corda.finance.contracts.Frequency import net.corda.finance.contracts.Frequency
import net.corda.finance.contracts.Tenor import net.corda.finance.contracts.Tenor
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Ignore import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -1,7 +1,7 @@
package net.corda.finance.contracts.universal package net.corda.finance.contracts.universal
import net.corda.finance.contracts.Frequency import net.corda.finance.contracts.Frequency
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.time.Instant import java.time.Instant

View File

@ -2,7 +2,7 @@ package net.corda.finance.contracts.universal
import net.corda.finance.contracts.Frequency import net.corda.finance.contracts.Frequency
import net.corda.finance.contracts.Tenor import net.corda.finance.contracts.Tenor
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Ignore import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

View File

@ -1,6 +1,6 @@
package net.corda.finance.contracts.universal package net.corda.finance.contracts.universal
import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.core.SerializationEnvironmentRule
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.time.Instant import java.time.Instant

View File

@ -4,7 +4,9 @@ import net.corda.core.messaging.startFlow
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.finance.EUR import net.corda.finance.EUR
import net.corda.finance.USD import net.corda.finance.USD
import net.corda.testing.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas import net.corda.testing.internal.IntegrationTestSchemas

View File

@ -37,6 +37,7 @@ object CommercialPaperSchemaV1 : MappedSchema(
var issuancePartyHash: String, var issuancePartyHash: String,
@Column(name = "issuance_ref") @Column(name = "issuance_ref")
@Type(type = "corda-wrapper-binary")
var issuanceRef: ByteArray, var issuanceRef: ByteArray,
@Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE)

View File

@ -5,9 +5,9 @@ import net.corda.core.identity.AnonymousParty;
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.node.services.api.IdentityServiceInternal; import net.corda.node.services.api.IdentityServiceInternal;
import net.corda.testing.DummyCommandData; import net.corda.testing.core.DummyCommandData;
import net.corda.testing.SerializationEnvironmentRule; import net.corda.testing.core.SerializationEnvironmentRule;
import net.corda.testing.TestIdentity; import net.corda.testing.core.TestIdentity;
import net.corda.testing.node.MockServices; import net.corda.testing.node.MockServices;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@ -17,7 +17,7 @@ import static net.corda.finance.Currencies.DOLLARS;
import static net.corda.finance.Currencies.issuedBy; import static net.corda.finance.Currencies.issuedBy;
import static net.corda.testing.node.NodeTestUtils.transaction; import static net.corda.testing.node.NodeTestUtils.transaction;
import static net.corda.testing.internal.InternalTestUtilsKt.rigorousMock; import static net.corda.testing.internal.InternalTestUtilsKt.rigorousMock;
import static net.corda.testing.TestConstants.DUMMY_NOTARY_NAME; import static net.corda.testing.core.TestConstants.DUMMY_NOTARY_NAME;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
/** /**

Some files were not shown because too many files have changed in this diff Show More