公证服务信息_使用多个公证员提高网络吞吐量
公證服務信息
您是否需要高吞吐量的Corda網絡? 網絡的吞吐量是否穩定? 您是否已經從其他領域擠出了所有可能的表現? 如果您對這些問題的回答是“是”,那么我可能會為您提供一些有用的信息。 我列出了這些問題,以減少您過早優化Corda網絡/應用程序的機會。 如果它是處理請求/事務中最慢的部分之一,則切換到使用多個公證人只會對性能產生顯著影響。 在考慮使用多個公證人之前,很可能需要改進其他方面。
在我繼續之前。 我真的需要這么說。 在本文中,我并不是在談論使用公證集群,該公證集群由相互溝通以就是否使用過國家達成共識的公證人組成。 我說的是有多個公證人,每個公證人都有自己的身份,這些公證人僅與向其發送交易以進行驗證的節點進行交互。 這種區別必須加以區分,并且應該消除對我將在本文中準確描述的任何混淆。
在撰寫本文時,Corda的當前版本為:
- 開源3.3
- 企業3.2
我為什么要這樣做?
好吧 讓我們真正深入探討為什么要使用多個公證人。 圖表最能做到這一點,所以讓我們使用一個:
具有一個公證人的網絡的簡單視圖
這種情況看起來不太好。 但是,實際上可能并不那么糟糕。 如果網絡的吞吐量不是很高,則此體系結構應該能夠處理通過公證人的事務。
如引言中所述。 當發送到公證人的交易率變得很高時,這成為一個問題。 一旦達到這一點,公證人將開始落后。 因為它不能足夠快地驗證事務中的狀態。 如果性能對網絡很重要,那么這是檢查的好地方。
從代碼角度來看,這是您可能已經在編寫CorDapps的標準格式。 您可以根據特定條件選擇公證人,然后在其中發送交易。 您所處理的整個網絡中甚至可能只有一個公證人。 例如,在編寫類似于以下代碼的代碼之前,在我編寫的所有代碼示例中,它們僅依賴于網絡中的單個公證人,每次都盲目地使用那個。
private fun notary(): Party = serviceHub.networkMapCache.notaryIdentities.first()切換到多個公證人
從依賴一個公證人的網絡過渡到一個由許多公證人組成的設計,從根本上講,需要兩件事:
- 網絡中有多個公證人。
- 一種選擇向哪個公證人發送交易的算法。
此外,如果使用狀態,則將來的交易會參考為交易選擇的公證人。 如果最終遇到消耗了來自不同公證人的輸入狀態的情況,則必須執行公證人變更事務。 稍后我將討論這個主題。
下面是如何將先前的設計更改為使用一些公證人的方法:
具有多個公證人的網絡的簡化視圖
關于此圖的最好之處在于,它說明了向網絡添加另一個公證人并在其中重新分配負載是多么簡單。 沒有什么可以阻止我們向網絡中添加越來越多的公證人。 但是,在某些情況下添加更多內容不會導致性能提高。 這一直回到我之前提到的內容。 添加更多的公證人只會在公證人本身達到飽和時增加吞吐量。
為發行交易選擇公證人
以下是選擇使用哪種公證人的可能算法:
private fun transaction(): TransactionBuilder =TransactionBuilder(notary()).apply {addOutputState(message, MessageContract.CONTRACT_ID)addCommand(Send(), message.participants.map(Party::owningKey))}private fun notary(): Party {val index = message.type.hashCode() % serviceHub.networkMapCache.notaryIdentities.sizereturn serviceHub.networkMapCache.notaryIdentities.single { it.name.organisation == "Notary-$index" } }在此示例中,事務根據輸入狀態的屬性之一的hashCode和網絡中的公證人數來選擇要使用的公證人。
選擇公證人的方式可以根據需要簡單或復雜。 這將取決于要求,例如對于提議的交易僅信任一部分公證人,或者對網絡變化中的公證人具有彈性。
從同一公證人消費狀態時選擇公證人
這是很好而且很簡單的…如果所有輸入狀態都引用同一個公證人。 下面是它的外觀(此示例僅使用一個輸入…,因為我懶于編寫另一個版本):
private fun transaction(response: MessageState): TransactionBuilder =TransactionBuilder(notary()).apply {addInputState(message)addOutputState(response, MessageContract.CONTRACT_ID)addCommand(Reply(), response.participants.map(Party::owningKey))}private fun notary(): Party = message.state.notary如您所見,所有事務要做的就是檢索與輸入狀態相關的公證人并將其用于自身。 可以提取此信息,因為message是StateAndRef ,訪問其state屬性將返回TransactionState 。 遵循這種格式。 創建消耗狀態并產生大量輸出的新事務非常簡單。 此格式對于多個輸入狀態也有效。 當且僅當它們都引用同一個公證人。
因此……討論所有帶有不同公證人的輸入狀態。 我可能應該進一步討論。
消費來自不同公證人的狀態時選擇公證人
在這里我們必須要小心,否則我們將看到類似以下錯誤:
java.lang.IllegalArgumentException: Input state requires notary "O=Notary-1, L=London, C=GB" which does not match the transaction notary "O=Notary-0, L=London, C=GB".該錯誤表明輸入狀態與包含它的事務沒有相同的公證人。
要解決此錯誤,我們需要使用公證更改交易。 根據文檔:
“用于更改州公證人的流程。 這是必需的,因為事務的所有輸入狀態必須指向同一公證人。”
我想把它放在那里,以防萬一你以為我是個騙子!
執行公證變更交易的代碼如下所示:
@Suspendable private fun notaryChange(message: StateAndRef<MessageState>,notary: Party ): StateAndRef<MessageState> =if (message.state.notary != notary) {subFlow(NotaryChangeFlow(message,notary))} else {message}我相信您可以弄清楚自己的狀況,但是要使自己變得更加聰明……我將告訴您。 message表示輸入狀態, notary是新交易將使用的公證人。 如果公證人相同,則可以返回狀態,因為無需對其進行任何操作。 如果它們確實不同,則調用NotaryChangeFlow ,它接受傳遞給原始函數的兩個參數。 這將返回一個新的StateAndRef ,然后從函數中返回它。
然后可以將從此函數返回的StateAndRef放入事務中。
如果您不確定傳遞到事務中的狀態是否來自同一公證人,那么建議您堅持使用本節中的代碼。 選擇事務將使用的公證人(無論是特定的還是從輸入狀態中獲取的公證人),然后對任何需要進行公證的事務執行公證變更事務。 例如,我認為類似于下面的代碼將提供一個通用且健壯的解決方案:
@Suspendable private fun transaction(): TransactionBuilder {val messages = getMessageStates()val notary = notary()return TransactionBuilder(notary).apply {messages.forEach {addInputState(notaryChange(it, notary))}addCommand(Delete(),(messages.flatMap { it.state.data.participants }.toSet() + ourIdentity).map(Party::owningKey))} }@Suspendable private fun notaryChange(message: StateAndRef<MessageState>,notary: Party ): StateAndRef<MessageState> =if (message.state.notary != notary) {subFlow(NotaryChangeFlow(message,notary))} else {message}// however you want to choose your specific Notary private fun notary(): Party =serviceHub.networkMapCache.notaryIdentities.single { it.name.organisation == "Notary-1" }在這里,為交易選擇了一個特定的公證人,如果需要,每個輸入的公證人都將更改為所選公證人,并且簽名者包括消費狀態的所有參與者。 這可能不適合您自己的用例。 很好。 但是,這在為不斷變化的公證人服務時(主要是為了提高性能)應該是一個很好的起點。
稍稍更改此解決方案,我們可以改為根據輸入狀態參考的“公證人”來選擇“公證人”。 由于只有notary功能確實需要更改,因此我從示例中排除了其余代碼。
private fun notary(messages: List<StateAndRef<MessageState>>): Party =messages.map { it.state.notary }.groupingBy { it }.eachCount().maxBy { (_, size) -> size }?.key ?: throw IllegalStateException("No Notary found")此功能選擇的公證人是根據輸入狀態共享的最常見的公證人來決定的。 這樣一來,所需的公證變更交易就更少了,因為大多數輸入已經引用了所選公證。 如果您不知道輸入引用的是哪個公證人,這應該提供最佳性能。
結論
在Corda網絡中實現高性能取決于消除系統中的瓶頸和其他常規性能調整。 公證人就是這樣一個瓶頸。 在非常高的吞吐量通過公證人的情況下,網絡的性能將開始達到平穩狀態。 公證人不能以傳入的速率足夠快地處理請求。移動使用共享請求負載的多個公證人將提高網絡的性能。 這在確定使用哪個公證人時帶來了額外的復雜性,并可能需要公證人變更事務。 但是,如果您的網絡確實需要實現高吞吐量。 這將是一個值得研究的領域。
我將在這里發表最后的評論。 隨著公證人內部性能的提高,對這種體系結構的需求將減少。 甚至可能達到這樣一個程度,即一個公證人能夠完全處理大量傳入請求。 隨著Corda不斷提高其整體性能,這是一個值得關注的領域。
這篇文章中使用的代碼可以在我的GitHub上找到 。
翻譯自: https://www.javacodegeeks.com/2018/11/increasing-network-multiple-notaries.html
公證服務信息
總結
以上是生活随笔為你收集整理的公证服务信息_使用多个公证员提高网络吞吐量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓软件商店下载(下载安卓应用市场)
- 下一篇: 编写脚本电脑怎么编写界面_在任何无法理解