Una Cross-Program Invocation (CPI) si verifica quando un programma chiama un'istruzione su un altro programma durante l'esecuzione. Le CPI abilitano la componibilità: le istruzioni di qualsiasi programma possono essere invocate da qualsiasi altro programma sulla rete.
CPI senza firmatari PDA
Utilizzo della funzione invoke, Anchor CpiContext, esempi Rust nativi, esempi di CPI per trasferimento SOL.
CPI con firmatari PDA
Utilizzo di invoke_signed con signer seeds, Anchor CpiContext con PDA, esempi di firma PDA in Rust nativo.
Esecuzione CPI e privilegi
Flusso di esecuzione CPI in 11 passaggi, regole di estensione dei privilegi, rientranza, validazione degli account.
Modello di costo CPI e sincronizzazione dati
Formula del costo CPI, costi di serializzazione, sincronizzazione dei dati degli account, firma PDA, dati di ritorno.
Fatti chiave
- Due funzioni:
invoke(senza firma PDA) einvoke_signed(con firma PDA). - Estensione dei privilegi: i privilegi degli account (firmatario, scrivibile) si estendono dal chiamante al chiamato. Un chiamato non può aumentare i privilegi oltre ciò che il chiamante ha passato.
- Budget di calcolo condiviso: il consumo di CU del chiamato riduce il budget rimanente del chiamante.
- Rientranza: l'auto-ricorsione diretta è consentita (A->A->A). La
rientranza indiretta non lo è (A->B->A restituisce
ReentrancyNotAllowed).
Limiti
| Limite | Valore | Fonte |
|---|---|---|
| Profondità massima stack istruzioni | 5 (9 con SIMD-0268) | MAX_INSTRUCTION_STACK_DEPTH, MAX_INSTRUCTION_STACK_DEPTH_SIMD_0268 |
| Costo invocazione CPI | 1.000 CU (946 con SIMD-0339) | DEFAULT_INVOCATION_COST, INVOKE_UNITS_COST_SIMD_0339 |
| Firmatari PDA massimi per CPI | 16 | MAX_SIGNERS |
| Dati istruzione CPI massimi | 10 KiB (10.240 byte) | MAX_INSTRUCTION_DATA_LEN |
| Dati di ritorno massimi | 1.024 byte | MAX_RETURN_DATA |
| Account info CPI massimi | 128 (255 con SIMD-0339)* | MAX_CPI_ACCOUNT_INFOS, MAX_CPI_ACCOUNT_INFOS_SIMD_0339 |
| Costo serializzazione CPI | 1 CU per 250 byte | cpi_bytes_per_unit |
| Riallocazione dati account massima per CPI | 10.240 byte (10 KiB) | MAX_PERMITTED_DATA_INCREASE |
invoke vs invoke_signed
Solana fornisce due funzioni per effettuare CPI:
| Funzione | Caso d'uso | Firma PDA |
|---|---|---|
invoke | CPI in cui tutti i firmatari richiesti hanno già firmato la transazione originale | No |
invoke_signed | CPI in cui il programma chiamante deve firmare per conto di un PDA di sua proprietà | Sì, tramite signer seeds |
Internamente, invoke chiama semplicemente invoke_signed con un array
di signer seeds vuoto. Usa invoke quando non hai bisogno della firma PDA,
e invoke_signed quando il programma deve autorizzare un'azione per conto
di un PDA.
Entrambe le funzioni attivano alla fine la stessa syscall
(sol_invoke_signed_rust)
e seguono lo stesso percorso di runtime
(cpi_common).
L'unica differenza è se vengono forniti i signer seeds. Quando i seeds vengono
forniti, il runtime deriva le pubkey PDA e le aggiunge all'insieme dei firmatari
validi prima del controllo dei privilegi.
Is this page helpful?