You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Solana交易时出现的Transaction simulation failed指令处理错误

问题根因

错误触发点为代码第67行的unwrap()调用:调用迭代器的position()方法查找groom为a的记录时返回了None,直接调用unwrap()触发panic导致交易失败。

具体原因及修复方案

1. 反序列化错误分支逻辑缺失

原有代码中反序列化账户数据的match分支里,非InvalidData的错误场景仅打印了日志,既没有返回合法的Vec<LoveRecord>,也没有抛出错误终止程序,会导致existing_data_messages变量值异常,后续查找记录必然失败。
修复代码:

let mut existing_data_messages = match <Vec<LoveRecord>>::try_from_slice(&account.data.borrow()) {
    Ok(data) => data,
    Err(err) => {
        if err.kind() == InvalidData {
            msg!("InvalidData so initializing account data");
            get_init_love_records()
        } else {
            msg!("Unknown error decoding account data {:?}", err);
            return Err(ProgramError::InvalidAccountData);
        }
    }
};

2. 占位记录匹配逻辑风险

初始化的10条记录均为groom="a",第一次写入会把匹配到的第一条记录替换为传入的值,第二次调用时就找不到groom="a的占位记录,直接触发panic。
修复方案:
将unwrap()改为错误抛出,避免panic,同时可根据业务返回明确的无可用占位记录提示:

let index = existing_data_messages.iter().position(|p| p.groom == String::from(DUMMY_TX_ID))
    .ok_or(ProgramError::InvalidAccountData)?;

3. 账户空间不足风险

String类型的序列化长度是可变的,初始化的10条短字符串记录序列化后长度固定,若后续传入的groom或created_on长度超过初始值,序列化后的updated_data长度会超过账户分配的空间,执行copy_from_slice会触发越界错误。
修复方案:

  • 创建账户时预分配足够空间,按照业务最大可能的字段长度计算10条记录的总大小,初始化账户时直接分配对应容量
  • 或者将可变长度的String替换为固定长度数组存储内容,例如[u8; 64],避免序列化长度波动

4. 可变借用冲突问题

原有代码反序列化时使用了&account.data.borrow_mut(),只读反序列化不需要可变借用,容易和后续写入操作的借用产生冲突,改为只读的borrow()即可(参考第一条修复代码的写法)。

内容的提问来源于stack exchange,提问作者Akshay S P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:09:02