corda / net.corda.core.flows / CollectSignaturesFlow

CollectSignaturesFlow

class CollectSignaturesFlow : FlowLogic<SignedTransaction>

The CollectSignaturesFlow is used to automate the collection of counter-party signatures for a given transaction.

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 are collected based upon the WireTransaction.requiredSigningKeys property which contains the union of all the PublicKeys listed in the transaction's commands as well as a notary's public key, if required. This flow returns a SignedTransaction which can then be passed to the FinalityFlow for notarisation. The other side of this flow is the SignTransactionFlow.

WARNING: This flow ONLY works with ServiceHub.legalIdentityKeys and WILL break if used with randomly generated keys by the ServiceHub.keyManagementService.

Usage:

  1. The provided transaction is invalid
  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
  4. The counterparty rejects the provided transaction

Example - issuing a multi-lateral agreement which requires N signatures:

    val builder = TransactionBuilder(notaryRef)
    val issueCommand = Command(Agreement.Commands.Issue(), state.participants)
    builder.withItems(state, issueCommand)
    builder.toWireTransaction().toLedgerTransaction(serviceHub).verify()
    // Transaction creator signs transaction.
    val ptx = serviceHub.signInitialTransaction(builder)
    // Call to CollectSignaturesFlow.
    // The returned signed transaction will have all signatures appended apart from the notary's.
    val stx = subFlow(CollectSignaturesFlow(ptx))

Parameters

partiallySignedTx - Transaction to collect the remaining signatures for sessionsToCollectFrom - A session for every party we need to collect a signature from. Must be an exact match. myOptionalKeys - set of keys in the transaction which are owned by this node. This includes keys used on commands, not just in the states. If null, the default well known identity of the node is used.

Types

COLLECTING

object COLLECTING : Step

VERIFYING

object VERIFYING : Step

Constructors

<init>

CollectSignaturesFlow(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection<FlowSession>, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker())CollectSignaturesFlow(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection<FlowSession>, myOptionalKeys: Iterable<PublicKey>?, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker())

The CollectSignaturesFlow is used to automate the collection of counter-party signatures for a given transaction.

Properties

myOptionalKeys

val myOptionalKeys: Iterable<PublicKey>?

partiallySignedTx

val partiallySignedTx: SignedTransaction

progressTracker

val progressTracker: ProgressTracker

Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something helpful with the progress reports e.g record to the audit service. If this flow is invoked as a subflow of another, then the tracker will be made a child of the current step in the parent. If it's null, this flow doesn't track progress.

sessionsToCollectFrom

val sessionsToCollectFrom: Collection<FlowSession>

Inherited Properties

logger

val logger: Logger

This is where you should log things to.

ourIdentity

val ourIdentity: Party

Specifies the identity to use for this flow. This will be one of the multiple identities that belong to this node. This is the same as calling ourIdentityAndCert.party.

ourIdentityAndCert

val ourIdentityAndCert: PartyAndCertificate

Specifies the identity, with certificate, to use for this flow. This will be one of the multiple identities that belong to this node.

runId

val runId: StateMachineRunId

Returns a wrapped java.util.UUID object that identifies this state machine run (i.e. subflows have the same identifier as their parents).

serviceHub

val serviceHub: ServiceHub

Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is only available once the flow has started, which means it cannnot be accessed in the constructor. Either access this lazily or from inside call.

Functions

call

fun call(): SignedTransaction

This is where you fill out your business logic.

Inherited Functions

checkFlowPermission

fun checkFlowPermission(permissionName: String, extraAuditData: Map<String, String>): Unit

Flows can call this method to ensure that the active FlowInitiator is authorised for a particular action. This provides fine grained control over application level permissions, when RPC control over starting the flow is insufficient, or the permission is runtime dependent upon the choices made inside long lived flow code. For example some users may have restricted limits on how much cash they can transfer, or whether they can change certain fields. An audit event is always recorded whenever this method is used. If the permission is not granted for the FlowInitiator a FlowException is thrown.

flowStackSnapshot

fun flowStackSnapshot(): FlowStackSnapshot?

Returns a shallow copy of the Quasar stack frames at the time of call to flowStackSnapshot. Use this to inspect what objects would be serialised at the time of call to a suspending action (e.g. send/receive). Note: This logic is only available during tests and is not meant to be used during the production deployment. Therefore the default implementation does nothing.

getFlowInfo

fun getFlowInfo(otherParty: Party): FlowInfo

Returns a FlowInfo object describing the flow otherParty is using. With FlowInfo.flowVersion it provides the necessary information needed for the evolution of flows and enabling backwards compatibility.

initiateFlow

fun initiateFlow(party: Party): FlowSession

Creates a communication session with party. Subsequently you may send/receive using this session object. Note that this function does not communicate in itself, the counter-flow will be kicked off by the first send/receive.

persistFlowStackSnapshot

fun persistFlowStackSnapshot(): Unit

Persists a shallow copy of the Quasar stack frames at the time of call to persistFlowStackSnapshot. Use this to track the monitor evolution of the quasar stack values during the flow execution. The flow stack snapshot is stored in a file located in {baseDir}/flowStackSnapshots/YYYY-MM-DD/{flowId}/ where baseDir is the node running directory and flowId is the flow unique identifier generated by the platform.

receive

fun <R : Any> receive(otherParty: Party): UntrustworthyData<R>

Suspends until the specified otherParty sends us a message of type R.

open fun <R : Any> receive(receiveType: Class<R>, otherParty: Party): UntrustworthyData<R>

Suspends until the specified otherParty sends us a message of type receiveType.

recordAuditEvent

fun recordAuditEvent(eventType: String, comment: String, extraAuditData: Map<String, String>): Unit

Flows can call this method to record application level flow audit events

send

open fun send(otherParty: Party, payload: Any): Unit

Queues the given payload for sending to the otherParty and continues without suspending.

sendAndReceive

fun <R : Any> sendAndReceive(otherParty: Party, payload: Any): UntrustworthyData<R>

Serializes and queues the given payload object for sending to the otherParty. Suspends until a response is received, which must be of the given R type.

open fun <R : Any> sendAndReceive(receiveType: Class<R>, otherParty: Party, payload: Any): UntrustworthyData<R>

Serializes and queues the given payload object for sending to the otherParty. Suspends until a response is received, which must be of the given receiveType. Remember that when receiving data from other parties the data should not be trusted until it's been thoroughly verified for consistency and that all expectations are satisfied, as a malicious peer may send you subtly corrupted data in order to exploit your code.

subFlow

open fun <R> subFlow(subLogic: FlowLogic<R>): R

Invokes the given subflow. This function returns once the subflow completes successfully with the result returned by that subflow's call method. If the subflow has a progress tracker, it is attached to the current step in this flow's progress tracker.

track

fun track(): DataFeed<String, String>?

Returns a pair of the current progress step, as a string, and an observable of stringified changes to the progressTracker.

waitForLedgerCommit

fun waitForLedgerCommit(hash: SecureHash): SignedTransaction

Suspends the flow until the transaction with the specified ID is received, successfully verified and sent to the vault for processing. Note that this call suspends until the transaction is considered valid by the local node, but that doesn't imply the vault will consider it relevant.

Companion Object Functions

tracker

fun tracker(): ProgressTracker