ENT-10306 Determine whether to use 2PF based on the execution CorDapp TPV. (#7447)

This commit is contained in:
Jose Coll 2023-08-21 09:11:00 +01:00 committed by GitHub
parent d2029b3e0c
commit a6786769e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 18 deletions

View File

@ -30,7 +30,7 @@ import java.util.*
class ContractUpgradeFlowTest : WithContracts, WithFinality { class ContractUpgradeFlowTest : WithContracts, WithFinality {
companion object { companion object {
private val classMockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP, DUMMY_CONTRACTS_CORDAPP, enclosedCordapp())) private val classMockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP, DUMMY_CONTRACTS_CORDAPP, enclosedCordapp()))
@JvmStatic @JvmStatic
@AfterClass @AfterClass

View File

@ -40,6 +40,7 @@ import net.corda.core.utilities.unwrap
import net.corda.coretesting.internal.matchers.flow.willReturn import net.corda.coretesting.internal.matchers.flow.willReturn
import net.corda.coretesting.internal.matchers.flow.willThrow import net.corda.coretesting.internal.matchers.flow.willThrow
import net.corda.coretests.flows.WithFinality.FinalityInvoker import net.corda.coretests.flows.WithFinality.FinalityInvoker
import net.corda.coretests.flows.WithFinality.OldFinalityInvoker
import net.corda.finance.GBP import net.corda.finance.GBP
import net.corda.finance.POUNDS import net.corda.finance.POUNDS
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
@ -59,7 +60,6 @@ import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.CHARLIE_NAME import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.TestIdentity import net.corda.testing.core.TestIdentity
import net.corda.testing.core.singleIdentity import net.corda.testing.core.singleIdentity
import net.corda.testing.node.internal.CustomCordapp
import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.FINANCE_WORKFLOWS_CORDAPP import net.corda.testing.node.internal.FINANCE_WORKFLOWS_CORDAPP
@ -87,9 +87,7 @@ class FinalityFlowTests : WithFinality {
} }
override val mockNet = InternalMockNetwork(cordappsForAllNodes = setOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP, DUMMY_CONTRACTS_CORDAPP, enclosedCordapp(), override val mockNet = InternalMockNetwork(cordappsForAllNodes = setOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP, DUMMY_CONTRACTS_CORDAPP, enclosedCordapp(),
findCordapp("net.corda.finance.test.flows"), findCordapp("net.corda.finance.test.flows")))
CustomCordapp(targetPlatformVersion = 3, classes = setOf(FinalityFlow::class.java))))
private val aliceNode = makeNode(ALICE_NAME) private val aliceNode = makeNode(ALICE_NAME)
private val notary = mockNet.defaultNotaryIdentity private val notary = mockNet.defaultNotaryIdentity
@ -124,7 +122,7 @@ class FinalityFlowTests : WithFinality {
val oldBob = createBob(cordapps = listOf(tokenOldCordapp())) val oldBob = createBob(cordapps = listOf(tokenOldCordapp()))
val stx = aliceNode.issuesCashTo(oldBob) val stx = aliceNode.issuesCashTo(oldBob)
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
aliceNode.startFlowAndRunNetwork(FinalityFlow(stx)).resultFuture.getOrThrow() aliceNode.startFlowAndRunNetwork(OldFinalityInvoker(stx)).resultFuture.getOrThrow()
assertThat(oldBob.services.validatedTransactions.getTransaction(stx.id)).isNotNull assertThat(oldBob.services.validatedTransactions.getTransaction(stx.id)).isNotNull
} }

View File

@ -4,7 +4,13 @@ import co.paralleluniverse.fibers.Suspendable
import com.natpryce.hamkrest.MatchResult import com.natpryce.hamkrest.MatchResult
import com.natpryce.hamkrest.Matcher import com.natpryce.hamkrest.Matcher
import com.natpryce.hamkrest.equalTo import com.natpryce.hamkrest.equalTo
import net.corda.core.flows.* import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.ReceiveFinalityFlow
import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.FlowStateMachineHandle import net.corda.core.internal.FlowStateMachineHandle
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
@ -58,4 +64,13 @@ interface WithFinality : WithMockNet {
subFlow(ReceiveFinalityFlow(otherSide)) subFlow(ReceiveFinalityFlow(otherSide))
} }
} }
@StartableByRPC
class OldFinalityInvoker(private val transaction: SignedTransaction) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
@Suppress("DEPRECATION")
return subFlow(FinalityFlow(transaction))
}
}
} }

View File

@ -219,6 +219,7 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
val requiresNotarisation = needsNotarySignature(transaction) val requiresNotarisation = needsNotarySignature(transaction)
val useTwoPhaseFinality = serviceHub.myInfo.platformVersion >= PlatformVersionSwitches.TWO_PHASE_FINALITY val useTwoPhaseFinality = serviceHub.myInfo.platformVersion >= PlatformVersionSwitches.TWO_PHASE_FINALITY
&& serviceHub.getAppContext().cordapp.targetPlatformVersion >= PlatformVersionSwitches.TWO_PHASE_FINALITY
if (useTwoPhaseFinality) { if (useTwoPhaseFinality) {
val stxn = if (requiresNotarisation) { val stxn = if (requiresNotarisation) {
@ -250,6 +251,7 @@ class FinalityFlow private constructor(val transaction: SignedTransaction,
return stxn return stxn
} }
else { else {
logger.warnOnce("The current usage of FinalityFlow is not using Two Phase Finality. Please consider upgrading your CorDapp (refer to Corda 4.11 release notes).")
val stxn = if (requiresNotarisation) { val stxn = if (requiresNotarisation) {
notarise().first notarise().first
} else transaction } else transaction
@ -501,6 +503,8 @@ class ReceiveFinalityFlow(private val otherSideSession: FlowSession,
val requiresNotarisation = needsNotarySignature(stx) val requiresNotarisation = needsNotarySignature(stx)
val fromTwoPhaseFinalityNode = serviceHub.networkMapCache.getNodeByLegalIdentity(otherSideSession.counterparty)?.platformVersion!! >= PlatformVersionSwitches.TWO_PHASE_FINALITY val fromTwoPhaseFinalityNode = serviceHub.networkMapCache.getNodeByLegalIdentity(otherSideSession.counterparty)?.platformVersion!! >= PlatformVersionSwitches.TWO_PHASE_FINALITY
&& serviceHub.getAppContext().cordapp.targetPlatformVersion >= PlatformVersionSwitches.TWO_PHASE_FINALITY
if (fromTwoPhaseFinalityNode) { if (fromTwoPhaseFinalityNode) {
if (requiresNotarisation) { if (requiresNotarisation) {
serviceHub.telemetryServiceInternal.span("${this::class.java.name}#recordUnnotarisedTransaction", flowLogic = this) { serviceHub.telemetryServiceInternal.span("${this::class.java.name}#recordUnnotarisedTransaction", flowLogic = this) {
@ -537,6 +541,7 @@ class ReceiveFinalityFlow(private val otherSideSession: FlowSession,
otherSideSession.send(FetchDataFlow.Request.End) // Finish fetching data (deferredAck) otherSideSession.send(FetchDataFlow.Request.End) // Finish fetching data (deferredAck)
} }
} else { } else {
logger.warnOnce("The current usage of ReceiveFinalityFlow is not using Two Phase Finality. Please consider upgrading your CorDapp (refer to Corda 4.11 release notes).")
serviceHub.telemetryServiceInternal.span("${this::class.java.name}#recordTransactions", flowLogic = this) { serviceHub.telemetryServiceInternal.span("${this::class.java.name}#recordTransactions", flowLogic = this) {
serviceHub.recordTransactions(statesToRecord, setOf(stx)) serviceHub.recordTransactions(statesToRecord, setOf(stx))
} }

View File

@ -72,6 +72,7 @@ import net.corda.testing.internal.IS_OPENJ9
import net.corda.testing.internal.LogHelper import net.corda.testing.internal.LogHelper
import net.corda.testing.internal.vault.VaultFiller import net.corda.testing.internal.vault.VaultFiller
import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.FINANCE_WORKFLOWS_CORDAPP
import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.InternalMockNodeParameters import net.corda.testing.node.internal.InternalMockNodeParameters
import net.corda.testing.node.internal.TestStartedNode import net.corda.testing.node.internal.TestStartedNode
@ -141,7 +142,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
// We run this in parallel threads to help catch any race conditions that may exist. The other tests // We run this in parallel threads to help catch any race conditions that may exist. The other tests
// we run in the unit test thread exclusively to speed things up, ensure deterministic results and // we run in the unit test thread exclusively to speed things up, ensure deterministic results and
// allow interruption half way through. // allow interruption half way through.
mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP), threadPerNode = true) mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP), threadPerNode = true)
val notaryNode = mockNet.defaultNotaryNode val notaryNode = mockNet.defaultNotaryNode
val notary = mockNet.defaultNotaryIdentity val notary = mockNet.defaultNotaryIdentity
notaryNode.services.ledger(notary) { notaryNode.services.ledger(notary) {
@ -248,7 +249,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `shutdown and restore`() { fun `shutdown and restore`() {
Assume.assumeTrue(!IS_OPENJ9) Assume.assumeTrue(!IS_OPENJ9)
mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP)) mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP))
val notaryNode = mockNet.defaultNotaryNode val notaryNode = mockNet.defaultNotaryNode
val notary = mockNet.defaultNotaryIdentity val notary = mockNet.defaultNotaryIdentity
notaryNode.services.ledger(notary) { notaryNode.services.ledger(notary) {

View File

@ -13,6 +13,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.issuedBy import net.corda.finance.issuedBy
import net.corda.testing.node.internal.CustomCordapp
import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.startFlow import net.corda.testing.node.internal.startFlow
@ -23,7 +24,8 @@ import rx.schedulers.Schedulers
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
class ServiceHubConcurrentUsageTest { class ServiceHubConcurrentUsageTest {
private val mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP)) private val mockNet = InternalMockNetwork(cordappsForAllNodes = listOf(FINANCE_CONTRACTS_CORDAPP,
CustomCordapp(classes = setOf(TestFlow::class.java))))
@After @After
fun stopNodes() { fun stopNodes() {

View File

@ -75,7 +75,9 @@ class TimedFlowTests {
@JvmStatic @JvmStatic
fun setup() { fun setup() {
mockNet = InternalMockNetwork( mockNet = InternalMockNetwork(
cordappsForAllNodes = listOf(DUMMY_CONTRACTS_CORDAPP, enclosedCordapp()), cordappsForAllNodes = listOf(DUMMY_CONTRACTS_CORDAPP,
CustomCordapp(classes = setOf(FinalityFlow::class.java)),
enclosedCordapp()),
defaultParameters = MockNetworkParameters().withServicePeerAllocationStrategy(InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin()), defaultParameters = MockNetworkParameters().withServicePeerAllocationStrategy(InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin()),
threadPerNode = true threadPerNode = true
) )

View File

@ -58,6 +58,7 @@ import net.corda.testing.internal.IS_OPENJ9
import net.corda.testing.internal.LogHelper import net.corda.testing.internal.LogHelper
import net.corda.testing.node.InMemoryMessagingNetwork.MessageTransfer import net.corda.testing.node.InMemoryMessagingNetwork.MessageTransfer
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.internal.CustomCordapp
import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP import net.corda.testing.node.internal.DUMMY_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.InternalMockNetwork
@ -124,7 +125,7 @@ class FlowFrameworkTests {
@Before @Before
fun setUpMockNet() { fun setUpMockNet() {
mockNet = InternalMockNetwork( mockNet = InternalMockNetwork(
cordappsForAllNodes = listOf(DUMMY_CONTRACTS_CORDAPP, FINANCE_CONTRACTS_CORDAPP), cordappsForAllNodes = listOf(DUMMY_CONTRACTS_CORDAPP, FINANCE_CONTRACTS_CORDAPP, CustomCordapp(setOf("net.corda.node.services.statemachine"))),
servicePeerAllocationStrategy = RoundRobin() servicePeerAllocationStrategy = RoundRobin()
) )

View File

@ -1,10 +1,10 @@
apply plugin: 'kotlin' apply plugin: 'kotlin'
//apply plugin: 'net.corda.plugins.cordapp' apply plugin: 'net.corda.plugins.cordapp'
//apply plugin: 'net.corda.plugins.quasar-utils' //apply plugin: 'net.corda.plugins.quasar-utils'
dependencies { dependencies {
compile project(":core") cordaCompile project(":core")
compile project(':finance:workflows') cordapp project(':finance:workflows')
} }
jar { jar {
@ -14,4 +14,18 @@ jar {
// Driver will not include it as part of an out-of-process node. // Driver will not include it as part of an out-of-process node.
attributes('Corda-Testing': true) attributes('Corda-Testing': true)
} }
}
cordapp {
targetPlatformVersion corda_platform_version.toInteger()
minimumPlatformVersion 1
workflow {
name "Corda Cash Observers Test CorDapp"
versionId 1
vendor "R3"
licence "Open Source (Apache 2)"
}
signing {
enabled false
}
} }

View File

@ -1,10 +1,10 @@
apply plugin: 'kotlin' apply plugin: 'kotlin'
//apply plugin: 'net.corda.plugins.cordapp' apply plugin: 'net.corda.plugins.cordapp'
//apply plugin: 'net.corda.plugins.quasar-utils' //apply plugin: 'net.corda.plugins.quasar-utils'
dependencies { dependencies {
compile project(":core") cordaCompile project(":core")
compile project(":testing:cordapps:dbfailure:dbfcontracts") cordapp project(":testing:cordapps:dbfailure:dbfcontracts")
} }
jar { jar {
@ -14,4 +14,18 @@ jar {
// Driver will not include it as part of an out-of-process node. // Driver will not include it as part of an out-of-process node.
attributes('Corda-Testing': true) attributes('Corda-Testing': true)
} }
}
cordapp {
targetPlatformVersion corda_platform_version.toInteger()
minimumPlatformVersion 1
workflow {
name "Corda DB Failure Test CorDapp"
versionId 1
vendor "R3"
licence "Open Source (Apache 2)"
}
signing {
enabled false
}
} }