Все еще новичок в Corda.
Я пытаюсь запустить образец Corda Accounts SupplyChain через MockNetwork, чтобы я мог отлаживать свои потоки. Для этого мне нужно создать учетные записи и запустить поток SendInvoice. Вот мой тест потока
class FlowTests {
private lateinit var network: MockNetwork
private lateinit var buyer: StartedMockNode
private lateinit var seller: StartedMockNode
private lateinit var shippingCo: StartedMockNode
@Before
fun setup() {
network = MockNetwork(MockNetworkParameters( networkParameters = testNetworkParameters(minimumPlatformVersion = 4),
cordappsForAllNodes = listOf(
TestCordapp.findCordapp("com.accounts_SupplyChain.contracts"),
TestCordapp.findCordapp("com.accounts_SupplyChain.flows"),
TestCordapp.findCordapp("com.accounts_SupplyChain.schemas"),
TestCordapp.findCordapp("com.r3.corda.lib.accounts.contracts"),
// This CorDapp has the missing service from your error message.
TestCordapp.findCordapp("com.r3.corda.lib.accounts.workflows"),
TestCordapp.findCordapp("com.r3.corda.lib.ci")
)))
buyer = network.createPartyNode()
seller = network.createPartyNode()
shippingCo = network.createPartyNode()
listOf(buyer,seller,shippingCo).forEach {it.registerInitiatedFlow(SendInvoiceResponder::class.java)}
network.runNetwork()
}
@After
fun tearDown() {
network.stopNodes()
}
@Test
fun Test1() {
// Create Buyer Account
val flow1 = CreateNewAccount("BuyerProcurement")
val future1 = buyer.startFlow(flow1);
// Share the account
val flow3 = ShareAccountTo("BuyerProcurement", shareTo = seller.info.singleIdentity())
val future3 = buyer.startFlow(flow3)
// On Seller Node
val flow7 = CreateNewAccount("SellerSales")
val future7 = seller.startFlow(flow7)
val flow10 = ShareAccountTo("SellerSales", shareTo = buyer.info.singleIdentity())
val future10 = seller.startFlow(flow10)
// Check the accounts are created on the buyer node
val flowView = ViewMyAccounts()
val fut = buyer.startFlow(flowView)
// Check the accounts are creted on the seller Node
val flowView2 = ViewMyAccounts()
val fut2 = seller.startFlow(flowView)
// Now send an Invoice
val sendInvoice = SendInvoice(whoAmI = "SellerSales",whereTo = "BuyerProcurement", amount = 500)
val futureSendInvoice = seller.startFlow(sendInvoice)
network.runNetwork()
val resp1= future1.getOrThrow()
println(resp1.toString())
val resp2 = future7.getOrThrow()
println(resp2.toString())
val buyerAccounts = fut.getOrThrow()
println(buyerAccounts.toString())
val sellerAccounts= fut2.getOrThrow()
println(sellerAccounts.toString())
// Get the invoice Created
val invoiceCreation = futureSendInvoice.getOrThrow()
println(invoiceCreation.toString())
}
}
Не очень элегантно, но это всего лишь тест.
Ответ, который я получаю:
BuyerProcurement team's account was created. UUID is : 60d91f03-4112-4c2a-801b-95fe4297bf3b
SellerSales team's account was created. UUID is : 09a4a089-2a98-4148-a00d-252438d816f1
[BuyerProcurement]
[SellerSales]
, так что я думаю, что учетные записи созданы (возможно, нет !!). Однако при запуске потока:
val flow10 = ShareAccountTo("SellerSales", shareTo = buyer.info.singleIdentity())
val future10 = seller.startFlow(flow10)
я получаю сообщение об ошибке:
java.util.NoSuchElementException: List is empty.
at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:478)
at com.accounts_SupplyChain.flows.SendInvoice.call(SendInvoice.kt:67)
at com.accounts_SupplyChain.flows.SendInvoice.call(SendInvoice.kt:26)
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:270)
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:46)
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63)
Устанавливая точки останова в SendInvoice.kt, я обнаружил, что это вызвано попыткой получить targetAccount ( BuyerProcurement):
@Suspendable
override fun call(): String {
//Generate key for transaction
progressTracker.currentStep = GENERATING_KEYS
val myAccount = accountService.accountInfo(whoAmI).single().state.data
val myKey = subFlow(NewKeyForAccount(myAccount.identifier.id)).owningKey
/// ERROR HERE //////
val targetAccount = accountService.accountInfo(whereTo).single().state.data
val targetAcctAnonymousParty = subFlow(RequestKeyForAccount(targetAccount))
//generating State for transfer
progressTracker.currentStep = GENERATING_TRANSACTION
val output = InvoiceState(amount, AnonymousParty(myKey),targetAcctAnonymousParty,UUID.randomUUID())
val transactionBuilder = TransactionBuilder(serviceHub.networkMapCache.notaryIdentities.first())
transactionBuilder.addOutputState(output)
.addCommand(InvoiceStateContract.Commands.Create(), listOf(targetAcctAnonymousParty.owningKey,myKey))
У кого-нибудь есть идеи. Мне нужно быть в состоянии пройти через мои потоки, чтобы определить, почему они не завершаются.