بررسی الحاق بیت‌کوین کش به کیف پول سخت‌افزاری Trezor

ترزور یکی از مورد اعتمادترین و فراگیرترین کیف پول سخت افزاری در جهان است. ترزور ارائه دهنده امنیت بی نظیر برای ارزهای رمزنگاری‌ شده، مدیریت پسورد و تایید دو مرحله‌ای است و در عین حال استفاده از آن چه کارشناس امنیتی باشید و چه کاربر مبتدی، بسیار ساده است. اعضای تیم این کیف پول در این مطلب به بیان باگ‌ها و مسایلی پرداخته‌اند که هنگام الحاق بیت‌کوین کش به این کیف پول اتفاق افتاد و باعث شد این کیف پول سه روز دیرتر برای میزبانی این ارز آماده شود.

0 123

ناکامی‌و کامیابی

هنگامی‌که برای نخستین بار وعده الحاق BCH به کیف پول ترزور (TREZOR) را دادیم هرگز تصور نمی‌کردیم فرآیند آن تا این حد سخت و پرفشار و طولانی باشد. هر چه نباشد بیت‌کوین کش تنها یک فورک از بیت‌کوین با چند تفاوت مشخص است. ما این اصلاحات را در نظر گرفتیم و همه تغییرات ثبت شده را پیاده ساختیم. نسخه جدیدی از فریم ویر ترزور (TREZOR firmware) منتشر شد، یک ارز جدید به کیف پول ترزور اضافه شد و نسخه تازه‌ای از سرور Bitcore پیاده شد که یک بک اند (backend) مختص BCH بود. همه این‌ها در مدت زمان کوتاهی انجام شد زیرا ما کمتر از یک هفته وقت داشتیم این پروژه اورژانسی را انجام دهیم. امیدوار بودیم که همه چیز خوب پیش برود، زیرا طبق اصول مستند عمل کرده بودیم. اما همه چیز خوب پیش نرفت.

در این مطلب، مایلیم مطالبی را که طی روزهای گذشته نگفتیم، توضیح دهیم. قصد داریم بررسی کنیم که اشکال کار کجا بود، چرا همه چیز خوب پیش نرفت و در آینده چطور می‌توانیم بهتر عمل کنیم.

تصمیم‌گیری برای پشتیبانی از BCH

تصمیم گیری درباره ی پشتیبانی از BCH در وهله ی اول ساده و مشخص بود. شاید این تصمیم کمی‌زود گرفته شد. ما قول دادیم که اگر BCH در مقابل حمله تکرار (replay attack) مقاوم باشد، قابلیت پشتیبانی از بیت‌کوین کش را در ترزور ایجاد خواهیم کرد. هدف ما این بود توسعه دهندگان BCH را متقاعد کنیم که مقاوم بودن در مورد حمله تکرار به نفع هر دو ارز BTC و BCH است و اگر آن ها آن را اعمال کنند، یک کیف پول دیگر را در اکوسیستم خود خواهند داشت. در نهایت، آن‌ها این حفاظت را اجباری کردند و ما باید به وعده خود عمل می‌کردیم.

ساخت فریم ویر

در ترزور ابتدا، ساخت یک فریم ویر (firmware) جدید بدون هیچ مشکلی به انجام رسید. پشتیبانی از BCH برقرار شد و قابلیت‌های دیگری که وجودشان لازم بود به سیستم اضافه شدند (این قابلیت‌ها نیازمند یک مقاله جداگانه هستند و هنگامی‌که فریم ویر برای کیف پول ترزور منتشر شود، آن‌ها را پوشش خواهیم داد). فریم ویر آزمایش شد و مشخص شد آماده انتشار است. خلاصه اینکه هیچ مشکلی در فریم ویر نسخه 1.5.1 وجود نداشت.

باید اشاره کنیم که انجام این کار با چنین سرعتی بدون کمک‌های یوچن (Jochen) و سالیم (Saleem) امکان‌پذیر نبود.

توسعه Bitcore بیت‌کوین کش

ساخت Bitcore قصه دیگری بود و با اینکه اصلا انتظار نمی‌رفت، تبدیل به یک کابوس شد. ابتدا بهتر است با مفاهیم کلی آشنا شویم.

  • Bitcore Bitcore یک سرور بیت‌کوین است که خدمات اضافی دارد. بیت‌کور را نباید با هسته بیت‌کوین (Bitcoin Core) اشتباه گرفت. اینسایت (Insight) یک کاوشگر بلاکچین است که معمولا همراه با Bitcore نصب می‌شود. ما از Bitcore به عنوان یک بک اند (backend) برای تمامی‌ارز رمزهای موجود در کیف پول ترزور استفاده می‌کنیم.
  • BitcoinABC – پیاده سازی یک گره کامل از استاندارد بیت‌کوین کش را BitcoinABC می‌نامند.
  • بخشی از معماری Bitcore یک پچ ست (patchset) برای کد هسته بیت‌کوین می‌باشد. به عبارت دیگر، برای اجرای Bitcore هر پول دیگری، باید سورس کد برنامه که پول دلخواه را اجرا می‌کند تغییر دهیم و امکان جستجوی تراکنش با آدرس را به آن اضافه نماییم. در این مورد، می‌بایست BitcoinABC را اصلاح نماییم.
  • با توجه به اینکه خود BitcoinABC یک فورک از هسته بیت‌کوین (Bitcoin Core) می‌باشد، انجام چنین کاری باید آسان می‌بود. اما BitcoinABC تغییرات زیادی در کدهای آن ها ایجاد کرده بود. این مساله ایجاد امکان پشتیبانی را بسیار زمان بر ساخت زیرا تقریبا تمام سطرهای کد تغییر کرده بود.
  • BitcoinABC فاقد تست نت (testnet) عمومی‌است.
  • آخرین انتشار BitcoinABC تنها چند روز پیش از تاریخ فورک صورت گرفت، در نتیجه ما اصلا امکان تست‌های گسترده نداشتیم.

قالب کد به کلی تغییر کرده بود و در ابتدا مشکلات فراوانی ایجاد کرد. با این کار ما به کمک hanchon توانستیم Bitcore را با BitcoinABC راه‌اندازی کنیم. Bitcore بیت‌کوین کش اجرا شد و بدون هیچ مشکلی همگام سازی گردید. تست‌های Git با موفقیت انجام شد، گره به شبکه متصل گردید و همه چیز به کار افتاد.

همانطور که برخی از شما دیدید، گره پیش از فورک به خوبی جواب داد. اگر به آنلاین شدن ابزار درخواست بیت‌کوین کش (BCH Claim Tool) چند ساعت قبل از فورک توجه کرده باشید، متوجه موفقیت گره شده‌اید. به نظر می‌رسید که در روز یکم آگوست هیچ مشکلی به وجود نخواهد آمد.

با این حال، روزی که فورک اتفاق افتاد، ناگهان متوجه اتفاقات عجیبی شدیم. در حین مراقبت از سرور Bitcore بیت‌کوین کش، دیدیم که سرور ناگهان آدرس‌ها و تراکنش‌ها را از دست داد. آدرس‌ها مانده حساب منفی داشتند؛ چیزی که عملا غیرممکن است. به این ترتیب، نخستین تاخیر در پیاده سازی به وجود آمد زیرا ما نمی‌توانستیم کیف پولی را که از داده های خراب استفاده می‌کند منتشر نماییم.

در این زمان، تصمیم گرفتیم فقط ابزار درخواست BCH را منتشر کنیم تا شما بتوانید برای انتقال سکه‌های خود به یک کیف پول دیگر درخواست دهید. ابزار درخواست هم به سرور Bitcore متکی است اما در ارسال تراکنش‌ها به خوبی عمل کرد زیرا با گرفتن مانده BCH از مانده BTC فعلی، نقص ایجاد شده را دور می‌زد.

هنگامی‌که مشغول باگ زدایی و برطرف کردن مشکل بودیم متوجه شدیم که سرور Bitcore ما تنها اینسایتی  (Insight) نیست که اطلاعات تراکنش در آن ناپدید می‌شود. این مشکل در تمامی‌سرورهایی که Bitcore را اجرا می‌کردند به وجود آمده بود، از جمله در بلاک دوزر (Blockdozer) .

باگ

علت ناپدید شدن تراکنش‌ها در Bitcore ما چه بود؟ پس از چند ساعت باگ زدایی متوجه باگی شدیم که منشاء این اختلال بود. هنگامی‌که سرور Bitcore ری استارت می‌شد، آدرس ایندکس برخی بلوک‌ها را به صورت رندوم پاک می‌کرد. با این وجود هنگامی‌ که آن بلوک به شکل دستی نامعتبر و دوباره ایندکس می‌شد، خود به خود ایندکس آن درست می‌شد؛ بنابراین باگ مورد نظر قطعیت نداشت.

جستجوی باگ

هر گره بیت‌کوین در هر بار شروع از دیتابیس بلوک خود یک « آزمون سلامت » (sanity check) می‌گیرد. در حین این فرآیند، چند بلوک در حافظه از بلاکچین قطع می‌شوند و سپس دوباره متصل می‌گردند تا وضعیت آن ها بررسی و مقایسه شود. از آن جایی که این کار در حافظه صورت می‌گیرد، حتی اگر بلوک‌ها دوباره متصل نشوند هیچ اثر جانبی ندارد. پچ های Bitcore این توابع را تغییر می‌دهند و یک فرآیند دیگر اضافه می‌کنند؛ که آن فرآیند خواندن و ذخیره  آدرس‌ها در یک ایندکس جداگانه است.

در عین حال با توجه به اینکه BitcoinABC نسبت به شاخه اصلی هسته بیت‌کوین تغییراتی دارد، آن‌ها به شکلی زیرکانه منطق یکی از شیوه‌های به کار رفته در این فرآیند را عوض کرده‌اند. این مساله باعث شد، هنگام اجرا در حافظه یا دیسک، شیوه مذکور حالت فرآیند را چه در مرحله « چک اولیه » و یا در « اجرای استاندارد » نادیده بگیرد.

به جای آن، در هر ری استارت،  فرآیند در حالت « روی دیسک » (حالت دوم) اجرا می‌شد و اطلاعات آدرس‌ها از شش بلوک آخر حذف می‌شد. این مساله باعث ایجاد ناسازگاری در دیتابیس شد و با از بین رفتن برخی تراکنش‌ها، شماری از آدرس‌ها مانده حساب منفی گرفتند.

درست کردن باگ

ما مجبور بودیم علاوه بر بازنویسی و کامپایل اجباری کد، تمامی‌بلوک‌های مشکل‌دار را در بلاکچین خود نامعتبر کنیم. در حین رفع اشکال، مجبور شدیم ابزار درخواست را قطع کنیم چرا که بک اند آفلاین شده بود (این اتفاق در دوم آگوست افتاد).

متاسفانه، این فرآیند تمامی‌دیتابیس را برای BCH خراب کرد. زنجیره بیت‌کوین بسیار جلوتر از آن بود که بتوان از آن استفاده کرد و سرور هرگونه تایید مجدد را رد می‌کرد، به همین خاطر مجبور شدیم یک دیتابیس را کپی کنیم و همه چیز را از اول ایندکس‌بندی نماییم. اما فرآیند ایندکس‌بندی مجدد به پایان نرسید زیرا بسیار کند شد. با اینکه تخمین زمانی اولیه برای کل عملیات 7 – 5 ساعت بود، پس از 12 ساعت ایندکس‌بندی مجدد، تخمین آپدیت شده نشان می‌داد که این کار 12 ساعت دیگر طول می‌کشد. ما نمی‌توانستیم 12 ساعت دیگر صبر کنیم. در نهایت، ایندکس‌ها را از گره بیت‌کوین خودمان کپی کردیم، تمامی‌بلوک‌ها را تا بلوک فورک نامعتبر ساختیم و BitcoinABC را استارت زدیم.

افزون بر این، برای اطمینان از داشتن یک بکاپ از دیتا بیس در صورت خرابی مجدد، 300 GB از دیتای سرورهای مختلف را کپی کردیم. به این ترتیب، اگر بک اند با یک باگ دیگر رو به رو شود، می‌توانیم به سرعت آن را بازیابی نماییم. پس از گرفتن بکاپ، بک اند را راه انداختیم و چند تراکنش را تست کردیم. پس از موفقیت این تراکنش‌ها، اخبار مربوط را منتشر ساختیم.

پس از مواجهه و رفع مشکلات پشت سر هم، در نهایت توانستیم بیت‌کوین کش را در کیف پول ترزور به کار بیندازیم. این اتفاق در سوم آگوست، ساعت 20:30 (به وقت جهانی) افتاد.

درس‌هایی که آموختیم

جا دارد اشاره کنیم که ما این مطلب را برای این ننوشتیم که تقصیر را گردن کسی بیندازیم. بک پورتینگ (backporting) کد یک نسخه جدیدتر هسته بیت‌کوین، تقصیر هیچ کس نیست. به هم ریختن اوضاع به خاطر کد مشکل دار نبود. نبود زمان برای تست کارکردها و درست کردن اشکالات باعث بروز مشکل شد. اگر زمان بیشتری وجود داشت، می‌توانستیم این باگ را پیش از تست کردن شناسایی و رفع کنیم.

از این هارد فورک درس‌های زیادی می‌توان گرفت. در اینجا به برخی از مهم ترین آن ها اشاره می‌کنیم:

  • ما به منظور تحقق برخی شرایط، برقراری پشتیبانی را اعلام نخواهیم کرد.
  • ما اعلام نخواهیم کرد که قابلیت‌ها در تاریخ مشخص منتشر می‌شوند.
  • ما فرض می‌کنیم که کدها دارای باگ هستند.
  • ما برای توسعه کد و اجتناب از مشکلات زمان می‌گذاریم.

به خاطر شکیبایی فراوانی که در حین این اتفاق از خود نشان دادید از شما سپاسگذاریم. پشتیبانی شما در چنین برهه‌هایی حیاتی است و ما بسیار قدردان پیام‌های مثبتی هستیم که در حین این بحران برای ما فرستادید. ما امیدوار هستیم که در آینده ی نزدیک با شرایطی مانند این رو به رو نشویم.

شاید از این مطالب هم خوشتان بیاید.

ارسال پاسخ

آدرس ایمیل شما منتشر نخواهد شد.