عوامی ٹیسٹ: ایتھریم پرائیویسی اور اسکیل ایبلٹی حل

بلاکس ایک جدید ٹیکنالوجی ہے جو انسانی زندگی کے بہت سے شعبوں کو بہتر بنانے کا وعدہ کرتی ہے۔ یہ حقیقی عمل اور مصنوعات کو ڈیجیٹل اسپیس میں لاتا ہے، مالیاتی لین دین کی رفتار اور وشوسنییتا کو یقینی بناتا ہے، ان کی لاگت کو کم کرتا ہے، اور آپ کو وکندریقرت نیٹ ورکس میں سمارٹ کنٹریکٹس کا استعمال کرتے ہوئے جدید DAPP ایپلی کیشنز بنانے کی بھی اجازت دیتا ہے۔

بلاکچین کے بہت سے فوائد اور متنوع ایپلی کیشنز کو دیکھتے ہوئے، یہ عجیب لگ سکتا ہے کہ اس امید افزا ٹیکنالوجی نے ابھی تک ہر صنعت میں اپنی جگہ نہیں بنائی ہے۔ مسئلہ یہ ہے کہ جدید وکندریقرت بلاکچین میں اسکیل ایبلٹی کی کمی ہے۔ Ethereum فی سیکنڈ تقریباً 20 ٹرانزیکشنز پر کارروائی کرتا ہے، جو آج کے متحرک کاروبار کی ضروریات کو پورا کرنے کے لیے کافی نہیں ہے۔ ایک ہی وقت میں، بلاک چین ٹیکنالوجی استعمال کرنے والی کمپنیاں ہیکنگ اور نیٹ ورک کی ناکامیوں کے خلاف اعلیٰ درجے کے تحفظ کی وجہ سے ایتھرئم کو ترک کرنے سے ہچکچا رہی ہیں۔

بلاکچین پر وکندریقرت، سیکورٹی، اور اسکیل ایبلٹی کو یقینی بنانے کے لیے، اس طرح اسکیل ایبلٹی ٹریلیما کو حل کرنا، ترقیاتی ٹیم موقع Plasma Cash بنایا، ایک چائلڈ چین جس میں ایک سمارٹ کنٹریکٹ اور Node.js پر مبنی ایک نجی نیٹ ورک شامل ہے، جو وقتاً فوقتاً اپنی حالت کو روٹ چین (ایتھریم) میں منتقل کرتا ہے۔

عوامی ٹیسٹ: ایتھریم پرائیویسی اور اسکیل ایبلٹی حل

پلازما کیش میں کلیدی عمل

1. صارف 'ڈپازٹ' اسمارٹ کنٹریکٹ فنکشن کو کال کرتا ہے، ETH میں اس رقم کو پاس کرتا ہے جسے وہ پلازما کیش ٹوکن میں رکھنا چاہتا ہے۔ سمارٹ کنٹریکٹ فنکشن ایک ٹوکن بناتا ہے اور اس کے بارے میں ایک ایونٹ تیار کرتا ہے۔

2. سمارٹ کنٹریکٹ ایونٹس کے لیے سبسکرائب کیے گئے پلازما کیش نوڈس ڈیپازٹ تخلیق کا ایونٹ حاصل کرتے ہیں اور پول میں ٹوکن تخلیق کا لین دین شامل کرتے ہیں۔

3. وقتاً فوقتاً، خصوصی پلازما کیش نوڈس پول (1 ملین تک) سے تمام لین دین لیتے ہیں اور ان سے ایک بلاک بناتے ہیں، مرکل کے درخت کا حساب لگاتے ہیں اور اس کے مطابق، ہیش۔ یہ بلاک تصدیق کے لیے دوسرے نوڈس کو بھیجا جاتا ہے۔ نوڈس چیک کرتے ہیں کہ آیا مرکل ہیش درست ہے، آیا لین دین درست ہے یا نہیں (مثال کے طور پر، آیا ٹوکن بھیجنے والا اس کا مالک ہے)۔ بلاک کی تصدیق کرنے کے بعد، نوڈ سمارٹ کنٹریکٹ کے 'سبمٹ بلاک' فنکشن کو کال کرتا ہے، جو بلاک کے نمبر اور مرکل ہیش کو زنجیر چین میں محفوظ کرتا ہے۔ سمارٹ کنٹریکٹ بلاک کے کامیاب اضافے کے بارے میں ایک ایونٹ تیار کرتا ہے۔ لین دین کو پول سے ہٹا دیا جاتا ہے۔

4. نوڈس جو بلاک جمع کرانے کا واقعہ وصول کرتے ہیں وہ ٹرانزیکشنز کو لاگو کرنا شروع کر دیتے ہیں جو بلاک میں شامل کیے گئے تھے۔

5. کسی وقت، ٹوکن کا مالک (یا غیر مالک) اسے پلازما کیش سے واپس لینا چاہتا ہے۔ ایسا کرنے کے لیے، وہ 'startExit' فنکشن کو کال کرتا ہے، اسے ٹوکن پر آخری 2 لین دین کے بارے میں معلومات بھیجتا ہے، جو اس بات کی تصدیق کرتا ہے کہ وہ ٹوکن کا مالک ہے۔ سمارٹ کنٹریکٹ، مرکل ہیش کا استعمال کرتے ہوئے، بلاکس میں لین دین کی موجودگی کو چیک کرتا ہے اور واپسی کے لیے ٹوکن بھیجتا ہے، جو دو ہفتوں میں ہو گا۔

6. اگر ٹوکن نکالنے کا عمل خلاف ورزیوں کے ساتھ ہوا ہے (ٹوکن واپسی کے طریقہ کار کے آغاز کے بعد خرچ کیا گیا تھا یا ٹوکن نکالنے سے پہلے ہی کسی اور کا تھا)، ٹوکن کا مالک دو ہفتوں کے اندر واپسی کی تردید کر سکتا ہے۔

عوامی ٹیسٹ: ایتھریم پرائیویسی اور اسکیل ایبلٹی حل

رازداری دو طریقوں سے حاصل کی جاتی ہے۔

1. روٹ چین ان لین دین کے بارے میں کچھ نہیں جانتا ہے جو چائلڈ چین کے اندر بنتے اور بھیجے جاتے ہیں۔ پلازما کیش میں / سے ETH کس نے جمع کیا اور نکالا اس کے بارے میں معلومات عوامی رہتی ہیں۔

2. چائلڈ چین zk-SNARKs کا استعمال کرتے ہوئے گمنام لین دین کی اجازت دیتا ہے۔

ٹیکنالوجی اسٹیک

  • نوڈ جے ایس
  • ریڈس
  • ایتھیریم۔
  • نرم

ٹیسٹنگ

پلازما کیش تیار کرتے وقت، ہم نے سسٹم کی رفتار کو جانچا اور درج ذیل نتائج حاصل کیے:

  • پول میں فی سیکنڈ 35 ٹرانزیکشنز شامل کیے جاتے ہیں۔
  • ایک بلاک میں 1 تک کے لین دین کو محفوظ کیا جا سکتا ہے۔

ٹیسٹ مندرجہ ذیل 3 سرورز پر کیے گئے تھے۔

1. Intel Core i7-6700 Quad-Core Skylake بشمول۔ NVMe SSD - 512 GB، 64 GB DDR4 RAM
3 توثیق کرنے والے پلازما کیش نوڈس اٹھائے گئے ہیں۔

2. AMD Ryzen 7 1700X Octa-core "Summit Ridge" (Zen)، SATA SSD - 500 GB، 64 GB DDR4 RAM
ایک Ropsten testnet ETH نوڈ اٹھایا گیا ہے۔
3 توثیق کرنے والے پلازما کیش نوڈس اٹھائے گئے۔

3. Intel Core i9-9900K Octa-Core بشمول۔ NVMe SSD - 1 TB، 64 GB DDR4 RAM
1 پلازما کیش نوڈ جمع کرانے میں اضافہ ہوا۔
3 توثیق کرنے والے پلازما کیش نوڈس اٹھائے گئے۔
پلازما کیش نیٹ ورک میں لین دین کو شامل کرنے کے لیے ایک ٹیسٹ شروع کیا گیا۔

کل: نجی نیٹ ورک میں 10 پلازما کیش نوڈس۔

ٹیسٹ 1

ایک بلاک میں 1 ملین لین دین کی حد ہے۔ لہذا، 1 ​​ملین ٹرانزیکشنز 2 بلاکس میں آتی ہیں (چونکہ سسٹم ٹرانزیکشنز کا حصہ لینے اور بھیجے جانے کے دوران انہیں جمع کرانے کا انتظام کرتا ہے)۔


ابتدائی حالت: آخری بلاک #7؛ 1 ملین ٹرانزیکشنز اور ٹوکنز ڈیٹا بیس میں محفوظ ہیں۔

00:00 - ٹرانزیکشن جنریشن اسکرپٹ کا آغاز
01:37 — 1 ملین ٹرانزیکشنز بن چکے ہیں اور نوڈ پر بھیجنا شروع ہو گیا ہے۔
01:46 — جمع کروانے والے نوڈ نے پول سے 240k ٹرانزیکشنز کیں اور بلاک نمبر 8 بنا۔ ہم یہ بھی دیکھتے ہیں کہ 320 سیکنڈ میں 10k لین دین پول میں شامل ہو جاتے ہیں۔
01:58 — بلاک نمبر 8 پر دستخط کیے گئے اور تصدیق کے لیے بھیجے گئے۔
02:03 — بلاک نمبر 8 کی توثیق ہو گئی ہے اور سمارٹ کنٹریکٹ کے 'submitBlock' فنکشن کو مرکل ہیش اور بلاک نمبر کے ساتھ کال کیا جاتا ہے۔
02:10 - ڈیمو اسکرپٹ نے کام ختم کیا، جس نے 1 سیکنڈ میں 32 ملین ٹرانزیکشنز بھیجے
02:33 - نوڈس نے معلومات حاصل کرنا شروع کیں کہ بلاک #8 کو روٹ چین میں شامل کیا گیا ہے، اور 240k ٹرانزیکشنز کو انجام دینا شروع کر دیا ہے۔
02:40 - 240k ٹرانزیکشنز کو پول سے حذف کر دیا گیا تھا، جو پہلے سے بلاک نمبر 8 میں ہیں
02:56 — جمع کرانے والے نوڈ نے پول سے بقیہ 760k ٹرانزیکشنز لیے اور مرکل ہیش اور سائننگ بلاک #9 کا حساب لگانا شروع کر دیا۔
03:20 - تمام نوڈس میں 1 ملین 240k ٹرانزیکشنز اور ٹوکنز ہوتے ہیں۔
03:35 — بلاک نمبر 9 پر دستخط کیے گئے ہیں اور دوسرے نوڈس کو تصدیق کے لیے بھیجے گئے ہیں۔
03:41 - نیٹ ورک میں خرابی پیدا ہوگئی ہے۔
04:40 — بلاک نمبر 9 کی توثیق کا انتظار وقت ختم ہونے کی وجہ سے رک گیا۔
04:54 — جمع کرانے والے نوڈ نے پول سے بقیہ 760k ٹرانزیکشنز لیے اور مرکل ہیش اور سائننگ بلاک #9 کا حساب لگانا شروع کر دیا۔
05:32 — بلاک نمبر 9 پر دستخط کیے گئے ہیں اور دوسرے نوڈس کو تصدیق کے لیے بھیجے گئے ہیں۔
05:53 - بلاک نمبر 9 کی توثیق ہو گئی ہے اور اسے روٹ چین میں بھیج دیا گیا ہے۔
06:17 — نوڈس کو یہ معلومات ملنا شروع ہوئیں کہ بلاک نمبر 9 کو روٹ چین میں شامل کیا گیا ہے اور 760k ٹرانزیکشنز کو انجام دینا شروع کر دیا ہے۔
06:47 - پول کو ان ٹرانزیکشنز سے صاف کر دیا گیا جو بلاک نمبر 9 میں ہیں۔
09:06 — تمام نوڈس میں 2 ملین ٹرانزیکشنز اور ٹوکنز ہوتے ہیں۔

ٹیسٹ 2

فی بلاک 350k کی حد ہے۔ نتیجے کے طور پر، ہمارے پاس 3 بلاکس ہیں۔


ابتدائی حالت: آخری بلاک #9؛ 2 ملین ٹرانزیکشنز اور ٹوکنز ڈیٹا بیس میں محفوظ ہیں۔

00:00 — ٹرانزیکشن جنریشن اسکرپٹ پہلے سے چل رہی ہے۔
00:44 — 1 ملین ٹرانزیکشنز بن چکے ہیں اور نوڈ پر بھیجنا شروع ہو گیا ہے۔
00:56 — جمع کروانے والے نوڈ نے پول سے 320k ٹرانزیکشنز کیں اور بلاک نمبر 10 بنا۔ ہم یہ بھی دیکھتے ہیں کہ 320 سیکنڈ میں 10k لین دین پول میں شامل ہو جاتے ہیں۔
01:12 — بلاک نمبر 10 پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
01:18 - ڈیمو اسکرپٹ نے کام ختم کیا، جس نے 1 سیکنڈ میں 34 ملین ٹرانزیکشنز بھیجے
01:20 — بلاک نمبر 10 کی توثیق کی گئی اور روٹ چین کو بھیجا گیا۔
01:51 - تمام نوڈس کو روٹ چین سے معلومات موصول ہوئی ہیں جن میں بلاک #10 شامل کیا گیا ہے، اور 320k ٹرانزیکشنز کا اطلاق شروع کریں
02:01 - 320k ٹرانزیکشنز کے لیے پول صاف کر دیا گیا تھا جو بلاک #10 میں شامل کیے گئے تھے۔
02:15 — جمع کرانے والے نوڈ نے پول سے 350k ٹرانزیکشنز کیں اور بلاک نمبر 11 بنا
02:34 — بلاک نمبر 11 پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
02:51 — بلاک نمبر 11 کی توثیق کی گئی اور روٹ چین کو بھیجا گیا۔
02:55 - آخری نوڈ نے بلاک #10 سے لین دین مکمل کیا۔
10:59 - بلاک نمبر 9 کے جمع کرانے کے ساتھ ایک ٹرانزیکشن بہت لمبے عرصے تک روٹ چین میں کی گئی، لیکن یہ مکمل ہو گیا اور تمام نوڈس کو اس کے بارے میں معلومات موصول ہوئیں اور 350k ٹرانزیکشنز پر عمل درآمد شروع ہو گیا۔
11:05 - 320k ٹرانزیکشنز کے لیے پول صاف کر دیا گیا تھا جو بلاک #11 میں شامل کیے گئے تھے۔
12:10 - تمام نوڈس میں 1 ملین 670k ٹرانزیکشنز اور ٹوکنز ہوتے ہیں۔
12:17 — جمع کرانے والے نوڈ نے پول سے 330k ٹرانزیکشنز کیے اور بلاک نمبر 12 بنا
12:32 — بلاک نمبر 12 پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
12:39 — بلاک نمبر 12 کی توثیق کی گئی اور روٹ چین کو بھیجا گیا۔
13:44 - تمام نوڈس کو روٹ چین سے معلومات موصول ہوئی ہیں کہ بلاک #12 کو شامل کیا گیا ہے اور 330k ٹرانزیکشنز کو لاگو کرنا شروع کر دیا ہے۔
14:50 — تمام نوڈس میں 2 ملین ٹرانزیکشنز اور ٹوکنز ہوتے ہیں۔

ٹیسٹ 3

پہلے اور دوسرے سرورز میں، ایک توثیق کرنے والے نوڈ کو جمع کروانے والے نوڈ سے بدل دیا گیا تھا۔


ابتدائی حالت: آخری بلاک #84؛ 0 ٹرانزیکشنز اور ٹوکنز ڈیٹا بیس میں محفوظ ہیں۔

00:00 - 3 اسکرپٹ لانچ کیے گئے ہیں جو ہر ایک میں 1 ملین ٹرانزیکشنز تیار اور بھیجتے ہیں
01:38 — 1 ملین ٹرانزیکشنز بن چکے ہیں اور نوڈ #3 کو جمع کرانے کے لیے بھیجنا شروع ہو گیا ہے۔
01:50 — جمع کروائیں نوڈ #3 نے پول اور فارم بلاک #330 (f85) سے 21k ٹرانزیکشنز کیں۔ ہم یہ بھی دیکھتے ہیں کہ 350 سیکنڈ میں 10k لین دین پول میں شامل ہو جاتے ہیں۔
01:53 — 1 ملین ٹرانزیکشنز بن چکے ہیں اور نوڈ #1 کو جمع کرانے کے لیے بھیجنا شروع ہو گیا ہے۔
01:50 — جمع کروائیں نوڈ #3 نے پول اور فارم بلاک #330 (f85) سے 21k ٹرانزیکشنز کیں۔ ہم یہ بھی دیکھتے ہیں کہ 350 سیکنڈ میں 10k لین دین پول میں شامل ہو جاتے ہیں۔
02:01 — جمع کروائیں نوڈ #1 نے پول سے 250k لین دین لیا اور بلاک #85 (65e)
02:06 — بلاک #85 (f21) پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
02:08 — سرور ڈیمو اسکرپٹ #3 نے کام ختم کیا، جس نے 1 سیکنڈ میں 30 ملین ٹرانزیکشنز بھیجے
02:14 — بلاک #85 (f21) کی توثیق کی گئی اور روٹ چین کو بھیج دی گئی۔
02:19 — بلاک #85 (65e) پر دستخط کیے گئے اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے
02:22 — 1 ملین ٹرانزیکشنز بن چکے ہیں اور نوڈ #2 کو جمع کرانے کے لیے بھیجنا شروع ہو گیا ہے۔
02:27 — بلاک #85 (65e) کی توثیق کی گئی اور روٹ چین کو بھیج دی گئی۔
02:29 — جمع کروائیں نوڈ نمبر 2 نے پول سے 111855 ٹرانزیکشنز کیں اور بلاک نمبر 85 (256) بنا۔
02:36 — بلاک نمبر 85 (256) پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
02:36 — سرور ڈیمو اسکرپٹ #1 نے کام ختم کیا، جس نے 1 سیکنڈ میں 42.5 ملین ٹرانزیکشنز بھیجے
02:38 — بلاک #85 (256) کی توثیق کی گئی اور روٹ چین کو بھیج دیا گیا۔
03:08 — سرور اسکرپٹ کیس نمبر 2 نے کام ختم کیا، جس نے 1 سیکنڈ میں 47 ملین ٹرانزیکشنز بھیجے
03:38 — تمام نوڈس کو روٹ چین سے معلومات موصول ہوئی ہیں جو #85 (f21)، #86(65e)، #87(256) کو بلاک کرتی ہیں اور 330k، 250k، 111855 ٹرانزیکشنز کو لاگو کرنا شروع کر دیتے ہیں۔
03:49 — پول کو 330k, 250k, 111855 ٹرانزیکشنز کے لیے صاف کیا گیا تھا جو بلاکس #85 (f21), #86(65e), #87(256) میں شامل کیے گئے تھے۔
03:59 — جمع کروائیں نوڈ #1 نے پول سے 888145 ٹرانزیکشنز کیں اور بلاک #88 (214) فارمز، جمع کروائیں نوڈ #2 نے پول سے 750k ٹرانزیکشنز کیں اور بلاک #88 (50a) فارمز، نوڈ #3 نے 670k ٹرانزیکشنز کیں پول اور فارم بلاک #88 (d3b)
04:44 — بلاک #88 (d3b) پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
04:58 — بلاک نمبر 88 (214) پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
05:11 — بلاک #88 (50a) پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
05:11 — بلاک #85 (d3b) کی توثیق کی گئی اور روٹ چین کو بھیج دی گئی۔
05:36 — بلاک #85 (214) کی توثیق کی گئی اور روٹ چین کو بھیج دیا گیا۔
05:43 — تمام نوڈس کو روٹ چین سے معلومات موصول ہوئی ہیں جن میں بلاکس #88 (d3b)، #89 (214) کو شامل کیا گیا ہے اور 670k، 750k ٹرانزیکشنز کا اطلاق شروع کر دیا گیا ہے۔
06:50 — بلاک نمبر 85 (50a) ٹوٹے ہوئے کنکشن کی وجہ سے درست نہیں ہوا۔
06:55 — جمع کروائیں نوڈ #2 نے پول سے 888145 ٹرانزیکشنز کیے اور بلاک #90 (50a) فارمز
08:14 — بلاک #90 (50a) پر دستخط کیے گئے ہیں اور تصدیق کے لیے دوسرے نوڈس کو بھیجے گئے ہیں۔
09:04 — بلاک #90 (50a) کی توثیق کی گئی اور روٹ چین کو بھیج دیا گیا۔
11:23 - تمام نوڈس نے روٹ چین سے معلومات حاصل کیں جن میں بلاک #90 (50a) شامل کر دیا گیا ہے، اور 888145 ٹرانزیکشنز کو لاگو کرنا شروع کر دیا ہے۔ اسی وقت، سرور #3 نے طویل عرصے سے بلاکس #88 (d3b)، #89 (214) سے لین دین کا اطلاق کیا ہے۔
12:11 - تمام تالاب خالی ہیں۔
13:41 - سرور #3 کے تمام نوڈس 3 ملین ٹرانزیکشنز اور ٹوکنز پر مشتمل ہیں۔
14:35 - سرور #1 کے تمام نوڈس 3 ملین ٹرانزیکشنز اور ٹوکنز پر مشتمل ہیں۔
19:24 - سرور #2 کے تمام نوڈس 3 ملین ٹرانزیکشنز اور ٹوکنز پر مشتمل ہیں۔

راہ میں حائل رکاوٹوں

پلازما کیش کی ترقی کے دوران، ہمیں درج ذیل مسائل کا سامنا کرنا پڑا، جنہیں ہم نے بتدریج حل کیا اور حل کر رہے ہیں:

1. نظام کے مختلف افعال کے تعامل کا تنازعہ۔ مثال کے طور پر، پول میں لین دین کو شامل کرنے کے فنکشن نے بلاکس کو جمع کرانے اور درست کرنے کے کام کو روک دیا، اور اس کے برعکس، جس کی وجہ سے رفتار میں کمی واقع ہوئی۔

2. یہ فوری طور پر واضح نہیں تھا کہ بڑی تعداد میں لین دین کیسے بھیجے جائیں اور اسی وقت ڈیٹا کی منتقلی کے اخراجات کو کم سے کم کیا جائے۔

3. یہ واضح نہیں تھا کہ اعلیٰ نتائج حاصل کرنے کے لیے ڈیٹا کو کیسے اور کہاں ذخیرہ کرنا ہے۔

4. یہ واضح نہیں تھا کہ نوڈس کے درمیان نیٹ ورک کو کیسے ترتیب دیا جائے، کیونکہ 1 ملین ٹرانزیکشنز کے ساتھ بلاک سائز تقریباً 100 MB لیتا ہے۔

5. سنگل تھریڈڈ موڈ میں کام کرنے سے نوڈس کے درمیان رابطہ ٹوٹ جاتا ہے جب لمبا حساب ہوتا ہے (مثال کے طور پر مرکل ٹری بنانا اور اس کی ہیش کا حساب لگانا)۔

ہم نے اس سب سے کیسے نمٹا؟

پلازما کیش نوڈ کا پہلا ورژن ایک قسم کا کمبائن تھا جو ایک ہی وقت میں سب کچھ کر سکتا تھا: لین دین کو قبول کرنا، بلاکس کو جمع کرنا اور تصدیق کرنا، اور ڈیٹا تک رسائی کے لیے API فراہم کرنا۔ چونکہ نوڈ جے ایس مقامی طور پر سنگل تھریڈڈ ہے، اس لیے بھاری مرکل ٹری کیلکولیشن فنکشن ٹرانزیکشن کو شامل کرنے کے فنکشن کو روک رہا تھا۔ ہم نے اس مسئلے کے دو حل دیکھے ہیں:

1. کئی NodeJS عمل شروع کریں، جن میں سے ہر ایک مخصوص افعال انجام دیتا ہے۔

2. worker_threads کا استعمال کریں اور کوڈ کے کچھ حصے کے عمل کو تھریڈز میں منتقل کریں۔

نتیجے کے طور پر، ہم نے ایک ہی وقت میں دونوں اختیارات کا استعمال کیا: ہم نے منطقی طور پر ایک نوڈ کو 3 حصوں میں تقسیم کیا جو الگ الگ کام کر سکتے ہیں، لیکن ایک ہی وقت میں ہم آہنگی کے ساتھ

1. نوڈ جمع کرو جو پول میں لین دین کو قبول کرتا ہے اور بلاکس بناتا ہے۔

2. ایک توثیق کرنے والا نوڈ جو نوڈس کی درستگی کو چیک کرتا ہے۔

3. API نوڈ - ڈیٹا تک رسائی کے لیے ایک API فراہم کرتا ہے۔

ایک ہی وقت میں، آپ cli کا استعمال کرتے ہوئے یونکس ساکٹ کے ذریعے ہر نوڈ سے جڑ سکتے ہیں۔

بھاری آپریشن، جیسے مرکل کے درخت کا حساب، ہم ایک الگ دھاگے میں چلے گئے۔

اس طرح، ہم نے پلازما کیش کے تمام فنکشنز کو بیک وقت اور بغیر کسی ناکامی کے نارمل آپریشن حاصل کر لیا ہے۔

جیسے ہی سسٹم فعال ہوا، ہم نے رفتار کی جانچ شروع کردی اور بدقسمتی سے، غیر تسلی بخش نتائج برآمد ہوئے: فی سیکنڈ 5 ٹرانزیکشنز اور فی بلاک 000 ٹرانزیکشنز تک۔ مجھے یہ معلوم کرنا تھا کہ کیا غلط طریقے سے نافذ کیا گیا تھا۔

شروع کرنے کے لیے، ہم نے نظام کی اعلیٰ صلاحیت کا پتہ لگانے کے لیے پلازما کیش کے ساتھ رابطے کے طریقہ کار کی جانچ شروع کی۔ پہلے ہم نے لکھا تھا کہ پلازما کیش نوڈ یونکس ساکٹ انٹرفیس فراہم کرتا ہے۔ یہ اصل میں متن تھا۔ json اشیاء کو `JSON.parse()` اور `JSON.stringify()` کا استعمال کرتے ہوئے بھیجا گیا تھا۔

```json
{
  "action": "sendTransaction",
  "payload":{
    "prevHash": "0x8a88cc4217745fd0b4eb161f6923235da10593be66b841d47da86b9cd95d93e0",
    "prevBlock": 41,
    "tokenId": "57570139642005649136210751546585740989890521125187435281313126554130572876445",
    "newOwner": "0x200eabe5b26e547446ae5821622892291632d4f4",
    "type": "pay",
    "data": "",
    "signature": "0xd1107d0c6df15e01e168e631a386363c72206cb75b233f8f3cf883134854967e1cd9b3306cc5c0ce58f0a7397ae9b2487501b56695fe3a3c90ec0f61c7ea4a721c"
  }
}
```

ہم نے ایسی اشیاء کی منتقلی کی رفتار کی پیمائش کی اور ~ 130k فی سیکنڈ حاصل کی۔ ہم نے json کے ساتھ کام کرنے کے لیے معیاری افعال کو تبدیل کرنے کی کوشش کی، لیکن کارکردگی بہتر نہیں ہوئی۔ V8 انجن کو ان آپریشنز کے لیے اچھی طرح سے بہتر بنایا جانا چاہیے۔

ہم نے کلاسز کے ذریعے لین دین، ٹوکن، بلاکس کے ساتھ کام کیا۔ اس طرح کی کلاسیں بناتے وقت، کارکردگی میں 2 گنا کمی آئی، جس سے ظاہر ہوتا ہے کہ OOP ہمارے لیے موزوں نہیں ہے۔ مجھے ہر چیز کو مکمل طور پر فعال نقطہ نظر پر دوبارہ لکھنا پڑا۔

ڈیٹا بیس میں ریکارڈنگ

ابتدائی طور پر، Redis کو ڈیٹا سٹوریج کے لیے سب سے زیادہ پیداواری حل کے طور پر منتخب کیا گیا تھا جو ہماری ضرورت کو پورا کرتا ہے: کلیدی قدر اسٹوریج، ہیش ٹیبلز کے ساتھ کام، سیٹ۔ ہم نے redis-benchmark چلایا اور 80 پائپ لائننگ موڈ میں ~1k آپریشن فی سیکنڈ حاصل کیا۔

اعلی کارکردگی کے لیے، ہم نے Redis کو مزید باریک بنایا:

  • یونکس ساکٹ کنکشن قائم کیا۔
  • ڈسک میں محفوظ کرنے کی حالت کو غیر فعال کر دیا گیا (قابل اعتماد کے لیے، آپ ایک نقل ترتیب دے سکتے ہیں اور علیحدہ Redis میں ڈسک پر محفوظ کر سکتے ہیں)۔

Redis میں، ایک پول ایک ہیش ٹیبل ہے، کیونکہ ہمیں ایک درخواست میں تمام لین دین حاصل کرنے اور ایک ایک کرکے لین دین کو حذف کرنے کی اہلیت کی ضرورت ہوتی ہے۔ ہم نے ایک باقاعدہ فہرست استعمال کرنے کی کوشش کی، لیکن پوری فہرست کو اتارتے وقت یہ آہستہ کام کرتی ہے۔

معیاری NodeJS استعمال کرتے وقت، Redis لائبریریوں کو فی سیکنڈ 18k ٹرانزیکشنز کی کارکردگی ملی۔ رفتار 9 گنا کم ہوگئی۔

چونکہ بینچ مارک نے ہمیں 5 گنا زیادہ امکانات واضح طور پر دکھائے، ہم نے بہتر بنانا شروع کیا۔ ہم نے لائبریری کو ioredis میں تبدیل کیا اور 25k فی سیکنڈ کی کارکردگی حاصل کی۔ ہم نے 'hset' کمانڈ کا استعمال کرتے ہوئے ایک ایک کر کے لین دین کو شامل کیا۔ اس طرح، ہم نے Redis میں بہت سی درخواستیں تیار کیں۔ پیک میں لین دین کو یکجا کرنے اور ایک 'hmset' کمانڈ کے ساتھ بھیجنے کا ایک خیال تھا۔ نتیجہ 32k فی سیکنڈ ہے۔

کئی وجوہات کی بنا پر، جن کی ہم ذیل میں وضاحت کریں گے، ہم `Buffer` کا استعمال کرتے ہوئے ڈیٹا کے ساتھ کام کرتے ہیں اور جیسا کہ یہ نکلا، اگر ہم اسے لکھنے سے پہلے متن (`buffer.toString('hex')`) میں ترجمہ کرتے ہیں، تو ہم اضافی حاصل کر سکتے ہیں۔ کارکردگی اس طرح رفتار 35k فی سیکنڈ تک بڑھا دی گئی۔ اس وقت، ہم نے مزید اصلاح کو معطل کرنے کا فیصلہ کیا۔

ہمیں بائنری پروٹوکول پر جانا پڑا کیونکہ:

1. سسٹم اکثر ہیش، دستخط وغیرہ کا حساب لگاتا ہے اور اس کے لیے اسے بفر میں ڈیٹا کی ضرورت ہوتی ہے۔

2. خدمات کے درمیان بھیجے جانے پر، بائنری ڈیٹا کا وزن متن سے کم ہوتا ہے۔ مثال کے طور پر، 1 ملین لین دین کے ساتھ بلاک بھیجتے وقت، متن میں موجود ڈیٹا 300 میگا بائٹس سے زیادہ لے سکتا ہے۔

3. مسلسل ڈیٹا کی تبدیلی کارکردگی کو متاثر کرتی ہے۔

لہذا، ہم نے اپنے بائنری ڈیٹا اسٹوریج اور ٹرانسفر پروٹوکول کو ایک بنیاد کے طور پر لیا، جو شاندار `بائنری-ڈیٹا` لائبریری کی بنیاد پر تیار کیا گیا ہے۔

نتیجے کے طور پر، ہمارے پاس درج ذیل ڈیٹا ڈھانچے ہیں:

- لین دین

  ```json
  {
    prevHash: BD.types.buffer(20),
    prevBlock: BD.types.uint24le,
    tokenId: BD.types.string(null),
    type: BD.types.uint8,
    newOwner: BD.types.buffer(20),
    dataLength: BD.types.uint24le,
    data: BD.types.buffer(({current}) => current.dataLength),
    signature: BD.types.buffer(65),
    hash: BD.types.buffer(32),
    blockNumber: BD.types.uint24le,
    timestamp: BD.types.uint48le,
  }
  ```

- ٹوکن

  ```json
  {
    id: BD.types.string(null),
    owner: BD.types.buffer(20),
    block: BD.types.uint24le,
    amount: BD.types.string(null),
  }
  ```

- بلاک

  ```json
  {
    number: BD.types.uint24le,
    merkleRootHash: BD.types.buffer(32),
    signature: BD.types.buffer(65),
    countTx: BD.types.uint24le,
    transactions: BD.types.array(Transaction.Protocol, ({current}) => current.countTx),
    timestamp: BD.types.uint48le,
  }
  ```

معمول کی کمانڈز `BD.encode(block, Protocol).slice();` اور `BD.decode(buffer, Protocol)` کے ساتھ ہم ڈیٹا کو `Buffer` میں تبدیل کرتے ہیں تاکہ اسے Redis میں محفوظ کیا جا سکے یا اسے دوسرے نوڈ پر بھیج دیا جا سکے۔ ڈیٹا واپس حاصل کریں.

ہمارے پاس خدمات کے درمیان ڈیٹا کی منتقلی کے لیے 2 بائنری پروٹوکول بھی ہیں:

- یونکس ساکٹ کے ذریعے پلازما نوڈ کے ساتھ بات چیت کے لیے پروٹوکول

  ```json
  {
    type: BD.types.uint8,
    messageId: BD.types.uint24le,
    error: BD.types.uint8,
    length: BD.types.uint24le,
    payload: BD.types.buffer(({node}) => node.length)
  }
  ```

جہاں:

  • `ٹائپ`۔ - انجام دی جانی والی کارروائی، مثال کے طور پر، 1 - لین دین بھیجیں، 2 - لین دین حاصل کریں؛
  • `پے لوڈ` - متعلقہ فنکشن کو منتقل کرنے کے لیے ڈیٹا؛
  • `messageId` - پیغام کی شناخت تاکہ جواب کی شناخت کی جاسکے۔

- نوڈس کے درمیان تعامل کا پروٹوکول

  ```json
  {
    code: BD.types.uint8,
    versionProtocol: BD.types.uint24le,
    seq: BD.types.uint8,
    countChunk: BD.types.uint24le,
    chunkNumber: BD.types.uint24le,
    length: BD.types.uint24le,
    payload: BD.types.buffer(({node}) => node.length)
  }
  ```

جہاں:

  • `کوڈ` - پیغام کوڈ، مثال کے طور پر 6 - PREPARE_NEW_BLOCK، 7 - BLOCK_VALID، 8 - BLOCK_COMMIT؛
  • ورژن پروٹوکول - پروٹوکول ورژن، چونکہ مختلف ورژن والے نوڈس کو نیٹ ورک میں اٹھایا جا سکتا ہے اور وہ مختلف طریقے سے کام کر سکتے ہیں۔
  • `seq` - پیغام شناخت کنندہ؛
  • 'countChunk' и `chunkNumber` بڑے پیغامات کو تقسیم کرنے کے لیے ضروری؛
  • 'لمبائی' и `پے لوڈ` لمبائی اور ڈیٹا خود۔

چونکہ ہم نے ڈیٹا کو پہلے سے ٹائپ کیا ہے، اس لیے اختتامی نظام Ethereum کی `rlp` لائبریری سے کہیں زیادہ تیز ہے۔ بدقسمتی سے، ہم ابھی تک اسے ترک کرنے میں کامیاب نہیں ہو سکے ہیں، کیونکہ سمارٹ کنٹریکٹ کو حتمی شکل دینا ضروری ہے، جسے ہم مستقبل میں کرنے کا ارادہ رکھتے ہیں۔

اگر ہم رفتار تک پہنچنے میں کامیاب ہو گئے۔ 35 000 فی سیکنڈ کے لین دین، ہم بھی زیادہ سے زیادہ وقت میں ان پر کارروائی کرنے کی ضرورت ہے. چونکہ بلاک کی تشکیل کا تخمینی وقت 30 سیکنڈ ہے، ہمیں بلاک میں شامل کرنے کی ضرورت ہے۔ 1 000 000 لین دین، جس کا مطلب ہے مزید بھیجنا 100 ایم بی ڈیٹا۔

ابتدائی طور پر، ہم نے نوڈ کمیونیکیشن کے لیے `ethereumjs-devp2p` لائبریری کا استعمال کیا، لیکن یہ ڈیٹا کی مقدار کو ہینڈل نہیں کر سکا۔ نتیجے کے طور پر، ہم نے `ws` لائبریری کا استعمال کیا اور ویب ساکٹ کے ذریعے بائنری ڈیٹا کی منتقلی کو ترتیب دیا۔ یقیناً، ہمیں بڑے ڈیٹا پیکٹ بھیجتے وقت بھی مسائل کا سامنا کرنا پڑا، لیکن ہم نے انہیں ٹکڑوں میں تقسیم کر دیا اور اب ایسی کوئی پریشانی نہیں ہے۔

مرکل کے درخت کی تشکیل اور ہیش کیلکولیشن بھی 1 000 000 لین دین کے بارے میں کی ضرورت ہے 10 مسلسل کمپیوٹنگ کے سیکنڈ. اس وقت کے دوران، تمام نوڈس کے ساتھ کنکشن کو توڑنے کا وقت ہے. اس حساب کو الگ تھریڈ میں منتقل کرنے کا فیصلہ کیا گیا۔

نتیجہ:

درحقیقت، ہماری دریافتیں نئی ​​نہیں ہیں، لیکن کسی وجہ سے، بہت سے ماہرین ترقی کرتے وقت ان کے بارے میں بھول جاتے ہیں۔

  • آبجیکٹ اورینٹڈ پروگرامنگ کے بجائے فنکشنل پروگرامنگ کا استعمال کارکردگی کو بہتر بناتا ہے۔
  • پیداواری نوڈ جے ایس سسٹم کے لیے ایک یک سنگی سروس فن تعمیر سے بدتر ہے۔
  • ہیوی کمپیوٹیشن کے لیے `worker_threads` کا استعمال سسٹم کی ردعمل کو بہتر بناتا ہے، خاص طور پر i/o آپریشنز سے نمٹنے کے دوران۔
  • یونکس ساکٹ HTTP درخواستوں سے زیادہ مستحکم اور تیز ہے۔
  • اگر آپ کو نیٹ ورک پر بڑے ڈیٹا کو تیزی سے منتقل کرنے کی ضرورت ہے، تو بہتر ہے کہ ویب ساکٹس کا استعمال کریں اور بائنری ڈیٹا کو ٹکڑوں میں بھیجیں جو نہ پہنچنے کی صورت میں آگے بھیجے جائیں، اور پھر ایک پیغام میں جوڑ دیں۔

ہم آپ کو دورہ کرنے کی دعوت دیتے ہیں۔ GitHub کے پروجیکٹ: https://github.com/opporty-com/Plasma-Cash/tree/new-version

مضمون کے ساتھ مل کر لکھا گیا تھا۔ الیگزینڈر ناشیوان، سینئر ڈویلپر Clever Solution Inc..

ماخذ: www.habr.com

نیا تبصرہ شامل کریں