CORDA-939 - Dont expose FlowStateMachine via public API (#2438)

* Create CordaInternal attribute for properties on public classes that are not part of the api and apply to FlowLogic.stateMachine

* Remove startFlow from public test api and replace with startFlowAndReturnFuture

* Update api-current with changed signature

* Change test used in documentation to use public test methods

* Remove the rest of the unneccessary usages of the startFlow test utility

* Remove extra whitespace

* Rename startFlowAndReturnFuture back to startFlow

* Update api

* The annotation doesn't appear unless its marked as on the actual getter and setter

* Updated docs and removed pointless attribute

* Deleted whitespace
This commit is contained in:
Anthony Keenan 2018-02-07 11:55:06 +00:00 committed by GitHub
parent 95f062e8ff
commit 8081ee42ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 115 additions and 101 deletions

View File

@ -14,6 +14,8 @@
public void setMessage(String)
public void setOriginalExceptionClassName(String)
##
public @interface net.corda.core.CordaInternal
##
public final class net.corda.core.CordaOID extends java.lang.Object
@org.jetbrains.annotations.NotNull public static final String CORDA_PLATFORM = "1.3.6.1.4.1.50530.1"
public static final net.corda.core.CordaOID INSTANCE
@ -1227,7 +1229,7 @@ public abstract class net.corda.core.flows.FlowLogic extends java.lang.Object
@org.jetbrains.annotations.Nullable public net.corda.core.utilities.ProgressTracker getProgressTracker()
@org.jetbrains.annotations.NotNull public final net.corda.core.flows.StateMachineRunId getRunId()
@org.jetbrains.annotations.NotNull public final net.corda.core.node.ServiceHub getServiceHub()
@org.jetbrains.annotations.NotNull public final net.corda.core.internal.FlowStateMachine getStateMachine()
@net.corda.core.CordaInternal @org.jetbrains.annotations.NotNull public final net.corda.core.internal.FlowStateMachine getStateMachine()
@co.paralleluniverse.fibers.Suspendable @org.jetbrains.annotations.NotNull public final net.corda.core.flows.FlowSession initiateFlow(net.corda.core.identity.Party)
@co.paralleluniverse.fibers.Suspendable public final void persistFlowStackSnapshot()
@kotlin.Deprecated @co.paralleluniverse.fibers.Suspendable @org.jetbrains.annotations.NotNull public net.corda.core.utilities.UntrustworthyData receive(Class, net.corda.core.identity.Party)
@ -1236,7 +1238,7 @@ public abstract class net.corda.core.flows.FlowLogic extends java.lang.Object
public final void recordAuditEvent(String, String, Map)
@kotlin.Deprecated @co.paralleluniverse.fibers.Suspendable public void send(net.corda.core.identity.Party, Object)
@kotlin.Deprecated @co.paralleluniverse.fibers.Suspendable @org.jetbrains.annotations.NotNull public net.corda.core.utilities.UntrustworthyData sendAndReceive(Class, net.corda.core.identity.Party, Object)
public final void setStateMachine(net.corda.core.internal.FlowStateMachine)
@net.corda.core.CordaInternal public final void setStateMachine(net.corda.core.internal.FlowStateMachine)
@co.paralleluniverse.fibers.Suspendable @kotlin.jvm.JvmStatic public static final void sleep(java.time.Duration)
@co.paralleluniverse.fibers.Suspendable public Object subFlow(net.corda.core.flows.FlowLogic)
@org.jetbrains.annotations.Nullable public final net.corda.core.messaging.DataFeed track()
@ -4153,7 +4155,7 @@ public final class net.corda.testing.node.NodeTestUtils extends java.lang.Object
@org.jetbrains.annotations.NotNull public static final net.corda.testing.dsl.LedgerDSL ledger(net.corda.core.node.ServiceHub, kotlin.jvm.functions.Function1)
@org.jetbrains.annotations.NotNull public static final net.corda.testing.dsl.LedgerDSL ledger(net.corda.core.node.ServiceHub, net.corda.core.identity.Party, kotlin.jvm.functions.Function1)
@org.jetbrains.annotations.NotNull public static final net.corda.core.context.InvocationContext newContext(net.corda.node.services.api.StartedNodeServices)
@org.jetbrains.annotations.NotNull public static final net.corda.core.internal.FlowStateMachine startFlow(net.corda.node.services.api.StartedNodeServices, net.corda.core.flows.FlowLogic)
@org.jetbrains.annotations.NotNull public static final net.corda.core.concurrent.CordaFuture startFlow(net.corda.node.services.api.StartedNodeServices, net.corda.core.flows.FlowLogic)
@org.jetbrains.annotations.NotNull public static final net.corda.core.context.Actor testActor(net.corda.core.identity.CordaX500Name)
@org.jetbrains.annotations.NotNull public static final net.corda.core.context.InvocationContext testContext(net.corda.core.identity.CordaX500Name)
@org.jetbrains.annotations.NotNull public static final net.corda.testing.dsl.LedgerDSL transaction(net.corda.core.node.ServiceHub, kotlin.jvm.functions.Function1)

View File

@ -58,12 +58,12 @@ class IdentitySyncFlowTests {
val anonymous = true
val ref = OpaqueBytes.of(0x01)
val issueFlow = aliceNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, alice, anonymous, notary))
val issueTx = issueFlow.resultFuture.getOrThrow().stx
val issueTx = issueFlow.getOrThrow().stx
val confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance<Cash.State>().single().owner
assertNull(bobNode.database.transaction { bobNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) })
// Run the flow to sync up the identities
aliceNode.services.startFlow(Initiator(bob, issueTx.tx)).resultFuture.getOrThrow()
aliceNode.services.startFlow(Initiator(bob, issueTx.tx)).getOrThrow()
val expected = aliceNode.database.transaction {
aliceNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity)
}
@ -88,7 +88,7 @@ class IdentitySyncFlowTests {
val anonymous = true
val ref = OpaqueBytes.of(0x01)
val issueFlow = charlieNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, charlie, anonymous, notary))
val issueTx = issueFlow.resultFuture.getOrThrow().stx
val issueTx = issueFlow.getOrThrow().stx
val confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance<Cash.State>().single().owner
val confidentialIdentCert = charlieNode.services.identityService.certificateFromKey(confidentialIdentity.owningKey)!!
@ -97,11 +97,11 @@ class IdentitySyncFlowTests {
assertNotNull(aliceNode.database.transaction { aliceNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) })
// Generate a payment from Charlie to Alice, including the confidential state
val payTx = charlieNode.services.startFlow(CashPaymentFlow(1000.DOLLARS, alice, anonymous)).resultFuture.getOrThrow().stx
val payTx = charlieNode.services.startFlow(CashPaymentFlow(1000.DOLLARS, alice, anonymous)).getOrThrow().stx
// Run the flow to sync up the identities, and confirm Charlie's confidential identity doesn't leak
assertNull(bobNode.database.transaction { bobNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) })
aliceNode.services.startFlow(Initiator(bob, payTx.tx)).resultFuture.getOrThrow()
aliceNode.services.startFlow(Initiator(bob, payTx.tx)).getOrThrow()
assertNull(bobNode.database.transaction { bobNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) })
}

View File

@ -30,7 +30,7 @@ class SwapIdentitiesFlowTests {
val requesterFlow = aliceNode.services.startFlow(SwapIdentitiesFlow(bob))
// Get the results
val actual: Map<Party, AnonymousParty> = requesterFlow.resultFuture.getOrThrow().toMap()
val actual: Map<Party, AnonymousParty> = requesterFlow.getOrThrow().toMap()
assertEquals(2, actual.size)
// Verify that the generated anonymous identities do not match the well known identities
val aliceAnonymousIdentity = actual[alice] ?: throw IllegalStateException()

View File

@ -0,0 +1,11 @@
package net.corda.core
/**
* These methods are not part of Corda's API compatibility guarantee and applications should not use them.
*
* These fields are only meant to be used by Corda internally, and are not intended to be part of the public API.
*/
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@MustBeDocumented
annotation class CordaInternal

View File

@ -2,6 +2,7 @@ package net.corda.core.flows
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.strands.Strand
import net.corda.core.CordaInternal
import net.corda.core.crypto.SecureHash
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
@ -419,7 +420,9 @@ abstract class FlowLogic<out T> {
* is public only because it must be accessed across module boundaries.
*/
var stateMachine: FlowStateMachine<*>
@CordaInternal
get() = _stateMachine ?: throw IllegalStateException("This can only be done after the flow has been started.")
@CordaInternal
set(value) {
_stateMachine = value
}

View File

@ -40,7 +40,7 @@ public class FlowsInJavaTest {
@Test
public void suspendableActionInsideUnwrap() throws Exception {
bobNode.registerInitiatedFlow(SendHelloAndThenReceive.class);
Future<String> result = startFlow(aliceNode.getServices(), new SendInUnwrapFlow(bob)).getResultFuture();
Future<String> result = startFlow(aliceNode.getServices(), new SendInUnwrapFlow(bob));
mockNet.runNetwork();
assertThat(result.get()).isEqualTo("Hello");
}
@ -56,7 +56,7 @@ public class FlowsInJavaTest {
private void primitiveReceiveTypeTest(Class<?> receiveType) throws InterruptedException {
PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(bob, receiveType);
Future<?> result = startFlow(aliceNode.getServices(), flow).getResultFuture();
Future<?> result = startFlow(aliceNode.getServices(), flow);
mockNet.runNetwork();
try {
result.get();

View File

@ -65,7 +65,7 @@ class AttachmentTests {
mockNet.runNetwork()
val bobFlow = bobNode.startAttachmentFlow(setOf(id), alice)
mockNet.runNetwork()
assertEquals(0, bobFlow.resultFuture.getOrThrow().fromDisk.size)
assertEquals(0, bobFlow.getOrThrow().fromDisk.size)
// Verify it was inserted into node one's store.
val attachment = bobNode.database.transaction {
@ -77,7 +77,7 @@ class AttachmentTests {
// Shut down node zero and ensure node one can still resolve the attachment.
aliceNode.dispose()
val response: FetchDataFlow.Result<Attachment> = bobNode.startAttachmentFlow(setOf(id), alice).resultFuture.getOrThrow()
val response: FetchDataFlow.Result<Attachment> = bobNode.startAttachmentFlow(setOf(id), alice).getOrThrow()
assertEquals(attachment, response.fromDisk[0])
}
@ -92,7 +92,7 @@ class AttachmentTests {
val alice = aliceNode.info.singleIdentity()
val bobFlow = bobNode.startAttachmentFlow(setOf(hash), alice)
mockNet.runNetwork()
val e = assertFailsWith<FetchDataFlow.HashNotFound> { bobFlow.resultFuture.getOrThrow() }
val e = assertFailsWith<FetchDataFlow.HashNotFound> { bobFlow.getOrThrow() }
assertEquals(hash, e.requested)
}
@ -127,7 +127,7 @@ class AttachmentTests {
mockNet.runNetwork()
val bobFlow = bobNode.startAttachmentFlow(setOf(id), alice)
mockNet.runNetwork()
assertFailsWith<FetchDataFlow.DownloadedVsRequestedDataMismatch> { bobFlow.resultFuture.getOrThrow() }
assertFailsWith<FetchDataFlow.DownloadedVsRequestedDataMismatch> { bobFlow.getOrThrow() }
}
private fun StartedNode<*>.startAttachmentFlow(hashes: Set<SecureHash>, otherSide: Party) = services.startFlow(InitiatingFetchAttachmentsFlow(otherSide, hashes))

View File

@ -115,7 +115,7 @@ class CollectSignaturesFlowTests {
val state = DummyContract.MultiOwnerState(magicNumber, parties)
val flow = aliceNode.services.startFlow(TestFlow.Initiator(state, notary))
mockNet.runNetwork()
val result = flow.resultFuture.getOrThrow()
val result = flow.getOrThrow()
result.verifyRequiredSignatures()
println(result.tx)
println(result.sigs)
@ -127,7 +127,7 @@ class CollectSignaturesFlowTests {
val ptx = aliceNode.services.signInitialTransaction(onePartyDummyContract)
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(ptx, emptySet()))
mockNet.runNetwork()
val result = flow.resultFuture.getOrThrow()
val result = flow.getOrThrow()
result.verifyRequiredSignatures()
println(result.tx)
println(result.sigs)
@ -141,7 +141,7 @@ class CollectSignaturesFlowTests {
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(ptx, emptySet()))
mockNet.runNetwork()
assertFailsWith<IllegalArgumentException>("The Initiator of CollectSignaturesFlow must have signed the transaction.") {
flow.resultFuture.getOrThrow()
flow.getOrThrow()
}
}
@ -155,7 +155,7 @@ class CollectSignaturesFlowTests {
val signedByBoth = bobNode.services.addSignature(signedByA)
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(signedByBoth, emptySet()))
mockNet.runNetwork()
val result = flow.resultFuture.getOrThrow()
val result = flow.getOrThrow()
println(result.tx)
println(result.sigs)
}

View File

@ -81,24 +81,24 @@ class ContractUpgradeFlowTest {
requireNotNull(btx)
// The request is expected to be rejected because party B hasn't authorised the upgrade yet.
val rejectedFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx!!.tx.outRef(0), DummyContractV2::class.java)).resultFuture
val rejectedFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx!!.tx.outRef(0), DummyContractV2::class.java))
mockNet.runNetwork()
assertFailsWith(UnexpectedFlowEndException::class) { rejectedFuture.getOrThrow() }
// Party B authorise the contract state upgrade, and immediately deauthorise the same.
bobNode.services.startFlow(ContractUpgradeFlow.Authorise(btx!!.tx.outRef<ContractState>(0), DummyContractV2::class.java)).resultFuture.getOrThrow()
bobNode.services.startFlow(ContractUpgradeFlow.Deauthorise(btx.tx.outRef<ContractState>(0).ref)).resultFuture.getOrThrow()
bobNode.services.startFlow(ContractUpgradeFlow.Authorise(btx!!.tx.outRef<ContractState>(0), DummyContractV2::class.java)).getOrThrow()
bobNode.services.startFlow(ContractUpgradeFlow.Deauthorise(btx.tx.outRef<ContractState>(0).ref)).getOrThrow()
// The request is expected to be rejected because party B has subsequently deauthorised and a previously authorised upgrade.
val deauthorisedFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx.tx.outRef(0), DummyContractV2::class.java)).resultFuture
val deauthorisedFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx.tx.outRef(0), DummyContractV2::class.java))
mockNet.runNetwork()
assertFailsWith(UnexpectedFlowEndException::class) { deauthorisedFuture.getOrThrow() }
// Party B authorise the contract state upgrade
bobNode.services.startFlow(ContractUpgradeFlow.Authorise(btx.tx.outRef<ContractState>(0), DummyContractV2::class.java)).resultFuture.getOrThrow()
bobNode.services.startFlow(ContractUpgradeFlow.Authorise(btx.tx.outRef<ContractState>(0), DummyContractV2::class.java)).getOrThrow()
// Party A initiates contract upgrade flow, expected to succeed this time.
val resultFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx.tx.outRef(0), DummyContractV2::class.java)).resultFuture
val resultFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx.tx.outRef(0), DummyContractV2::class.java))
mockNet.runNetwork()
val result = resultFuture.getOrThrow()
@ -213,7 +213,7 @@ class ContractUpgradeFlowTest {
fun `upgrade Cash to v2`() {
// Create some cash.
val chosenIdentity = alice
val result = aliceNode.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), notary)).resultFuture
val result = aliceNode.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), notary))
mockNet.runNetwork()
val stx = result.getOrThrow().stx
val anonymisedRecipient = result.get().recipient!!
@ -221,7 +221,7 @@ class ContractUpgradeFlowTest {
val baseState = aliceNode.database.transaction { aliceNode.services.vaultService.queryBy<ContractState>().states.single() }
assertTrue(baseState.state.data is Cash.State, "Contract state is old version.")
// Starts contract upgrade flow.
val upgradeResult = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(stateAndRef, CashV2::class.java)).resultFuture
val upgradeResult = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(stateAndRef, CashV2::class.java))
mockNet.runNetwork()
upgradeResult.getOrThrow()
// Get contract state from the vault.

View File

@ -53,7 +53,7 @@ class FinalityFlowTests {
val stx = aliceServices.signInitialTransaction(builder)
val flow = aliceServices.startFlow(FinalityFlow(stx))
mockNet.runNetwork()
val notarisedTx = flow.resultFuture.getOrThrow()
val notarisedTx = flow.getOrThrow()
notarisedTx.verifyRequiredSignatures()
val transactionSeenByB = bobServices.database.transaction {
bobServices.validatedTransactions.getTransaction(notarisedTx.id)
@ -71,7 +71,7 @@ class FinalityFlowTests {
val flow = aliceServices.startFlow(FinalityFlow(stx))
mockNet.runNetwork()
assertFailsWith<IllegalArgumentException> {
flow.resultFuture.getOrThrow()
flow.getOrThrow()
}
}
}

View File

@ -52,7 +52,7 @@ class ReceiveMultipleFlowTests {
val flow = nodes[0].services.startFlow(initiatingFlow)
mockNet.runNetwork()
val receivedAnswer = flow.resultFuture.getOrThrow()
val receivedAnswer = flow.getOrThrow()
assertThat(receivedAnswer).isEqualTo(answer)
}
@ -64,7 +64,7 @@ class ReceiveMultipleFlowTests {
nodes[2].registerAnswer(AlgorithmDefinition::class, stringValue)
val flow = nodes[0].services.startFlow(ParallelAlgorithmMap(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity()))
mockNet.runNetwork()
val result = flow.resultFuture.getOrThrow()
val result = flow.getOrThrow()
assertThat(result).isEqualTo(doubleValue * stringValue.length)
}
@ -76,7 +76,7 @@ class ReceiveMultipleFlowTests {
nodes[2].registerAnswer(ParallelAlgorithmList::class, value2)
val flow = nodes[0].services.startFlow(ParallelAlgorithmList(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity()))
mockNet.runNetwork()
val data = flow.resultFuture.getOrThrow()
val data = flow.getOrThrow()
assertThat(data[0]).isEqualTo(value1)
assertThat(data[1]).isEqualTo(value2)
assertThat(data.fold(1.0) { a, b -> a * b }).isEqualTo(value1 * value2)

View File

@ -52,14 +52,14 @@ class ResolveTransactionsFlowTest {
fun tearDown() {
mockNet.stopNodes()
}
// DOCEND 3
// DOCEND 3
// DOCSTART 1
@Test
fun `resolve from two hashes`() {
val (stx1, stx2) = makeTransactions()
val p = TestFlow(setOf(stx2.id), megaCorp)
val future = miniCorpNode.services.startFlow(p).resultFuture
val future = miniCorpNode.services.startFlow(p)
mockNet.runNetwork()
val results = future.getOrThrow()
assertEquals(listOf(stx1.id, stx2.id), results.map { it.id })
@ -74,7 +74,7 @@ class ResolveTransactionsFlowTest {
fun `dependency with an error`() {
val stx = makeTransactions(signFirstTX = false).second
val p = TestFlow(setOf(stx.id), megaCorp)
val future = miniCorpNode.services.startFlow(p).resultFuture
val future = miniCorpNode.services.startFlow(p)
mockNet.runNetwork()
assertFailsWith(SignedTransaction.SignaturesMissingException::class) { future.getOrThrow() }
}
@ -83,7 +83,7 @@ class ResolveTransactionsFlowTest {
fun `resolve from a signed transaction`() {
val (stx1, stx2) = makeTransactions()
val p = TestFlow(stx2, megaCorp)
val future = miniCorpNode.services.startFlow(p).resultFuture
val future = miniCorpNode.services.startFlow(p)
mockNet.runNetwork()
future.getOrThrow()
miniCorpNode.database.transaction {
@ -108,7 +108,7 @@ class ResolveTransactionsFlowTest {
cursor = stx
}
val p = TestFlow(setOf(cursor.id), megaCorp, 40)
val future = miniCorpNode.services.startFlow(p).resultFuture
val future = miniCorpNode.services.startFlow(p)
mockNet.runNetwork()
assertFailsWith<ResolveTransactionsFlow.ExcessivelyLargeTransactionGraph> { future.getOrThrow() }
}
@ -132,7 +132,7 @@ class ResolveTransactionsFlowTest {
}
val p = TestFlow(setOf(stx3.id), megaCorp)
val future = miniCorpNode.services.startFlow(p).resultFuture
val future = miniCorpNode.services.startFlow(p)
mockNet.runNetwork()
future.getOrThrow()
}
@ -154,7 +154,7 @@ class ResolveTransactionsFlowTest {
}
val stx2 = makeTransactions(withAttachment = id).second
val p = TestFlow(stx2, megaCorp)
val future = miniCorpNode.services.startFlow(p).resultFuture
val future = miniCorpNode.services.startFlow(p)
mockNet.runNetwork()
future.getOrThrow()

View File

@ -15,11 +15,7 @@ import net.corda.core.utilities.unwrap
import net.corda.node.internal.StartedNode
import net.corda.node.services.messaging.Message
import net.corda.node.services.statemachine.SessionData
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.MessagingServiceSpy
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.setMessagingServiceSpy
import net.corda.testing.node.startFlow
import net.corda.testing.node.*
import org.junit.After
import org.junit.Before
import org.junit.Rule
@ -102,6 +98,6 @@ class TutorialMockNetwork {
expectedEx.expect(IllegalArgumentException::class.java)
expectedEx.expectMessage("Expected to receive 1")
initiatingReceiveFlow.resultFuture.getOrThrow()
initiatingReceiveFlow.getOrThrow()
}
}

View File

@ -60,7 +60,7 @@ class CustomVaultQueryTest {
OpaqueBytes.of(0x01),
notary))
// Wait for the flow to stop and print
flowHandle1.resultFuture.getOrThrow()
flowHandle1.getOrThrow()
}
private fun topUpCurrencies() {
@ -69,7 +69,7 @@ class CustomVaultQueryTest {
OpaqueBytes.of(0x01),
nodeA.info.chooseIdentity(),
notary))
flowHandle1.resultFuture.getOrThrow()
flowHandle1.getOrThrow()
}
private fun getBalances(): Pair<Map<Currency, Amount<Currency>>, Map<Currency, Amount<Currency>>> {

View File

@ -43,7 +43,7 @@ class FxTransactionBuildTutorialTest {
OpaqueBytes.of(0x01),
notary))
// Wait for the flow to stop and print
flowHandle1.resultFuture.getOrThrow()
flowHandle1.getOrThrow()
printBalances()
// Using NodeB as Issuer create some pounds.
@ -51,7 +51,7 @@ class FxTransactionBuildTutorialTest {
OpaqueBytes.of(0x01),
notary))
// Wait for flow to come to an end and print
flowHandle2.resultFuture.getOrThrow()
flowHandle2.getOrThrow()
printBalances()
// Setup some futures on the vaults to await the arrival of the exchanged funds at both nodes
@ -65,7 +65,7 @@ class FxTransactionBuildTutorialTest {
nodeB.info.chooseIdentity(),
weAreBaseCurrencySeller = false))
// wait for the flow to finish and the vault updates to be done
doIt.resultFuture.getOrThrow()
doIt.getOrThrow()
// Get the balances when the vault updates
nodeAVaultUpdate.get()
val balancesA = nodeA.database.transaction {

View File

@ -56,7 +56,7 @@ class WorkflowTransactionBuildTutorialTest {
// Kick of the proposal flow
val flow1 = aliceServices.startFlow(SubmitTradeApprovalFlow("1234", bob))
// Wait for the flow to finish
val proposalRef = flow1.resultFuture.getOrThrow()
val proposalRef = flow1.getOrThrow()
val proposalLinearId = proposalRef.state.data.linearId
// Wait for NodeB to include it's copy in the vault
nodeBVaultUpdate.get()
@ -80,7 +80,7 @@ class WorkflowTransactionBuildTutorialTest {
// Run the manual completion flow from NodeB
val flow2 = bobServices.startFlow(SubmitCompletionFlow(latestFromB.ref, WorkflowState.APPROVED))
// wait for the flow to end
val completedRef = flow2.resultFuture.getOrThrow()
val completedRef = flow2.getOrThrow()
// wait for the vault updates to stabilise
nodeAVaultUpdate.get()
secondNodeBVaultUpdate.get()

View File

@ -31,10 +31,10 @@ class CashSelectionH2ImplTest {
// spend operation below.
// Issuing Integer.MAX_VALUE will not cause an exception since PersistentCashState.pennies is a long
nCopies(2, Integer.MAX_VALUE).map { issueAmount ->
node.services.startFlow(CashIssueFlow(issueAmount.POUNDS, OpaqueBytes.of(1), mockNet.defaultNotaryIdentity)).resultFuture
node.services.startFlow(CashIssueFlow(issueAmount.POUNDS, OpaqueBytes.of(1), mockNet.defaultNotaryIdentity))
}.transpose().getOrThrow()
// The spend must be more than the size of a single cash state to force the accumulator onto the second state.
node.services.startFlow(CashPaymentFlow((Integer.MAX_VALUE + 1L).POUNDS, node.info.legalIdentities[0])).resultFuture.getOrThrow()
node.services.startFlow(CashPaymentFlow((Integer.MAX_VALUE + 1L).POUNDS, node.info.legalIdentities[0])).getOrThrow()
}
@Test
@ -50,8 +50,8 @@ class CashSelectionH2ImplTest {
val flow2 = bankA.services.startFlow(CashPaymentFlow(amount = 100.DOLLARS, anonymous = false, recipient = notary))
val flow3 = bankA.services.startFlow(CashPaymentFlow(amount = 100.DOLLARS, anonymous = false, recipient = notary))
assertThatThrownBy { flow1.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
assertThatThrownBy { flow2.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
assertThatThrownBy { flow3.resultFuture.getOrThrow() }.isInstanceOf(CashException::class.java)
assertThatThrownBy { flow1.getOrThrow() }.isInstanceOf(CashException::class.java)
assertThatThrownBy { flow2.getOrThrow() }.isInstanceOf(CashException::class.java)
assertThatThrownBy { flow3.getOrThrow() }.isInstanceOf(CashException::class.java)
}
}

View File

@ -33,7 +33,7 @@ class CashExitFlowTests {
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
notary = mockNet.defaultNotaryIdentity
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary))
mockNet.runNetwork()
future.getOrThrow()
}
@ -46,7 +46,7 @@ class CashExitFlowTests {
@Test
fun `exit some cash`() {
val exitAmount = 500.DOLLARS
val future = bankOfCordaNode.services.startFlow(CashExitFlow(exitAmount, ref)).resultFuture
val future = bankOfCordaNode.services.startFlow(CashExitFlow(exitAmount, ref))
mockNet.runNetwork()
val exitTx = future.getOrThrow().stx.tx
val expected = (initialBalance - exitAmount).`issued by`(bankOfCorda.ref(ref))
@ -59,7 +59,7 @@ class CashExitFlowTests {
@Test
fun `exit zero cash`() {
val expected = 0.DOLLARS
val future = bankOfCordaNode.services.startFlow(CashExitFlow(expected, ref)).resultFuture
val future = bankOfCordaNode.services.startFlow(CashExitFlow(expected, ref))
mockNet.runNetwork()
assertFailsWith<CashException> {
future.getOrThrow()

View File

@ -41,7 +41,7 @@ class CashIssueFlowTests {
fun `issue some cash`() {
val expected = 500.DOLLARS
val ref = OpaqueBytes.of(0x01)
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(expected, ref, notary)).resultFuture
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(expected, ref, notary))
mockNet.runNetwork()
val issueTx = future.getOrThrow().stx
val output = issueTx.tx.outputsOfType<Cash.State>().single()
@ -52,7 +52,7 @@ class CashIssueFlowTests {
fun `issue zero cash`() {
val expected = 0.DOLLARS
val ref = OpaqueBytes.of(0x01)
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(expected, ref, notary)).resultFuture
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(expected, ref, notary))
mockNet.runNetwork()
assertFailsWith<IllegalArgumentException> {
future.getOrThrow()

View File

@ -35,7 +35,7 @@ class CashPaymentFlowTests {
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
aliceNode = mockNet.createPartyNode(ALICE_NAME)
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, mockNet.defaultNotaryIdentity)).resultFuture
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, mockNet.defaultNotaryIdentity))
future.getOrThrow()
}
@ -56,8 +56,7 @@ class CashPaymentFlowTests {
val (_, vaultUpdatesBoc) = bankOfCordaNode.services.vaultService.trackBy<Cash.State>(criteria)
val (_, vaultUpdatesBankClient) = aliceNode.services.vaultService.trackBy<Cash.State>(criteria)
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expectedPayment,
payTo)).resultFuture
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expectedPayment, payTo))
mockNet.runNetwork()
future.getOrThrow()
@ -89,7 +88,7 @@ class CashPaymentFlowTests {
val payTo = aliceNode.info.chooseIdentity()
val expected = 4000.DOLLARS
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expected,
payTo)).resultFuture
payTo))
mockNet.runNetwork()
assertFailsWith<CashException> {
future.getOrThrow()
@ -101,7 +100,7 @@ class CashPaymentFlowTests {
val payTo = aliceNode.info.chooseIdentity()
val expected = 0.DOLLARS
val future = bankOfCordaNode.services.startFlow(CashPaymentFlow(expected,
payTo)).resultFuture
payTo))
mockNet.runNetwork()
assertFailsWith<IllegalArgumentException> {
future.getOrThrow()

View File

@ -92,7 +92,7 @@ class BFTNotaryServiceTests {
addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DummyContract.PROGRAM_ID, AlwaysAcceptAttachmentConstraint)
}
// Create a new consensus while the redundant replica is sleeping:
services.startFlow(NotaryFlow.Client(trivialTx)).resultFuture
services.startFlow(NotaryFlow.Client(trivialTx))
}
mockNet.runNetwork()
f.getOrThrow()
@ -127,7 +127,7 @@ class BFTNotaryServiceTests {
val flows = spendTxs.map { NotaryFlow.Client(it) }
val stateMachines = flows.map { services.startFlow(it) }
mockNet.runNetwork()
val results = stateMachines.map { Try.on { it.resultFuture.getOrThrow() } }
val results = stateMachines.map { Try.on { it.getOrThrow() } }
val successfulIndex = results.mapIndexedNotNull { index, result ->
if (result is Try.Success) {
val signers = result.value.map { it.by }

View File

@ -44,7 +44,7 @@ class RaftNotaryServiceTests {
val firstSpendTx = bankA.services.signInitialTransaction(firstTxBuilder)
val firstSpend = bankA.services.startFlow(NotaryFlow.Client(firstSpendTx))
firstSpend.resultFuture.getOrThrow()
firstSpend.getOrThrow()
val secondSpendBuilder = TransactionBuilder(defaultNotaryIdentity).withItems(inputState).run {
val dummyState = DummyContract.SingleOwnerState(0, bankA.info.chooseIdentity())
@ -55,7 +55,7 @@ class RaftNotaryServiceTests {
val secondSpendTx = bankA.services.signInitialTransaction(secondSpendBuilder)
val secondSpend = bankA.services.startFlow(NotaryFlow.Client(secondSpendTx))
val ex = assertFailsWith(NotaryException::class) { secondSpend.resultFuture.getOrThrow() }
val ex = assertFailsWith(NotaryException::class) { secondSpend.getOrThrow() }
val error = ex.error as NotaryError.Conflict
assertEquals(error.txId, secondSpendTx.id)
}

View File

@ -22,7 +22,7 @@ class FlowVersioningTest : NodeBasedTest() {
val bob = startNode(BOB_NAME, platformVersion = 3)
bob.internals.installCoreFlow(PretendInitiatingCoreFlow::class, ::PretendInitiatedCoreFlow)
val (alicePlatformVersionAccordingToBob, bobPlatformVersionAccordingToAlice) = alice.services.startFlow(
PretendInitiatingCoreFlow(bob.info.chooseIdentity())).resultFuture.getOrThrow()
PretendInitiatingCoreFlow(bob.info.chooseIdentity())).getOrThrow()
assertThat(alicePlatformVersionAccordingToBob).isEqualTo(2)
assertThat(bobPlatformVersionAccordingToAlice).isEqualTo(3)
}

View File

@ -3,9 +3,7 @@ package net.corda.services.messaging
import co.paralleluniverse.fibers.Suspendable
import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCConnection
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.random63BitValue
import net.corda.core.crypto.toStringShort
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.flows.InitiatedBy
@ -193,7 +191,7 @@ abstract class MQSecurityTest : NodeBasedTest() {
bob.registerInitiatedFlow(ReceiveFlow::class.java)
val bobParty = bob.info.chooseIdentity()
// Perform a protocol exchange to force the peer queue to be created
alice.services.startFlow(SendFlow(bobParty, 0)).resultFuture.getOrThrow()
alice.services.startFlow(SendFlow(bobParty, 0)).getOrThrow()
return bobParty
}

View File

@ -67,7 +67,7 @@ class NetworkParametersTest {
val alice = mockNet.createPartyNode(ALICE_NAME)
assertThat(alice.services.networkMapCache.notaryIdentities).doesNotContain(fakeNotaryId)
assertFails {
alice.services.startFlow(CashIssueFlow(500.DOLLARS, OpaqueBytes.of(0x01), fakeNotaryId)).resultFuture.getOrThrow()
alice.services.startFlow(CashIssueFlow(500.DOLLARS, OpaqueBytes.of(0x01), fakeNotaryId)).getOrThrow()
}
}

View File

@ -536,7 +536,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.registerInitiatedFlow(BuyerAcceptor::class.java)
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine }
val seller = SellerInitiator(buyer, notary, assetToSell, 1000.DOLLARS, anonymous)
val sellerResult = sellerNode.services.startFlow(seller).resultFuture
val sellerResult = sellerNode.services.startFlow(seller)
return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id)
}

View File

@ -74,7 +74,7 @@ class NotaryChangeTests {
mockNet.runNetwork()
val newState = future.resultFuture.getOrThrow()
val newState = future.getOrThrow()
assertEquals(newState.state.notary, newNotary)
val loadedStateA = clientNodeA.services.loadState(newState.ref)
val loadedStateB = clientNodeB.services.loadState(newState.ref)
@ -91,7 +91,7 @@ class NotaryChangeTests {
mockNet.runNetwork()
assertThatExceptionOfType(StateReplacementException::class.java).isThrownBy {
future.resultFuture.getOrThrow()
future.getOrThrow()
}
}
@ -104,7 +104,7 @@ class NotaryChangeTests {
val flow = NotaryChangeFlow(state, newNotary)
val future = clientNodeA.services.startFlow(flow)
mockNet.runNetwork()
val newState = future.resultFuture.getOrThrow()
val newState = future.getOrThrow()
assertEquals(newState.state.notary, newNotary)
val recordedTx = clientNodeA.services.validatedTransactions.getTransaction(newState.ref.txhash)!!
@ -150,7 +150,7 @@ class NotaryChangeTests {
val future = node.services.startFlow(flow)
mockNet.runNetwork()
return future.resultFuture.getOrThrow()
return future.getOrThrow()
}
private fun moveState(state: StateAndRef<DummyContract.SingleOwnerState>, fromNode: StartedNode<*>, toNode: StartedNode<*>): StateAndRef<DummyContract.SingleOwnerState> {
@ -161,7 +161,7 @@ class NotaryChangeTests {
val future = fromNode.services.startFlow(notaryFlow)
mockNet.runNetwork()
val notarySignature = future.resultFuture.getOrThrow()
val notarySignature = future.getOrThrow()
val finalTransaction = stx + notarySignature
fromNode.services.recordTransactions(finalTransaction)

View File

@ -143,8 +143,8 @@ class ScheduledFlowTests {
val N = 100
val futures = mutableListOf<CordaFuture<*>>()
for (i in 0 until N) {
futures.add(aliceNode.services.startFlow(InsertInitialStateFlow(bob, notary)).resultFuture)
futures.add(bobNode.services.startFlow(InsertInitialStateFlow(alice, notary)).resultFuture)
futures.add(aliceNode.services.startFlow(InsertInitialStateFlow(bob, notary)))
futures.add(bobNode.services.startFlow(InsertInitialStateFlow(alice, notary)))
}
mockNet.waitQuiescent()

View File

@ -38,7 +38,7 @@ import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.pumpReceive
import net.corda.testing.node.startFlow
import net.corda.testing.node.internal.startFlow
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType

View File

@ -19,8 +19,8 @@ import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.dummyCommand
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.startFlow
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.startFlow
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Before
@ -120,11 +120,11 @@ class NotaryServiceTests {
// Note that the notary will only return identical signatures when using deterministic signature
// schemes (e.g. EdDSA) and when deterministic metadata is attached (no timestamps or nonces).
// We only really care that both signatures are over the same transaction and by the same notary.
val sig1 = f1.resultFuture.getOrThrow().single()
val sig1 = f1.getOrThrow().single()
assertEquals(sig1.by, notary.owningKey)
assertTrue(sig1.isValid(stx.id))
val sig2 = f2.resultFuture.getOrThrow().single()
val sig2 = f2.getOrThrow().single()
assertEquals(sig2.by, notary.owningKey)
assertTrue(sig2.isValid(stx.id))
}
@ -153,7 +153,7 @@ class NotaryServiceTests {
mockNet.runNetwork()
val ex = assertFailsWith(NotaryException::class) { future.resultFuture.getOrThrow() }
val ex = assertFailsWith(NotaryException::class) { future.getOrThrow() }
val notaryError = ex.error as NotaryError.Conflict
assertEquals(notaryError.txId, stx2.id)
notaryError.conflict.verified()
@ -161,7 +161,7 @@ class NotaryServiceTests {
private fun runNotaryClient(stx: SignedTransaction): CordaFuture<List<TransactionSignature>> {
val flow = NotaryFlow.Client(stx)
val future = aliceServices.startFlow(flow).resultFuture
val future = aliceServices.startFlow(flow)
mockNet.runNetwork()
return future
}

View File

@ -94,7 +94,7 @@ class ValidatingNotaryServiceTests {
private fun runClient(stx: SignedTransaction): CordaFuture<List<TransactionSignature>> {
val flow = NotaryFlow.Client(stx)
val future = aliceServices.startFlow(flow).resultFuture
val future = aliceServices.startFlow(flow)
mockNet.runNetwork()
return future
}

View File

@ -227,7 +227,7 @@ class NodeInterestRatesTest {
val flow = FilteredRatesFlow(tx, oracle, fixOf, BigDecimal("0.675"), BigDecimal("0.1"))
LogHelper.setLevel("rates")
mockNet.runNetwork()
val future = aliceNode.services.startFlow(flow).resultFuture
val future = aliceNode.services.startFlow(flow)
mockNet.runNetwork()
future.getOrThrow()
// We should now have a valid fix of our tx from the oracle.

View File

@ -160,7 +160,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
val instigator = StartDealFlow(
node2.info.chooseIdentity(),
AutoOffer(mockNet.defaultNotaryIdentity, irs)) // TODO Pass notary as parameter to Simulation.
val instigatorTxFuture = node1.services.startFlow(instigator).resultFuture
val instigatorTxFuture = node1.services.startFlow(instigator)
return allOf(instigatorTxFuture.toCompletableFuture(), acceptorTxFuture).thenCompose { instigatorTxFuture.toCompletableFuture() }
}

View File

@ -290,7 +290,7 @@ class FlowStackSnapshotTest {
val mockNet = MockNetwork(emptyList(), threadPerNode = true)
val node = mockNet.createPartyNode()
node.registerInitiatedFlow(DummyFlow::class.java)
node.services.startFlow(FlowStackSnapshotSerializationTestingFlow()).resultFuture.get()
node.services.startFlow(FlowStackSnapshotSerializationTestingFlow()).get()
val thrown = try {
// Due to the [MockNetwork] implementation, the easiest way to trigger object serialization process is at
// the network stopping stage.

View File

@ -2,6 +2,7 @@
package net.corda.testing.node
import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.Actor
import net.corda.core.context.AuthServiceId
import net.corda.core.context.InvocationContext
@ -60,13 +61,9 @@ fun testActor(owningLegalIdentity: CordaX500Name = CordaX500Name("Test Company I
fun testContext(owningLegalIdentity: CordaX500Name = CordaX500Name("Test Company Inc.", "London", "GB")) = InvocationContext.rpc(testActor(owningLegalIdentity))
/**
* Starts an already constructed flow. Note that you must be on the server thread to call this method. [InvocationContext]
* has origin [InvocationOrigin.RPC] and actor with id "Only For Testing".
*/
fun <T> StartedNodeServices.startFlow(logic: FlowLogic<T>): FlowStateMachine<T> = startFlow(logic, newContext()).getOrThrow()
/**
* Creates a new [InvocationContext] for testing purposes.
*/
fun StartedNodeServices.newContext() = testContext(myInfo.chooseIdentity().name)
fun <T> StartedNodeServices.startFlow(logic: FlowLogic<T>): CordaFuture<T> = startFlow(logic, newContext()).getOrThrow().resultFuture

View File

@ -2,12 +2,18 @@ package net.corda.testing.node.internal
import net.corda.core.CordaException
import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.InvocationContext
import net.corda.core.context.InvocationOrigin
import net.corda.core.flows.FlowLogic
import net.corda.core.internal.FlowStateMachine
import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.times
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.millis
import net.corda.core.utilities.seconds
import net.corda.node.services.api.StartedNodeServices
import net.corda.testing.node.newContext
import org.slf4j.LoggerFactory
import java.net.Socket
import java.net.SocketException
@ -91,3 +97,5 @@ fun <A> poll(
class ListenProcessDeathException(hostAndPort: NetworkHostAndPort, listenProcess: Process) :
CordaException("The process that was expected to listen on $hostAndPort has died with status: ${listenProcess.exitValue()}")
fun <T> StartedNodeServices.startFlow(logic: FlowLogic<T>): FlowStateMachine<T> = startFlow(logic, newContext()).getOrThrow()