Skip to content

Commit 25b1a69

Browse files
Merge pull request #6007 from waynercheung/feat/ethGetBlockByNumber_finalized
feat(jsonrpc): jsonrpc supports finalized
2 parents e3ab041 + afd9540 commit 25b1a69

File tree

7 files changed

+454
-185
lines changed

7 files changed

+454
-185
lines changed

framework/src/main/java/org/tron/core/Wallet.java

+25-5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
import static org.tron.core.config.Parameter.DatabaseConstants.PROPOSAL_COUNT_LIMIT_MAX;
3030
import static org.tron.core.services.jsonrpc.JsonRpcApiUtil.parseEnergyFee;
3131
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.EARLIEST_STR;
32+
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.FINALIZED_STR;
33+
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.LATEST_STR;
34+
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.PENDING_STR;
35+
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.TAG_PENDING_SUPPORT_ERROR;
3236
import static org.tron.core.vm.utils.FreezeV2Util.getV2EnergyUsage;
3337
import static org.tron.core.vm.utils.FreezeV2Util.getV2NetUsage;
3438
import static org.tron.protos.contract.Common.ResourceCode;
@@ -682,6 +686,20 @@ public Block getBlockByNum(long blockNum) {
682686
}
683687
}
684688

689+
public Block getSolidBlock() {
690+
try {
691+
long blockNum = getSolidBlockNum();
692+
return chainBaseManager.getBlockByNum(blockNum).getInstance();
693+
} catch (StoreException e) {
694+
logger.info(e.getMessage());
695+
return null;
696+
}
697+
}
698+
699+
public long getSolidBlockNum() {
700+
return chainBaseManager.getDynamicPropertiesStore().getLatestSolidifiedBlockNum();
701+
}
702+
685703
public BlockCapsule getBlockCapsuleByNum(long blockNum) {
686704
try {
687705
return chainBaseManager.getBlockByNum(blockNum);
@@ -707,10 +725,12 @@ public long getTransactionCountByBlockNum(long blockNum) {
707725
public Block getByJsonBlockId(String id) throws JsonRpcInvalidParamsException {
708726
if (EARLIEST_STR.equalsIgnoreCase(id)) {
709727
return getBlockByNum(0);
710-
} else if ("latest".equalsIgnoreCase(id)) {
728+
} else if (LATEST_STR.equalsIgnoreCase(id)) {
711729
return getNowBlock();
712-
} else if ("pending".equalsIgnoreCase(id)) {
713-
throw new JsonRpcInvalidParamsException("TAG pending not supported");
730+
} else if (FINALIZED_STR.equalsIgnoreCase(id)) {
731+
return getSolidBlock();
732+
} else if (PENDING_STR.equalsIgnoreCase(id)) {
733+
throw new JsonRpcInvalidParamsException(TAG_PENDING_SUPPORT_ERROR);
714734
} else {
715735
long blockNumber;
716736
try {
@@ -725,8 +745,8 @@ public Block getByJsonBlockId(String id) throws JsonRpcInvalidParamsException {
725745

726746
public List<Transaction> getTransactionsByJsonBlockId(String id)
727747
throws JsonRpcInvalidParamsException {
728-
if ("pending".equalsIgnoreCase(id)) {
729-
throw new JsonRpcInvalidParamsException("TAG pending not supported");
748+
if (PENDING_STR.equalsIgnoreCase(id)) {
749+
throw new JsonRpcInvalidParamsException(TAG_PENDING_SUPPORT_ERROR);
730750
} else {
731751
Block block = getByJsonBlockId(id);
732752
return block != null ? block.getTransactionsList() : null;

framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcApiUtil.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package org.tron.core.services.jsonrpc;
22

33
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.EARLIEST_STR;
4+
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.FINALIZED_STR;
45
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.LATEST_STR;
56
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.PENDING_STR;
7+
import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.TAG_PENDING_SUPPORT_ERROR;
68

79
import com.google.common.base.Throwables;
810
import com.google.common.primitives.Longs;
@@ -513,14 +515,17 @@ public static long parseEnergyFee(long timestamp, String energyPriceHistory) {
513515
return -1;
514516
}
515517

516-
public static long getByJsonBlockId(String blockNumOrTag) throws JsonRpcInvalidParamsException {
518+
public static long getByJsonBlockId(String blockNumOrTag, Wallet wallet)
519+
throws JsonRpcInvalidParamsException {
517520
if (PENDING_STR.equalsIgnoreCase(blockNumOrTag)) {
518-
throw new JsonRpcInvalidParamsException("TAG pending not supported");
521+
throw new JsonRpcInvalidParamsException(TAG_PENDING_SUPPORT_ERROR);
519522
}
520523
if (StringUtils.isEmpty(blockNumOrTag) || LATEST_STR.equalsIgnoreCase(blockNumOrTag)) {
521524
return -1;
522525
} else if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)) {
523526
return 0;
527+
} else if (FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
528+
return wallet.getSolidBlockNum();
524529
} else {
525530
return ByteArray.jsonHexToLong(blockNumOrTag);
526531
}

framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java

+12-5
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,13 @@ public enum RequestSource {
136136
public static final String EARLIEST_STR = "earliest";
137137
public static final String PENDING_STR = "pending";
138138
public static final String LATEST_STR = "latest";
139+
public static final String FINALIZED_STR = "finalized";
140+
public static final String TAG_PENDING_SUPPORT_ERROR = "TAG pending not supported";
139141

140142
private static final String JSON_ERROR = "invalid json request";
141143
private static final String BLOCK_NUM_ERROR = "invalid block number";
142-
private static final String TAG_NOT_SUPPORT_ERROR = "TAG [earliest | pending] not supported";
144+
private static final String TAG_NOT_SUPPORT_ERROR =
145+
"TAG [earliest | pending | finalized] not supported";
143146
private static final String QUANTITY_NOT_SUPPORT_ERROR =
144147
"QUANTITY not supported, just support TAG as latest";
145148
private static final String NO_BLOCK_HEADER = "header not found";
@@ -351,7 +354,8 @@ public String getLatestBlockNum() {
351354
public String getTrxBalance(String address, String blockNumOrTag)
352355
throws JsonRpcInvalidParamsException {
353356
if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)
354-
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)) {
357+
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)
358+
|| FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
355359
throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR);
356360
} else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) {
357361
byte[] addressData = addressCompatibleToByteArray(address);
@@ -488,7 +492,8 @@ private String call(byte[] ownerAddressByte, byte[] contractAddressByte, long va
488492
public String getStorageAt(String address, String storageIdx, String blockNumOrTag)
489493
throws JsonRpcInvalidParamsException {
490494
if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)
491-
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)) {
495+
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)
496+
|| FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
492497
throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR);
493498
} else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) {
494499
byte[] addressByte = addressCompatibleToByteArray(address);
@@ -523,7 +528,8 @@ public String getStorageAt(String address, String storageIdx, String blockNumOrT
523528
public String getABIOfSmartContract(String contractAddress, String blockNumOrTag)
524529
throws JsonRpcInvalidParamsException {
525530
if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)
526-
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)) {
531+
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)
532+
|| FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
527533
throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR);
528534
} else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) {
529535
byte[] addressData = addressCompatibleToByteArray(contractAddress);
@@ -823,7 +829,8 @@ public String getCall(CallArguments transactionCall, Object blockParamObj)
823829
}
824830

825831
if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag)
826-
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)) {
832+
|| PENDING_STR.equalsIgnoreCase(blockNumOrTag)
833+
|| FINALIZED_STR.equalsIgnoreCase(blockNumOrTag)) {
827834
throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR);
828835
} else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) {
829836
byte[] addressData = addressCompatibleToByteArray(transactionCall.getFrom());

framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogFilterWrapper.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@ public LogFilterWrapper(FilterRequest fr, long currentMaxBlockNum, Wallet wallet
5151
// then if toBlock < maxBlockNum, set fromBlock = toBlock
5252
// then if toBlock >= maxBlockNum, set fromBlock = maxBlockNum
5353
if (StringUtils.isEmpty(fr.getFromBlock()) && StringUtils.isNotEmpty(fr.getToBlock())) {
54-
toBlockSrc = JsonRpcApiUtil.getByJsonBlockId(fr.getToBlock());
54+
toBlockSrc = JsonRpcApiUtil.getByJsonBlockId(fr.getToBlock(), wallet);
5555
if (toBlockSrc == -1) {
5656
toBlockSrc = Long.MAX_VALUE;
5757
}
5858
fromBlockSrc = Math.min(toBlockSrc, currentMaxBlockNum);
5959

6060
} else if (StringUtils.isNotEmpty(fr.getFromBlock())
6161
&& StringUtils.isEmpty(fr.getToBlock())) {
62-
fromBlockSrc = JsonRpcApiUtil.getByJsonBlockId(fr.getFromBlock());
62+
fromBlockSrc = JsonRpcApiUtil.getByJsonBlockId(fr.getFromBlock(), wallet);
6363
if (fromBlockSrc == -1) {
6464
fromBlockSrc = currentMaxBlockNum;
6565
}
@@ -70,8 +70,8 @@ public LogFilterWrapper(FilterRequest fr, long currentMaxBlockNum, Wallet wallet
7070
toBlockSrc = Long.MAX_VALUE;
7171

7272
} else {
73-
fromBlockSrc = JsonRpcApiUtil.getByJsonBlockId(fr.getFromBlock());
74-
toBlockSrc = JsonRpcApiUtil.getByJsonBlockId(fr.getToBlock());
73+
fromBlockSrc = JsonRpcApiUtil.getByJsonBlockId(fr.getFromBlock(), wallet);
74+
toBlockSrc = JsonRpcApiUtil.getByJsonBlockId(fr.getToBlock(), wallet);
7575
if (fromBlockSrc == -1 && toBlockSrc == -1) {
7676
fromBlockSrc = currentMaxBlockNum;
7777
toBlockSrc = Long.MAX_VALUE;

framework/src/test/java/org/tron/core/WalletTest.java

+17-6
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public class WalletTest extends BaseTest {
142142
private static boolean init;
143143

144144
static {
145-
Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF);
145+
Args.setParam(new String[] {"-d", dbPath()}, Constant.TEST_CONF);
146146
OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc";
147147
RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150";
148148
}
@@ -155,7 +155,8 @@ public void before() {
155155
}
156156
initTransaction();
157157
initBlock();
158-
chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(5);
158+
chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(BLOCK_NUM_FIVE);
159+
chainBaseManager.getDynamicPropertiesStore().saveLatestSolidifiedBlockNum(BLOCK_NUM_TWO);
159160
chainBaseManager.getDelegatedResourceStore().reset();
160161
init = true;
161162
}
@@ -169,6 +170,7 @@ private void initTransaction() {
169170
TRANSACTION_TIMESTAMP_ONE, BLOCK_NUM_ONE);
170171
addTransactionToStore(transaction1);
171172

173+
// solidified
172174
transaction2 = getBuildTransaction(
173175
getBuildTransferContract(ACCOUNT_ADDRESS_TWO, ACCOUNT_ADDRESS_THREE),
174176
TRANSACTION_TIMESTAMP_TWO, BLOCK_NUM_TWO);
@@ -287,6 +289,7 @@ private void initBlock() {
287289

288290
private void addBlockToStore(Block block) {
289291
BlockCapsule blockCapsule = new BlockCapsule(block);
292+
chainBaseManager.getBlockIndexStore().put(blockCapsule.getBlockId());
290293
chainBaseManager.getBlockStore().put(blockCapsule.getBlockId().getBytes(), blockCapsule);
291294
}
292295

@@ -1245,19 +1248,19 @@ public void testListNodes() {
12451248
* delegate_balance = 1000_000L; => 277
12461249
* delegate_balance = 1000_000_000L; => 279
12471250
* delegate_balance = 1000_000_000_000L => 280
1248-
*
1251+
* <p>
12491252
* We initialize account information as follows
12501253
* account balance = 1000_000_000_000L
12511254
* account frozen_balance = 1000_000_000L
1252-
*
1255+
* <p>
12531256
* then estimateConsumeBandWidthSize cost 279
1254-
*
1257+
* <p>
12551258
* so we have following result:
12561259
* TransactionUtil.estimateConsumeBandWidthSize(
12571260
* dynamicStore,ownerCapsule.getBalance()) ===> false
12581261
* TransactionUtil.estimateConsumeBandWidthSize(
12591262
* dynamicStore,ownerCapsule.getFrozenV2BalanceForBandwidth()) ===> true
1260-
*
1263+
* <p>
12611264
* This test case is used to verify the above conclusions
12621265
*/
12631266
@Test
@@ -1282,5 +1285,13 @@ public void testGetCanDelegatedMaxSizeBandWidth123() {
12821285
chainBaseManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(DELEGATE_PERIOD / 3000);
12831286
}
12841287

1288+
@Test
1289+
public void testGetSolidBlock() {
1290+
long blkNum = wallet.getSolidBlockNum();
1291+
Assert.assertEquals(BLOCK_NUM_TWO, blkNum);
1292+
1293+
Block block = wallet.getSolidBlock();
1294+
assertEquals(block2, block);
1295+
}
12851296
}
12861297

framework/src/test/java/org/tron/core/jsonrpc/JsonRpcTest.java

+1-103
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ public void testLogFilter() {
190190
} catch (JsonRpcInvalidParamsException e) {
191191
Assert.fail();
192192
}
193+
193194
try {
194195
new LogFilter(new FilterRequest(null, null, null, new String[] {"0x0"}, null));
195196
} catch (JsonRpcInvalidParamsException e) {
@@ -240,109 +241,6 @@ public void testLogFilter() {
240241
}
241242
}
242243

243-
/**
244-
* test fromBlock and toBlock parameters
245-
*/
246-
@Test
247-
public void testLogFilterWrapper() {
248-
249-
// fromBlock and toBlock are both empty
250-
try {
251-
LogFilterWrapper logFilterWrapper =
252-
new LogFilterWrapper(new FilterRequest(null, null, null, null, null), 100, null);
253-
Assert.assertEquals(logFilterWrapper.getFromBlock(), 100);
254-
Assert.assertEquals(logFilterWrapper.getToBlock(), Long.MAX_VALUE);
255-
} catch (JsonRpcInvalidParamsException e) {
256-
Assert.fail();
257-
}
258-
259-
// fromBlock is not empty and smaller than currentMaxBlockNum, toBlock is empty
260-
try {
261-
LogFilterWrapper logFilterWrapper =
262-
new LogFilterWrapper(new FilterRequest("0x14", null, null, null, null), 100, null);
263-
Assert.assertEquals(logFilterWrapper.getFromBlock(), 20);
264-
Assert.assertEquals(logFilterWrapper.getToBlock(), Long.MAX_VALUE);
265-
} catch (JsonRpcInvalidParamsException e) {
266-
Assert.fail();
267-
}
268-
269-
// fromBlock is not empty and bigger than currentMaxBlockNum, toBlock is empty
270-
try {
271-
LogFilterWrapper logFilterWrapper =
272-
new LogFilterWrapper(new FilterRequest("0x78", null, null, null, null), 100, null);
273-
Assert.assertEquals(logFilterWrapper.getFromBlock(), 120);
274-
Assert.assertEquals(logFilterWrapper.getToBlock(), Long.MAX_VALUE);
275-
} catch (JsonRpcInvalidParamsException e) {
276-
Assert.fail();
277-
}
278-
279-
// fromBlock is empty, toBlock is not empty and smaller than currentMaxBlockNum
280-
try {
281-
LogFilterWrapper logFilterWrapper =
282-
new LogFilterWrapper(new FilterRequest(null, "0x14", null, null, null), 100, null);
283-
Assert.assertEquals(logFilterWrapper.getFromBlock(), 20);
284-
Assert.assertEquals(logFilterWrapper.getToBlock(), 20);
285-
} catch (JsonRpcInvalidParamsException e) {
286-
Assert.fail();
287-
}
288-
289-
// fromBlock is empty, toBlock is not empty and bigger than currentMaxBlockNum
290-
try {
291-
LogFilterWrapper logFilterWrapper =
292-
new LogFilterWrapper(new FilterRequest(null, "0x78", null, null, null), 100, null);
293-
Assert.assertEquals(logFilterWrapper.getFromBlock(), 100);
294-
Assert.assertEquals(logFilterWrapper.getToBlock(), 120);
295-
} catch (JsonRpcInvalidParamsException e) {
296-
Assert.fail();
297-
}
298-
299-
// fromBlock is not empty, toBlock is not empty
300-
try {
301-
LogFilterWrapper logFilterWrapper =
302-
new LogFilterWrapper(new FilterRequest("0x14", "0x78", null, null, null), 100, null);
303-
Assert.assertEquals(logFilterWrapper.getFromBlock(), 20);
304-
Assert.assertEquals(logFilterWrapper.getToBlock(), 120);
305-
} catch (JsonRpcInvalidParamsException e) {
306-
Assert.fail();
307-
}
308-
try {
309-
LogFilterWrapper logFilterWrapper =
310-
new LogFilterWrapper(new FilterRequest("0x78", "0x14", null, null, null), 100, null);
311-
} catch (JsonRpcInvalidParamsException e) {
312-
Assert.assertEquals("please verify: fromBlock <= toBlock", e.getMessage());
313-
}
314-
315-
//fromBlock or toBlock is not hex num
316-
try {
317-
LogFilterWrapper logFilterWrapper =
318-
new LogFilterWrapper(new FilterRequest("earliest", null, null, null, null), 100, null);
319-
Assert.assertEquals(logFilterWrapper.getFromBlock(), 0);
320-
Assert.assertEquals(logFilterWrapper.getToBlock(), Long.MAX_VALUE);
321-
} catch (JsonRpcInvalidParamsException e) {
322-
Assert.fail();
323-
}
324-
try {
325-
LogFilterWrapper logFilterWrapper =
326-
new LogFilterWrapper(new FilterRequest("latest", null, null, null, null), 100, null);
327-
Assert.assertEquals(logFilterWrapper.getFromBlock(), 100);
328-
Assert.assertEquals(logFilterWrapper.getToBlock(), Long.MAX_VALUE);
329-
} catch (JsonRpcInvalidParamsException e) {
330-
Assert.fail();
331-
}
332-
try {
333-
LogFilterWrapper logFilterWrapper =
334-
new LogFilterWrapper(new FilterRequest("pending", null, null, null, null), 100, null);
335-
} catch (JsonRpcInvalidParamsException e) {
336-
Assert.assertEquals("TAG pending not supported", e.getMessage());
337-
}
338-
try {
339-
LogFilterWrapper logFilterWrapper =
340-
new LogFilterWrapper(new FilterRequest("test", null, null, null, null), 100, null);
341-
} catch (JsonRpcInvalidParamsException e) {
342-
Assert.assertEquals("Incorrect hex syntax", e.getMessage());
343-
}
344-
}
345-
346244
private int[] getBloomIndex(String s) {
347245
Bloom bloom = Bloom.create(Hash.sha3(ByteArray.fromHexString(s)));
348246
BitSet bs = BitSet.valueOf(bloom.getData());

0 commit comments

Comments
 (0)