Facebook Libra focus on query balance
วันนี้เรามาทำความเข้าใจการตรวจสอบเงินใน libra ด้วยคำสั่ง query balance นะครับ
เริ่มจากการสร้าง account ด้วยคำสั่ง account create หลังจากนั้นสร้าง coins ด้วยคำสั่ง account mint ถ้ายังไม่เคย mint แต่เรารู้มาจาก stories เรื่อง Facebook Libra focus on account create แล้วว่าเงินที่สร้างไว้ที่เครื่องใดจะยังคงอยู่กับ account นั้นๆเสมอนะครับ ในกรณีนี้ผมเคย mint เงินไว้ที่ account#0 แล้วเพราะฉะนั้นผมสามารถ create account แล้ว query balance 0 เพื่อตรวจเช็คยอด coins ได้เลย
ว่าแต่ค่า balance ของ account#0 นี้ได้มาได้อย่างไรกันนะ เปิด function QueryCommandGetBalance ที่เขียนด้วยภาษา rust ขึ้นมาพบว่ามีการเรียกใช้งาน get_balance ของ object client ครับ ซึ่งเท่าที่ดู code ค่อนข้างตรงไปตรงมา โดยไปเรียก function get_account_address_from_parameter เพื่อให้ได้ address ของ account ที่กำลังต้องการ query balance หลังจากนั้นจึงเรียก function get_account_resource_and_update เมื่อได้ response กลับมาจึงนำ balance มาแสดงให้ผู้ใช้งานทราบ
มาถึงตรงนี้จะเห็นว่ามันไม่ได้ง่ายๆตรงไปตรงมาอย่างที่คิดไว้ตั้งแต่แรก เพราะว่าจะมีการเรียก function get_account_state_and_update ของ object client ไป get account status จาก validator และ update status ของ account นั้นๆก่อนถ้าหากเป็นการ cached ไว้
ว่าแต่ account มีกี่ status กันนะ ? เมื่อเปิด code ดูก็พบว่ามี 3 AccountStatus
- Local: เป็น account ที่ อยู่ใน local cache เท่านั้นไม่ได้คงอยู่ (persisted) บน chain
- Persisted: เป็น account ที่ persisted บน chain แล้ว
- Unknown: เป็น account ที่ไม่ทราบสถานะ คาดว่าเป็นเพราะ client ไม่สามารถติดต่อสื่อสารกับ validator ได้
เมื่อเข้าใจ status ของ account แล้วก็กลับมาทำความเข้าใจ function get_account_state_and_update ของ object client กันต่อครับ
ผลลัพธ์ของการ print debug ทำให้ผมเข้าใจได้ว่ามีการเก็บข้อมูล Raw data ที่น่าจะนำ bits&bytes มาแปลงเป็นข้อมูลได้ และ … ว้าววววว มันฉลาดพอที่จะสามารถ decode ด้วย Helper methods AccountResource ให้เราสามารถอ่าน structure ข้างในได้เลยอัตโนมัติ
ไปต่อครับ! เมื่อดู code ต่อไปจะเห็นว่ามีการเรียกใช้ function get_account_blob ของ object grpc_client เพื่อรับ account state ล่าสุดจาก validator ผ่าน function get_with_proof_sync ซึ่งก็จะไปเรียก get_with_proof_async นั่นล่ะ แต่ว่ามีการเพิ่มขั้นตอนการ wait (synchronize) และเรียกซํ้าเข้าไป :)
เมื่ออ่านมาถึง function get_with_proof_async ผมสนใจ UpdateToLatestLedgerRequest จึงทำการ print debug ออกมาดูว่า request ที่ส่งไปมีค่าอะไรอยู่ข้างใน ก็พบว่ามี client_known_version และ address ของ account#0
จะเห็นว่ามี comment TODO ที่กล่าวถึงการวางแผนระยะยาวสำหรับ client_known_version เพื่อให้ทำงานกับ validator set change ได้ มี 2 เรื่องที่น่าสนใจในจุดนี้
- การวางแผนระยะยาวในการพัฒนาแสดงให้เห็นถึงประสบการณ์ของทีมพัฒนาของ libra ซึ่งน่าจะมาจาก facebook ที่มองถึงเรื่อง compatibility ที่จะเป็นโจทย์ใหญ่ในการบริหารจัดการระบบในระยะยาว ซึ่งนักพัฒนาหลายๆท่านไม่ได้คิดถึงจุดนี้กันสักเท่าไหร่เพราะส่วนใหญ่ต้องการให้ product ออกสู่ท้องตลาดโดยเร็วที่สุด ซึ่งในความเป็นจริงแล้วมันคงต้อง balance ให้ไม่ช้าเกินไปและไม่ไวเกินไปจนลืมสิ่งที่สำคัญครับ เพราะถ้าช้าเกินไปก็ไม่ทันกินแต่ถ้าไวจนลืมสิ่งสำคัญไปก็ไม่ดี :)
- การออกแบบให้มี client_known_version ทำให้ผมคิดถึง client unknown version ในทางกลับกัน เช่น ถ้าเราสร้าง client กันเองมันจะไม่สนับสนุนใช่ไหม ? (หมายถึงช่วง go live แล้วนะครับไม่ใช่ testnet) หรือสุดท้ายก็จะต้องมีการออกมาตรฐานสำหรับการพัฒนา ? และหรือจะต้องมีวิธีที่จะขออนุญาติเปลี่ยนจาก unknown เป็น known ?
อย่างไรก็ตามใน code function get_with_proof_async ของ grpc_client นั้นมีการเรียกใช้ UpdateToLatestLedger ซึ่งจุดนี้เป็นการส่งข้อมูลไป admission control แล้วนะครับ ในขั้นตอน admission control นี้เนื่องจากอาจทำให้บทความยาวมากๆ ขอทำความเข้าใจเรื่องนี้ในบทความแยกออกไป (ถ้ามี) นะครับ อ้างอิงคำอธิบายจาก libra
เมื่อได้รับ response มาก็จะมีการนำ response มา verify client known version, ledger info signature และ matching sub response vs request ซึ่งเราคงยังไม่ลงรายละเอียดเรื่องนี้ ให้เข้าใจว่าภายหลังจาก verify แล้วจะถือว่าข้อมูลที่ได้มาจาก response นั้นเชื่อถือได้แล้วครับ
ว่าแต่ไหนๆก็ไหนๆลอง print debug response มาดูหน่อยดีกว่าว่ามีอะไรบ้างกันนะ ผมย้อนกลับไปที่ function get_with_proof_sync เพื่อที่จะ print response ออกมาดู
ว้าววววววว Result แสดงถึงโครงสร้างข้อมูล Response จาก validator ที่น่าสนใจที่จะทำความเข้าใจมันต่อไป เพียงแต่วันนี้เวลาหมด ราตรีสวัสดิ์ครับ :)
บทความอื่นๆเกี่ยวกับการทำความเข้าใจ 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 admission control (Part 1)
Facebook Libra focus on admission control (Part 2)
Facebook Libra focus on mempool
Facebook Libra focus on consensus (Part 1)