Facebook Libra focus on Consensus (Part 1)

Apisak Srihamat
3 min readAug 3, 2019

--

วันนี้มาเรียนรู้เรื่อง consensus กันนะครับ จากความเดิมตอนที่แล้วเรื่อง Facebook Libra focus on Mempool ภายหลังจากใน mempool มีข้อมูล transaction ที่จัดเรียง priority เอาไว้รอที่จะให้นำไปกระทำการยืนยันต่อครับ หากสนใจทำความเข้าใจกันเล็กน้อยเกี่ยวกับทฤษฎีให้อ้างอิง Life of a transaction, State Machine Replication in the Libra Blockchain, FBFT และ Hotstuff นะครับ เราสายลุยไม่คุยให้เสียเวลามาเปิด code libra ดูกันเลยครับ

จาก code libra นั้น consensus’s README อธิบายไว้ว่า consensus components ถูกพัฒนาเป็น Actor model มี message คุยกันระหว่าง sub-components ด้วย tokio framwork ซึ่ง actor model (ที่ถูกเข้าถึงโดยหลายๆ sub-components ณ เวลาใดๆ) คือ consensus data structure “BlockStore” ซึ่งคอยจัดการ blocks, execution, quorum certificates และ shared data structure อื่นๆ

Consensus มี components หลักๆดังนี้

  1. Transaction Manager เป็น interface ไปที่ mempool และทำการ pulling transactions และ removing transactions ที่ committed ไปแล้ว ซึ่ง proposer ใช้การ pull transactions ที่ต้องการจาก mempool เพื่อจะสร้าง proposal block.
  2. State Computer เป็น interface สำหรับการ execution สามารถ execute blocks, commit blocks และ sync
  3. BlockStore มีหน้าที่เก็บ tree ของ proposal blocks, block execution, votes, quorum certificates, และ persistent storage. นอกจากนี้ยังเก็บรวบรวมโครงสร้างข้อมูลให้ถูกต้องและเข้าถึงได้จากส่วนงานอื่นๆ
  4. EventProcessor มีหน้าที่ประมวลผลแต่ละ events (เช่น process_new_round, process_proposal, process_vote) โดยจะทำการประมาลผลแบบ async สำหรับแต่ละ event type และ drive protocol.
  5. Pacemaker มีหน้าที่ทำ liveness consensus protocol โดยจะเปลี่ยนรอบการทำงานทุกๆ timeout certificates หรือ quorum certificates และ proposes blocks เมื่อมี proposer สำหรับรอบนั้นๆ
  6. SafetyRules มีหน้าที่ดูแลความปลอดภัยของ consensus protocol. ซึ่งจะประมวลผล quorum certificates และ ledgerinfo เพื่อที่จะเรียนรู้เกี่ยวกับ new commits และ guarantees ว่ามีมากกว่า 2 voting rules แล้ว รวมถึงกรณีที่เกิดการ restart (ตั้งแต่ safety data ยังอยู่ใน local storage)

เอาล่ะ มาตอบคำถามง่ายๆกันว่า TransactionManager มันเริ่มรันได้ยังไง เนื่องจากเป็นการเริ่มทำงานที่แตกต่างจากส่วนอื่นๆที่เราเคยศึกษาที่มี client เป็นผู้เริ่มเรียกใช้งาน โดยการ revert engineering ไล่ย้อนจาก TransactionManager มีอยู่ 2 functions :)

  1. function pull_txns: จะถูกเรียกโดย object ProposalGenerator ใน function generate_proposal
  2. function commit_txns: จะถูกเรียกโดย object EventProcessor ใน function process_commit

เริ่มที่ pull_txns ก่อนนะครับ function generate_proposal ซึ่งถูกเรียกต่อมาจาก process_new_round_event อีกทีนึง โดยมันจะถูก trigger เพียงครั้งเดียวในแต่ละรอบ (round) โดย new quorum certificate หรือ timeout certificate จากรอบก่อนหน้า ซึ่งลักษณะการทำงานเป็น task (TaskExecutor ของเจ้า tokio) จะ spawn process_new_round_events ที่มี while loop วนทำงานวนเป็นรอบอยู่ตลอดเวลา ซึ่งจริงๆแล้ว function start ของ StateMachineReplication จะไล่ start_event_processing (spawn) processes ดังนี้

  1. process_new_round_events (เรากำลังสนใจ process นี้แต่เดี๋ยวคงจะเชื่อมกันหมด ^^”)
  2. process_proposals
  3. process_wining_proposals
  4. process_block_retrievals
  5. process_chunk_retrievals
  6. process_vote
  7. process_timeout_msg
  8. process_outgoing_pacemaker_timeouts
  9. process_sync_info_msgs
ใน function start_event_processing เจ้า tokio (executor) ทำการ spawn process_new_round_events ขึ้นมาครับ โดยมี new_round_events_receiver เป็น channel คอยรับข้อมูล events ใหม่เสมอ
async function process_new_round_events ของ object ChainedBftSMR ที่ถูก spawn ด้วย tokio, ซึ่ง receiver.next().await นี่ล่ะที่จะเป็นผู้รับ event
async function process_new_round_event ของ object EventProcessor จริงๆ function มันยาวมากนะครับ อธิบายคร่าวๆคือ ไม่ว่ามันจะได้รับ triggered จาก new quorum certificate หรือ timeout certificate จากรอบก่อนหน้า ถ้า replica นั้นๆเป็น new proposal สำหรับรอบนี้ ก็พร้อมที่จะ propose และ guarantee ว่าสามารถ create proposal ให้ all honest replicas สามารถ vote ได้

อย่างไรก็ตามใน async function process_new_round_event ผมเห็นว่า libra developer มี debug! Propose มาดูจึงไม่รอช้าทดสอบเปิดดู log ตาม จำได้จากบทความก่อนหน้านี้ว่า consensus มันมีความพยายามที่จะส่ง event(s) กันตลอดเวลาแม้เราจะไม่ได้ส่ง command account mint หรือ transaction ใดๆ ผมตัดรูปมาในส่วนที่มันจะมีการ repeat sequence การทำงานประมาณนี้อยู่ตลอดเวลา (Highlight สีเหลืองคือแต่ละ process ที่ spawn ออกมาที่มีการ debug)

ผลลัพธ์ของการอ่าน debug log จะเห็นการขั้นตอนการทำงานชัดเจนว่า เกิดขั้นตอนดังนี้ Process_New_Round_Event -> Process_Proposal -> Process_Commit -> Process_Winning_Proposal อย่าลืมว่ามีบาง process ยังไม่ได้มีการ print debug เพราะฉะนั้นอาจจะถูกเรียกแต่เราไม่เห็นตรงนี้ และ round id ที่แต่ละ process จัดการก็เป็นคนละ id กัน ทำให้เข้าใจได้ว่า แต่ละ process มีระยะเวลาการทำงานไม่พร้อมกันและมี queue ของ events (channel) เป็นของตัวเอง

ใครเป็นคนส่ง certificate event มาให้ในแต่ละ round ? ในขั้นตอนนี้ผมใช้วิธีค้นหาจากผู้ใช้งาน sender และ NewRoundEvent จึงพบว่า function create_new_round_task ของ object LocalPacemakerInner เป็นผู้สร้าง NewRoundEvent มาโดย NewRoundReason จะถูก pass parameter เข้ามาจาก caller

function create_new_round_task ของ object LocalPacemakerInner

แล้วใครเรียกใช้งาน create_new_round_task บ้างล่ะ ?

  1. function update_current_round ของ object LocalPacemakerInner (QCReady หรือ timeout) => ถูกเรียกมาจาก function process_certificates, process_remote_timeout ของ object Pacemaker
  2. Constructure ของ LocalPacemaker (QCReady) => ถูกเรียกจาก function create_pacemaker ของ object ChainedBftSMR ซึ่งจะถูกเรียก (ครั้งเดียวตอนเริ่มทำงาน) ใน function start ของ object StateMachineReplication

มาถึงตรงนี้จะเห็นว่า Pacemaker นั้นเองที่เป็นผู้สร้าง event ในแต่ละรอบ จะว่าไปเราได้อธิบายแล้วว่า Pacemaker เป็น component ที่มีหน้าที่ “liveness” consensus protocol ในตอนต้นนะครับ :)

“Pacemaker มีหน้าที่ทำ liveness consensus protocol โดยจะเปลี่ยนรอบการทำงานทุกๆ timeout certificates หรือ quorum certificates และ proposes blocks เมื่อมี proposer สำหรับรอบนั้นๆ”

โดยสรุปแล้ว ตอนนี้เราเริ่มเข้าใจวิธีการทำงานของ “background process” หรือในอีกชื่อนึงคือ “EventProcessor” และบางส่วนของ component “Pacemaker” แล้วว่ามีการทำงานร่วมกันอย่างไร มีอีกหลายเรื่องที่น่าสนใจ เช่น รายละเอียดการทำงานของ TransactionManager, การ proposes blocks เมื่อมี proposer, State computer และ Safty Rules เป็นต้น ยังไงคงต้องติดเอาไว้ก่อนนะครับ หวังว่าจะมีโอกาสและเวลาได้ศึกษา libra’s consensus ต่อไป

สรุปภาพรวมของ Libra’s consensus จากความเข้าใจวันนี้

บทความอื่นๆเกี่ยวกับการทำความเข้าใจ source code libra มีดังนี้ครับ

Facebook Libra on Windows is easy

Facebook Libra focus on account create

Facebook Libra focus on account mint

Facebook Libra focus on query balance

Facebook Libra focus on admission control (Part 1)

Facebook Libra focus on admission control (Part 2)

Facebook Libra focus on mempool

--

--

Apisak Srihamat

Master of Science AIT, Embedded systems course UC Irvine, Bachelor of Computer Engineering KMITL, Love innovation ideas.