nitrate_program/
cpi.rs

1// Copyright (c) 2024 nifty-oss maintainers
2// Copyright (c) 2024 Magnetar Fields
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Cross-program invocation helper types.
17
18use solana_program::pubkey::Pubkey;
19
20use crate::account_info::AccountInfo;
21
22/// An `AccountMeta`` as expected by `sol_invoke_signed_c`.
23#[repr(C)]
24#[derive(Debug, Clone)]
25pub struct CAccountMeta {
26    // Public key of the account.
27    pub pubkey: *const Pubkey,
28
29    // Is the account writable?
30    pub is_writable: bool,
31
32    // Transaction was signed by this account's key?
33    pub is_signer: bool,
34}
35
36impl From<&AccountInfo> for CAccountMeta {
37    fn from(account: &AccountInfo) -> Self {
38        CAccountMeta {
39            pubkey: offset(account.raw, 8),
40            is_writable: account.is_writable(),
41            is_signer: account.is_signer(),
42        }
43    }
44}
45
46/// An `AccountInfo`` as expected by `sol_invoke_signed_c`.
47#[repr(C)]
48#[derive(Clone)]
49pub struct CAccountInfo {
50    // Public key of the account.
51    pub key: *const Pubkey,
52
53    // Number of lamports owned by this account.
54    pub lamports: *const u64,
55
56    // Length of data in bytes.
57    pub data_len: u64,
58
59    // On-chain data within this account.
60    pub data: *const u8,
61
62    // Program that owns this account.
63    pub owner: *const Pubkey,
64
65    // The epoch at which this account will next owe rent.
66    pub rent_epoch: u64,
67
68    // Transaction was signed by this account's key?
69    pub is_signer: bool,
70
71    // Is the account writable?
72    pub is_writable: bool,
73
74    // This account's data contains a loaded program (and is now read-only).
75    pub executable: bool,
76}
77
78#[inline(always)]
79const fn offset<T, U>(ptr: *const T, offset: usize) -> *const U {
80    unsafe { (ptr as *const u8).add(offset) as *const U }
81}
82
83impl From<&AccountInfo> for CAccountInfo {
84    fn from(account: &AccountInfo) -> Self {
85        CAccountInfo {
86            key: offset(account.raw, 8),
87            lamports: offset(account.raw, 72),
88            data_len: account.data_len() as u64,
89            data: offset(account.raw, 88),
90            owner: offset(account.raw, 40),
91            rent_epoch: 0,
92            is_signer: account.is_signer(),
93            is_writable: account.is_writable(),
94            executable: account.executable(),
95        }
96    }
97}
98
99/*
100impl CAccountInfo {
101    /// A CPI utility function
102    #[inline(always)]
103    pub(crate) fn to_account_meta(&self) -> CAccountMeta {
104        CAccountMeta {
105            pubkey: self.key,
106            is_writable: self.is_writable,
107            is_signer: self.is_signer,
108        }
109    }
110
111    /// A CPI utility function.
112    /// Intended for PDAs that didn't sign transaction but must sign for cpi.
113    #[inline(always)]
114    pub(crate) fn to_account_meta_signer(&self) -> CAccountMeta {
115        CAccountMeta {
116            pubkey: self.key,
117            is_writable: self.is_writable,
118            is_signer: true,
119        }
120    }
121}
122*/
123
124/// An `Instruction` as expected by `sol_invoke_signed_c`.
125#[repr(C)]
126#[derive(Debug, PartialEq, Clone)]
127pub struct CInstruction {
128    /// Public key of the program.
129    pub program_id: *const Pubkey,
130
131    /// Accounts expected by the program instruction.
132    pub accounts: *const CAccountMeta,
133
134    /// Number of accounts expected by the program instruction.
135    pub accounts_len: u64,
136
137    /// Data expected by the program instruction.
138    pub data: *const u8,
139
140    /// Length of the data expected by the program instruction.
141    pub data_len: u64,
142}