Ujian Awam: Penyelesaian untuk Privasi dan Kebolehskalaan pada Ethereum

Bloccain adalah teknologi inovatif yang menjanjikan untuk meningkatkan banyak bidang kehidupan manusia. Ia memindahkan proses dan produk sebenar ke dalam ruang digital, memastikan kelajuan dan kebolehpercayaan transaksi kewangan, mengurangkan kosnya, dan juga membolehkan anda mencipta aplikasi DAPP moden menggunakan kontrak pintar dalam rangkaian terdesentralisasi.

Memandangkan banyak faedah dan pelbagai aplikasi blockchain, nampaknya mengejutkan bahawa teknologi yang menjanjikan ini belum lagi memasuki setiap industri. Masalahnya ialah blockchain terdesentralisasi moden tidak berskala. Ethereum memproses kira-kira 20 transaksi sesaat, yang tidak mencukupi untuk memenuhi keperluan perniagaan dinamik hari ini. Pada masa yang sama, syarikat yang menggunakan teknologi blockchain teragak-agak untuk meninggalkan Ethereum kerana tahap perlindungannya yang tinggi daripada penggodaman dan kegagalan rangkaian.

Untuk memastikan desentralisasi, keselamatan dan kebolehskalaan dalam rantaian blok, sekali gus menyelesaikan Trilemma Skalabiliti, pasukan pembangunan Peluang mencipta Plasma Cash, rantaian subsidiari yang terdiri daripada kontrak pintar dan rangkaian persendirian berdasarkan Node.js, yang secara berkala memindahkan keadaannya kepada rantaian akar (Ethereum).

Ujian Awam: Penyelesaian untuk Privasi dan Kebolehskalaan pada Ethereum

Proses utama dalam Plasma Cash

1. Pengguna memanggil fungsi kontrak pintar `deposit`, memasukkan ke dalamnya amaun ETH yang dia mahu deposit ke dalam token Tunai Plasma. Fungsi kontrak pintar mencipta token dan menjana peristiwa mengenainya.

2. Nod Plasma Cash yang melanggan acara kontrak pintar menerima acara tentang membuat deposit dan menambah transaksi tentang membuat token ke kumpulan.

3. Secara berkala, nod Plasma Cash khas mengambil semua urus niaga daripada kumpulan (sehingga 1 juta) dan membentuk satu blok daripadanya, mengira pokok Merkle dan, dengan itu, cincang. Blok ini dihantar ke nod lain untuk pengesahan. Nod menyemak sama ada cincangan Merkle adalah sah dan sama ada urus niaga itu sah (contohnya, sama ada pengirim token adalah pemiliknya). Selepas mengesahkan blok, nod memanggil fungsi `submitBlock` kontrak pintar, yang menyimpan nombor blok dan cincang Merkle ke rantai tepi. Kontrak pintar menjana peristiwa yang menunjukkan kejayaan penambahan blok. Urus niaga dialih keluar dari kolam.

4. Nod yang menerima peristiwa penyerahan blok mula menggunakan urus niaga yang telah ditambahkan pada blok.

5. Pada satu ketika, pemilik (atau bukan pemilik) token ingin mengeluarkannya daripada Plasma Cash. Untuk melakukan ini, dia memanggil fungsi `startExit`, menghantar ke dalamnya maklumat tentang 2 transaksi terakhir pada token, yang mengesahkan bahawa dia adalah pemilik token. Kontrak pintar, menggunakan cincang Merkle, menyemak kehadiran transaksi dalam blok dan menghantar token untuk pengeluaran, yang akan berlaku dalam masa dua minggu.

6. Jika operasi pengeluaran token berlaku dengan pelanggaran (token telah dibelanjakan selepas prosedur pengeluaran bermula atau token sudah menjadi milik orang lain sebelum pengeluaran), pemilik token boleh menafikan pengeluaran dalam masa dua minggu.

Ujian Awam: Penyelesaian untuk Privasi dan Kebolehskalaan pada Ethereum

Privasi dicapai dalam dua cara

1. Rantaian akar tidak mengetahui apa-apa tentang urus niaga yang dijana dan dimajukan dalam rantaian anak. Maklumat tentang siapa yang mendeposit dan mengeluarkan ETH daripada Plasma Cash kekal terbuka.

2. Rantaian anak membenarkan transaksi tanpa nama menggunakan zk-SNARKs.

Timbunan teknologi

  • NodeJS
  • Redis
  • Ethereum
  • Tanah

Ujian

Semasa membangunkan Plasma Cash, kami menguji kelajuan sistem dan memperoleh keputusan berikut:

  • sehingga 35 transaksi sesaat ditambahkan pada kumpulan;
  • sehingga 1 transaksi boleh disimpan dalam satu blok.

Ujian telah dijalankan pada 3 pelayan berikut:

1. Intel Core i7-6700 Quad-Core Skylake termasuk. NVMe SSD – 512 GB, 64 GB DDR4 RAM
3 nod Tunai Plasma yang mengesahkan telah dinaikkan.

2. AMD Ryzen 7 1700X Octa-Core “Summit Ridge” (Zen), SATA SSD – 500 GB, 64 GB DDR4 RAM
Nod ETH testnet Ropsten dinaikkan.
3 nod Tunai Plasma yang mengesahkan telah dinaikkan.

3. Intel Core i9-9900K Octa-Core termasuk. NVMe SSD – 1 TB, 64 GB DDR4 RAM
1 nod penyerahan Plasma Cash dinaikkan.
3 nod Tunai Plasma yang mengesahkan telah dinaikkan.
Ujian telah dilancarkan untuk menambah transaksi pada rangkaian Plasma Cash.

Jumlah: 10 nod Tunai Plasma dalam rangkaian peribadi.

Ujian 1

Terdapat had 1 juta transaksi setiap blok. Oleh itu, 1 juta urus niaga jatuh ke dalam 2 blok (kerana sistem berjaya mengambil bahagian daripada urus niaga dan menyerahkan semasa ia dihantar).


Keadaan awal: blok terakhir #7; 1 juta transaksi dan token disimpan dalam pangkalan data.

00:00 — permulaan skrip penjanaan transaksi
01:37 - 1 juta transaksi telah dibuat dan penghantaran ke nod bermula
01:46 — serah nod mengambil 240k transaksi daripada kumpulan dan borang blok #8. Kami juga melihat bahawa 320k transaksi ditambahkan pada kumpulan dalam masa 10 saat
01:58 — blok #8 ditandatangani dan dihantar untuk pengesahan
02:03 — blok #8 disahkan dan fungsi `submitBlock` kontrak pintar dipanggil dengan cincang Merkle dan nombor blok
02:10 — skrip demo selesai berfungsi, yang menghantar 1 juta transaksi dalam masa 32 saat
02:33 - nod mula menerima maklumat bahawa blok #8 telah ditambahkan pada rantai akar, dan mula melakukan 240k transaksi
02:40 - 240k transaksi telah dialih keluar daripada kumpulan, yang sudah berada di blok #8
02:56 — serah nod mengambil baki 760k transaksi daripada kumpulan dan mula mengira cincang Merkle dan blok tandatangan #9
03:20 - semua nod mengandungi 1 juta 240k transaksi dan token
03:35 — blok #9 ditandatangani dan dihantar untuk pengesahan ke nod lain
03:41 - ralat rangkaian berlaku
04:40 — menunggu pengesahan blok #9 telah tamat masa
04:54 — serah nod mengambil baki 760k transaksi daripada kumpulan dan mula mengira cincang Merkle dan blok tandatangan #9
05:32 — blok #9 ditandatangani dan dihantar untuk pengesahan ke nod lain
05:53 — blok #9 disahkan dan dihantar ke rantai akar
06:17 - nod mula menerima maklumat bahawa blok #9 telah ditambahkan pada rantaian akar dan mula melakukan 760k transaksi
06:47 — kumpulan telah mengosongkan transaksi yang berada di blok #9
09:06 - semua nod mengandungi 2 juta transaksi dan token

Ujian 2

Terdapat had 350k setiap blok. Akibatnya, kami mempunyai 3 blok.


Keadaan awal: blok terakhir #9; 2 juta transaksi dan token disimpan dalam pangkalan data

00:00 — skrip penjanaan transaksi telah pun dilancarkan
00:44 - 1 juta transaksi telah dibuat dan penghantaran ke nod bermula
00:56 — serah nod mengambil 320k transaksi daripada kumpulan dan borang blok #10. Kami juga melihat bahawa 320k transaksi ditambahkan pada kumpulan dalam masa 10 saat
01:12 — blok #10 ditandatangani dan dihantar ke nod lain untuk pengesahan
01:18 — skrip demo selesai berfungsi, yang menghantar 1 juta transaksi dalam masa 34 saat
01:20 — blok #10 disahkan dan dihantar ke rantai akar
01:51 - semua nod menerima maklumat daripada rantai akar yang menyekat #10 telah ditambahkan dan mula menggunakan 320k transaksi
02:01 - kumpulan telah dibersihkan untuk 320k transaksi yang telah ditambahkan pada blok #10
02:15 — serah nod mengambil 350k transaksi daripada kumpulan dan borang blok #11
02:34 — blok #11 ditandatangani dan dihantar ke nod lain untuk pengesahan
02:51 — blok #11 disahkan dan dihantar ke rantai akar
02:55 — nod terakhir menyelesaikan transaksi dari blok #10
10:59 — transaksi dengan penyerahan blok #9 mengambil masa yang sangat lama dalam rantaian akar, tetapi ia telah selesai dan semua nod menerima maklumat mengenainya dan mula melakukan 350k transaksi
11:05 - kumpulan telah dibersihkan untuk 320k transaksi yang telah ditambahkan pada blok #11
12:10 - semua nod mengandungi 1 juta 670k transaksi dan token
12:17 — serah nod mengambil 330k transaksi daripada kumpulan dan borang blok #12
12:32 — blok #12 ditandatangani dan dihantar ke nod lain untuk pengesahan
12:39 — blok #12 disahkan dan dihantar ke rantai akar
13:44 - semua nod menerima maklumat daripada rantai akar yang menyekat #12 telah ditambahkan dan mula menggunakan 330k transaksi
14:50 - semua nod mengandungi 2 juta transaksi dan token

Ujian 3

Dalam pelayan pertama dan kedua, satu nod pengesahan telah digantikan dengan nod penyerahan.


Keadaan awal: blok terakhir #84; 0 transaksi dan token disimpan dalam pangkalan data

00:00 — 3 skrip telah dilancarkan yang menjana dan menghantar 1 juta transaksi setiap satu
01:38 — 1 juta transaksi telah dibuat dan penghantaran untuk menyerahkan nod #3 bermula
01:50 — serahkan nod #3 mengambil 330k transaksi daripada kumpulan dan borang blok #85 (f21). Kami juga melihat bahawa 350k transaksi ditambahkan pada kumpulan dalam masa 10 saat
01:53 — 1 juta transaksi telah dibuat dan penghantaran untuk menyerahkan nod #1 bermula
01:50 — serahkan nod #3 mengambil 330k transaksi daripada kumpulan dan borang blok #85 (f21). Kami juga melihat bahawa 350k transaksi ditambahkan pada kumpulan dalam masa 10 saat
02:01 — serahkan nod #1 mengambil 250k transaksi daripada kumpulan dan blok borang #85 (65e)
02:06 — blok #85 (f21) ditandatangani dan dihantar ke nod lain untuk pengesahan
02:08 — skrip demo pelayan #3, yang menghantar 1 juta transaksi dalam 30 saat, selesai berfungsi
02:14 — blok #85 (f21) disahkan dan dihantar ke rantai akar
02:19 — blok #85 (65e) ditandatangani dan dihantar ke nod lain untuk pengesahan
02:22 — 1 juta transaksi telah dibuat dan penghantaran untuk menyerahkan nod #2 bermula
02:27 — blok #85 (65e) disahkan dan dihantar ke rantaian akar
02:29 — serahkan nod #2 mengambil 111855 transaksi daripada kumpulan dan blok borang #85 (256).
02:36 — blok #85 (256) ditandatangani dan dihantar ke nod lain untuk pengesahan
02:36 — skrip demo pelayan #1, yang menghantar 1 juta transaksi dalam 42.5 saat, selesai berfungsi
02:38 — blok #85 (256) disahkan dan dihantar ke rantaian akar
03:08 — skrip pelayan #2 selesai berfungsi, yang menghantar 1 juta transaksi dalam masa 47 saat
03:38 - semua nod menerima maklumat daripada rantai akar yang menyekat #85 (f21), #86(65e), #87(256) telah ditambahkan dan mula menggunakan 330k, 250k, 111855 transaksi
03:49 - kumpulan telah dibersihkan pada 330k, 250k, 111855 transaksi yang ditambahkan pada blok #85 (f21), #86(65e), #87(256)
03:59 — serah nod #1 mengambil 888145 transaksi daripada kumpulan dan borang blok #88 (214), serah nod #2 mengambil 750k transaksi daripada kumpulan dan borang blok #88 (50a), serah nod #3 mengambil 670k transaksi daripada kolam dan borang blok #88 (d3b)
04:44 — blok #88 (d3b) ditandatangani dan dihantar ke nod lain untuk pengesahan
04:58 — blok #88 (214) ditandatangani dan dihantar ke nod lain untuk pengesahan
05:11 — blok #88 (50a) ditandatangani dan dihantar ke nod lain untuk pengesahan
05:11 — blok #85 (d3b) disahkan dan dihantar ke rantai akar
05:36 — blok #85 (214) disahkan dan dihantar ke rantaian akar
05:43 - semua nod menerima maklumat daripada rantai akar yang menyekat #88 (d3b), #89(214) telah ditambahkan dan mula menggunakan 670k, 750k transaksi
06:50 — disebabkan kegagalan komunikasi, blok #85 (50a) tidak disahkan
06:55 — serahkan nod #2 mengambil 888145 transaksi daripada kumpulan dan blok borang #90 (50a)
08:14 — blok #90 (50a) ditandatangani dan dihantar ke nod lain untuk pengesahan
09:04 — blok #90 (50a) disahkan dan dihantar ke rantaian akar
11:23 - semua nod menerima maklumat daripada rantai akar yang menyekat #90 (50a) telah ditambahkan dan mula menggunakan 888145 transaksi. Pada masa yang sama, pelayan #3 telah pun menggunakan transaksi dari blok #88 (d3b), #89(214)
12:11 - semua kolam kosong
13:41 — semua nod pelayan #3 mengandungi 3 juta transaksi dan token
14:35 — semua nod pelayan #1 mengandungi 3 juta transaksi dan token
19:24 — semua nod pelayan #2 mengandungi 3 juta transaksi dan token

Halangan

Semasa pembangunan Plasma Cash, kami menghadapi masalah berikut, yang secara beransur-ansur kami selesaikan dan sedang diselesaikan:

1. Konflik dalam interaksi pelbagai fungsi sistem. Sebagai contoh, fungsi menambah urus niaga ke kumpulan menyekat kerja menyerahkan dan mengesahkan blok, dan sebaliknya, yang membawa kepada penurunan kelajuan.

2. Tidak jelas dengan segera cara menghantar sejumlah besar transaksi sambil meminimumkan kos pemindahan data.

3. Tidak jelas bagaimana dan di mana untuk menyimpan data untuk mencapai hasil yang tinggi.

4. Tidak jelas cara mengatur rangkaian antara nod, kerana saiz blok dengan 1 juta transaksi mengambil kira-kira 100 MB.

5. Bekerja dalam mod satu-benang memutuskan sambungan antara nod apabila pengiraan panjang berlaku (contohnya, membina pokok Merkle dan mengira cincangnya).

Bagaimana kita menghadapi semua ini?

Versi pertama nod Plasma Cash ialah sejenis gabungan yang boleh melakukan segala-galanya pada masa yang sama: menerima urus niaga, menyerahkan dan mengesahkan blok dan menyediakan API untuk mengakses data. Memandangkan NodeJS secara asalnya berbenang tunggal, fungsi pengiraan pokok Merkle yang berat menyekat fungsi tambah transaksi. Kami melihat dua pilihan untuk menyelesaikan masalah ini:

1. Lancarkan beberapa proses NodeJS, setiap satunya menjalankan fungsi tertentu.

2. Gunakan worker_threads dan alihkan pelaksanaan sebahagian kod ke dalam benang.

Akibatnya, kami menggunakan kedua-dua pilihan pada masa yang sama: kami secara logik membahagikan satu nod kepada 3 bahagian yang boleh berfungsi secara berasingan, tetapi pada masa yang sama serentak

1. Nod penyerahan, yang menerima transaksi ke dalam kumpulan dan mencipta blok.

2. Nod pengesahan yang menyemak kesahihan nod.

3. Nod API - menyediakan API untuk mengakses data.

Dalam kes ini, anda boleh menyambung ke setiap nod melalui soket unix menggunakan cli.

Kami memindahkan operasi berat, seperti mengira pokok Merkle, ke dalam benang yang berasingan.

Oleh itu, kami telah mencapai operasi normal semua fungsi Plasma Cash secara serentak dan tanpa kegagalan.

Setelah sistem berfungsi, kami mula menguji kelajuan dan, malangnya, menerima keputusan yang tidak memuaskan: 5 transaksi sesaat dan sehingga 000 transaksi setiap blok. Saya terpaksa memikirkan apa yang dilaksanakan secara tidak betul.

Sebagai permulaan, kami mula menguji mekanisme komunikasi dengan Plasma Cash untuk mengetahui keupayaan puncak sistem. Kami telah menulis sebelum ini bahawa nod Plasma Cash menyediakan antara muka soket unix. Pada mulanya ia berasaskan teks. objek json telah dihantar menggunakan `JSON.parse()` dan `JSON.stringify()`.

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

Kami mengukur kelajuan pemindahan objek tersebut dan mendapati ~ 130k sesaat. Kami cuba menggantikan fungsi standard untuk bekerja dengan json, tetapi prestasi tidak bertambah baik. Enjin V8 mesti dioptimumkan dengan baik untuk operasi ini.

Kami bekerja dengan urus niaga, token dan blok melalui kelas. Apabila mencipta kelas sedemikian, prestasi menurun sebanyak 2 kali, yang menunjukkan bahawa OOP tidak sesuai untuk kami. Saya terpaksa menulis semula segala-galanya kepada pendekatan yang berfungsi semata-mata.

Merekod dalam pangkalan data

Pada mulanya, Redis dipilih untuk penyimpanan data sebagai salah satu penyelesaian paling produktif yang memenuhi keperluan kami: penyimpanan nilai kunci, bekerja dengan jadual cincang, set. Kami melancarkan penanda aras semula dan mendapat ~80k operasi sesaat dalam 1 mod saluran paip.

Untuk prestasi tinggi, kami menala Redis dengan lebih halus:

  • Sambungan soket unix telah diwujudkan.
  • Kami melumpuhkan menyimpan keadaan ke cakera (untuk kebolehpercayaan, anda boleh menyediakan replika dan menyimpan ke cakera dalam Redis yang berasingan).

Dalam Redis, pool ialah jadual cincang kerana kita perlu dapat mengambil semua transaksi dalam satu pertanyaan dan memadamkan transaksi satu demi satu. Kami cuba menggunakan senarai biasa, tetapi ia lebih perlahan apabila memunggah keseluruhan senarai.

Apabila menggunakan NodeJS standard, perpustakaan Redis mencapai prestasi 18k transaksi sesaat. Kelajuan menurun 9 kali ganda.

Oleh kerana penanda aras menunjukkan kepada kami kemungkinan adalah jelas 5 kali lebih besar, kami mula mengoptimumkan. Kami menukar perpustakaan kepada ioredis dan mendapat prestasi 25k sesaat. Kami menambah transaksi satu demi satu menggunakan arahan `hset`. Jadi kami telah menghasilkan banyak pertanyaan dalam Redis. Idea timbul untuk menggabungkan transaksi ke dalam kelompok dan menghantarnya dengan satu arahan `hmset`. Hasilnya ialah 32k sesaat.

Atas beberapa sebab, yang akan kami terangkan di bawah, kami bekerja dengan data menggunakan `Buffer` dan, ternyata, jika anda menukarnya kepada teks (`buffer.toString('hex')`) sebelum menulis, anda boleh mendapatkan tambahan prestasi. Oleh itu, kelajuan meningkat kepada 35k sesaat. Pada masa ini, kami memutuskan untuk menggantung pengoptimuman selanjutnya.

Kami terpaksa bertukar kepada protokol binari kerana:

1. Sistem sering mengira cincang, tandatangan, dsb., dan untuk ini ia memerlukan data dalam `Buffer.

2. Apabila dihantar antara perkhidmatan, berat data binari kurang daripada teks. Sebagai contoh, apabila menghantar blok dengan 1 juta transaksi, data dalam teks boleh mengambil lebih daripada 300 megabait.

3. Mengubah data secara berterusan menjejaskan prestasi.

Oleh itu, kami mengambil sebagai asas protokol binari kami sendiri untuk menyimpan dan menghantar data, yang dibangunkan berdasarkan perpustakaan `data-binari` yang indah.

Akibatnya, kami mendapat struktur data berikut:

-Transaksi

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

—Sekat

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

Dengan arahan biasa `BD.encode(block, Protocol).slice();` dan `BD.decode(buffer, Protocol)` kami menukar data kepada `Buffer` untuk disimpan dalam Redis atau memajukan ke nod lain dan mendapatkan semula data kembali.

Kami juga mempunyai 2 protokol binari untuk memindahkan data antara perkhidmatan:

— Protokol untuk interaksi dengan Nod Plasma melalui soket 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)
  }
  ```

di mana:

  • `Type` — tindakan yang akan dilakukan, sebagai contoh, 1 — sendTransaction, 2 — getTransaction;
  • `muatan` — data yang perlu dihantar ke fungsi yang sesuai;
  • `messageId` — id mesej supaya respons dapat dikenal pasti.

— Protokol untuk interaksi antara nod

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

di mana:

  • `kod` — kod mesej, contohnya 6 — PREPARE_NEW_BLOCK, 7 — BLOCK_VALID, 8 — BLOCK_COMMIT;
  • `versionProtocol` — versi protokol, kerana nod dengan versi berbeza boleh dinaikkan pada rangkaian dan ia boleh berfungsi secara berbeza;
  • `seq` — pengecam mesej;
  • `countChunk` и `chunkNumber` diperlukan untuk memisahkan mesej besar;
  • `panjang` и `muatan` panjang dan data itu sendiri.

Memandangkan kami menaip data terlebih dahulu, sistem akhir adalah lebih pantas daripada perpustakaan `rlp` Ethereum. Malangnya, kami masih belum dapat menolaknya, kerana kontrak pintar itu perlu dimuktamadkan, yang kami rancang untuk lakukan pada masa hadapan.

Jika kita berjaya mencapai kelajuan 35 000 transaksi sesaat, kita juga perlu memprosesnya dalam masa yang optimum. Memandangkan anggaran masa pembentukan blok mengambil masa 30 saat, kita perlu memasukkan dalam blok 1 000 000 transaksi, yang bermaksud menghantar lebih banyak 100 MB data.

Pada mulanya, kami menggunakan perpustakaan `ethereumjs-devp2p` untuk berkomunikasi antara nod, tetapi ia tidak dapat mengendalikan begitu banyak data. Hasilnya, kami menggunakan perpustakaan `ws` dan mengkonfigurasikan penghantaran data binari melalui soket web. Sudah tentu, kami juga menghadapi masalah semasa menghantar paket data yang besar, tetapi kami membahagikannya kepada beberapa bahagian dan kini masalah ini telah hilang.

Juga membentuk pokok Merkle dan mengira cincang 1 000 000 urus niaga memerlukan kira-kira 10 saat pengiraan berterusan. Pada masa ini, sambungan dengan semua nod berjaya putus. Ia telah memutuskan untuk mengalihkan pengiraan ini ke urutan yang berasingan.

Kesimpulan:

Sebenarnya, penemuan kami bukanlah sesuatu yang baru, tetapi atas sebab tertentu ramai pakar melupakannya semasa membangun.

  • Menggunakan Pengaturcaraan Fungsian dan bukannya Pengaturcaraan Berorientasikan Objek meningkatkan produktiviti.
  • Monolit lebih teruk daripada seni bina perkhidmatan untuk sistem NodeJS yang produktif.
  • Menggunakan `benang_pekerja` untuk pengiraan berat meningkatkan responsif sistem, terutamanya apabila berurusan dengan operasi i/o.
  • soket unix lebih stabil dan lebih pantas daripada permintaan http.
  • Sekiranya anda perlu memindahkan data besar dengan cepat melalui rangkaian, lebih baik menggunakan soket web dan menghantar data binari, dibahagikan kepada ketulan, yang boleh dimajukan jika mereka tidak tiba, dan kemudian digabungkan menjadi satu mesej.

Kami menjemput anda untuk melawat GitHub projek: https://github.com/opporty-com/Plasma-Cash/tree/new-version

Artikel itu ditulis bersama oleh Alexander Nashivan, pemaju kanan Clever Solution Inc.

Sumber: www.habr.com

Tambah komen