mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
Move tests to using named identities (#1879)
Move tests to using named identities in preparation for multiple identities work. Includes: * NetworkMapCacheTest * NodeInterestRatesTest * NodeVaultServiceTest * ContractUpgradeFlowTest * Cash tests * AttachmentSerializationTest * CordaRPCOpsImplTest * VaultWithCashTest * ScheduledFlowTests
This commit is contained in:
parent
9d6d027523
commit
19aba62fc6
@ -64,7 +64,7 @@ class NodeMonitorModelTest {
|
||||
invokeRpc(CordaRPCOps::stateMachinesFeed),
|
||||
invokeRpc(CordaRPCOps::networkMapFeed))
|
||||
)
|
||||
val aliceNodeHandle = startNode(providedName = ALICE.name, rpcUsers = listOf(cashUser)).getOrThrow()
|
||||
val aliceNodeHandle = startNode(providedName = ALICE_NAME, rpcUsers = listOf(cashUser)).getOrThrow()
|
||||
aliceNode = aliceNodeHandle.nodeInfo
|
||||
newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo }
|
||||
val monitor = NodeMonitorModel()
|
||||
@ -79,7 +79,7 @@ class NodeMonitorModelTest {
|
||||
rpc = monitor.proxyObservable.value!!
|
||||
notaryParty = defaultNotaryIdentity
|
||||
|
||||
val bobNodeHandle = startNode(providedName = BOB.name, rpcUsers = listOf(cashUser)).getOrThrow()
|
||||
val bobNodeHandle = startNode(providedName = BOB_NAME, rpcUsers = listOf(cashUser)).getOrThrow()
|
||||
bobNode = bobNodeHandle.nodeInfo
|
||||
val monitorBob = NodeMonitorModel()
|
||||
stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed()
|
||||
@ -91,20 +91,20 @@ class NodeMonitorModelTest {
|
||||
|
||||
@Test
|
||||
fun `network map update`() = setup {
|
||||
val charlieNode = newNode(CHARLIE.name)
|
||||
val charlieNode = newNode(CHARLIE_NAME)
|
||||
val nonServiceIdentities = aliceNode.legalIdentitiesAndCerts + bobNode.legalIdentitiesAndCerts + charlieNode.legalIdentitiesAndCerts
|
||||
networkMapUpdates.filter { it.node.legalIdentitiesAndCerts.any { it in nonServiceIdentities } }
|
||||
.expectEvents(isStrict = false) {
|
||||
sequence(
|
||||
// TODO : Add test for remove when driver DSL support individual node shutdown.
|
||||
expect { output: NetworkMapCache.MapChange ->
|
||||
require(output.node.chooseIdentity().name == ALICE.name) { "Expecting : ${ALICE.name}, Actual : ${output.node.chooseIdentity().name}" }
|
||||
require(output.node.legalIdentities.any { it.name == ALICE_NAME }) { "Expecting : ${ALICE_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" }
|
||||
},
|
||||
expect { output: NetworkMapCache.MapChange ->
|
||||
require(output.node.chooseIdentity().name == BOB.name) { "Expecting : ${BOB.name}, Actual : ${output.node.chooseIdentity().name}" }
|
||||
require(output.node.legalIdentities.any { it.name == BOB_NAME }) { "Expecting : ${BOB_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" }
|
||||
},
|
||||
expect { output: NetworkMapCache.MapChange ->
|
||||
require(output.node.chooseIdentity().name == CHARLIE.name) { "Expecting : ${CHARLIE.name}, Actual : ${output.node.chooseIdentity().name}" }
|
||||
require(output.node.legalIdentities.any { it.name == CHARLIE_NAME }) { "Expecting : ${CHARLIE_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.corda.client.rpc
|
||||
|
||||
import net.corda.core.context.*
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.concurrent.flatMap
|
||||
import net.corda.core.internal.packageName
|
||||
import net.corda.core.messaging.*
|
||||
@ -28,7 +29,6 @@ import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
@ -42,6 +42,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
|
||||
invokeRpc("vaultQueryByCriteria"))
|
||||
)
|
||||
private lateinit var node: StartedNode<Node>
|
||||
private lateinit var identity: Party
|
||||
private lateinit var client: CordaRPCClient
|
||||
private var connection: CordaRPCConnection? = null
|
||||
|
||||
@ -51,8 +52,9 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
node = startNode(ALICE.name, rpcUsers = listOf(rpcUser))
|
||||
node = startNode(ALICE_NAME, rpcUsers = listOf(rpcUser))
|
||||
client = CordaRPCClient(node.internals.configuration.rpcAddress!!)
|
||||
identity = node.info.identityFromX500Name(ALICE_NAME)
|
||||
}
|
||||
|
||||
@After
|
||||
@ -86,7 +88,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
|
||||
println("Creating proxy")
|
||||
println("Starting flow")
|
||||
val flowHandle = connection!!.proxy.startTrackedFlow(::CashIssueFlow,
|
||||
20.DOLLARS, OpaqueBytes.of(0), node.info.chooseIdentity()
|
||||
20.DOLLARS, OpaqueBytes.of(0), identity
|
||||
)
|
||||
println("Started flow, waiting on result")
|
||||
flowHandle.progress.subscribe {
|
||||
@ -98,7 +100,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
|
||||
@Test
|
||||
fun `sub-type of FlowException thrown by flow`() {
|
||||
login(rpcUser.username, rpcUser.password)
|
||||
val handle = connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, node.info.chooseIdentity())
|
||||
val handle = connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, identity)
|
||||
assertThatExceptionOfType(CashException::class.java).isThrownBy {
|
||||
handle.returnValue.getOrThrow()
|
||||
}
|
||||
@ -107,7 +109,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
|
||||
@Test
|
||||
fun `check basic flow has no progress`() {
|
||||
login(rpcUser.username, rpcUser.password)
|
||||
connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, node.info.chooseIdentity()).use {
|
||||
connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, identity).use {
|
||||
assertFalse(it is FlowProgressHandle<*>)
|
||||
}
|
||||
}
|
||||
@ -120,7 +122,7 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
|
||||
assertTrue(startCash.isEmpty(), "Should not start with any cash")
|
||||
|
||||
val flowHandle = proxy.startFlow(::CashIssueFlow,
|
||||
123.DOLLARS, OpaqueBytes.of(0), node.info.chooseIdentity()
|
||||
123.DOLLARS, OpaqueBytes.of(0), identity
|
||||
)
|
||||
println("Started issuing cash, waiting on result")
|
||||
flowHandle.returnValue.get()
|
||||
@ -136,13 +138,12 @@ class CordaRPCClientTest : NodeBasedTest(listOf("net.corda.finance.contracts", C
|
||||
val impersonatedActor = Actor(Actor.Id("Mark Dadada"), AuthServiceId("Test"), owningLegalIdentity = BOB.name)
|
||||
login(rpcUser.username, rpcUser.password, externalTrace, impersonatedActor)
|
||||
val proxy = connection!!.proxy
|
||||
val nodeIdentity = node.info.chooseIdentity()
|
||||
|
||||
val updates = proxy.stateMachinesFeed().updates
|
||||
|
||||
node.services.startFlow(CashIssueFlow(2000.DOLLARS, OpaqueBytes.of(0), nodeIdentity), InvocationContext.shell()).flatMap { it.resultFuture }.getOrThrow()
|
||||
proxy.startFlow(::CashIssueFlow, 123.DOLLARS, OpaqueBytes.of(0), nodeIdentity).returnValue.getOrThrow()
|
||||
proxy.startFlowDynamic(CashIssueFlow::class.java, 1000.DOLLARS, OpaqueBytes.of(0), nodeIdentity).returnValue.getOrThrow()
|
||||
node.services.startFlow(CashIssueFlow(2000.DOLLARS, OpaqueBytes.of(0),identity), InvocationContext.shell()).flatMap { it.resultFuture }.getOrThrow()
|
||||
proxy.startFlow(::CashIssueFlow, 123.DOLLARS, OpaqueBytes.of(0), identity).returnValue.getOrThrow()
|
||||
proxy.startFlowDynamic(CashIssueFlow::class.java, 1000.DOLLARS, OpaqueBytes.of(0), identity).returnValue.getOrThrow()
|
||||
|
||||
val historicalIds = mutableSetOf<Trace.InvocationId>()
|
||||
var sessionId: Trace.SessionId? = null
|
||||
|
@ -3,10 +3,12 @@ package net.corda.confidential
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import org.junit.Before
|
||||
import net.corda.testing.node.MockNodeParameters
|
||||
import org.junit.Test
|
||||
import kotlin.test.*
|
||||
|
||||
@ -83,28 +85,30 @@ class SwapIdentitiesFlowTests {
|
||||
val notaryNode = mockNet.defaultNotaryNode
|
||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||
val bob: Party = bobNode.services.myInfo.singleIdentity()
|
||||
val alice: PartyAndCertificate = aliceNode.info.singleIdentityAndCert()
|
||||
val bob: PartyAndCertificate = bobNode.info.singleIdentityAndCert()
|
||||
val notary: PartyAndCertificate = mockNet.defaultNotaryIdentityAndCert
|
||||
// Check that the wrong signature is rejected
|
||||
notaryNode.database.transaction {
|
||||
notaryNode.services.keyManagementService.freshKeyAndCert(notaryNode.services.myInfo.chooseIdentityAndCert(), false)
|
||||
notaryNode.services.keyManagementService.freshKeyAndCert(notary, false)
|
||||
}.let { anonymousNotary ->
|
||||
val sigData = SwapIdentitiesFlow.buildDataToSign(anonymousNotary)
|
||||
val signature = notaryNode.services.keyManagementService.sign(sigData, anonymousNotary.owningKey)
|
||||
assertFailsWith<SwapIdentitiesException>("Signature does not match the given identity and nonce") {
|
||||
SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob, anonymousNotary, signature.withoutKey())
|
||||
SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob.party, anonymousNotary, signature.withoutKey())
|
||||
}
|
||||
}
|
||||
// Check that the right signing key, but wrong identity is rejected
|
||||
val anonymousAlice = aliceNode.database.transaction {
|
||||
aliceNode.services.keyManagementService.freshKeyAndCert(aliceNode.services.myInfo.chooseIdentityAndCert(), false)
|
||||
val anonymousAlice: PartyAndCertificate = aliceNode.database.transaction {
|
||||
aliceNode.services.keyManagementService.freshKeyAndCert(alice, false)
|
||||
}
|
||||
bobNode.database.transaction {
|
||||
bobNode.services.keyManagementService.freshKeyAndCert(bobNode.services.myInfo.chooseIdentityAndCert(), false)
|
||||
bobNode.services.keyManagementService.freshKeyAndCert(bob, false)
|
||||
}.let { anonymousBob ->
|
||||
val sigData = SwapIdentitiesFlow.buildDataToSign(anonymousAlice)
|
||||
val signature = bobNode.services.keyManagementService.sign(sigData, anonymousBob.owningKey)
|
||||
assertFailsWith<SwapIdentitiesException>("Signature does not match the given identity and nonce.") {
|
||||
SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob, anonymousBob, signature.withoutKey())
|
||||
SwapIdentitiesFlow.validateAndRegisterIdentity(aliceNode.services.identityService, bob.party, anonymousBob, signature.withoutKey())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,21 @@ data class NodeInfo(val addresses: List<NetworkHostAndPort>,
|
||||
/** Returns true if [party] is one of the identities of this node, else false. */
|
||||
fun isLegalIdentity(party: Party): Boolean = party in legalIdentities
|
||||
|
||||
fun identityFromX500Name(name: CordaX500Name): Party {
|
||||
val identity = legalIdentitiesAndCerts.singleOrNull { it.name == name } ?: throw IllegalArgumentException("Node does not have an identity \"$name\"")
|
||||
return identity.party
|
||||
/**
|
||||
* Get a legal identity of this node from the X.500 name. This is intended for use in cases where the node is
|
||||
* expected to have a matching identity, and will throw an exception if no match is found.
|
||||
*
|
||||
* @throws IllegalArgumentException if the node has no matching identity.
|
||||
*/
|
||||
fun identityFromX500Name(name: CordaX500Name): Party = identityAndCertFromX500Name(name).party
|
||||
|
||||
/**
|
||||
* Get a legal identity and certificate of this node from the X.500 name. This is intended for use in cases where
|
||||
* the node is expected to have a matching identity, and will throw an exception if no match is found.
|
||||
*
|
||||
* @throws IllegalArgumentException if the node has no matching identity.
|
||||
*/
|
||||
fun identityAndCertFromX500Name(name: CordaX500Name): PartyAndCertificate {
|
||||
return legalIdentitiesAndCerts.singleOrNull { it.name == name } ?: throw IllegalArgumentException("Node does not have an identity \"$name\"")
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import co.paralleluniverse.fibers.Suspendable;
|
||||
import com.google.common.primitives.Primitives;
|
||||
import net.corda.core.identity.Party;
|
||||
import net.corda.node.internal.StartedNode;
|
||||
import net.corda.testing.node.MockNetwork;
|
||||
import net.corda.testing.TestConstants;
|
||||
import net.corda.testing.node.MockNetwork;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -13,7 +13,7 @@ import org.junit.Test;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static net.corda.testing.CoreTestUtils.chooseIdentity;
|
||||
import static net.corda.testing.CoreTestUtils.singleIdentity;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static net.corda.testing.NodeTestUtils.startFlow;
|
||||
@ -22,11 +22,13 @@ public class FlowsInJavaTest {
|
||||
private final MockNetwork mockNet = new MockNetwork();
|
||||
private StartedNode<MockNetwork.MockNode> aliceNode;
|
||||
private StartedNode<MockNetwork.MockNode> bobNode;
|
||||
private Party bob;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
aliceNode = mockNet.createPartyNode(TestConstants.getALICE().getName());
|
||||
bobNode = mockNet.createPartyNode(TestConstants.getBOB().getName());
|
||||
bob = singleIdentity(bobNode.getInfo());
|
||||
}
|
||||
|
||||
@After
|
||||
@ -37,7 +39,7 @@ public class FlowsInJavaTest {
|
||||
@Test
|
||||
public void suspendableActionInsideUnwrap() throws Exception {
|
||||
bobNode.getInternals().registerInitiatedFlow(SendHelloAndThenReceive.class);
|
||||
Future<String> result = startFlow(aliceNode.getServices(), new SendInUnwrapFlow(chooseIdentity(bobNode.getInfo()))).getResultFuture();
|
||||
Future<String> result = startFlow(aliceNode.getServices(), new SendInUnwrapFlow(bob)).getResultFuture();
|
||||
mockNet.runNetwork();
|
||||
assertThat(result.get()).isEqualTo("Hello");
|
||||
}
|
||||
@ -52,7 +54,7 @@ public class FlowsInJavaTest {
|
||||
}
|
||||
|
||||
private void primitiveReceiveTypeTest(Class<?> receiveType) throws InterruptedException {
|
||||
PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(chooseIdentity(bobNode.getInfo()), receiveType);
|
||||
PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(bob, receiveType);
|
||||
Future<?> result = startFlow(aliceNode.getServices(), flow).getResultFuture();
|
||||
mockNet.runNetwork();
|
||||
try {
|
||||
|
@ -41,13 +41,20 @@ class ContractUpgradeFlowTest {
|
||||
private lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var bobNode: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var notary: Party
|
||||
private lateinit var alice: Party
|
||||
private lateinit var bob: Party
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows"))
|
||||
aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
bobNode = mockNet.createPartyNode(BOB.name)
|
||||
aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||
bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||
notary = mockNet.defaultNotaryIdentity
|
||||
alice = aliceNode.info.singleIdentity()
|
||||
bob = bobNode.info.singleIdentity()
|
||||
|
||||
// Process registration
|
||||
mockNet.runNetwork()
|
||||
}
|
||||
|
||||
@After
|
||||
@ -58,11 +65,11 @@ class ContractUpgradeFlowTest {
|
||||
@Test
|
||||
fun `2 parties contract upgrade`() {
|
||||
// Create dummy contract.
|
||||
val twoPartyDummyContract = DummyContract.generateInitial(0, notary, aliceNode.info.chooseIdentity().ref(1), bobNode.info.chooseIdentity().ref(1))
|
||||
val twoPartyDummyContract = DummyContract.generateInitial(0, notary, alice.ref(1), bob.ref(1))
|
||||
val signedByA = aliceNode.services.signInitialTransaction(twoPartyDummyContract)
|
||||
val stx = bobNode.services.addSignature(signedByA)
|
||||
|
||||
aliceNode.services.startFlow(FinalityFlow(stx, setOf(bobNode.info.chooseIdentity())))
|
||||
aliceNode.services.startFlow(FinalityFlow(stx, setOf(bob)))
|
||||
mockNet.runNetwork()
|
||||
|
||||
val atx = aliceNode.database.transaction { aliceNode.services.validatedTransactions.getTransaction(stx.id) }
|
||||
@ -128,7 +135,7 @@ class ContractUpgradeFlowTest {
|
||||
fun `2 parties contract upgrade using RPC`() {
|
||||
rpcDriver(initialiseSerialization = false) {
|
||||
// Create dummy contract.
|
||||
val twoPartyDummyContract = DummyContract.generateInitial(0, notary, aliceNode.info.chooseIdentity().ref(1), bobNode.info.chooseIdentity().ref(1))
|
||||
val twoPartyDummyContract = DummyContract.generateInitial(0, notary, alice.ref(1), bob.ref(1))
|
||||
val signedByA = aliceNode.services.signInitialTransaction(twoPartyDummyContract)
|
||||
val stx = bobNode.services.addSignature(signedByA)
|
||||
|
||||
@ -140,7 +147,7 @@ class ContractUpgradeFlowTest {
|
||||
))
|
||||
val rpcA = startProxy(aliceNode, user)
|
||||
val rpcB = startProxy(bobNode, user)
|
||||
val handle = rpcA.startFlow(::FinalityInvoker, stx, setOf(bobNode.info.chooseIdentity()))
|
||||
val handle = rpcA.startFlow(::FinalityInvoker, stx, setOf(bob))
|
||||
mockNet.runNetwork()
|
||||
handle.returnValue.getOrThrow()
|
||||
|
||||
@ -202,7 +209,7 @@ class ContractUpgradeFlowTest {
|
||||
@Test
|
||||
fun `upgrade Cash to v2`() {
|
||||
// Create some cash.
|
||||
val chosenIdentity = aliceNode.info.chooseIdentity()
|
||||
val chosenIdentity = alice
|
||||
val result = aliceNode.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), notary)).resultFuture
|
||||
mockNet.runNetwork()
|
||||
val stx = result.getOrThrow().stx
|
||||
|
@ -5,8 +5,8 @@ import net.corda.core.identity.Party
|
||||
import net.corda.core.utilities.UntrustworthyData
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.unwrap
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.node.network
|
||||
import net.corda.testing.singleIdentity
|
||||
import net.corda.testing.startFlow
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
@ -20,7 +20,7 @@ class ReceiveMultipleFlowTests {
|
||||
val stringValue = "Thriller"
|
||||
nodes[2].registerAnswer(AlgorithmDefinition::class, stringValue)
|
||||
|
||||
val flow = nodes[0].services.startFlow(ParallelAlgorithmMap(nodes[1].info.chooseIdentity(), nodes[2].info.chooseIdentity()))
|
||||
val flow = nodes[0].services.startFlow(ParallelAlgorithmMap(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity()))
|
||||
runNetwork()
|
||||
|
||||
val result = flow.resultFuture.getOrThrow()
|
||||
@ -37,7 +37,7 @@ class ReceiveMultipleFlowTests {
|
||||
val value2 = 6.0
|
||||
nodes[2].registerAnswer(ParallelAlgorithmList::class, value2)
|
||||
|
||||
val flow = nodes[0].services.startFlow(ParallelAlgorithmList(nodes[1].info.chooseIdentity(), nodes[2].info.chooseIdentity()))
|
||||
val flow = nodes[0].services.startFlow(ParallelAlgorithmList(nodes[1].info.singleIdentity(), nodes[2].info.singleIdentity()))
|
||||
runNetwork()
|
||||
val data = flow.resultFuture.getOrThrow()
|
||||
|
||||
|
@ -10,9 +10,9 @@ import net.corda.core.utilities.sequence
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.testing.MEGA_CORP
|
||||
import net.corda.testing.MINI_CORP
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.singleIdentity
|
||||
import net.corda.testing.startFlow
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -45,8 +45,8 @@ class ResolveTransactionsFlowTest {
|
||||
megaCorpNode.internals.registerInitiatedFlow(TestResponseFlow::class.java)
|
||||
miniCorpNode.internals.registerInitiatedFlow(TestResponseFlow::class.java)
|
||||
notary = mockNet.defaultNotaryIdentity
|
||||
megaCorp = megaCorpNode.info.chooseIdentity()
|
||||
miniCorp = miniCorpNode.info.chooseIdentity()
|
||||
megaCorp = megaCorpNode.info.singleIdentity()
|
||||
miniCorp = miniCorpNode.info.singleIdentity()
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -7,6 +7,7 @@ import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.FlowSession
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.TestDataVendingFlow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.FetchAttachmentsFlow
|
||||
import net.corda.core.internal.FetchDataFlow
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
@ -15,9 +16,11 @@ import net.corda.node.internal.InitiatedFlowFactory
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.node.services.persistence.NodeAttachmentService
|
||||
import net.corda.node.utilities.currentDBSession
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.ALICE_NAME
|
||||
import net.corda.testing.BOB_NAME
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNodeParameters
|
||||
import net.corda.testing.singleIdentity
|
||||
import net.corda.testing.startFlow
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -63,13 +66,16 @@ class AttachmentSerializationTest {
|
||||
private lateinit var mockNet: MockNetwork
|
||||
private lateinit var server: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var client: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var serverIdentity: Party
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mockNet = MockNetwork()
|
||||
server = mockNet.createNode()
|
||||
client = mockNet.createNode()
|
||||
server = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
||||
client = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
|
||||
client.internals.disableDBCloseOnStop() // Otherwise the in-memory database may disappear (taking the checkpoint with it) while we reboot the client.
|
||||
mockNet.runNetwork()
|
||||
serverIdentity = server.info.singleIdentity()
|
||||
}
|
||||
|
||||
@After
|
||||
@ -91,9 +97,7 @@ class AttachmentSerializationTest {
|
||||
private class ClientResult(internal val attachmentContent: String)
|
||||
|
||||
@InitiatingFlow
|
||||
private abstract class ClientLogic(server: StartedNode<*>) : FlowLogic<ClientResult>() {
|
||||
internal val server = server.info.chooseIdentity()
|
||||
|
||||
private abstract class ClientLogic(val serverIdentity: Party) : FlowLogic<ClientResult>() {
|
||||
@Suspendable
|
||||
internal fun communicate(serverSession: FlowSession) {
|
||||
serverSession.sendAndReceive<String>("ping one").unwrap { assertEquals("pong", it) }
|
||||
@ -112,30 +116,30 @@ class AttachmentSerializationTest {
|
||||
override val signers get() = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
private class CustomAttachmentLogic(server: StartedNode<*>, private val attachmentId: SecureHash, private val customContent: String) : ClientLogic(server) {
|
||||
private class CustomAttachmentLogic(serverIdentity: Party, private val attachmentId: SecureHash, private val customContent: String) : ClientLogic(serverIdentity) {
|
||||
@Suspendable
|
||||
override fun getAttachmentContent(): String {
|
||||
val customAttachment = CustomAttachment(attachmentId, customContent)
|
||||
val session = initiateFlow(server)
|
||||
val session = initiateFlow(serverIdentity)
|
||||
communicate(session)
|
||||
return customAttachment.customContent
|
||||
}
|
||||
}
|
||||
|
||||
private class OpenAttachmentLogic(server: StartedNode<*>, private val attachmentId: SecureHash) : ClientLogic(server) {
|
||||
private class OpenAttachmentLogic(serverIdentity: Party, private val attachmentId: SecureHash) : ClientLogic(serverIdentity) {
|
||||
@Suspendable
|
||||
override fun getAttachmentContent(): String {
|
||||
val localAttachment = serviceHub.attachments.openAttachment(attachmentId)!!
|
||||
val session = initiateFlow(server)
|
||||
val session = initiateFlow(serverIdentity)
|
||||
communicate(session)
|
||||
return localAttachment.extractContent()
|
||||
}
|
||||
}
|
||||
|
||||
private class FetchAttachmentLogic(server: StartedNode<*>, private val attachmentId: SecureHash) : ClientLogic(server) {
|
||||
private class FetchAttachmentLogic(serverIdentity: Party, private val attachmentId: SecureHash) : ClientLogic(serverIdentity) {
|
||||
@Suspendable
|
||||
override fun getAttachmentContent(): String {
|
||||
val serverSession = initiateFlow(server)
|
||||
val serverSession = initiateFlow(serverIdentity)
|
||||
val (downloadedAttachment) = subFlow(FetchAttachmentsFlow(setOf(attachmentId), serverSession)).downloaded
|
||||
serverSession.send(FetchDataFlow.Request.End)
|
||||
communicate(serverSession)
|
||||
@ -166,14 +170,14 @@ class AttachmentSerializationTest {
|
||||
@Test
|
||||
fun `custom (and non-persisted) attachment should be saved in checkpoint`() {
|
||||
val attachmentId = SecureHash.sha256("any old data")
|
||||
launchFlow(CustomAttachmentLogic(server, attachmentId, "custom"), 1)
|
||||
launchFlow(CustomAttachmentLogic(serverIdentity, attachmentId, "custom"), 1)
|
||||
assertEquals("custom", rebootClientAndGetAttachmentContent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `custom attachment should be saved in checkpoint even if its data was persisted`() {
|
||||
val attachmentId = client.saveAttachment("genuine")
|
||||
launchFlow(CustomAttachmentLogic(server, attachmentId, "custom"), 1)
|
||||
launchFlow(CustomAttachmentLogic(serverIdentity, attachmentId, "custom"), 1)
|
||||
client.hackAttachment(attachmentId, "hacked") // Should not be reloaded, checkAttachmentsOnLoad may cause next line to blow up if client attempts it.
|
||||
assertEquals("custom", rebootClientAndGetAttachmentContent())
|
||||
}
|
||||
@ -182,7 +186,7 @@ class AttachmentSerializationTest {
|
||||
fun `only the hash of a regular attachment should be saved in checkpoint`() {
|
||||
val attachmentId = client.saveAttachment("genuine")
|
||||
client.attachments.checkAttachmentsOnLoad = false // Cached by AttachmentImpl.
|
||||
launchFlow(OpenAttachmentLogic(server, attachmentId), 1)
|
||||
launchFlow(OpenAttachmentLogic(serverIdentity, attachmentId), 1)
|
||||
client.hackAttachment(attachmentId, "hacked")
|
||||
assertEquals("hacked", rebootClientAndGetAttachmentContent(false)) // Pass in false to allow non-genuine data to be loaded.
|
||||
}
|
||||
@ -190,7 +194,7 @@ class AttachmentSerializationTest {
|
||||
@Test
|
||||
fun `only the hash of a FetchAttachmentsFlow attachment should be saved in checkpoint`() {
|
||||
val attachmentId = server.saveAttachment("genuine")
|
||||
launchFlow(FetchAttachmentLogic(server, attachmentId), 2, sendData = true)
|
||||
launchFlow(FetchAttachmentLogic(serverIdentity, attachmentId), 2, sendData = true)
|
||||
client.hackAttachment(attachmentId, "hacked")
|
||||
assertEquals("hacked", rebootClientAndGetAttachmentContent(false))
|
||||
}
|
||||
|
@ -2,9 +2,13 @@ package net.corda.core.transactions
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.testing.*
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.SerializationEnvironmentRule
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.dummyCommand
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.singleIdentity
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@ -18,6 +22,7 @@ class LedgerTransactionQueryTests {
|
||||
@JvmField
|
||||
val testSerialization = SerializationEnvironmentRule()
|
||||
private val services: MockServices = MockServices()
|
||||
private val identity: Party = services.myInfo.singleIdentity()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
@ -66,8 +71,8 @@ class LedgerTransactionQueryTests {
|
||||
tx.addInputState(makeDummyStateAndRef(i.toString()))
|
||||
tx.addOutputState(makeDummyState(i), DummyContract.PROGRAM_ID)
|
||||
tx.addOutputState(makeDummyState(i.toString()), DummyContract.PROGRAM_ID)
|
||||
tx.addCommand(Commands.Cmd1(i), listOf(services.myInfo.chooseIdentity().owningKey))
|
||||
tx.addCommand(Commands.Cmd2(i), listOf(services.myInfo.chooseIdentity().owningKey))
|
||||
tx.addCommand(Commands.Cmd1(i), listOf(identity.owningKey))
|
||||
tx.addCommand(Commands.Cmd2(i), listOf(identity.owningKey))
|
||||
}
|
||||
return tx.toLedgerTransaction(services)
|
||||
}
|
||||
|
@ -7,8 +7,7 @@ import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.testing.BOC
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.BOC_NAME
|
||||
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNetwork.MockNode
|
||||
@ -31,8 +30,8 @@ class CashExitFlowTests {
|
||||
fun start() {
|
||||
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(),
|
||||
cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
||||
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
||||
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
||||
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
|
||||
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
|
||||
notary = mockNet.defaultNotaryIdentity
|
||||
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture
|
||||
mockNet.runNetwork()
|
||||
|
@ -7,8 +7,7 @@ import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.`issued by`
|
||||
import net.corda.finance.contracts.asset.Cash
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.testing.BOC
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.BOC_NAME
|
||||
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNetwork.MockNode
|
||||
@ -28,8 +27,8 @@ class CashIssueFlowTests {
|
||||
@Before
|
||||
fun start() {
|
||||
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
||||
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
||||
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
||||
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
|
||||
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
|
||||
notary = mockNet.defaultNotaryIdentity
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,9 @@ class CashPaymentFlowTests {
|
||||
@Before
|
||||
fun start() {
|
||||
mockNet = MockNetwork(servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
||||
bankOfCordaNode = mockNet.createPartyNode(BOC.name)
|
||||
aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
bankOfCorda = bankOfCordaNode.info.chooseIdentity()
|
||||
bankOfCordaNode = mockNet.createPartyNode(BOC_NAME)
|
||||
bankOfCorda = bankOfCordaNode.info.identityFromX500Name(BOC_NAME)
|
||||
aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||
val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, mockNet.defaultNotaryIdentity)).resultFuture
|
||||
future.getOrThrow()
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import net.corda.node.services.messaging.RpcPermissions
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNetwork.MockNode
|
||||
import net.corda.testing.node.MockNodeParameters
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.junit.After
|
||||
@ -54,6 +55,7 @@ class CordaRPCOpsImplTest {
|
||||
|
||||
private lateinit var mockNet: MockNetwork
|
||||
private lateinit var aliceNode: StartedNode<MockNode>
|
||||
private lateinit var alice: Party
|
||||
private lateinit var notary: Party
|
||||
private lateinit var rpc: CordaRPCOps
|
||||
private lateinit var stateMachineUpdates: Observable<StateMachineUpdate>
|
||||
@ -63,14 +65,15 @@ class CordaRPCOpsImplTest {
|
||||
@Before
|
||||
fun setup() {
|
||||
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset"))
|
||||
aliceNode = mockNet.createNode()
|
||||
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
||||
rpc = SecureCordaRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database, aliceNode.services)
|
||||
CURRENT_RPC_CONTEXT.set(RpcAuthContext(InvocationContext.rpc(testActor()), RpcPermissions.NONE))
|
||||
|
||||
mockNet.runNetwork()
|
||||
withPermissions(invokeRpc(CordaRPCOps::notaryIdentities)) {
|
||||
notary = rpc.notaryIdentities().first()
|
||||
notary = rpc.notaryIdentities().single()
|
||||
}
|
||||
alice = aliceNode.services.myInfo.identityFromX500Name(ALICE_NAME)
|
||||
}
|
||||
|
||||
@After
|
||||
@ -115,7 +118,7 @@ class CordaRPCOpsImplTest {
|
||||
|
||||
val anonymisedRecipient = result.returnValue.getOrThrow().recipient!!
|
||||
val expectedState = Cash.State(Amount(quantity,
|
||||
Issued(aliceNode.info.chooseIdentity().ref(ref), GBP)),
|
||||
Issued(alice.ref(ref), GBP)),
|
||||
anonymisedRecipient)
|
||||
|
||||
// Query vault via RPC
|
||||
@ -153,7 +156,7 @@ class CordaRPCOpsImplTest {
|
||||
|
||||
mockNet.runNetwork()
|
||||
|
||||
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, aliceNode.info.chooseIdentity())
|
||||
rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, alice)
|
||||
|
||||
mockNet.runNetwork()
|
||||
|
||||
@ -187,7 +190,7 @@ class CordaRPCOpsImplTest {
|
||||
require(stx.tx.outputs.size == 1)
|
||||
val signaturePubKeys = stx.sigs.map { it.by }.toSet()
|
||||
// Only Alice signed, as issuer
|
||||
val aliceKey = aliceNode.info.chooseIdentity().owningKey
|
||||
val aliceKey = alice.owningKey
|
||||
require(signaturePubKeys.size <= aliceKey.keys.size)
|
||||
require(aliceKey.isFulfilledBy(signaturePubKeys))
|
||||
},
|
||||
|
@ -97,6 +97,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||
val alice = aliceNode.info.singleIdentity()
|
||||
val bank = bankNode.info.singleIdentity()
|
||||
val bob = bobNode.info.singleIdentity()
|
||||
val notary = mockNet.defaultNotaryIdentity
|
||||
val cashIssuer = bank.ref(1)
|
||||
val cpIssuer = bank.ref(1, 2, 3)
|
||||
@ -114,9 +115,9 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
1200.DOLLARS `issued by` bank.ref(0), null, notary).second
|
||||
}
|
||||
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
|
||||
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode,
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, bob, aliceNode, bobNode,
|
||||
"alice's paper".outputStateAndRef())
|
||||
|
||||
// TODO: Verify that the result was inserted into the transaction database.
|
||||
@ -147,6 +148,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
val bankNode = mockNet.createPartyNode(BOC_NAME)
|
||||
val alice = aliceNode.info.singleIdentity()
|
||||
val bank = bankNode.info.singleIdentity()
|
||||
val bob = bobNode.info.singleIdentity()
|
||||
val issuer = bank.ref(1)
|
||||
val notary = mockNet.defaultNotaryIdentity
|
||||
|
||||
@ -163,7 +165,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
1200.DOLLARS `issued by` bank.ref(0), null, notary).second
|
||||
}
|
||||
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
|
||||
|
||||
val cashLockId = UUID.randomUUID()
|
||||
bobNode.database.transaction {
|
||||
@ -174,7 +176,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode,
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, bob, aliceNode, bobNode,
|
||||
"alice's paper".outputStateAndRef())
|
||||
|
||||
assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow())
|
||||
@ -210,6 +212,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
val notary = mockNet.defaultNotaryIdentity
|
||||
val alice = aliceNode.info.singleIdentity()
|
||||
val bank = bankNode.info.singleIdentity()
|
||||
val bob = bobNode.info.singleIdentity()
|
||||
val issuer = bank.ref(1, 2, 3)
|
||||
|
||||
bobNode.database.transaction {
|
||||
@ -220,8 +223,8 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
fillUpForSeller(false, issuer, alice,
|
||||
1200.DOLLARS `issued by` bank.ref(0), null, notary).second
|
||||
}
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
|
||||
val aliceFuture = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
|
||||
val aliceFuture = runBuyerAndSeller(notary, bob, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult
|
||||
|
||||
// Everything is on this thread so we can now step through the flow one step at a time.
|
||||
// Seller Alice already sent a message to Buyer Bob. Pump once:
|
||||
@ -333,16 +336,16 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
val bobsFakeCash = bobNode.database.transaction {
|
||||
fillUpForBuyer(false, issuer, AnonymousParty(bob.owningKey), notary)
|
||||
}.second
|
||||
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode)
|
||||
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, bob, notaryNode, bankNode)
|
||||
val alicesFakePaper = aliceNode.database.transaction {
|
||||
fillUpForSeller(false, issuer, alice,
|
||||
1200.DOLLARS `issued by` bank.ref(0), attachmentID, notary).second
|
||||
}
|
||||
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
|
||||
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
|
||||
|
||||
mockNet.runNetwork() // Clear network map registration messages
|
||||
|
||||
runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef())
|
||||
runBuyerAndSeller(notary, bob, aliceNode, bobNode, "alice's paper".outputStateAndRef())
|
||||
|
||||
mockNet.runNetwork()
|
||||
|
||||
@ -420,6 +423,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
val notary = mockNet.defaultNotaryIdentity
|
||||
val alice: Party = aliceNode.info.singleIdentity()
|
||||
val bank: Party = bankNode.info.singleIdentity()
|
||||
val bob = bobNode.info.singleIdentity()
|
||||
val issuer = bank.ref(1, 2, 3)
|
||||
|
||||
ledger(aliceNode.services) {
|
||||
@ -438,20 +442,20 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
val bobsFakeCash = bobNode.database.transaction {
|
||||
fillUpForBuyer(false, issuer, AnonymousParty(bobsKey), notary)
|
||||
}.second
|
||||
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode)
|
||||
insertFakeTransactions(bobsFakeCash, bobNode, bob, notaryNode, bankNode)
|
||||
|
||||
val alicesFakePaper = aliceNode.database.transaction {
|
||||
fillUpForSeller(false, issuer, alice,
|
||||
1200.DOLLARS `issued by` bank.ref(0), attachmentID, notary).second
|
||||
}
|
||||
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
|
||||
|
||||
val aliceTxStream = aliceNode.services.validatedTransactions.track().updates
|
||||
val aliceTxMappings = with(aliceNode) {
|
||||
database.transaction { services.stateMachineRecordedTransactionMapping.track().updates }
|
||||
}
|
||||
val aliceSmId = runBuyerAndSeller(notary, aliceNode, bobNode,
|
||||
val aliceSmId = runBuyerAndSeller(notary, bob, aliceNode, bobNode,
|
||||
"alice's paper".outputStateAndRef()).sellerId
|
||||
|
||||
mockNet.runNetwork()
|
||||
@ -511,12 +515,13 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
)
|
||||
|
||||
private fun runBuyerAndSeller(notary: Party,
|
||||
buyer: Party,
|
||||
sellerNode: StartedNode<MockNetwork.MockNode>,
|
||||
buyerNode: StartedNode<MockNetwork.MockNode>,
|
||||
assetToSell: StateAndRef<OwnableState>): RunResult {
|
||||
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java)
|
||||
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine }
|
||||
val seller = SellerInitiator(buyerNode.info.chooseIdentity(), notary, assetToSell, 1000.DOLLARS, anonymous)
|
||||
val seller = SellerInitiator(buyer, notary, assetToSell, 1000.DOLLARS, anonymous)
|
||||
val sellerResult = sellerNode.services.startFlow(seller).resultFuture
|
||||
return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id)
|
||||
}
|
||||
@ -582,10 +587,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
fillUpForSeller(aliceError, issuer, alice,1200.DOLLARS `issued by` issuer, null, notary).second
|
||||
}
|
||||
|
||||
insertFakeTransactions(bobsBadCash, bobNode, notaryNode, bankNode)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode)
|
||||
insertFakeTransactions(bobsBadCash, bobNode, bob, notaryNode, bankNode)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, alice, notaryNode, bankNode)
|
||||
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef())
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, bob, aliceNode, bobNode, "alice's paper".outputStateAndRef())
|
||||
|
||||
mockNet.runNetwork()
|
||||
|
||||
@ -605,13 +610,14 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
private fun insertFakeTransactions(
|
||||
wtxToSign: List<WireTransaction>,
|
||||
node: StartedNode<*>,
|
||||
identity: Party,
|
||||
notaryNode: StartedNode<*>,
|
||||
vararg extraSigningNodes: StartedNode<*>): Map<SecureHash, SignedTransaction> {
|
||||
val notaryParty = mockNet.defaultNotaryIdentity
|
||||
val signed = wtxToSign.map {
|
||||
val id = it.id
|
||||
val sigs = mutableListOf<TransactionSignature>()
|
||||
val nodeKey = node.info.chooseIdentity().owningKey
|
||||
val nodeKey = identity.owningKey
|
||||
sigs += node.services.keyManagementService.sign(
|
||||
SignableData(id, SignatureMetadata(1, Crypto.findSignatureScheme(nodeKey).schemeNumberID)),
|
||||
nodeKey
|
||||
@ -621,11 +627,12 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
|
||||
notaryParty.owningKey
|
||||
)
|
||||
extraSigningNodes.forEach { currentNode ->
|
||||
val currentIdentity = currentNode.info.singleIdentity()
|
||||
sigs += currentNode.services.keyManagementService.sign(
|
||||
SignableData(id, SignatureMetadata(
|
||||
1,
|
||||
Crypto.findSignatureScheme(currentNode.info.chooseIdentity().owningKey).schemeNumberID)),
|
||||
currentNode.info.chooseIdentity().owningKey)
|
||||
Crypto.findSignatureScheme(currentIdentity.owningKey).schemeNumberID)),
|
||||
currentIdentity.owningKey)
|
||||
}
|
||||
SignedTransaction(it, sigs)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import net.corda.testing.*
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNetwork.NotarySpec
|
||||
import net.corda.testing.node.MockNodeParameters
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -37,6 +38,7 @@ class NotaryChangeTests {
|
||||
private lateinit var clientNodeB: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var newNotaryParty: Party
|
||||
private lateinit var oldNotaryParty: Party
|
||||
private lateinit var clientA: Party
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
@ -45,8 +47,9 @@ class NotaryChangeTests {
|
||||
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY.name), NotarySpec(oldNotaryName)),
|
||||
cordappPackages = listOf("net.corda.testing.contracts")
|
||||
)
|
||||
clientNodeA = mockNet.createNode()
|
||||
clientNodeB = mockNet.createNode()
|
||||
clientNodeA = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
||||
clientNodeB = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
|
||||
clientA = clientNodeA.info.singleIdentity()
|
||||
oldNotaryNode = mockNet.notaryNodes[1]
|
||||
newNotaryParty = clientNodeA.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME)!!
|
||||
oldNotaryParty = clientNodeA.services.networkMapCache.getNotary(DUMMY_NOTARY_SERVICE_NAME.copy(organisation = "Old Dummy Notary"))!!
|
||||
@ -59,7 +62,7 @@ class NotaryChangeTests {
|
||||
|
||||
@Test
|
||||
fun `should change notary for a state with single participant`() {
|
||||
val state = issueState(clientNodeA, oldNotaryParty)
|
||||
val state = issueState(clientNodeA.services, clientA, oldNotaryParty)
|
||||
assertEquals(state.state.notary, oldNotaryParty)
|
||||
val newState = changeNotary(state, clientNodeA, newNotaryParty)
|
||||
assertEquals(newState.state.notary, newNotaryParty)
|
||||
@ -97,7 +100,7 @@ class NotaryChangeTests {
|
||||
|
||||
@Test
|
||||
fun `should not break encumbrance links`() {
|
||||
val issueTx = issueEncumberedState(clientNodeA, oldNotaryParty)
|
||||
val issueTx = issueEncumberedState(clientNodeA.services, clientA, oldNotaryParty)
|
||||
|
||||
val state = StateAndRef(issueTx.outputs.first(), StateRef(issueTx.id, 0))
|
||||
val newNotary = newNotaryParty
|
||||
@ -131,7 +134,7 @@ class NotaryChangeTests {
|
||||
|
||||
@Test
|
||||
fun `notary change and regular transactions are properly handled during resolution in longer chains`() {
|
||||
val issued = issueState(clientNodeA, oldNotaryParty)
|
||||
val issued = issueState(clientNodeA.services, clientA, oldNotaryParty)
|
||||
val moved = moveState(issued, clientNodeA, clientNodeB)
|
||||
|
||||
// We don't to tx resolution when moving state to another node, so need to add the issue transaction manually
|
||||
@ -170,8 +173,8 @@ class NotaryChangeTests {
|
||||
return finalTransaction.tx.outRef(0)
|
||||
}
|
||||
|
||||
private fun issueEncumberedState(node: StartedNode<*>, notaryIdentity: Party): WireTransaction {
|
||||
val owner = node.info.chooseIdentity().ref(0)
|
||||
private fun issueEncumberedState(services: ServiceHub, nodeIdentity: Party, notaryIdentity: Party): WireTransaction {
|
||||
val owner = nodeIdentity.ref(0)
|
||||
val stateA = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
|
||||
val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
|
||||
val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party)
|
||||
@ -182,9 +185,9 @@ class NotaryChangeTests {
|
||||
addOutputState(stateC, DummyContract.PROGRAM_ID, notaryIdentity)
|
||||
addOutputState(stateB, DummyContract.PROGRAM_ID, notaryIdentity, encumbrance = 1) // Encumbered by stateC
|
||||
}
|
||||
val stx = node.services.signInitialTransaction(tx)
|
||||
node.services.recordTransactions(stx)
|
||||
return tx.toWireTransaction(node.services)
|
||||
val stx = services.signInitialTransaction(tx)
|
||||
services.recordTransactions(stx)
|
||||
return tx.toWireTransaction(services)
|
||||
}
|
||||
|
||||
// TODO: Add more test cases once we have a general flow/service exception handling mechanism:
|
||||
@ -196,10 +199,10 @@ class NotaryChangeTests {
|
||||
// - The transaction type is not a notary change transaction at all.
|
||||
}
|
||||
|
||||
fun issueState(node: StartedNode<*>, notaryIdentity: Party): StateAndRef<DummyContract.SingleOwnerState> {
|
||||
val tx = DummyContract.generateInitial(Random().nextInt(), notaryIdentity, node.info.chooseIdentity().ref(0))
|
||||
val stx = node.services.signInitialTransaction(tx)
|
||||
node.services.recordTransactions(stx)
|
||||
fun issueState(services: ServiceHub, nodeIdentity: Party, notaryIdentity: Party): StateAndRef<DummyContract.SingleOwnerState> {
|
||||
val tx = DummyContract.generateInitial(Random().nextInt(), notaryIdentity, nodeIdentity.ref(0))
|
||||
val stx = services.signInitialTransaction(tx)
|
||||
services.recordTransactions(stx)
|
||||
return stx.tx.outRef(0)
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,13 @@ package net.corda.node.services.events
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.context.Origin
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.flows.FinalityFlow
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.FlowLogicRefFactory
|
||||
import net.corda.core.flows.SchedulableFlow
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.context.Origin
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.node.services.queryBy
|
||||
import net.corda.core.node.services.vault.DEFAULT_PAGE_NUM
|
||||
@ -20,11 +20,10 @@ import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.node.internal.StartedNode
|
||||
import net.corda.node.services.statemachine.StateMachineManager
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.contracts.DummyContract
|
||||
import net.corda.testing.dummyCommand
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.startFlow
|
||||
import net.corda.testing.node.MockNodeParameters
|
||||
import org.junit.After
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Before
|
||||
@ -39,9 +38,11 @@ class ScheduledFlowTests {
|
||||
}
|
||||
|
||||
private lateinit var mockNet: MockNetwork
|
||||
private lateinit var nodeA: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var nodeB: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var bobNode: StartedNode<MockNetwork.MockNode>
|
||||
private lateinit var notary: Party
|
||||
private lateinit var alice: Party
|
||||
private lateinit var bob: Party
|
||||
|
||||
data class ScheduledState(val creationTime: Instant,
|
||||
val source: Party,
|
||||
@ -97,9 +98,11 @@ class ScheduledFlowTests {
|
||||
@Before
|
||||
fun setup() {
|
||||
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.testing.contracts"))
|
||||
nodeA = mockNet.createNode()
|
||||
nodeB = mockNet.createNode()
|
||||
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
|
||||
bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
|
||||
notary = mockNet.defaultNotaryIdentity
|
||||
alice = aliceNode.info.singleIdentity()
|
||||
bob = bobNode.info.singleIdentity()
|
||||
}
|
||||
|
||||
@After
|
||||
@ -110,20 +113,20 @@ class ScheduledFlowTests {
|
||||
@Test
|
||||
fun `create and run scheduled flow then wait for result`() {
|
||||
var countScheduledFlows = 0
|
||||
nodeA.smm.track().updates.subscribe {
|
||||
aliceNode.smm.track().updates.subscribe {
|
||||
if (it is StateMachineManager.Change.Add) {
|
||||
val context = it.logic.stateMachine.context
|
||||
if (context.origin is Origin.Scheduled)
|
||||
countScheduledFlows++
|
||||
}
|
||||
}
|
||||
nodeA.services.startFlow(InsertInitialStateFlow(nodeB.info.chooseIdentity(), notary))
|
||||
aliceNode.services.startFlow(InsertInitialStateFlow(bob, notary))
|
||||
mockNet.waitQuiescent()
|
||||
val stateFromA = nodeA.database.transaction {
|
||||
nodeA.services.vaultService.queryBy<ScheduledState>().states.single()
|
||||
val stateFromA = aliceNode.database.transaction {
|
||||
aliceNode.services.vaultService.queryBy<ScheduledState>().states.single()
|
||||
}
|
||||
val stateFromB = nodeB.database.transaction {
|
||||
nodeB.services.vaultService.queryBy<ScheduledState>().states.single()
|
||||
val stateFromB = bobNode.database.transaction {
|
||||
bobNode.services.vaultService.queryBy<ScheduledState>().states.single()
|
||||
}
|
||||
assertEquals(1, countScheduledFlows)
|
||||
assertEquals("Must be same copy on both nodes", stateFromA, stateFromB)
|
||||
@ -135,8 +138,8 @@ class ScheduledFlowTests {
|
||||
val N = 100
|
||||
val futures = mutableListOf<CordaFuture<*>>()
|
||||
for (i in 0 until N) {
|
||||
futures.add(nodeA.services.startFlow(InsertInitialStateFlow(nodeB.info.chooseIdentity(), notary)).resultFuture)
|
||||
futures.add(nodeB.services.startFlow(InsertInitialStateFlow(nodeA.info.chooseIdentity(), notary)).resultFuture)
|
||||
futures.add(aliceNode.services.startFlow(InsertInitialStateFlow(bob, notary)).resultFuture)
|
||||
futures.add(bobNode.services.startFlow(InsertInitialStateFlow(alice, notary)).resultFuture)
|
||||
}
|
||||
mockNet.waitQuiescent()
|
||||
|
||||
@ -144,11 +147,11 @@ class ScheduledFlowTests {
|
||||
futures.forEach { it.getOrThrow() }
|
||||
|
||||
// Convert the states into maps to make error reporting easier
|
||||
val statesFromA: List<StateAndRef<ScheduledState>> = nodeA.database.transaction {
|
||||
queryStatesWithPaging(nodeA.services.vaultService)
|
||||
val statesFromA: List<StateAndRef<ScheduledState>> = aliceNode.database.transaction {
|
||||
queryStatesWithPaging(aliceNode.services.vaultService)
|
||||
}
|
||||
val statesFromB: List<StateAndRef<ScheduledState>> = nodeB.database.transaction {
|
||||
queryStatesWithPaging(nodeB.services.vaultService)
|
||||
val statesFromB: List<StateAndRef<ScheduledState>> = bobNode.database.transaction {
|
||||
queryStatesWithPaging(bobNode.services.vaultService)
|
||||
}
|
||||
assertEquals("Expect all states to be present", 2 * N, statesFromA.count())
|
||||
statesFromA.forEach { ref ->
|
||||
|
@ -1,11 +1,12 @@
|
||||
package net.corda.node.services.network
|
||||
|
||||
import net.corda.core.node.services.NetworkMapCache
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.testing.BOB
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.testing.ALICE_NAME
|
||||
import net.corda.testing.BOB_NAME
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNodeParameters
|
||||
import net.corda.testing.singleIdentity
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Test
|
||||
@ -23,26 +24,29 @@ class NetworkMapCacheTest {
|
||||
@Test
|
||||
fun `key collision`() {
|
||||
val entropy = BigInteger.valueOf(24012017L)
|
||||
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE.name, entropyRoot = entropy))
|
||||
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME, entropyRoot = entropy))
|
||||
val alice = aliceNode.info.singleIdentity()
|
||||
|
||||
// Node A currently knows only about itself, so this returns node A
|
||||
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(aliceNode.info.chooseIdentity().owningKey).singleOrNull(), aliceNode.info)
|
||||
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB.name, entropyRoot = entropy))
|
||||
assertEquals(aliceNode.info.chooseIdentity(), bobNode.info.chooseIdentity())
|
||||
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(alice.owningKey).singleOrNull(), aliceNode.info)
|
||||
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME, entropyRoot = entropy))
|
||||
val bob = bobNode.info.singleIdentity()
|
||||
assertEquals(alice, bob)
|
||||
|
||||
aliceNode.services.networkMapCache.addNode(bobNode.info)
|
||||
// The details of node B write over those for node A
|
||||
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(aliceNode.info.chooseIdentity().owningKey).singleOrNull(), bobNode.info)
|
||||
assertEquals(aliceNode.services.networkMapCache.getNodesByLegalIdentityKey(alice.owningKey).singleOrNull(), bobNode.info)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getNodeByLegalIdentity`() {
|
||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||
val alice = aliceNode.info.singleIdentity()
|
||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||
val bobCache: NetworkMapCache = bobNode.services.networkMapCache
|
||||
val expected = aliceNode.info
|
||||
|
||||
val actual = bobNode.database.transaction { bobCache.getNodeByLegalIdentity(aliceNode.info.chooseIdentity()) }
|
||||
val actual = bobNode.database.transaction { bobCache.getNodeByLegalIdentity(alice) }
|
||||
assertEquals(expected, actual)
|
||||
|
||||
// TODO: Should have a test case with anonymous lookup
|
||||
@ -50,27 +54,27 @@ class NetworkMapCacheTest {
|
||||
|
||||
@Test
|
||||
fun `getPeerByLegalName`() {
|
||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||
val bobCache: NetworkMapCache = bobNode.services.networkMapCache
|
||||
val expected = aliceNode.info.legalIdentities.single()
|
||||
val expected = aliceNode.info.singleIdentity()
|
||||
|
||||
val actual = bobNode.database.transaction { bobCache.getPeerByLegalName(ALICE.name) }
|
||||
val actual = bobNode.database.transaction { bobCache.getPeerByLegalName(ALICE_NAME) }
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `remove node from cache`() {
|
||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
val bobNode = mockNet.createPartyNode(BOB.name)
|
||||
val bobLegalIdentity = bobNode.info.chooseIdentity()
|
||||
val alice = aliceNode.info.chooseIdentity()
|
||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||
val bobNode = mockNet.createPartyNode(BOB_NAME)
|
||||
val bob = bobNode.info.singleIdentity()
|
||||
val alice = aliceNode.info.singleIdentity()
|
||||
val bobCache = bobNode.services.networkMapCache
|
||||
bobNode.database.transaction {
|
||||
assertThat(bobCache.getNodeByLegalIdentity(alice) != null)
|
||||
bobCache.removeNode(aliceNode.info)
|
||||
assertThat(bobCache.getNodeByLegalIdentity(alice) == null)
|
||||
assertThat(bobCache.getNodeByLegalIdentity(bobLegalIdentity) != null)
|
||||
assertThat(bobCache.getNodeByLegalIdentity(bob) != null)
|
||||
assertThat(bobCache.getNodeByLegalName(alice.name) == null)
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import net.corda.core.crypto.*
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.internal.packageName
|
||||
import net.corda.core.node.StatesToRecord
|
||||
import net.corda.core.node.services.StatesNotAvailableException
|
||||
@ -59,11 +60,12 @@ class NodeVaultServiceTest {
|
||||
@Rule
|
||||
@JvmField
|
||||
val testSerialization = SerializationEnvironmentRule()
|
||||
lateinit var services: MockServices
|
||||
private lateinit var services: MockServices
|
||||
private lateinit var identity: PartyAndCertificate
|
||||
private lateinit var issuerServices: MockServices
|
||||
private lateinit var bocServices: MockServices
|
||||
val vaultService get() = services.vaultService as NodeVaultService
|
||||
lateinit var database: CordaPersistence
|
||||
private val vaultService get() = services.vaultService as NodeVaultService
|
||||
private lateinit var database: CordaPersistence
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
@ -71,6 +73,8 @@ class NodeVaultServiceTest {
|
||||
val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(cordappPackages = cordappPackages)
|
||||
database = databaseAndServices.first
|
||||
services = databaseAndServices.second
|
||||
// This is safe because MockServices only ever have a single identity
|
||||
identity = services.myInfo.singleIdentityAndCert()
|
||||
issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY)
|
||||
bocServices = MockServices(cordappPackages, BOC_NAME, BOC_KEY)
|
||||
services.identityService.verifyAndRegisterIdentity(DUMMY_CASH_ISSUER_IDENTITY)
|
||||
@ -456,7 +460,7 @@ class NodeVaultServiceTest {
|
||||
fun addNoteToTransaction() {
|
||||
val megaCorpServices = MockServices(cordappPackages, MEGA_CORP.name, MEGA_CORP_KEY)
|
||||
database.transaction {
|
||||
val freshKey = services.myInfo.chooseIdentity().owningKey
|
||||
val freshKey = identity.owningKey
|
||||
|
||||
// Issue a txn to Send us some Money
|
||||
val usefulBuilder = TransactionBuilder(null).apply {
|
||||
@ -488,11 +492,11 @@ class NodeVaultServiceTest {
|
||||
fun `is ownable state relevant`() {
|
||||
val service = vaultService
|
||||
val amount = Amount(1000, Issued(BOC.ref(1), GBP))
|
||||
val wellKnownCash = Cash.State(amount, services.myInfo.chooseIdentity())
|
||||
val wellKnownCash = Cash.State(amount, identity.party)
|
||||
val myKeys = services.keyManagementService.filterMyKeys(listOf(wellKnownCash.owner.owningKey))
|
||||
assertTrue { service.isRelevant(wellKnownCash, myKeys.toSet()) }
|
||||
|
||||
val anonymousIdentity = services.keyManagementService.freshKeyAndCert(services.myInfo.chooseIdentityAndCert(), false)
|
||||
val anonymousIdentity = services.keyManagementService.freshKeyAndCert(identity, false)
|
||||
val anonymousCash = Cash.State(amount, anonymousIdentity.party)
|
||||
val anonymousKeys = services.keyManagementService.filterMyKeys(listOf(anonymousCash.owner.owningKey))
|
||||
assertTrue { service.isRelevant(anonymousCash, anonymousKeys.toSet()) }
|
||||
@ -508,6 +512,7 @@ class NodeVaultServiceTest {
|
||||
@Test
|
||||
fun `correct updates are generated for general transactions`() {
|
||||
val service = vaultService
|
||||
val notary = identity.party
|
||||
val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply {
|
||||
service.updates.subscribe(this)
|
||||
}
|
||||
@ -518,30 +523,30 @@ class NodeVaultServiceTest {
|
||||
val amount = Amount(1000, Issued(BOC.ref(1), GBP))
|
||||
|
||||
// Issue then move some cash
|
||||
val builder = TransactionBuilder(identity.party).apply {
|
||||
val issueBuilder = TransactionBuilder(notary).apply {
|
||||
Cash().generateIssue(this, amount, anonymousIdentity.party.anonymise(), identity.party)
|
||||
}
|
||||
val issueTx = builder.toWireTransaction(bocServices)
|
||||
val issueTx = issueBuilder.toWireTransaction(bocServices)
|
||||
val cashState = StateAndRef(issueTx.outputs.single(), StateRef(issueTx.id, 0))
|
||||
|
||||
// ensure transaction contract state is persisted in DBStorage
|
||||
val signedIssuedTx = services.signInitialTransaction(builder)
|
||||
val signedIssuedTx = services.signInitialTransaction(issueBuilder)
|
||||
services.validatedTransactions.addTransaction(signedIssuedTx)
|
||||
|
||||
database.transaction { service.notify(StatesToRecord.ONLY_RELEVANT, issueTx) }
|
||||
val expectedIssueUpdate = Vault.Update(emptySet(), setOf(cashState), null)
|
||||
|
||||
database.transaction {
|
||||
val builder = TransactionBuilder(services.myInfo.chooseIdentity()).apply {
|
||||
val moveBuilder = TransactionBuilder(notary).apply {
|
||||
Cash.generateSpend(services, this, Amount(1000, GBP), thirdPartyIdentity)
|
||||
}
|
||||
val moveTx = builder.toWireTransaction(services)
|
||||
val moveTx = moveBuilder.toWireTransaction(services)
|
||||
service.notify(StatesToRecord.ONLY_RELEVANT, moveTx)
|
||||
}
|
||||
val expectedMoveUpdate = Vault.Update(setOf(cashState), emptySet(), null)
|
||||
|
||||
// ensure transaction contract state is persisted in DBStorage
|
||||
val signedMoveTx = services.signInitialTransaction(builder)
|
||||
val signedMoveTx = services.signInitialTransaction(issueBuilder)
|
||||
services.validatedTransactions.addTransaction(signedMoveTx)
|
||||
|
||||
val observedUpdates = vaultSubscriber.onNextEvents
|
||||
@ -551,7 +556,7 @@ class NodeVaultServiceTest {
|
||||
@Test
|
||||
fun `correct updates are generated when changing notaries`() {
|
||||
val service = vaultService
|
||||
val notary = services.myInfo.chooseIdentity()
|
||||
val notary = identity.party
|
||||
|
||||
val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply {
|
||||
service.updates.subscribe(this)
|
||||
|
@ -6,6 +6,7 @@ import net.corda.core.contracts.LinearState
|
||||
import net.corda.core.contracts.UniqueIdentifier
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.concurrent.fork
|
||||
import net.corda.core.internal.concurrent.transpose
|
||||
import net.corda.core.internal.packageName
|
||||
@ -53,7 +54,8 @@ class VaultWithCashTest {
|
||||
lateinit var issuerServices: MockServices
|
||||
val vaultService: VaultService get() = services.vaultService
|
||||
lateinit var database: CordaPersistence
|
||||
lateinit var notaryServices: MockServices
|
||||
private lateinit var notaryServices: MockServices
|
||||
private lateinit var notary: Party
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
@ -63,6 +65,7 @@ class VaultWithCashTest {
|
||||
services = databaseAndServices.second
|
||||
issuerServices = MockServices(cordappPackages, DUMMY_CASH_ISSUER_NAME, DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY)
|
||||
notaryServices = MockServices(cordappPackages, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
|
||||
notary = notaryServices.myInfo.legalIdentitiesAndCerts.single().party
|
||||
}
|
||||
|
||||
@After
|
||||
@ -237,10 +240,10 @@ class VaultWithCashTest {
|
||||
val linearId = UniqueIdentifier()
|
||||
|
||||
// Issue a linear state
|
||||
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
val dummyIssueBuilder = TransactionBuilder(notary = notary).apply {
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
|
||||
addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
|
||||
addCommand(dummyCommand(notary!!.owningKey))
|
||||
}
|
||||
val dummyIssue = notaryServices.signInitialTransaction(dummyIssueBuilder)
|
||||
|
||||
@ -261,7 +264,7 @@ class VaultWithCashTest {
|
||||
// Issue a linear state
|
||||
val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
|
||||
.addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
|
||||
.addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
|
||||
.addCommand(dummyCommand(notary.owningKey))
|
||||
val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder)
|
||||
val dummyIssue = services.addSignature(dummyIssuePtx)
|
||||
|
||||
@ -277,7 +280,7 @@ class VaultWithCashTest {
|
||||
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY)
|
||||
.addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
|
||||
.addInputState(dummyIssue.tx.outRef<LinearState>(0))
|
||||
.addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
|
||||
.addCommand(dummyCommand(notary.owningKey))
|
||||
|
||||
val dummyMove = notaryServices.signInitialTransaction(dummyMoveBuilder)
|
||||
|
||||
@ -348,12 +351,12 @@ class VaultWithCashTest {
|
||||
linearStates.forEach { println(it.state.data.linearId) }
|
||||
|
||||
// Create a txn consuming different contract types
|
||||
val dummyMoveBuilder = TransactionBuilder(notary = DUMMY_NOTARY).apply {
|
||||
val dummyMoveBuilder = TransactionBuilder(notary = notary).apply {
|
||||
addOutputState(DummyLinearContract.State(participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID)
|
||||
addOutputState(DummyDealContract.State(ref = "999", participants = listOf(freshIdentity)), DUMMY_DEAL_PROGRAM_ID)
|
||||
addInputState(linearStates.first())
|
||||
addInputState(deals.first())
|
||||
addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey))
|
||||
addCommand(dummyCommand(notary!!.owningKey))
|
||||
}
|
||||
|
||||
val dummyMove = notaryServices.signInitialTransaction(dummyMoveBuilder)
|
||||
|
@ -19,6 +19,7 @@ import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNodeParameters
|
||||
import net.corda.testing.node.MockServices
|
||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
|
||||
@ -51,13 +52,15 @@ class NodeInterestRatesTest {
|
||||
private val DUMMY_CASH_ISSUER_KEY = generateKeyPair()
|
||||
private val DUMMY_CASH_ISSUER = Party(CordaX500Name(organisation = "Cash issuer", locality = "London", country = "GB"), DUMMY_CASH_ISSUER_KEY.public)
|
||||
private val services = MockServices(listOf("net.corda.finance.contracts.asset"), DUMMY_CASH_ISSUER.name, DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY)
|
||||
// This is safe because MockServices only ever have a single identity
|
||||
private val identity = services.myInfo.singleIdentity()
|
||||
|
||||
private lateinit var oracle: NodeInterestRates.Oracle
|
||||
private lateinit var database: CordaPersistence
|
||||
|
||||
private fun fixCmdFilter(elem: Any): Boolean {
|
||||
return when (elem) {
|
||||
is Command<*> -> services.myInfo.chooseIdentity().owningKey in elem.signers && elem.value is Fix
|
||||
is Command<*> -> identity.owningKey in elem.signers && elem.value is Fix
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@ -152,7 +155,7 @@ class NodeInterestRatesTest {
|
||||
database.transaction {
|
||||
val tx = makePartialTX()
|
||||
val fix = oracle.query(listOf(NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M"))).first()
|
||||
tx.addCommand(fix, services.myInfo.chooseIdentity().owningKey)
|
||||
tx.addCommand(fix, identity.owningKey)
|
||||
// Sign successfully.
|
||||
val wtx = tx.toWireTransaction(services)
|
||||
val ftx = wtx.buildFilteredTransaction(Predicate { fixCmdFilter(it) })
|
||||
@ -167,7 +170,7 @@ class NodeInterestRatesTest {
|
||||
val tx = makePartialTX()
|
||||
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
|
||||
val badFix = Fix(fixOf, BigDecimal("0.6789"))
|
||||
tx.addCommand(badFix, services.myInfo.chooseIdentity().owningKey)
|
||||
tx.addCommand(badFix, identity.owningKey)
|
||||
val wtx = tx.toWireTransaction(services)
|
||||
val ftx = wtx.buildFilteredTransaction(Predicate { fixCmdFilter(it) })
|
||||
val e1 = assertFailsWith<NodeInterestRates.UnknownFix> { oracle.sign(ftx) }
|
||||
@ -182,12 +185,12 @@ class NodeInterestRatesTest {
|
||||
val fix = oracle.query(listOf(NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M"))).first()
|
||||
fun filtering(elem: Any): Boolean {
|
||||
return when (elem) {
|
||||
is Command<*> -> services.myInfo.chooseIdentity().owningKey in elem.signers && elem.value is Fix
|
||||
is Command<*> -> identity.owningKey in elem.signers && elem.value is Fix
|
||||
is TransactionState<ContractState> -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
tx.addCommand(fix, services.myInfo.chooseIdentity().owningKey)
|
||||
tx.addCommand(fix, identity.owningKey)
|
||||
val wtx = tx.toWireTransaction(services)
|
||||
val ftx = wtx.buildFilteredTransaction(Predicate(::filtering))
|
||||
assertFailsWith<IllegalArgumentException> { oracle.sign(ftx) }
|
||||
@ -205,17 +208,18 @@ class NodeInterestRatesTest {
|
||||
@Test
|
||||
fun `network tearoff`() = withoutTestSerialization {
|
||||
val mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts", "net.corda.irs"))
|
||||
val aliceNode = mockNet.createPartyNode(ALICE.name)
|
||||
val oracleNode = mockNet.createNode().apply {
|
||||
val aliceNode = mockNet.createPartyNode(ALICE_NAME)
|
||||
val oracleNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME)).apply {
|
||||
internals.registerInitiatedFlow(NodeInterestRates.FixQueryHandler::class.java)
|
||||
internals.registerInitiatedFlow(NodeInterestRates.FixSignHandler::class.java)
|
||||
database.transaction {
|
||||
services.cordaService(NodeInterestRates.Oracle::class.java).knownFixes = TEST_DATA
|
||||
}
|
||||
}
|
||||
val oracle = oracleNode.services.myInfo.singleIdentity()
|
||||
val tx = makePartialTX()
|
||||
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
|
||||
val flow = FilteredRatesFlow(tx, oracleNode.info.chooseIdentity(), fixOf, BigDecimal("0.675"), BigDecimal("0.1"))
|
||||
val flow = FilteredRatesFlow(tx, oracle, fixOf, BigDecimal("0.675"), BigDecimal("0.1"))
|
||||
LogHelper.setLevel("rates")
|
||||
mockNet.runNetwork()
|
||||
val future = aliceNode.services.startFlow(flow).resultFuture
|
||||
|
@ -8,6 +8,7 @@ import net.corda.core.crypto.entropyToKeyPair
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.internal.createDirectories
|
||||
import net.corda.core.internal.createDirectory
|
||||
import net.corda.core.internal.uncheckedCast
|
||||
@ -163,6 +164,14 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
|
||||
return defaultNotaryNode.info.legalIdentities[1] // TODO Resolve once network parameters is merged back in
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the identity of the default notary node.
|
||||
* @see defaultNotaryNode
|
||||
*/
|
||||
val defaultNotaryIdentityAndCert: PartyAndCertificate get() {
|
||||
return defaultNotaryNode.info.legalIdentitiesAndCerts.singleOrNull() ?: throw IllegalStateException("Default notary has multiple identities")
|
||||
}
|
||||
|
||||
/**
|
||||
* Because this executor is shared, we need to be careful about nodes shutting it down.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user