Distributed Ledger for Wheelssets: Izkušnje s Hyperledger Fabric

Pozdravljeni, delam v ekipi projekta DRD KP (distribuirani register podatkov za spremljanje življenjskega cikla kolesnih dvojic). Tukaj želim deliti izkušnje naše ekipe pri razvoju poslovne verige blokov za ta projekt pod omejitvami tehnologije. Večinoma bom govoril o Hyperledger Fabric, vendar je tukaj opisan pristop mogoče ekstrapolirati na katero koli dovoljeno verigo blokov. Končni cilj naše raziskave je pripraviti blockchain rešitve za podjetja tako, da bo končni izdelek prijeten za uporabo in ne prezahteven za vzdrževanje.

Tu ne bo nobenih odkritij, nepričakovanih rešitev in tu ne bodo izpostavljeni nobeni edinstveni dogodki (ker jih nimam). Rad bi le delil svojo skromno izkušnjo, pokazal, da je "bilo mogoče" in morda v komentarjih prebral izkušnje drugih ljudi o sprejemanju dobrih in manj dobrih odločitev.

Težava: verige blokov se še ne spreminjajo

Danes so prizadevanja mnogih razvijalcev usmerjena v to, da bi blockchain postala resnično priročna tehnologija in ne časovna bomba v lepem ovoju. State channels, optimistic rollup, plasma in sharding bodo verjetno postali običajni. Nekega dne. Ali pa bo TON ponovno preložil lansiranje za šest mesecev in naslednja skupina Plasma bo prenehala obstajati. Lahko verjamemo v naslednji načrt in ponoči beremo briljantne bele knjige, vendar moramo tukaj in zdaj nekaj narediti s tem, kar imamo. Naredi sranje.

Naloga, zastavljena naši ekipi v trenutnem projektu, je na splošno videti takole: obstaja veliko subjektov, ki dosegajo nekaj tisoč, ki ne želijo graditi odnosov na zaupanju; Na DLT je treba zgraditi rešitev, ki bo delovala na običajnih osebnih računalnikih brez posebnih zahtev glede zmogljivosti in zagotavljala uporabniško izkušnjo nič slabšo od vseh centraliziranih računovodskih sistemov. Tehnologija, ki stoji za rešitvijo, mora čim bolj zmanjšati možnost zlonamerne manipulacije podatkov – zato je tu blockchain.

Slogani iz belih knjig in medijev nam obljubljajo, da nam bo naslednji razvoj omogočil milijone transakcij na sekundo. Kaj je v resnici?

Mainnet Ethereum trenutno deluje s približno 30 tps. Že zaradi tega ga je težko dojemati kot blockchain kakor koli primeren za potrebe podjetij. Med dovoljenimi rešitvami so merila uspešnosti, ki kažejo 2000 tps (Sklepčnost) ali 3000 tps (Tkanina Hyperledger, v publikaciji je malo manj, vendar morate upoštevati, da je bil primerjalni test izveden na starem konsenznem motorju). bil poskus radikalne obdelave blaga, ki ni dal najslabših rezultatov, 20000 tps, vendar je to zaenkrat le akademska raziskava, ki čaka na svojo stabilno implementacijo. Malo verjetno je, da se bo korporacija, ki si lahko privošči vzdrževanje oddelka razvijalcev blockchain, sprijaznila s takšnimi kazalniki. Toda težava ni samo prepustnost, tu je tudi zakasnitev.

Latenca

Zakasnitev od trenutka, ko je transakcija sprožena, do njene končne odobritve s strani sistema, ni odvisna samo od hitrosti, s katero sporočilo prehaja skozi vse stopnje validacije in naročanja, temveč tudi od parametrov oblikovanja bloka. Tudi če nam naša veriga blokov omogoča prenos s hitrostjo 1000000 tps, vendar potrebuje 10 minut za ustvarjanje 488 MB bloka, ali nam bo postalo lažje?

Oglejmo si podrobneje življenjski cikel transakcij v Hyperledger Fabric, da bomo razumeli, kje se porabi čas in kako je povezan s parametri generiranja blokov.

Distributed Ledger for Wheelssets: Izkušnje s Hyperledger Fabric
vzeto od tukaj: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Odjemalec ustvari transakcijo, jo pošlje enakovrednim podpornikom, slednji simulirajo transakcijo (uporabijo spremembe, ki jih naredi verižna koda, za trenutno stanje, vendar se ne zavežejo v knjigo) in prejmejo RWSet - imena ključev, različice in vrednosti ​​vzeto iz zbirke v CouchDB, ( 2) indosanti odjemalcu pošljejo nazaj podpisan RWSet, (3) odjemalec bodisi preveri prisotnost podpisov vseh potrebnih vrstnikov (indosantov) in nato pošlje transakcijo storitvi za naročanje , ali ga pošlje brez preverjanja (preverjanje bo še vedno opravljeno pozneje), storitev naročanja oblikuje blok in ( 4) pošlje nazaj vsem vrstnikom, ne le indosantom; vrstniki preverijo, ali se različice ključev v nizu za branje ujemajo z različicami v bazi podatkov, ali imajo vsi indosanti podpise in končno potrdijo blok.

A to še ni vse. Besede "naročnik tvori blok" ne skrivajo samo vrstnega reda transakcij, ampak tudi 3 zaporedne omrežne zahteve od vodje do sledilcev in nazaj: vodja doda sporočilo v dnevnik, ga pošlje sledilcem, slednji ga doda v svoj dnevnik, pošlje potrditev uspešne replikacije vodji, vodja potrdi sporočilo, pošlje potrditev potrditve sledilcem, sledilci potrdijo. Manjša kot sta velikost in čas nastajanja bloka, pogosteje bo morala naročna služba vzpostaviti konsenz. Hyperledger Fabric ima dva parametra za oblikovanje bloka: BatchTimeout - čas oblikovanja bloka in BatchSize - velikost bloka (število transakcij in velikost samega bloka v bajtih). Takoj ko eden od parametrov doseže mejo, se sprosti nov blok. Več kot je vrstnih vozlišč, dlje bo to trajalo. Zato morate povečati BatchTimeout in BatchSize. Toda ker so RWSets različic, večji ko je blok, ki ga naredimo, večja je verjetnost sporov MVCC. Poleg tega, ko se BatchTimeout poveča, se UX katastrofalno poslabša. Naslednja shema za reševanje teh težav se mi zdi razumna in očitna.

Kako se izogniti čakanju na finalizacijo bloka in ne izgubiti možnosti sledenja statusu transakcije

Daljši kot sta čas oblikovanja in velikost bloka, večja je prepustnost verige blokov. Eno ne sledi neposredno drugemu, vendar je treba zapomniti, da vzpostavitev soglasja v RAFT zahteva tri omrežne zahteve od vodilnega do sledilcev in nazaj. Več kot je vrstnih vozlišč, dlje bo to trajalo. Manjša kot sta velikost in čas nastanka bloka, več je takih interakcij. Kako povečati čas generiranja in velikost bloka brez povečanja odzivnega časa sistema za končnega uporabnika?

Najprej moramo nekako rešiti konflikte MVCC, ki jih povzroča velika velikost bloka, ki lahko vključuje različne RWSet z isto različico. Očitno je, da na strani odjemalca (v povezavi z omrežjem blockchain je to lahko zaledje, in resno mislim) potrebujete Obravnavalec konfliktov MVCC, ki je lahko ločena storitev ali običajni dekorator nad klicem, ki sproži transakcijo z logiko ponovnega poskusa.

Ponovni poskus je mogoče izvesti z eksponentno strategijo, vendar se bo zakasnitev zmanjšala prav tako eksponentno. Zato bi morali uporabiti bodisi naključni ponovni poskus v določenih majhnih mejah bodisi stalni poskus. S pogledom na možna trčenja v prvi možnosti.

Naslednji korak je narediti interakcijo odjemalca s sistemom asinhrono, tako da ne čaka 15, 30 ali 10000000 sekund, kar bomo nastavili kot BatchTimeout. Toda hkrati je treba ohraniti možnost preverjanja, ali so spremembe, ki jih sproži transakcija, zabeležene/niso zabeležene v verigi blokov.
Bazo podatkov lahko uporabite za shranjevanje statusa transakcije. Najenostavnejša možnost je CouchDB zaradi enostavne uporabe: baza podatkov ima uporabniški vmesnik takoj po namestitvi, API REST in zanjo lahko enostavno nastavite replikacijo in razčlenjevanje. Lahko preprosto ustvarite ločeno zbirko v istem primerku CouchDB, ki uporablja Fabric za shranjevanje svojega svetovnega stanja. Te vrste dokumentov moramo shraniti.

{
 Status string // Статус транзакции: "pending", "done", "failed"
 TxID: string // ID транзакции
 Error: string // optional, сообщение об ошибке
}

Ta dokument se zapiše v bazo podatkov, preden se transakcija pošlje vrstnikom, ID entitete se vrne uporabniku (isti ID se uporabi kot ključ), če je to operacija ustvarjanja, nato pa se polja Status, TxID in Error posodabljajo, ko ustrezne informacije prejmejo od vrstnikov.

Distributed Ledger for Wheelssets: Izkušnje s Hyperledger Fabric

V tej shemi uporabnik ne čaka, da se blok končno oblikuje, 10 sekund opazuje vrtljivo kolo na zaslonu, prejme takojšen odziv sistema in nadaljuje z delom.

Za shranjevanje statusov transakcij smo izbrali BoltDB, ker moramo prihraniti pomnilnik in ne želimo izgubljati časa z omrežno interakcijo z ločenim strežnikom baz podatkov, še posebej, če ta interakcija poteka z uporabo protokola z navadnim besedilom. Mimogrede, ne glede na to, ali uporabljate CouchDB za izvajanje zgoraj opisane sheme ali preprosto za shranjevanje svetovnega stanja, je v vsakem primeru smiselno optimizirati način shranjevanja podatkov v CouchDB. V CouchDB je velikost vozlišč b-drevesa privzeto 1279 bajtov, kar je veliko manj kot velikost sektorja na disku, kar pomeni, da bosta tako branje kot ponovno uravnoteženje drevesa zahtevala več fizičnega dostopa do diska. Optimalna velikost ustreza standardu Napredni format in je 4 kilobajte. Za optimizacijo moramo nastaviti parameter btree_chunk_size enako 4096 v konfiguracijski datoteki CouchDB. Za BoltDB takšen ročni poseg To ne zahteva.

Povratni pritisk: strategija varovanja

Lahko pa je veliko sporočil. Več kot sistem zmore, deljenje virov z ducatom drugih storitev poleg tistih, ki so prikazane na diagramu - in vse to bi moralo delovati brezhibno tudi na strojih, na katerih bi bilo izvajanje Intellij Idea izjemno dolgočasno.

Problem različnih zmogljivosti komunikacijskih sistemov, proizvajalca in potrošnika, se rešuje na različne načine. Poglejmo, kaj lahko storimo.

Spuščanje: Lahko trdimo, da smo sposobni obdelati največ X transakcij v T sekundah. Vse zahteve, ki presegajo to omejitev, se zavržejo. To je precej preprosto, potem pa lahko pozabite na UX.

Računovodstvo: potrošnik mora imeti nekakšen vmesnik, prek katerega lahko, odvisno od obremenitve, nadzoruje TPS proizvajalca. Ni slabo, vendar razvijalcem odjemalca nalaga obveznosti, ki ustvarjajo obremenitev za implementacijo tega vmesnika. To je za nas nesprejemljivo, saj bo blockchain v prihodnosti integriran v veliko število že dolgo obstoječih sistemov.

Pufranje: Namesto da bi se uprli toku vhodnih podatkov, lahko ta tok medpomnimo in obdelamo z zahtevano hitrostjo. Očitno je to najboljša rešitev, če želimo zagotoviti dobro uporabniško izkušnjo. Medpomnilnik smo implementirali s čakalno vrsto v RabbitMQ.

Distributed Ledger for Wheelssets: Izkušnje s Hyperledger Fabric

Shemi sta bili dodani dve novi akciji: (1) ko prispe zahteva za API, se sporočilo s parametri, potrebnimi za klic transakcije, postavi v čakalno vrsto in odjemalec prejme sporočilo, da je transakcijo sprejel sistem, (2) zaledje bere podatke iz čakalne vrste s hitrostjo, določeno v konfiguraciji; sproži transakcijo in posodobi podatke v shrambi stanja.
Zdaj lahko povečate čas oblikovanja in zmogljivost bloka, kolikor želite, tako da skrijete zamude pred uporabnikom.

Druga orodja

Tukaj ni bilo nič povedano o verižni kodi, ker v njej praviloma ni ničesar za optimizacijo. Verižna koda mora biti čim bolj preprosta in varna – to je vse, kar se od nje zahteva. Ogrodje nam pomaga pisati verižno kodo preprosto in varno CCKit iz S7 Techlab in statični analizator oživiti^CC.

Poleg tega naša ekipa razvija nabor pripomočkov, s katerimi bo delo s Fabricom preprosto in prijetno: blockchain raziskovalec, pripomoček za samodejne spremembe konfiguracije omrežja (dodajanje/odstranjevanje organizacij, vozlišča RAFT), pripomoček za preklic potrdil in odstranitev identitete. Če želite prispevati, ste dobrodošli.

Zaključek

Ta pristop vam omogoča, da enostavno zamenjate Hyperledger Fabric s Quorumom, drugimi zasebnimi omrežji Ethereum (PoA ali celo PoW), znatno zmanjšate dejansko prepustnost, a hkrati ohranite normalen UX (tako za uporabnike v brskalniku kot za integrirane sisteme). Pri zamenjavi Fabric z Ethereumom v shemi boste morali samo spremeniti logiko storitve/dekoraterja ponovnega poskusa iz obdelave sporov MVCC v atomsko nonce inkrement in ponovno pošiljanje. Medpomnjenje in shranjevanje stanja sta omogočila ločitev odzivnega časa od časa oblikovanja bloka. Zdaj lahko dodate na tisoče vozlišč naročil in se ne bojite, da se bloki oblikujejo prepogosto in nalagajo storitev naročanja.

V bistvu je to vse, kar sem želel deliti. Vesel bom, če bo to komu pomagalo pri njegovem delu.

Vir: www.habr.com

Dodaj komentar