MongoDB 事件插件
通过 MongoDB 中继插件订阅 TRON 链上事件——自带索引与条件查询能力的数据库归档。可选配合 TRON Event Query 搭建 HTTP 事件查询网关。
前置阅读
MongoDB 事件插件负责将 TRON 链上产生的事件写入 MongoDB 数据库。相比于Kafka 插件,MongoDB 方案的优势在于可以直接基于数据库索引做临时条件查询(Ad-hoc Queries)。例如,可以检索“过去一小时内智能合约 A 触发的所有事件”或“地址 B 在指定区块范围内的全部交易流水”,无需额外搭建复杂的数据湖分析引擎。
如果业务需要归档链上事件,并提供条件检索与数据搜索能力,MongoDB 是更合适的选择。
一个完整的 MongoDB 事件订阅架构包含以下三个组件:
┌──────────────┐ 事件投递 ┌────────────┐ 数据写入 ┌──────────┐ HTTP 查询 ┌──────────┐
│ TRON 全节点 │ ──────────▶ │ 事件插件 │ ──────────▶ │ MongoDB │ ◀───────── │ 查询服务 │
│ (java-tron) │ (进程内) │ (.jar 包) │ │ 数据库 │ 数据查询 │ (选配项) │
└──────────────┘ └────────────┘ └──────────┘ └────┬─────┘
│ HTTP 响应
▼
┌──────────────┐
│ 业务系统 │
└──────────────┘其中,全节点、插件包及 MongoDB 数据库是整套架构的必要组件。查询服务(TRON Event Query)是可选组件:如果业务系统可以直接使用 MongoDB 驱动查询数据库,可以跳过该服务的部署。
推荐硬件(全节点与插件主机)
MongoDB 插件直接在全节点进程内部运行,其 CPU 和内存开销属于全节点总工作负载的一部分。MongoDB 数据库服务建议部署在独立的服务器上运行,防止高频的数据写入与索引计算和全节点的共识进程发生 CPU/内存/磁盘 I/O 上的抢占。
| 资源项 | 推荐硬件规格 |
|---|---|
| CPU / 内存 | 16 核 / 32 GB 以上 |
| SSD 磁盘 | 全节点数据至少 3 TB;MongoDB 容量按事件量和保留时间另行规划 |
| 运行环境 | Linux / macOS |
1. 编译 MongoDB 事件插件
从 GitHub 克隆事件插件代码,并使用 Gradle 编译打包出 MongoDB 版本:
git clone https://github.com/tronprotocol/event-plugin.git
cd event-plugin
./gradlew build编译成功后,当前版本生成的插件包位于:event-plugin/build/plugins/plugin-mongodb-3.0.0.zip。插件版本升级后文件名可能变化,请以 build/plugins 目录中的实际文件名为准,并在后续配置中使用同一文件名。
2. 部署 MongoDB 数据库
版本说明以下步骤以 Ubuntu 22.04 x86_64 上的 MongoDB 7.0.24 为例。ARM64 或其他操作系统应从 MongoDB 社区下载中心选择与系统和处理器架构匹配、仍在支持周期内的版本。
MongoDB 7.0 的服务端归档包不包含 MongoDB Shell,请另行按照 mongosh 安装指南安装
mongosh。
# 安装 MongoDB 二进制归档包所需的系统依赖
sudo apt-get update
sudo apt-get install -y curl libcurl4 libgssapi-krb5-2 libldap-2.5-0 libwrap0 \
libsasl2-2 libsasl2-modules libsasl2-modules-gssapi-mit openssl liblzma5
# 下载并校验归档包 — 以 Ubuntu 22.04 x86_64 上的 7.0.24 为例
MONGODB_VERSION=7.0.24
MONGODB_PLATFORM=ubuntu2204
MONGODB_ARCHIVE=mongodb-linux-x86_64-${MONGODB_PLATFORM}-${MONGODB_VERSION}.tgz
cd /home/java-tron
curl -O "https://fastdl.mongodb.org/linux/${MONGODB_ARCHIVE}"
curl -O "https://fastdl.mongodb.org/linux/${MONGODB_ARCHIVE}.sha256"
sha256sum -c "${MONGODB_ARCHIVE}.sha256"
tar zxvf "${MONGODB_ARCHIVE}"
mv "mongodb-linux-x86_64-${MONGODB_PLATFORM}-${MONGODB_VERSION}" mongodb
# 将二进制路径配置到环境变量中
export MONGOPATH=/home/java-tron/mongodb/
export PATH=$PATH:$MONGOPATH/bin
# 准备数据目录及日志文件存放路径
mkdir -p /home/java-tron/mongodb/{log,data}
touch /home/java-tron/mongodb/log/mongodb.log在本地创建配置文件 mgdb.conf:
storage:
dbPath: /home/java-tron/mongodb/data
wiredTiger:
engineConfig:
cacheSizeGB: 2
systemLog:
destination: file
path: /home/java-tron/mongodb/log/mongodb.log
logAppend: true
net:
port: 27017
bindIp: 127.0.0.1
processManagement:
fork: true
security:
authorization: enabled
核心参数说明
- 如果全节点与 MongoDB 部署在同一台服务器上,保持
net.bindIp: 127.0.0.1。跨主机部署时,应将net.bindIp设为127.0.0.1,<MongoDB-private-IP>,同时监听环回地址和 MongoDB 主机的明确私网 IP,并将后文的event.subscribe.server设为“该私网 IP +:27017”。通过防火墙或安全组仅允许全节点服务器访问,不要将 MongoDB 的27017端口开放给公网。- 解压前必须确认
sha256sum -c返回OK。更强的来源认证可按 MongoDB 官方指南使用发布签名验证。- MongoDB 会根据可用内存自动设置 WiredTiger 缓存大小。示例中的
storage.wiredTiger.engineConfig.cacheSizeGB: 2适用于 MongoDB 与全节点共享主机时为全节点预留内存,不是通用推荐值。请按主机可用内存调整;在容器中运行或与其他内存密集型进程共用主机时,建议显式限制缓存。
启动 MongoDB 并创建鉴权账户:
# 启动 MongoDB 服务
mongod --config ./mgdb.conf
# 进入控制台
mongosh
# 进入 admin 库创建超级管理员账户
> use admin
> db.createUser({user:"root", pwd:"<Your-Password1>", roles:[{role:"root", db:"admin"}]})
# 认证超级管理员登录,并创建 eventlog 数据库及其专属的 Owner 账户
> db.auth("root", "<Your-Password1>")
> use eventlog
> db.createUser({user:"tron", pwd:"<Your-Password2>", roles:[{role:"dbOwner", db:"eventlog"}]})请在实际部署中将 <Your-Password1> 和 <Your-Password2> 替换为强密码;后续 dbconfig、db.auth 和 mongo.password 中的 eventlog 用户密码必须与 <Your-Password2> 保持一致。
3. 配置全节点
在全节点的 config.conf 中追加 event.subscribe 配置块:
event.subscribe = {
enable = true // 启用事件订阅
version = 1 // 1 表示启用 V2.0 事件框架(支持历史回填);0 表示启用 V1.0 框架(默认值)
startSyncBlockNum = 0 // 仅在 V2.0 框架下有效——具体配置参见下方说明
native = {
useNativeQueue = false // 必须配置为 false,否则事件将走 ZeroMQ 而非外部插件
bindport = 5555
sendqueuelength = 1000
}
path = "/deploy/fullnode/event-plugin/build/plugins/plugin-mongodb-3.0.0.zip" // 插件包的绝对路径
server = "127.0.0.1:27017" // MongoDB 服务连接地址
dbconfig = "eventlog|tron|<Your-Password2>" // 格式为:数据库名|鉴权用户名|鉴权密码
contractParse = true
topics = [
{ triggerName = "block", enable = true, topic = "block" },
{ triggerName = "transaction", enable = true, topic = "transaction" },
{ triggerName = "contractevent", enable = true, topic = "contractevent" },
{ triggerName = "contractlog", enable = true, topic = "contractlog" }
]
filter = {
fromblock = "" // "", "earliest", 或特定的区块高度
toblock = "" // "", "latest", 或特定的区块高度
contractAddress = [ "" ] // 合约地址过滤;保留为空时匹配所有合约
contractTopic = [ "" ] // 事件哈希过滤;保留为空时匹配所有合约事件
}
}各配置项具体说明:
| 配置项名称 | 核心含义 |
|---|---|
enable | 设为 true 以启用事件订阅。 |
version | 事件中继框架版本。1 代表 V2.0(支持历史回填);0 代表 V1.0。详情请阅读事件服务框架介绍。 |
startSyncBlockNum | 仅在 V2.0 框架下生效。设为 0 或负值时禁用历史回填;设为正数时,启动后会从该指定的区块高度重播事件。 |
native.useNativeQueue | 必须配置为 false 以便通过插件进行投递。(若设为 true,全节点将直接走内置的 ZeroMQ 通道。) |
path | 指向本地插件包 plugin-mongodb-3.0.0.zip 的绝对路径。 |
server | MongoDB 的服务连接地址,格式为 IP:Port。默认端口为 27017。 |
dbconfig | 写入 MongoDB 时的认证配置,格式为 数据库名|账户名|密码。 |
contractParse | 设为 true 时,智能合约事件会由全节点先根据合约 ABI 自动解析完成,然后再存入 MongoDB 中。 |
topics[].triggerName | 触发器标识符。支持的七个选项已在事件类型中说明,不可修改。 |
topics[].enable | 设为 false 可暂时停用该类型的触发投递,而无需将其从配置中删除。 |
topics[].topic | 指定存储该类型事件的 MongoDB 集合(Collection)名称。 |
filter | 可选过滤器。用于按高度区间、特定合约或事件 Topic 哈希来过滤合约事件/日志的投递范围。 |
4. 启动全节点与连通性验证
确保 MongoDB 服务已经正常在后台运行,并在 config.conf 中设置 event.subscribe.enable = true,然后启动全节点:
java -jar FullNode.jar -c config.conf观察日志,验证 MongoDB 插件是否已成功加载:
tail -f logs/tron.log | grep -i eventplugin如果加载正常,控制台会出现类似以下日志输出:
[o.t.c.l.EventPluginLoader] '/path/to/plugin-mongodb-3.0.0.zip' loaded接着,进入 MongoDB 控制台,验证事件数据是否正在写入各数据集合中:
mongosh --host 127.0.0.1 --port 27017
> use eventlog
> db.auth("tron", "<Your-Password2>")
> show collections # 应该包含:block, transaction, contractevent, contractlog 等集合
> db.block.find().limit(1) # 查询最新写入的一条区块事件记录如果 find() 正常返回了 JSON 文档,说明整套事件订阅的中继链路已正常走通。如果未生成集合,请检查全节点日志中插件中继的报错信息,并核实 MongoDB 连接鉴权及网络可达性。
5. (可选)部署 TRON Event Query 服务
TRON Event Query 服务是一个基于 Spring Boot 编写的轻量级 HTTP 接口网关。它能将底层的 MongoDB 聚合查询封装为语义更明确的 RESTful API,供前端或下游业务调用。
运行环境TRON Event Query 的构建目标为 Java 8,请使用 JDK 8 进行构建和运行。其
deploy.sh使用bc计算 JVM 堆内存,运行该脚本前需安装bc。
从源码克隆并使用 Maven 进行打包编译:
git clone https://github.com/tronprotocol/tron-eventquery.git
cd tron-eventquery
# 安装并配置好 Maven 3.9+ 环境,并安装 deploy.sh 所需的 bc
sudo apt-get update
sudo apt-get install -y bc
mvn --version
mvn package编辑 tron-eventquery/config.conf 连接配置文件:
mongo.host=<mongo-ip>
mongo.port=27017
mongo.dbname=eventlog
mongo.username=tron
mongo.password=<Your-Password2>
mongo.connectionsPerHost=8
mongo.threadsAllowedToBlockForConnectionMultiplier=4在 MongoDB 7.0 环境中运行 insertIndex.sh 前,将脚本中的以下代码:
mongodb='mongo '$mongoIp':'$mongoPort替换为:
mongodb="mongosh --host ${mongoIp} --port ${mongoPort}"然后启动服务并构建必要的数据库查询索引:
sh deploy.sh
sh insertIndex.sh该服务默认监听 8080 端口。如需自定义运行端口,可以编辑 deploy.sh 脚本:
nohup java -jar -Dserver.port=8081 target/troneventquery-1.0.0-SNAPSHOT.jar 2>&1 &HTTP API 接口参考
该服务提供跨交易、转账、区块、日志等维度的 HTTP 查询接口。所有 API 默认返回 JSON 格式数据。接口的分页功能可通过参数 limit(默认 25 条)与 start(默认从 1 开始的索引)控制,排序可通过参数 sort 调节(前缀带 - 代表降序)。以下 base URL 为 http://<host>:<port>。
交易接口
| 接口 Endpoint | 具体用途 |
|---|---|
GET /transactions | 分页列出所有交易;支持参数:limit、sort、start、block |
GET /transactions/{hash} | 精确获取单笔交易的详情 |
示例请求:GET /transactions?limit=1&sort=-timeStamp&start=2&block=0
转账接口
| 接口 Endpoint | 具体用途 |
|---|---|
GET /transfers | 分页获取转账历史;支持参数:limit、sort、start、from、to、token |
GET /transfers/{hash} | 获取特定交易哈希中发生的转账记录 |
示例请求:GET /transfers?token=trx&limit=1&from=TJ7yJNWS8RmvpXcAyXBhvFDfGpV9ZYc3vt&to=TAEcoD8J7P5QjWT32r31gat8L7Sga2qUy8
事件接口
| 接口 Endpoint | 具体用途 |
|---|---|
GET /events | 分页列出事件;支持参数:limit、sort、start、since、block |
GET /events/transaction/{transactionId} | 获取特定交易产生的事件 |
GET /events/{contractAddress} | 获取指定智能合约产生的所有事件 |
GET /events/contract/{contractAddress}/{eventName} | 按合约地址 + 事件名称进行检索 |
GET /events/contract/{contractAddress}/{eventName}/{blockNumber} | 过滤查询区块高度大于等于 blockNumber 的合约事件 |
GET /events/timestamp | 查询在指定时间戳之后的事件;支持参数:since、contract、limit、sort |
GET /events/confirmed | 仅检索已被网络固化的区块中触发的事件;支持参数同上 |
示例请求:GET /events/TMYcx6eoRXnePKT1jVn25ZNeMNJ6828HWk?limit=1&sort=-timeStamp&block=0
区块接口
| 接口 Endpoint | 具体用途 |
|---|---|
GET /blocks | 分页查询区块元数据;支持参数:limit、sort、start、block |
GET /blocks/{hash} | 按区块哈希获取单区块信息 |
GET /blocks/latestSolidifiedBlockNumber | 获取当前网络最新的固化区块高度 |
合约原始日志接口
| 接口 Endpoint | 具体用途 |
|---|---|
GET /contractlogs | 分页查询原始日志;支持参数:limit、sort、start、block |
GET /contractlogs/transaction/{transactionId} | 获取特定交易中的所有原始日志 |
GET /contractlogs/contract/{contractAddress} | 获取特定合约产生的所有原始日志 |
GET /contractlogs/uniqueId/{uniqueId} | 根据唯一日志 ID 精确获取单条日志 |
基于请求体提供 ABI 的实时解码接口 (3.6+)
如果所查询的合约未注册,导致日志没有被自动解码,可以直接在 HTTP 请求体(POST)中附带合约 ABI,网关会执行即时反序列化解码:
| 接口 Endpoint | 传输请求体格式 |
|---|---|
POST /contract/transaction/{transactionId} | abi=<ABI 格式的 JSON 字符串> |
POST /contract/contractAddress/{contractAddress} | abi=<ABI 格式的 JSON 字符串> |
POST /contract/uniqueId/{uniqueId} | abi=<ABI 格式的 JSON 字符串> |
返回的 JSON 结构与 GET /contractlogs/... 类似,但其中的 data 字段已根据 POST 请求体中的 ABI 实时解码。
相关资源
- 事件订阅概述——如何选用 MongoDB、ZeroMQ 或 Kafka 方案
- ZeroMQ 事件插件——全节点内置事件分发通道的配置
- Kafka 事件插件——支持高吞吐与消息重播的 Kafka 方案
- 监听合约事件——应用层消费合约事件的实践指南
- 部署节点——节点基础部署步骤
Updated 8 days ago