Ommaviy test: Ethereum-da maxfiylik va o'lchovlilik uchun yechim

Bloksan inson hayotining ko'plab sohalarini yaxshilashga va'da beradigan innovatsion texnologiyadir. U haqiqiy jarayonlar va mahsulotlarni raqamli makonga o'tkazadi, moliyaviy operatsiyalarning tezligi va ishonchliligini ta'minlaydi, ularning narxini pasaytiradi, shuningdek markazlashtirilmagan tarmoqlarda aqlli shartnomalar yordamida zamonaviy DAPP ilovalarini yaratishga imkon beradi.

Blokcheynning ko'plab afzalliklari va turli xil qo'llanilishini hisobga olsak, bu istiqbolli texnologiya hali har bir sohada o'z yo'lini yo'qotmaganligi ajablanarli tuyulishi mumkin. Muammo shundaki, zamonaviy markazlashtirilmagan blokcheynlarda miqyoslash imkoniyati yo'q. Ethereum sekundiga 20 ga yaqin tranzaktsiyalarni amalga oshiradi, bu bugungi dinamik biznes ehtiyojlarini qondirish uchun etarli emas. Shu bilan birga, blokcheyn texnologiyasidan foydalanadigan kompaniyalar Ethereumni xakerlik va tarmoqdagi nosozliklardan yuqori darajada himoyalanganligi sababli tark etishda ikkilanishadi.

Blockchain-da markazsizlashtirish, xavfsizlik va miqyosni ta'minlash, shu bilan Scalability Trilemma-ni hal qilish, ishlab chiqish guruhi Imkoniyat Node.js asosidagi aqlli shartnoma va xususiy tarmoqdan tashkil topgan Plazma Cash sho‘ba zanjiri yaratildi, u vaqti-vaqti bilan o‘z holatini ildiz zanjiriga (Ethereum) o‘tkazadi.

Ommaviy test: Ethereum-da maxfiylik va o'lchovlilik uchun yechim

Plazma naqd puldagi asosiy jarayonlar

1. Foydalanuvchi aqlli shartnoma funksiyasini "depozit" deb ataydi va unga Plazma Cash tokeniga kiritmoqchi bo'lgan ETH miqdorini o'tkazadi. Aqlli kontrakt funktsiyasi token yaratadi va u haqida voqea hosil qiladi.

2. Smart kontrakt voqealariga obuna bo'lgan Plazma Cash tugunlari depozit yaratish haqidagi voqeani oladi va hovuzga token yaratish bo'yicha tranzaksiyani qo'shadi.

3. Vaqti-vaqti bilan maxsus Plazma Cash tugunlari hovuzdan barcha operatsiyalarni (1 milliongacha) oladi va ulardan blok hosil qiladi, Merkle daraxtini va shunga mos ravishda xeshni hisoblab chiqadi. Bu blok tekshirish uchun boshqa tugunlarga yuboriladi. Tugunlar Merkle xeshi haqiqiyligini va tranzaktsiyalarning haqiqiyligini tekshiradi (masalan, token jo'natuvchisi uning egasimi yoki yo'qmi). Blokni tekshirgandan so'ng, tugun aqlli shartnomaning "submitBlock" funksiyasini chaqiradi, bu blok raqamini va Merkle xeshini chekka zanjirga saqlaydi. Aqlli shartnoma blokning muvaffaqiyatli qo'shilganligini ko'rsatadigan hodisani yaratadi. Tranzaktsiyalar hovuzdan olib tashlanadi.

4. Blokni topshirish hodisasini olgan tugunlar blokga qo'shilgan tranzaktsiyalarni qo'llashni boshlaydi.

5. Bir nuqtada, tokenning egasi (yoki egasi bo'lmagan) uni Plazma Cashdan olishni xohlaydi. Buning uchun u `startExit` funksiyasini chaqirib, unga tokenning egasi ekanligini tasdiqlovchi so`nggi 2 ta tranzaksiya haqidagi ma`lumotlarni uzatadi. Merkle xesh yordamida aqlli shartnoma bloklarda tranzaktsiyalar mavjudligini tekshiradi va ikki hafta ichida sodir bo'ladigan tokenni olib qo'yish uchun yuboradi.

6. Agar tokenni yechib olish operatsiyasi qoidabuzarliklar bilan yuz bergan bo‘lsa (token yechib olish jarayoni boshlanganidan keyin sarflangan yoki token yechib olingunga qadar boshqa birovniki bo‘lgan), token egasi ikki hafta ichida olib qo‘yishni rad etishi mumkin.

Ommaviy test: Ethereum-da maxfiylik va o'lchovlilik uchun yechim

Maxfiylik ikki yo'l bilan amalga oshiriladi

1. Ildiz zanjiri bolalar zanjirida yaratilgan va uzatiladigan tranzaktsiyalar haqida hech narsa bilmaydi. Plazma Cash-dan ETHni kim qo'ygani va olib qo'yganligi haqidagi ma'lumotlar ochiqligicha qolmoqda.

2. Bolalar zanjiri zk-SNARKs yordamida anonim tranzaktsiyalarni amalga oshirishga imkon beradi.

Texnologiya to'plami

  • NodeJS
  • Redis
  • Eteriy
  • Sild

Viktorina

Plazma Cashni ishlab chiqishda biz tizim tezligini sinab ko'rdik va quyidagi natijalarga erishdik:

  • hovuzga soniyada 35 000 tagacha tranzaksiya qo'shiladi;
  • blokda 1 000 000 tagacha tranzaktsiyalar saqlanishi mumkin.

Sinovlar quyidagi 3 ta serverda o'tkazildi:

1. Intel Core i7-6700 Quad-Core Skylake, shu jumladan. NVMe SSD – 512 GB, 64 GB DDR4 operativ xotira
3 ta tasdiqlovchi Plazma Cash tugunlari ko'tarildi.

2. AMD Ryzen 7 1700X sakkiz yadroli “Summit Ridge” (Zen), SATA SSD – 500 GB, 64 GB DDR4 operativ xotira
Ropsten testnet ETH tuguni ko'tarildi.
3 ta tasdiqlovchi Plazma Cash tugunlari ko'tarildi.

3. Intel Core i9-9900K Octa-Core, shu jumladan. NVMe SSD – 1 TB, 64 GB DDR4 operativ xotira
1 Plazma Naqd pul yuborish tugunlari ko'tarildi.
3 ta tasdiqlovchi Plazma Cash tugunlari ko'tarildi.
Plazma Cash tarmog'iga tranzaktsiyalarni qo'shish uchun sinov boshlandi.

Jami: Xususiy tarmoqdagi 10 ta Plazma Cash tugunlari.

Test 1

Bitta blok uchun 1 million tranzaksiya chegarasi mavjud. Shunday qilib, 1 million tranzaksiya 2 blokga to'g'ri keladi (chunki tizim tranzaktsiyalarning bir qismini oladi va ularni jo'natish paytida jo'natadi).


Dastlabki holat: oxirgi blok №7; Ma'lumotlar bazasida 1 million tranzaksiya va token saqlanadi.

00:00 — tranzaksiya yaratish skriptining boshlanishi
01:37 - 1 million tranzaksiya yaratildi va tugunga jo'natish boshlandi
01:46 — yuborish tuguni hovuzdan 240 ming tranzaksiya oldi va №8 blokni shakllantiradi. Shuningdek, biz 320 soniya ichida hovuzga 10 ming tranzaksiya qo'shilganini ko'ramiz
01:58 — №8 blok imzolandi va tasdiqlash uchun yuborildi
02:03 — №8 blok tasdiqlandi va aqlli shartnomaning “submitBlock” funksiyasi Merkle xesh va blok raqami bilan chaqiriladi.
02:10 — 1 soniya ichida 32 million tranzaksiya yuborgan demo-skript ishladi.
02:33 - tugunlar ildiz zanjiriga №8 blok qo'shilganligi haqida ma'lumot olishni boshladi va 240 ming tranzaksiyani amalga oshira boshladi.
02:40 - 240-blokda allaqachon mavjud bo'lgan hovuzdan 8 ming tranzaksiya olib tashlandi
02:56 — jo‘natish tuguni hovuzdan qolgan 760 ming tranzaksiyani oldi va Merkle xeshini va №9 imzo blokini hisoblashni boshladi.
03:20 - barcha tugunlarda 1 million 240 ming tranzaksiya va tokenlar mavjud
03:35 — №9 blok imzolanadi va tasdiqlash uchun boshqa tugunlarga yuboriladi
03:41 - tarmoq xatosi yuz berdi
04:40 — №9 blokni tekshirishni kutish vaqti tugadi
04:54 — jo‘natish tuguni hovuzdan qolgan 760 ming tranzaksiyani oldi va Merkle xeshini va №9 imzo blokini hisoblashni boshladi.
05:32 — №9 blok imzolanadi va tasdiqlash uchun boshqa tugunlarga yuboriladi
05:53 — №9 blok tasdiqlandi va ildiz zanjiriga yuborildi
06:17 - tugunlar ildiz zanjiriga №9 blok qo'shilganligi haqida ma'lumot olishni boshladi va 760 ming tranzaksiyani amalga oshira boshladi.
06:47 — hovuz 9-blokdagi tranzaksiyalardan tozalandi
09:06 - barcha tugunlarda 2 million tranzaksiya va token mavjud

Test 2

Har bir blok uchun 350 ming cheklov mavjud. Natijada bizda 3 ta blok bor.


Dastlabki holat: oxirgi blok №9; Ma'lumotlar bazasida 2 million tranzaksiya va token saqlanadi

00:00 — tranzaksiya yaratish skripti allaqachon ishga tushirilgan
00:44 - 1 million tranzaksiya yaratildi va tugunga jo'natish boshlandi
00:56 — yuborish tuguni hovuzdan 320 ming tranzaksiya oldi va №10 blokni shakllantiradi. Shuningdek, biz 320 soniya ichida hovuzga 10 ming tranzaksiya qo'shilganini ko'ramiz
01:12 — №10 blok imzolanadi va tekshirish uchun boshqa tugunlarga yuboriladi
01:18 — 1 soniya ichida 34 million tranzaksiya yuborgan demo-skript ishladi.
01:20 — №10 blok tasdiqlandi va ildiz zanjiriga yuborildi
01:51 - barcha tugunlar ildiz zanjiridan №10 blok qo'shilganligi haqida ma'lumot oldi va 320 ming tranzaksiyani qo'llashni boshladi.
02:01 - 320-blokga qo'shilgan 10 ming tranzaksiya uchun hovuz tozalandi
02:15 — jo‘natish tuguni hovuzdan 350 ming tranzaksiya oldi va №11 blokni shakllantiradi
02:34 — №11 blok imzolanadi va tekshirish uchun boshqa tugunlarga yuboriladi
02:51 — №11 blok tasdiqlandi va ildiz zanjiriga yuborildi
02:55 - oxirgi tugun №10 blokdan tranzaktsiyalarni yakunladi
10:59 — №9 blokni topshirish bilan tranzaksiya ildiz zanjirida juda uzoq davom etdi, ammo u yakunlandi va barcha tugunlar bu haqda maʼlumot oldi va 350 ming tranzaksiyani amalga oshira boshladi.
11:05 - 320-blokga qo'shilgan 11 ming tranzaksiya uchun hovuz tozalandi
12:10 - barcha tugunlarda 1 million 670 ming tranzaksiya va tokenlar mavjud
12:17 — jo‘natish tuguni hovuzdan 330 ming tranzaksiya oldi va №12 blokni shakllantiradi.
12:32 — №12 blok imzolanadi va tekshirish uchun boshqa tugunlarga yuboriladi
12:39 — №12 blok tasdiqlandi va ildiz zanjiriga yuborildi
13:44 - barcha tugunlar ildiz zanjiridan №12 blok qo'shilganligi haqida ma'lumot oldi va 330 ming tranzaksiyani qo'llashni boshladi.
14:50 - barcha tugunlarda 2 million tranzaksiya va token mavjud

Test 3

Birinchi va ikkinchi serverlarda bitta tasdiqlovchi tugun jo'natuvchi tugun bilan almashtirildi.


Dastlabki holat: oxirgi blok №84; 0 ta tranzaksiya va tokenlar maʼlumotlar bazasida saqlangan

00:00 — har biri 3 million tranzaksiya yaratuvchi va jo‘natuvchi 1 ta skript ishga tushirildi
01:38 — 1 million tranzaksiya yaratildi va №3 tugunga jo'natish boshlandi
01:50 — jo‘natish №3 tugun hovuzdan 330 ming tranzaksiya oldi va №85 (f21) blokini shakllantiradi. Shuningdek, biz 350 soniya ichida hovuzga 10 ming tranzaksiya qo'shilganini ko'ramiz
01:53 — 1 million tranzaksiya yaratildi va №1 tugunga jo'natish boshlandi
01:50 — jo‘natish №3 tugun hovuzdan 330 ming tranzaksiya oldi va №85 (f21) blokini shakllantiradi. Shuningdek, biz 350 soniya ichida hovuzga 10 ming tranzaksiya qo'shilganini ko'ramiz
02:01 — №1 tugun hovuzdan 250 ming tranzaksiya oldi va № 85 (65e) blokini yuboring
02:06 - blok № 85 (f21) imzolanadi va tekshirish uchun boshqa tugunlarga yuboriladi
02:08 — 3 soniya ichida 1 million tranzaksiya yuborgan №30 serverning demo-skripti ishladi.
02:14 — blok #85 (f21) tasdiqlandi va ildiz zanjiriga yuborildi
02:19 - blok № 85 (65e) imzolanadi va tekshirish uchun boshqa tugunlarga yuboriladi
02:22 — 1 million tranzaksiya yaratildi va №2 tugunga jo'natish boshlandi
02:27 - blok № 85 (65e) tasdiqlangan va ildiz zanjiriga yuborilgan
02:29 — jo‘natish №2 tugun hovuzdan 111855 ta tranzaksiyani oldi va №85 (256) blokni shakllantiradi.
02:36 - blok № 85 (256) imzolanadi va tasdiqlash uchun boshqa tugunlarga yuboriladi
02:36 — 1 soniya ichida 1 million tranzaksiya yuborgan №42.5 serverning demo-skripti ishladi.
02:38 — blok #85 (256) tasdiqlandi va ildiz zanjiriga yuborildi
03:08 — 2 soniya ichida 1 million tranzaksiya yuborgan №47 server skripti ishladi.
03:38 - barcha tugunlar №85 (f21), №86(65e), №87(256) bloklari qo'shilgan va 330k, 250k, 111855 tranzaksiyalarni qo'llashni boshlagan ildiz zanjiridan ma'lumot oldi.
03:49 - hovuz 330k, 250k, 111855 tranzaksiyada tozalandi, ular №85 (f21), №86(65e), №87(256) bloklariga qo'shildi.
03:59 — №1 submit tugun hovuzdan 888145 88 ta tranzaksiya oldi va № 214 (2) shakl bloki, 750-sonli submit tugun hovuzdan 88 ming tranzaksiya oldi va № 50 (3a) blok bloki, jo‘natish №670 tugunidan 88 ming tranzaksiya amalga oshirildi. hovuz va shakllar bloki №3 (dXNUMXb)
04:44 - blok № 88 (d3b) imzolanadi va tekshirish uchun boshqa tugunlarga yuboriladi
04:58 - blok № 88 (214) imzolanadi va tasdiqlash uchun boshqa tugunlarga yuboriladi
05:11 - blok № 88 (50a) imzolanadi va tekshirish uchun boshqa tugunlarga yuboriladi
05:11 — blok #85 (d3b) tasdiqlandi va ildiz zanjiriga yuborildi
05:36 — blok #85 (214) tasdiqlandi va ildiz zanjiriga yuborildi
05:43 - barcha tugunlar №88 (d3b), №89(214) bloklari qo'shilgan va 670k, 750k tranzaksiyalarni qo'llashni boshlagan ildiz zanjiridan ma'lumot oldi.
06:50 — aloqa uzilishi tufayli №85 blok (50a) tasdiqlanmadi
06:55 — jo‘natish №2 tugun hovuzdan 888145 ta tranzaksiyani oldi va №90 blok (50a) shakllar
08:14 - blok № 90 (50a) imzolanadi va tekshirish uchun boshqa tugunlarga yuboriladi
09:04 — blok #90 (50a) tasdiqlandi va ildiz zanjiriga yuborildi
11:23 - barcha tugunlar ildiz zanjiridan №90 (50a) blok qo'shilganligi haqida ma'lumot oldi va 888145 tranzaksiyani qo'llashni boshladi. Shu bilan birga, №3 server allaqachon №88 (d3b), №89(214) bloklaridan tranzaksiyalarni qo'llagan.
12:11 - barcha hovuzlar bo'sh
13:41 — №3 serverning barcha tugunlarida 3 million tranzaksiya va token mavjud
14:35 — №1 serverning barcha tugunlarida 3 million tranzaksiya va token mavjud
19:24 — №2 serverning barcha tugunlarida 3 million tranzaksiya va token mavjud

To'siqlar

Plazma Cash-ni ishlab chiqish jarayonida biz quyidagi muammolarga duch keldik, biz ularni asta-sekin hal qildik va hal qilyapmiz:

1. Turli tizim funktsiyalarining o'zaro ta'sirida ziddiyat. Misol uchun, pulga tranzaktsiyalarni qo'shish funktsiyasi bloklarni topshirish va tasdiqlash ishini blokladi va aksincha, bu tezlikni pasayishiga olib keldi.

2. Ma'lumot uzatish xarajatlarini minimallashtirgan holda juda ko'p miqdordagi tranzaktsiyalarni qanday jo'natish darhol aniq emas edi.

3. Yuqori natijalarga erishish uchun ma'lumotlarni qanday va qayerda saqlash kerakligi aniq emas edi.

4. Tugunlar orasidagi tarmoqni qanday tashkil qilish aniq emas edi, chunki 1 million tranzaksiyaga ega blokning o'lchami taxminan 100 MB ni tashkil qiladi.

5. Bir torli rejimda ishlash uzoq hisob-kitoblar sodir bo'lganda (masalan, Merkle daraxtini qurish va uning xeshini hisoblash) tugunlar orasidagi aloqani buzadi.

Bularning barchasini qanday hal qildik?

Plazma Cash tugunining birinchi versiyasi bir vaqtning o'zida hamma narsani bajarishi mumkin bo'lgan bir turdagi kombinat edi: tranzaktsiyalarni qabul qilish, bloklarni yuborish va tasdiqlash, ma'lumotlarga kirish uchun API taqdim etish. NodeJS asli bitta torli bo'lganligi sababli, og'ir Merkle daraxtini hisoblash funktsiyasi tranzaksiyani qo'shish funktsiyasini blokladi. Ushbu muammoni hal qilishning ikkita variantini ko'rdik:

1. Har biri o'ziga xos funktsiyalarni bajaradigan bir nechta NodeJS jarayonlarini ishga tushiring.

2. Worker_threads dan foydalaning va kodning bir qismi bajarilishini iplarga o'tkazing.

Natijada, biz ikkala variantni bir vaqtning o'zida ishlatdik: biz mantiqiy ravishda bitta tugunni alohida ishlashi mumkin bo'lgan 3 qismga ajratdik, lekin bir vaqtning o'zida sinxron tarzda.

1. Pulga tranzaktsiyalarni qabul qiladigan va bloklarni yaratadigan topshirish tugunlari.

2. Tugunlarning haqiqiyligini tekshiradigan tasdiqlovchi tugun.

3. API tuguni - ma'lumotlarga kirish uchun API taqdim etadi.

Bunday holda, cli-dan foydalanib, har bir tugunga unix soketi orqali ulanishingiz mumkin.

Biz Merkle daraxtini hisoblash kabi og'ir operatsiyalarni alohida ipga o'tkazdik.

Shunday qilib, biz barcha Plazma Cash funktsiyalarining bir vaqtning o'zida va nosozliklarsiz normal ishlashiga erishdik.

Tizim ishlagandan so'ng, biz tezlikni sinab ko'rishni boshladik va afsuski, qoniqarsiz natijalarni oldik: sekundiga 5 000 tranzaksiya va blok uchun 50 000 tranzaksiyagacha. Men nima noto'g'ri amalga oshirilganligini aniqlashim kerak edi.

Boshlash uchun biz tizimning eng yuqori imkoniyatlarini aniqlash uchun Plazma Cash bilan aloqa mexanizmini sinovdan o'tkaza boshladik. Biz avvalroq Plazma Cash tuguni unix soket interfeysini ta'minlaydi, deb yozgan edik. Dastlab u matnga asoslangan edi. json obyektlari `JSON.parse()` va `JSON.stringify()` yordamida yuborilgan.

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

Biz bunday ob'ektlarning uzatish tezligini o'lchadik va sekundiga ~ 130k ni topdik. Biz json bilan ishlash uchun standart funktsiyalarni almashtirishga harakat qildik, lekin ishlash yaxshilanmadi. V8 dvigateli ushbu operatsiyalar uchun yaxshi optimallashtirilgan bo'lishi kerak.

Biz darslar orqali tranzaktsiyalar, tokenlar va bloklar bilan ishladik. Bunday sinflarni yaratishda ishlash 2 baravar kamaydi, bu OOP biz uchun mos emasligini ko'rsatadi. Men hamma narsani sof funktsional yondashuvga qayta yozishim kerak edi.

Ma'lumotlar bazasiga yozib olish

Dastlab, Redis ma'lumotlarni saqlash uchun bizning talablarimizni qondiradigan eng samarali echimlardan biri sifatida tanlandi: kalit-qiymatni saqlash, xesh-jadvallar, to'plamlar bilan ishlash. Biz redis-benchmarkni ishga tushirdik va 80 quvur liniyasi rejimida sekundiga ~1k operatsiya oldik.

Yuqori samaradorlik uchun biz Redisni yanada yaxshi sozladik:

  • Unix soket ulanishi o'rnatildi.
  • Biz holatni diskda saqlashni o'chirib qo'ydik (ishonchliligi uchun siz replika o'rnatishingiz va diskda alohida Redis-da saqlashingiz mumkin).

Redis-da hovuz xesh-jadvaldir, chunki biz bitta so'rovda barcha tranzaksiyalarni olishimiz va tranzaktsiyalarni birma-bir o'chirishimiz kerak. Biz oddiy ro'yxatni ishlatishga harakat qildik, lekin butun ro'yxatni o'chirishda u sekinroq.

Standart NodeJS dan foydalanganda Redis kutubxonalari soniyasiga 18 ming tranzaksiyaga erishdi. Tezlik 9 marta kamaydi.

Benchmark bizga imkoniyatlar 5 baravar katta ekanligini ko'rsatganligi sababli, biz optimallashtirishni boshladik. Biz kutubxonani ioredisga o'zgartirdik va soniyada 25k ishlashga erishdik. Biz "hset" buyrug'i yordamida tranzaktsiyalarni birma-bir qo'shdik. Shunday qilib, biz Redis-da juda ko'p so'rovlarni yaratdik. Tranzaktsiyalarni partiyalarga birlashtirish va ularni bitta "hmset" buyrug'i bilan yuborish g'oyasi paydo bo'ldi. Natijada soniyasiga 32k.

Quyida tasvirlab beradigan bir qancha sabablarga ko‘ra biz ma’lumotlar bilan “Bufer” yordamida ishlaymiz va ma’lum bo‘lishicha, agar siz uni yozishdan oldin matnga (‘buffer.toString(‘hex’)) aylantirsangiz, qo‘shimcha ma’lumotlarni olishingiz mumkin. ishlash. Shunday qilib, tezlik sekundiga 35k ga oshirildi. Ayni paytda biz keyingi optimallashtirishni to'xtatishga qaror qildik.

Ikkilik protokolga o'tishimiz kerak edi, chunki:

1. Tizim ko'pincha xeshlarni, imzolarni va hokazolarni hisoblab chiqadi va buning uchun "Bufer"dagi ma'lumotlar kerak.

2. Xizmatlar o'rtasida yuborilganda, ikkilik ma'lumotlar matndan kamroq og'irlik qiladi. Misol uchun, 1 million tranzaksiyaga ega blokni jo'natishda matndagi ma'lumotlar 300 megabaytdan ortiqni egallashi mumkin.

3. Doimiy ravishda ma'lumotlarni o'zgartirish ishlashga ta'sir qiladi.

Shuning uchun biz ajoyib "ikkilik ma'lumotlar" kutubxonasi asosida ishlab chiqilgan ma'lumotlarni saqlash va uzatish uchun o'zimizning ikkilik protokolimizni asos qilib oldik.

Natijada biz quyidagi ma'lumotlar tuzilmalarini oldik:

- Tranzaksiya

  ```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,
  }
  ```

- Token

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

- Blok

  ```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,
  }
  ```

Odatdagidek `BD.encode(block, Protocol).slice();` va `BD.decode(bufer, Protocol)` buyruqlari yordamida biz Redis-da saqlash yoki boshqa tugunga yoʻnaltirish va maʼlumotlarni olish uchun maʼlumotlarni “Bufer”ga aylantiramiz. ma'lumotlarni qaytarish.

Shuningdek, bizda xizmatlar o'rtasida ma'lumotlarni uzatish uchun ikkita ikkilik protokollar mavjud:

— Unix rozetkasi orqali Plazma tugun bilan o'zaro ishlash protokoli

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

qaerda:

  • `turi` — bajariladigan harakat, masalan, 1 — sendTransaction, 2 — getTransaction;
  • `foydali yuk` — tegishli funktsiyaga uzatilishi kerak bo'lgan ma'lumotlar;
  • `xabar identifikatori` — javobni aniqlash uchun xabar identifikatori.

— Tugunlar orasidagi o'zaro ta'sir protokoli

  ```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)
  }
  ```

qaerda:

  • `kod` — xabar kodi, masalan 6 — PREPARE_NEW_BLOCK, 7 — BLOCK_VALID, 8 — BLOCK_COMMIT;
  • `versiya Protocol` — protokol versiyasi, chunki tarmoqda turli versiyalarga ega tugunlar ko'tarilishi mumkin va ular boshqacha ishlashi mumkin;
  • `seq` — xabar identifikatori;
  • 'countChunk' и "bo'lak raqami" katta xabarlarni bo'lish uchun zarur;
  • `uzunlik` и `foydali yuk` uzunligi va ma'lumotlarning o'zi.

Biz ma'lumotlarni oldindan yozganimiz sababli, yakuniy tizim Ethereumning "rlp" kutubxonasiga qaraganda ancha tezroq. Afsuski, biz hali buni rad eta olmadik, chunki kelajakda amalga oshirishni rejalashtirgan aqlli shartnomani yakunlash kerak.

Agar biz tezlikka erisha olsak 35 000 soniyada tranzaktsiyalar, biz ham ularni optimal vaqtda qayta ishlashimiz kerak. Taxminan blokni shakllantirish vaqti 30 soniya davom etganligi sababli, biz blokga kiritishimiz kerak 1 000 000 tranzaktsiyalar, bu ko'proq yuborishni anglatadi 100 MB ma'lumot.

Dastlab, biz tugunlar o'rtasida muloqot qilish uchun "ethereumjs-devp2p" kutubxonasidan foydalanganmiz, ammo u juda ko'p ma'lumotlarni ishlata olmadi. Natijada, biz `ws` kutubxonasidan foydalandik va websocket orqali ikkilik ma`lumotlarni yuborishni sozladik. Albatta, biz katta ma'lumotlar paketlarini yuborishda ham muammolarga duch keldik, lekin biz ularni bo'laklarga ajratdik va endi bu muammolar yo'qoldi.

Shuningdek, Merkle daraxtini shakllantirish va hashni hisoblash 1 000 000 operatsiyalar haqida talab qiladi 10 sekund uzluksiz hisoblash. Bu vaqt ichida barcha tugunlar bilan aloqa uzilib qoladi. Ushbu hisobni alohida mavzuga o'tkazishga qaror qilindi.

Natijalar:

Aslida, bizning topilmalarimiz yangi emas, lekin negadir ko'plab mutaxassislar ishlab chiqishda ular haqida unutishadi.

  • Ob'ektga yo'naltirilgan dasturlash o'rniga Funktsional dasturlashdan foydalanish samaradorlikni oshiradi.
  • Monolit samarali NodeJS tizimi uchun xizmat arxitekturasidan ham yomonroq.
  • Og'ir hisoblash uchun "worker_threads" dan foydalanish tizimning javob berish qobiliyatini yaxshilaydi, ayniqsa kiritish/chiqarish operatsiyalari bilan ishlashda.
  • unix soket http so'rovlariga qaraganda ancha barqaror va tezroq.
  • Agar siz tarmoq orqali katta hajmdagi ma'lumotlarni tezda uzatishingiz kerak bo'lsa, veb-rozetkalardan foydalanish va ikkilik ma'lumotlarni yuborish yaxshiroqdir, bo'laklarga bo'linadi, agar ular kelmasa, yo'naltirilishi mumkin, keyin esa bitta xabarga birlashtiriladi.

Sizni tashrif buyurishga taklif qilamiz GitHub loyiha: https://github.com/opporty-com/Plasma-Cash/tree/new-version

Maqola bilan hamkorlikda yozilgan Aleksandr Nashivan, katta dasturchi Clever Solution Inc.

Manba: www.habr.com

a Izoh qo'shish