contracts, node: Port CommercialPaperTests, TwoPartyTradeProtocolTests and GroupToGraphConversion to use new dsl

This commit is contained in:
Andras Slemmer
2016-07-04 17:15:02 +01:00
parent 9b36df607e
commit cde315aca9
3 changed files with 122 additions and 125 deletions

View File

@ -86,7 +86,9 @@ class TwoPartyTradeProtocolTests {
// we run in the unit test thread exclusively to speed things up, ensure deterministic results and
// allow interruption half way through.
net = MockNetwork(false, true)
transactionGroupFor<ContractState> {
ledger {
val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
val aliceNode = net.createPartyNode(notaryNode.info, ALICE.name, ALICE_KEY)
val bobNode = net.createPartyNode(notaryNode.info, BOB.name, BOB_KEY)
@ -113,7 +115,7 @@ class TwoPartyTradeProtocolTests {
aliceNode.smm,
notaryNode.info,
bobNode.info.identity,
lookup("alice's paper"),
"alice's paper".outputStateAndRef(),
1000.DOLLARS `issued by` issuer,
ALICE_KEY,
buyerSessionID
@ -133,7 +135,8 @@ class TwoPartyTradeProtocolTests {
@Test
fun `shutdown and restore`() {
transactionGroupFor<ContractState> {
ledger {
val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
val aliceNode = net.createPartyNode(notaryNode.info, ALICE.name, ALICE_KEY)
var bobNode = net.createPartyNode(notaryNode.info, BOB.name, BOB_KEY)
@ -155,7 +158,7 @@ class TwoPartyTradeProtocolTests {
aliceNode.smm,
notaryNode.info,
bobNode.info.identity,
lookup("alice's paper"),
"alice's paper".outputStateAndRef(),
1000.DOLLARS `issued by` issuer,
ALICE_KEY,
buyerSessionID
@ -246,7 +249,7 @@ class TwoPartyTradeProtocolTests {
@Test
fun `check dependencies of sale asset are resolved`() {
transactionGroupFor<ContractState> {
ledger {
val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
val aliceNode = makeNodeWithTracking(notaryNode.info, ALICE.name, ALICE_KEY)
val bobNode = makeNodeWithTracking(notaryNode.info, BOB.name, BOB_KEY)
@ -275,7 +278,7 @@ class TwoPartyTradeProtocolTests {
aliceNode.smm,
notaryNode.info,
bobNode.info.identity,
lookup("alice's paper"),
"alice's paper".outputStateAndRef(),
1000.DOLLARS `issued by` issuer,
ALICE_KEY,
buyerSessionID
@ -350,19 +353,19 @@ class TwoPartyTradeProtocolTests {
@Test
fun `dependency with error on buyer side`() {
transactionGroupFor<ContractState> {
ledger {
runWithError(true, false, "at least one asset input")
}
}
@Test
fun `dependency with error on seller side`() {
transactionGroupFor<ContractState> {
ledger {
runWithError(false, true, "must be timestamped")
}
}
private fun TransactionGroupDSL<ContractState>.runWithError(bobError: Boolean, aliceError: Boolean,
private fun LedgerDsl<TransactionDslInterpreter, LedgerDslInterpreter<TransactionDslInterpreter>>.runWithError(bobError: Boolean, aliceError: Boolean,
expectedMessageSubstring: String) {
val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
val aliceNode = net.createPartyNode(notaryNode.info, ALICE.name, ALICE_KEY)
@ -385,7 +388,7 @@ class TwoPartyTradeProtocolTests {
aliceNode.smm,
notaryNode.info,
bobNode.info.identity,
lookup("alice's paper"),
"alice's paper".outputStateAndRef(),
1000.DOLLARS `issued by` issuer,
ALICE_KEY,
buyerSessionID
@ -411,9 +414,10 @@ class TwoPartyTradeProtocolTests {
assertTrue(e.cause!!.cause!!.message!!.contains(expectedMessageSubstring))
}
private fun TransactionGroupDSL<ContractState>.insertFakeTransactions(wtxToSign: List<WireTransaction>,
services: ServiceHub,
vararg extraKeys: KeyPair): Map<SecureHash, SignedTransaction> {
private fun insertFakeTransactions(
wtxToSign: List<WireTransaction>,
services: ServiceHub,
vararg extraKeys: KeyPair): Map<SecureHash, SignedTransaction> {
val signed: List<SignedTransaction> = signAll(wtxToSign, *extraKeys)
services.recordTransactions(signed)
val validatedTransactions = services.storageService.validatedTransactions
@ -423,9 +427,10 @@ class TwoPartyTradeProtocolTests {
return signed.associateBy { it.id }
}
private fun TransactionGroupDSL<ContractState>.fillUpForBuyer(withError: Boolean,
owner: PublicKey = BOB_PUBKEY,
issuer: PartyAndReference = MEGA_CORP.ref(1)): Pair<Wallet, List<WireTransaction>> {
private fun LedgerDsl<TransactionDslInterpreter, LedgerDslInterpreter<TransactionDslInterpreter>>.fillUpForBuyer(
withError: Boolean,
owner: PublicKey = BOB_PUBKEY,
issuer: PartyAndReference = MEGA_CORP.ref(1)): Pair<Wallet, List<WireTransaction>> {
// Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she
// wants to sell to Bob.
@ -434,7 +439,7 @@ class TwoPartyTradeProtocolTests {
output("elbonian money 1") { 800.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY }
output("elbonian money 2") { 1000.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY }
if (!withError)
arg(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() }
timestamp(TEST_TX_TIME)
}
@ -442,44 +447,44 @@ class TwoPartyTradeProtocolTests {
val bc1 = transaction {
input("elbonian money 1")
output("bob cash 1") { 800.DOLLARS.CASH `issued by` issuer `owned by` owner }
arg(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
}
val bc2 = transaction {
input("elbonian money 2")
output("bob cash 2") { 300.DOLLARS.CASH `issued by` issuer `owned by` owner }
output { 700.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } // Change output.
arg(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
}
val wallet = Wallet(listOf<StateAndRef<Cash.State>>(lookup("bob cash 1"), lookup("bob cash 2")))
val wallet = Wallet(listOf("bob cash 1".outputStateAndRef(), "bob cash 2".outputStateAndRef()))
return Pair(wallet, listOf(eb1, bc1, bc2))
}
private fun TransactionGroupDSL<ContractState>.fillUpForSeller(withError: Boolean,
owner: PublicKey,
amount: Amount<Issued<Currency>>,
notary: Party,
attachmentID: SecureHash?): Pair<Wallet, List<WireTransaction>> {
private fun LedgerDsl<TransactionDslInterpreter, LedgerDslInterpreter<TransactionDslInterpreter>>.fillUpForSeller(
withError: Boolean,
owner: PublicKey,
amount: Amount<Issued<Currency>>,
notary: Party,
attachmentID: SecureHash?): Pair<Wallet, List<WireTransaction>> {
val ap = transaction {
output("alice's paper") {
CommercialPaper.State(MEGA_CORP.ref(1, 2, 3), owner, amount, TEST_TX_TIME + 7.days)
}
arg(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
if (!withError)
arg(notary.owningKey) { TimestampCommand(TEST_TX_TIME, 30.seconds) }
command(notary.owningKey) { TimestampCommand(TEST_TX_TIME, 30.seconds) }
if (attachmentID != null)
attachment(attachmentID)
}
val wallet = Wallet(listOf<StateAndRef<Cash.State>>(lookup("alice's paper")))
val wallet = Wallet(listOf("alice's paper".outputStateAndRef()))
return Pair(wallet, listOf(ap))
}
class RecordingTransactionStorage(val delegate: TransactionStorage) : TransactionStorage {
val records = Collections.synchronizedList(ArrayList<TxRecord>())
val records: MutableList<TxRecord> = Collections.synchronizedList(ArrayList<TxRecord>())
override fun addTransaction(transaction: SignedTransaction) {
records.add(TxRecord.Add(transaction))

View File

@ -2,35 +2,34 @@ package com.r3corda.node.visualiser
import com.r3corda.core.contracts.CommandData
import com.r3corda.core.contracts.ContractState
import com.r3corda.core.contracts.TransactionState
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.testing.TransactionGroupDSL
import com.r3corda.core.testing.*
import org.graphstream.graph.Edge
import org.graphstream.graph.Node
import org.graphstream.graph.implementations.SingleGraph
import kotlin.reflect.memberProperties
class GraphVisualiser(val dsl: TransactionGroupDSL<in ContractState>) {
class GraphVisualiser(val dsl: LedgerDsl<TestTransactionDslInterpreter, TestLedgerDslInterpreter>) {
companion object {
val css = GraphVisualiser::class.java.getResourceAsStream("graph.css").bufferedReader().readText()
}
fun convert(): SingleGraph {
val tg = dsl.toTransactionGroup()
val tg = dsl.interpreter.toTransactionGroup()
val graph = createGraph("Transaction group", css)
// Map all the transactions, including the bogus non-verified ones (with no inputs) to graph nodes.
for ((txIndex, tx) in (tg.transactions + tg.nonVerifiedRoots).withIndex()) {
val txNode = graph.addNode<Node>("tx$txIndex")
if (tx !in tg.nonVerifiedRoots)
txNode.label = dsl.labelForTransaction(tx).let { it ?: "TX ${tx.id.prefixChars()}" }
txNode.label = dsl.interpreter.transactionName(tx.id).let { it ?: "TX[${tx.id.prefixChars()}]" }
txNode.styleClass = "tx"
// Now create a vertex for each output state.
for (outIndex in tx.outputs.indices) {
val node = graph.addNode<Node>(tx.outRef<ContractState>(outIndex).ref.toString())
val state = tx.outputs[outIndex]
node.label = stateToLabel(state)
node.label = stateToLabel(state.data)
node.styleClass = stateToCSSClass(state.data) + ",state"
node.setAttribute("state", state)
val edge = graph.addEdge<Edge>("tx$txIndex-out$outIndex", txNode, node, true)
@ -56,8 +55,8 @@ class GraphVisualiser(val dsl: TransactionGroupDSL<in ContractState>) {
return graph
}
private fun stateToLabel(state: TransactionState<*>): String {
return dsl.labelForState(state) ?: stateToTypeName(state.data)
private fun stateToLabel(state: ContractState): String {
return dsl.interpreter.outputToLabel(state) ?: stateToTypeName(state)
}
private fun commandToTypeName(state: CommandData) = state.javaClass.canonicalName.removePrefix("contracts.").replace('$', '.')
@ -73,4 +72,4 @@ class GraphVisualiser(val dsl: TransactionGroupDSL<in ContractState>) {
}
})
}
}
}