mirror of
https://github.com/corda/corda.git
synced 2025-01-14 08:49:47 +00:00
Merge OS to Enterprise - fixes after merge: update SQL Server cash query, test in pertestcordapp module, platform version 1
This commit is contained in:
parent
2bdd8b681d
commit
07e46ddb3c
@ -1,6 +1,6 @@
|
|||||||
gradlePluginsVersion=3.0.0
|
gradlePluginsVersion=3.0.0
|
||||||
kotlinVersion=1.1.60
|
kotlinVersion=1.1.60
|
||||||
platformVersion=2
|
platformVersion=1
|
||||||
guavaVersion=21.0
|
guavaVersion=21.0
|
||||||
bouncycastleVersion=1.57
|
bouncycastleVersion=1.57
|
||||||
typesafeConfigVersion=1.3.1
|
typesafeConfigVersion=1.3.1
|
||||||
|
@ -28,7 +28,7 @@ class CashSelectionSQLServerImpl : AbstractCashSelection() {
|
|||||||
override fun toString() = "${this::class.java} for $JDBC_DRIVER_NAME"
|
override fun toString() = "${this::class.java} for $JDBC_DRIVER_NAME"
|
||||||
|
|
||||||
override fun executeQuery(connection: Connection, amount: Amount<Currency>, lockId: UUID, notary: Party?,
|
override fun executeQuery(connection: Connection, amount: Amount<Currency>, lockId: UUID, notary: Party?,
|
||||||
onlyFromIssuerParties: Set<AbstractParty>, withIssuerRefs: Set<OpaqueBytes>) : ResultSet {
|
onlyFromIssuerParties: Set<AbstractParty>, withIssuerRefs: Set<OpaqueBytes>, withResultSet: (ResultSet) -> Boolean): Boolean {
|
||||||
|
|
||||||
val selectJoin = """
|
val selectJoin = """
|
||||||
WITH row(transaction_id, output_index, pennies, total, lock_id) AS
|
WITH row(transaction_id, output_index, pennies, total, lock_id) AS
|
||||||
@ -51,19 +51,22 @@ class CashSelectionSQLServerImpl : AbstractCashSelection() {
|
|||||||
FROM row where row.total <= ? + row.pennies"""
|
FROM row where row.total <= ? + row.pennies"""
|
||||||
|
|
||||||
// Use prepared statement for protection against SQL Injection
|
// Use prepared statement for protection against SQL Injection
|
||||||
val psSelectJoin = connection.prepareStatement(selectJoin)
|
connection.prepareStatement(selectJoin).use { statement ->
|
||||||
var pIndex = 0
|
var pIndex = 0
|
||||||
psSelectJoin.setString(++pIndex, amount.token.currencyCode)
|
statement.setString(++pIndex, amount.token.currencyCode)
|
||||||
psSelectJoin.setString(++pIndex, lockId.toString())
|
statement.setString(++pIndex, lockId.toString())
|
||||||
if (notary != null)
|
if (notary != null)
|
||||||
psSelectJoin.setString(++pIndex, notary.name.toString())
|
statement.setString(++pIndex, notary.name.toString())
|
||||||
if (onlyFromIssuerParties.isNotEmpty())
|
if (onlyFromIssuerParties.isNotEmpty())
|
||||||
psSelectJoin.setObject(++pIndex, onlyFromIssuerParties.map { it.owningKey.toBase58String() as Any}.toTypedArray() )
|
statement.setObject(++pIndex, onlyFromIssuerParties.map { it.owningKey.toBase58String() as Any }.toTypedArray())
|
||||||
if (withIssuerRefs.isNotEmpty())
|
if (withIssuerRefs.isNotEmpty())
|
||||||
psSelectJoin.setObject(++pIndex, withIssuerRefs.map { it.bytes as Any }.toTypedArray())
|
statement.setObject(++pIndex, withIssuerRefs.map { it.bytes as Any }.toTypedArray())
|
||||||
psSelectJoin.setLong(++pIndex, amount.quantity)
|
statement.setLong(++pIndex, amount.quantity)
|
||||||
log.debug(selectJoin)
|
log.debug(selectJoin)
|
||||||
|
|
||||||
return psSelectJoin.executeQuery()
|
statement.executeQuery().use { rs ->
|
||||||
|
return withResultSet(rs)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,7 +20,8 @@ const val NODE_DATABASE_PREFIX = "node_"
|
|||||||
data class DatabaseConfig(
|
data class DatabaseConfig(
|
||||||
val initialiseSchema: Boolean = true,
|
val initialiseSchema: Boolean = true,
|
||||||
val serverNameTablePrefix: String = "",
|
val serverNameTablePrefix: String = "",
|
||||||
val transactionIsolationLevel: TransactionIsolationLevel = TransactionIsolationLevel.REPEATABLE_READ
|
val transactionIsolationLevel: TransactionIsolationLevel = TransactionIsolationLevel.REPEATABLE_READ,
|
||||||
|
val schema: String? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
// This class forms part of the node config and so any changes to it must be handled with care
|
// This class forms part of the node config and so any changes to it must be handled with care
|
||||||
|
@ -89,8 +89,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
// Some CP is issued onto the ledger by MegaCorp.
|
// Some CP is issued onto the ledger by MegaCorp.
|
||||||
transaction("Issuance") {
|
transaction("Issuance") {
|
||||||
attachments(CP_PROGRAM_ID, CommercialPaper.CP_PROGRAM_ID)
|
attachments(CP_PROGRAM_ID, CommercialPaper.CP_PROGRAM_ID)
|
||||||
output(thisTest.getContract(), "paper") { thisTest.getPaper() }
|
output(thisTest.getContract(), "paper", thisTest.getPaper())
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -101,10 +101,10 @@ class CommercialPaperTestsGeneric {
|
|||||||
attachments(Cash.PROGRAM_ID, CommercialPaper.CP_PROGRAM_ID)
|
attachments(Cash.PROGRAM_ID, CommercialPaper.CP_PROGRAM_ID)
|
||||||
input("paper")
|
input("paper")
|
||||||
input("alice's $900")
|
input("alice's $900")
|
||||||
output(Cash.PROGRAM_ID, "borrowed $900") { 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP }
|
output(Cash.PROGRAM_ID, "borrowed $900", 900.DOLLARS.CASH issuedBy issuer ownedBy MEGA_CORP)
|
||||||
output(thisTest.getContract(), "alice's paper") { "paper".output<CommercialPaper.State>().withOwner(ALICE) }
|
output(thisTest.getContract(), "alice's paper", "paper".output<CommercialPaper.State>().withOwner(ALICE))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getMoveCommand() }
|
command(MEGA_CORP_PUBKEY, thisTest.getMoveCommand())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,12 +116,12 @@ class CommercialPaperTestsGeneric {
|
|||||||
input("some profits")
|
input("some profits")
|
||||||
|
|
||||||
fun TransactionDSL<TransactionDSLInterpreter>.outputs(aliceGetsBack: Amount<Issued<Currency>>) {
|
fun TransactionDSL<TransactionDSLInterpreter>.outputs(aliceGetsBack: Amount<Issued<Currency>>) {
|
||||||
output(Cash.PROGRAM_ID, "Alice's profit") { aliceGetsBack.STATE ownedBy ALICE }
|
output(Cash.PROGRAM_ID, "Alice's profit", aliceGetsBack.STATE ownedBy ALICE)
|
||||||
output(Cash.PROGRAM_ID, "Change") { (someProfits - aliceGetsBack).STATE ownedBy MEGA_CORP }
|
output(Cash.PROGRAM_ID, "Change", (someProfits - aliceGetsBack).STATE ownedBy MEGA_CORP)
|
||||||
}
|
}
|
||||||
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
command(ALICE_PUBKEY) { thisTest.getRedeemCommand(DUMMY_NOTARY) }
|
command(ALICE_PUBKEY, thisTest.getRedeemCommand(DUMMY_NOTARY))
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
outputs(700.DOLLARS `issued by` issuer)
|
outputs(700.DOLLARS `issued by` issuer)
|
||||||
@ -138,7 +138,7 @@ class CommercialPaperTestsGeneric {
|
|||||||
timeWindow(TEST_TX_TIME + 8.days)
|
timeWindow(TEST_TX_TIME + 8.days)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output(thisTest.getContract()) { "paper".output<CommercialPaper.State>() }
|
output(thisTest.getContract(), "paper".output<CommercialPaper.State>())
|
||||||
this `fails with` "must be destroyed"
|
this `fails with` "must be destroyed"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,8 +152,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
output(thisTest.getContract()) { thisTest.getPaper() }
|
output(thisTest.getContract(), thisTest.getPaper())
|
||||||
command(MINI_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MINI_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "output states are issued by a command signer"
|
this `fails with` "output states are issued by a command signer"
|
||||||
}
|
}
|
||||||
@ -164,8 +164,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
output(thisTest.getContract()) { thisTest.getPaper().withFaceValue(0.DOLLARS `issued by` issuer) }
|
output(thisTest.getContract(), thisTest.getPaper().withFaceValue(0.DOLLARS `issued by` issuer))
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
@ -176,8 +176,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
output(thisTest.getContract()) { thisTest.getPaper().withMaturityDate(TEST_TX_TIME - 10.days) }
|
output(thisTest.getContract(), thisTest.getPaper().withMaturityDate(TEST_TX_TIME - 10.days))
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "maturity date is not in the past"
|
this `fails with` "maturity date is not in the past"
|
||||||
}
|
}
|
||||||
@ -189,8 +189,8 @@ class CommercialPaperTestsGeneric {
|
|||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
attachment(CP_PROGRAM_ID)
|
attachment(CP_PROGRAM_ID)
|
||||||
input(thisTest.getContract(), thisTest.getPaper())
|
input(thisTest.getContract(), thisTest.getPaper())
|
||||||
output(thisTest.getContract()) { thisTest.getPaper() }
|
output(thisTest.getContract(), thisTest.getPaper())
|
||||||
command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand(DUMMY_NOTARY) }
|
command(MEGA_CORP_PUBKEY, thisTest.getIssueCommand(DUMMY_NOTARY))
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,10 @@ import net.corda.core.transactions.TransactionBuilder
|
|||||||
import net.corda.core.transactions.WireTransaction
|
import net.corda.core.transactions.WireTransaction
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.node.services.vault.NodeVaultService
|
import net.corda.node.services.vault.NodeVaultService
|
||||||
import net.corda.node.utilities.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.testing.*
|
import net.corda.testing.*
|
||||||
import net.corda.testing.contracts.DummyState
|
import net.corda.testing.contracts.DummyState
|
||||||
import net.corda.testing.contracts.calculateRandomlySizedAmounts
|
import net.corda.testing.contracts.VaultFiller.Companion.calculateRandomlySizedAmounts
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseAndMockServices
|
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseAndMockServices
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@ -133,34 +133,34 @@ class CashTests {
|
|||||||
fun trivial() = withTestSerialization {
|
fun trivial() = withTestSerialization {
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = 2000.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = 2000.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(ALICE_PUBKEY) { DummyCommandData }
|
command(ALICE_PUBKEY, DummyCommandData)
|
||||||
// Invalid command
|
// Invalid command
|
||||||
this `fails with` "required com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash.Commands.Move command"
|
this `fails with` "required com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash.Commands.Move command"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(BOB_PUBKEY) { Cash.Commands.Move() }
|
command(BOB_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the owning keys are a subset of the signing keys"
|
this `fails with` "the owning keys are a subset of the signing keys"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
output(Cash.PROGRAM_ID) { outState issuedBy MINI_CORP }
|
output(Cash.PROGRAM_ID, outState issuedBy MINI_CORP)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "at least one cash input"
|
this `fails with` "at least one cash input"
|
||||||
}
|
}
|
||||||
// Simple reallocation works.
|
// Simple reallocation works.
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,9 +172,9 @@ class CashTests {
|
|||||||
// Check we can't "move" money into existence.
|
// Check we can't "move" money into existence.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { DummyState() }
|
input(Cash.PROGRAM_ID, DummyState())
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MINI_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
|
|
||||||
this `fails with` "there is at least one cash input for this group"
|
this `fails with` "there is at least one cash input for this group"
|
||||||
}
|
}
|
||||||
@ -187,19 +187,19 @@ class CashTests {
|
|||||||
// institution is allowed to issue as much cash as they want.
|
// institution is allowed to issue as much cash as they want.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Issue() }
|
command(ALICE_PUBKEY, Cash.Commands.Issue())
|
||||||
this `fails with` "output states are issued by a command signer"
|
this `fails with` "output states are issued by a command signer"
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
output(Cash.PROGRAM_ID) {
|
output(Cash.PROGRAM_ID,
|
||||||
Cash.State(
|
Cash.State(
|
||||||
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
|
amount = 1000.DOLLARS `issued by` MINI_CORP.ref(12, 34),
|
||||||
owner = AnonymousParty(ALICE_PUBKEY)
|
owner = AnonymousParty(ALICE_PUBKEY)
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MINI_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
@ -236,18 +236,18 @@ class CashTests {
|
|||||||
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
|
// We can consume $1000 in a transaction and output $2000 as long as it's signed by an issuer.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { issuerInState }
|
input(Cash.PROGRAM_ID, issuerInState)
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(amount = inState.amount * 2) }
|
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount * 2))
|
||||||
|
|
||||||
// Move fails: not allowed to summon money.
|
// Move fails: not allowed to summon money.
|
||||||
tweak {
|
tweak {
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue works.
|
// Issue works.
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,29 +255,29 @@ class CashTests {
|
|||||||
// Can't use an issue command to lower the amount.
|
// Can't use an issue command to lower the amount.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(amount = inState.amount.splitEvenly(2).first()) }
|
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount.splitEvenly(2).first()))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't have an issue command that doesn't actually issue money.
|
// Can't have an issue command that doesn't actually issue money.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState }
|
output(Cash.PROGRAM_ID, inState)
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this `fails with` "output values sum to more than the inputs"
|
this `fails with` "output values sum to more than the inputs"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't have any other commands if we have an issue command (because the issue command overrules them)
|
// Can't have any other commands if we have an issue command (because the issue command overrules them)
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(amount = inState.amount * 2) }
|
output(Cash.PROGRAM_ID, inState.copy(amount = inState.amount * 2))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Issue())
|
||||||
this `fails with` "there is only a single issue command"
|
this `fails with` "there is only a single issue command"
|
||||||
}
|
}
|
||||||
this.verifies()
|
this.verifies()
|
||||||
@ -309,26 +309,26 @@ class CashTests {
|
|||||||
// Splitting value works.
|
// Splitting value works.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
tweak {
|
tweak {
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
val splits4 = inState.amount.splitEvenly(4)
|
val splits4 = inState.amount.splitEvenly(4)
|
||||||
for (i in 0..3) output(Cash.PROGRAM_ID) { inState.copy(amount = splits4[i]) }
|
for (i in 0..3) output(Cash.PROGRAM_ID, inState.copy(amount = splits4[i]))
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
// Merging 4 inputs into 2 outputs works.
|
// Merging 4 inputs into 2 outputs works.
|
||||||
tweak {
|
tweak {
|
||||||
val splits2 = inState.amount.splitEvenly(2)
|
val splits2 = inState.amount.splitEvenly(2)
|
||||||
val splits4 = inState.amount.splitEvenly(4)
|
val splits4 = inState.amount.splitEvenly(4)
|
||||||
for (i in 0..3) input(Cash.PROGRAM_ID) { inState.copy(amount = splits4[i]) }
|
for (i in 0..3) input(Cash.PROGRAM_ID, inState.copy(amount = splits4[i]))
|
||||||
for (i in 0..1) output(Cash.PROGRAM_ID) { inState.copy(amount = splits2[i]) }
|
for (i in 0..1) output(Cash.PROGRAM_ID, inState.copy(amount = splits2[i]))
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
// Merging 2 inputs into 1 works.
|
// Merging 2 inputs into 1 works.
|
||||||
tweak {
|
tweak {
|
||||||
val splits2 = inState.amount.splitEvenly(2)
|
val splits2 = inState.amount.splitEvenly(2)
|
||||||
for (i in 0..1) input(Cash.PROGRAM_ID) { inState.copy(amount = splits2[i]) }
|
for (i in 0..1) input(Cash.PROGRAM_ID, inState.copy(amount = splits2[i]))
|
||||||
output(Cash.PROGRAM_ID) { inState }
|
output(Cash.PROGRAM_ID, inState)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,17 +339,17 @@ class CashTests {
|
|||||||
fun zeroSizedValues() = withTestSerialization {
|
fun zeroSizedValues() = withTestSerialization {
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
|
input(Cash.PROGRAM_ID, inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "zero sized inputs"
|
this `fails with` "zero sized inputs"
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState }
|
output(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "zero sized outputs"
|
this `fails with` "zero sized outputs"
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
@ -360,58 +360,58 @@ class CashTests {
|
|||||||
// Can't change issuer.
|
// Can't change issuer.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { outState issuedBy MINI_CORP }
|
output(Cash.PROGRAM_ID, outState issuedBy MINI_CORP)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't change deposit reference when splitting.
|
// Can't change deposit reference when splitting.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
val splits2 = inState.amount.splitEvenly(2)
|
val splits2 = inState.amount.splitEvenly(2)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
for (i in 0..1) output(Cash.PROGRAM_ID) { outState.copy(amount = splits2[i]).editDepositRef(i.toByte()) }
|
for (i in 0..1) output(Cash.PROGRAM_ID, outState.copy(amount = splits2[i]).editDepositRef(i.toByte()))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't mix currencies.
|
// Can't mix currencies.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer))
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = 200.POUNDS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = 200.POUNDS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) {
|
input(Cash.PROGRAM_ID,
|
||||||
inState.copy(
|
inState.copy(
|
||||||
amount = 150.POUNDS `issued by` defaultIssuer,
|
amount = 150.POUNDS `issued by` defaultIssuer,
|
||||||
owner = AnonymousParty(BOB_PUBKEY)
|
owner = AnonymousParty(BOB_PUBKEY)
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't have superfluous input states from different issuers.
|
// Can't have superfluous input states from different issuers.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) { inState issuedBy MINI_CORP }
|
input(Cash.PROGRAM_ID, inState issuedBy MINI_CORP)
|
||||||
output(Cash.PROGRAM_ID) { outState }
|
output(Cash.PROGRAM_ID, outState)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Can't combine two different deposits at the same issuer.
|
// Can't combine two different deposits at the same issuer.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) { inState.editDepositRef(3) }
|
input(Cash.PROGRAM_ID, inState.editDepositRef(3))
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = inState.amount * 2).editDepositRef(3) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = inState.amount * 2).editDepositRef(3))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "for reference [01]"
|
this `fails with` "for reference [01]"
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
@ -422,21 +422,21 @@ class CashTests {
|
|||||||
// Single input/output straightforward case.
|
// Single input/output straightforward case.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { issuerInState }
|
input(Cash.PROGRAM_ID, issuerInState)
|
||||||
output(Cash.PROGRAM_ID) { issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
output(Cash.PROGRAM_ID, issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer) }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||||
this `fails with` "required com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash.Commands.Move command"
|
this `fails with` "required com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash.Commands.Move command"
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -449,20 +449,20 @@ class CashTests {
|
|||||||
// Multi-issuer case.
|
// Multi-issuer case.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { issuerInState }
|
input(Cash.PROGRAM_ID, issuerInState)
|
||||||
input(Cash.PROGRAM_ID) { issuerInState.copy(owner = MINI_CORP) issuedBy MINI_CORP }
|
input(Cash.PROGRAM_ID, issuerInState.copy(owner = MINI_CORP) issuedBy MINI_CORP)
|
||||||
|
|
||||||
output(Cash.PROGRAM_ID) { issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) issuedBy MINI_CORP }
|
output(Cash.PROGRAM_ID, issuerInState.copy(amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) issuedBy MINI_CORP)
|
||||||
output(Cash.PROGRAM_ID) { issuerInState.copy(owner = MINI_CORP, amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
output(Cash.PROGRAM_ID, issuerInState.copy(owner = MINI_CORP, amount = issuerInState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||||
|
|
||||||
command(MEGA_CORP_PUBKEY, MINI_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(listOf(MEGA_CORP_PUBKEY, MINI_CORP_PUBKEY), Cash.Commands.Move())
|
||||||
|
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
|
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
|
|
||||||
command(MINI_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` MINI_CORP.ref(defaultRef)) }
|
command(MINI_CORP_PUBKEY, Cash.Commands.Exit(200.DOLLARS `issued by` MINI_CORP.ref(defaultRef)))
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
@ -473,10 +473,10 @@ class CashTests {
|
|||||||
// Single input/output straightforward case.
|
// Single input/output straightforward case.
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
output(Cash.PROGRAM_ID) { outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) }
|
output(Cash.PROGRAM_ID, outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer))
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
@ -487,25 +487,25 @@ class CashTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
// Gather 2000 dollars from two different issuers.
|
// Gather 2000 dollars from two different issuers.
|
||||||
input(Cash.PROGRAM_ID) { inState }
|
input(Cash.PROGRAM_ID, inState)
|
||||||
input(Cash.PROGRAM_ID) { inState issuedBy MINI_CORP }
|
input(Cash.PROGRAM_ID, inState issuedBy MINI_CORP)
|
||||||
command(ALICE_PUBKEY) { Cash.Commands.Move() }
|
command(ALICE_PUBKEY, Cash.Commands.Move())
|
||||||
|
|
||||||
// Can't merge them together.
|
// Can't merge them together.
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY), amount = 2000.DOLLARS `issued by` defaultIssuer) }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY), amount = 2000.DOLLARS `issued by` defaultIssuer))
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
// Missing MiniCorp deposit
|
// Missing MiniCorp deposit
|
||||||
tweak {
|
tweak {
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY)))
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY)))
|
||||||
this `fails with` "the amounts balance"
|
this `fails with` "the amounts balance"
|
||||||
}
|
}
|
||||||
|
|
||||||
// This works.
|
// This works.
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY)))
|
||||||
output(Cash.PROGRAM_ID) { inState.copy(owner = AnonymousParty(BOB_PUBKEY)) issuedBy MINI_CORP }
|
output(Cash.PROGRAM_ID, inState.copy(owner = AnonymousParty(BOB_PUBKEY)) issuedBy MINI_CORP)
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
@ -517,11 +517,11 @@ class CashTests {
|
|||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
val pounds = Cash.State(658.POUNDS `issued by` MINI_CORP.ref(3, 4, 5), AnonymousParty(BOB_PUBKEY))
|
val pounds = Cash.State(658.POUNDS `issued by` MINI_CORP.ref(3, 4, 5), AnonymousParty(BOB_PUBKEY))
|
||||||
input(Cash.PROGRAM_ID) { inState ownedBy AnonymousParty(ALICE_PUBKEY) }
|
input(Cash.PROGRAM_ID, inState ownedBy AnonymousParty(ALICE_PUBKEY))
|
||||||
input(Cash.PROGRAM_ID) { pounds }
|
input(Cash.PROGRAM_ID, pounds)
|
||||||
output(Cash.PROGRAM_ID) { inState ownedBy AnonymousParty(BOB_PUBKEY) }
|
output(Cash.PROGRAM_ID, inState ownedBy AnonymousParty(BOB_PUBKEY))
|
||||||
output(Cash.PROGRAM_ID) { pounds ownedBy AnonymousParty(ALICE_PUBKEY) }
|
output(Cash.PROGRAM_ID, pounds ownedBy AnonymousParty(ALICE_PUBKEY))
|
||||||
command(ALICE_PUBKEY, BOB_PUBKEY) { Cash.Commands.Move() }
|
command(listOf(ALICE_PUBKEY, BOB_PUBKEY), Cash.Commands.Move())
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
@ -844,19 +844,19 @@ class CashTests {
|
|||||||
ledger(mockService) {
|
ledger(mockService) {
|
||||||
unverifiedTransaction {
|
unverifiedTransaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash") {
|
output(Cash.PROGRAM_ID, "MEGA_CORP cash",
|
||||||
Cash.State(
|
Cash.State(
|
||||||
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
|
amount = 1000.DOLLARS `issued by` MEGA_CORP.ref(1, 1),
|
||||||
owner = MEGA_CORP
|
owner = MEGA_CORP
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
attachment(Cash.PROGRAM_ID)
|
attachment(Cash.PROGRAM_ID)
|
||||||
input("MEGA_CORP cash")
|
input("MEGA_CORP cash")
|
||||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash 2", "MEGA_CORP cash".output<Cash.State>().copy(owner = AnonymousParty(ALICE_PUBKEY)))
|
output(Cash.PROGRAM_ID, "MEGA_CORP cash 2", "MEGA_CORP cash".output<Cash.State>().copy(owner = AnonymousParty(ALICE_PUBKEY)))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -866,7 +866,7 @@ class CashTests {
|
|||||||
input("MEGA_CORP cash")
|
input("MEGA_CORP cash")
|
||||||
// We send it to another pubkey so that the transaction is not identical to the previous one
|
// We send it to another pubkey so that the transaction is not identical to the previous one
|
||||||
output(Cash.PROGRAM_ID, "MEGA_CORP cash 3", "MEGA_CORP cash".output<Cash.State>().copy(owner = ALICE))
|
output(Cash.PROGRAM_ID, "MEGA_CORP cash 3", "MEGA_CORP cash".output<Cash.State>().copy(owner = ALICE))
|
||||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
command(MEGA_CORP_PUBKEY, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
this.fails()
|
this.fails()
|
||||||
|
@ -41,7 +41,7 @@ import net.corda.node.services.api.Checkpoint
|
|||||||
import net.corda.node.services.api.CheckpointStorage
|
import net.corda.node.services.api.CheckpointStorage
|
||||||
import net.corda.node.services.api.WritableTransactionStorage
|
import net.corda.node.services.api.WritableTransactionStorage
|
||||||
import net.corda.node.services.persistence.DBTransactionStorage
|
import net.corda.node.services.persistence.DBTransactionStorage
|
||||||
import net.corda.node.utilities.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
import net.corda.testing.*
|
import net.corda.testing.*
|
||||||
import net.corda.testing.node.*
|
import net.corda.testing.node.*
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
@ -536,7 +536,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
sellerNode: StartedNode<MockNetwork.MockNode>,
|
sellerNode: StartedNode<MockNetwork.MockNode>,
|
||||||
buyerNode: StartedNode<MockNetwork.MockNode>,
|
buyerNode: StartedNode<MockNetwork.MockNode>,
|
||||||
assetToSell: StateAndRef<OwnableState>): RunResult {
|
assetToSell: StateAndRef<OwnableState>): RunResult {
|
||||||
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java)
|
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.registerInitiatedFlow(BuyerAcceptor::class.java)
|
||||||
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine }
|
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine }
|
||||||
val seller = SellerInitiator(buyer, notary, assetToSell, 1000.DOLLARS, anonymous)
|
val seller = SellerInitiator(buyer, notary, assetToSell, 1000.DOLLARS, anonymous)
|
||||||
val sellerResult = sellerNode.services.startFlow(seller).resultFuture
|
val sellerResult = sellerNode.services.startFlow(seller).resultFuture
|
||||||
@ -673,13 +673,13 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
// wants to sell to Bob.
|
// wants to sell to Bob.
|
||||||
val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||||
// Issued money to itself.
|
// Issued money to itself.
|
||||||
output(Cash.PROGRAM_ID, "elbonian money 1", notary = notary) { 800.DOLLARS.CASH issuedBy issuer ownedBy interimOwner }
|
output(Cash.PROGRAM_ID, "elbonian money 1", notary = notary, contractState = 800.DOLLARS.CASH issuedBy issuer ownedBy interimOwner)
|
||||||
output(Cash.PROGRAM_ID, "elbonian money 2", notary = notary) { 1000.DOLLARS.CASH issuedBy issuer ownedBy interimOwner }
|
output(Cash.PROGRAM_ID, "elbonian money 2", notary = notary, contractState = 1000.DOLLARS.CASH issuedBy issuer ownedBy interimOwner)
|
||||||
if (!withError) {
|
if (!withError) {
|
||||||
command(issuer.party.owningKey) { Cash.Commands.Issue() }
|
command(issuer.party.owningKey, Cash.Commands.Issue())
|
||||||
} else {
|
} else {
|
||||||
// Put a broken command on so at least a signature is created
|
// Put a broken command on so at least a signature is created
|
||||||
command(issuer.party.owningKey) { Cash.Commands.Move() }
|
command(issuer.party.owningKey, Cash.Commands.Move())
|
||||||
}
|
}
|
||||||
timeWindow(TEST_TX_TIME)
|
timeWindow(TEST_TX_TIME)
|
||||||
if (withError) {
|
if (withError) {
|
||||||
@ -692,16 +692,16 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
// Bob gets some cash onto the ledger from BoE
|
// Bob gets some cash onto the ledger from BoE
|
||||||
val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||||
input("elbonian money 1")
|
input("elbonian money 1")
|
||||||
output(Cash.PROGRAM_ID, "bob cash 1", notary = notary) { 800.DOLLARS.CASH issuedBy issuer ownedBy owner }
|
output(Cash.PROGRAM_ID, "bob cash 1", notary = notary, contractState = 800.DOLLARS.CASH issuedBy issuer ownedBy owner)
|
||||||
command(interimOwner.owningKey) { Cash.Commands.Move() }
|
command(interimOwner.owningKey, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||||
input("elbonian money 2")
|
input("elbonian money 2")
|
||||||
output(Cash.PROGRAM_ID, "bob cash 2", notary = notary) { 300.DOLLARS.CASH issuedBy issuer ownedBy owner }
|
output(Cash.PROGRAM_ID, "bob cash 2", notary = notary, contractState = 300.DOLLARS.CASH issuedBy issuer ownedBy owner)
|
||||||
output(Cash.PROGRAM_ID, notary = notary) { 700.DOLLARS.CASH issuedBy issuer ownedBy interimOwner } // Change output.
|
output(Cash.PROGRAM_ID, notary = notary, contractState = 700.DOLLARS.CASH issuedBy issuer ownedBy interimOwner) // Change output.
|
||||||
command(interimOwner.owningKey) { Cash.Commands.Move() }
|
command(interimOwner.owningKey, Cash.Commands.Move())
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,10 +717,9 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
|||||||
attachmentID: SecureHash?,
|
attachmentID: SecureHash?,
|
||||||
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {
|
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {
|
||||||
val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||||
output(CommercialPaper.CP_PROGRAM_ID, "alice's paper", notary = notary) {
|
output(CommercialPaper.CP_PROGRAM_ID, "alice's paper", notary = notary,
|
||||||
CommercialPaper.State(issuer, owner, amount, TEST_TX_TIME + 7.days)
|
contractState = CommercialPaper.State(issuer, owner, amount, TEST_TX_TIME + 7.days))
|
||||||
}
|
command(issuer.party.owningKey, CommercialPaper.Commands.Issue())
|
||||||
command(issuer.party.owningKey) { CommercialPaper.Commands.Issue() }
|
|
||||||
if (!withError)
|
if (!withError)
|
||||||
timeWindow(time = TEST_TX_TIME)
|
timeWindow(time = TEST_TX_TIME)
|
||||||
if (attachmentID != null)
|
if (attachmentID != null)
|
||||||
|
@ -10,7 +10,6 @@ import net.corda.core.utilities.OpaqueBytes
|
|||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.finance.flows.CashIssueAndPaymentFlow
|
import net.corda.finance.flows.CashIssueAndPaymentFlow
|
||||||
import net.corda.testing.http.HttpApi
|
import net.corda.testing.http.HttpApi
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for communicating with Bank of Corda node
|
* Interface for communicating with Bank of Corda node
|
||||||
|
@ -4,7 +4,6 @@ import net.corda.cordform.CordformContext
|
|||||||
import net.corda.cordform.CordformDefinition
|
import net.corda.cordform.CordformDefinition
|
||||||
import net.corda.cordform.CordformNode
|
import net.corda.cordform.CordformNode
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.div
|
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.node.services.config.NotaryConfig
|
import net.corda.node.services.config.NotaryConfig
|
||||||
import net.corda.node.services.config.RaftConfig
|
import net.corda.node.services.config.RaftConfig
|
||||||
|
@ -26,7 +26,6 @@ import net.corda.node.services.api.StateMachineRecordedTransactionMappingStorage
|
|||||||
import net.corda.node.services.api.VaultServiceInternal
|
import net.corda.node.services.api.VaultServiceInternal
|
||||||
import net.corda.node.services.api.WritableTransactionStorage
|
import net.corda.node.services.api.WritableTransactionStorage
|
||||||
import net.corda.node.services.config.configOf
|
import net.corda.node.services.config.configOf
|
||||||
import net.corda.node.services.config.DatabaseConfig
|
|
||||||
import net.corda.node.services.identity.InMemoryIdentityService
|
import net.corda.node.services.identity.InMemoryIdentityService
|
||||||
import net.corda.node.services.keys.freshCertificate
|
import net.corda.node.services.keys.freshCertificate
|
||||||
import net.corda.node.services.keys.getSigner
|
import net.corda.node.services.keys.getSigner
|
||||||
|
Loading…
Reference in New Issue
Block a user