mirror of
https://github.com/corda/corda.git
synced 2025-04-16 07:27:17 +00:00
ENT-2198 Add more benchmarks to the overnight performance run (#1313)
This commit is contained in:
parent
30aad25841
commit
2acd89850a
@ -0,0 +1,65 @@
|
||||
package com.r3.corda.enterprise.perftestcordapp.flows
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
|
||||
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.OnLedgerAsset
|
||||
import com.r3.corda.enterprise.perftestcordapp.contracts.asset.PartyAndAmount
|
||||
import net.corda.confidential.SwapIdentitiesFlow
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.Issued
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionState
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import java.util.*
|
||||
|
||||
@StartableByRPC
|
||||
class CashPaymentFromKnownStatesFlow(
|
||||
val inputs: Set<StateRef>,
|
||||
val numberOfStates: Int,
|
||||
val amountPerState: Amount<Currency>,
|
||||
val recipient: Party,
|
||||
val anonymous: Boolean,
|
||||
progressTracker: ProgressTracker) : AbstractCashFlow<AbstractCashFlow.Result>(progressTracker) {
|
||||
|
||||
constructor(inputs: Set<StateRef>,
|
||||
numberOfStates: Int,
|
||||
amountPerState: Amount<Currency>,
|
||||
recipient: Party,
|
||||
anonymous: Boolean) : this(inputs, numberOfStates, amountPerState, recipient, anonymous, tracker())
|
||||
|
||||
@Suspendable
|
||||
override fun call(): AbstractCashFlow.Result {
|
||||
fun deriveState(txState: TransactionState<Cash.State>, amt: Amount<Issued<Currency>>, owner: AbstractParty) = txState.copy(data = txState.data.copy(amount = amt, owner = owner))
|
||||
|
||||
progressTracker.currentStep = AbstractCashFlow.Companion.GENERATING_ID
|
||||
val txIdentities = if (anonymous) {
|
||||
subFlow(SwapIdentitiesFlow(recipient))
|
||||
} else {
|
||||
emptyMap<Party, AnonymousParty>()
|
||||
}
|
||||
val anonymousRecipient = txIdentities[recipient] ?: recipient
|
||||
progressTracker.currentStep = AbstractCashFlow.Companion.GENERATING_TX
|
||||
val builder = TransactionBuilder(notary = null)
|
||||
|
||||
val cashStateAndRef = inputs.map { serviceHub.toStateAndRef<Cash.State>(it) }
|
||||
val amounts = ArrayList(Collections.nCopies(numberOfStates, PartyAndAmount(anonymousRecipient, amountPerState)))
|
||||
val changeIdentity = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false)
|
||||
|
||||
val (spendTx, keysForSigning) = OnLedgerAsset.generateSpend(builder, amounts, cashStateAndRef,
|
||||
changeIdentity.party.anonymise(),
|
||||
{ state, quantity, owner -> deriveState(state, quantity, owner) },
|
||||
{ Cash().generateMoveCommand() })
|
||||
|
||||
progressTracker.currentStep = AbstractCashFlow.Companion.SIGNING_TX
|
||||
val tx = serviceHub.signInitialTransaction(spendTx, keysForSigning)
|
||||
|
||||
progressTracker.currentStep = AbstractCashFlow.Companion.FINALISING_TX
|
||||
val notarised = finaliseTx(tx, setOf(recipient), "Unable to notarise spend")
|
||||
return AbstractCashFlow.Result(notarised.id, anonymousRecipient)
|
||||
}
|
||||
}
|
@ -50,6 +50,8 @@ abstract class BaseFlowSampler : AbstractJavaSamplerClient() {
|
||||
|
||||
private var labelValue: String? = null
|
||||
|
||||
protected open var flowResult: Any? = null
|
||||
|
||||
override fun getDefaultParameters(): Arguments {
|
||||
// Add copies of all args, since they seem to be mutable.
|
||||
return Arguments().apply {
|
||||
@ -96,13 +98,14 @@ abstract class BaseFlowSampler : AbstractJavaSamplerClient() {
|
||||
result.sampleLabel = labelValue ?: flowInvoke.flowLogicClass.simpleName
|
||||
result.latencyEnd()
|
||||
try {
|
||||
val flowResult = handle.returnValue.get()
|
||||
flowResult = handle.returnValue.get()
|
||||
result.sampleEnd()
|
||||
result.apply {
|
||||
isSuccessful = true
|
||||
additionalFlowResponseProcessing(context, this, flowResult)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
flowResult = null
|
||||
result.sampleEnd()
|
||||
e.printStackTrace()
|
||||
result.apply {
|
||||
|
@ -13,10 +13,12 @@ package com.r3.corda.jmeter
|
||||
import com.r3.corda.enterprise.perftestcordapp.DOLLARS
|
||||
import com.r3.corda.enterprise.perftestcordapp.POUNDS
|
||||
import com.r3.corda.enterprise.perftestcordapp.flows.*
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.messaging.CordaRPCOps
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import org.apache.jmeter.config.Argument
|
||||
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext
|
||||
import org.apache.jmeter.samplers.SampleResult
|
||||
@ -90,8 +92,8 @@ class CashIssueSampler : AbstractSampler() {
|
||||
class CashIssueAndPaySampler : AbstractSampler() {
|
||||
companion object JMeterProperties {
|
||||
val otherParty = Argument("otherPartyName", "", "<meta>", "The X500 name of the payee.")
|
||||
val coinSelection = Argument("useCoinSelection", "true", "<meta>", "True to use coin selection and false (or anything else) to avoid coin selection.")
|
||||
val anonymousIdentities = Argument("anonymousIdentities", "true", "<meta>", "True to use anonymous identities and false (or anything else) to use well known identities.")
|
||||
val coinSelection = Argument("useCoinSelection", "false", "<meta>", "True to use coin selection and false (or anything else) to avoid coin selection.")
|
||||
val anonymousIdentities = Argument("anonymousIdentities", "false", "<meta>", "True to use anonymous identities and false (or anything else) to use well known identities.")
|
||||
}
|
||||
|
||||
lateinit var counterParty: Party
|
||||
@ -233,3 +235,50 @@ class LinearStateBatchNotariseSampler : AbstractSampler() {
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sampler that issues cash once per sampler, and then generates a transaction to pay 1 dollar "numberOfStatesPerTx" times
|
||||
* to a specified party per sample, thus invoking the notary and the payee via P2P.
|
||||
*
|
||||
* This allows us to test performance with different numbers of states per transaction, and to eliminate issuance from
|
||||
* each sample (unlike CashIssueAndPaySampler).
|
||||
*/
|
||||
class CashPaySampler : AbstractSampler() {
|
||||
companion object JMeterProperties {
|
||||
val otherParty = Argument("otherPartyName", "", "<meta>", "The X500 name of the payee.")
|
||||
val numberOfStatesPerTx = Argument("numberOfStatesPerTx", "1", "<meta>", "The number of payment states per transaction.")
|
||||
val anonymousIdentities = Argument("anonymousIdentities", "false", "<meta>", "True to use anonymous identities and false (or anything else) to use well known identities.")
|
||||
}
|
||||
|
||||
lateinit var counterParty: Party
|
||||
var numberOfStatesPerTxCount: Int = 1
|
||||
var useAnonymousIdentities: Boolean = true
|
||||
private var inputIndex = 0
|
||||
|
||||
override fun setupTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) {
|
||||
getNotaryIdentity(rpcProxy, testContext)
|
||||
counterParty = getIdentity(rpcProxy, testContext, otherParty)
|
||||
numberOfStatesPerTxCount = testContext.getParameter(numberOfStatesPerTx.name, numberOfStatesPerTx.value).toInt()
|
||||
useAnonymousIdentities = testContext.getParameter(anonymousIdentities.name, anonymousIdentities.value).toBoolean()
|
||||
|
||||
// Now issue lots of USD
|
||||
val amount = 1_000_000_000.DOLLARS
|
||||
val flowInvoke = FlowInvoke<CashIssueFlow>(CashIssueFlow::class.java, arrayOf(amount, OpaqueBytes.of(1), notaryIdentity))
|
||||
val handle = rpcProxy.startFlowDynamic(flowInvoke.flowLogicClass, *(flowInvoke.args))
|
||||
flowResult = handle.returnValue.getOrThrow()
|
||||
}
|
||||
|
||||
override fun createFlowInvoke(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext): FlowInvoke<*> {
|
||||
// Change is always Nth output
|
||||
val input = StateRef((flowResult as AbstractCashFlow.Result).id, inputIndex)
|
||||
val amount = 1.DOLLARS
|
||||
inputIndex = numberOfStatesPerTxCount
|
||||
return FlowInvoke<CashPaymentFromKnownStatesFlow>(CashPaymentFromKnownStatesFlow::class.java, arrayOf(setOf(input), numberOfStatesPerTxCount, amount, counterParty, useAnonymousIdentities))
|
||||
}
|
||||
|
||||
override fun teardownTest(rpcProxy: CordaRPCOps, testContext: JavaSamplerContext) {
|
||||
}
|
||||
|
||||
override val additionalArgs: Set<Argument>
|
||||
get() = setOf(notary, otherParty, numberOfStatesPerTx, anonymousIdentities)
|
||||
}
|
@ -61,7 +61,7 @@
|
||||
</collectionProp>
|
||||
</Arguments>
|
||||
<hashTree/>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Empty Flow 200 Thread Group ${__machineName}" enabled="false">
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Empty Flow 200 Thread Group ${__machineName}" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
@ -542,7 +542,7 @@
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Cash Issue 200 Thread Group ${__machineName}" enabled="false">
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Cash Issue 200 Thread Group ${__machineName}" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
@ -649,9 +649,9 @@
|
||||
<stringProp name="Argument.value">${otherPartyName}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="useCoinSelection" elementType="Argument">
|
||||
<stringProp name="Argument.name">useCoinSelection</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<elementProp name="numberOfStatesPerTx" elementType="Argument">
|
||||
<stringProp name="Argument.name">numberOfStatesPerTx</stringProp>
|
||||
<stringProp name="Argument.value">1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="anonymousIdentities" elementType="Argument">
|
||||
@ -661,7 +661,7 @@
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashIssueAndPaySampler</stringProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashPaySampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
@ -718,9 +718,9 @@
|
||||
<stringProp name="Argument.value">${otherPartyName}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="useCoinSelection" elementType="Argument">
|
||||
<stringProp name="Argument.name">useCoinSelection</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<elementProp name="numberOfStatesPerTx" elementType="Argument">
|
||||
<stringProp name="Argument.name">numberOfStatesPerTx</stringProp>
|
||||
<stringProp name="Argument.value">1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="anonymousIdentities" elementType="Argument">
|
||||
@ -730,7 +730,7 @@
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashIssueAndPaySampler</stringProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashPaySampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
@ -787,9 +787,9 @@
|
||||
<stringProp name="Argument.value">${otherPartyName}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="useCoinSelection" elementType="Argument">
|
||||
<stringProp name="Argument.name">useCoinSelection</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<elementProp name="numberOfStatesPerTx" elementType="Argument">
|
||||
<stringProp name="Argument.name">numberOfStatesPerTx</stringProp>
|
||||
<stringProp name="Argument.value">1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="anonymousIdentities" elementType="Argument">
|
||||
@ -799,7 +799,7 @@
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashIssueAndPaySampler</stringProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashPaySampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
@ -856,9 +856,9 @@
|
||||
<stringProp name="Argument.value">${otherPartyName}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="useCoinSelection" elementType="Argument">
|
||||
<stringProp name="Argument.name">useCoinSelection</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<elementProp name="numberOfStatesPerTx" elementType="Argument">
|
||||
<stringProp name="Argument.name">numberOfStatesPerTx</stringProp>
|
||||
<stringProp name="Argument.value">1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="anonymousIdentities" elementType="Argument">
|
||||
@ -868,7 +868,7 @@
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashIssueAndPaySampler</stringProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashPaySampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
@ -925,9 +925,9 @@
|
||||
<stringProp name="Argument.value">${otherPartyName}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="useCoinSelection" elementType="Argument">
|
||||
<stringProp name="Argument.name">useCoinSelection</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<elementProp name="numberOfStatesPerTx" elementType="Argument">
|
||||
<stringProp name="Argument.name">numberOfStatesPerTx</stringProp>
|
||||
<stringProp name="Argument.value">1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="anonymousIdentities" elementType="Argument">
|
||||
@ -937,7 +937,7 @@
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashIssueAndPaySampler</stringProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashPaySampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
@ -994,9 +994,9 @@
|
||||
<stringProp name="Argument.value">${otherPartyName}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="useCoinSelection" elementType="Argument">
|
||||
<stringProp name="Argument.name">useCoinSelection</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<elementProp name="numberOfStatesPerTx" elementType="Argument">
|
||||
<stringProp name="Argument.name">numberOfStatesPerTx</stringProp>
|
||||
<stringProp name="Argument.value">1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="anonymousIdentities" elementType="Argument">
|
||||
@ -1006,7 +1006,7 @@
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashIssueAndPaySampler</stringProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashPaySampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
@ -1063,9 +1063,9 @@
|
||||
<stringProp name="Argument.value">${otherPartyName}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="useCoinSelection" elementType="Argument">
|
||||
<stringProp name="Argument.name">useCoinSelection</stringProp>
|
||||
<stringProp name="Argument.value">false</stringProp>
|
||||
<elementProp name="numberOfStatesPerTx" elementType="Argument">
|
||||
<stringProp name="Argument.name">numberOfStatesPerTx</stringProp>
|
||||
<stringProp name="Argument.value">1</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="anonymousIdentities" elementType="Argument">
|
||||
@ -1075,7 +1075,7 @@
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashIssueAndPaySampler</stringProp>
|
||||
<stringProp name="classname">com.r3.corda.jmeter.CashPaySampler</stringProp>
|
||||
</JavaSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
|
Loading…
x
Reference in New Issue
Block a user