我在开发Solana的链上程序时出现超过计算单元最大单位的错误而崩溃。 有什么办法可以增加最大计算单元?
您可以参考 Solana Cookbook 中的这个tutorial
请注意,您必须将第一个指令作为设置预算的指令。
Typescript 的示例片段:
const data = Buffer.from(
Uint8Array.of(0, ...new BN(256000).toArray("le", 4))
);
const additionalComputeBudgetInstruction = new TransactionInstruction({
keys: [],
programId: new PublicKey("ComputeBudget111111111111111111111111111111"),
data,
});
const transaction = new Transaction()
.add(additionalComputeBudgetInstruction);
如果您使用
solana-program-test
来测试您的应用程序,您可以使用set_compute_max_units()
设置更高或更低的计算单元,即:
use solana_program_test::ProgramTest;
use crate::id;
use crate::processor::process_instruction;
let mut pt = ProgramTest::new("my_program", id(), processor!(process_instruction));
pt.set_compute_max_units(5_000_000);
对于
solana-test-validator
,暂不支持,欢迎PR!
1.9.2 版及更高版本的 SDK 确实对提高(或降低)计算预算和堆大小进行了更改。在
sdk/src/compute_budget.rs
的 solana 回购中
https://github.com/solana-labs/solana/blob/master/sdk/src/compute_budget.rs#L35
这应该适用于本地测试,但尚未为 devnet、mainnet-beta 等启用
它的工作方式是创建一个
request_units
指令并放在交易中的第一条指令:
/// Submits the program instruction as per the
/// instruction definition
fn submit_transaction(
rpc_client: &RpcClient,
wallet_signer: &dyn Signer,
instructions: Vec<Instruction>,
) -> Result<Signature, Box<dyn std::error::Error>> {
let mut transaction =
Transaction::new_unsigned(Message::new(&instructions, Some(&wallet_signer.pubkey())));
let recent_blockhash = rpc_client
.get_latest_blockhash()
.map_err(|err| format!("error: unable to get recent blockhash: {}", err))?;
transaction
.try_sign(&vec![wallet_signer], recent_blockhash)
.map_err(|err| format!("error: failed to sign transaction: {}", err))?;
let signature = rpc_client
.send_and_confirm_transaction(&transaction)
.map_err(|err| format!("error: send transaction: {}", err))?;
Ok(signature)
}
///
fn foo() {
// Other details omitted
let accounts = &[];
let instruction = Instruction::new_with_borsh(PROG_KEY, &0u8, accounts.to_vec());
let bump_budget = ComputeBudgetInstruction::request_units(400_000u32);
let txn = submit_transaction(
&connection,
&main_payer,
[bump_budget, instruction.clone(), instruction.clone()].to_vec(),
);
注意在日志输出中,第 3 行和第 7 行中的每条指令都有回撤:
[2022-02-05T09:08:49.715294000Z DEBUG solana_runtime::message_processor::stable_log] Program PWDnx8LkjJUn9bAVzG6Fp6BuvB41x7DkBZdo9YLMGcc invoke [1]
[2022-02-05T09:08:49.715522000Z DEBUG solana_runtime::message_processor::stable_log] Program log: process_instruction: PWDnx8LkjJUn9bAVzG6Fp6BuvB41x7DkBZdo9YLMGcc: 0 accounts, data=[0]
[2022-02-05T09:08:49.715551000Z DEBUG solana_runtime::message_processor::stable_log] Program PWDnx8LkjJUn9bAVzG6Fp6BuvB41x7DkBZdo9YLMGcc consumed 12843 of 400000 compute units
[2022-02-05T09:08:49.715675000Z DEBUG solana_runtime::message_processor::stable_log] Program PWDnx8LkjJUn9bAVzG6Fp6BuvB41x7DkBZdo9YLMGcc success
[2022-02-05T09:08:49.723680000Z DEBUG solana_runtime::message_processor::stable_log] Program PWDnx8LkjJUn9bAVzG6Fp6BuvB41x7DkBZdo9YLMGcc invoke [1]
[2022-02-05T09:08:49.723818000Z DEBUG solana_runtime::message_processor::stable_log] Program log: process_instruction: PWDnx8LkjJUn9bAVzG6Fp6BuvB41x7DkBZdo9YLMGcc: 0 accounts, data=[0]
[2022-02-05T09:08:49.723837000Z DEBUG solana_runtime::message_processor::stable_log] Program PWDnx8LkjJUn9bAVzG6Fp6BuvB41x7DkBZdo9YLMGcc consumed 12843 of 387157 compute units
[2022-02-05T09:08:49.724017000Z DEBUG solana_runtime::message_processor::stable_log] Program PWDnx8LkjJUn9bAVzG6Fp6BuvB41x7DkBZdo9YLMGcc success