本文深入探讨了Solana区块链中的Bank模块,重点介绍其在账户和程序状态管理、交易执行和程序调用验证中的关键角色,详述了Bank的生命周期、InvokeContext的处理以及与计算资源的管理等技术细节。
接下来的第三部分:TPU,本文详细讲解了 bank 模块,这是 Solana 区块链的核心组件。
银行模块的重要性不容忽视:
它管理所有账户和程序的状态,执行链上程序,并跟踪它们的进展。
在高层次上,一个 bank 与由单一领导者生成的块相关,每个 bank(除了创世银行)指向一个父银行。
bank 是处理已确认交易的主要入口。在 Bank::process_transactions 中,它创建一个 InvokeContext 来处理每个交易 。
invoke_context.process_instruction 是处理每个指令的关键函数,它验证被调用的程序没有不当行为,维护一个缓存以存储编译的指令,并返回使用的计算单位等。
它有几个参数:instruction_data 和 instruction_accounts,program_indices(用于检索调用的 program_id)、compute_units_consumed(记录执行指令时使用的计算单位,初始为 0)和 timings(用于执行时间信息)。
要在程序上调用指令,invoke_context.process_instruction 首先使用程序的拥有者加载程序,然后调用程序的入口点。
被调用程序的拥有者是以下之一:
如果它是本地加载程序( NativeLoader1111111111111111111111111111111),那么相应的内置程序的入口点 process_instruction 将被调用:
否则,内置程序的入口点 process_instruction 将被调用:
process_instruction 函数接受三个参数作为输入:first_instruction_account(被调用的 program_id)、instruction_data 和 invoke_context 本身:
考虑 system_instruction.process_instruction,它处理以下指令:
使用最频繁的指令是 CreateAccount, Transfer 和 Allocate。
bpf_loader.process_instruction 函数用于执行用户部署的智能合约(即,BPF 字节码):
该函数调用 process_instruction_common,创建一个 BpfExecutor 并传递程序数据,然后调用其执行函数:
在 BpfExecutor.execute 中,它创建一个虚拟机并通过 vm.execute_program_jit 或 vm.execute_program_interpreted 执行程序。
重要的是,BPF 字节码并不是由 Linux 内核执行,而是由一个 BPF 虚拟机( EbpfVm)。
默认情况下,use_jit 为假,使用 vm.execute_program_interpreted,即 BPF 代码由虚拟机解释。这也意味着 Solana 有很大的潜力进一步提高性能,例如通过在 Linux 内核中本机执行 BPF 代码(尽管需要更多技术细节和安全保护措施)。
虚拟机是 EbpfVm,在 rbpf 中定义( uBPF 的扩展版本:用于eBPF程序的虚拟机和 JIT 编译器)。
请注意,rbpf 并未经过审计,它包含许多不安全的 Rust 函数块。rbpf 中的任何错误可能导致严重的漏洞,例如整数溢出和内存损坏。有关示例,请参见 BlockSec 的 这篇文章。
当被调用程序通过 invoke 或 invoke_signed 调用另一个程序时,该程序将被加载并调用其入口点。
在内部,这是通过 syscall 调用 sol_invoke_signed_rust 来完成的,此后将再次调用 invoke_context.process_instruction。
相应的 BPF 指令是 ebpf::CALL_IMM(参见 vm.rs L939-L972)
syscall.function 是从 syscall_registry 中检索的,该注册中心已使用许多内置系统调用进行初始化,如 sol_invoke_signed_c、sol_invoke_signed_rust、sol_create_program_address、sol_keccak256 等。
有关注册系统调用的完整列表,请参见 syscall.rs。
在处理 CPI 后,结果(对所有涉及账户的更新)将被复制回调用者:
InvokeContext 具有一个 transaction_context 用于跟踪当前调用上下文,并确保
Solana 在验证指令调用的设计 类似于 事务内存:它先执行指令,然后验证结果,以确保被调用程序没有不当行为。
bank 还负责验证指令和每个 CPI 的结果,以判断是否符合 会计规则,这是一系列对 Solana 非常关键的属性。
具体取决于调用级别,它将调用 verify 或 verify_and_update(如果验证,则也更新结果):
bank 在指令执行前后维护指令账户的状态,并广泛检查规则:
在高层次上,银行的生命周期包括以下阶段:
我们将继续在下一篇文章中介绍 Solana 的架构及其技术组件。
sec3 是一家安全研究公司,为 Solana 项目为数百万用户提供准备工作。sec3 的启动审计是一次严格的以研究者为主导的代码检查,旨在调查并认证主网等级智能合约;sec3 的持续审计软件平台 X-ray 与 GitHub 集成,逐步扫描拉取请求,帮助项目在部署前巩固代码;sec3 的部署后安全解决方案 WatchTower 确保资金安全。sec3 正在为 Web3 项目构建基于技术的可扩展解决方案,以确保在扩展时协议能够保持安全。
要了解更多关于 sec3 的信息,请访问 https://www.sec3.dev
- 原文链接: sec3.dev/blog/solana-int...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!