У меня есть приложение Corda, которое использует M14 для создания и запуска корды для запуска TwoPartyProtocol, где обе стороны могут обмениваться данными для достижения консенсуса в отношении действительности данных. Я следил за кулинарной книгой Корды, чтобы построить поток.
Кроме того, после прочтения документов с нескольких разных вех кордов я понял, что M14 больше не нуждается в flowSessions, как упоминалось в примечаниях к выпуску, что также устраняет необходимость регистрации сервисов.
My TwoPartyFlow с внутренней FlowLogics:
class TwoPartyFlow{ @InitiatingFlow @StartableByRPC open class Requestor(val price: Long, val otherParty: Party) : FlowLogic<SignedTransaction>(){ @Suspendable override fun call(): SignedTransaction { val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity send(otherParty, price) /*Some code to generate SignedTransaction*/ } } @InitiatedBy(Requestor::class) open class Responder(val requestingParty : Party) : FlowLogic<SignedTransaction>(){ @Suspendable override fun call(): SignedTransaction { val request = receive<Long>(requestor).unwrap { price -> price } println(request) /*Some code to generate SignedTransaction*/ } } }
Но, работая выше, используя startTrackedFlow от Api, вызывается ошибка выше:
Party CN=Other,O=Other,L=NY,C=US rejected session request: com.testapp.flow.TwoPartyFlow$Requestor has not been registered
Мне было трудно найти причину из кордовых документов или журналов, поскольку реализации двух партийных потоков изменились между несколькими вехами корды. Может кто-нибудь помочь мне понять проблему здесь.
Мой API-адрес:
@GET @Path("start-flow") fun requestOffering(@QueryParam(value = "price") price: String) : Response{ val price : Long = 10L /*Code to get otherParty details*/ val otherPartyHostAndPort = HostAndPort.fromString("localhost:10031") val client = CordaRPCClient(otherPartyHostAndPort) val services : CordaRPCOps = client.start("user1","test").proxy val otherParty: Party = services.nodeIdentity().legalIdentity val (status, message) = try { val flowHandle = services.startTrackedFlow(::Requestor, price, otherParty) val result = flowHandle.use { it.returnValue.getOrThrow() } // Return the response. Response.Status.CREATED to "Transaction id ${result.id} committed to ledger.\n" } catch (e: Exception) { Response.Status.BAD_REQUEST to e.message } return Response.status(status).entity(message).build() }
Задача myRradle deployNodes:
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['build']) { directory "./build/nodes" networkMap "CN=Controller,O=R3,OU=corda,L=London,C=UK" node { name "CN=Controller,O=R3,OU=corda,L=London,C=UK" advertisedServices = ["corda.notary.validating"] p2pPort 10021 rpcPort 10022 cordapps = [] } node { name "CN=Subject,O=Subject,L=NY,C=US" advertisedServices = [] p2pPort 10027 rpcPort 10028 webPort 10029 cordapps = [] rpcUsers = [[ user: "user1", "password": "test", "permissions": []]] } node { name "CN=Other,O=Other,L=NY,C=US" advertisedServices = [] p2pPort 10030 rpcPort 10031 webPort 10032 cordapps = [] rpcUsers = [[ user: "user1", "password": "test", "permissions": []]] }
Кажется, есть пара проблем с кодом, который вы опубликовали:
@StartableByRPC
, а не @StartableNByRPC
startTrackedFlow
должна быть длинной, а не int Однако даже после устранения этих проблем я не смог воспроизвести вашу ошибку. Можете ли вы применить эти исправления, выполнить чистое повторное развертывание своих узлов ( gradlew clean deployNodes
) и посмотреть, изменяется ли ошибка?
Вы не должны подключаться к другому узлу через RPC. RPC – это то, как владелец узла говорит со своим узлом. В реальном мире у вас не было бы учетных данных RPC другого узла и не удалось бы войти в узел таким образом.
Вместо этого вы должны использовать клиент RPC своего собственного узла для получения идентификатора контрагента:
val otherParty = services.partyFromX500Name("CN=Other,O=Other,L=NY,C=US")!!
См. Пример M14: https://github.com/corda/cordapp-example/blob/release-M14/kotlin-source/src/main/kotlin/com/example/api/ExampleApi.kt .