Jaribio la Umma: Suluhisho la Faragha na Uharibifu kwenye Ethereum

Bloccain ni teknolojia ya kibunifu inayoahidi kuboresha maeneo mengi ya maisha ya mwanadamu. Inahamisha michakato na bidhaa halisi kwenye nafasi ya dijiti, inahakikisha kasi na uaminifu wa shughuli za kifedha, inapunguza gharama zao, na pia hukuruhusu kuunda programu za kisasa za DAPP kwa kutumia mikataba mahiri katika mitandao iliyogatuliwa.

Kwa kuzingatia faida nyingi na matumizi anuwai ya blockchain, inaweza kuonekana kuwa ya kushangaza kwamba teknolojia hii ya kuahidi bado haijaingia katika kila tasnia. Shida ni kwamba blockchains za kisasa zilizowekwa madarakani hazina uzani. Ethereum inachakata kuhusu shughuli 20 kwa sekunde, ambayo haitoshi kukidhi mahitaji ya biashara ya leo yenye nguvu. Wakati huo huo, makampuni yanayotumia teknolojia ya blockchain yanasita kuacha Ethereum kutokana na kiwango cha juu cha ulinzi kutoka kwa hacking na kushindwa kwa mtandao.

Ili kuhakikisha ugatuaji, usalama na upunguzaji katika blockchain, na hivyo kutatua Scalability Trilemma, timu ya maendeleo. Fursa iliunda Plasma Cash, mnyororo tanzu unaojumuisha mkataba mzuri na mtandao wa kibinafsi kulingana na Node.js, ambayo mara kwa mara huhamisha hali yake kwenye mnyororo wa mizizi (Ethereum).

Jaribio la Umma: Suluhisho la Faragha na Uharibifu kwenye Ethereum

Michakato muhimu katika Pesa ya Plasma

1. Mtumiaji huita kipengele cha chaguo mahiri cha mkataba `deposit`, akipitisha ndani yake kiasi cha ETH anachotaka kuweka kwenye tokeni ya Plasma Cash. Chaguo za kukokotoa za mkataba mahiri huunda tokeni na kutoa tukio kuihusu.

2. Nodi za Plasma Cash zinazojisajili kupokea matukio ya mikataba mahiri hupokea tukio kuhusu kuweka amana na kuongeza muamala kuhusu kuunda tokeni kwenye hifadhi.

3. Mara kwa mara, nodi maalum za Fedha za Plasma huchukua shughuli zote kutoka kwa bwawa (hadi milioni 1) na kuunda kizuizi kutoka kwao, kuhesabu mti wa Merkle na, ipasavyo, hashi. Kizuizi hiki kinatumwa kwa nodi zingine kwa uthibitishaji. Nodi hukagua ikiwa heshi ya Merkle ni halali na ikiwa miamala ni halali (kwa mfano, ikiwa mtumaji wa tokeni ndiye mmiliki wake). Baada ya kuthibitisha kizuizi, nodi huita kipengele cha `submitBlock` cha mkataba mahiri, ambacho huhifadhi nambari ya kuzuia na heshi ya Merkle kwenye msururu wa makali. Mkataba mahiri hutoa tukio linaloonyesha mafanikio ya kuongezwa kwa block. Shughuli zinaondolewa kwenye bwawa.

4. Nodi zinazopokea tukio la uwasilishaji wa kizuizi huanza kutumia miamala ambayo iliongezwa kwenye kizuizi.

5. Wakati fulani, mmiliki (au asiye mmiliki) wa ishara anataka kuiondoa kutoka kwa Fedha ya Plasma. Ili kufanya hivyo, anaita kazi ya `startExit`, kupita ndani yake habari kuhusu shughuli 2 za mwisho kwenye ishara, ambayo inathibitisha kuwa yeye ndiye mmiliki wa ishara. Mkataba wa smart, kwa kutumia hash ya Merkle, huangalia uwepo wa shughuli katika vitalu na kutuma ishara kwa uondoaji, ambayo itatokea katika wiki mbili.

6. Ikiwa operesheni ya uondoaji wa ishara ilitokea kwa ukiukwaji (ishara ilitumiwa baada ya utaratibu wa uondoaji kuanza au ishara ilikuwa tayari ya mtu mwingine kabla ya kujiondoa), mmiliki wa ishara anaweza kukataa uondoaji ndani ya wiki mbili.

Jaribio la Umma: Suluhisho la Faragha na Uharibifu kwenye Ethereum

Faragha hupatikana kwa njia mbili

1. Msururu wa mizizi haujui chochote kuhusu miamala ambayo hutolewa na kutumwa ndani ya mlolongo wa watoto. Taarifa kuhusu ni nani aliyeweka na kutoa ETH kwenye Plasma Cash bado hadharani.

2. Mlolongo wa watoto huruhusu shughuli zisizojulikana kwa kutumia zk-SNARKs.

Mkusanyiko wa teknolojia

  • NodeJS
  • Rejea
  • Ethereum
  • Udongo

Upimaji

Wakati wa kutengeneza Pesa ya Plasma, tulijaribu kasi ya mfumo na kupata matokeo yafuatayo:

  • hadi shughuli 35 kwa sekunde zinaongezwa kwenye bwawa;
  • hadi miamala 1 inaweza kuhifadhiwa kwenye kizuizi.

Majaribio yalifanywa kwenye seva 3 zifuatazo:

1. Intel Core i7-6700 Quad-Core Skylake incl. NVMe SSD – 512 GB, 64 GB DDR4 RAM
Nodi 3 za Fedha za Plasma zilitolewa.

2. AMD Ryzen 7 1700X Octa-Core β€œSummit Ridge” (Zen), SATA SSD – GB 500, 64 GB DDR4 RAM
Nodi ya ETH ya Ropsten testnet iliinuliwa.
Nodi 3 za Fedha za Plasma zilitolewa.

3. Intel Core i9-9900K Octa-Core incl. NVMe SSD – 1 TB, 64 GB DDR4 RAM
Nodi 1 ya uwasilishaji ya Pesa ya Plasma ilitolewa.
Nodi 3 za Fedha za Plasma zilitolewa.
Jaribio lilianzishwa ili kuongeza miamala kwenye mtandao wa Plasma Cash.

Jumla: Nodi 10 za Fedha za Plasma kwenye mtandao wa kibinafsi.

Jaribio 1

Kuna kikomo cha miamala milioni 1 kwa kila block. Kwa hiyo, shughuli milioni 1 huanguka katika vitalu 2 (kwani mfumo unasimamia kuchukua sehemu ya shughuli na kuwasilisha wakati zinatumwa).


Hali ya awali: kizuizi cha mwisho # 7; Shughuli na tokeni milioni 1 zimehifadhiwa kwenye hifadhidata.

00:00 - kuanza kwa hati ya utengenezaji wa shughuli
01:37 - miamala milioni 1 iliundwa na kutuma kwa nodi ilianza
01:46 - nodi ya kuwasilisha ilichukua miamala ya 240k kutoka kwa bwawa na kuunda block #8. Pia tunaona kuwa miamala ya 320k huongezwa kwenye bwawa katika sekunde 10
01:58 - kizuizi #8 kimetiwa saini na kutumwa kwa uthibitisho
02:03 β€” block #8 imeidhinishwa na utendakazi wa `submitBlock` wa mkataba mahiri unaitwa kwa heshi ya Merkle na nambari ya kizuizi.
02:10 - hati ya onyesho imekamilika kufanya kazi, ambayo ilituma miamala milioni 1 katika sekunde 32
02:33 - nodi zilianza kupokea habari kwamba block #8 iliongezwa kwenye mlolongo wa mizizi, na kuanza kufanya shughuli 240k.
02:40 - miamala ya 240k iliondolewa kwenye bwawa, ambayo tayari iko kwenye block #8.
02:56 - nodi ya kuwasilisha ilichukua miamala iliyobaki ya 760k kutoka kwa bwawa na kuanza kukokotoa hashi ya Merkle na kusaini block #9.
03:20 - nodi zote zina miamala na tokeni milioni 1 za 240k
03:35 - kizuizi #9 kimetiwa saini na kutumwa kwa uthibitisho kwa nodi zingine
03:41 - hitilafu ya mtandao ilitokea
04:40 β€” kusubiri uthibitisho wa block #9 umeisha
04:54 - nodi ya kuwasilisha ilichukua miamala iliyobaki ya 760k kutoka kwa bwawa na kuanza kukokotoa hashi ya Merkle na kusaini block #9.
05:32 - kizuizi #9 kimetiwa saini na kutumwa kwa uthibitisho kwa nodi zingine
05:53 - block #9 imethibitishwa na kutumwa kwa mnyororo wa mizizi
06:17 - nodi zilianza kupokea habari kwamba block #9 iliongezwa kwenye mlolongo wa mizizi na kuanza kufanya shughuli za 760k.
06:47 - bwawa limeondoa miamala iliyo kwenye kitalu #9
09:06 - nodi zote zina shughuli milioni 2 na ishara

Jaribio 2

Kuna kikomo cha 350k kwa kila block. Kama matokeo, tuna vitalu 3.


Hali ya awali: kizuizi cha mwisho # 9; Miamala na tokeni milioni 2 zimehifadhiwa kwenye hifadhidata

00:00 - hati ya kutengeneza muamala tayari imezinduliwa
00:44 - miamala milioni 1 iliundwa na kutuma kwa nodi ilianza
00:56 - nodi ya kuwasilisha ilichukua miamala ya 320k kutoka kwa bwawa na kuunda block #10. Pia tunaona kuwa miamala ya 320k huongezwa kwenye bwawa katika sekunde 10
01:12 - block #10 imetiwa saini na kutumwa kwa nodi zingine kwa uthibitisho
01:18 - hati ya onyesho imekamilika kufanya kazi, ambayo ilituma miamala milioni 1 katika sekunde 34
01:20 - block #10 imethibitishwa na kutumwa kwa mlolongo wa mizizi
01:51 - nodi zote zilipokea taarifa kutoka kwa mnyororo wa mizizi ambao block #10 iliongezwa na kuanza kutumia miamala ya 320k
02:01 - bwawa limeidhinishwa kwa miamala ya 320k ambayo iliongezwa kuzuia #10
02:15 - nodi ya kuwasilisha ilichukua miamala ya 350k kutoka kwa bwawa na kuunda block #11
02:34 - block #11 imetiwa saini na kutumwa kwa nodi zingine kwa uthibitisho
02:51 - block #11 imethibitishwa na kutumwa kwa mnyororo wa mizizi
02:55 - nodi ya mwisho ilikamilisha shughuli kutoka kwa block #10
10:59 - shughuli na uwasilishaji wa block #9 ilichukua muda mrefu sana kwenye mnyororo wa mizizi, lakini ilikamilishwa na nodi zote zilipokea habari juu yake na kuanza kufanya shughuli za 350k.
11:05 - bwawa limeidhinishwa kwa miamala ya 320k ambayo iliongezwa kuzuia #11
12:10 - nodi zote zina miamala na tokeni milioni 1 670k
12:17 - nodi ya kuwasilisha ilichukua miamala ya 330k kutoka kwa bwawa na kuunda kizuizi #12
12:32 - block #12 imetiwa saini na kutumwa kwa nodi zingine kwa uthibitisho
12:39 - block #12 imethibitishwa na kutumwa kwa mlolongo wa mizizi
13:44 - nodi zote zilipokea taarifa kutoka kwa mnyororo wa mizizi ambao block #12 iliongezwa na kuanza kutumia miamala ya 330k
14:50 - nodi zote zina shughuli milioni 2 na ishara

Jaribio 3

Katika seva za kwanza na za pili, nodi moja ya kuthibitisha ilibadilishwa na nodi ya kuwasilisha.


Hali ya awali: kizuizi cha mwisho #84; 0 shughuli na ishara zilizohifadhiwa kwenye hifadhidata

00:00 - Hati 3 zimezinduliwa zinazozalisha na kutuma miamala milioni 1 kila moja
01:38 - miamala milioni 1 iliundwa na kutuma kuwasilisha nodi #3 ilianza
01:50 - wasilisha nodi #3 ilichukua miamala ya 330k kutoka kwa bwawa na kuunda kizuizi #85 (f21). Pia tunaona kuwa miamala ya 350k huongezwa kwenye bwawa katika sekunde 10
01:53 - miamala milioni 1 iliundwa na kutuma kuwasilisha nodi #1 ilianza
01:50 - wasilisha nodi #3 ilichukua miamala ya 330k kutoka kwa bwawa na kuunda kizuizi #85 (f21). Pia tunaona kuwa miamala ya 350k huongezwa kwenye bwawa katika sekunde 10
02:01 - wasilisha nodi # 1 ilichukua miamala ya 250k kutoka kwa bwawa na kuunda kizuizi #85 (65e)
02:06 - block #85 (f21) imetiwa saini na kutumwa kwa nodi zingine kwa uthibitisho
02:08 - hati ya onyesho ya seva # 3, ambayo ilituma miamala milioni 1 kwa sekunde 30, kumaliza kufanya kazi
02:14 - block #85 (f21) imethibitishwa na kutumwa kwa mlolongo wa mizizi
02:19 - block #85 (65e) imetiwa saini na kutumwa kwa nodi zingine kwa uthibitisho
02:22 - miamala milioni 1 iliundwa na kutuma kuwasilisha nodi #2 ilianza
02:27 - block #85 (65e) imethibitishwa na kutumwa kwa mlolongo wa mizizi
02:29 - wasilisha nodi # 2 ilichukua miamala 111855 kutoka kwa bwawa na kuunda block #85 (256).
02:36 - block #85 (256) imetiwa saini na kutumwa kwa nodi zingine ili kuthibitishwa
02:36 - hati ya onyesho ya seva # 1, ambayo ilituma miamala milioni 1 kwa sekunde 42.5, kumaliza kufanya kazi
02:38 - block #85 (256) imethibitishwa na kutumwa kwa mnyororo wa mizizi
03:08 - hati ya seva #2 ilimaliza kufanya kazi, ambayo ilituma miamala milioni 1 katika sekunde 47
03:38 - nodi zote zilipokea taarifa kutoka kwa msururu wa mizizi unaozuia #85 (f21), #86(65e), #87(256) ziliongezwa na kuanza kutumia miamala 330k, 250k, 111855
03:49 - bwawa liliondolewa kwa miamala ya 330k, 250k, 111855 ambayo iliongezwa kwenye vitalu #85 (f21), #86(65e), #87(256)
03:59 - nodi ya kuwasilisha #1 ilichukua miamala 888145 kutoka kwa bwawa na fomu za kizuizi #88 (214), wasilisha nodi #2 ilichukua miamala ya 750k kutoka kwa bwawa na fomu ya kuzuia #88 (50a), wasilisha nodi #3 ilichukua miamala ya 670k kutoka bwawa na fomu block #88 (d3b)
04:44 β€” block #88 (d3b) imetiwa saini na kutumwa kwa nodi zingine ili kuthibitishwa
04:58 - block #88 (214) imetiwa saini na kutumwa kwa nodi zingine ili kuthibitishwa
05:11 - block #88 (50a) imetiwa saini na kutumwa kwa nodi zingine ili kuthibitishwa
05:11 - block #85 (d3b) imethibitishwa na kutumwa kwa mnyororo wa mizizi
05:36 - block #85 (214) imethibitishwa na kutumwa kwa mnyororo wa mizizi
05:43 - nodi zote zilipokea taarifa kutoka kwa msururu wa mizizi unaozuia #88 (d3b), #89(214) zimeongezwa na zinaanza kutumia miamala ya 670k, 750k.
06:50 - kutokana na kushindwa kwa mawasiliano, block #85 (50a) haikuthibitishwa
06:55 - wasilisha nodi #2 ilichukua miamala 888145 kutoka kwa bwawa na kuunda kizuizi #90 (50a)
08:14 - block #90 (50a) imetiwa saini na kutumwa kwa nodi zingine ili kuthibitishwa
09:04 - block #90 (50a) imethibitishwa na kutumwa kwa mlolongo wa mizizi
11:23 - nodi zote zilipokea taarifa kutoka kwa mnyororo wa mizizi ambao block #90 (50a) iliongezwa, na kuanza kutumia miamala 888145. Wakati huo huo, seva #3 tayari imetumia miamala kutoka kwa vitalu #88 (d3b), #89(214)
12:11 - mabwawa yote ni tupu
13:41 - nodi zote za seva #3 zina shughuli na ishara milioni 3
14:35 - nodi zote za seva #1 zina shughuli na ishara milioni 3
19:24 - nodi zote za seva #2 zina shughuli na ishara milioni 3

Vikwazo

Wakati wa ukuzaji wa Pesa ya Plasma, tulikutana na shida zifuatazo, ambazo tulitatua polepole na tunatatua:

1. Migogoro katika mwingiliano wa kazi mbalimbali za mfumo. Kwa mfano, kazi ya kuongeza shughuli kwenye bwawa ilizuia kazi ya kuwasilisha na kuthibitisha vitalu, na kinyume chake, ambayo imesababisha kushuka kwa kasi.

2. Haikuweza kufahamika mara moja jinsi ya kutuma idadi kubwa ya miamala huku ikipunguza gharama za uhamishaji data.

3. Haikuwa wazi jinsi na wapi kuhifadhi data ili kufikia matokeo ya juu.

4. Haikuwa wazi jinsi ya kuandaa mtandao kati ya nodes, kwa kuwa ukubwa wa block na shughuli milioni 1 inachukua kuhusu 100 MB.

5. Kufanya kazi katika hali ya uzi mmoja huvunja muunganisho kati ya nodi wakati mahesabu marefu yanapotokea (kwa mfano, kujenga mti wa Merkle na kuhesabu heshi yake).

Je, tulikabiliana vipi na haya yote?

Toleo la kwanza la nodi ya Plasma Cash ilikuwa aina ya mchanganyiko ambayo inaweza kufanya kila kitu kwa wakati mmoja: kukubali shughuli, kuwasilisha na kuthibitisha vitalu, na kutoa API kwa ajili ya kupata data. Kwa kuwa NodeJS ina uzi mmoja asili, kikokotoo kikubwa cha kukokotoa mti wa Merkle kilizuia kitendakazi cha kuongeza muamala. Tuliona chaguzi mbili za kutatua shida hii:

1. Zindua michakato kadhaa ya NodeJS, ambayo kila moja hufanya kazi maalum.

2. Tumia worker_threads na usogeze utekelezaji wa sehemu ya msimbo kwenye nyuzi.

Kama matokeo, tulitumia chaguzi zote mbili kwa wakati mmoja: kwa mantiki tuligawa nodi moja katika sehemu 3 ambazo zinaweza kufanya kazi tofauti, lakini wakati huo huo kwa usawa.

1. Njia ya uwasilishaji, ambayo inakubali shughuli kwenye bwawa na kuunda vizuizi.

2. Nodi ya uthibitisho ambayo hukagua uhalali wa nodi.

3. API nodi - hutoa API kwa ajili ya kupata data.

Katika kesi hii, unaweza kuunganisha kwa kila nodi kupitia tundu la unix kwa kutumia cli.

Tulihamisha shughuli nzito, kama vile kukokotoa mti wa Merkle, kwenye uzi tofauti.

Kwa hivyo, tumepata utendakazi wa kawaida wa kazi zote za Pesa ya Plasma kwa wakati mmoja na bila kushindwa.

Mara tu mfumo ulipofanya kazi, tulianza kupima kasi na, kwa bahati mbaya, tulipata matokeo yasiyo ya kuridhisha: shughuli 5 kwa sekunde na hadi miamala 000 kwa kila block. Ilinibidi kubaini ni nini kilitekelezwa kimakosa.

Kuanza, tulianza kujaribu utaratibu wa mawasiliano na Plasma Cash ili kujua uwezo wa kilele wa mfumo. Tuliandika hapo awali kwamba nodi ya Fedha ya Plasma hutoa kiolesura cha tundu unix. Hapo awali, ilitegemea maandishi. vipengee vya json vilitumwa kwa kutumia `JSON.parse()` na `JSON.stringify()`.

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

Tulipima kasi ya uhamishaji wa vitu kama hivyo na tukapata ~ 130k kwa sekunde. Tulijaribu kubadilisha vipengele vya kawaida vya kufanya kazi na json, lakini utendaji haukuboresha. Injini ya V8 lazima iboreshwe vyema kwa shughuli hizi.

Tulifanya kazi na miamala, tokeni na vizuizi kupitia madarasa. Wakati wa kuunda madarasa kama haya, utendaji ulipungua kwa mara 2, ambayo inaonyesha kuwa OOP haifai kwetu. Ilinibidi kuandika tena kila kitu kwa njia ya kufanya kazi tu.

Kurekodi katika hifadhidata

Hapo awali, Redis ilichaguliwa kwa ajili ya kuhifadhi data kama mojawapo ya suluhu zenye tija zaidi zinazokidhi mahitaji yetu: hifadhi ya thamani kuu, kufanya kazi na jedwali la hashi, seti. Tulizindua redis-benchmark na tukapata shughuli za ~80k kwa sekunde katika hali 1 ya uwekaji bomba.

Kwa utendakazi wa hali ya juu, tulirekebisha Redis vizuri zaidi:

  • Muunganisho wa soketi unix umeanzishwa.
  • Tulizima kuokoa hali kwenye diski (kwa kuegemea, unaweza kuanzisha replica na kuhifadhi kwenye diski katika Redis tofauti).

Katika Redis, bwawa ni jedwali la hashi kwa sababu tunahitaji kuwa na uwezo wa kurejesha shughuli zote katika hoja moja na kufuta miamala moja baada ya nyingine. Tulijaribu kutumia orodha ya kawaida, lakini ni polepole wakati wa kupakua orodha nzima.

Wakati wa kutumia NodeJS ya kawaida, maktaba za Redis zilipata utendakazi wa miamala 18k kwa sekunde. Kasi ilipungua mara 9.

Kwa kuwa alama ilituonyesha uwezekano ulikuwa mkubwa mara 5, tulianza kuboresha. Tulibadilisha maktaba kuwa ioredis na tukapata utendakazi wa 25k kwa sekunde. Tuliongeza shughuli moja baada ya nyingine kwa kutumia amri ya `hset`. Kwa hivyo tulikuwa tukizalisha maswali mengi katika Redis. Wazo liliibuka la kuchanganya shughuli katika makundi na kuzituma kwa amri moja `hmset`. Matokeo yake ni 32k kwa sekunde.

Kwa sababu kadhaa, ambazo tutazielezea hapa chini, tunafanya kazi na data kwa kutumia `Buffer` na, kama inavyotokea, ukiibadilisha kuwa maandishi (`buffer.toString('hex')`) kabla ya kuandika, unaweza kupata ziada. utendaji. Kwa hivyo, kasi iliongezeka hadi 35k kwa sekunde. Kwa sasa, tuliamua kusimamisha uboreshaji zaidi.

Ilitubidi kubadili hadi itifaki ya binary kwa sababu:

1. Mfumo mara nyingi huhesabu heshi, saini, n.k., na kwa hili unahitaji data katika `Bafa.

2. Inapotumwa kati ya huduma, data ya jozi ina uzito chini ya maandishi. Kwa mfano, wakati wa kutuma kizuizi na miamala milioni 1, data katika maandishi inaweza kuchukua zaidi ya megabytes 300.

3. Kubadilisha data kila wakati huathiri utendaji.

Kwa hivyo, tulichukua kama msingi wetu itifaki ya binary ya kuhifadhi na kusambaza data, iliyotengenezwa kwa msingi wa maktaba ya ajabu ya `data-mbili`.

Kama matokeo, tulipata miundo ifuatayo ya data:

-Shughuli

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

- Ishara

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

-Kuzuia

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

Kwa amri za kawaida `BD.encode(block, Protocol).slice();` na `BD.decode(buffer, Protocol)` tunabadilisha data kuwa `Buffer` kwa kuhifadhi katika Redis au kusambaza kwa nodi nyingine na kurejesha data. data nyuma.

Pia tuna itifaki 2 za binary za kuhamisha data kati ya huduma:

- Itifaki ya mwingiliano na Njia ya Plasma kupitia tundu la unix

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

ambapo:

  • `aina` - hatua ya kufanywa, kwa mfano, 1 - sendTransaction, 2 - getTransaction;
  • `mzigo wa malipo` - data ambayo inahitaji kupitishwa kwa kazi inayofaa;
  • `kitambulisho cha ujumbe` - kitambulisho cha ujumbe ili jibu liweze kutambuliwa.

- Itifaki ya mwingiliano kati ya nodi

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

ambapo:

  • `code` - msimbo wa ujumbe, kwa mfano 6 - PREPARE_NEW_BLOCK, 7 - BLOCK_VALID, 8 - BLOCK_COMMIT;
  • `versionProtocol` - toleo la itifaki, kwani nodi zilizo na matoleo tofauti zinaweza kuinuliwa kwenye mtandao na zinaweza kufanya kazi tofauti;
  • `seq` - kitambulisho cha ujumbe;
  • `countChunk` ΠΈ `chunkNumber` muhimu kwa kugawanya ujumbe mkubwa;
  • `urefu` ΠΈ `mzigo wa malipo` urefu na data yenyewe.

Kwa kuwa tuliandika data mapema, mfumo wa mwisho una kasi zaidi kuliko maktaba ya `rlp` ya Ethereum. Kwa bahati mbaya, bado hatujaweza kuikataa, kwani ni muhimu kukamilisha mkataba mzuri, ambao tunapanga kufanya katika siku zijazo.

Ikiwa tulifanikiwa kufikia kasi 35 000 shughuli kwa sekunde, tunahitaji pia kuzichakata kwa wakati mwafaka. Kwa kuwa muda wa takriban wa kuunda block huchukua sekunde 30, tunahitaji kujumuisha kwenye kizuizi 1 000 000 shughuli, ambayo ina maana kutuma zaidi 100 MB ya data.

Hapo awali, tulitumia maktaba ya `ethereumjs-devp2p` kuwasiliana kati ya nodi, lakini haikuweza kushughulikia data nyingi. Kwa hivyo, tulitumia maktaba ya `ws` na kusanidi kutuma data ya jozi kupitia websocket. Bila shaka, pia tulikutana na matatizo wakati wa kutuma pakiti kubwa za data, lakini tuligawanya katika vipande na sasa matatizo haya yamekwenda.

Pia kutengeneza mti wa Merkle na kukokotoa heshi 1 000 000 shughuli inahitaji kuhusu 10 sekunde za hesabu inayoendelea. Wakati huu, uunganisho na nodes zote huweza kuvunja. Iliamuliwa kuhamisha hesabu hii kwa uzi tofauti.

Hitimisho:

Kwa kweli, matokeo yetu sio mapya, lakini kwa sababu fulani wataalam wengi husahau juu yao wakati wa kuendeleza.

  • Kutumia Upangaji Utendaji badala ya Upangaji Unaoelekezwa na Kitu huboresha tija.
  • Monolith ni mbaya zaidi kuliko usanifu wa huduma kwa mfumo wa NodeJS wenye tija.
  • Kutumia `nyuzi_za_za_kazi` kwa ukokotoaji mzito huboresha utendakazi wa mfumo, hasa wakati wa kushughulikia shughuli za i/o.
  • soketi ya unix ni thabiti zaidi na haraka kuliko maombi ya http.
  • Ikiwa unahitaji haraka kuhamisha data kubwa kwenye mtandao, ni bora kutumia soketi za wavuti na kutuma data ya binary, iliyogawanywa katika vipande, ambayo inaweza kutumwa ikiwa haifiki, na kisha kuunganishwa kwenye ujumbe mmoja.

Tunakualika kutembelea GitHub mradi: https://github.com/opporty-com/Plasma-Cash/tree/new-version

Makala hiyo iliandikwa na Alexander Nashivan, msanidi mkuu Kampuni ya Clever Solution Inc.

Chanzo: mapenzi.com

Kuongeza maoni