Существует несколько подходов, позволяющих предотвратить запуск определенных потоков узлами:
Вы можете установить только CorDapp, определяющий специфичные для страховщика потоки на узлах страховщика, а не на банковских узлах
- Вы можете даже пойти так далеко, что только сделаете доступным JAR-файл CorDapp, содержащий потоки страховщика, к узлам страховщика
Как говорит Kid101, вы можете ограничить разрешения узлов RPC, чтобы только пользователи RPC узлов страховщика могли запускать рассматриваемый поток. Например:
rpcUsers=[
{
username=exampleUser
password=examplePass
permissions=[
"StartFlow.net.corda.flows.ExampleFlow1",
"StartFlow.net.corda.flows.ExampleFlow2"
]
}
...
]
Эти два подхода основаны на доверии между узлами. Ничто не мешает одному из банковских узлов получить CorDapp, содержащий потоки страховщика, и предоставить себе разрешения RPC для его запуска.
Если узлы не доверяют (что вы должны предполагать, что они находятся в мире DLT), вы должны использовать один из следующих подходов:
Вы можете выполнить проверку в потоке респондента. Например, если у вас есть пара потоков IssueInsurancePolicyFlow
/ IssueInsurancePolicyFlowResponder
, вы можете добавить проверку в IssueInsurancePolicyFlowResponder
, чтобы убедиться, что инициатор IssueInsurancePolicyFlow
является узлом страховщика.
В псевдокоде:
if (counterpartySession.counterparty !in insurerNodeList) {
throw IllegalStateException("Flow must be run by an insurer node.")
}
Здесь вам решать, как получить список действительных узлов страховщика. Например, его можно прочитать из базы данных узла респондента.
Обратите внимание, что этот подход работает только в том случае, если требуется подписывающее лицо, отличное от инициатора (кроме нотариуса). В противном случае невозможно заставить нечестный банковский узел отправить сообщение честному контрагенту для вызова потока ответчика (и, следовательно, включенного чека).
Обратите внимание, что эту проверку следует поместить в поток ответчика, поскольку инициатор не может изменить код, выполняемый на стороне ответчика. Если чек помещен в поток инициатора, узел банка может создать свой собственный инициирующий поток и оставить этот чек
Вы можете выполнить проверку в рамках самого договора. Например:
override fun verify(tx: LedgerTransaction) {
...
val dealStateOutput = tx.outputsOfType<DealState>().single()
if (dealStateOutput.insurer !in approvedInsurers)
throw IllegalArgumentException("Unapproved insurer.")
...
}
Сложность такого подхода заключается в получении списка утвержденных страховщиков в договоре. Вы можете жестко закодировать его, но со временем оно может измениться, что заставит вас обновить контракт. Одной из альтернатив может быть включение команды, подписанной оракулом, указывающей, что данный страховщик утвержден, и проверка соответствия этого страховщика страховщику в состоянии вывода.