Merge remote-tracking branch 'remotes/open/master' into merges/march-6-16-56

# Conflicts:
#	node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt
This commit is contained in:
sollecitom 2018-03-06 16:59:13 +00:00
commit 906dae11ad
12 changed files with 41 additions and 36 deletions

View File

@ -19,3 +19,6 @@ dependencies {
project(it.path) project(it.path)
} }
} }
// Don't create an empty jar. The plugins are now in child projects.
jar.enabled = false

View File

@ -12,7 +12,7 @@ import net.corda.core.utilities.unwrap
object IdentitySyncFlow { object IdentitySyncFlow {
/** /**
* Flow for ensuring that our counter-parties in a transaction have the full certificate paths for *our* * Flow for ensuring that our counterparties in a transaction have the full certificate paths for *our*
* confidential identities used in states present in the transaction. This is intended for use as a sub-flow of * confidential identities used in states present in the transaction. This is intended for use as a sub-flow of
* another flow, typically between transaction assembly and signing. An example of where this is useful is where * another flow, typically between transaction assembly and signing. An example of where this is useful is where
* a recipient of a state wants to know that it is being paid by the correct party, and the owner of the state is a * a recipient of a state wants to know that it is being paid by the correct party, and the owner of the state is a

View File

@ -64,7 +64,7 @@ class SwapIdentitiesFlow(private val otherParty: Party,
throw SwapIdentitiesException("Signature does not match the expected identity ownership assertion.", ex) throw SwapIdentitiesException("Signature does not match the expected identity ownership assertion.", ex)
} }
// Validate then store their identity so that we can prove the key in the transaction is owned by the // Validate then store their identity so that we can prove the key in the transaction is owned by the
// counter-party. // counterparty.
identityService.verifyAndRegisterIdentity(anonymousOtherSide) identityService.verifyAndRegisterIdentity(anonymousOtherSide)
return anonymousOtherSide return anonymousOtherSide
} }

View File

@ -13,7 +13,7 @@ import net.corda.core.utilities.unwrap
import java.security.PublicKey import java.security.PublicKey
/** /**
* The [CollectSignaturesFlow] is used to automate the collection of counter-party signatures for a given transaction. * The [CollectSignaturesFlow] is used to automate the collection of counterparty signatures for a given transaction.
* *
* You would typically use this flow after you have built a transaction with the TransactionBuilder and signed it with * You would typically use this flow after you have built a transaction with the TransactionBuilder and signed it with
* your key pair. If there are additional signatures to collect then they can be collected using this flow. Signatures * your key pair. If there are additional signatures to collect then they can be collected using this flow. Signatures
@ -35,9 +35,9 @@ import java.security.PublicKey
* 2. Any of the required signing parties cannot be found in the [ServiceHub.networkMapCache] of the initiator * 2. Any of the required signing parties cannot be found in the [ServiceHub.networkMapCache] of the initiator
* 3. If the wrong key has been used by a counterparty to sign the transaction * 3. If the wrong key has been used by a counterparty to sign the transaction
* 4. The counterparty rejects the provided transaction * 4. The counterparty rejects the provided transaction
* - The flow will return a [SignedTransaction] with all the counter-party signatures (but not the notary's!) * - The flow will return a [SignedTransaction] with all the counterparty signatures (but not the notary's!)
* - If the provided transaction has already been signed by all counter-parties then this flow simply returns the * - If the provided transaction has already been signed by all counterparties then this flow simply returns the
* provided transaction without contacting any counter-parties * provided transaction without contacting any counterparties
* - Call the [FinalityFlow] with the return value of this flow * - Call the [FinalityFlow] with the return value of this flow
* *
* Example - issuing a multi-lateral agreement which requires N signatures: * Example - issuing a multi-lateral agreement which requires N signatures:
@ -68,13 +68,13 @@ class CollectSignaturesFlow @JvmOverloads constructor(val partiallySignedTx: Sig
@JvmOverloads constructor(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection<FlowSession>, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : this(partiallySignedTx, sessionsToCollectFrom, null, progressTracker) @JvmOverloads constructor(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection<FlowSession>, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : this(partiallySignedTx, sessionsToCollectFrom, null, progressTracker)
companion object { companion object {
object COLLECTING : ProgressTracker.Step("Collecting signatures from counter-parties.") object COLLECTING : ProgressTracker.Step("Collecting signatures from counterparties.")
object VERIFYING : ProgressTracker.Step("Verifying collected signatures.") object VERIFYING : ProgressTracker.Step("Verifying collected signatures.")
@JvmStatic @JvmStatic
fun tracker() = ProgressTracker(COLLECTING, VERIFYING) fun tracker() = ProgressTracker(COLLECTING, VERIFYING)
// TODO: Make the progress tracker adapt to the number of counter-parties to collect from. // TODO: Make the progress tracker adapt to the number of counterparties to collect from.
} }
@ -101,7 +101,7 @@ class CollectSignaturesFlow @JvmOverloads constructor(val partiallySignedTx: Sig
// the FinalityFlow. // the FinalityFlow.
val unsigned = if (notaryKey != null) notSigned - notaryKey else notSigned val unsigned = if (notaryKey != null) notSigned - notaryKey else notSigned
// If the unsigned counter-parties list is empty then we don't need to collect any more signatures here. // If the unsigned counterparties list is empty then we don't need to collect any more signatures here.
if (unsigned.isEmpty()) return partiallySignedTx if (unsigned.isEmpty()) return partiallySignedTx
val partyToKeysMap = groupPublicKeysByWellKnownParty(serviceHub, unsigned) val partyToKeysMap = groupPublicKeysByWellKnownParty(serviceHub, unsigned)
@ -109,7 +109,7 @@ class CollectSignaturesFlow @JvmOverloads constructor(val partiallySignedTx: Sig
require(sessionsToCollectFrom.map { it.counterparty }.toSet() == partyToKeysMap.keys) { require(sessionsToCollectFrom.map { it.counterparty }.toSet() == partyToKeysMap.keys) {
"The Initiator of CollectSignaturesFlow must pass in exactly the sessions required to sign the transaction." "The Initiator of CollectSignaturesFlow must pass in exactly the sessions required to sign the transaction."
} }
// Collect signatures from all counter-parties and append them to the partially signed transaction. // Collect signatures from all counterparties and append them to the partially signed transaction.
val counterpartySignatures = sessionsToCollectFrom.flatMap { session -> val counterpartySignatures = sessionsToCollectFrom.flatMap { session ->
subFlow(CollectSignatureFlow(partiallySignedTx, session, partyToKeysMap[session.counterparty]!!)) subFlow(CollectSignatureFlow(partiallySignedTx, session, partyToKeysMap[session.counterparty]!!))
} }
@ -161,7 +161,7 @@ class CollectSignatureFlow(val partiallySignedTx: SignedTransaction, val session
* *
* 1. Should actually be signed by the [Party] invoking this flow * 1. Should actually be signed by the [Party] invoking this flow
* 2. Is valid as per the contracts referenced in the transaction * 2. Is valid as per the contracts referenced in the transaction
* 3. Has been, at least, signed by the counter-party which created it * 3. Has been, at least, signed by the counterparty which created it
* 4. Conforms to custom checking provided in the [checkTransaction] method of the [SignTransactionFlow] * 4. Conforms to custom checking provided in the [checkTransaction] method of the [SignTransactionFlow]
* *
* Usage: * Usage:
@ -258,7 +258,7 @@ abstract class SignTransactionFlow(val otherSideSession: FlowSession,
/** /**
* The [checkTransaction] method allows the caller of this flow to provide some additional checks over the proposed * The [checkTransaction] method allows the caller of this flow to provide some additional checks over the proposed
* transaction received from the counter-party. For example: * transaction received from the counterparty. For example:
* *
* - Ensuring that the transaction you are receiving is the transaction you *EXPECT* to receive. I.e. is has the * - Ensuring that the transaction you are receiving is the transaction you *EXPECT* to receive. I.e. is has the
* expected type and number of inputs and outputs * expected type and number of inputs and outputs
@ -273,7 +273,7 @@ abstract class SignTransactionFlow(val otherSideSession: FlowSession,
* [IllegalArgumentException], [IllegalStateException] and [AssertionError] will be caught and rethrown as flow * [IllegalArgumentException], [IllegalStateException] and [AssertionError] will be caught and rethrown as flow
* exceptions i.e. the other side will be given information about what exact check failed. * exceptions i.e. the other side will be given information about what exact check failed.
* *
* @param stx a partially signed transaction received from your counter-party. * @param stx a partially signed transaction received from your counterparty.
* @throws FlowException if the proposed transaction fails the checks. * @throws FlowException if the proposed transaction fails the checks.
*/ */
@Suspendable @Suspendable

View File

@ -360,7 +360,7 @@ interface CordaRPCOps : RPCOps {
/** Sets the value of the node's flows draining mode. /** Sets the value of the node's flows draining mode.
* If this mode is [enabled], the node will reject new flows through RPC, ignore scheduled flows, and do not process * If this mode is [enabled], the node will reject new flows through RPC, ignore scheduled flows, and do not process
* initial session messages, meaning that P2P counter-parties will not be able to initiate new flows involving the node. * initial session messages, meaning that P2P counterparties will not be able to initiate new flows involving the node.
* *
* @param enabled whether the flows draining mode will be enabled. * @param enabled whether the flows draining mode will be enabled.
* */ * */

View File

@ -421,7 +421,7 @@ Subflows
Subflows are pieces of reusable flows that may be run by calling ``FlowLogic.subFlow``. There are two broad categories Subflows are pieces of reusable flows that may be run by calling ``FlowLogic.subFlow``. There are two broad categories
of subflows, inlined and initiating ones. The main difference lies in the counter-flow's starting method, initiating of subflows, inlined and initiating ones. The main difference lies in the counter-flow's starting method, initiating
ones initiate counter-flows automatically, while inlined ones expect some parent counter-flow to run the inlined ones initiate counter-flows automatically, while inlined ones expect some parent counter-flow to run the inlined
counter-part. counterpart.
Inlined subflows Inlined subflows
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^

View File

@ -76,14 +76,14 @@ You can see an example of using ``SwapIdentitiesFlow`` in ``TwoPartyDealFlow.kt`
1. Generate a new confidential identity from our well-known identity 1. Generate a new confidential identity from our well-known identity
2. Create a ``CertificateOwnershipAssertion`` object containing the new confidential identity (X500 name, public key) 2. Create a ``CertificateOwnershipAssertion`` object containing the new confidential identity (X500 name, public key)
5. Sign this object with the confidential identity's private key 3. Sign this object with the confidential identity's private key
6. Send the confidential identity and aforementioned signature to counter-parties, while receiving theirs 4. Send the confidential identity and aforementioned signature to counterparties, while receiving theirs
7. Verify the signatures to ensure that identities were generated by the involved set of parties 5. Verify the signatures to ensure that identities were generated by the involved set of parties
8. Verify the confidential identities are owned by the expected well known identities 6. Verify the confidential identities are owned by the expected well known identities
9. Store the confidential identities and return them to the calling flow 7. Store the confidential identities and return them to the calling flow
This ensures not only that the confidential identity X.509 certificates are signed by the correct well-known This ensures not only that the confidential identity X.509 certificates are signed by the correct well-known
identities, but also that the confidential identity private key is held by the counter-party, and that a party cannot identities, but also that the confidential identity private key is held by the counterparty, and that a party cannot
claim ownership of another party's confidential identities. claim ownership of another party's confidential identities.
IdentitySyncFlow IdentitySyncFlow

View File

@ -27,10 +27,10 @@ The flow returns the same transactions, in the same order, with the additional s
CollectSignaturesFlow CollectSignaturesFlow
--------------------- ---------------------
The ``CollectSignaturesFlow`` is used to automate the collection of signatures from the counter-parties to a transaction. The ``CollectSignaturesFlow`` is used to automate the collection of signatures from the counterparties to a transaction.
You use the ``CollectSignaturesFlow`` by passing it a ``SignedTransaction`` which has at least been signed by yourself. You use the ``CollectSignaturesFlow`` by passing it a ``SignedTransaction`` which has at least been signed by yourself.
The flow will handle the resolution of the counter-party identities and request a signature from each counter-party. The flow will handle the resolution of the counterparty identities and request a signature from each counterparty.
Finally, the flow will verify all the signatures and return a ``SignedTransaction`` with all the collected signatures. Finally, the flow will verify all the signatures and return a ``SignedTransaction`` with all the collected signatures.

View File

@ -315,7 +315,7 @@ of the page, and enter the IOU details into the web-form. The IOU must have a po
.. sourcecode:: none .. sourcecode:: none
Counter-party: Select from list Counterparty: Select from list
Value (Int): 5 Value (Int): 5
And click submit. Upon clicking submit, the modal dialogue will close, and the nodes will agree the IOU. And click submit. Upon clicking submit, the modal dialogue will close, and the nodes will agree the IOU.
@ -375,7 +375,7 @@ This will print out the following progress steps:
✅ Verifying contract constraints. ✅ Verifying contract constraints.
✅ Signing transaction with our private key. ✅ Signing transaction with our private key.
✅ Gathering the counterparty's signature. ✅ Gathering the counterparty's signature.
✅ Collecting signatures from counter-parties. ✅ Collecting signatures from counterparties.
✅ Verifying collected signatures. ✅ Verifying collected signatures.
✅ Obtaining notary signature and recording transaction. ✅ Obtaining notary signature and recording transaction.
✅ Requesting signature by notary service ✅ Requesting signature by notary service

View File

@ -31,7 +31,7 @@ interface StartedNode<out N : AbstractNode> {
/** /**
* Use this method to register your initiated flows in your tests. This is automatically done by the node when it * Use this method to register your initiated flows in your tests. This is automatically done by the node when it
* starts up for all [FlowLogic] classes it finds which are annotated with [InitiatedBy]. * starts up for all [FlowLogic] classes it finds which are annotated with [InitiatedBy].
* @return An [Observable] of the initiated flows started by counter-parties. * @return An [Observable] of the initiated flows started by counterparties.
*/ */
fun <T : FlowLogic<*>> registerInitiatedFlow(initiatedFlowClass: Class<T>) = internals.registerInitiatedFlow(smm, initiatedFlowClass) fun <T : FlowLogic<*>> registerInitiatedFlow(initiatedFlowClass: Class<T>) = internals.registerInitiatedFlow(smm, initiatedFlowClass)

View File

@ -177,8 +177,10 @@ data class NodeConfigurationImpl(
override val attachmentCacheBound: Long = NodeConfiguration.defaultAttachmentCacheBound, override val attachmentCacheBound: Long = NodeConfiguration.defaultAttachmentCacheBound,
override val graphiteOptions: GraphiteOptions? = null, override val graphiteOptions: GraphiteOptions? = null,
// do not use or remove (breaks DemoBench together with rejection of unknown configuration keys during parsing) // do not use or remove (breaks DemoBench together with rejection of unknown configuration keys during parsing)
private val h2port: Int = 0 private val h2port: Int = 0,
) : NodeConfiguration { // do not use or remove (used by Capsule)
private val jarDirs: List<String> = emptyList()
) : NodeConfiguration {
companion object { companion object {
private val logger = loggerFor<NodeConfigurationImpl>() private val logger = loggerFor<NodeConfigurationImpl>()
} }

View File

@ -95,7 +95,7 @@ The response should be something like
} }
Now, if we ask the same question of Bank C we will see that it's id matches the id for Bank C as a counter Now, if we ask the same question of Bank C we will see that it's id matches the id for Bank C as a counter
party to Bank A and Bank A will appear as a counter party party to Bank A and Bank A will appear as a counterparty
curl -i -H "Content-Type: application/json" -X GET http://localhost:10011/api/simmvaluationdemo/whoami curl -i -H "Content-Type: application/json" -X GET http://localhost:10011/api/simmvaluationdemo/whoami
@ -104,9 +104,9 @@ party to Bank A and Bank A will appear as a counter party
In what follows, we assume we are Bank A (which is listening on port 10005) In what follows, we assume we are Bank A (which is listening on port 10005)
Notice the id field in the output of the ``whoami`` command. We are going to use the id associated Notice the id field in the output of the ``whoami`` command. We are going to use the id associated
with Bank C, one of our counter parties, to create a trade. The general command for this is: with Bank C, one of our counterparties, to create a trade. The general command for this is:
curl -i -H "Content-Type: application/json" -X PUT -d <<<JSON representation of the trade>>> http://localhost:10005/api/simmvaluationdemo/<<<counter party id>>>/trades curl -i -H "Content-Type: application/json" -X PUT -d <<<JSON representation of the trade>>> http://localhost:10005/api/simmvaluationdemo/<<<counterparty id>>>/trades
where the representation of the trade is where the representation of the trade is
@ -152,7 +152,7 @@ Once executed, the expected response is:
With the trade completed and stored by both parties, the complete list of trades with our counterparty can be seen with the following command With the trade completed and stored by both parties, the complete list of trades with our counterparty can be seen with the following command
curl -X GET http://localhost:10005/api/simmvaluationdemo/<<<counter party id>>>/trades curl -X GET http://localhost:10005/api/simmvaluationdemo/<<<counterparty id>>>/trades
The command for our example, using Bank A, would thus be The command for our example, using Bank A, would thus be
@ -161,7 +161,7 @@ The command for our example, using Bank A, would thus be
whilst a specific trade can be seen with whilst a specific trade can be seen with
curl -X GET http://localhost:10005/api/simmvaluationdemo/<<<counter party id>>>/trades/<<<trade id>>> curl -X GET http://localhost:10005/api/simmvaluationdemo/<<<counterparty id>>>/trades/<<<trade id>>>
If we look at the trade we created above, we assigned it the id "trade1", the complete command in this case would be If we look at the trade we created above, we assigned it the id "trade1", the complete command in this case would be
@ -172,7 +172,7 @@ If we look at the trade we created above, we assigned it the id "trade1", the co
curl -i -H "Content-Type: application/json" \ curl -i -H "Content-Type: application/json" \
-X POST \ -X POST \
-d <<<JSON representation>>> -d <<<JSON representation>>>
http://localhost:10005/api/simmvaluationdemo/<<<counter party id>>>/portfolio/valuations/calculate http://localhost:10005/api/simmvaluationdemo/<<<counterparty id>>>/portfolio/valuations/calculate
Again, the specific command to continue our example would be Again, the specific command to continue our example would be
@ -183,9 +183,9 @@ Again, the specific command to continue our example would be
**Viewing a valuation** **Viewing a valuation**
In the same way we can ask for specific instances of trades with a counter party, we can request details of valuations In the same way we can ask for specific instances of trades with a counterparty, we can request details of valuations
curl -i -H "Content-Type: application/json" -X GET http://localhost:10005/api/simmvaluationdemo/<<<counter party id>>>/portfolio/valuations curl -i -H "Content-Type: application/json" -X GET http://localhost:10005/api/simmvaluationdemo/<<<counterparty id>>>/portfolio/valuations
The specific command for out Bank A example is The specific command for out Bank A example is