Verejný test: Riešenie pre ochranu súkromia a škálovateľnosť na Ethereu

Blockchain je inovatívna technológia, ktorá sľubuje zlepšenie mnohých oblastí ľudského života. Prenáša reálne procesy a produkty do digitálneho priestoru, zaisťuje rýchlosť a spoľahlivosť finančných transakcií, znižuje ich náklady a tiež umožňuje vytvárať moderné aplikácie DAPP pomocou smart kontraktov v decentralizovaných sieťach.

Vzhľadom na mnohé výhody a rôznorodé aplikácie blockchainu sa môže zdať prekvapujúce, že táto sľubná technológia sa ešte nedostala do každého odvetvia. Problémom je, že moderným decentralizovaným blockchainom chýba škálovateľnosť. Ethereum spracuje približne 20 transakcií za sekundu, čo nestačí na uspokojenie potrieb dnešných dynamických podnikov. Spoločnosti využívajúce technológiu blockchain zároveň váhajú s opustením Etherea kvôli jeho vysokému stupňu ochrany pred hackermi a zlyhaniami siete.

Vývojový tím zaisťuje decentralizáciu, bezpečnosť a škálovateľnosť v blockchaine, čím rieši Trilemu škálovateľnosti Príležitosť vytvoril Plasma Cash, dcérsky reťazec pozostávajúci z inteligentnej zmluvy a súkromnej siete založenej na Node.js, ktorá pravidelne prenáša svoj stav do koreňového reťazca (Ethereum).

Verejný test: Riešenie pre ochranu súkromia a škálovateľnosť na Ethereu

Kľúčové procesy v plazmovej hotovosti

1. Používateľ zavolá funkciu inteligentnej zmluvy `vklad` a odovzdá do nej množstvo ETH, ktoré chce vložiť do tokenu Plasma Cash. Funkcia inteligentnej zmluvy vytvorí token a vygeneruje o ňom udalosť.

2. Plazmové hotovostné uzly prihlásené na udalosti inteligentnej zmluvy dostanú udalosť o vytvorení vkladu a pridajú transakciu o vytvorení tokenu do fondu.

3. Špeciálne uzly Plasma Cash pravidelne odoberajú všetky transakcie z fondu (až do 1 milióna) a tvoria z nich blok, vypočítavajú strom Merkle a podľa toho aj hash. Tento blok sa odošle do iných uzlov na overenie. Uzly kontrolujú, či je Merkle hash platný a či sú transakcie platné (napríklad, či je odosielateľ tokenu jeho vlastníkom). Po overení bloku uzol zavolá funkciu `submitBlock` smart kontraktu, ktorá uloží číslo bloku a Merkle hash do okrajového reťazca. Inteligentná zmluva generuje udalosť označujúcu úspešné pridanie bloku. Transakcie sú odstránené z fondu.

4. Uzly, ktoré prijmú udalosť odoslania bloku, začnú aplikovať transakcie, ktoré boli pridané do bloku.

5. V určitom okamihu vlastník (alebo nevlastník) tokenu ho chce stiahnuť z Plasma Cash. Za týmto účelom zavolá funkciu `startExit` a odovzdá do nej informácie o posledných 2 transakciách na tokene, ktoré potvrdzujú, že je vlastníkom tokenu. Inteligentná zmluva pomocou Merkle hash skontroluje prítomnosť transakcií v blokoch a odošle token na výber, ktorý sa uskutoční o dva týždne.

6. Ak k operácii výberu tokenu došlo s porušeniami (token bol vyčerpaný po začatí postupu výberu alebo token už pred výberom patril niekomu inému), vlastník tokenu môže výber odmietnuť do dvoch týždňov.

Verejný test: Riešenie pre ochranu súkromia a škálovateľnosť na Ethereu

Súkromie sa dosahuje dvoma spôsobmi

1. Koreňový reťazec nevie nič o transakciách, ktoré sa generujú a preposielajú v rámci podriadeného reťazca. Informácie o tom, kto vložil a vybral ETH z Plasma Cash, zostávajú verejné.

2. Podradený reťazec umožňuje anonymné transakcie pomocou zk-SNARK.

Zásobník technológií

  • NodeJS
  • Redis
  • Etherium
  • zašpinené

Testovanie

Pri vývoji Plasma Cash sme testovali rýchlosť systému a získali nasledujúce výsledky:

  • do fondu sa pridá až 35 000 transakcií za sekundu;
  • do bloku je možné uložiť až 1 000 000 transakcií.

Testy boli vykonané na nasledujúcich 3 serveroch:

1. Intel Core i7-6700 Quad-Core Skylake vrát. NVMe SSD – 512 GB, 64 GB DDR4 RAM
Zvýšili sa 3 validujúce plazmové hotovostné uzly.

2. AMD Ryzen 7 1700X Octa-Core „Summit Ridge“ (Zen), SATA SSD – 500 GB, 64 GB DDR4 RAM
Uzol ETH testovacej siete Ropsten bol zdvihnutý.
Zvýšili sa 3 validujúce plazmové hotovostné uzly.

3. Intel Core i9-9900K Octa-Core vr. NVMe SSD – 1 TB, 64 GB DDR4 RAM
1 Plazmový uzol odovzdania hotovosti bol zdvihnutý.
Zvýšili sa 3 validujúce plazmové hotovostné uzly.
Bol spustený test pridávania transakcií do siete Plasma Cash.

Celkom: 10 Plazmových hotovostných uzlov v súkromnej sieti.

Test 1

Existuje limit 1 milión transakcií na blok. Preto 1 milión transakcií spadá do 2 blokov (keďže systém zvláda časť transakcií prebrať a odoslať počas ich odosielania).


Počiatočný stav: posledný blok #7; V databáze je uložených 1 milión transakcií a tokenov.

00:00 — začiatok skriptu generovania transakcie
01:37 - Vytvorilo sa 1 milión transakcií a začalo sa odosielanie do uzla
01:46 — odoslaný uzol prevzal 240 8 transakcií z fondu a bloku formulárov č. 320. Tiež vidíme, že 10 XNUMX transakcií sa pridá do fondu za XNUMX sekúnd
01:58 — blok #8 je podpísaný a odoslaný na overenie
02:03 — blok #8 je overený a funkcia `submitBlock` inteligentnej zmluvy je zavolaná s Merkleovým hashom a číslom bloku
02:10 — skončil funkčný demo skript, ktorý odoslal 1 milión transakcií za 32 sekúnd
02:33 - uzly začali dostávať informácie, že blok #8 bol pridaný do koreňového reťazca, a začali vykonávať 240 XNUMX transakcií
02:40 – Z fondu bolo odstránených 240 8 transakcií, ktoré sú už v bloku č. XNUMX
02:56 — Uzol odoslania zobral zvyšných 760 9 transakcií z fondu a začal počítať Merkle hash a podpisový blok #XNUMX
03:20 - všetky uzly obsahujú 1 milión 240 XNUMX transakcií a tokenov
03:35 — blok #9 je podpísaný a odoslaný na overenie do iných uzlov
03:41 - vyskytla sa chyba siete
04:40 — čakanie na potvrdenie bloku č. 9 vypršalo
04:54 — Uzol odoslania zobral zvyšných 760 9 transakcií z fondu a začal počítať Merkle hash a podpisový blok #XNUMX
05:32 — blok #9 je podpísaný a odoslaný na overenie do iných uzlov
05:53 — blok #9 je overený a odoslaný do koreňového reťazca
06:17 - uzly začali dostávať informácie, že blok #9 bol pridaný do koreňového reťazca a začali vykonávať 760 XNUMX transakcií
06:47 — fond sa vyčistil od transakcií, ktoré sú v bloku #9
09:06 - všetky uzly obsahujú 2 milióny transakcií a tokenov

Test 2

Limit je 350 tisíc na blok. V dôsledku toho máme 3 bloky.


Počiatočný stav: posledný blok #9; V databáze sú uložené 2 milióny transakcií a tokenov

00:00 — skript generovania transakcií už bol spustený
00:44 - Vytvorilo sa 1 milión transakcií a začalo sa odosielanie do uzla
00:56 — odoslaný uzol prevzal 320 10 transakcií z fondu a bloku formulárov č. 320. Tiež vidíme, že 10 XNUMX transakcií sa pridá do fondu za XNUMX sekúnd
01:12 — blok #10 je podpísaný a odoslaný do iných uzlov na overenie
01:18 — skončil funkčný demo skript, ktorý odoslal 1 milión transakcií za 34 sekúnd
01:20 — blok #10 je overený a odoslaný do koreňového reťazca
01:51 - všetky uzly dostali informácie z koreňového reťazca, že bol pridaný blok #10 a začali aplikovať 320 XNUMX transakcií
02:01 - fond sa vyčistil pre 320 10 transakcií, ktoré boli pridané do bloku #XNUMX
02:15 — Uzol odoslania prevzal 350 11 transakcií z fondu a bloku formulárov č. XNUMX
02:34 — blok #11 je podpísaný a odoslaný do iných uzlov na overenie
02:51 — blok #11 je overený a odoslaný do koreňového reťazca
02:55 — posledný uzol dokončil transakcie z bloku #10
10:59 — transakcia s odoslaním bloku #9 trvala v koreňovom reťazci veľmi dlho, ale bola dokončená a všetky uzly o nej dostali informácie a začali vykonávať 350 XNUMX transakcií
11:05 - fond sa vyčistil pre 320 11 transakcií, ktoré boli pridané do bloku #XNUMX
12:10 - všetky uzly obsahujú 1 milión 670 XNUMX transakcií a tokenov
12:17 — odoslaný uzol prevzal 330 12 transakcií z bloku a formulárov č. XNUMX
12:32 — blok #12 je podpísaný a odoslaný do iných uzlov na overenie
12:39 — blok #12 je overený a odoslaný do koreňového reťazca
13:44 - všetky uzly dostali informácie z koreňového reťazca, že bol pridaný blok č. 12 a začali aplikovať 330 XNUMX transakcií
14:50 - všetky uzly obsahujú 2 milióny transakcií a tokenov

Test 3

V prvom a druhom serveri bol jeden overovací uzol nahradený odosielajúcim uzlom.


Počiatočný stav: posledný blok #84; 0 transakcií a tokenov uložených v databáze

00:00 — Boli spustené 3 skripty, z ktorých každý generuje a odosiela 1 milión transakcií
01:38 — Vytvorilo sa 1 milión transakcií a začalo sa odosielanie do uzla č. 3 na odoslanie
01:50 — odoslaný uzol #3 prevzal 330 85 transakcií z fondu a bloku formulárov #21 (f350). Tiež vidíme, že 10 XNUMX transakcií sa pridá do fondu za XNUMX sekúnd
01:53 — Vytvorilo sa 1 milión transakcií a začalo sa odosielanie do uzla č. 1 na odoslanie
01:50 — odoslaný uzol #3 prevzal 330 85 transakcií z fondu a bloku formulárov #21 (f350). Tiež vidíme, že 10 XNUMX transakcií sa pridá do fondu za XNUMX sekúnd
02:01 — odoslať uzol č. 1 prevzal 250 85 transakcií z fondu a bloku formulárov č. 65 (XNUMXe)
02:06 — blok #85 (f21) je podpísaný a odoslaný do iných uzlov na overenie
02:08 — demo skript servera #3, ktorý odoslal 1 milión transakcií za 30 sekúnd, skončil
02:14 — blok #85 (f21) je overený a odoslaný do koreňového reťazca
02:19 — blok #85 (65e) je podpísaný a odoslaný do iných uzlov na overenie
02:22 — Vytvorilo sa 1 milión transakcií a začalo sa odosielanie do uzla č. 2 na odoslanie
02:27 — blok #85 (65e) overený a odoslaný do koreňového reťazca
02:29 — uzol odoslania č. 2 prevzal 111855 85 transakcií z bloku a bloku formulárov č. 256 (XNUMX).
02:36 — blok #85 (256) je podpísaný a odoslaný do iných uzlov na overenie
02:36 — demo skript servera #1, ktorý odoslal 1 milión transakcií za 42.5 sekúnd, skončil
02:38 — blok #85 (256) je overený a odoslaný do koreňového reťazca
03:08 — Skript servera #2 dokončil prácu, ktorá odoslala 1 milión transakcií za 47 sekúnd
03:38 - všetky uzly dostali informácie z koreňového reťazca, že boli pridané bloky #85 (f21), #86(65e), #87(256) a začali uplatňovať 330k, 250k, 111855 transakcií
03:49 - fond bol vymazaný pri 330 250, 111855 85, 21 86 transakciách, ktoré boli pridané do blokov #65 (f87), #256(XNUMXe), #XNUMX(XNUMX)
03:59 — odoslanie uzla č. 1 prevzalo 888145 88 transakcií zo skupiny a bloku formulárov č. 214 (2), odoslanie uzla č. 750 prevzalo 88 50 transakcií z fondu a bloku formulárov č. 3 (670a), odoslanie uzla č. 88 prevzalo 3 XNUMX transakcií z blok a formuláre blok #XNUMX (dXNUMXb)
04:44 — blok #88 (d3b) je podpísaný a odoslaný do iných uzlov na overenie
04:58 — blok #88 (214) je podpísaný a odoslaný do iných uzlov na overenie
05:11 — blok #88 (50a) je podpísaný a odoslaný do iných uzlov na overenie
05:11 — blok #85 (d3b) je overený a odoslaný do koreňového reťazca
05:36 — blok #85 (214) je overený a odoslaný do koreňového reťazca
05:43 - všetky uzly dostali informácie z koreňového reťazca, že boli pridané bloky #88 (d3b), #89(214) a začínajú uplatňovať 670 750, XNUMX XNUMX transakcií
06:50 — z dôvodu zlyhania komunikácie nebol potvrdený blok #85 (50a).
06:55 — odoslaný uzol č. 2 prevzal 888145 90 transakcií z bloku a formulárov č. 50 (XNUMXa)
08:14 — blok #90 (50a) je podpísaný a odoslaný do iných uzlov na overenie
09:04 — blok #90 (50a) je overený a odoslaný do koreňového reťazca
11:23 - všetky uzly dostali informácie z koreňového reťazca, že bol pridaný blok #90 (50a), a začali aplikovať 888145 transakcií. Zároveň server #3 už aplikoval transakcie z blokov #88 (d3b), #89(214)
12:11 - všetky bazény sú prázdne
13:41 — všetky uzly servera #3 obsahujú 3 milióny transakcií a tokenov
14:35 — všetky uzly servera #1 obsahujú 3 milióny transakcií a tokenov
19:24 — všetky uzly servera #2 obsahujú 3 milióny transakcií a tokenov

Prekážky

Pri vývoji Plasma Cash sme sa stretli s nasledujúcimi problémami, ktoré sme postupne riešili a riešime:

1. Konflikt v interakcii rôznych funkcií systému. Napríklad funkcia pridávania transakcií do fondu blokovala prácu pri odosielaní a overovaní blokov a naopak, čo viedlo k poklesu rýchlosti.

2. Bezprostredne nebolo jasné, ako odoslať obrovské množstvo transakcií a zároveň minimalizovať náklady na prenos dát.

3. Nebolo jasné, ako a kde ukladať dáta, aby sa dosiahli vysoké výsledky.

4. Nebolo jasné, ako organizovať sieť medzi uzlami, pretože veľkosť bloku s 1 miliónom transakcií zaberá asi 100 MB.

5. Práca v režime s jedným vláknom preruší spojenie medzi uzlami, keď sa vyskytnú dlhé výpočty (napríklad zostavenie stromu Merkle a výpočet jeho hash).

Ako sme sa s tým všetkým vysporiadali?

Prvá verzia uzla Plasma Cash bola akýmsi kombajnom, ktorý dokázal robiť všetko súčasne: prijímať transakcie, odosielať a overovať bloky a poskytovať API na prístup k údajom. Keďže NodeJS je natívne jednovláknový, funkcia výpočtu stromu Merkle zablokovala funkciu pridania transakcie. Videli sme dve možnosti riešenia tohto problému:

1. Spustite niekoľko procesov NodeJS, z ktorých každý vykonáva špecifické funkcie.

2. Použite worker_threads a presuňte vykonávanie časti kódu do vlákien.

V dôsledku toho sme použili obe možnosti súčasne: jeden uzol sme logicky rozdelili na 3 časti, ktoré môžu pracovať oddelene, ale súčasne synchrónne

1. Uzol odoslania, ktorý prijíma transakcie do fondu a vytvára bloky.

2. Overovací uzol, ktorý kontroluje platnosť uzlov.

3. Uzol API – poskytuje API pre prístup k údajom.

V tomto prípade sa môžete ku každému uzlu pripojiť cez unixovú zásuvku pomocou cli.

Ťažké operácie, ako napríklad výpočet Merkleho stromu, sme presunuli do samostatného vlákna.

Takto sme dosiahli normálnu prevádzku všetkých funkcií Plasma Cash súčasne a bez porúch.

Keď bol systém funkčný, začali sme testovať rýchlosť a bohužiaľ sme dostali neuspokojivé výsledky: 5 000 transakcií za sekundu a až 50 000 transakcií na blok. Musel som prísť na to, čo bolo implementované nesprávne.

Na začiatok sme začali testovať mechanizmus komunikácie s Plasma Cash, aby sme zistili špičkovú kapacitu systému. Už sme napísali, že uzol Plasma Cash poskytuje rozhranie soketu unix. Spočiatku to bolo založené na texte. Objekty json boli odoslané pomocou `JSON.parse()` a `JSON.stringify()`.

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

Zmerali sme prenosovú rýchlosť takýchto objektov a zistili sme ~ 130 k za sekundu. Snažili sme sa nahradiť štandardné funkcie pre prácu s json, ale výkon sa nezlepšil. Motor V8 musí byť na tieto operácie dobre optimalizovaný.

Pracovali sme s transakciami, tokenmi a blokmi prostredníctvom tried. Pri vytváraní takýchto tried výkon klesol 2-krát, čo naznačuje, že OOP nie je pre nás vhodný. Všetko som musel prepísať na čisto funkčný prístup.

Záznam do databázy

Spočiatku bol Redis vybraný pre ukladanie dát ako jedno z najproduktívnejších riešení, ktoré spĺňa naše požiadavky: úložisko kľúč-hodnota, práca s hašovacími tabuľkami, množinami. Spustili sme redis-benchmark a získali sme ~ 80 1 operácií za sekundu v XNUMX pipeline režime.

Pre vysoký výkon sme Redis vyladili jemnejšie:

  • Bolo vytvorené pripojenie soketu unix.
  • Zakázali sme ukladanie stavu na disk (pre spoľahlivosť si môžete nastaviť repliku a uložiť na disk v samostatnom Redis).

V Redis je fond hašovacia tabuľka, pretože musíme byť schopní získať všetky transakcie v jednom dotaze a odstrániť transakcie jednu po druhej. Pokúsili sme sa použiť bežný zoznam, ale pri uvoľňovaní celého zoznamu je to pomalšie.

Pri použití štandardného NodeJS dosiahli knižnice Redis výkon 18 9 transakcií za sekundu. Rýchlosť klesla XNUMX-krát.

Keďže nám benchmark ukázal, že možnosti boli jednoznačne 5-krát väčšie, začali sme s optimalizáciou. Zmenili sme knižnicu na ioredis a dosiahli sme výkon 25 k za sekundu. Transakcie sme pridávali jednu po druhej pomocou príkazu `hset`. V Redis sme teda generovali veľa dopytov. Vznikol nápad spojiť transakcie do dávok a odoslať ich jedným príkazom `hmset`. Výsledkom je 32 XNUMX za sekundu.

Z niekoľkých dôvodov, ktoré popíšeme nižšie, pracujeme s údajmi pomocou `Buffer` a ako sa ukázalo, ak ich pred zápisom skonvertujete na text (`buffer.toString('hex')`), môžete získať ďalšie výkon. Rýchlosť sa tak zvýšila na 35 XNUMX za sekundu. Momentálne sme sa rozhodli pozastaviť ďalšiu optimalizáciu.

Museli sme prejsť na binárny protokol, pretože:

1. Systém často počíta hashe, podpisy atď., a na to potrebuje údaje vo vyrovnávacej pamäti.

2. Pri odosielaní medzi službami vážia binárne dáta menej ako text. Napríklad pri odoslaní bloku s 1 miliónom transakcií môžu dáta v texte zabrať viac ako 300 megabajtov.

3. Neustále transformovanie údajov ovplyvňuje výkon.

Preto sme za základ vzali náš vlastný binárny protokol na ukladanie a prenos údajov, vyvinutý na základe úžasnej knižnice „binárnych údajov“.

V dôsledku toho sme dostali nasledujúce dátové štruktúry:

—Transakcia

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

— Blokovať

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

Pomocou zvyčajných príkazov `BD.encode(block, Protocol).slice();` a `BD.decode(buffer, Protocol)` konvertujeme dáta do `Buffer` na uloženie v Redis alebo presmerovanie do iného uzla a načítanie dáta späť.

Máme tiež 2 binárne protokoly na prenos údajov medzi službami:

— Protokol pre interakciu s Plasma Node cez unixovú zásuvku

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

kde:

  • `type` — akcia, ktorá sa má vykonať, napríklad 1 — sendTransaction, 2 — getTransaction;
  • „užitočné zaťaženie“. — údaje, ktoré je potrebné odovzdať príslušnej funkcii;
  • „ID správy“. — ID správy, aby bolo možné identifikovať odpoveď.

— Protokol pre interakciu medzi uzlami

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

kde:

  • „kód“. — kód správy, napríklad 6 — PREPARE_NEW_BLOCK, 7 — BLOCK_VALID, 8 — BLOCK_COMMIT;
  • `versionProtocol` — verzia protokolu, pretože uzly s rôznymi verziami môžu byť vytvorené v sieti a môžu pracovať odlišne;
  • „sekv“. — identifikátor správy;
  • `countChunk` и `chunkNumber` potrebné na rozdelenie veľkých správ;
  • "dĺžka". и „užitočné zaťaženie“. dĺžka a samotné údaje.

Keďže sme údaje vopred napísali, konečný systém je oveľa rýchlejší ako knižnica `rlp` Ethereum. Žiaľ, zatiaľ sa nám to nepodarilo odmietnuť, keďže je potrebné dopracovať smart kontrakt, čo plánujeme urobiť v budúcnosti.

Ak sa nám podarilo dosiahnuť rýchlosť 35 000 transakcií za sekundu, musíme ich tiež spracovať v optimálnom čase. Keďže približný čas vytvorenia bloku trvá 30 sekúnd, musíme do bloku zahrnúť 1 000 000 transakcií, čo znamená posielať viac 100 MB údajov.

Spočiatku sme na komunikáciu medzi uzlami používali knižnicu `ethereumjs-devp2p`, ale nedokázala spracovať toľko údajov. V dôsledku toho sme použili knižnicu `ws` a nakonfigurovali odosielanie binárnych údajov cez websocket. Samozrejme, že sme sa stretli aj s problémami pri odosielaní veľkých dátových paketov, no rozdelili sme ich na časti a teraz sú tieto problémy preč.

Tiež vytvorenie stromu Merkle a výpočet hashu 1 000 000 transakcií vyžaduje o 10 sekúnd nepretržitého výpočtu. Počas tejto doby sa spojenie so všetkými uzlami podarí prerušiť. Bolo rozhodnuté presunúť tento výpočet do samostatného vlákna.

Závery:

V skutočnosti naše zistenia nie sú nové, no z nejakého dôvodu na ne mnohí odborníci pri vývoji zabúdajú.

  • Používanie funkčného programovania namiesto objektovo orientovaného programovania zvyšuje produktivitu.
  • Monolit je horší ako architektúra služieb pre produktívny systém NodeJS.
  • Použitie `worker_threads` pre náročné výpočty zlepšuje odozvu systému, najmä pri práci s I/O operáciami.
  • unixový socket je stabilnejší a rýchlejší ako požiadavky http.
  • Ak potrebujete rýchlo preniesť veľké dáta cez sieť, je lepšie použiť websockets a posielať binárne dáta, rozdelené na časti, ktoré je možné preposlať, ak neprídu, a následne spojiť do jednej správy.

Pozývame vás na návštevu GitHub projekt: https://github.com/opporty-com/Plasma-Cash/tree/new-version

Článok bol spoluautorom Alexander Nashivan, senior developer Spoločnosť Clever Solution Inc.

Zdroj: hab.com

Pridať komentár