Publisks tests: Ethereum privātuma un mērogojamības risinājums

Blokķēde ir inovatÄ«va tehnoloÄ£ija, kas sola uzlabot daudzas cilvēka dzÄ«ves jomas. Tas pārnes reālus procesus un produktus digitālajā telpā, nodroÅ”ina finanÅ”u darÄ«jumu ātrumu un uzticamÄ«bu, samazina to izmaksas, kā arÄ« ļauj izveidot modernas DAPP lietojumprogrammas, izmantojot viedos lÄ«gumus decentralizētos tÄ«klos.

Ņemot vērā blokķēdes daudzās priekÅ”rocÄ«bas un daudzveidÄ«gos pielietojumus, var Ŕķist pārsteidzoÅ”i, ka Ŕī daudzsoloŔā tehnoloÄ£ija vēl nav nonākusi visās nozarēs. Problēma ir tā, ka mÅ«sdienu decentralizētajām blokķēdēm trÅ«kst mērogojamÄ«bas. Ethereum apstrādā aptuveni 20 darÄ«jumus sekundē, kas nav pietiekami, lai apmierinātu mÅ«sdienu dinamisko uzņēmumu vajadzÄ«bas. Tajā paŔā laikā uzņēmumi, kas izmanto blokķēdes tehnoloÄ£iju, vilcinās atteikties no Ethereum, jo ā€‹ā€‹tas ir ļoti aizsargāts pret uzlauÅ”anu un tÄ«kla kļūmēm.

Lai nodroÅ”inātu blokķēdes decentralizāciju, droŔību un mērogojamÄ«bu, tādējādi atrisinot Scalability Trilemma, izstrādes komanda Iespēja izveidoja Plasma Cash, meitas ķēdi, kas sastāv no viedā lÄ«guma un privāta tÄ«kla, kura pamatā ir Node.js, kas periodiski nodod savu stāvokli saknes ķēdei (Ethereum).

Publisks tests: Ethereum privātuma un mērogojamības risinājums

Galvenie procesi Plasma Cash

1. Lietotājs izsauc viedā lÄ«guma funkciju "depozÄ«ts", nododot tajā ETH summu, ko viņŔ vēlas iemaksāt Plasma Cash marÄ·ierā. Viedā lÄ«guma funkcija izveido marÄ·ieri un Ä£enerē notikumu par to.

2. Plasma Cash mezgli, kas abonēti viedā līguma notikumiem, saņem notikumu par depozīta izveidi un pievieno pūlam darījumu par marķiera izveidi.

3. Periodiski Ä«paÅ”ie Plasma Cash mezgli ņem visus darÄ«jumus no pÅ«la (lÄ«dz 1 miljonam) un veido no tiem bloku, aprēķina Merkle koku un attiecÄ«gi hash. Å is bloks tiek nosÅ«tÄ«ts uz citiem mezgliem pārbaudei. Mezgli pārbauda, ā€‹ā€‹vai Merkles hash ir derÄ«gs un vai darÄ«jumi ir derÄ«gi (piemēram, vai marÄ·iera sÅ«tÄ«tājs ir tā Ä«paÅ”nieks). Pēc bloka pārbaudes mezgls izsauc viedā lÄ«guma funkciju "submitBlock", kas malu ķēdē saglabā bloka numuru un Merkle jaucējkodu. Viedais lÄ«gums Ä£enerē notikumu, kas norāda uz veiksmÄ«gu bloka pievienoÅ”anu. DarÄ«jumi tiek izņemti no kopas.

4. Mezgli, kas saņem bloka iesniegÅ”anas notikumu, sāk lietot blokam pievienotās transakcijas.

5. Kādā brÄ«dÄ« marÄ·iera Ä«paÅ”nieks (vai Ä«paÅ”nieks) vēlas to izņemt no Plasma Cash. Lai to izdarÄ«tu, viņŔ izsauc funkciju `startExit`, nododot tai informāciju par pēdējiem 2 darÄ«jumiem ar marÄ·ieri, kas apstiprina, ka viņŔ ir marÄ·iera Ä«paÅ”nieks. Viedais lÄ«gums, izmantojot Merkles hash, pārbauda darÄ«jumu esamÄ«bu blokos un nosÅ«ta tokenu izņemÅ”anai, kas notiks pēc divām nedēļām.

6. Ja marÄ·iera izņemÅ”anas darbÄ«ba notikusi ar pārkāpumiem (žetons tika iztērēts pēc izņemÅ”anas procedÅ«ras sākuma vai marÄ·ieris jau bija kādam citam pirms izņemÅ”anas), marÄ·iera Ä«paÅ”nieks divu nedēļu laikā var atspēkot izņemÅ”anu.

Publisks tests: Ethereum privātuma un mērogojamības risinājums

Privātums tiek sasniegts divos veidos

1. Saknes ķēde neko nezina par darÄ«jumiem, kas tiek Ä£enerēti un pārsÅ«tÄ«ti pakārtotajā ķēdē. Informācija par to, kurÅ” iemaksāja un izņēma ETH no Plasma Cash, joprojām ir publiska.

2. Pakārtotā ķēde ļauj veikt anonīmus darījumus, izmantojot zk-SNARK.

Tehnoloģiju kaudze

  • NodeJS
  • Redis
  • Etiijs
  • Augsne

TestēŔana

Izstrādājot Plasma Cash, mēs pārbaudÄ«jām sistēmas ātrumu un ieguvām Ŕādus rezultātus:

  • pÅ«lam tiek pievienoti lÄ«dz 35 000 transakciju sekundē;
  • blokā var saglabāt lÄ«dz 1 000 000 transakciju.

Testi tika veikti uz Ŕādiem 3 serveriem:

1. Intel Core i7-6700 Quad-Core Skylake iesk. NVMe SSD ā€“ 512 GB, 64 GB DDR4 RAM
Tika pacelti 3 validējoÅ”ie Plasma Cash mezgli.

2. AMD Ryzen 7 1700X astoņkodolu "Summit Ridge" (Zen), SATA SSD - 500 GB, 64 GB DDR4 RAM
Tika paaugstināts Ropsten testnet ETH mezgls.
Tika pacelti 3 validējoÅ”ie Plasma Cash mezgli.

3. Intel Core i9-9900K Octa-Core iesk. NVMe SSD ā€“ 1 TB, 64 GB DDR4 RAM
Tika paaugstināts 1 Plasma Cash iesniegŔanas mezgls.
Tika pacelti 3 validējoÅ”ie Plasma Cash mezgli.
Tika uzsākts tests, lai pievienotu darījumus Plasma Cash tīklam.

Kopā: 10 Plasma Cash mezgli privātajā tīklā.

1. pārbaudÄ«jums

Vienā blokā ir 1 miljona darÄ«jumu ierobežojums. LÄ«dz ar to 1 miljons transakciju iedalās 2 blokos (jo sistēma paspēj paņemt daļu no darÄ«jumiem un iesniegt to nosÅ«tÄ«Å”anas laikā).


Sākotnējais stāvoklis: pēdējais bloks #7; Datubāzē tiek glabāts 1 miljons darījumu un marķieru.

00:00 ā€” darÄ«juma Ä£enerÄ“Å”anas skripta sākums
01:37 - tika izveidots 1 miljons transakciju un sākās nosūtīŔana uz mezglu
01:46 ā€” iesniegÅ”anas mezgls paņēma 240 8 darÄ«jumu no pÅ«la un veidoja 320. bloku. Mēs arÄ« redzam, ka 10 XNUMX darÄ«jumu tiek pievienoti pÅ«lam XNUMX sekunžu laikā
01:58 ā€” bloks #8 ir parakstÄ«ts un nosÅ«tÄ«ts apstiprināŔanai
02:03 ā€” tiek apstiprināts bloks #8 un viedā lÄ«guma funkcija "submitBlock" tiek izsaukta ar Merkles jaucējkodu un bloka numuru
02:10 ā€” beidza darbu demonstrācijas skripts, kas nosÅ«tÄ«ja 1 miljonu darÄ«jumu 32 sekundēs
02:33 - mezgli sāka saņemt informāciju, ka bloks #8 ir pievienots saknes ķēdei, un sāka veikt 240 XNUMX darījumu
02:40 - no kopas tika izņemti 240 8 transakciju, kas jau ir blokā #XNUMX
02:56 ā€” iesniegÅ”anas mezgls paņēma atlikuÅ”os 760 9 darÄ«jumus no kopas un sāka aprēķināt Merkle hash un parakstÄ«Å”anas bloku #XNUMX
03:20 ā€” visos mezglos ir 1 miljons 240 XNUMX darÄ«jumu un marÄ·ieru
03:35 ā€” bloks #9 tiek parakstÄ«ts un nosÅ«tÄ«ts apstiprināŔanai citiem mezgliem
03:41 ā€” radās tÄ«kla kļūda
04:40 ā€” ir beidzies gaidÄ«Å”anas bloka #9 validācija
04:54 ā€” iesniegÅ”anas mezgls paņēma atlikuÅ”os 760 9 darÄ«jumus no kopas un sāka aprēķināt Merkle hash un parakstÄ«Å”anas bloku #XNUMX
05:32 ā€” bloks #9 tiek parakstÄ«ts un nosÅ«tÄ«ts apstiprināŔanai citiem mezgliem
05:53 ā€” bloks #9 ir apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
06:17 - mezgli sāka saņemt informāciju, ka bloks #9 tika pievienots saknes ķēdei un sāka veikt 760 XNUMX darījumus
06:47 ā€” pÅ«ls ir notÄ«rÄ«ts no darÄ«jumiem, kas ir blokā #9
09:06 - visos mezglos ir 2 miljoni darījumu un marķieru

2. pārbaudÄ«jums

Katram blokam ir 350 k ierobežojums. Rezultātā mums ir 3 bloki.


Sākotnējais stāvoklis: pēdējais bloks #9; Datubāzē tiek glabāti 2 miljoni darījumu un marķieru

00:00 ā€” transakciju Ä£enerÄ“Å”anas skripts jau ir palaists
00:44 - tika izveidots 1 miljons transakciju un sākās nosūtīŔana uz mezglu
00:56 ā€” iesniegÅ”anas mezgls paņēma 320 10 darÄ«jumu no pÅ«la un veidoja 320. bloku. Mēs arÄ« redzam, ka 10 XNUMX darÄ«jumu tiek pievienoti pÅ«lam XNUMX sekunžu laikā
01:12 ā€” bloks #10 tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
01:18 ā€” beidza darbu demonstrācijas skripts, kas nosÅ«tÄ«ja 1 miljonu darÄ«jumu 34 sekundēs
01:20 ā€” bloks #10 tiek apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
01:51 - visi mezgli saņēma informāciju no saknes ķēdes, ka tika pievienots bloks #10, un sāk piemērot 320 XNUMX darījumus
02:01 ā€” pÅ«ls ir notÄ«rÄ«ts 320 10 darÄ«jumu, kas tika pievienoti blokam #XNUMX
02:15 ā€” iesniegÅ”anas mezgls paņēma 350 11 darÄ«jumu no pÅ«la un veidoja XNUMX. bloku
02:34 ā€” bloks #11 tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
02:51 ā€” bloks #11 tiek apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
02:55 ā€” pēdējais mezgls pabeidza darÄ«jumus no bloka #10
10:59 ā€” darÄ«jums ar bloka #9 iesniegÅ”anu saknes ķēdē aizņēma ļoti ilgu laiku, taču tas tika pabeigts un visi mezgli saņēma informāciju par to un sāka veikt 350 XNUMX darÄ«jumu
11:05 ā€” pÅ«ls ir notÄ«rÄ«ts 320 11 darÄ«jumu, kas tika pievienoti blokam #XNUMX
12:10 ā€” visos mezglos ir 1 miljons 670 XNUMX darÄ«jumu un marÄ·ieru
12:17 ā€” iesniegÅ”anas mezgls paņēma 330 12 darÄ«jumu no pÅ«la un veidoja XNUMX. bloku
12:32 ā€” bloks #12 tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
12:39 ā€” bloks #12 tiek apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
13:44 - visi mezgli saņēma informāciju no saknes ķēdes, ka bloks #12 ir pievienots un sāk piemērot 330 XNUMX darījumus
14:50 - visos mezglos ir 2 miljoni darījumu un marķieru

3. pārbaudÄ«jums

Pirmajā un otrajā serverī viens validācijas mezgls tika aizstāts ar iesniegŔanas mezglu.


Sākotnējais stāvoklis: pēdējais bloks #84; 0 transakciju un marķieru, kas saglabāti datu bāzē

00:00 ā€” ir palaisti 3 skripti, kas Ä£enerē un nosÅ«ta 1 miljonu transakciju katrs
01:38 ā€” tika izveidots 1 miljons transakciju un tika sākta nosÅ«tÄ«Å”ana iesniegÅ”anas mezglam #3
01:50 ā€” iesniegÅ”anas mezgls #3 paņēma 330 85 darÄ«jumu no pÅ«la un veidoja 21. bloku (f350). Mēs arÄ« redzam, ka 10 XNUMX darÄ«jumu tiek pievienoti pÅ«lam XNUMX sekunžu laikā
01:53 ā€” tika izveidots 1 miljons transakciju un tika sākta nosÅ«tÄ«Å”ana iesniegÅ”anas mezglam #1
01:50 ā€” iesniegÅ”anas mezgls #3 paņēma 330 85 darÄ«jumu no pÅ«la un veidoja 21. bloku (f350). Mēs arÄ« redzam, ka 10 XNUMX darÄ«jumu tiek pievienoti pÅ«lam XNUMX sekunžu laikā
02:01 ā€” iesniegÅ”anas mezgls Nr. 1 paņēma 250 85 darÄ«jumu no pÅ«la un veidoja bloku Nr. 65 (XNUMXe)
02:06 ā€” bloks #85 (f21) tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
02:08 ā€” 3. servera demonstrācijas skripts, kas 1 sekundēs nosÅ«tÄ«ja 30 miljonu transakciju, beidza darboties
02:14 ā€” bloks #85 (f21) tiek apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
02:19 ā€” bloks #85 (65e) tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
02:22 ā€” tika izveidots 1 miljons transakciju un tika sākta nosÅ«tÄ«Å”ana iesniegÅ”anas mezglam #2
02:27 ā€” bloks #85 (65e) apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
02:29 ā€” iesniegÅ”anas mezgls #2 paņēma 111855 darÄ«jumus no pÅ«la un veidlapu bloku #85 (256).
02:36 ā€” bloks #85 (256) tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
02:36 ā€” 1. servera demonstrācijas skripts, kas 1 sekundēs nosÅ«tÄ«ja 42.5 miljonu transakciju, beidza darboties
02:38 ā€” bloks #85 (256) tiek apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
03:08 ā€” beidza darboties servera #2 skripts, kas nosÅ«tÄ«ja 1 miljonu transakciju 47 sekundēs
03:38 - visi mezgli saņēma informāciju no saknes ķēdes, ka tika pievienoti bloki #85 (f21), #86(65e), #87(256), un sāka piemērot 330k, 250k, 111855 darījumus.
03:49 ā€” pÅ«ls tika notÄ«rÄ«ts pie 330 k, 250 k, 111855 85 darÄ«jumiem, kas tika pievienoti blokiem #21 (f86), #65(87e), #256(XNUMX)
03:59 ā€” iesniegÅ”anas mezgls #1 paņēma 888145 88 darÄ«jumus no pÅ«la un veidlapu bloku #214 (2), iesniegÅ”anas mezgls #750 paņēma 88 50 darÄ«jumu no pÅ«la un veidlapu bloku #3 (670a), iesniegÅ”anas mezgls #88 paņēma 3 XNUMX darÄ«jumu no baseins un formu bloks #XNUMX (dXNUMXb)
04:44 ā€” bloks #88 (d3b) ir parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
04:58 ā€” bloks #88 (214) tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
05:11 ā€” bloks #88 (50a) tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
05:11 ā€” bloks #85 (d3b) ir apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
05:36 ā€” bloks #85 (214) tiek apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
05:43 - visi mezgli saņēma informāciju no saknes ķēdes, ka ir pievienoti bloki #88 (d3b), #89(214) un sāk piemērot 670k, 750k darījumus
06:50 ā€” sakaru kļūmes dēļ bloks #85 (50a) netika apstiprināts
06:55 ā€” iesniegÅ”anas mezgls #2 paņēma 888145 darÄ«jumus no pÅ«la un veidlapu bloku #90 (50a)
08:14 ā€” bloks #90 (50a) tiek parakstÄ«ts un nosÅ«tÄ«ts uz citiem mezgliem apstiprināŔanai
09:04 ā€” bloks #90 (50a) tiek apstiprināts un nosÅ«tÄ«ts uz saknes ķēdi
11:23 - visi mezgli saņēma informāciju no saknes ķēdes, ka ir pievienots bloks #90 (50a), un sāk piemērot 888145 darÄ«jumus. Tajā paŔā laikā serveris #3 jau ir piemērojis darÄ«jumus no blokiem #88 (d3b), #89(214)
12:11 - visi baseini ir tukŔi
13:41 ā€” visos servera #3 mezglos ir 3 miljoni transakciju un marÄ·ieru
14:35 ā€” visos servera #1 mezglos ir 3 miljoni transakciju un marÄ·ieru
19:24 ā€” visos servera #2 mezglos ir 3 miljoni transakciju un marÄ·ieru

ŠķērŔļi

Plasma Cash izstrādes gaitā saskārāmies ar Ŕādām problēmām, kuras pakāpeniski atrisinājām un risinām:

1. Konflikts dažādu sistēmas funkciju mijiedarbÄ«bā. Piemēram, transakciju pievienoÅ”anas pÅ«lam funkcija bloķēja bloku iesniegÅ”anas un apstiprināŔanas darbu un otrādi, kas izraisÄ«ja ātruma samazināŔanos.

2. Uzreiz nebija skaidrs, kā nosūtīt milzīgu skaitu darījumu, vienlaikus samazinot datu pārsūtīŔanas izmaksas.

3. Nebija skaidrs, kā un kur uzglabāt datus, lai sasniegtu augstus rezultātus.

4. Nebija skaidrs, kā organizēt tÄ«klu starp mezgliem, jo ā€‹ā€‹bloka lielums ar 1 miljonu transakciju aizņem apmēram 100 MB.

5. Strādājot viena vītnes režīmā, savienojums starp mezgliem tiek pārtraukts, kad notiek ilgi aprēķini (piemēram, veidojot Merkle koku un aprēķinot tā jaucējfunkciju).

Kā mēs ar to visu tikām galā?

Pirmā Plasma Cash mezgla versija bija sava veida kombināts, kas varēja darÄ«t visu vienlaikus: pieņemt darÄ«jumus, iesniegt un apstiprināt blokus un nodroÅ”ināt API piekļuvei datiem. Tā kā NodeJS sākotnēji ir viens pavediens, smagā Merkle koka aprēķina funkcija bloķēja pievienoÅ”anas transakcijas funkciju. Mēs redzējām divas Ŕīs problēmas risināŔanas iespējas:

1. Palaidiet vairākus NodeJS procesus, no kuriem katrs veic noteiktas funkcijas.

2. Izmantojiet worker_threads un pārvietojiet koda daļas izpildi pavedienos.

Rezultātā mēs izmantojām abas iespējas vienlaikus: loÄ£iski sadalÄ«jām vienu mezglu 3 daļās, kas var darboties atseviŔķi, bet tajā paŔā laikā sinhroni

1. IesniegÅ”anas mezgls, kas pieņem darÄ«jumus pÅ«lā un izveido blokus.

2. Validācijas mezgls, kas pārbauda mezglu derīgumu.

3. API mezgls ā€” nodroÅ”ina API piekļuvei datiem.

Šajā gadījumā jūs varat izveidot savienojumu ar katru mezglu, izmantojot unix ligzdu, izmantojot cli.

Mēs pārcēlām smagas darbÄ«bas, piemēram, Merkles koka aprēķināŔanu, atseviŔķā pavedienā.

Tādējādi esam panākuÅ”i visu Plasma Cash funkciju normālu darbÄ«bu vienlaicÄ«gi un bez kļūmēm.

Kad sistēma darbojās, mēs sākām pārbaudÄ«t ātrumu un diemžēl saņēmām neapmierinoÅ”us rezultātus: 5 transakciju sekundē un lÄ«dz 000 50 transakciju blokā. Man bija jāizdomā, kas tika ieviests nepareizi.

Sākumā mēs sākām pārbaudÄ«t saziņas mehānismu ar Plasma Cash, lai noskaidrotu sistēmas maksimālo spēju. IepriekÅ” rakstÄ«jām, ka Plasma Cash mezgls nodroÅ”ina unix ligzdas saskarni. Sākotnēji tas bija balstÄ«ts uz tekstu. json objekti tika nosÅ«tÄ«ti, izmantojot "JSON.parse()" un "JSON.stringify()".

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

Mēs izmērÄ«jām Ŕādu objektu pārraides ātrumu un atradām ~ 130k sekundē. Mēs mēģinājām aizstāt standarta funkcijas darbam ar json, taču veiktspēja neuzlabojās. V8 dzinējam jābÅ«t labi optimizētam Ŕīm darbÄ«bām.

Mēs strādājām ar darÄ«jumiem, marÄ·ieriem un blokiem, izmantojot nodarbÄ«bas. Veidojot Ŕādas nodarbÄ«bas, veiktspēja kritās 2 reizes, kas liecina, ka OOP mums nav piemērots. Man vajadzēja visu pārrakstÄ«t uz tÄ«ri funkcionālu pieeju.

IerakstÄ«Å”ana datu bāzē

Sākotnēji Redis datu glabāŔanai tika izvēlēts kā viens no produktÄ«vākajiem risinājumiem, kas apmierina mÅ«su prasÄ«bas: atslēgu-vērtÄ«bu uzglabāŔana, darbs ar hash tabulām, komplektiem. Mēs palaižām etalonuzdevumu redis un saņēmām ~ 80 1 darbÄ«bu sekundē XNUMX konveijera režīmā.

Lai nodroÅ”inātu augstu veiktspēju, mēs Redis precÄ«zāk noregulējām:

  • Ir izveidots unix ligzdas savienojums.
  • Mēs atspējojām stāvokļa saglabāŔanu diskā (uzticamÄ«bas labad varat iestatÄ«t kopiju un saglabāt diskā atseviŔķā Redis).

Programmā Redis pūls ir hash tabula, jo mums ir jāspēj izgūt visas transakcijas vienā vaicājumā un dzēst darījumus pa vienam. Mēs mēģinājām izmantot parasto sarakstu, taču tas ir lēnāks, izlādējot visu sarakstu.

Izmantojot standarta NodeJS, Redis bibliotēkas sasniedza 18 9 darÄ«jumu sekundē. Ātrums kritās XNUMX reizes.

Tā kā etalons mums parādÄ«ja, ka iespējas ir 5 reizes lielākas, mēs sākām optimizēt. Mēs mainÄ«jām bibliotēku uz ioredis un saņēmām veiktspēju 25 k sekundē. Mēs pievienojām darÄ«jumus pa vienam, izmantojot komandu hset. Tāpēc mēs Ä£enerējām daudz vaicājumu pakalpojumā Redis. Radās ideja apvienot darÄ«jumus pa partijām un nosÅ«tÄ«t tos ar vienu komandu `hmset`. Rezultāts ir 32k sekundē.

Vairāku iemeslu dēļ, kurus mēs aprakstÄ«sim tālāk, mēs strādājam ar datiem, izmantojot `Buferi`, un, kā izrādās, ja pirms rakstÄ«Å”anas konvertēsit tos par tekstu (`buffer.toString('hex')`), varat iegÅ«t papildu informāciju. sniegumu. Tādējādi ātrums tika palielināts lÄ«dz 35k sekundē. Å obrÄ«d mēs nolēmām apturēt turpmāko optimizāciju.

Mums bija jāpārslēdzas uz bināro protokolu, jo:

1. Sistēma bieži aprēķina jaucējus, parakstus utt., un Å”im nolÅ«kam tai ir nepiecieÅ”ami dati buferÄ«.

2. SÅ«tot starp pakalpojumiem, binārie dati sver mazāk nekā teksts. Piemēram, nosÅ«tot bloku ar 1 miljonu transakciju, tekstā esoÅ”ie dati var aizņemt vairāk nekā 300 megabaitus.

3. PastāvÄ«ga datu pārveidoÅ”ana ietekmē veiktspēju.

Tāpēc mēs par pamatu ņēmām mÅ«su paÅ”u bināro protokolu datu glabāŔanai un pārsÅ«tÄ«Å”anai, kas izstrādāts, pamatojoties uz brÄ«niŔķīgo "bināro datu" bibliotēku.

Rezultātā mēs saņēmām Ŕādas datu struktÅ«ras:

ā€” DarÄ«jums

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

ā€” Žetons

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

-Bloķēt

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

Ar parastajām komandām `BD.encode(block, Protocol).slice();` un `BD.decode(buffer, Protocol)` mēs pārvērÅ”am datus par buferi, lai tos saglabātu programmā Redis vai pārsÅ«tÄ«tu uz citu mezglu un izgÅ«tu datus atpakaļ.

Mums ir arī 2 binārie protokoli datu pārsūtīŔanai starp pakalpojumiem:

ā€” Protokols mijiedarbÄ«bai ar plazmas mezglu, izmantojot unix ligzdu

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

ja:

  • `tips` ā€” veicamā darbÄ«ba, piemēram, 1 ā€” sendTransaction, 2 ā€” getTransaction;
  • `krava` ā€” dati, kas jānodod attiecÄ«gajai funkcijai;
  • 'messageId' ā€” ziņojuma ID, lai atbildi varētu identificēt.

ā€” Mezglu mijiedarbÄ«bas protokols

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

ja:

  • `kods` ā€” ziņojuma kods, piemēram, 6 ā€” PREPARE_NEW_BLOCK, 7 ā€” BLOCK_VALID, 8 ā€” BLOCK_COMMIT;
  • 'versionProtocol' ā€” protokola versija, jo tÄ«klā var tikt izvirzÄ«ti mezgli ar dažādām versijām un tie var darboties atŔķirÄ«gi;
  • "seq". ā€” ziņojuma identifikators;
  • `countChunk` Šø `chunkNumber` nepiecieÅ”ams lielu ziņojumu sadalÄ«Å”anai;
  • `garums` Šø `krava` garums un paÅ”i dati.

Tā kā mēs iepriekÅ” ievadÄ«jām datus, galÄ«gā sistēma ir daudz ātrāka nekā Ethereum ā€œrlpā€ bibliotēka. Diemžēl vēl neesam varējuÅ”i no tā atteikt, jo nepiecieÅ”ams pabeigt viedo lÄ«gumu, ko plānojam darÄ«t arÄ« turpmāk.

Ja mums izdotos sasniegt ātrumu 35 000 darÄ«jumus sekundē, mums arÄ« tie ir jāapstrādā optimālā laikā. Tā kā aptuvenais bloka veidoÅ”anas laiks aizņem 30 sekundes, mums ir jāiekļauj blokā 1 000 000 darÄ«jumiem, kas nozÄ«mē vairāk sÅ«tÄ«Å”anu 100 MB datu.

Sākotnēji mēs izmantojām bibliotēku "ethereumjs-devp2p", lai sazinātos starp mezgliem, taču tā nevarēja apstrādāt tik daudz datu. Rezultātā mēs izmantojām ā€œwsā€ bibliotēku un konfigurējām bināro datu sÅ«tÄ«Å”anu, izmantojot tÄ«mekļa ligzdu. Protams, mēs arÄ« saskārāmies ar problēmām, sÅ«tot lielas datu paketes, taču mēs tās sadalÄ«jām gabalos, un tagad Ŕīs problēmas ir pazuduÅ”as.

ArÄ« Merkles koka veidoÅ”ana un hash aprēķināŔana 1 000 000 darÄ«jumiem ir nepiecieÅ”ams apmēram 10 sekundes nepārtraukta aprēķina. Å ajā laikā savienojums ar visiem mezgliem izdodas pārraut. Tika nolemts Å”o aprēķinu pārcelt uz atseviŔķu pavedienu.

Secinājumi:

Patiesībā mūsu atklājumi nav jauni, taču nez kāpēc daudzi eksperti par tiem aizmirst, izstrādājot.

  • Funkcionālās programmÄ“Å”anas izmantoÅ”ana objektorientētas programmÄ“Å”anas vietā uzlabo produktivitāti.
  • MonolÄ«ts ir sliktāks nekā pakalpojumu arhitektÅ«ra produktÄ«vai NodeJS sistēmai.
  • Darbinieka_pavedienu izmantoÅ”ana intensÄ«viem aprēķiniem uzlabo sistēmas reaģētspēju, Ä«paÅ”i, ja tiek veiktas i/o operācijas.
  • unix ligzda ir stabilāka un ātrāka nekā http pieprasÄ«jumi.
  • Ja jums ir nepiecieÅ”ams ātri pārsÅ«tÄ«t lielus datus tÄ«klā, labāk ir izmantot tÄ«mekļa kontaktligzdas un nosÅ«tÄ«t bināros datus, kas sadalÄ«ti gabalos, kurus var pārsÅ«tÄ«t, ja tie nepienāk, un pēc tam apvienot vienā ziņojumā.

Aicinām ciemos GitHub projekts: https://github.com/opporty-com/Plasma-Cash/tree/new-version

Raksta līdzautors Aleksandrs NaŔivans, vecākais izstrādātājs Clever Solution Inc.

Avots: www.habr.com

Pievieno komentāru