Introducing versioning of flows using the FlowVersion annotation.

Core flows, which are baked into the platform, are also versioned using the platform version of the node. Several core flows, such as the data vending ones, which were provided via plugins are now instead baked into the node.
This commit is contained in:
Shams Asari
2017-04-27 12:29:41 +01:00
parent 3d401d1dcb
commit cfe5786d2d
33 changed files with 363 additions and 265 deletions

View File

@ -26,7 +26,7 @@ sealed class FlowInitiator {
/** Started when we get new session initiation request. */
data class Peer(val party: Party) : FlowInitiator()
/** Started as scheduled activity. */
class Scheduled(val scheduledState: ScheduledStateRef) : FlowInitiator()
data class Scheduled(val scheduledState: ScheduledStateRef) : FlowInitiator()
object Shell : FlowInitiator() // TODO When proper ssh access enabled, add username/use RPC?
}

View File

@ -0,0 +1,18 @@
package net.corda.core.flows
/**
* Annotation for initiating [FlowLogic]s to specify the version of their flow protocol. The version is a single integer
* [value] which increments by one whenever a release is made where the flow protocol changes in any manner which is
* backwards incompatible. This may be a change in the sequence of sends and receives between the client and service flows,
* or it could be a change in the meaning. The version is used when a flow first initiates communication with a party to
* inform them what version they are using. For this reason the annotation is not applicable for the initiated flow.
*
* This flow version integer is not the same as Corda's platform version, though it follows a similar semantic.
*
* Note: Only one version of the same flow can currently be loaded at the same time. Any session request by a client flow for
* a different version will be rejected.
*
* Defaults to a flow version of 1 if not specified.
*/
// TODO Add support for multiple versions once CorDapps are loaded in separate class loaders
annotation class FlowVersion(val value: Int)

View File

@ -190,6 +190,8 @@ interface Message {
interface ReceivedMessage : Message {
/** The authenticated sender. */
val peer: X500Name
/** Platform version of the sender's node. */
val platformVersion: Int
}
/** A singleton that's useful for validating topic strings */

View File

@ -6,7 +6,6 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.serialization.CordaSerializable
import net.corda.core.transactions.SignedTransaction
/**
* Notify the specified parties about a transaction. The remote peers will download this transaction and its
* dependency graph, verifying them all. The flow returns when all peers have acknowledged the transactions
@ -26,7 +25,7 @@ class BroadcastTransactionFlow(val notarisedTransaction: SignedTransaction,
// TODO: Messaging layer should handle this broadcast for us
val msg = NotifyTxRequest(notarisedTransaction)
participants.filter { it != serviceHub.myInfo.legalIdentity }.forEach { participant ->
// This pops out the other side in DataVending.NotifyTransactionHandler.
// This pops out the other side in NotifyTransactionHandler
send(participant, msg)
}
}

View File

@ -88,9 +88,7 @@ object NotaryChangeFlow : AbstractStateReplacementFlow() {
}
class Acceptor(otherSide: Party,
override val progressTracker: ProgressTracker = tracker()) : AbstractStateReplacementFlow.Acceptor<Party>(otherSide) {
class Acceptor(otherSide: Party) : AbstractStateReplacementFlow.Acceptor<Party>(otherSide) {
/**
* Check the notary change proposal.
*

View File

@ -2,7 +2,6 @@ package net.corda.core.flows
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.crypto.Party
import net.corda.core.node.PluginServiceHub
import net.corda.core.utilities.ProgressTracker
import net.corda.flows.TxKeyFlowUtilities
import java.security.PublicKey
@ -14,9 +13,6 @@ import java.security.cert.Certificate
* DoS of the node, as key generation/storage is vastly more expensive than submitting a request.
*/
object TxKeyFlow {
fun registerServiceFlow(services: PluginServiceHub) {
services.registerServiceFlow(Requester::class.java, ::Provider)
}
class Requester(val otherSide: Party,
override val progressTracker: ProgressTracker) : FlowLogic<Pair<PublicKey, Certificate?>>() {

View File

@ -32,7 +32,7 @@ class TxKeyFlowUtilitiesTests {
val bobKey: Party = bobNode.services.myInfo.legalIdentity
// Run the flows
TxKeyFlow.registerServiceFlow(bobNode.services)
bobNode.registerServiceFlow(TxKeyFlow.Requester::class) { TxKeyFlow.Provider(it) }
val requesterFlow = aliceNode.services.startFlow(TxKeyFlow.Requester(bobKey))
// Get the results