From 96b0801f57a23164b0b72d0c3e910da9cd94d044 Mon Sep 17 00:00:00 2001 From: 0xbigapple Date: Wed, 1 Apr 2026 21:25:21 +0800 Subject: [PATCH] feat(jsonrpc): add blockTimestamp to logs and receipts --- .../tron/core/services/jsonrpc/TronJsonRpc.java | 14 +++++++++++--- .../core/services/jsonrpc/filters/LogMatch.java | 3 ++- .../services/jsonrpc/types/TransactionReceipt.java | 3 +++ .../org/tron/core/jsonrpc/LogMatchExactlyTest.java | 3 +++ .../services/jsonrpc/TransactionReceiptTest.java | 2 ++ 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java index 115df6ef9da..ea8f51fc465 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java @@ -461,10 +461,12 @@ class LogFilterElement { private final String[] topics; @Getter private final boolean removed; + @Getter + private final String blockTimestamp; public LogFilterElement(String blockHash, Long blockNum, String txId, Integer txIndex, String contractAddress, List topicList, String logData, int logIdx, - boolean removed) { + boolean removed, Long blockTimestamp) { logIndex = ByteArray.toJsonHex(logIdx); this.blockNumber = blockNum == null ? null : ByteArray.toJsonHex(blockNum); this.blockHash = blockHash == null ? null : ByteArray.toJsonHex(blockHash); @@ -477,6 +479,8 @@ public LogFilterElement(String blockHash, Long blockNum, String txId, Integer tx topics[i] = ByteArray.toJsonHex(topicList.get(i).getData()); } this.removed = removed; + this.blockTimestamp = blockTimestamp == null ? null + : ByteArray.toJsonHex(blockTimestamp / 1000); } @Override @@ -500,12 +504,16 @@ public boolean equals(Object o) { if (!Objects.equals(logIndex, item.logIndex)) { return false; } - return removed == item.removed; + if (removed != item.removed) { + return false; + } + return Objects.equals(blockTimestamp, item.blockTimestamp); } @Override public int hashCode() { - return Objects.hash(blockHash, transactionHash, transactionIndex, logIndex, removed); + return Objects.hash(blockHash, transactionHash, transactionIndex, + logIndex, removed, blockTimestamp); } } diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogMatch.java b/framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogMatch.java index cf958d1e2cb..67d229b2948 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogMatch.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogMatch.java @@ -66,7 +66,8 @@ public static List matchBlock(LogFilter logFilter, long blockN topicList, ByteArray.toHexString(log.getData().toByteArray()), logIndexInBlock, - removed + removed, + transactionInfo.getBlockTimeStamp() ); matchedLog.add(logFilterElement); } diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/types/TransactionReceipt.java b/framework/src/main/java/org/tron/core/services/jsonrpc/types/TransactionReceipt.java index fd57ec0d9ad..302b735212f 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/types/TransactionReceipt.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/types/TransactionReceipt.java @@ -35,6 +35,7 @@ public static class TransactionLog { private String data; private String[] topics; private boolean removed = false; + private String blockTimestamp; public TransactionLog() {} } @@ -108,6 +109,7 @@ public TransactionReceipt( // Set logs List logList = new ArrayList<>(); + String blockTimestamp = ByteArray.toJsonHex(txInfo.getBlockTimeStamp() / 1000); for (int logIndex = 0; logIndex < txInfo.getLogCount(); logIndex++) { TransactionInfo.Log log = txInfo.getLogList().get(logIndex); TransactionLog transactionLog = new TransactionLog(); @@ -116,6 +118,7 @@ public TransactionReceipt( transactionLog.setTransactionIndex(this.transactionIndex); transactionLog.setBlockHash(this.blockHash); transactionLog.setBlockNumber(this.blockNumber); + transactionLog.setBlockTimestamp(blockTimestamp); byte[] addressByte = convertToTronAddress(log.getAddress().toByteArray()); transactionLog.setAddress(ByteArray.toJsonHexAddress(addressByte)); diff --git a/framework/src/test/java/org/tron/core/jsonrpc/LogMatchExactlyTest.java b/framework/src/test/java/org/tron/core/jsonrpc/LogMatchExactlyTest.java index 0f9f125b74e..2151801fc59 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/LogMatchExactlyTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/LogMatchExactlyTest.java @@ -37,6 +37,7 @@ private TransactionInfo createTransactionInfo(byte[] address, byte[][] topicArra LogInfo logInfo = new LogInfo(address, topics, data); logList.add(LogInfo.buildLog(logInfo)); builder.addAllLog(logList); + builder.setBlockTimeStamp(1000000L); return builder.build(); } @@ -230,6 +231,8 @@ public void testMatchBlock() { LogFilterElement logFilterElement1 = elementList.get(0); LogFilterElement logFilterElement2 = elementList2.get(0); + Assert.assertEquals("0x3e8", logFilterElement1.getBlockTimestamp()); + Assert.assertEquals("0x3e8", logFilterElement2.getBlockTimestamp()); Assert.assertEquals(logFilterElement1.hashCode(), logFilterElement2.hashCode()); Assert.assertEquals(logFilterElement1, logFilterElement2); diff --git a/framework/src/test/java/org/tron/core/services/jsonrpc/TransactionReceiptTest.java b/framework/src/test/java/org/tron/core/services/jsonrpc/TransactionReceiptTest.java index a53a32daf45..2ba1187227c 100644 --- a/framework/src/test/java/org/tron/core/services/jsonrpc/TransactionReceiptTest.java +++ b/framework/src/test/java/org/tron/core/services/jsonrpc/TransactionReceiptTest.java @@ -32,6 +32,7 @@ public void testTransactionReceipt() throws JsonRpcInternalException { Protocol.TransactionInfo transactionInfo = Protocol.TransactionInfo.newBuilder() .setId(ByteString.copyFrom("1".getBytes())) .setContractAddress(ByteString.copyFrom("address1".getBytes())) + .setBlockTimeStamp(1000000L) .setReceipt(Protocol.ResourceReceipt.newBuilder() .setEnergyUsageTotal(100L) .setResult(Protocol.Transaction.Result.contractResult.DEFAULT) @@ -90,6 +91,7 @@ public void testTransactionReceipt() throws JsonRpcInternalException { Assert.assertEquals(transactionReceipt.getLogs()[0].getBlockNumber(), "0x1"); Assert.assertEquals(transactionReceipt.getLogs()[0].getTransactionHash(), "0x31"); Assert.assertEquals(transactionReceipt.getLogs()[0].getTransactionIndex(), "0x0"); + Assert.assertEquals(transactionReceipt.getLogs()[0].getBlockTimestamp(), "0x3e8"); // assert default fields Assert.assertNull(transactionReceipt.getRoot());