Afgelopen week stuurde @redacted_noah een rant over hoe Zero Copy™️ op @anchorlang de perfecte alpha is voor elke @solana dev Ik dacht dat zero copy alleen werd gebruikt voor zeer grote accounts Ik realiseerde me dat ik geen idee had waarom ik het soms gebruikte Ik besloot er dieper op in te gaan, laat me je meenemen 👇
@SuperteamFRANCE @SuperteamJapan Waarom hebben we het eigenlijk over Zero copy data parsing? De standaard dataparser van Anchor heet Borsh. Wanneer je een Anchor-instructie aanroept, gaat Borsh je accountgegevens kopiëren naar een Borsh-structuur (naar een geheugenslot dat "de heap" wordt genoemd, daarover later meer)
Wanneer je een account in je instructie opneemt, gebruik je een formaat dat er als volgt uitziet.
Wanneer je zero copy gebruikt, zal je code er als volgt uitzien.
Wat gebeurt daar eigenlijk? Het is niet meteen duidelijk! Eerst moeten we begrijpen hoe Solana zijn Rust-appgegevens gebruikt: de heap, de stack en de "zero copy" ruimte.
1. Stack: Dit is waar we lokale en eenvoudige datatypes opslaan. Je krijgt 4KiB aan ruimte voor elke stack, elke functieaanroep krijgt zijn eigen 4KiB toewijzing. "Toegangsviolatie in stackframe X op adres XXXXX van grootte X." is het soort fout dat je krijgt wanneer je de maximale stackgrootte overschrijdt. In Anchor is de eerste oplossing voor deze fout om een `Box` te gebruiken om de gegevens van de stack naar de "heap" te verplaatsen 👇
2. Heap in Solana: Programma's draaien in een BPF VM met standaard 32KB heap. Dit is een eenmalige toewijzing voor één hele aanroep. Hier zou je meer dynamische datatypes (Vec, String) opslaan. Het deserialiseren van accounts met Borsh kopieert gegevens naar de heap, waardoor de ruimte snel opraakt.
3. Zero copy: Als je de heap en stack moet omzeilen omdat je volledige databudget wordt overschreden (veel CPI's, met grote rekeningen), gebruik je Zero copy. Zero copy stelt je in staat om met de gegevens te werken zonder deze eerst te hoeven toewijzen of kopiëren door deserialisatie over te slaan.
Wanneer heeft Zero copy zin? 1. Grote gegevens 2. Werken met veel CPI's Laten we doorgaan:
1. Grote gegevens Laten we zeggen dat je een lijst van wallets wilt bijhouden die direct in jouw staat zijn om volledig on-chain controles uit te voeren (als je dit moet doen, kijk dan naar merkle-bomen 😅, dit is niet de manier om het te doen) Net als bij een loterij, het opslaan van elk deelnemer's adres voordat je de finale trekking uitvoert en een winnaar selecteert. Dit zal gemakkelijk de 32kb geheugen overschrijden. Eén deelnemer = 32 bytes, dus als je van plan bent om succesvol te zijn en ruimte wilt alloceren voor 1000 deelnemers, dan verbruikt dit al de hele heap-grootte (32 000 bytes) In deze situatie kun je Zero copy gebruiken om de beperking te omzeilen en te kunnen werken met veel grotere accounts zonder de heap- of stacklimieten te raken.
HOE OP TE LOSSEN? Simpel! Gebruik gewoon Zero Copy overal. Het is zo eenvoudig als dit 👇 (voeg de #[account("zero_copy")] macro-attribuut toe aan de RootEscrow-account) MAAR Zero Copy brengt een andere uitdaging met zich mee, de reden waarom Anchor in de eerste plaats voor Borsh heeft gekozen: byte-alignment.
Byte-alignment is een laag-niveau techniek die elke Solana-ontwikkelaar zou moeten begrijpen, met of zonder zero copy. Het vereist dat structs zero-copy veilig zijn via bytemuck (byte-alignment kan panieksituaties veroorzaken als het niet correct wordt behandeld). Ik zal binnenkort een andere thread over dit *opwindende* onderwerp publiceren 🔥
In de tussentijd, kijk naar @legendsdotfun, het product waar ik sinds half september aan werk en waaraan ik deelneem aan de @colosseum Cypherpunk hackathon Registreer je product, geef upvotes aan veelbelovende nieuwe teams Laten we elke solana legende laten stralen 🤝
Veel dank aan de geiten: - @redacted_noah - @blockiosaurus - @0xIchigo Voor het proeflezen van deze live ontdekkingsdraad!
5,5K