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.
Esempio di cross-program invocation
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?