mirror of
https://github.com/corda/corda.git
synced 2025-01-18 02:39:51 +00:00
add simple network verification cordapp (#3412)
* add simple network verification cordapp * add ability to filter checked counterparties to specific x500
This commit is contained in:
parent
f103bdc98a
commit
f19564f9f8
49
samples/network-verifier/build.gradle
Normal file
49
samples/network-verifier/build.gradle
Normal file
@ -0,0 +1,49 @@
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'net.corda.plugins.cordapp'
|
||||
apply plugin: 'net.corda.plugins.cordformation'
|
||||
|
||||
dependencies {
|
||||
cordaCompile project(":core")
|
||||
cordaCompile project(":node-api")
|
||||
cordaCompile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
|
||||
testCompile project(":test-utils")
|
||||
testCompile "junit:junit:$junit_version"
|
||||
}
|
||||
|
||||
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
|
||||
ext.rpcUsers = [['username': "default", 'password': "default", 'permissions': [ 'ALL' ]]]
|
||||
|
||||
directory "./build/nodes"
|
||||
node {
|
||||
name "O=Notary Service,L=Zurich,C=CH"
|
||||
notary = [validating : false]
|
||||
p2pPort 10002
|
||||
rpcSettings {
|
||||
port 10003
|
||||
adminPort 10004
|
||||
}
|
||||
h2Port 20004
|
||||
}
|
||||
node {
|
||||
name "O=Bank A,L=London,C=GB"
|
||||
p2pPort 10005
|
||||
cordapps = []
|
||||
rpcUsers = ext.rpcUsers
|
||||
rpcSettings {
|
||||
port 10007
|
||||
adminPort 10008
|
||||
}
|
||||
}
|
||||
node {
|
||||
name "O=Bank B,L=New York,C=US"
|
||||
p2pPort 10009
|
||||
cordapps = []
|
||||
rpcUsers = ext.rpcUsers
|
||||
rpcSettings {
|
||||
port 10011
|
||||
adminPort 10012
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package net.corda.verification
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.contracts.CommandData
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.flows.*
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.core.utilities.unwrap
|
||||
|
||||
|
||||
@StartableByRPC
|
||||
@InitiatingFlow
|
||||
class TestCommsFlowInitiator(val x500Name: CordaX500Name? = null) : FlowLogic<List<String>>() {
|
||||
|
||||
object SENDING : ProgressTracker.Step("SENDING")
|
||||
object RECIEVED_ALL : ProgressTracker.Step("RECIEVED_ALL")
|
||||
object FINALIZING : ProgressTracker.Step("FINALIZING")
|
||||
|
||||
override val progressTracker: ProgressTracker = ProgressTracker(SENDING, RECIEVED_ALL, FINALIZING)
|
||||
|
||||
@Suspendable
|
||||
override fun call(): List<String> {
|
||||
progressTracker.currentStep = SENDING
|
||||
val responses = serviceHub.networkMapCache.allNodes.map {
|
||||
it.legalIdentities.first()
|
||||
}.filterNot {
|
||||
it in serviceHub.myInfo.legalIdentities
|
||||
}.filterNot {
|
||||
it in serviceHub.networkMapCache.notaryIdentities
|
||||
}.filter(::matchesX500)
|
||||
.map {
|
||||
val initiateFlow = initiateFlow(it)
|
||||
initiateFlow.receive<String>().unwrap { it }
|
||||
}.toList().also {
|
||||
progressTracker.currentStep = RECIEVED_ALL
|
||||
}
|
||||
val tx = TransactionBuilder(notary = serviceHub.networkMapCache.notaryIdentities.first())
|
||||
tx.addOutputState(CommsTestState(responses, serviceHub.myInfo.legalIdentities.first()), CommsTestContract::class.qualifiedName!!)
|
||||
tx.addCommand(CommsTestCommand, serviceHub.myInfo.legalIdentities.first().owningKey)
|
||||
val signedTx = serviceHub.signInitialTransaction(tx)
|
||||
subFlow(FinalityFlow(signedTx))
|
||||
return responses
|
||||
}
|
||||
|
||||
fun matchesX500(it: Party): Boolean {
|
||||
return x500Name?.equals(it.name) ?: true
|
||||
}
|
||||
}
|
||||
|
||||
@InitiatedBy(TestCommsFlowInitiator::class)
|
||||
class TestCommsFlowResponder(val otherSideSession: FlowSession) : FlowLogic<Unit>() {
|
||||
@Suspendable
|
||||
override fun call() {
|
||||
otherSideSession.send("Hello from: " + serviceHub.myInfo.legalIdentities.first().name.toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@CordaSerializable
|
||||
data class CommsTestState(val responses: List<String>, val issuer: AbstractParty) : ContractState {
|
||||
override val participants: List<AbstractParty>
|
||||
get() = listOf(issuer)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@CordaSerializable
|
||||
object CommsTestCommand : CommandData
|
||||
|
||||
|
||||
class CommsTestContract : Contract {
|
||||
override fun verify(tx: LedgerTransaction) {
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package net.corda.verification
|
||||
|
||||
import net.corda.core.contracts.CommandData
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.flows.FinalityFlow
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
|
||||
|
||||
@StartableByRPC
|
||||
class TestNotaryFlow : FlowLogic<String>() {
|
||||
|
||||
object ISSUING : ProgressTracker.Step("ISSUING")
|
||||
object ISSUED : ProgressTracker.Step("ISSUED")
|
||||
object DESTROYING : ProgressTracker.Step("DESTROYING")
|
||||
object FINALIZED : ProgressTracker.Step("FINALIZED")
|
||||
|
||||
override val progressTracker: ProgressTracker = ProgressTracker(ISSUING, ISSUED, DESTROYING, FINALIZED)
|
||||
|
||||
|
||||
override fun call(): String {
|
||||
val issueBuilder = TransactionBuilder()
|
||||
val notary = serviceHub.networkMapCache.notaryIdentities.first()
|
||||
issueBuilder.notary = notary;
|
||||
val myIdentity = serviceHub.myInfo.legalIdentities.first()
|
||||
issueBuilder.addOutputState(NotaryTestState(notary.name.toString(), myIdentity), NotaryTestContract::class.qualifiedName!!)
|
||||
issueBuilder.addCommand(NotaryTestCommand, myIdentity.owningKey)
|
||||
val signedTx = serviceHub.signInitialTransaction(issueBuilder)
|
||||
val issueResult = subFlow(FinalityFlow(signedTx))
|
||||
progressTracker.currentStep = ISSUED
|
||||
val destroyBuilder = TransactionBuilder()
|
||||
destroyBuilder.notary = notary;
|
||||
destroyBuilder.addInputState(issueResult.tx.outRefsOfType<NotaryTestState>().first())
|
||||
destroyBuilder.addCommand(NotaryTestCommand, myIdentity.owningKey)
|
||||
val signedDestroyT = serviceHub.signInitialTransaction(destroyBuilder)
|
||||
val result = subFlow(FinalityFlow(signedDestroyT))
|
||||
progressTracker.currentStep = DESTROYING
|
||||
progressTracker.currentStep = FINALIZED
|
||||
return "notarised: " + result.notary.toString() + "::" + result.tx.id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@CordaSerializable
|
||||
data class NotaryTestState(val id: String, val issuer: AbstractParty) : ContractState {
|
||||
override val participants: List<AbstractParty>
|
||||
get() = listOf(issuer)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@CordaSerializable
|
||||
object NotaryTestCommand : CommandData
|
||||
|
||||
|
||||
class NotaryTestContract : Contract {
|
||||
override fun verify(tx: LedgerTransaction) {
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package net.corda.configsample
|
||||
|
||||
import net.corda.testing.core.ALICE_NAME
|
||||
import net.corda.testing.core.DUMMY_BANK_A_NAME
|
||||
import net.corda.testing.core.DUMMY_NOTARY_NAME
|
||||
import net.corda.testing.core.TestIdentity
|
||||
import net.corda.verification.TestCommsFlowInitiator
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class TestCommsFlowInitiatorTest {
|
||||
|
||||
val ALICE = TestIdentity(ALICE_NAME, 70)
|
||||
val NOTARY = TestIdentity(DUMMY_NOTARY_NAME, 12)
|
||||
val DUMMY_BANK_A = TestIdentity(DUMMY_BANK_A_NAME, 3)
|
||||
|
||||
@Test
|
||||
fun `should allow all node infos through if no x500 is passed`() {
|
||||
val testCommsFlowInitiator = TestCommsFlowInitiator()
|
||||
|
||||
Assert.assertTrue(testCommsFlowInitiator.matchesX500(ALICE.party))
|
||||
Assert.assertTrue(testCommsFlowInitiator.matchesX500(NOTARY.party))
|
||||
Assert.assertTrue(testCommsFlowInitiator.matchesX500(DUMMY_BANK_A.party))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should allow only specified x500 if no x500 is passed`() {
|
||||
val testCommsFlowInitiator = TestCommsFlowInitiator(ALICE_NAME)
|
||||
|
||||
Assert.assertTrue(testCommsFlowInitiator.matchesX500(ALICE.party))
|
||||
Assert.assertFalse(testCommsFlowInitiator.matchesX500(NOTARY.party))
|
||||
Assert.assertFalse(testCommsFlowInitiator.matchesX500(DUMMY_BANK_A.party))
|
||||
}
|
||||
}
|
@ -58,5 +58,6 @@ include 'samples:simm-valuation-demo:contracts-states'
|
||||
include 'samples:notary-demo'
|
||||
include 'samples:bank-of-corda-demo'
|
||||
include 'samples:cordapp-configuration'
|
||||
include 'samples:network-verifier'
|
||||
include 'serialization'
|
||||
include 'serialization-deterministic'
|
||||
|
Loading…
Reference in New Issue
Block a user