Uji Publik: Solusi untuk Privasi dan Skalabilitas di Ethereum

окчейн adalah teknologi inovatif yang menjanjikan untuk meningkatkan banyak bidang kehidupan manusia. Ini mentransfer proses dan produk nyata ke dalam ruang digital, memastikan kecepatan dan keandalan transaksi keuangan, mengurangi biayanya, dan juga memungkinkan Anda membuat aplikasi DAPP modern menggunakan kontrak pintar di jaringan terdesentralisasi.

Mengingat banyaknya manfaat dan beragam penerapan blockchain, mungkin mengejutkan bahwa teknologi yang menjanjikan ini belum diterapkan di setiap industri. Masalahnya adalah blockchain modern yang terdesentralisasi tidak memiliki skalabilitas. Ethereum memproses sekitar 20 transaksi per detik, yang tidak cukup untuk memenuhi kebutuhan bisnis dinamis saat ini. Pada saat yang sama, perusahaan yang menggunakan teknologi blockchain ragu-ragu untuk meninggalkan Ethereum karena tingkat perlindungannya yang tinggi terhadap peretasan dan kegagalan jaringan.

Untuk memastikan desentralisasi, keamanan dan skalabilitas dalam blockchain, sehingga memecahkan Trilema Skalabilitas, tim pengembangan Opporty menciptakan Plasma Cash, rantai anak perusahaan yang terdiri dari kontrak pintar dan jaringan pribadi berdasarkan Node.js, yang secara berkala mentransfer statusnya ke rantai akar (Ethereum).

Uji Publik: Solusi untuk Privasi dan Skalabilitas di Ethereum

Proses utama dalam Plasma Cash

1. Pengguna memanggil fungsi kontrak pintar `deposit`, meneruskan ke dalamnya jumlah ETH yang ingin dia setorkan ke dalam token Plasma Cash. Fungsi kontrak pintar membuat token dan menghasilkan peristiwa tentangnya.

2. Node Plasma Cash yang berlangganan acara kontrak pintar menerima acara tentang pembuatan deposit dan menambahkan transaksi tentang pembuatan token ke kumpulan.

3. Secara berkala, node Plasma Cash khusus mengambil semua transaksi dari kumpulan (hingga 1 juta) dan membentuk blok darinya, menghitung pohon Merkle dan, karenanya, hashnya. Blok ini dikirim ke node lain untuk verifikasi. Node memeriksa apakah hash Merkle valid dan apakah transaksinya valid (misalnya, apakah pengirim token adalah pemiliknya). Setelah memverifikasi blok, node memanggil fungsi `submitBlock` dari kontrak pintar, yang menyimpan nomor blok dan hash Merkle ke rantai tepi. Kontrak pintar menghasilkan peristiwa yang menunjukkan keberhasilan penambahan blok. Transaksi dihapus dari kumpulan.

4. Node yang menerima event penyerahan blok mulai menerapkan transaksi yang ditambahkan ke blok.

5. Pada titik tertentu, pemilik (atau bukan pemilik) token ingin menariknya dari Plasma Cash. Untuk melakukan ini, dia memanggil fungsi `startExit`, meneruskan ke dalamnya informasi tentang 2 transaksi terakhir pada token, yang mengonfirmasi bahwa dia adalah pemilik token tersebut. Kontrak pintar, menggunakan hash Merkle, memeriksa keberadaan transaksi di blok dan mengirimkan token untuk penarikan, yang akan dilakukan dalam dua minggu.

6. Jika operasi penarikan token terjadi dengan pelanggaran (token dihabiskan setelah prosedur penarikan dimulai atau token sudah menjadi milik orang lain sebelum penarikan), pemilik token dapat menolak penarikan tersebut dalam waktu dua minggu.

Uji Publik: Solusi untuk Privasi dan Skalabilitas di Ethereum

Privasi dicapai dengan dua cara

1. Rantai akar tidak mengetahui apa pun tentang transaksi yang dihasilkan dan diteruskan dalam rantai anak. Informasi tentang siapa yang menyetor dan menarik ETH dari Plasma Cash tetap bersifat publik.

2. Rantai anak memungkinkan transaksi anonim menggunakan zk-SNARKs.

Tumpukan teknologi

  • NodeJS
  • Redis
  • Etherium
  • tanah

Pengujian

Saat mengembangkan Plasma Cash, kami menguji kecepatan sistem dan memperoleh hasil sebagai berikut:

  • hingga 35 transaksi per detik ditambahkan ke kumpulan;
  • hingga 1 transaksi dapat disimpan dalam satu blok.

Pengujian dilakukan pada 3 server berikut:

1. Intel Core i7-6700 Quad-Core Skylake termasuk. NVMe SSD – 512 GB, RAM DDR64 4 GB
3 node Plasma Cash yang memvalidasi telah dibangkitkan.

2. AMD Ryzen 7 1700X Octa-Core “Summit Ridge” (Zen), SSD SATA – 500 GB, RAM DDR64 4 GB
Node ETH testnet Ropsten dinaikkan.
3 node Plasma Cash yang memvalidasi telah dibangkitkan.

3. Intel Core i9-9900K Octa-Core termasuk. NVMe SSD – 1 TB, RAM DDR64 4 GB
1 node pengiriman Plasma Cash dinaikkan.
3 node Plasma Cash yang memvalidasi telah dibangkitkan.
Tes diluncurkan untuk menambahkan transaksi ke jaringan Plasma Cash.

Total: 10 node Plasma Cash di jaringan pribadi.

Tes 1

Ada batasan 1 juta transaksi per blok. Oleh karena itu, 1 juta transaksi terbagi dalam 2 blok (karena sistem berhasil mengambil bagian dari transaksi dan mengirimkannya saat sedang dikirim).


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

00:00 — permulaan skrip pembuatan transaksi
01:37 - 1 juta transaksi dibuat dan pengiriman ke node dimulai
01:46 — simpul pengiriman mengambil 240 ribu transaksi dari kumpulan dan membentuk blok #8. Kami juga melihat 320 ribu transaksi ditambahkan ke kumpulan dalam 10 detik
01:58 — blok #8 ditandatangani dan dikirim untuk validasi
02:03 — blok #8 divalidasi dan fungsi `submitBlock` dari kontrak pintar dipanggil dengan hash Merkle dan nomor blok
02:10 — skrip demo selesai berfungsi, yang mengirimkan 1 juta transaksi dalam 32 detik
02:33 - node mulai menerima informasi bahwa blok #8 telah ditambahkan ke rantai akar, dan mulai melakukan 240 ribu transaksi
02:40 - 240 ribu transaksi telah dihapus dari pool, yang sudah ada di blok #8
02:56 — simpul pengiriman mengambil sisa 760 ribu transaksi dari kumpulan dan mulai menghitung hash Merkle dan blok penandatanganan #9
03:20 - semua node berisi 1 juta 240 ribu transaksi dan token
03:35 — blok #9 ditandatangani dan dikirim untuk validasi ke node lain
03:41 - terjadi kesalahan jaringan
04:40 — menunggu validasi blok #9 telah habis waktunya
04:54 — simpul pengiriman mengambil sisa 760 ribu transaksi dari kumpulan dan mulai menghitung hash Merkle dan blok penandatanganan #9
05:32 — blok #9 ditandatangani dan dikirim untuk validasi ke node lain
05:53 — blok #9 divalidasi dan dikirim ke rantai akar
06:17 - node mulai menerima informasi bahwa blok #9 telah ditambahkan ke rantai akar dan mulai melakukan 760 ribu transaksi
06:47 — kumpulan telah dibersihkan dari transaksi yang ada di blok #9
09:06 - semua node berisi 2 juta transaksi dan token

Tes 2

Ada batas 350k per blok. Hasilnya, kami memiliki 3 blok.


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

00:00 — skrip pembuatan transaksi telah diluncurkan
00:44 - 1 juta transaksi dibuat dan pengiriman ke node dimulai
00:56 — simpul pengiriman mengambil 320 ribu transaksi dari kumpulan dan membentuk blok #10. Kami juga melihat 320 ribu transaksi ditambahkan ke kumpulan dalam 10 detik
01:12 — blok #10 ditandatangani dan dikirim ke node lain untuk validasi
01:18 — skrip demo selesai berfungsi, yang mengirimkan 1 juta transaksi dalam 34 detik
01:20 — blok #10 divalidasi dan dikirim ke rantai akar
01:51 - semua node menerima informasi dari rantai akar bahwa blok #10 telah ditambahkan dan mulai menerapkan 320 ribu transaksi
02:01 - kumpulan telah dibersihkan untuk 320 ribu transaksi yang ditambahkan ke blok #10
02:15 — simpul pengiriman mengambil 350 ribu transaksi dari kumpulan dan membentuk blok #11
02:34 — blok #11 ditandatangani dan dikirim ke node lain untuk validasi
02:51 — blok #11 divalidasi dan dikirim ke rantai akar
02:55 — node terakhir menyelesaikan transaksi dari blok #10
10:59 — transaksi dengan penyerahan blok #9 membutuhkan waktu yang sangat lama di rantai akar, tetapi transaksi tersebut selesai dan semua node menerima informasi tentang hal tersebut dan mulai melakukan 350 ribu transaksi
11:05 - kumpulan telah dibersihkan untuk 320 ribu transaksi yang ditambahkan ke blok #11
12:10 - semua node berisi 1 juta 670 ribu transaksi dan token
12:17 — simpul pengiriman mengambil 330 ribu transaksi dari kumpulan dan membentuk blok #12
12:32 — blok #12 ditandatangani dan dikirim ke node lain untuk validasi
12:39 — blok #12 divalidasi dan dikirim ke rantai akar
13:44 - semua node menerima informasi dari rantai akar bahwa blok #12 telah ditambahkan dan mulai menerapkan 330 ribu transaksi
14:50 - semua node berisi 2 juta transaksi dan token

Tes 3

Di server pertama dan kedua, satu node validasi digantikan oleh node pengirim.


Keadaan awal: blok terakhir #84; 0 transaksi dan token disimpan di database

00:00 — 3 skrip telah diluncurkan yang masing-masing menghasilkan dan mengirim 1 juta transaksi
01:38 — 1 juta transaksi dibuat dan pengiriman ke node #3 dimulai
01:50 — kirim node #3 mengambil 330 ribu transaksi dari kumpulan dan membentuk blok #85 (f21). Kami juga melihat 350 ribu transaksi ditambahkan ke kumpulan dalam 10 detik
01:53 — 1 juta transaksi dibuat dan pengiriman ke node #1 dimulai
01:50 — kirim node #3 mengambil 330 ribu transaksi dari kumpulan dan membentuk blok #85 (f21). Kami juga melihat 350 ribu transaksi ditambahkan ke kumpulan dalam 10 detik
02:01 — kirim node #1 mengambil 250 ribu transaksi dari kumpulan dan membentuk blok #85 (65e)
02:06 — blok #85 (f21) ditandatangani dan dikirim ke node lain untuk validasi
02:08 — skrip demo server #3, yang mengirimkan 1 juta transaksi dalam 30 detik, selesai berfungsi
02:14 — blok #85 (f21) divalidasi dan dikirim ke rantai akar
02:19 — blok #85 (65e) ditandatangani dan dikirim ke node lain untuk validasi
02:22 — 1 juta transaksi dibuat dan pengiriman ke node #2 dimulai
02:27 — blok #85 (65e) divalidasi dan dikirim ke rantai akar
02:29 — kirim node #2 mengambil 111855 transaksi dari pool dan membentuk blok #85 (256).
02:36 — blok #85 (256) ditandatangani dan dikirim ke node lain untuk validasi
02:36 — skrip demo server #1, yang mengirimkan 1 juta transaksi dalam 42.5 detik, selesai berfungsi
02:38 — blok #85 (256) divalidasi dan dikirim ke rantai akar
03:08 — skrip server #2 selesai bekerja, yang mengirimkan 1 juta transaksi dalam 47 detik
03:38 - semua node menerima informasi dari rantai akar yang memblokir #85 (f21), #86(65e), #87(256) ditambahkan dan mulai menerapkan 330k, 250k, 111855 transaksi
03:49 - kumpulan diselesaikan pada 330k, 250k, 111855 transaksi yang ditambahkan ke blok #85 (f21), #86(65e), #87(256)
03:59 — kirim node #1 mengambil 888145 transaksi dari pool dan membentuk blok #88 (214), submit node #2 mengambil 750 ribu transaksi dari pool dan membentuk blok #88 (50a), submit node #3 mengambil 670 ribu transaksi dari kolam dan formulir blok #88 (d3b)
04:44 — blok #88 (d3b) ditandatangani dan dikirim ke node lain untuk validasi
04:58 — blok #88 (214) ditandatangani dan dikirim ke node lain untuk validasi
05:11 — blok #88 (50a) ditandatangani dan dikirim ke node lain untuk validasi
05:11 — blok #85 (d3b) divalidasi dan dikirim ke rantai akar
05:36 — blok #85 (214) divalidasi dan dikirim ke rantai akar
05:43 - semua node menerima informasi dari rantai akar yang memblokir #88 (d3b), #89(214) telah ditambahkan dan mulai menerapkan 670k, 750k transaksi
06:50 — karena kegagalan komunikasi, blok #85 (50a) tidak divalidasi
06:55 — kirim node #2 mengambil 888145 transaksi dari pool dan membentuk blok #90 (50a)
08:14 — blok #90 (50a) ditandatangani dan dikirim ke node lain untuk validasi
09:04 — blok #90 (50a) divalidasi dan dikirim ke rantai akar
11:23 - semua node menerima informasi dari rantai akar bahwa blok #90 (50a) telah ditambahkan, dan mulai menerapkan 888145 transaksi. Pada saat yang sama, server #3 telah menerapkan transaksi dari blok #88 (d3b), #89(214)
12:11 - semua kolam kosong
13:41 — semua node server #3 berisi 3 juta transaksi dan token
14:35 — semua node server #1 berisi 3 juta transaksi dan token
19:24 — semua node server #2 berisi 3 juta transaksi dan token

Hambatan

Selama pengembangan Plasma Cash, kami menemui masalah-masalah berikut, yang secara bertahap kami pecahkan dan selesaikan:

1. Konflik dalam interaksi berbagai fungsi sistem. Misalnya, fungsi menambahkan transaksi ke kumpulan memblokir pekerjaan pengiriman dan validasi blok, dan sebaliknya, yang menyebabkan penurunan kecepatan.

2. Belum jelas bagaimana cara mengirim transaksi dalam jumlah besar sambil meminimalkan biaya transfer data.

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

4. Tidak jelas bagaimana mengatur jaringan antar node, karena ukuran blok dengan 1 juta transaksi memakan waktu sekitar 100 MB.

5. Bekerja dalam mode single-thread memutus koneksi antar node ketika perhitungan panjang terjadi (misalnya, membangun pohon Merkle dan menghitung hashnya).

Bagaimana kita menghadapi semua ini?

Versi pertama dari node Plasma Cash adalah sejenis gabungan yang dapat melakukan semuanya secara bersamaan: menerima transaksi, mengirimkan dan memvalidasi blok, dan menyediakan API untuk mengakses data. Karena NodeJS pada dasarnya adalah single-threaded, fungsi perhitungan pohon Merkle yang berat memblokir fungsi penambahan transaksi. Kami melihat dua opsi untuk menyelesaikan masalah ini:

1. Luncurkan beberapa proses NodeJS, yang masing-masing menjalankan fungsi tertentu.

2. Gunakan Work_threads dan pindahkan eksekusi sebagian kode ke dalam thread.

Hasilnya, kami menggunakan kedua opsi secara bersamaan: kami secara logis membagi satu node menjadi 3 bagian yang dapat bekerja secara terpisah, tetapi pada saat yang sama secara sinkron.

1. Node penyerahan, yang menerima transaksi ke dalam kumpulan dan membuat blok.

2. Node validasi yang memeriksa validitas node.

3. Node API - menyediakan API untuk mengakses data.

Dalam hal ini, Anda dapat terhubung ke setiap node melalui soket unix menggunakan cli.

Kami memindahkan operasi berat, seperti penghitungan pohon Merkle, ke thread terpisah.

Dengan demikian, kami telah mencapai pengoperasian normal semua fungsi Plasma Cash secara bersamaan dan tanpa kegagalan.

Setelah sistem berfungsi, kami mulai menguji kecepatannya dan, sayangnya, menerima hasil yang tidak memuaskan: 5 transaksi per detik dan hingga 000 transaksi per blok. Saya harus mencari tahu apa yang diterapkan secara tidak benar.

Untuk memulainya, kami mulai menguji mekanisme komunikasi dengan Plasma Cash untuk mengetahui kemampuan puncak sistem. Kami menulis sebelumnya bahwa node Plasma Cash menyediakan antarmuka soket unix. Awalnya berbasis teks. objek json dikirim 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 kecepatan transfer objek tersebut dan menemukan ~ 130k per detik. Kami mencoba mengganti fungsi standar untuk bekerja dengan json, tetapi kinerjanya tidak meningkat. Mesin V8 harus dioptimalkan dengan baik untuk pengoperasian ini.

Kami bekerja dengan transaksi, token, dan blok melalui kelas. Saat membuat kelas seperti itu, kinerjanya turun 2 kali lipat, yang menunjukkan bahwa OOP tidak cocok untuk kami. Saya harus menulis ulang semuanya ke pendekatan yang murni fungsional.

Merekam di database

Awalnya, Redis dipilih untuk penyimpanan data sebagai salah satu solusi paling produktif yang memenuhi persyaratan kami: penyimpanan nilai kunci, bekerja dengan tabel hash, set. Kami meluncurkan redis-benchmark dan mendapatkan ~80 ribu operasi per detik dalam 1 mode pipeline.

Untuk performa tinggi, kami menyempurnakan Redis:

  • Koneksi soket unix telah dibuat.
  • Kami menonaktifkan penyimpanan status ke disk (untuk keandalan, Anda dapat menyiapkan replika dan menyimpan ke disk di Redis terpisah).

Di Redis, pool adalah tabel hash karena kita harus bisa mengambil semua transaksi dalam satu query dan menghapus transaksi satu per satu. Kami mencoba menggunakan daftar biasa, tetapi lebih lambat saat membongkar seluruh daftar.

Saat menggunakan NodeJS standar, perpustakaan Redis mencapai kinerja 18 ribu transaksi per detik. Kecepatannya turun 9 kali lipat.

Karena tolok ukur menunjukkan kepada kami kemungkinannya jelas 5 kali lebih besar, kami mulai mengoptimalkannya. Kami mengubah perpustakaan menjadi ioredis dan mendapatkan kinerja 25k per detik. Kami menambahkan transaksi satu per satu menggunakan perintah `hset`. Jadi kami menghasilkan banyak pertanyaan di Redis. Muncul ide untuk menggabungkan transaksi ke dalam batch dan mengirimkannya dengan satu perintah `hmset`. Hasilnya adalah 32k per detik.

Karena beberapa alasan, yang akan kami jelaskan di bawah, kami bekerja dengan data menggunakan `Buffer` dan, ternyata, jika Anda mengonversinya menjadi teks (`buffer.toString('hex')`) sebelum menulis, Anda bisa mendapatkan tambahan pertunjukan. Dengan demikian, kecepatannya ditingkatkan menjadi 35k per detik. Saat ini, kami memutuskan untuk menunda pengoptimalan lebih lanjut.

Kami harus beralih ke protokol biner karena:

1. Sistem sering kali menghitung hash, tanda tangan, dll., dan untuk ini memerlukan data di `Buffer.

2. Saat dikirim antar layanan, data biner berbobot lebih ringan daripada teks. Misalnya, saat mengirim blok dengan 1 juta transaksi, data dalam teks bisa memakan lebih dari 300 megabyte.

3. Transformasi data yang terus-menerus memengaruhi kinerja.

Oleh karena itu, kami menggunakan protokol biner kami sendiri untuk menyimpan dan mengirimkan data, yang dikembangkan berdasarkan perpustakaan `data biner` yang luar biasa.

Hasilnya, kami mendapatkan 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,
  }
  ```

— Tanda

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

-Memblokir

  ```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 perintah biasa `BD.encode(block, Protocol).slice();` dan `BD.decode(buffer, Protocol)` kami mengonversi data menjadi `Buffer` untuk disimpan di Redis atau meneruskan ke node lain dan mengambil data kembali.

Kami juga memiliki 2 protokol biner untuk mentransfer data antar layanan:

— Protokol untuk interaksi dengan Plasma Node 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:

  • `ketik` — tindakan yang akan dilakukan, misalnya, 1 — sendTransaction, 2 — getTransaction;
  • `muatan` — data yang perlu diteruskan ke fungsi yang sesuai;
  • `pesanId` — id pesan sehingga respons dapat diidentifikasi.

— Protokol untuk interaksi antar node

  ```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:

  • `kode` — kode pesan, misalnya 6 — PREPARE_NEW_BLOCK, 7 — BLOCK_VALID, 8 — BLOCK_COMMIT;
  • `versiProtokol` — versi protokol, karena node dengan versi berbeda dapat dimunculkan di jaringan dan bekerja secara berbeda;
  • `seq` — pengidentifikasi pesan;
  • `hitungBagian` и `Nomor potongan` diperlukan untuk memisahkan pesan berukuran besar;
  • `panjang` и `muatan` panjang dan data itu sendiri.

Karena kami telah mengetikkan data sebelumnya, sistem akhir jauh lebih cepat daripada perpustakaan `rlp` Ethereum. Sayangnya, kami belum bisa menolaknya, karena smart contract yang rencananya akan kami lakukan di masa mendatang perlu diselesaikan.

Jika kita berhasil mencapai kecepatannya 35 000 transaksi per detik, kita juga perlu memprosesnya dalam waktu yang optimal. Karena perkiraan waktu pembentukan blok membutuhkan waktu 30 detik, kita perlu memasukkannya ke dalam blok 1 000 000 transaksi, yang berarti mengirim lebih banyak 100 MB data.

Awalnya, kami menggunakan perpustakaan `ethereumjs-devp2p` untuk berkomunikasi antar node, namun tidak dapat menangani begitu banyak data. Hasilnya, kami menggunakan perpustakaan `ws` dan mengonfigurasi pengiriman data biner melalui websocket. Tentu saja kami juga mengalami masalah saat mengirim paket data yang besar, tetapi kami membaginya menjadi beberapa bagian dan sekarang masalah tersebut hilang.

Juga membentuk pohon Merkle dan menghitung hash 1 000 000 transaksi membutuhkan tentang 10 detik perhitungan terus menerus. Selama waktu ini, koneksi dengan semua node berhasil diputus. Diputuskan untuk memindahkan perhitungan ini ke thread terpisah.

Kesimpulan:

Sebenarnya temuan kami bukanlah hal baru, namun entah kenapa banyak ahli yang melupakannya saat mengembangkannya.

  • Menggunakan Pemrograman Fungsional daripada Pemrograman Berorientasi Objek meningkatkan produktivitas.
  • Monolit lebih buruk daripada arsitektur layanan untuk sistem NodeJS yang produktif.
  • Menggunakan `worker_threads` untuk komputasi berat akan meningkatkan respons sistem, terutama saat menangani operasi i/o.
  • soket unix lebih stabil dan lebih cepat daripada permintaan http.
  • Jika Anda perlu mentransfer data besar dengan cepat melalui jaringan, lebih baik menggunakan soket web dan mengirim data biner, dibagi menjadi beberapa bagian, yang dapat diteruskan jika tidak sampai, dan kemudian digabungkan menjadi satu pesan.

Kami mengundang Anda untuk berkunjung GitHub proyek: https://github.com/opporty-com/Plasma-Cash/tree/new-version

Artikel ini ditulis bersama oleh Alexander Nashivan, pengembang senior Solusi Cerdas Inc.

Sumber: www.habr.com

Tambah komentar