mirror of
https://github.com/corda/corda.git
synced 2025-06-15 21:58:17 +00:00
Change CashIssueFlow to use anonymous identity
* Add functions for: * Retrieving nodes via their legal identity * Filtering a set of public keys down to those the node has corresponding private keys for * Modify contract upgrade flows to handle identifying participants after an anomymisation step * Correct terminology: "party who" -> "party which" * Modify CashIssueFlow and CashPaymentFlow to optionally use an anonymous identity for the recipient.
This commit is contained in:
@ -13,7 +13,10 @@ import net.corda.core.flows.InitiatedBy
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.Vault
|
||||
import net.corda.core.node.services.queryBy
|
||||
import net.corda.core.node.services.unconsumedStates
|
||||
import net.corda.core.node.services.vault.QueryCriteria
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.unwrap
|
||||
@ -39,14 +42,15 @@ private fun gatherOurInputs(serviceHub: ServiceHub,
|
||||
amountRequired: Amount<Issued<Currency>>,
|
||||
notary: Party?): Pair<List<StateAndRef<Cash.State>>, Long> {
|
||||
// Collect cash type inputs
|
||||
val cashStates = serviceHub.vaultService.unconsumedStates<Cash.State>()
|
||||
val queryCriteria = QueryCriteria.VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, setOf(Cash.State::class.java))
|
||||
val cashStates = serviceHub.vaultQueryService.queryBy<Cash.State>(queryCriteria).states
|
||||
// extract our identity for convenience
|
||||
val ourIdentity = serviceHub.myInfo.legalIdentity
|
||||
val ourKeys = serviceHub.keyManagementService.keys
|
||||
// Filter down to our own cash states with right currency and issuer
|
||||
val suitableCashStates = cashStates.filter {
|
||||
val state = it.state.data
|
||||
(state.owner == ourIdentity)
|
||||
&& (state.amount.token == amountRequired.token)
|
||||
// TODO: We may want to have the list of our states pre-cached somewhere for performance
|
||||
(state.owner.owningKey in ourKeys) && (state.amount.token == amountRequired.token)
|
||||
}
|
||||
require(!suitableCashStates.isEmpty()) { "Insufficient funds" }
|
||||
var remaining = amountRequired.quantity
|
||||
@ -132,9 +136,6 @@ class ForeignExchangeFlow(val tradeId: String,
|
||||
require(it.inputs.all { it.state.notary == notary }) {
|
||||
"notary of remote states must be same as for our states"
|
||||
}
|
||||
require(it.inputs.all { it.state.data.owner == remoteRequestWithNotary.owner }) {
|
||||
"The inputs are not owned by the correct counterparty"
|
||||
}
|
||||
require(it.inputs.all { it.state.data.amount.token == remoteRequestWithNotary.amount.token }) {
|
||||
"Inputs not of the correct currency"
|
||||
}
|
||||
@ -200,7 +201,7 @@ class ForeignExchangeFlow(val tradeId: String,
|
||||
// We have already validated their response and trust our own data
|
||||
// so we can sign. Note the returned SignedTransaction is still not fully signed
|
||||
// and would not pass full verification yet.
|
||||
return serviceHub.signInitialTransaction(builder)
|
||||
return serviceHub.signInitialTransaction(builder, ourSigners.single())
|
||||
}
|
||||
// DOCEND 3
|
||||
}
|
||||
@ -234,10 +235,11 @@ class ForeignExchangeRemoteFlow(val source: Party) : FlowLogic<Unit>() {
|
||||
val ourResponse = prepareOurInputsAndOutputs(serviceHub, request)
|
||||
|
||||
// Send back our proposed states and await the full transaction to verify
|
||||
val ourKey = serviceHub.keyManagementService.filterMyKeys(ourResponse.inputs.flatMap { it.state.data.participants }.map { it.owningKey }).single()
|
||||
val proposedTrade = sendAndReceive<SignedTransaction>(source, ourResponse).unwrap {
|
||||
val wtx = it.tx
|
||||
// check all signatures are present except our own and the notary
|
||||
it.verifySignatures(serviceHub.myInfo.legalIdentity.owningKey, wtx.notary!!.owningKey)
|
||||
it.verifySignatures(ourKey, wtx.notary!!.owningKey)
|
||||
|
||||
// We need to fetch their complete input states and dependencies so that verify can operate
|
||||
checkDependencies(it)
|
||||
@ -251,7 +253,7 @@ class ForeignExchangeRemoteFlow(val source: Party) : FlowLogic<Unit>() {
|
||||
}
|
||||
|
||||
// assuming we have completed state and business level validation we can sign the trade
|
||||
val ourSignature = serviceHub.createSignature(proposedTrade)
|
||||
val ourSignature = serviceHub.createSignature(proposedTrade, ourKey)
|
||||
|
||||
// send the other side our signature.
|
||||
send(source, ourSignature)
|
||||
|
Reference in New Issue
Block a user