1 个稳定版本
1.11.2 | 2022年9月27日 |
---|---|
1.11.1 |
|
#14 in #geyser
15KB
102 代码行
最简单的 Geyser 插件
什么是 Solana Geyser 插件?
Solana 验证器可能会将账户和事务数据“泄露”到验证器之外。这种数据流是通过Geyser 插件接口。实现的。
外部库可以通过实现必要的函数来将该接口“插入”,从而监听账户和事务流。
该动态库在运行时提供给验证器。验证器可以打开该库并调用实现的回调或钩子,这些回调或钩子使用账户和事务数据。
然后库可以使用这些数据并采取进一步的操作,例如记录、将数据插入到数据库或消费者/生产者系统中等。
Solana Geyser 插件框架
这是您会遇到的最简单的 geyser 插件实现,它所做的只是记录来自插件管理器到我们的插件框架的每个调用。这是一个熟悉插件工作流程的好方法,更重要的是调试。
⚠️ 代码仅用于教育目的,在生产环境中,您会希望删除任何花哨的日志,并通过利用线程、不同的进程或外部服务等尽可能在钩子中做最少的工作...
试试看!
运行
./scripts/run.sh
我如何知道它是否工作?
./scripts/logs.sh
插件或验证器崩溃?
./scripts/check_errors.sh
插件实现示例
- 一个 PostgreSQL 插件
- 向 gRPC 服务发送插件的插件
- RabbitMQ 生产者插件
- 围绕 Geyser 插件的整体架构
- Kafka 生产者插件
- Amazon SQS 插件
- Google BigTable 插件
- 从 PostgreSQL 数据库接收请求的 RPC 服务器
更进一步
Geyser 插件配置
使用测试验证器时,动态库路径通过 --geyser-plugin-config
参数提供给验证器。
solana-test-validator --geyser-plugin-config config/geyser-plugin-config-mac.json
# or use ./scripts/run.sh
至少配置文件应该
- 是 JSON 格式
- 包含您的 geyser 插件动态库路径 .so 或(mac 上的 dylib)
例如
{
"libpath": "libsolana_geyser_plugin_scaffold.dylib"
}
当然,您的生产验证器不会在 mac 上运行,因此请相应地更新路径并使用 .so 版本。
此外,在运行时,Solana 插件管理器会将配置文件的路径传递回您的插件。在 on_load(&mut self, config_file: &str) 生命周期事件中,将提供 config_file
路径。因此,您可以添加任何您认为插件可能需要的附加配置,并在插件加载时进行解析。
关于插件管理器的更多信息
接下来是什么?
起始项目可能很简单,但最重要的是您能够调试并查看日志。
的确,如果您能够获取数据,接下来要做什么就完全取决于您了。问题是您将如何处理这些数据?
- 您会将这些日志转发到日志服务吗?
- 您会将这些数据插入到数据库中?并为您的特定需求创建索引?
- 您会构建一个完整的消费者/生产者系统,使用 Kafka 和其他队列管道吗?
- 天高任鸟飞,放手去实现吧!🚀
关于性能的注意事项
向前看,请确保将最小的工作量放入 trait 回调中!并且不仅限于回调,还包括从它们起源的所有同步执行路径。
实际上,您的插件正在运行验证器的一部分,而验证器是非常繁忙的!您需要确保尽快从回调中返回,并执行最小的工作。从那里,有多个策略
- 尽可能利用线程。
- 将艰巨的工作派发到外部进程,甚至到验证器机器之外。
- 利用队列系统,以扩展和增加您数据管道的可能性。
您可能需要上述解决方案之一,或者将它们全部组合。答案在于您的需求、您自己的基础设施和团队规模。
调试
(推荐方式)
使用您的 IDE,在库中添加一些断点,找到附加到 solana-test-validator
进程的选项,您现在可以调试库代码了!例如,这是在 CLion 中这样做的方式。
终端方式
这有点复杂,但有助于在生产机器上调试。(如果您的 IDE 允许使用反向 SSH 隧道进行远程调试,请尝试一下!)
-
运行验证器
-
使用 lldb 附加到进程
lldb -p `pgrep -x solana-test-validator`
-
此时,进程已经为您暂停
(lldb) Process XXXXX stopped
-
您现在可以在库中设置断点
(lldb) breakpoint set --name update_account
- 继续运行
(lldb) continue
Process 22436 resuming
- lldb 触发您的断点
thread #113, name = 'solPohTickProd', stop reason = breakpoint 1.1
frame #0: 0x000000010563ecd8 libsolana_geyser_plugin_scaffold.dylib`_$LT$solana_geyser_plugin_scaffold..geyser_plugin_hook..GeyserPluginHook$u20$as$u20$solana_geyser_plugin_interface..geyser_plugin_interface..GeyserPlugin$GT$::update_account::h6833f303509d44fe(self=0x0000000000000001, account=ReplicaAccountInfoVersions @ 0x00000002c4dc1c18, slot=16082, is_startup=false) at geyser_plugin_hook.rs:51:15
依赖项
~40–57MB
~1M SLoC