MongoDB event plugin

Subscribe to TRON on-chain events via the MongoDB plugin — indexed event storage you can query directly via HTTP through the optional TRON Event Query service. Best for analytics, ad-hoc lookups, and small applications.

📘

Prerequisites

The MongoDB plugin writes TRON on-chain events into MongoDB collections, where they remain indexed and queryable. Compared to the Kafka plugin, MongoDB does not provide replay-by-offset semantics but does offer ad-hoc queries — "give me every event from contract X in the last hour", "fetch transactions from address A between blocks N and M" — without standing up a separate analytics pipeline. Use MongoDB when you want events both stored and searchable from a single tool.

The full setup has three components:

┌──────────────┐   events    ┌────────────┐    write    ┌──────────┐    HTTP    ┌──────────┐
│ TRON Fullnode│ ──────────▶ │   Plugin   │ ──────────▶ │ MongoDB  │ ◀───────── │  Query   │
│  (java-tron) │  (in-proc)  │   (.jar)   │             │          │   query    │  Service │
└──────────────┘             └────────────┘             └──────────┘            └────┬─────┘
                                                                                     │ HTTP
                                                                                     ▼
                                                                              ┌──────────────┐
                                                                              │  your app    │
                                                                              └──────────────┘

The Fullnode + plugin + MongoDB combination is mandatory. The TRON Event Query service is optional — if you query MongoDB directly from your application, you can skip it.

Recommended hardware (Fullnode and plugin host)

The MongoDB plugin runs inside the Fullnode process, so its CPU and memory usage is part of the Fullnode's total workload. MongoDB itself can run on the same host or a different one — for production, prefer a separate host so MongoDB I/O does not contend with the consensus path.

ResourceSuggested
CPU / RAM16 cores / 32 GB
SSDAt least 3 TB for Fullnode data; size MongoDB separately for event volume and retention
OSLinux or macOS

1. Build the MongoDB event plugin

git clone https://github.com/tronprotocol/event-plugin.git
cd event-plugin
./gradlew build

After a successful build, the current version produces event-plugin/build/plugins/plugin-mongodb-3.0.0.zip. The filename may change when the plugin version changes. Use the filename actually generated under build/plugins, and use that same filename in the configuration below.

2. Deploy MongoDB

📘

Use a current MongoDB release.

The commands below use MongoDB 7.0.24 on Ubuntu 22.04 x86_64 as a concrete example. For ARM64 or another operating system, choose a supported release that matches both the operating system and processor architecture from the MongoDB Community Download Center.

MongoDB 7.0 server archives do not include the MongoDB Shell. Install mongosh separately by following the mongosh installation guide.

# Install the system libraries required by the MongoDB binary archive
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

# Download and verify — this example targets Ubuntu 22.04 x86_64 and MongoDB 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

# Set environment variables
export MONGOPATH=/home/java-tron/mongodb/
export PATH=$PATH:$MONGOPATH/bin

# Prepare data and log directories
mkdir -p /home/java-tron/mongodb/{log,data}
touch /home/java-tron/mongodb/log/mongodb.log

Create mgdb.conf with absolute paths:

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
📘

Configuration notes

  • For same-host deployments, keep net.bindIp: 127.0.0.1. For cross-host deployments, set net.bindIp to 127.0.0.1,<MongoDB-private-IP> so MongoDB listens on both loopback and the host's specific private IP address, then set the later event.subscribe.server setting to that private IP followed by :27017. Use a firewall or security group to allow only the Fullnode server, and do not make MongoDB port 27017 accessible from the public Internet.
  • Do not extract the archive unless sha256sum -c reports OK. For stronger source authentication, follow the MongoDB package verification guide and verify the release signature.
  • MongoDB automatically sizes the WiredTiger cache based on available memory. The example value storage.wiredTiger.engineConfig.cacheSizeGB: 2 reserves memory for the Fullnode when both services share a host; it is not a general recommendation. Adjust it for the host's available memory, and consider an explicit limit when running in a container or alongside other memory-intensive processes.

Start MongoDB and provision the accounts:

# Launch
mongod --config ./mgdb.conf

# Create an admin
mongosh
> use admin
> db.createUser({user:"root", pwd:"<Your-Password1>", roles:[{role:"root", db:"admin"}]})

# Create the eventlog database and its owner
> db.auth("root", "<Your-Password1>")
> use eventlog
> db.createUser({user:"tron", pwd:"<Your-Password2>", roles:[{role:"dbOwner", db:"eventlog"}]})

Replace <Your-Password1> and <Your-Password2> with strong production passwords. Use the same <Your-Password2> value in the later dbconfig, db.auth, and mongo.password settings.

3. Configure the Fullnode

Add an event.subscribe block to config.conf:

event.subscribe = {
  enable = true         // enable event subscription
  version = 1            // 1 = V2.0 event framework, 0 = V1.0 (default)
  startSyncBlockNum = 0  // V2.0 only — see below

  native = {
    useNativeQueue = false   // false routes events through the external plugin
    bindport = 5555
    sendqueuelength = 1000
  }

  path = "/deploy/fullnode/event-plugin/build/plugins/plugin-mongodb-3.0.0.zip"
  server = "127.0.0.1:27017"
  dbconfig = "eventlog|tron|<Your-Password2>"   // dbname|username|password
  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", or a block number
    toblock = ""               // "", "latest", or a block number
    contractAddress = [ "" ]   // empty matches all
    contractTopic = [ "" ]     // empty matches all
  }
}
FieldMeaning
enableSet to true to enable event subscription.
versionEvent framework version. 1 = V2.0 (supports historical backfill). 0 = V1.0 (default). See Event service framework for the differences.
startSyncBlockNumV2.0 only. 0 or negative disables historical sync; positive value replays events starting from that block.
native.useNativeQueueMust be false to route through the MongoDB plugin. (true selects the built-in ZeroMQ publisher.)
pathAbsolute path to plugin-mongodb-3.0.0.zip.
serverMongoDB address as IP:port. Default MongoDB port is 27017.
dbconfigdbname|username|password of the MongoDB database created above.
contractParseWhen true, contract events are decoded against the contract's ABI before being stored.
topics[].triggerNameBuilt-in trigger identifier. The seven supported values are documented in Event types. Must not be changed.
topics[].enablefalse leaves the entry inactive without removing it.
topics[].topicMongoDB collection name where this category's events are stored.
filterOptional. Narrows the contract-event/log streams by block range, contract address, or event topic. Block and transaction streams are not filtered.

4. Start the Fullnode and verify

Start MongoDB before the Fullnode, set event.subscribe.enable = true in config.conf, and then start the Fullnode:

java -jar FullNode.jar -c config.conf

Verify the plugin loaded:

tail -f logs/tron.log | grep -i eventplugin

A successful load logs:

[o.t.c.l.EventPluginLoader] '/path/to/plugin-mongodb-3.0.0.zip' loaded

Verify events are being written:

mongosh --host 127.0.0.1 --port 27017
> use eventlog
> db.auth("tron", "<Your-Password2>")
> show collections          # should list block, transaction, contractevent, contractlog
> db.block.find().limit(1)  # latest block event

If db.block.find() returns documents, the end-to-end flow is working. Otherwise, inspect the Fullnode log for plugin errors and the MongoDB log for connection or authentication errors.


5. (Optional) Deploy the TRON Event Query service

The TRON Event Query service is a small HTTP server that wraps MongoDB queries behind a REST API. Use it when your application prefers HTTP over a MongoDB driver.

📘

Runtime environment

TRON Event Query targets Java 8. Use JDK 8 to build and run the service. Its deploy.sh script uses bc to calculate the JVM heap size, so install bc before running the script.

# Clone
git clone https://github.com/tronprotocol/tron-eventquery.git
cd tron-eventquery

# Install Maven 3.9+ and bc, which is required by deploy.sh
sudo apt-get update
sudo apt-get install -y bc
mvn --version
mvn package

Configure 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

Before running insertIndex.sh with MongoDB 7.0, replace the following line in the script:

mongodb='mongo '$mongoIp':'$mongoPort

with:

mongodb="mongosh --host ${mongoIp} --port ${mongoPort}"

Then start the service and bootstrap the required indexes:

sh deploy.sh
sh insertIndex.sh

The service listens on port 8080 by default. To change the port, edit deploy.sh:

nohup java -jar -Dserver.port=8081 target/troneventquery-1.0.0-SNAPSHOT.jar 2>&1 &

HTTP API reference

The Event Query service exposes lookups across transactions, transfers, events, and blocks. All endpoints return JSON; pagination is via limit (default 25) and start (default 1, 1-indexed). Sort order is controlled by sort (prefix with - for descending). The base URL below is http://<host>:<port>.

Transactions

EndpointPurpose
GET /transactionsList transactions; supports limit, sort, start, block
GET /transactions/{hash}Fetch a single transaction by ID

Example: GET /transactions?limit=1&sort=-timeStamp&start=2&block=0

Transfers

EndpointPurpose
GET /transfersList transfers; supports limit, sort, start, from, to, token
GET /transfers/{hash}Fetch transfers in a specific transaction

Example: GET /transfers?token=trx&limit=1&from=TJ7yJNWS8RmvpXcAyXBhvFDfGpV9ZYc3vt&to=TAEcoD8J7P5QjWT32r31gat8L7Sga2qUy8

Events

EndpointPurpose
GET /eventsList events; supports limit, sort, start, since, block
GET /events/transaction/{transactionId}Events emitted by a specific transaction
GET /events/{contractAddress}Events from a specific contract
GET /events/contract/{contractAddress}/{eventName}Events filtered by contract + event name
GET /events/contract/{contractAddress}/{eventName}/{blockNumber}Same, filtered to blocks ≥ blockNumber
GET /events/timestampEvents at or after a timestamp; supports since, contract, limit, start, sort
GET /events/confirmedEvents from solidified blocks only; supports since, limit, start, sort

Example: GET /events/TMYcx6eoRXnePKT1jVn25ZNeMNJ6828HWk?limit=1&sort=-timeStamp&block=0

Blocks

EndpointPurpose
GET /blocksList blocks; supports limit, sort, start, block
GET /blocks/{hash}Fetch a single block by hash
GET /blocks/latestSolidifiedBlockNumberThe latest solidified block number

Contract logs

EndpointPurpose
GET /contractlogsList contract logs; supports limit, sort, start, block
GET /contractlogs/transaction/{transactionId}Logs from a specific transaction
GET /contractlogs/contract/{contractAddress}Logs from a specific contract
GET /contractlogs/uniqueId/{uniqueId}Log by unique ID

Contract logs with on-request ABI (3.6+)

When the contract is not pre-registered, you can POST the ABI together with the lookup:

EndpointBody
POST /contract/transaction/{transactionId}abi=<ABI JSON>
POST /contract/contractAddress/{contractAddress}abi=<ABI JSON>
POST /contract/uniqueId/{uniqueId}abi=<ABI JSON>

These return the same shape as GET /contractlogs/... but with logs decoded against the supplied ABI on the fly.


Related resources