22个版本
0.8.0-beta.3 | 2023年11月22日 |
---|---|
0.8.0-beta.2 | 2023年6月6日 |
0.7.9 | 2024年6月26日 |
0.7.7 | 2024年2月1日 |
0.5.0 | 2022年6月16日 |
#808 in 神奇豆子
494每月下载量
用于 3 crates
125KB
2K SLoC
NEAR Lake Framework
NEAR Lake Framework是NEAR Lake的一个小型库伴侣。它允许您构建自己的索引器,订阅来自NEAR Lake数据源的块流,并创建自己的逻辑来处理NEAR协议数据。
示例
fn main() -> anyhow::Result<()> {
near_lake_framework::LakeBuilder::default()
.testnet()
.start_block_height(112205773)
.build()?
.run(handle_block)?;
Ok(())
}
// The handler function to take the `Block`
// and print the block height
async fn handle_block(
block: near_lake_primitives::block::Block,
) -> anyhow::Result<()> {
eprintln!(
"Block #{}",
block.block_height(),
);
# Ok(())
}
将上下文传递给函数
#[derive(near_lake_framework::LakeContext)]
struct MyContext {
my_field: String
}
fn main() -> anyhow::Result<()> {
let context = MyContext {
my_field: "My value".to_string(),
};
near_lake_framework::LakeBuilder::default()
.testnet()
.start_block_height(112205773)
.build()?
.run_with_context(handle_block, &context)?;
Ok(())
}
// The handler function to take the `Block`
// and print the block height
async fn handle_block(
block: near_lake_primitives::block::Block,
context: &MyContext,
) -> anyhow::Result<()> {
eprintln!(
"Block #{} / {}",
block.block_height(),
context.my_field,
);
# Ok(())
}
收据上下文的父事务
这是一个老问题,NEAR协议在收据中不提供父事务哈希。这对于需要知道父事务哈希以构建事务树的索引器来说是一个问题。我们已经为你准备好了lake-parent-transaction-cache
crate,它提供了父事务哈希的缓存。
use near_lake_framework::near_lake_primitives;
use near_lake_primitives::CryptoHash;
use near_lake_parent_transaction_cache::{ParentTransactionCache, ParentTransactionCacheBuilder};
use near_lake_primitives::actions::ActionMetaDataExt;
fn main() -> anyhow::Result<()> {
let parent_transaction_cache_ctx = ParentTransactionCacheBuilder::default()
.build()?;
// Lake Framework start boilerplate
near_lake_framework::LakeBuilder::default()
.mainnet()
.start_block_height(88444526)
.build()?
// developer-defined async function that handles each block
.run_with_context(print_function_call_tx_hash, &parent_transaction_cache_ctx)?;
Ok(())
}
async fn print_function_call_tx_hash(
mut block: near_lake_primitives::block::Block,
ctx: &ParentTransactionCache,
) -> anyhow::Result<()> {
// Cache has been updated before this function is called.
let block_height = block.block_height();
let actions: Vec<(
&near_lake_primitives::actions::FunctionCall,
Option<CryptoHash>,
)> = block
.actions()
.filter_map(|action| action.as_function_call())
.map(|action| {
(
action,
ctx.get_parent_transaction_hash(&action.receipt_id()),
)
})
.collect();
if !actions.is_empty() {
// Here's the usage of the context.
println!("Block #{:?}\n{:#?}", block_height, actions);
}
Ok(())
}
教程
更多示例
您可以在examples
文件夹中查看始终更新的示例。
我们试图保持更新的其他示例,但有时可能会失败
-
https://github.com/near-examples/near-lake-raw-printer 基于NEAR Lake Framework构建的数据打印器的简单示例
-
https://github.com/near-examples/near-lake-accounts-watcher 基于NEAR Lake框架构建的索引器的一个简单示例,用于教程目的
-
https://github.com/near-examples/indexer-tx-watcher-example-lake 基于NEAR Lake框架构建的索引器示例,用于监视与指定账户相关的交易
-
https://github.com/octopus-network/octopus-near-indexer-s3 一个使用NEAR Lake框架的社区项目
使用方法
AWS S3凭据
为了能够从AWS S3存储桶中获取对象,您需要提供AWS凭据。
将凭据传递给配置构建器
use near_lake_framework::LakeBuilder;
# fn main() {
let credentials = aws_credential_types::Credentials::new(
"AKIAIOSFODNN7EXAMPLE",
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
None,
None,
"custom_credentials",
);
let s3_config = aws_sdk_s3::Config::builder()
.credentials_provider(credentials)
.build();
let lake = LakeBuilder::default()
.s3_config(s3_config)
.s3_bucket_name("near-lake-data-custom")
.s3_region_name("eu-central-1")
.start_block_height(1)
.build()
.expect("Failed to build LakeConfig");
# }
您绝对不应该将凭据硬编码,这是不安全的。使用描述的方法通过CLI参数传递您读取的凭据
基于文件的AWS凭据
使用aws configure设置的AWS默认配置文件看起来类似于以下内容
~/.aws/credentials
[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
环境变量
或者,您可以通过具有常量名称的环境变量提供您的AWS凭据
$ export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
$ AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
$ AWS_DEFAULT_REGION=eu-central-1
依赖关系
将以下依赖关系添加到您的 Cargo.toml
...
[dependencies]
futures = "0.3.5"
itertools = "0.10.3"
tokio = { version = "1.1", features = ["sync", "time", "macros", "rt-multi-thread"] }
tokio-stream = { version = "0.1" }
# NEAR Lake Framework
near-lake-framework = "0.8.0"
自定义S3存储
如果您想运行自己的 near-lake 实例并在某些S3兼容存储中(例如Minio 或 Localstack)存储数据,您可以通过使用 s3_endpoint
选项覆盖默认S3 API端点
- 运行minio
$ mkdir -p /data/near-lake-custom && minio server /data
- 将自定义
aws_sdk_s3::config::Config
传递到 [LakeBuilder]
use near_lake_framework::LakeBuilder;
# #[tokio::main]
# async fn main() -> anyhow::Result<()> {
let aws_config = aws_config::from_env().load().await;
let s3_config = aws_sdk_s3::config::Builder::from(&aws_types::SdkConfig::from(aws_config))
.endpoint_url("http://0.0.0.0:9000")
.build();
LakeBuilder::default()
.s3_bucket_name("near-lake-custom")
.s3_region_name("eu-central-1")
.start_block_height(0)
.s3_config(s3_config)
.build()
.expect("Failed to build Lake");
# Ok(())
# }
配置
您应该通过 LakeConfigBuilder
结构在索引器应用程序启动之前配置所有内容。
可用参数
start_block_height(value: u64)
- 从该区块高度开始流式传输- 可选
s3_bucket_name(value: impl Into<String>)
- 提供AWS S3存储桶名称(如果您使用自定义S3兼容服务,则需要提供,否则您可以使用 LakeConfigBuilder::mainnet 和 LakeConfigBuilder::testnet) - 可选
LakeConfigBuilder::s3_region_name(value: impl Into<String>)
- 提供AWS S3区域名称(如果您需要设置自定义的) - 可选
LakeConfigBuilder::s3_config(value: aws_sdk_s3::config::Config
- 提供自定义 AWS SDK S3 配置
成本估算(2022年3月10日更新,计算更精确)
TL;DR 大约每月20美元(用于 AWS S3 访问,直接支付给 AWS)用于读取新鲜块
历史索引
块 | GET | LIST | GET 小计 | LIST 小计 | 总计 $ |
---|---|---|---|---|---|
1000 | 5000 | 4 | 0.00215 | 0.0000216 | $0.00 |
86,400 | 432000 | 345.6 | 0.18576 | 0.00186624 | $0.19 |
2,592,000 | 12960000 | 10368 | 5.5728 | 0.0559872 | $5.63 |
77,021,059 | 385105295 | 308084.236 | 165.5952769 | 1.663654874 | $167.26 |
注意: ~77m 的块是在我计算时的块数。
每天约84,400个块(每秒1个块 * 60秒 * 60分钟 * 24小时)
每月约2,592,000个块(每天86,400个块 * 30天)
网络索引的顶端
块 | GET | LIST | GET 小计 | LIST 小计 | 总计 $ |
---|---|---|---|---|---|
1000 | 5000 | 1000 | 0.00215 | 0.0054 | $0.01 |
86,400 | 432000 | 86,400 | 0.18576 | 0.46656 | $0.65 |
2,592,000 | 12960000 | 2,592,000 | 5.5728 | 13.9968 | $19.57 |
77,021,059 | 385105295 | 77,021,059 | 165.5952769 | 415.9137186 | $581.51 |
说明
假设 NEAR 协议每秒准确产生1个块(这实际上并不准确,平均块生产时间是1.3秒)。一天由86400秒组成,这是可以产生的最大块数。
根据Amazon S3 价格,list
请求按每1000次请求0.0054美元计费,而get
按每1000次请求0.00043美元计费。
计算(假设我们始终跟随网络顶端)
86400 blocks per day * 5 requests for each block / 1000 requests * $0.0004 per 1k requests = $0.19 * 30 days = $5.7
注意: 每个块的5个请求意味着我们有4个分片(1个用于公共块数据的文件和4个用于每个分片的单独文件)
我们需要在30天内执行的list
请求数量
86400 blocks per day / 1000 requests * $0.005 per 1k list requests = $0.47 * 30 days = $14.1
$5.7 + $14.1 = $19.8
价格取决于分片的数量
未来计划
我们使用具有明确验收标准的里程碑
依赖关系
~45MB
~731K SLoC