Bu yazı İngilizce orijinalinden çevrildi.
Geliştirici
GenLayer'ı %100 güvenli kılmak, 1. bölüm: Mimari
GenLayer'ın konsensüs sözleşmeleri, doğrulayıcı düğümleri ve GenVM, güvenli Intelligent Contract'lar için derinlemesine savunmaya dayalı bir mimariyi nasıl oluşturuyor?
Edgars Nemše8 dk okuma
GenLayer'ı %100 güvenliğe olabildiğince yaklaştırmak için neler yaptığımızı anlatan bir yazı dizisine başlıyoruz. Nedeni basit: GenLayer, fon tutan ve hüküm veren, görev açısından kritik bir sistem. Buradaki bir hata yalnızca bir kesinti anlamına gelmez; pek çok insanın çok para kaybetmesi demek olabilir. Bunu çok ciddiye alıyoruz.
Benzer bir arıza profiline sahip, her hatanın kritik olduğu sistemlerden ilham alıyoruz: uçuş kontrol bilgisayarları, endüstriyel kontrol yazılımları. Yaklaşımımız derinlemesine savunma: birbirinden bağımsız çok sayıda test ve doğrulama katmanı. Her birleştirmeden (merge) önce örneğe dayalı testler ve tüm sistemin uçtan uca çalıştırılması. Bir referans modele karşı üretken uyumluluk testleri. Testlerin fark edeceğini kanıtlamak için kodu bilerek bozan bir CI. Konsensüs protokolünün, temel özelliklerine dair makineyle denetlenmiş ispatlar içeren biçimsel bir TLA+ modeli. Ve daha fazlası.
Ama ilk savunma katmanı mimarinin kendisi: İyi tasarlanmış bir sistem, daha tek bir test yazılmadan bütün hata sınıflarını ortadan kaldırır. Testleri mimariyi bilmeden anlayamamanızın nedeni de bu: Hepsi doğrudan sistemin nasıl kurulduğundan çıkar. Bu yüzden bu ilk yazı temel parçaları ve aralarındaki arayüzleri ele alıyor. GenLayer'ın ne olduğunu ve hangi sorunu çözdüğünü bildiğinizi varsayıyorum; bilmiyorsanız Optimistic Democracy: Yapay zekâ için tasarlanmış, ticareti dönüştüren konsensüs yazısıyla ve dokümantasyonumuzla başlayın. Burada perde arkasındaki mühendisliğe odaklanacağız.
GenLayer, birbiriyle iletişim kuran üç ana bileşenden oluşur: GenLayer Chain üzerindeki konsensüs sözleşmeleri, doğrulayıcı düğümü ve GenVM. Aşağıdaki diyagram bunların nasıl bir araya geldiğini gösteriyor; yazının geri kalanı da her birini sırayla ele alıyor.
Konsensüs sözleşmeleri
Her GenLayer işlemi, bir EVM rollup'ı olan GenLayer Chain üzerinde Solidity sözleşmeleri olarak uygulanmış bir durum makinesinden geçer. Sözleşmeler tüm yaşam döngüsünü izler: Bir işlem kuyruğa alınır, lider onu önerir, doğrulayıcılar oylar, işlem kabul edilir ve itiraz penceresi kapandıktan sonra kesinleşir. İtirazlar aynı işlemi giderek büyüyen doğrulayıcı panellerine, en sonunda tüm kümeye kadar taşır. Doğrulayıcı kümesinin kendisi de burada yaşar: Doğrulayıcılar bu kümeye katılmak için stake eder, sözleşmeler de her işlem için kümeden bir lider ve bir panel seçer.
Zincir tek doğruluk kaynağıdır. Başka hiçbir şey yetkili durumu tutmaz: Bir işlemin yaşam döngüsünde nerede olduğunu bilmek istiyorsanız yanıt sözleşmelerdedir. Her durum değişikliği bir olay yayımlar ve sistemin geri kalanı sıradaki adımı bu olaylardan öğrenir.
Zincir aynı zamanda iletişim katmanıdır. Düğümler hiçbir zaman doğrudan birbirleriyle konuşmaz: Eşler arası ağ da yok, gossip de. Bir öneri bir işlemdir, bir oy bir işlemdir ve hepsini zincir sıralar. Bu, bütün bir konsensüs sorunları sınıfını daha ortaya çıkmadan ortadan kaldırır. Çatallanma olmaz, çünkü herkes aynı kanonik olay dizisini okur. Çifte taahhüt ya da çelişkili oy (equivocation) olmaz, çünkü sözleşme ikinci bir oyu sonradan tespit etmek yerine yapısı gereği reddeder. Protokolümüzde ağ bölünmesi yönetimi ya da görünüm değişikliği (view-change) mantığı da yoktur, çünkü mesajların teslimi ve sıralanması alttaki zincirin işidir. Zaman aşımları bile nesneldir: “Lider zamanında yanıt vermedi” ifadesi tek bir düğümün yerel görüşü değil, sözleşmenin blok zamanından doğrulayabileceği bir olgudur. Zincir ne olduğunu belirler; Optimistic Democracy'ye yalnızca bunun ne anlama geldiğine karar vermek kalır.
Bunun bedeli, her protokol adımının zincir üstünde bir işlem olması; dolayısıyla blok süresi konsensüs gecikmesinin alt sınırıdır. Bu bilinçli bir tercih: gecikmeden ödün vererek dağıtık sistem arızalarının bütün kategorilerini silmek. Bunun bir sonucu daha var: Her konsensüs kararının tüm geçmişi sıralı ve yeniden oynatılabilir bir kayıttır. Bu, dizinin ilerleyen bölümlerinde önem kazanacak.
Doğrulayıcı düğümü
Doğrulayıcı düğümü, operatörlerin çalıştırdığı yazılımdır. İlk netleştirilmesi gereken şey onun ne olmadığı: GenLayer Chain'in bir düğümü değildir. Zincir, kendi tam düğümleri ve kendi RPC'si olan normal bir EVM zinciridir; sıralama orada gerçekleşir. Doğrulayıcı düğümü bu zincirin bir istemcisidir: Bir zincir düğümünün RPC'sine bağlanır, olaylara abone olur ve işlem gönderir. Evet, bu iki düğüm katmanı ve iki RPC katmanı demek. Yine de iş bölümü nettir: Zincir düğümleri olayların sırası üzerinde anlaşır; doğrulayıcı düğümleri ise bu olaylara göre harekete geçer.
İçeride, tek bir binary'de üç şey bir arada:
- Bir konsensüs işçisi. Asıl görev bu: Düğüm zincirdeki olayları izler ve bir işlem için lider ya da doğrulayıcı olarak seçildiğinde o işlemi GenVM üzerinden, operatör hangi modelleri yapılandırdıysa onlarla yürütür; ardından oylarını ve açıklamalarını gönderir. Zincirin gözünde imzalı işlemler gönderen sıradan bir hesaptır.
- Bir tam düğüm. Zinciri takip eder ve GenLayer durumunu tutar. Zincir sıralı kaydı ve konsensüs durumunu saklar; Intelligent Contract'ların kendi durumu ise türetilmiştir: Düğüm kabul edilmiş işlemleri GenVM üzerinden yeniden oynatır ve ortaya çıkan durumu kendi yerel veritabanında tutar.
- RPC. Kullanıcıların, SDK'ların ve araçların konuştuğu, GenLayer'a dönük arayüz. GenLayer'a özgü okumalar türetilmiş durumdan yanıtlanır; standart
eth_metotları ise doğrudan bir zincir düğümüne aktarılır. İşlemler her zaman zincire gider; aktarma özelliği sayesinde tek bir bağlantı yeterli olur.
Yani düğüm aşağıdaki bir RPC'yi kullanır, yukarıya ise farklı bir RPC sunar. Aynı binary'yi doğrulama yapmadan da çalıştırabilirsiniz; senkronize olmaya ve RPC sunmaya devam eder. Ama asıl görev doğrulamadır ve bu dizinin ilgilendiği de bu görev. Stake ettiğiniz kısım da budur.
GenVM
GenVM, sözleşmelerin gerçekten yürütüldüğü yerdir ve Optimistic Democracy'nin işleyebilmesini sağlayan şey onun tasarımıdır: Determinizmi denetim altındaki deterministik olmayan işlemlerle birleştirir. LLM çağrıları ve web erişimi yalnızca geliştiricinin istediği yerde vardır, başka hiçbir yerde değil.
Her sözleşmenin en üst düzeyi deterministik modda çalışır. GenVM bir WASM korumalı alanıdır: Komut kümesi deterministiktir, bellek yalıtılmıştır ve VM'in sunduğu host fonksiyonları (depolama, calldata, sözleşmeler arası mesajlar) dışında dış dünyaya dokunmanın hiçbir yolu yoktur. Böylece aynı işlemi yürüten her doğrulayıcı, hash düzeyine kadar birebir aynı sonucu üretir.
Bu yürütmenin içinde sözleşme deterministik olmayan bloklar açabilir. Her blok kendi yalıtılmış GenVM örneğinde çalışır ve bu örnek, web'i okumak ve LLM çağırmak için ek host fonksiyonlarına sahip olur. Bu yetenekler yalnızca burada vardır: Deterministik kod onlara ulaşamaz, çünkü ilgili içe aktarmalar orada hiç yoktur.
Konsensüs bu ayrıma doğrudan karşılık gelir. Deterministik yürütme, her normal blokzincirde olduğu gibi her düğümde birebir aynı olmalıdır. Deterministik olmayan bloklar ise sonuçların doğrulayıcılar arasında meşru biçimde farklılaşabildiği yerlerdir; Optimistic Democracy'nin oylaması ve Eşdeğerlik İlkesi devreye burada girer.
Tam bir CPython yorumlayıcısını zincir üstüne koyup sözleşme dili olarak sıradan Python'u kullanabilmemizin nedeni de bu. Deterministik bir Python lehçesi icat etmedik: GenVM gerçek yorumlayıcıyı WASM'a derler ve korumalı alanın içinde çalıştırır. Sözleşme kodu değiştirilmeden çalışır; Python'un kendi içinde taşıdığı deterministik olmayan davranış ne olursa olsun deterministik ortamın içinde sabitlenir.
Zincir üstünde gerçek bir yorumlayıcı, eval gibi özellikler dâhil dilin tüm gücü demek. Bir sözleşme, yayına alındığında var olmayan kodu çalıştırabilir: Bir LLM yürütmenin ortasında kod yazabilir ve sözleşme bu kodu aynı çağrı içinde yürütebilir. Bu yine de güvenli ve deterministiktir, çünkü çalışan her şey aynı korumalı alanın içinde, aynı host fonksiyonlarıyla ve başka hiçbir şey olmadan yaşar.
Yorumlayıcı bir runner olarak dağıtılır: sözleşmenin başlığında hash'iyle sabitlenmiş, içerik adresli bir çalıştırma ortamı. Böylece sözleşmenizi yürüten her doğrulayıcı, yorumlayıcı derlemesine kadar bayt bayt aynı bir ortamı çalıştırır.
Yine de Python varsayılandır, sınır değil. GenVM'in sözleşme arayüzü WASM'dır: WASM'a derlenebilen her şey bir sözleşme olabilir. İsterseniz sözleşmenizi doğrudan Rust ya da C ile yazın; Python runner'ı yalnızca yaygın durumu kolaylaştıran standart ortamdır.
Uçtan uca bir işlem
- Bir kullanıcı zincire bir işlem gönderir: doğrudan bir zincir düğümüne ya da bir doğrulayıcı düğümünün aktarma özelliği üzerinden. İşlem konsensüs sözleşmelerine ulaşır ve kuyruğa alınır.
- Sözleşmeler bir lider ve bir doğrulayıcı paneli seçer ve bunu bir olayla duyurur.
- Liderin düğümü olayı yakalar ve işlemi kendi GenVM'inde yürütür: deterministik kodu korumalı alanda, deterministik olmayan blokları erişimi denetlenen host fonksiyonları üzerinden. Sonuç, liderin önerisi olarak zincire geri gönderilir.
- Her doğrulayıcının düğümü işlemi kendi GenVM'i üzerinden yeniden yürütür ve kendi sonucunu öneriyle karşılaştırır. Karşılaştırmanın sorduğu, liderin sonucunun birebir aynı olup olmadığı değil, kabul edilebilir olup olmadığıdır. Bu, Eşdeğerlik İlkesi'dir ve kriterlerini sözleşme geliştiricisi her çağrı için ayrı ayrı tanımlar. Oylar önce taahhüt edilir, sonra açıklanır.
- Çoğunluk hemfikir olursa işlem kabul edilir ve kararı yürürlüğe girer. Çoğunluk öneriyi reddederse ağ yeni bir lidere geçer ve yeniden dener; konsensüse yine ulaşılamazsa işlem sonuçsuz kalır ve sözleşme durumuna dokunulmaz. Kabul edilen bir sonuç da henüz kesin değildir: İtiraz penceresi açıkken herkes itiraz edebilir ve işlemi daha büyük bir doğrulayıcı paneline gönderebilir.
- Pencere kapanır, işlem kesinleşir. Artık kalıcıdır.
Bu akıştaki her ok iki ek yerinden birini geçer: Sözleşmelerle düğüm arasında aşağıya olaylar, yukarıya işlemler; düğümle GenVM arasında ise yürütme ve sonuç.
İlk savunma katmanı
Bu yazının anlattığı her şeyde ortak bir tema var: Derinlemesine savunma yaklaşımında ilk katman mimarinin kendisidir. Mimari, bütün hata sınıflarını baştan ortadan kaldırır: Tüm iletişim zincirden geçtiği için çatallanmalar, çifte oylar ve ağ bölünmesi yönetimi çözmemiz gereken sorunlar olmaktan çıkar. Test sayesinde değil, yapısı gereği geçerli olan özellikler sağlar: Determinizm WASM korumalı alanından, yeniden üretilebilirlik hash'le sabitlenmiş runner'lardan gelir. Ve sistemi test edilebilir kılan sınırları çizer: Diyagramdaki her ek yeri, bir katmanın iyi tanımlanmış bir arayüze karşı denetlenebileceği bir noktadır.
Sonraki katmanlar, mimarinin yapısı gereği garanti edemediği her şeyle ilgili. Her bileşenin arıza biçimleri farklı olduğundan test yaklaşımı da her biri için farklı: Konsensüs sözleşmeleri bir durum makinesi olarak, doğrulayıcı düğümü sözleşmelerin gerçek davranışına karşı, GenVM ise devraldığımız determinizmin gerçekten geçerli olduğunu doğrulamak için test edilir. Bileşenlerin birlikte çalışması gerektiği için test onların sınırlarında da bitmez: Bu katmanların sınırları ve kombinasyonları boyunca, tüm sistemin uçtan uca çalıştırılmasına kadar uzanır. Bu dizinin geri kalanı da bunu anlatacak.



