La settimana scorsa @redacted_noah ha inviato un sfogo su come Zero Copy™️ su @anchorlang sia l'alpha perfetto per ogni sviluppatore @solana Pensavo che zero copy fosse usato solo per account molto grandi Mi sono reso conto di non avere idea del perché a volte lo usassi Ho deciso di approfondire, lasciami portarti con me 👇
@SuperteamFRANCE @SuperteamJapan Prima di tutto, perché stiamo parlando di parsing dei dati senza copia? Il parser di dati predefinito di Anchor si chiama Borsh. Quando si chiama un'istruzione Anchor, Borsh copierà i dati del tuo account in una struttura Borsh (in uno slot di memoria chiamato "heap", di cui parleremo più avanti)
Quando includi un account nella tua istruzione, utilizzi un formato che appare così.
Quando utilizzi il zero copy, il tuo codice apparirà così.
Quindi, cosa sta realmente succedendo lì? Non è ovvio fin da subito! Prima dobbiamo capire come Solana utilizza i dati della sua app Rust: l'heap, lo stack e lo spazio "zero copy".
1. Stack: Questo è il luogo in cui memorizziamo tipi di dati locali e semplici. Hai 4KiB di spazio per ogni stack, ogni chiamata di funzione ottiene la propria allocazione di 4KiB. "Violazione di accesso nel frame dello stack X all'indirizzo XXXXX di dimensione X." è il tipo di errore che ottieni quando superi la dimensione massima dello stack. In Anchor, la prima soluzione per questo errore è utilizzare un `Box` per spostare i dati dallo stack all'"heap" 👇
2. Heap in Solana: I programmi vengono eseguiti in una BPF VM con 32KB di heap per impostazione predefinita. Questa è un'allocazione una tantum per un'intera invocazione. Qui è dove memorizzeresti tipi di dati più dinamici (Vec, String) Deserializzare gli account con Borsh copia i dati nell'heap, consumando rapidamente spazio.
3. Zero copy: Se devi bypassare l'heap e lo stack perché il tuo budget dati totale viene superato (molti CPI, con grandi conti) utilizzerai Zero copy. Zero copy ti consente di lavorare con i dati senza doverli allocare né copiare prima, saltando la deserializzazione.
Quando ha senso utilizzare Zero copy? 1. Dati di grandi dimensioni 2. Lavorare con molti CPI Continuiamo:
1. Dati di grandi dimensioni Supponiamo che tu voglia tenere traccia di un elenco di portafogli direttamente nel tuo stato per poter eseguire controlli completamente onchain (se hai bisogno di farlo, dai un'occhiata agli alberi di Merkle 😅, questo non è il modo per farlo) Come in una lotteria, memorizzare l'indirizzo di ciascun partecipante prima di eseguire l'estrazione finale e selezionare un vincitore. Questo supererà facilmente i 32kb di memoria. Un partecipante = 32 byte, quindi se prevedi di avere successo e allocare spazio per 1000 partecipanti, questo sta già consumando l'intera dimensione dell'heap (32 000 byte) In questa situazione, puoi utilizzare Zero copy per bypassare la limitazione e abilitare il lavoro con account molto più grandi senza colpire i limiti dell'heap né dello stack.
COME RISOLVERE? Semplice! Usa Zero Copy ovunque. È facile come questo 👇 (aggiungi l'attributo macro #[account("zero_copy")] all'account RootEscrow) MA Zero Copy comporta un'altra sfida, il motivo per cui Anchor ha scelto Borsh in primo luogo: allineamento dei byte.
L'allineamento dei byte è una tecnica a basso livello che ogni sviluppatore di Solana dovrebbe comprendere, sia utilizzando zero copy che no. Richiede che le strutture siano sicure per zero-copy tramite bytemuck (l'allineamento dei byte può causare panico se non gestito correttamente). Pubblicherò un altro thread su questo *eccitante* argomento presto 🔥
Nel frattempo, dai un'occhiata a @legendsdotfun, il prodotto che ho costruito da metà settembre e a cui partecipo all'hackathon @colosseum Cypherpunk. Registrati al tuo prodotto, dai voti a favore a nuovi team promettenti. Facciamo brillare ogni leggenda di solana 🤝
Un grande grazie alle capre: - @redacted_noah - @blockiosaurus - @0xIchigo Per aver corretto questo thread di scoperta dal vivo!
5,74K