Facebook Libra focus on Admission Control (Part 2: SubmitTransaction)
หลังจากถูกการงานการบ้านรุมเร้าเลยพักการเรียนรู้ไปหลายวัน วันนี้เรามาเรียนรู้เรื่อง Admission Control ในส่วนที่เกี่ยวข้องกับ SubmitTransaction กรณี Account Mint และ Transfer กันนะครับ โดยเราจะต้องรัน libra_swarm ด้วยคำสั่ง
$ RUST_LOG=debug cargo run -p libra_swarm -- -s
Source code ของ function submit_transaction_inner ค่อนข้างยาวจะขอสรุปเงื่อนไขการทำงานดังนี้
- check ว่า mempool เต็มหรือยัง ถ้ายังก็ไปต่อ
- ทำการแปลง signed_txn จาก library proto เพื่อสามารถ get gas_cost มาคำนวนได้
- vm_validator ทำการ validate_transaction โดย AC จะใช้ validator set information ไปหา state_root ของ transaction info เพื่อ verify signatures ของ validator set, จากนั้นจึงสร้าง VerifiedStateView ด้วย verified state
4. add transaction นั้นเข้าสู่ mempool
ในการศึกษาการทำงานนั้นผมสนใจที่ function validate_transaction (ขั้นตอนที่ 3) เพราะว่าในส่วนการ check mempool เป็นการตรวจเช็ค flag และในส่วนการแปลง signed_txn เราก็ได้ดูไปบ้างแล้วในขั้นตอนอื่นๆในบทความก่อนหน้านี้ครับ เพราะฉะนั้นเราจะกระโดดเข้าไปดูรายละเอียกใน function validate_transaction กันเลยนะครับ
ก่อนอื่นใน function validate_transaction มี TODO กล่าวเกี่ยวกับเงื่อนไขที่ validator ควรจะมี 2 options คือ
- trust storage: ไม่ไปหา root hash, สร้างโครงสร้างคล้ายการทำ verified state view โดยไม่ต้อง verification
- non-trust storage: AC จะใช้ validator set information ไปหา state_root ของ transaction info เพื่อ verify signatures ของ validator set, จากนั้นจึงสร้าง VerifiedStateView ด้วย verified state
ว่าแต่ ผมมีข้อสงสัยว่าใช้เงื่อนไขอะไรตัดสินใจว่าเป็น trust storage กันนะ ? น่าเสียดายที่ทีมงาน libra ยังไม่ได้ implement ส่วนงานนี้ (ทุก case เป็น non-trust storage) ผมได้ส่งคำถามไปที่ libra community หวังว่าทีมงาน libra จะมาตอบเร็วๆนี้ครับ
ซึ่ง function validate_transaction เรียก update_to_latest_ledger โดยส่ง RequestItem GetAccountState เข้าไป ซึ่งเราได้เรียนรู้ไปแล้วใน Facebook Libra focus on Admission Control Part 1 ว่าเราจะได้ 3 ค่า กลับมา คือ response_items (account_state_with_proof), ledger_info_with_sigs, validator_change_events
จากนั้นจึงนำ account_state_with_proof สืบกลับ (derived) ไปหา transaction_info และ transaction_state_root แล้วจึงสร้าง SparseMerkleTree (single root hash ใน memory) ขึ้นมาจาก state_root ที่ได้ เมื่อดูรูปโครงสร้างข้อมูลใน storage ของ libra จะเห็นภาพมากขึ้น
Libra จะใช้ SparseMerkleTree สำหรับ 2 กรณีนะครับ
- ใช้สนับสนุนการทำ ledger based consensus algorithm
- ใช้เป็นกระดาษทดจาก global MerkleTree เพื่อให้สามารถคำนวน แล้วจัดการกับ uncommitted transaction ได้ครับ
กลับมาที่ function validate_transaction กันต่อ ในขั้นตอนการสร้าง SparseMerkleTree ที่ตอนนี้มีแค่ state root นะครับ จึงต้องเรียกใช้งาน storage_read_client เข้าไป query ข้อมูล เพื่อให้ได้ SparseMerkleTree จากข้อมูลล่าสุดเรียกใช้ constructure ของ VerifiedStateView
ทดสอบ debug validation_status ของ function validate_transaction ใน function submit_transaction_inner
บทความอื่นๆเกี่ยวกับการทำความเข้าใจ 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 mempool
Facebook Libra focus on consensus (Part 1)