Skip to main content

只读账户

这个设计涵盖了runtime对只读和可写账户的处理。 修改同一账户的多个事务必须串行处理,以便它们总是以相同的顺序重放。 否则,这可能会给账本引入非确定性。 然而,有些事务只需要读取,而不需要修改特定账户的数据。 由于重放顺序并不重要,因此可以并行处理多个只读取同一账户的事务,从而提供性能优势。

为了识别只读账户,事务MessageHeader结构包含num_readonly_signed_accountsnum_readonly_unsigned_accounts。 指令program_ids作为只读、无符号账户包含在账户向量中,因为可执行账户同样不能在指令处理过程中被修改。

Runtime处理#

Runtime的交易处理规则需要稍微更新。 程序仍然不能写入或花费不属于自己的账户。 但新的runtime规则保证了只读账户不能被修改,即使是拥有这些账户的程序也不能修改。

只读账户具有以下属性。

  • 只读访问所有账户字段,包括lamports(不能贷记或借记) 和账户数据。

贷记、借记或修改只读账户的指令将失败。

账户锁定优化#

账户模块在runtime跟踪当前锁定的账户,从而将只读账户和可写账户分开。 默认的账户锁给一个账户赋予了 "可写 "的称号,并且一次只能由一个处理线程访问。 只读账户由一个单独的机制锁定,允许并行读取。

虽然还没有实现,但只读账户可以缓存在内存中,并由所有执行事务的线程共享。 一个理想的设计是,当一个只读账户被任何在runtime移动的事务引用时,保持这个缓存,并在最后一个事务退出runtime释放缓存。

只读账户也可以作为引用传入处理器,保存一个额外的副本。