EOS数据
从EOS上线一段时间来看,他产生的Block已经远远超过了以太坊。以太坊在交易完成后,很容易过滤出交易信息(如何获取交易Hash,在我之前以太坊文章中有详细描述,以太坊爱好者可以参考)。EOS机制与以太坊有区别,EOS如此大的数据量,我们就会问,EOS数据时如何获取,查询。今天我们就这个问题,给大家分析一下。写这篇文章的原因是,我们的EOS网路开启一段时间后,出现了状况,我们定位出问题出在数据这部分。
Data的价值分析
随着区块量各种应用的爆棚,EOS每天增加的用户量上万。我们从https://www.dappradar.com/ 上分析当前DApp排行榜,就可以清查看到目前的热点和应用方向。
如此多的应用,大家非常关心就是,交易数据如何获取。
通过history_plugin插件获取交易数据
在EOSIO的1.3.0版本之前,官方提供文档通过history_plugin插件获取交易历史数据,通过一下配置,可以获取交易历史数据。
如果你想搜集所有的交易信息,包括收集所有traces信息,
我们可以查看V1.1.0版本的官方文档描述
Options
-f [ --filter-on ] arg Track actions which match
receiver:action:actor. Actor may be
blank to include all. Receiver and
Action may not be blank.
Config Options for eosio::http_client_plugin:
--https-client-root-cert arg PEM encoded trusted root certificate
(or path to file containing one) used
to validate any TLS connections made.
(may specify multiple times)
--https-client-validate-peers arg (=1)
true: validate that the peer
certificates are valid and trusted,
false: ignore cert errors
可以通过config.ini 文件配置。
需要配置如下插件,配置方式
# config.ini
plugin = eosio::history_plugin
通过启动node节点,通过参数配置如下:
# nodeos startup params
--plugin eosio::history_plugin
如果我们需要收集所有traces信息,那么欢需要在config.ini文件中打开下面配置
# Track actions which match receiver:action:actor. Actor may be blank to include all. Action and Actor both blank allows all from Recieiver. Receiver may not be blank. (eosio::history_plugin)
# filter-on = //默认
filter-on =* #打开配置
# Do not track actions which match receiver:action:actor. Action and Actor both blank excludes all from Reciever. Actor blank excludes all from reciever:action. Receiver may not be blank. (eosio::history_plugin)
# filter-out =
# PEM encoded trusted root certificate (or path to file containing one) used to validate any TLS connections made. (may specify multiple times)
# (eosio::http_client_plugin)
# https-client-root-cert =
那么我们如何获取数据,典型的做法是,我们同步一个node节点,加入EOS主网,同步最新的链上数据,同时就能很方便的执行转账,使用命令行玩各种DApps。当然如果你懒得配置nodeos,也可以使用各个超级BP提供的RPC API。
比如从链上取到的一个Transaction如下:
account1111-> account2222
{
"timestamp": "2018-08-16T12:45:57.000",
"producer": "eosbixinboot",
"confirmed": 0,
"previous": "00ae4ccb182c2906e443ab99e2fa85cf8744f4ee5951a40a526c54e2f629202e",
"transaction_mroot": "47a441fd376307c48fe4a081ad90b3ed731c2e659dd97950510f2938f7585b11",
"action_mroot": "9462c900fa1b4db6aead6f38cfde7ae5a5020c283d703e8f31bad3719e66afcb",
"schedule_version": 291,
"new_producers": null,
"header_extensions": [],
"producer_signature": "SIG_K1_JuPWPNAFyjPNqZSLx27NiNVBY2eU6fGcJK91hxuXwHMQxXLFAxVzUuPeTS1RoPg9r53SvCrpRwpLBetff7Hu7QxiqsjCWz",
"transactions": [
{
"status": "executed",
"cpu_usage_us": 1313,
"net_usage_words": 16,
"trx": {
"id": "678c8b715d84bdf9d99627c5dc54c62a3ae0a0f06b7a99663aa769b252ea3af6",
"signatures": [
"SIG_K1_KWMARsmdRjwBKkdsz2uxM2KtbkLVxQRnNEj4yrjPvoXLUNo3ougmkgeLnvfcJPPpyHcrtiAJN3cPgowwJRQjJP7PX9HmKz"
],
"compression": "none",
"packed_context_free_data": "",
"context_free_data": [],
"packed_trx": "2979755b754be0ef6f12000000000100a6823403ea3055000000572d3ccdcd0170b4a29d6aefa6de00000000a8ed32322170b4a29d6aefa6de30c61843a169a23958474c000000000004454f53000000000000",
"transaction": {
"expiration": "2018-08-16T13:16:25",
"ref_block_num": 19317,
"ref_block_prefix": 309325792,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [
{
"account": "eosio.token",
"name": "transfer",
"authorization": [
{
"actor": "account1111",
"permission": "active"
}
],
"data": {
"from": "account1111",
"to": "account2222",
"quantity": "499.9000 EOS",
"memo": ""
},
"hex_data": "70b4a29d6aefa6de30c61843a169a23958474c000000000004454f530000000000"
}
],
"transaction_extensions": []
}
}
}
],
"block_extensions": [],
"id": "00ae4ccc6879ed8936a6b90e133c6f8a37a3c2dbc6e1486a4df677ce148f0840",
"block_num": 11422924,
"ref_block_prefix": 247047734
}
这里是一个完整的Transaction信息。
首先获取到的块是一个json串,在块信息中,包含了块生成的时间,BP名称等基本信息,不细说,看名称就能识别。其中的Transaction信息,看上图,能看到执行的合约是eosio.token,执行的是转账(Transfer)操作,从data中能看到,发送者是account1111,发送给account2222,数量是499.9000 EOS,很简单,很直观。一般从区块浏览器中看到这些就够了,转账的确认再加上确认数就可以了。
如何配置history_plugin插件
在history_plugin插件的配置下,可以查询一个账号的Transaction和Action都依赖于此插件,因为这种配置也有非常大的问题,但是在EOSIO的1.3.0版本,已经移除了此插件。那么还有其他地方记录这些状态信息么?
通过MongoDB插件获取数据
EOS上的数据对外输出都直接是json格式的,而MongoDB非常适合存储这样的数据。在EOSIO官方文档中是mongo_db_plugin,查看此文档能帮助你如何使用,更多的信息还得看下它的历史。在EOSIO1.0版本中,其实你是看不到此插件的,而在1.1的版本中才恢复,而且在当时的版本,问题不少,功能也有欠缺;在1.2版本之后才越来越稳定好用。
看看使用该插件都存储了哪些信息:
官方文档中,描述的非常清晰,我们就简单挑选出主要部分
https://developers.eos.io/eosio-nodeos/v1.3.0/docs/mongo_db_plugin
accounts - created on applied transaction
action_traces - created on applied transaction
block_states - created on accepted block
- block_num
- block_id
- block_header_state -
- see eosio::chain::block_header_state
- validated
- in_current_chain
blocks - created on accepted block
- block_num
- block_id
- block - signed block - see eosio::chain::signed_block
- validated - added on irreversible block
- in_current_chain - added on irreversible block
- irreversible=true - added on irreversible block
transaction_traces - created on applied transaction
- see chain::eosio::transaction_trace
transactions - created on accepted transaction - does not include inline actions
see eosio::chain::signed_transaction. In addition to signed_transaction data the following are also stored.
- trx_id - transaction id
- irreversible=true - added on irreversible block
- block_id - added on irreversble block
- block_num - added on irreversible block
- signing_keys
- accepted
- implicit
- scheduled
account_controls - created on applied transaction. Always updated even if mongodb-store-action-traces=false.
- controlled_account
- controlling_permission
- controlling_account
可以通过一下 地址查询 /v1/history/get_controlled_acounts
db.account_controls.find({"controlling_account":"hellozhangyi"}).pretty()
pub_keys - created on applied transaction. Always updated even if mongodb-store-action-traces=false.
- account
- permission
- public_key
我们可以参考github上大家对MongoDB的讨论,https://github.com/EOSIO/eos/pull/5066 分析这个问题。
在没有action_traces之前,前面说的traces信息主要看transaction_traces,里面包含了所有合约调用交互的细节,比如买卖RAM的所有转账信息。
那如何使用呢,上面的官方文档里面有配置说明,通常在配置文件config.ini中增加如下配置即可,当然还得启动mongodb(下面的参考链接里有)
abi-serializer-max-time-ms = 5000
plugin = eosio::mongo_db_plugin
mongodb-uri = mongodb://localhost:27017/eos
# 曾经刷测TPS的账号,目前已经停止
mongodb-filter-out = blocktwitter:tweet:
# 可以控制存储哪些信息
#mongodb-store-blocks = false
# 可以选择从哪个块开始存储
#mongodb-block-start = 19455000
通过脚本实现,在启动脚本中加入如下:
--abi-serializer-max-time-ms 5000 --plugin eosio::mongo_db_plugin -- mongodb-uri mongodb://localhost:27017/eos
我们可以通过robo3t工具,浏览mongoDb数据。
https://robomongo.org/ 下载工具
在新的官方文档中,提供了其他一些插件连接,后续我们再继续分析。
我们对一些问题的思考的探索
EOSIO的代码更新很快,有时候觉得后进入整理数据的人有时候是幸运的,nodeos稳定许多,mongodb_db_plugin插件还增加了更多的功能。不过EOS的链上数据增长也很快,存储blocks的文件夹都已经有61G,mongodb光存储transactions_traces信息都有几百G了。
- state数据库
早期想保存所有traces信息的人,如果使用filter-on=*配置,简直就不可能。因为traces信息很快将state数据库填满,使你在config.ini中配置的chain-state-db-size-mb不够用,而这也将使nodeos的同步停止,IO飙升,只能升机器的内存,当时用过128G内存的机器,很快就不够用了。这个也和EOSIO使用的状态数据库chainbase有关,有兴趣的可以查查,这也是,我们链运行几周后,无法同步数据,让我们联合分析了很久才查到的原因,也正是我也整理这篇文章的主要原因。 - 垃圾数据
在主网正式运行后不久,就一直能看到blocktwitter账号执行tweet,来压测整个网络的TPS,导致了大量无用的信息,这也是前面配置过滤该账号的原因。而最近又有部分非常规数据出现,比如账号cryptohongbo,在10月11日左右的数据,Actions虽然不明显,但是在traces中能发现大量数据,还不知道是用来做什么的。 - 新增账号
前面提到块中信息的不完整,导致的一个问题就是新增账号数统计,有可能不准确。比如直接调用系统合约创建账号,那么在块信息中会有体现。但是很多合约如signupeoseos提供了通过转账,自动帮你创建账号的功能。而这些信息是在块中看不到的,只有traces新中才有。
2018年11月9日写于深圳