mirror of
https://github.com/corda/corda.git
synced 2025-04-08 03:44:49 +00:00
Apply @Suspendable on all flow methods that call vault generateSpend (#612)
This commit is contained in:
parent
0612f147be
commit
3d401d1dcb
@ -1,5 +1,6 @@
|
||||
package net.corda.contracts;
|
||||
|
||||
import co.paralleluniverse.fibers.*;
|
||||
import com.google.common.collect.*;
|
||||
import kotlin.*;
|
||||
import net.corda.contracts.asset.*;
|
||||
@ -311,6 +312,7 @@ public class JavaCommercialPaper implements Contract {
|
||||
return generateIssue(issuance, faceValue, maturityDate, notary, null);
|
||||
}
|
||||
|
||||
@Suspendable
|
||||
public void generateRedeem(TransactionBuilder tx, StateAndRef<State> paper, VaultService vault) throws InsufficientBalanceException {
|
||||
vault.generateSpend(tx, StructuresKt.withoutIssuer(paper.getState().getData().getFaceValue()), paper.getState().getData().getOwner(), null);
|
||||
tx.addInputState(paper);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.contracts
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.contracts.asset.sumCashBy
|
||||
import net.corda.contracts.clause.AbstractIssue
|
||||
import net.corda.core.contracts.*
|
||||
@ -214,6 +215,7 @@ class CommercialPaper : Contract {
|
||||
* @throws InsufficientBalanceException if the vault doesn't contain enough money to pay the redeemer.
|
||||
*/
|
||||
@Throws(InsufficientBalanceException::class)
|
||||
@Suspendable
|
||||
fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, vault: VaultService) {
|
||||
// Add the cash movement using the states in our vault.
|
||||
val amount = paper.state.data.faceValue.let { amount -> Amount(amount.quantity, amount.token.product) }
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.contracts
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.contracts.asset.sumCashBy
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.NullPublicKey
|
||||
@ -124,6 +125,7 @@ class CommercialPaperLegacy : Contract {
|
||||
}
|
||||
|
||||
@Throws(InsufficientBalanceException::class)
|
||||
@Suspendable
|
||||
fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, vault: VaultService) {
|
||||
// Add the cash movement using the states in our vault.
|
||||
vault.generateSpend(tx, paper.state.data.faceValue.withoutIssuer(), paper.state.data.owner)
|
||||
|
@ -209,6 +209,7 @@ object TwoPartyTradeFlow {
|
||||
return ptx.toSignedTransaction(checkSufficientSignatures = false)
|
||||
}
|
||||
|
||||
@Suspendable
|
||||
private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<PublicKey>> {
|
||||
val ptx = TransactionType.General.Builder(notary)
|
||||
|
||||
|
@ -4,7 +4,9 @@ import net.corda.contracts.CommercialPaper
|
||||
import net.corda.contracts.asset.*
|
||||
import net.corda.contracts.testing.fillWithSomeTestCash
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.crypto.AnonymousParty
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.days
|
||||
import net.corda.core.flows.FlowStateMachine
|
||||
import net.corda.core.flows.StateMachineRunId
|
||||
@ -16,11 +18,7 @@ import net.corda.core.rootCause
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.core.utilities.ALICE
|
||||
import net.corda.core.utilities.BOB
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
import net.corda.core.utilities.LogHelper
|
||||
import net.corda.core.utilities.TEST_TX_TIME
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.flows.TwoPartyTradeFlow.Buyer
|
||||
import net.corda.flows.TwoPartyTradeFlow.Seller
|
||||
import net.corda.node.internal.AbstractNode
|
||||
@ -121,6 +119,57 @@ class TwoPartyTradeFlowTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = InsufficientBalanceException::class)
|
||||
fun `trade cash for commercial paper fails using soft locking`() {
|
||||
net = MockNetwork(false, true)
|
||||
|
||||
ledger {
|
||||
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
|
||||
val aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name)
|
||||
val bobNode = net.createPartyNode(notaryNode.info.address, BOB.name)
|
||||
val aliceKey = aliceNode.services.legalIdentityKey
|
||||
val notaryKey = notaryNode.services.notaryIdentityKey
|
||||
|
||||
aliceNode.disableDBCloseOnStop()
|
||||
bobNode.disableDBCloseOnStop()
|
||||
|
||||
val cashStates =
|
||||
bobNode.database.transaction {
|
||||
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, notaryNode.info.notaryIdentity, 3, 3)
|
||||
}
|
||||
|
||||
val alicesFakePaper = aliceNode.database.transaction {
|
||||
fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
|
||||
}
|
||||
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey, notaryKey)
|
||||
|
||||
val cashLockId = UUID.randomUUID()
|
||||
bobNode.database.transaction {
|
||||
// lock the cash states with an arbitrary lockId (to prevent the Buyer flow from claiming the states)
|
||||
bobNode.vault.softLockReserve(cashLockId, cashStates.states.map { it.ref }.toSet())
|
||||
}
|
||||
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode,
|
||||
"alice's paper".outputStateAndRef())
|
||||
|
||||
assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow())
|
||||
|
||||
aliceNode.stop()
|
||||
bobNode.stop()
|
||||
|
||||
aliceNode.database.transaction {
|
||||
assertThat(aliceNode.checkpointStorage.checkpoints()).isEmpty()
|
||||
}
|
||||
aliceNode.manuallyCloseDB()
|
||||
bobNode.database.transaction {
|
||||
assertThat(bobNode.checkpointStorage.checkpoints()).isEmpty()
|
||||
}
|
||||
bobNode.manuallyCloseDB()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `shutdown and restore`() {
|
||||
ledger {
|
||||
|
Loading…
x
Reference in New Issue
Block a user