Ripple是一個國際性支付系統,允許用戶像發送電子郵件一樣無縫地進行跨國界轉移資金(包括法定貨幣、數字貨幣和其他形式的價值)。如同比特幣等其他數字貨幣,ripple協議通過去中心化的計算機網絡允許進行P2P交易結算。然而,與其他數字貨幣協議不同,ripple協議的貨幣是不可知的,不要求用戶使用協議中的原生貨幣(XRP)。此外,技術能夠實現幾乎實時結算(3-6秒),而且將把每個國際交易發送給網絡中可得的最便宜的買賣差價。
機制
在核心處,ripple有記錄用來交易資產的賬戶、余額和要約信息的“總賬(Ledger)”。類似創建賬戶、進行支付、轉變資產等操作通過被稱為“交易”的簽署指令來進行。
因為ripple是一個用密碼寫的系統,賬戶可通過加密身份進行鑒定。交易被與加密身份相匹配的加密簽名檢驗。根據確定的、已知的規則,每個服務器處理每個交易。
雙重支付問題
根本無效的交易可以被所有參與者識別出來,例如從一個只有10美元的賬戶中發送20美元。然而,也有可能創建兩個交易,其中只有一個有效。這種情況被稱為雙重支付問題。
假設Alice在某個支付系統中有10美元。假定是一個有用的支付系統,如果她想的話,就必須能向Bob發送10美元。而且同樣,也可以發送給Charlie。然而,如果她向Bob和Charlie發送了相同的10美元,那么支付系統停止使用。因此以某種方法,向Bob發送10美元的行為必須阻止她向Charlie發送相同的10美元。
按照慣例,這是由中央機構解決的。例如,銀行會清除基于發行者可利用余額的支票,其中銀行是這些余額的唯一托管人。然而,像ripple一樣的分布式系統,明顯沒有中央機關。他們必須通過其他方式解決雙重支付問題。
簡化(雙重支付)問題
大部分雙重支付問題可以通過眾所周知的方法來解決,比如阻止一個賬戶支付它沒有的資金。實際上,雙重支付問題可以簡化為給交易排序。
再來看Alice試圖給Bob和Charlie發送相同10美元的例子。如果支付給Bob的行為被認為是第一位,那每個人都會同意她有資金支付Bob。而且如果支付給Charlie的行為被認為是第二位,那每個人都會同意她不能把那些資金給Charilie,因為現在是屬于Bob的。
我們也可以按照確定性的規則給交易排序。由于交易是數字信息的集合,所以它們能輕易被排序。
沒有中央機關的情況下,這對解決雙重支付問題來說足夠了,但它要求我們在確定交易結果之前掌握所有將要發生的交易,以便于我們進行排序。顯然,這是不實際的。
然而,如果我們能把交易分成群組而且就那些群組達成一致,那么我們就可以在那個群組中對交易進行排序。也就是說,只要每個參與者都同意把這些交易按照一個單位來處理,那么他們就能使用確定性的規則來解決雙重支付問題,不需要任何中央機構。參與者只各自對交易進行排序,并按照已知的規則以確定性的方法應用到交易上。
Ripple不依賴于兩個互相沖突的交易中的任何一個。根據確定性規則,交易群組是已生效的,而且一個群組里有兩個相沖突的交易沒有傷害。根據排序規定,第一位的交易會成功,第二位的交易會失敗。
一致共識的基本角色是讓過程中的參與者就交易可以被處理為一個單元來解決雙重支付問題的事宜達成一致。有四個理由說明這個協議比預期更容易達成。
1. 如果實在沒有理由讓一個交易不被納入此交易群組,那所有可靠的參與者都會同意收納它。如果所有參與者都已經同意,那一致共識就不用做任何事情了。
2. 如果有該交易不應被納入交易群組的任何理由,所有可靠的參與者會傾向于排斥它。如果交易仍然有效,那就沒有理由在第二輪不包含它,而且那時他們都應該同意包含它。
3. 有極少數的參與者會特別關心交易分組的方式。當所有人的重點是達成一致時,實現一致最為簡單。只有當他們分發利益時,實現一致才面臨挑戰。確定性原則甚至可以被用來構建組群,只有在邊界條件時才會導致不一致。例如,如果在一輪中有兩個相沖突的交易,確定性原則可以被用來決定誰進入下一輪。
4. 每個參與者最優先的事情是正確性。也就是說,不能違反那些人們所依賴的用來維護網絡完整性的準則。例如,一定不能處理一個沒有被正確簽署的交易。然而,每個可靠參與者的第二優先事情是一致性。一個具有雙重支付可能性的網絡根本沒有效用。每個可靠參與者最重視的是正確性,這個事實推進一致性進程。
如何實現一致共識
達成一致性開始于每個想要這樣做的參與者作出最初的決定。這是他們目睹的有效交易集合。
然后參與者大量投入到達成一致性的過程中:如果一個特定交易沒有得到多數支持,那參與者將同意推遲那個交易。如果一個特定交易擁有多數支持,參與者將同意包含這個交易。因此,輕微的多數快速成為全部支持,而且輕微的少數快速成為現有這一輪的普遍拒絕者。
為了防止一致性過程停留在50%附近,而且為了減少可靠的收斂性造成的重疊,要求包含某個交易的閾值越來越高。首先,如果超過50%的參與者同意,那參與者將持續同意包含這個交易。然后這個數字會上升至60%,而且會持續增加,直至有爭議性的交易被推遲至下一輪。
如果參與者發現絕對多數同意接下來處理某個交易集合,那就會宣布達成一致共識。
一致共識可能會失敗
開發一種永遠都能達成完美共識的一致性算法是不實際的。理解為什么會這樣的途徑之一是考慮一致共識過程是如何終止的。在某種程度上,每個參與者必須宣布已經達成一致性,而且某些交易集合已被認為是這個過程的結果。該聲明不能撤回地將參與者引入某些作為一致性過程結果的特定交易集合。
很明顯,有些參與者必須第一個做這件事或者永遠不會有參與者做,一致性永遠不能達成。目前,假設參與者首先已經這樣做了。當參與者決定一致性達成的時候,其他參與者還沒有做出這個決定。如果從他們角度而言,沒能改變這個已被同意的集合,那么他們就會作出一致性達成的決定。所以他們必須有能力改變被同意的集合。
換句話說,對于終止的一致共識進程,某個參與者必須宣布交易集合已達成一致,盡管其他每個參與者理論上仍能改變同意交易集合的決定。
這種失敗的可能性非常低,但不能縮減為零。技術性交易(engineering tradeoff)促使這種可能性降至千分之一以下,使得一致共識進程明顯放緩,并使一致共識更難容忍網絡和端點錯誤。
Ripple如何處理一致共識錯誤的
在一輪一致共識進程結束后,每個參與者申請他們認為被贊同的交易集合。這促使構建他們所認為的總賬應有的下一個狀態。
然后,同樣也是驗證者的參與者發布下一個總賬的加密指紋(cryptographic fingerprint),這被稱為“驗證”。如果達成一致,那絕大多數的驗證者應發布相同的指紋。
之后,參與者收集這些驗證。從驗證中,他們可以判斷出先前的一致共識是否會導致絕大多數參與者同意這個交易集合。
參與者將面臨以下三種情況之一,按可能性大小排序。
1. 他們建立了絕對多數同意的相同總賬。這種情況下,他們可以認為總賬被充分驗證,而且可以信賴總賬的內容。
2. 他們建立了不同于絕對多數同意的總賬。這種情況下,他們必須建立和接受絕對多數同意的總賬。這是一個典型的例子,他們很早宣布達成一致,之后其他參與者進行了修改。他們必須“跳轉”至絕對多數總賬,從而實現繼續運轉。
3. 收到的驗證中沒有出現明顯的絕對多數。這種情況下,先前的一致共識就被廢棄了,而且在任何一個總賬被驗證前,必須發起新一輪一致性協商。
當然,情況1是最常見的。無論如何,情況2是不會損害網絡的。小部分參與者會每一輪都出現情況2,而且網絡會順利運行。
情況3導致網絡停止幾秒來推動進程向前,但這極其少見。這種情況下,后來的一致共識更不容易失敗,因為一致共識進程化解了不一致,而且只有存在不一致會導致失敗。
在很少的情況中,整個網絡會幾秒鐘不能取得進展。作為交換,交易確認的平均次數會比較少。
理念
系統在某些組件失敗或某些參與者具有惡意的情況下提供結果的能力是可靠性的一種表現形式。盡管這很重要,但在加密支付系統中還有另一種更為重要的可靠性形式,即系統產生可信賴結果的能力。也就是說,當系統報告結果可靠時,我們應信賴那個結果。
然而,現實世界系統面臨以上兩種可靠性都讓步的運行狀況。這包括硬件故障、通信故障,甚至不可靠的參與者。Ripple部分設計理念就是為了發現并報告結果可靠性被削弱的情況,而不是提供一定不可靠的結果。
Ripple一致性算法為工作系統證明提供了另一種方法,而不是不必要地消耗計算資源。拜占庭錯誤是有可能的,而且確實發生過,但結果只是少數延遲。在所有情況中,ripple一致性算法只有在結果真正可靠時才會進行報告。
圖解
這是關于一致性共識算法的大致圖解。
一致性共識的目的是讓所有服務器都同意一組交易并生效到最后關閉總賬(Last Closed Ledger)上。他們不關心交易是否有效或者交易發生的順序。他們只關心所有服務器都贊同這組數據是什么。
一致共識是個持續迭代的過程。服務器發出一組交易的提案,然后其他從對端接收到(提案)的服務器也發出自己的提案。
這里我們有某一臺在Ripple網絡中的服務器的抽象化圖解。
在中間顯示了關閉包(Closing Bundle)。這是一組交易,網絡正在嘗試達成一致。
現在我們看到,(左上角)一個提案來到了這臺服務器。在一致共識達成期間,每個服務器都發出一系列的提案。提案就是 該服務器認為應該把他包含到關閉包里的交易列表。
(該服務器會對)這傳入的提案針對UNL進行檢查。如果發送提案的服務器在UNL列表上,那么這個提案被發送到關閉包,并且里面的所有交易都獲得1票。
而在網絡試圖達成在最后一個交易集合的共識(的過程中),新的交易進入。這些交易被收集在下一包。它們將被施加到下一個總帳(Ledger)。
在這里,我們看到了一個提案,來源服務器不是我們的UNL。這個提案被簡單地丟棄,而不用判斷什么要包含到最后關閉包里。
part2
現在,我們已經得到了來自其他服務器的一些提案。目前我們有5個活躍的UNL服務器。那些被超過50%的活躍服務器投過票的交易,都被認為應該(被服務器)打包。你可以看到標記為綠色的這些交易。
現在,計時器已經用完了,所以我們把我們的針對當前包的投票發送到網絡。一個交易是否該放到當前包里,這個(得票率)閾值也從50%提高到60%。這樣有很多不同意見的交易,將有一種傾向–被推到下一個總帳。
我們已經收到更多的提案(上圖是Server5的新提案到達),改變了我們的想法:關閉包應該包括(哪些交易)。(上圖可見“=”這個交易也到達了3/5的投票率)
一致共識機制認為:達到UNL的80% 服務器同意的那些交易,應該放入這個總賬。你可以看到在這里發生了,因為每個交易有4個或更多的得票或小于2票。這些交易將被發送并被施加到上次關閉總帳(Last Closed Ledger)。 (譯注:這里有個bug?圖標為“=”的交易,只有3票,也被發送到LCL了)
關閉包開始著手生成新的LCL。你在那個關閉過程中收集到的新交易,將被添加到之前的沒能到放總帳的交易候選集里。現在達成一致共識的過程重新開始……
譯者補充
這個文章只說了proposal過程。實際過程比這個復雜,一致性會包括兩步,Proposal和Validation;Ledger狀態會有三個,ClosingLedger,LCL,AcceptedL。
1. Proposal階段會發出自己的closing ledger,大家不斷根據收到的proposal建立交集,剩下的建disputed TXs進行投票,投票通過的會繼續保留在closing ledger,得票率要求隨時間提高
2. 投票不通過的留在下一個ledger處理
3. 然后就是靠那個復雜的ContinuousLedgerTiming::haveConsensus算法判定何時可以將closing ledger轉成LCL并發出validation
4. 然后validation超過quorum個則將LCL轉為accepted ledger繼續往前走,
5. 之后走的過程中一旦發現validation最多的LCL和自己的不一樣,則會轉入分支切換流程從網絡獲取新的LCL。
評論
查看更多