CORDA-3220: Updating FinalityFlow with functionality to specify StatesToRecord (#5482)

Updating FinalityFlow with functionality to allow the initiator to indicate the appropriate StatesToRecord. This allows the initiating party to record states in transactions which they are proposing but are not necessarily participants of. An example would be the issuance of a token where the only participant is the holder NOT the issuer.
This commit is contained in:
Nick Rogers 2019-09-19 12:58:05 -04:00 committed by Shams Asari
parent 389c91374e
commit 74e8b6e468
2 changed files with 27 additions and 3 deletions

View File

@ -20,6 +20,10 @@ import net.corda.core.utilities.debug
* is acceptable then it is from that point onwards committed to the ledger, and will be written through to the * is acceptable then it is from that point onwards committed to the ledger, and will be written through to the
* vault. Additionally it will be distributed to the parties reflected in the participants list of the states. * vault. Additionally it will be distributed to the parties reflected in the participants list of the states.
* *
* By default, the initiating flow will commit states that are relevant to the initiating party as indicated by
* [StatesToRecord.ONLY_RELEVANT]. Relevance is determined by the union of all participants to states which have been
* included in the transaction. This default behaviour may be modified by passing in an alternate value for [StatesToRecord].
*
* The transaction is expected to have already been resolved: if its dependencies are not available in local * The transaction is expected to have already been resolved: if its dependencies are not available in local
* storage, verification will fail. It must have signatures from all necessary parties other than the notary. * storage, verification will fail. It must have signatures from all necessary parties other than the notary.
* *
@ -40,7 +44,8 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
private val oldParticipants: Collection<Party>, private val oldParticipants: Collection<Party>,
override val progressTracker: ProgressTracker, override val progressTracker: ProgressTracker,
private val sessions: Collection<FlowSession>, private val sessions: Collection<FlowSession>,
private val newApi: Boolean) : FlowLogic<SignedTransaction>() { private val newApi: Boolean,
private val statesToRecord: StatesToRecord = ONLY_RELEVANT) : FlowLogic<SignedTransaction>() {
@Deprecated(DEPRECATION_MSG) @Deprecated(DEPRECATION_MSG)
constructor(transaction: SignedTransaction, extraRecipients: Set<Party>, progressTracker: ProgressTracker) : this( constructor(transaction: SignedTransaction, extraRecipients: Set<Party>, progressTracker: ProgressTracker) : this(
transaction, extraRecipients, progressTracker, emptyList(), false transaction, extraRecipients, progressTracker, emptyList(), false
@ -76,6 +81,22 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
progressTracker: ProgressTracker = tracker() progressTracker: ProgressTracker = tracker()
) : this(transaction, emptyList(), progressTracker, sessions, true) ) : this(transaction, emptyList(), progressTracker, sessions, true)
/**
* Notarise the given transaction and broadcast it to all the participants.
*
* @param transaction What to commit.
* @param sessions A collection of [FlowSession]s for each non-local participant of the transaction. Sessions to non-participants can
* also be provided.
* @param statesToRecord Which states to commit to the vault.
*/
@JvmOverloads
constructor(
transaction: SignedTransaction,
sessions: Collection<FlowSession>,
statesToRecord: StatesToRecord,
progressTracker: ProgressTracker = tracker()
) : this(transaction, emptyList(), progressTracker, sessions, true, statesToRecord)
/** /**
* Notarise the given transaction and broadcast it to all the participants. * Notarise the given transaction and broadcast it to all the participants.
* *
@ -202,7 +223,7 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
transaction transaction
} }
logger.info("Recording transaction locally.") logger.info("Recording transaction locally.")
serviceHub.recordTransactions(notarised) serviceHub.recordTransactions(statesToRecord, listOf(notarised))
logger.info("Recorded transaction locally successfully.") logger.info("Recorded transaction locally successfully.")
return notarised return notarised
} }
@ -246,7 +267,7 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
* @param otherSideSession The session which is providing the transaction to record. * @param otherSideSession The session which is providing the transaction to record.
* @param expectedTxId Expected ID of the transaction that's about to be received. This is typically retrieved from * @param expectedTxId Expected ID of the transaction that's about to be received. This is typically retrieved from
* [SignTransactionFlow]. Setting it to null disables the expected transaction ID check. * [SignTransactionFlow]. Setting it to null disables the expected transaction ID check.
* @param statesToRecord Which transactions to commit to the vault. Defaults to [StatesToRecord.ONLY_RELEVANT]. * @param statesToRecord Which states to commit to the vault. Defaults to [StatesToRecord.ONLY_RELEVANT].
*/ */
class ReceiveFinalityFlow @JvmOverloads constructor(private val otherSideSession: FlowSession, class ReceiveFinalityFlow @JvmOverloads constructor(private val otherSideSession: FlowSession,
private val expectedTxId: SecureHash? = null, private val expectedTxId: SecureHash? = null,

View File

@ -7,6 +7,9 @@ release, see :doc:`app-upgrade-notes`.
Unreleased Unreleased
---------- ----------
* Updating FinalityFlow with functionality to indicate the appropriate StatesToRecord. This allows the initiating party to record states
from transactions which they are proposing, but are not necessarily participants of.
* Removed the RPC exception privacy feature. Previously, in production mode, the exceptions thrown on the node were stripped of all content * Removed the RPC exception privacy feature. Previously, in production mode, the exceptions thrown on the node were stripped of all content
when rethrown on the RPC client. when rethrown on the RPC client.