Seperti kami tidak memblokir rantai

Bagaimana kami menggunakan kontrak pintar untuk membangun sistem untuk memilih proyek teknologi terbaik di IT MTS? Dan “jebakan” apa yang kita miliki, tetapi mampu keluar, membuktikan pada akhirnya bahwa adalah mungkin untuk mempertahankan registri terdistribusi pada perangkat seluler!



Mengapa diperlukan sistem berbasis blockchain?


Mari kita mulai dari awal. MTS memiliki tradisi panjang - untuk memilih proyek teknologi terbaik yang dibuat dalam setahun dan menghargai timnya. Tim menerima hadiah, penghargaan, dan ketenaran. Selama bertahun-tahun, berbagai proyek telah menjadi pemenang: dari sistem telekomunikasi yang sangat sarat dengan sistem kecerdasan buatan.

Pemilihan proyek terbaik selalu terjadi dalam beberapa tahap:

  • Tim berlaku
  • Pemilihan ahli teknis yang dihormati terjadi
  • Setelah ahli, proyek dipilih oleh manajer
  • Setelah menyelesaikan semua tahapan, bos besar memilih proyek terbaik.

Kami memutuskan bahwa skema ini tidak cukup transparan untuk para peserta dan berpikir: mengapa tidak memberikan sama sekali semua ahli di perusahaan kesempatan untuk memilih proyek teknologi terbaik? 


Jika kami menerapkan peluang ini tepat di telepon, kami akan melihat peringkat proyek saat ini dan siapa yang memilih siapa - ini akan memastikan transparansi penuh dari proses.

Kami membaca beberapa artikel tentang blockchain, dan gagasan membangun sistem registrasi terdistribusi dengan mantap di kepala kami. Tetapi bagaimana jika kita menerapkan kontrak pintar di sini ?

Kami tertarik oleh properti berikut:

  • keterbukaan - tidak ada server tunggal di mana Anda dapat memanipulasi informasi;
  • informasi yang ditempatkan dalam registri terdistribusi tetap di sana selamanya;
  • informasi tidak dapat dipalsukan (yah ... praktis)

Bukan blockchain




Blockchain sendiri seharusnya tidak digunakan untuk pemilihan seperti itu. Tetapi bagaimana jika kita mengambil protokol untuk membangun konsensus dalam sistem terdistribusi dan menerapkannya untuk membangun konsensus dalam hubungan manusia?

Mengingat bahwa kami harus bekerja di jaringan terbuka, kami perlu melindungi diri dari serangan non-Bizantium dan dari penggantian informasi pada perangkat pengguna.

Apa saja alternatifnya


Protokol yang paling terkenal adalah PAXOS. Itu tidak memiliki pemimpin yang eksplisit, dan semua perubahan melalui komitmen dua fase. Di awal setiap perubahan, Usulan terjadi. Jika berhasil, maka Terima dikirim.


Fitur algoritma dapat disebut fakta bahwa ia menggunakan pengatur waktu global untuk menentukan permintaan mana yang dihasilkan sebelumnya dan bahwa simpul yang melakukan perubahan harus berkomunikasi dengan semua node jaringan. Baca lebih lanjut tentang algoritme di sini .

Algoritme digunakan di banyak tempat, misalnya, dalam Cassandra DBMS. Kami tidak menyukai protokol ini dalam hal kompleksitas implementasi untuk tugas tersebut. Tapi pilihan kedua datang kepada kita - itu RAFT. Sebenarnya, ini adalah evolusi dari protokol PAXOS dengan pemimpin yang jelas.

Protokol yang disederhanakan dapat digambarkan sebagai berikut:
· Jaringan perangkat sedang dibangun yang saling mengetahui;
· Perangkat memilih di antara mereka sendiri seorang pemimpin yang membuat "keputusan penting" (misalnya, menambahkan entri ke registri atau mengubah komposisi jaringan);
· Perangkat pemimpin bertanggung jawab atas distribusi informasi di seluruh jaringan sehingga di mana pun itu identik;
· Begitu pemimpin berhenti untuk menyelesaikan tugasnya - pilihlah pemimpin baru.

Baca tentang protokol di sini .

Implementasi kami


Apa yang kita lakukan dan mengapa dunia menjadi motor lain? 


Hampir semua pengguna registri kami memiliki perangkat seluler yang hampir selalu aktif dan hampir selalu online, dan sebenarnya menggunakannya hampir selalu, jadi kami memutuskan untuk menjalankan algoritme registri distribusi pada perangkat seluler, dan bukan pada infrastruktur server, seperti implementasi terkenal lainnya .

Mari kita lihat "perangkap" apa yang kita hadapi, tapi kita berhasil keluar ...

Perangkap nomor 1: "Alamat saya bukan rumah dan bukan jalan"


"Tiba-tiba" ternyata bahwa untuk membangun jaringan P2P yang mengimplementasikan registri terdistribusi menggunakan protokol RAFT untuk replikasi data, setiap perangkat dapat berkomunikasi satu sama lain, yang berarti keduanya adalah klien dan server. Oleh karena itu, kami memerlukan alamat IP "putih" publik untuk setiap ponsel (mungkin tidak).

Jumlah IPv4s nyata sangat terbatas, sehingga operator telekomunikasi menggunakan teknologi NAT (Network Address Translation) dalam mode PAT (Port Address Translation), menerjemahkan beberapa alamat IP dari jaringan internal (yang didistribusikan ke pelanggan) menjadi satu alamat IP publik eksternal. Dengan demikian, kemampuan untuk menerima koneksi masuk dari Internet tidak termasuk.

Berita baiknya adalah ada banyak IPv6! 


Kami memiliki dukungan IPv6 yang termasuk dalam paket dasar. Juga, semua telepon modern mendukung IPv6, dan operator memberikan alamat v6 "putih" kepada pelanggan. Pilihan kami adalah IPv6.

Perangkap nomor 2: Semua orang pergi tidur


Tidak seperti server, ponsel terkadang masih mati. Kami menemukan ini ketika menguji prototipe pertama. Selain itu, alamat IPv6 yang disediakan oleh operator bersifat publik, tetapi tidak statis, setiap sesi komunikasi baru adalah alamat baru. Alamat perangkat seluler dapat berubah kapan saja. Dan jika tidak ada satu pun telepon dengan alamat yang kami ketahui di jaringan, itu tidak ada lagi (tidak ada yang dapat disambungkan untuk "menambah" nya). Karenanya, kami harus melanggar aturan "tidak ada server" sampai batas tertentu. Kami membuat satu simpul khusus di cloud dengan alamat statis yang dikenal. Tugasnya adalah untuk mengingat / memperbarui komposisi jaringan dan tidak mematikan. Artinya, ini adalah situs biasa, tidak ada yang hanya memilih dari itu, dan beralih ke sana, Anda selalu bisa mendapatkan daftar alamat saat ini dari semua peserta jaringan.

3: 



Itu perlu untuk entah bagaimana menyelesaikan masalah, sehingga tidak semua orang bisa memilih proyek, tetapi mereka yang membutuhkannya. Gagasan pertama adalah ini: memelihara database nomor telepon para ahli. Tetapi mereka menolaknya, karena mereka tidak ingin memberikan aplikasi hak untuk mengakses informasi ini.
Sebagai hasilnya, mereka membuat semuanya sederhana: mereka memutuskan untuk memasok setiap suara, setiap entri registri dengan tanda tangan digital pada kurva elips modis, yang akan menentukan keaslian catatan. Layanan WEB ditempatkan pada jaringan perusahaan, yang, dengan otorisasi domain, menentukan ahli dan menghasilkan kode QR unik untuknya dengan kunci enkripsi publik dan pribadi (tentu saja, di sisi klien). Pakar memindai kode dari aplikasi dan terhubung. Setelah itu, versi saat ini dari registri "digulung" di teleponnya dan kesempatan untuk memilih muncul.

4: Android 
 



Selama pengujian, hampir "tiba-tiba" terungkap bahwa beberapa pengguna adalah pemilik model perangkat seluler terkenal yang menjalankan sistem operasi iOS. Dan menjadi jelas bahwa perangkat lunak registri kami harus berjalan pada platform yang berbeda. Kami melihat ke arah bahasa pemrograman Kotlin, yang tidak hanya “trendy, stylish, youth”, tetapi juga multi-platform .

Konsep multi-platform di Kotlin menyiratkan bahwa ada bagian dari kode umum dan spesifik platform, tetapi karena sumber daya tim kami terbatas, kami menetapkan sendiri tugas menjijikkan menggunakan versi tunggal dari kode sumber untuk semua platform! Tentu saja, modul yang dapat dieksekusi harus asli untuk setiap platform. Kotlin mampu melakukan ini.

Tidak lebih cepat dikatakan daripada dilakukan! Kami memiliki satu SourceSet tunggal dengan kode sumber, dari mana kami mengumpulkan binari untuk semua platform (!), Menggunakan fitOndepend. Keren? Sangat keren!

Perangkap Nomor 5: Lalu lintas seluler tidak gratis 



Bagaimana kita dapat secara efektif mengimplementasikan interaksi antar node jaringan agar tidak menghabiskan semua lalu lintas pelanggan dan tidak menguras baterai perangkat seluler? Kami berasumsi bahwa jaringan dapat terdiri dari 1000 perangkat atau lebih! Opsi yang paling jelas adalah menggunakan UDP alih-alih TCP, misalnya, dalam prosedur pemilihan "leader" atau ketika mengirim Detak Jantung tanpa data. UDP lebih ekonomis karena menggunakan model transfer data sederhana, tanpa "jabat tangan" dan konfirmasi. Baik! Apa lagi? Tentu saja, asynchronous I / O!

Kami dengan cermat membaca dokumentasi untuk Kotlin Native.

Untuk semua target berbasis Unix atau Windows (termasuk Android dan iPhone) kami menyediakan lib platform posix. Ini berisi binding untuk implementasi platform dari standar POSIX.

Kemudian kami juga dengan cermat membaca dokumentasi standar POSIX dan menemukan fungsi luar biasa yang memungkinkan kami memproses acara soket dalam mode non-pemblokiran! Setelah terjun langsung ke dunia coroutine, soket, dan C Interop yang indah, kami dapat mewujudkan transportasi yang sangat efisien. Super!

Dan dalam bentuk apa untuk mengirim data? 



Tentu saja CBOR!

Format data biner yang ringkas, yang, semoga berhasil, diimplementasikan di perpustakaan multi-platform kotlinx.serialisasi . Menakjubkan!

Trap Number 6: Serialisasi 



Kali ini, ternyata secara tidak terduga ternyata kotlinx.serialisasi tidak di bawah androidNative (di bawah androidJvm, tentu saja, ada). Rekan-rekan yang terhormat dari JetBrains telah mengkonfirmasi bahwa saat ini mereka tidak sedang membangun perpustakaan untuk androidNative, dan sebelum rilis Kotlin 1.4 tidak ada lagi tempat untuk tugas ini dalam peta jalan. 


Apa yang harus dilakukan? Jika gunung tidak pergi ke Mohammed, Mohammed pergi ke gunung!

Kami sendiri telah menyusun kotlinx.serialisasi untuk semua platform, termasuk androidNative! Hal yang paling menakjubkan adalah itu berhasil! 


Perangkap nomor 7: Tempat menyimpan log? 



Jelas, dalam penyimpanan nilai kunci tertanam, tetapi di mana? Kami memilih lmdbx untuk kekompakan kode, kecepatan, multi-platform, dan kurangnya file WAL. Perpustakaan ini dikembangkan oleh orang-orang dari Positive Techlologies dan berasal dari perpustakaan LMDB yang legendaris dari salah satu penulis OpenLDAP Howard Chu. Dan itu, pada gilirannya, berakar pada implementasi pohon B + dari Martin Hedenfalk. By the way, di luar kotak, perpustakaan tidak dibangun untuk AndroidNative. Kami dengan hati-hati mengumpulkan semua kesalahan, dan penulis segera memberikan perbaikan - untuk itu terima kasih khusus kepada mereka!

Perangkap Nomor 8: C Interop 



Menyatukan semuanya terbukti menjadi tugas yang sangat tidak sepele. Selain soket lmdbx dan posix, kami mengintegrasikan perpustakaan untuk menghasilkan / memvalidasi tanda tangan digital pada kurva eliptik dan menghitung SHA256 menggunakan mekanisme C Interop yang menakjubkan . Dengan kata sederhana - dari aplikasi asli di Kotlin, Anda dapat memanggil fungsi C-library, termasuk dengan pointer ke pointer dan sihir lainnya, semuanya terlihat sedikit aneh.

Misalnya, memanggil getaddrinfo untuk mendapatkan sockaddr.



Bagaimana kamu menyukai Ilon Mask?

Menghubungkan C-library ke executable Kotlin Native adalah pencarian terpisah, yang juga berhasil kami lalui, tetapi bukan tanpa kruk. Kami secara dinamis membentuk file def langsung di skrip build untuk menunjukkan jalur yang benar ke pustaka relatif terhadap direktori root proyek dan kemudian mengganti deskriptor (def file) di bagian cinterop. Dalam file def itu sendiri, hanya path absolut yang ditentukan, yang tidak hanya dapat memiliki format berbeda jika perakitan dilakukan di bawah OS yang berbeda, tetapi sebenarnya pada mesin lokal pengembang, tentu saja, mungkin juga berbeda, yang jelas mengarah pada kesalahan selama tautan.

Tentang pemilihan


Pemilihan umum yang kami selenggarakan siang hari. Sedikit lebih dari 20 pakar ambil bagian dalam pengujian menggunakan jaringan kami. 21 proyek dievaluasi dalam 5 kategori, yaitu lebih dari 100 entri dengan suara untuk proyek ditambahkan ke dalam register.

Kesimpulan


Sebagai hasil dari proyek penelitian kecil ini, kami dapat membuktikan bahwa mempertahankan registri terdistribusi pada perangkat seluler dimungkinkan! Ini membuka banyak kemungkinan untuk menggunakan teknologi ini pada perangkat IoT untuk mengatur komputasi Edge-computing. Di depan kita masih menunggu uji beban, kerentanan terhadap serangan, dan toleransi kesalahan. Tetapi kami percaya bahwa kami akan berhasil!

Penulis artikel: arsitek dan pengembang Pusat Litbang MTS Dmitry Dzyuba, Alexey Vasilenko dan Semen Nevrev

All Articles