diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 39e8f06c281..2e759b2a30d 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -49,7 +49,6 @@ import com.google.common.collect.Range; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.ProtocolStringList; import java.math.BigInteger; import java.security.SignatureException; import java.util.ArrayList; @@ -163,7 +162,6 @@ import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.TransactionInfoCapsule; import org.tron.core.capsule.TransactionResultCapsule; -import org.tron.core.capsule.TransactionRetCapsule; import org.tron.core.capsule.VotesCapsule; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.capsule.utils.MarketUtils; @@ -780,7 +778,7 @@ public WitnessList getPaginatedNowWitnessList(long offset, long limit) throws if (limit > WITNESS_COUNT_LIMIT_MAX) { limit = WITNESS_COUNT_LIMIT_MAX; } - + /* In the maintenance period, the VoteStores will be cleared. To avoid the race condition of VoteStores deleted but Witness vote counts not updated, @@ -1502,8 +1500,8 @@ public Protocol.ChainParameters getChainParameters() { builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder() .setKey("getAllowTvmSelfdestructRestriction") .setValue(dbManager.getDynamicPropertiesStore().getAllowTvmSelfdestructRestriction()) - .build()); - + .build()); + builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder() .setKey("getProposalExpireTime") .setValue(dbManager.getDynamicPropertiesStore().getProposalExpireTime()) @@ -3852,8 +3850,8 @@ public ShieldedTRC20Parameters createShieldedContractParametersWithoutAsk( return builder.build(false); } - private int getShieldedTRC20LogType(TransactionInfo.Log log, byte[] contractAddress, - ProtocolStringList topicsList) throws ZksnarkException { + private int getShieldedTRC20LogType(TransactionInfo.Log log, byte[] contractAddress) + throws ZksnarkException { byte[] logAddress = log.getAddress().toByteArray(); byte[] addressWithoutPrefix = new byte[20]; if (ArrayUtils.isEmpty(contractAddress) || contractAddress.length != 21) { @@ -3866,33 +3864,14 @@ private int getShieldedTRC20LogType(TransactionInfo.Log log, byte[] contractAddr for (ByteString bs : logTopicsList) { topicsBytes = ByteUtil.merge(topicsBytes, bs.toByteArray()); } - if (Objects.isNull(topicsList) || topicsList.isEmpty()) { - if (Arrays.equals(topicsBytes, SHIELDED_TRC20_LOG_TOPICS_MINT)) { - return 1; - } else if (Arrays.equals(topicsBytes, SHIELDED_TRC20_LOG_TOPICS_TRANSFER)) { - return 2; - } else if (Arrays.equals(topicsBytes, SHIELDED_TRC20_LOG_TOPICS_BURN_LEAF)) { - return 3; - } else if (Arrays.equals(topicsBytes, SHIELDED_TRC20_LOG_TOPICS_BURN_TOKEN)) { - return 4; - } - } else { - for (String topic : topicsList) { - byte[] topicHash = Hash.sha3(ByteArray.fromString(topic)); - if (Arrays.equals(topicsBytes, topicHash)) { - if (topic.toLowerCase().contains("mint")) { - return 1; - } else if (topic.toLowerCase().contains("transfer")) { - return 2; - } else if (topic.toLowerCase().contains("burn")) { - if (topic.toLowerCase().contains("leaf")) { - return 3; - } else if (topic.toLowerCase().contains("token")) { - return 4; - } - } - } - } + if (Arrays.equals(topicsBytes, SHIELDED_TRC20_LOG_TOPICS_MINT)) { + return 1; + } else if (Arrays.equals(topicsBytes, SHIELDED_TRC20_LOG_TOPICS_TRANSFER)) { + return 2; + } else if (Arrays.equals(topicsBytes, SHIELDED_TRC20_LOG_TOPICS_BURN_LEAF)) { + return 3; + } else if (Arrays.equals(topicsBytes, SHIELDED_TRC20_LOG_TOPICS_BURN_TOKEN)) { + return 4; } } return 0; @@ -3942,8 +3921,7 @@ private Optional getNoteTxFromLogListByIvk( } private DecryptNotesTRC20 queryTRC20NoteByIvk(long startNum, long endNum, - byte[] shieldedTRC20ContractAddress, byte[] ivk, byte[] ak, byte[] nk, - ProtocolStringList topicsList) + byte[] shieldedTRC20ContractAddress, byte[] ivk, byte[] ak, byte[] nk) throws BadItemException, ZksnarkException, ContractExeException { if (!(startNum >= 0 && endNum > startNum && endNum - startNum <= 1000)) { throw new BadItemException( @@ -3964,7 +3942,7 @@ private DecryptNotesTRC20 queryTRC20NoteByIvk(long startNum, long endNum, Optional noteTx; int index = 0; for (TransactionInfo.Log log : logList) { - int logType = getShieldedTRC20LogType(log, shieldedTRC20ContractAddress, topicsList); + int logType = getShieldedTRC20LogType(log, shieldedTRC20ContractAddress); if (logType > 0) { noteBuilder = DecryptNotesTRC20.NoteTx.newBuilder(); noteBuilder.setTxid(ByteString.copyFrom(txId)); @@ -4048,12 +4026,11 @@ private boolean isShieldedTRC20NoteSpent(GrpcAPI.Note note, long pos, byte[] ak, public DecryptNotesTRC20 scanShieldedTRC20NotesByIvk( long startNum, long endNum, byte[] shieldedTRC20ContractAddress, - byte[] ivk, byte[] ak, byte[] nk, ProtocolStringList topicsList) + byte[] ivk, byte[] ak, byte[] nk) throws BadItemException, ZksnarkException, ContractExeException { checkAllowShieldedTransactionApi(); - return queryTRC20NoteByIvk(startNum, endNum, - shieldedTRC20ContractAddress, ivk, ak, nk, topicsList); + return queryTRC20NoteByIvk(startNum, endNum, shieldedTRC20ContractAddress, ivk, ak, nk); } private Optional getNoteTxFromLogListByOvk( @@ -4127,7 +4104,7 @@ private Optional getNoteTxFromLogListByOvk( } public DecryptNotesTRC20 scanShieldedTRC20NotesByOvk(long startNum, long endNum, - byte[] ovk, byte[] shieldedTRC20ContractAddress, ProtocolStringList topicsList) + byte[] ovk, byte[] shieldedTRC20ContractAddress) throws ZksnarkException, BadItemException { checkAllowShieldedTransactionApi(); @@ -4149,7 +4126,7 @@ public DecryptNotesTRC20 scanShieldedTRC20NotesByOvk(long startNum, long endNum, Optional noteTx; int index = 0; for (TransactionInfo.Log log : logList) { - int logType = getShieldedTRC20LogType(log, shieldedTRC20ContractAddress, topicsList); + int logType = getShieldedTRC20LogType(log, shieldedTRC20ContractAddress); if (logType > 0) { noteBuilder = DecryptNotesTRC20.NoteTx.newBuilder(); noteBuilder.setTxid(ByteString.copyFrom(txid)); diff --git a/framework/src/main/java/org/tron/core/services/RpcApiService.java b/framework/src/main/java/org/tron/core/services/RpcApiService.java index 63e7ba03fc7..26b07bf1e83 100755 --- a/framework/src/main/java/org/tron/core/services/RpcApiService.java +++ b/framework/src/main/java/org/tron/core/services/RpcApiService.java @@ -95,6 +95,7 @@ import org.tron.core.exception.VMIllegalException; import org.tron.core.exception.ZksnarkException; import org.tron.core.metrics.MetricsApiService; +import org.tron.core.services.http.Util; import org.tron.core.utils.TransactionUtil; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.IncomingViewingKey; @@ -292,6 +293,18 @@ private StatusRuntimeException getRunTimeException(Exception e) { } } + private static boolean rejectIfEventsPresent( + StreamObserver responseObserver, ProtocolStringList events) { + if (Util.hasMeaningfulEvents(events)) { + logger.info(Util.EVENTS_DEPRECATED_MSG); + responseObserver.onError(Status.INVALID_ARGUMENT + .withDescription(Util.EVENTS_DEPRECATED_MSG) + .asRuntimeException()); + return true; + } + return false; + } + /** * DatabaseApi. */ @@ -722,18 +735,19 @@ public void isSpend(NoteParameters request, StreamObserver response @Override public void scanShieldedTRC20NotesByIvk(IvkDecryptTRC20Parameters request, StreamObserver responseObserver) { + if (rejectIfEventsPresent(responseObserver, request.getEventsList())) { + return; + } long startNum = request.getStartBlockIndex(); long endNum = request.getEndBlockIndex(); byte[] contractAddress = request.getShieldedTRC20ContractAddress().toByteArray(); byte[] ivk = request.getIvk().toByteArray(); byte[] ak = request.getAk().toByteArray(); byte[] nk = request.getNk().toByteArray(); - ProtocolStringList topicsList = request.getEventsList(); try { responseObserver.onNext( - wallet.scanShieldedTRC20NotesByIvk(startNum, endNum, contractAddress, ivk, ak, nk, - topicsList)); + wallet.scanShieldedTRC20NotesByIvk(startNum, endNum, contractAddress, ivk, ak, nk)); } catch (Exception e) { responseObserver.onError(getRunTimeException(e)); @@ -744,15 +758,16 @@ public void scanShieldedTRC20NotesByIvk(IvkDecryptTRC20Parameters request, @Override public void scanShieldedTRC20NotesByOvk(OvkDecryptTRC20Parameters request, StreamObserver responseObserver) { + if (rejectIfEventsPresent(responseObserver, request.getEventsList())) { + return; + } long startNum = request.getStartBlockIndex(); long endNum = request.getEndBlockIndex(); byte[] contractAddress = request.getShieldedTRC20ContractAddress().toByteArray(); byte[] ovk = request.getOvk().toByteArray(); - ProtocolStringList topicList = request.getEventsList(); try { responseObserver - .onNext(wallet - .scanShieldedTRC20NotesByOvk(startNum, endNum, ovk, contractAddress, topicList)); + .onNext(wallet.scanShieldedTRC20NotesByOvk(startNum, endNum, ovk, contractAddress)); } catch (Exception e) { responseObserver.onError(getRunTimeException(e)); } @@ -2412,6 +2427,9 @@ public void createShieldedContractParametersWithoutAsk( public void scanShieldedTRC20NotesByIvk( IvkDecryptTRC20Parameters request, StreamObserver responseObserver) { + if (rejectIfEventsPresent(responseObserver, request.getEventsList())) { + return; + } long startNum = request.getStartBlockIndex(); long endNum = request.getEndBlockIndex(); try { @@ -2419,8 +2437,7 @@ public void scanShieldedTRC20NotesByIvk( request.getShieldedTRC20ContractAddress().toByteArray(), request.getIvk().toByteArray(), request.getAk().toByteArray(), - request.getNk().toByteArray(), - request.getEventsList()); + request.getNk().toByteArray()); responseObserver.onNext(decryptNotes); } catch (BadItemException | ZksnarkException e) { responseObserver.onError(getRunTimeException(e)); @@ -2438,13 +2455,15 @@ public void scanShieldedTRC20NotesByIvk( public void scanShieldedTRC20NotesByOvk( OvkDecryptTRC20Parameters request, StreamObserver responseObserver) { + if (rejectIfEventsPresent(responseObserver, request.getEventsList())) { + return; + } long startNum = request.getStartBlockIndex(); long endNum = request.getEndBlockIndex(); try { DecryptNotesTRC20 decryptNotes = wallet.scanShieldedTRC20NotesByOvk(startNum, endNum, request.getOvk().toByteArray(), - request.getShieldedTRC20ContractAddress().toByteArray(), - request.getEventsList()); + request.getShieldedTRC20ContractAddress().toByteArray()); responseObserver.onNext(decryptNotes); } catch (Exception e) { responseObserver.onError(getRunTimeException(e)); diff --git a/framework/src/main/java/org/tron/core/services/http/ScanShieldedTRC20NotesByIvkServlet.java b/framework/src/main/java/org/tron/core/services/http/ScanShieldedTRC20NotesByIvkServlet.java index 2b52883f490..49e3246baaa 100644 --- a/framework/src/main/java/org/tron/core/services/http/ScanShieldedTRC20NotesByIvkServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/ScanShieldedTRC20NotesByIvkServlet.java @@ -2,7 +2,6 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -41,15 +40,20 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) IvkDecryptTRC20Parameters.Builder ivkDecryptTRC20Parameters = IvkDecryptTRC20Parameters .newBuilder(); JsonFormat.merge(params.getParams(), ivkDecryptTRC20Parameters, params.isVisible()); - + try { + Util.rejectIfEventsPresent(ivkDecryptTRC20Parameters.getEventsList()); + } catch (IllegalArgumentException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + Util.processError(e, response); + return; + } GrpcAPI.DecryptNotesTRC20 notes = wallet .scanShieldedTRC20NotesByIvk(ivkDecryptTRC20Parameters.getStartBlockIndex(), ivkDecryptTRC20Parameters.getEndBlockIndex(), ivkDecryptTRC20Parameters.getShieldedTRC20ContractAddress().toByteArray(), ivkDecryptTRC20Parameters.getIvk().toByteArray(), ivkDecryptTRC20Parameters.getAk().toByteArray(), - ivkDecryptTRC20Parameters.getNk().toByteArray(), - ivkDecryptTRC20Parameters.getEventsList()); + ivkDecryptTRC20Parameters.getNk().toByteArray()); response.getWriter().println(convertOutput(notes, params.isVisible())); } catch (Exception e) { Util.processError(e, response); @@ -57,6 +61,13 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) } protected void doGet(HttpServletRequest request, HttpServletResponse response) { + try { + Util.rejectIfEventsPresent(request.getParameterValues("events")); + } catch (IllegalArgumentException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + Util.processError(e, response); + return; + } try { boolean visible = Util.getVisible(request); long startNum = Long.parseLong(request.getParameter("start_block_index")); @@ -74,7 +85,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) { GrpcAPI.DecryptNotesTRC20 notes = wallet .scanShieldedTRC20NotesByIvk(startNum, endNum, ByteArray.fromHexString(contractAddress), ByteArray.fromHexString(ivk), - ByteArray.fromHexString(ak), ByteArray.fromHexString(nk), null); + ByteArray.fromHexString(ak), ByteArray.fromHexString(nk)); response.getWriter().println(convertOutput(notes, visible)); } catch (Exception e) { Util.processError(e, response); diff --git a/framework/src/main/java/org/tron/core/services/http/ScanShieldedTRC20NotesByOvkServlet.java b/framework/src/main/java/org/tron/core/services/http/ScanShieldedTRC20NotesByOvkServlet.java index b5fbbab1625..33893347d8f 100644 --- a/framework/src/main/java/org/tron/core/services/http/ScanShieldedTRC20NotesByOvkServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/ScanShieldedTRC20NotesByOvkServlet.java @@ -1,6 +1,5 @@ package org.tron.core.services.http; -import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -24,14 +23,18 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) OvkDecryptTRC20Parameters.Builder ovkDecryptTRC20Parameters = OvkDecryptTRC20Parameters .newBuilder(); JsonFormat.merge(params.getParams(), ovkDecryptTRC20Parameters, params.isVisible()); - + try { + Util.rejectIfEventsPresent(ovkDecryptTRC20Parameters.getEventsList()); + } catch (IllegalArgumentException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + Util.processError(e, response); + return; + } GrpcAPI.DecryptNotesTRC20 notes = wallet .scanShieldedTRC20NotesByOvk(ovkDecryptTRC20Parameters.getStartBlockIndex(), ovkDecryptTRC20Parameters.getEndBlockIndex(), ovkDecryptTRC20Parameters.getOvk().toByteArray(), - ovkDecryptTRC20Parameters.getShieldedTRC20ContractAddress().toByteArray(), - ovkDecryptTRC20Parameters.getEventsList() - ); + ovkDecryptTRC20Parameters.getShieldedTRC20ContractAddress().toByteArray()); response.getWriter() .println(ScanShieldedTRC20NotesByIvkServlet.convertOutput(notes, params.isVisible())); } catch (Exception e) { @@ -40,6 +43,13 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) } protected void doGet(HttpServletRequest request, HttpServletResponse response) { + try { + Util.rejectIfEventsPresent(request.getParameterValues("events")); + } catch (IllegalArgumentException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + Util.processError(e, response); + return; + } try { boolean visible = Util.getVisible(request); long startBlockIndex = Long.parseLong(request.getParameter("start_block_index")); @@ -51,7 +61,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) { } GrpcAPI.DecryptNotesTRC20 notes = wallet .scanShieldedTRC20NotesByOvk(startBlockIndex, endBlockIndex, - ByteArray.fromHexString(ovk), ByteArray.fromHexString(contractAddress), null); + ByteArray.fromHexString(ovk), ByteArray.fromHexString(contractAddress)); response.getWriter() .println(ScanShieldedTRC20NotesByIvkServlet.convertOutput(notes, visible)); diff --git a/framework/src/main/java/org/tron/core/services/http/Util.java b/framework/src/main/java/org/tron/core/services/http/Util.java index 2b6b929d8a0..f763ce89d6e 100644 --- a/framework/src/main/java/org/tron/core/services/http/Util.java +++ b/framework/src/main/java/org/tron/core/services/http/Util.java @@ -12,6 +12,7 @@ import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; +import com.google.protobuf.ProtocolStringList; import java.io.BufferedReader; import java.io.IOException; @@ -64,6 +65,9 @@ @Slf4j(topic = "API") public class Util { + public static final String EVENTS_DEPRECATED_MSG = + "'events' field is deprecated and no longer supported"; + public static final String PERMISSION_ID = "Permission_id"; public static final String VISIBLE = "visible"; public static final String TRANSACTION = "transaction"; @@ -80,6 +84,28 @@ public class Util { public static final String FUNCTION_PARAMETER = "parameter"; public static final String CALL_DATA = "data"; + public static boolean hasMeaningfulEvents(ProtocolStringList events) { + return events.stream().anyMatch(s -> !s.isEmpty()); + } + + public static void rejectIfEventsPresent(ProtocolStringList events) { + if (hasMeaningfulEvents(events)) { + logger.info(EVENTS_DEPRECATED_MSG); + throw new IllegalArgumentException(EVENTS_DEPRECATED_MSG); + } + } + + public static void rejectIfEventsPresent(String[] eventsParams) { + if (eventsParams != null) { + for (String v : eventsParams) { + if (v != null && !v.isEmpty()) { + logger.info(EVENTS_DEPRECATED_MSG); + throw new IllegalArgumentException(EVENTS_DEPRECATED_MSG); + } + } + } + } + public static String printTransactionFee(String transactionFee) { JSONObject jsonObject = new JSONObject(); JSONObject receipt = JSONObject.parseObject(transactionFee); diff --git a/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java b/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java index c2c4bfe3006..e570fcdfe1a 100644 --- a/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java +++ b/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java @@ -2243,7 +2243,7 @@ public void testScanShieldedTRC20NotesByIvk() throws Exception { byte[] ivk = fvk.inViewingKey().value; GrpcAPI.DecryptNotesTRC20 scannedNotes = wallet.scanShieldedTRC20NotesByIvk( - statNum, endNum, SHIELDED_CONTRACT_ADDRESS, ivk, fvk.getAk(), fvk.getNk(), null); + statNum, endNum, SHIELDED_CONTRACT_ADDRESS, ivk, fvk.getAk(), fvk.getNk()); for (GrpcAPI.DecryptNotesTRC20.NoteTx noteTx : scannedNotes.getNoteTxsList()) { logger.info(noteTx.toString()); @@ -2258,7 +2258,7 @@ public void testscanShieldedTRC20NotesByOvk() throws Exception { FullViewingKey fvk = sk.fullViewingKey(); GrpcAPI.DecryptNotesTRC20 scannedNotes = wallet.scanShieldedTRC20NotesByOvk( - statNum, endNum, fvk.getOvk(), SHIELDED_CONTRACT_ADDRESS, null); + statNum, endNum, fvk.getOvk(), SHIELDED_CONTRACT_ADDRESS); for (GrpcAPI.DecryptNotesTRC20.NoteTx noteTx : scannedNotes.getNoteTxsList()) { logger.info(noteTx.toString()); @@ -2274,7 +2274,7 @@ public void isShieldedTRC20ContractNoteSpent() throws Exception { byte[] ivk = fvk.inViewingKey().value; GrpcAPI.DecryptNotesTRC20 scannedNotes = wallet.scanShieldedTRC20NotesByIvk( - statNum, endNum, SHIELDED_CONTRACT_ADDRESS, ivk, fvk.getAk(), fvk.getNk(), null); + statNum, endNum, SHIELDED_CONTRACT_ADDRESS, ivk, fvk.getAk(), fvk.getNk()); for (GrpcAPI.DecryptNotesTRC20.NoteTx noteTx : scannedNotes.getNoteTxsList()) { logger.info(noteTx.toString()); diff --git a/framework/src/test/java/org/tron/core/WalletMockTest.java b/framework/src/test/java/org/tron/core/WalletMockTest.java index efcf0da8d0d..3e0c1a4461d 100644 --- a/framework/src/test/java/org/tron/core/WalletMockTest.java +++ b/framework/src/test/java/org/tron/core/WalletMockTest.java @@ -17,9 +17,6 @@ import com.google.common.cache.CacheBuilder; import com.google.protobuf.Any; import com.google.protobuf.ByteString; -import com.google.protobuf.LazyStringArrayList; -import com.google.protobuf.ProtocolStringList; - import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -36,7 +33,9 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; import org.tron.api.GrpcAPI; +import org.tron.common.crypto.Hash; import org.tron.common.parameter.CommonParameter; +import org.tron.common.utils.ByteArray; import org.tron.common.utils.ByteUtil; import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.client.WalletClient; @@ -1058,19 +1057,16 @@ public void testGetShieldedTRC20LogType() { Wallet wallet = new Wallet(); Protocol.TransactionInfo.Log log = Protocol.TransactionInfo.Log.newBuilder().build(); byte[] contractAddress = "contractAddress".getBytes(StandardCharsets.UTF_8); - LazyStringArrayList topicsList = new LazyStringArrayList(); Throwable thrown = assertThrows(InvocationTargetException.class, () -> { Method privateMethod = Wallet.class.getDeclaredMethod( "getShieldedTRC20LogType", Protocol.TransactionInfo.Log.class, - byte[].class, - ProtocolStringList.class); + byte[].class); privateMethod.setAccessible(true); privateMethod.invoke(wallet, log, - contractAddress, - topicsList); + contractAddress); }); Throwable cause = thrown.getCause(); assertTrue(cause instanceof ZksnarkException); @@ -1088,18 +1084,14 @@ public void testGetShieldedTRC20LogType1() { .setAddress(ByteString.copyFrom(addressWithoutPrefix)) .build(); - LazyStringArrayList topicsList = new LazyStringArrayList(); try { Method privateMethod = Wallet.class.getDeclaredMethod( "getShieldedTRC20LogType", Protocol.TransactionInfo.Log.class, - byte[].class, - ProtocolStringList.class); + byte[].class); privateMethod.setAccessible(true); - privateMethod.invoke(wallet, - log, - contractAddress, - topicsList); + Object result = privateMethod.invoke(wallet, log, contractAddress); + assertEquals(0, ((Integer) result).intValue()); } catch (Exception e) { assertTrue(false); } @@ -1119,24 +1111,53 @@ public void testGetShieldedTRC20LogType2() { .addTopics(ByteString.copyFrom("topic".getBytes())) .build(); - LazyStringArrayList topicsList = new LazyStringArrayList(); - topicsList.add("topic"); try { Method privateMethod = Wallet.class.getDeclaredMethod( "getShieldedTRC20LogType", Protocol.TransactionInfo.Log.class, - byte[].class, - ProtocolStringList.class); + byte[].class); privateMethod.setAccessible(true); - privateMethod.invoke(wallet, - log, - contractAddress, - topicsList); + Object result = privateMethod.invoke(wallet, log, contractAddress); + assertEquals(0, ((Integer) result).intValue()); } catch (Exception e) { assertTrue(false); } } + @Test + public void testGetShieldedTRC20LogTypeReturnsCorrectInt() throws Exception { + Wallet wallet = new Wallet(); + final String SHIELDED_CONTRACT_ADDRESS_STR = "TGAmX5AqVUoXCf8MoHxbuhQPmhGfWTnEgA"; + byte[] contractAddress = WalletClient.decodeFromBase58Check(SHIELDED_CONTRACT_ADDRESS_STR); + byte[] addressWithoutPrefix = new byte[20]; + System.arraycopy(contractAddress, 1, addressWithoutPrefix, 0, 20); + + Method privateMethod = Wallet.class.getDeclaredMethod( + "getShieldedTRC20LogType", + Protocol.TransactionInfo.Log.class, + byte[].class); + privateMethod.setAccessible(true); + + String[] eventSignatures = { + "MintNewLeaf(uint256,bytes32,bytes32,bytes32,bytes32[21])", + "TransferNewLeaf(uint256,bytes32,bytes32,bytes32,bytes32[21])", + "BurnNewLeaf(uint256,bytes32,bytes32,bytes32,bytes32[21])", + "TokenBurn(address,uint256,bytes32[3])" + }; + int[] expectedTypes = {1, 2, 3, 4}; + + for (int i = 0; i < eventSignatures.length; i++) { + byte[] topicHash = Hash.sha3(ByteArray.fromString(eventSignatures[i])); + Protocol.TransactionInfo.Log log = Protocol.TransactionInfo.Log.newBuilder() + .setAddress(ByteString.copyFrom(addressWithoutPrefix)) + .addTopics(ByteString.copyFrom(topicHash)) + .build(); + Object result = privateMethod.invoke(wallet, log, contractAddress); + assertEquals("event " + eventSignatures[i] + " should map to log type " + + expectedTypes[i], expectedTypes[i], ((Integer) result).intValue()); + } + } + @Test public void testBuildShieldedTRC20InputWithAK() throws ZksnarkException { Wallet wallet = new Wallet(); diff --git a/framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java b/framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java index f40ec48e035..ab622fa63b0 100644 --- a/framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java +++ b/framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java @@ -1,6 +1,7 @@ package org.tron.core.services; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.tron.common.parameter.CommonParameter.getInstance; import static org.tron.common.utils.client.WalletClient.decodeFromBase58Check; import static org.tron.protos.Protocol.Transaction.Contract.ContractType.TransferContract; @@ -9,6 +10,8 @@ import com.google.protobuf.ByteString; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; +import io.grpc.Status; +import io.grpc.StatusRuntimeException; import java.io.IOException; import java.util.Objects; import java.util.concurrent.ExecutorService; @@ -556,6 +559,92 @@ public void testScanShieldedTRC20NotesByOvk() { assertNotNull(blockingStubPBFT.scanShieldedTRC20NotesByOvk(message)); } + @Test + public void testScanShieldedTRC20NotesByIvkRejectsDeprecatedEvents() { + IvkDecryptTRC20Parameters message = IvkDecryptTRC20Parameters.newBuilder() + .setStartBlockIndex(1) + .setEndBlockIndex(10) + .addEvents("mint") + .build(); + + StatusRuntimeException fullException = assertThrows(StatusRuntimeException.class, + () -> blockingStubFull.scanShieldedTRC20NotesByIvk(message)); + Assert.assertEquals(Status.Code.INVALID_ARGUMENT, fullException.getStatus().getCode()); + Assert.assertTrue(fullException.getStatus().getDescription() + .contains("'events' field is deprecated and no longer supported")); + + StatusRuntimeException solidityException = assertThrows(StatusRuntimeException.class, + () -> blockingStubSolidity.scanShieldedTRC20NotesByIvk(message)); + Assert.assertEquals(Status.Code.INVALID_ARGUMENT, solidityException.getStatus().getCode()); + Assert.assertTrue(solidityException.getStatus().getDescription() + .contains("'events' field is deprecated and no longer supported")); + + StatusRuntimeException pbftException = assertThrows(StatusRuntimeException.class, + () -> blockingStubPBFT.scanShieldedTRC20NotesByIvk(message)); + Assert.assertEquals(Status.Code.INVALID_ARGUMENT, pbftException.getStatus().getCode()); + Assert.assertTrue(pbftException.getStatus().getDescription() + .contains("'events' field is deprecated and no longer supported")); + } + + @Test + public void testScanShieldedTRC20NotesByOvkRejectsDeprecatedEvents() { + OvkDecryptTRC20Parameters message = OvkDecryptTRC20Parameters.newBuilder() + .setStartBlockIndex(1) + .setEndBlockIndex(10) + .addEvents("burn") + .build(); + + StatusRuntimeException fullException = assertThrows(StatusRuntimeException.class, + () -> blockingStubFull.scanShieldedTRC20NotesByOvk(message)); + Assert.assertEquals(Status.Code.INVALID_ARGUMENT, fullException.getStatus().getCode()); + Assert.assertTrue(fullException.getStatus().getDescription() + .contains("'events' field is deprecated and no longer supported")); + + StatusRuntimeException solidityException = assertThrows(StatusRuntimeException.class, + () -> blockingStubSolidity.scanShieldedTRC20NotesByOvk(message)); + Assert.assertEquals(Status.Code.INVALID_ARGUMENT, solidityException.getStatus().getCode()); + Assert.assertTrue(solidityException.getStatus().getDescription() + .contains("'events' field is deprecated and no longer supported")); + + StatusRuntimeException pbftException = assertThrows(StatusRuntimeException.class, + () -> blockingStubPBFT.scanShieldedTRC20NotesByOvk(message)); + Assert.assertEquals(Status.Code.INVALID_ARGUMENT, pbftException.getStatus().getCode()); + Assert.assertTrue(pbftException.getStatus().getDescription() + .contains("'events' field is deprecated and no longer supported")); + } + + @Test + public void testScanShieldedTRC20NotesByIvkEmptyEventsPassesGuard() { + IvkDecryptTRC20Parameters message = IvkDecryptTRC20Parameters.newBuilder() + .setStartBlockIndex(1) + .setEndBlockIndex(10) + .addEvents("") + .build(); + try { + blockingStubFull.scanShieldedTRC20NotesByIvk(message); + blockingStubSolidity.scanShieldedTRC20NotesByIvk(message); + blockingStubPBFT.scanShieldedTRC20NotesByIvk(message); + } catch (StatusRuntimeException e) { + Assert.fail("empty events should pass the guard, got: " + e.getStatus()); + } + } + + @Test + public void testScanShieldedTRC20NotesByOvkEmptyEventsPassesGuard() { + OvkDecryptTRC20Parameters message = OvkDecryptTRC20Parameters.newBuilder() + .setStartBlockIndex(1) + .setEndBlockIndex(10) + .addEvents("") + .build(); + try { + blockingStubFull.scanShieldedTRC20NotesByOvk(message); + blockingStubSolidity.scanShieldedTRC20NotesByOvk(message); + blockingStubPBFT.scanShieldedTRC20NotesByOvk(message); + } catch (StatusRuntimeException e) { + Assert.fail("empty events should pass the guard, got: " + e.getStatus()); + } + } + // @Test // public void testIsShieldedTRC20ContractNoteSpent() { // NfTRC20Parameters message = NfTRC20Parameters.newBuilder().build(); diff --git a/framework/src/test/java/org/tron/core/services/http/ScanShieldedTRC20NotesServletTest.java b/framework/src/test/java/org/tron/core/services/http/ScanShieldedTRC20NotesServletTest.java new file mode 100644 index 00000000000..c53274897e7 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/ScanShieldedTRC20NotesServletTest.java @@ -0,0 +1,119 @@ +package org.tron.core.services.http; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; +import static org.tron.core.services.http.Util.EVENTS_DEPRECATED_MSG; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.common.TestConstants; +import org.tron.core.config.args.Args; + +public class ScanShieldedTRC20NotesServletTest extends BaseTest { + + @Resource + private ScanShieldedTRC20NotesByIvkServlet scanShieldedTRC20NotesByIvkServlet; + + @Resource + private ScanShieldedTRC20NotesByOvkServlet scanShieldedTRC20NotesByOvkServlet; + + @BeforeClass + public static void init() { + Args.setParam(new String[]{"-d", dbPath()}, TestConstants.TEST_CONF); + } + + @Test + public void testIvkPostRejectsDeprecatedEvents() throws Exception { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + request.setContentType("application/json"); + request.setContent("{\"events\":[\"mint\"]}".getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + scanShieldedTRC20NotesByIvkServlet.doPost(request, response); + Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + Assert.assertTrue(response.getContentAsString().contains(EVENTS_DEPRECATED_MSG)); + } + + @Test + public void testIvkGetRejectsDeprecatedEvents() throws Exception { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + request.addParameter("events", "mint"); + MockHttpServletResponse response = new MockHttpServletResponse(); + scanShieldedTRC20NotesByIvkServlet.doGet(request, response); + Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + Assert.assertTrue(response.getContentAsString().contains(EVENTS_DEPRECATED_MSG)); + } + + @Test + public void testOvkPostRejectsDeprecatedEvents() throws Exception { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + request.setContentType("application/json"); + request.setContent("{\"events\":[\"burn\"]}".getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + scanShieldedTRC20NotesByOvkServlet.doPost(request, response); + Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + Assert.assertTrue(response.getContentAsString().contains(EVENTS_DEPRECATED_MSG)); + } + + @Test + public void testOvkGetRejectsDeprecatedEvents() throws Exception { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + request.addParameter("events", "burn"); + MockHttpServletResponse response = new MockHttpServletResponse(); + scanShieldedTRC20NotesByOvkServlet.doGet(request, response); + Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + Assert.assertTrue(response.getContentAsString().contains(EVENTS_DEPRECATED_MSG)); + } + + @Test + public void testIvkPostEmptyEventsPassesGuard() throws Exception { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + request.setContentType("application/json"); + request.setContent("{\"events\":[\"\"]}".getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + scanShieldedTRC20NotesByIvkServlet.doPost(request, response); + Assert.assertNotEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + Assert.assertFalse(response.getContentAsString().contains(EVENTS_DEPRECATED_MSG)); + } + + @Test + public void testOvkPostEmptyEventsPassesGuard() throws Exception { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + request.setContentType("application/json"); + request.setContent("{\"events\":[\"\"]}".getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + scanShieldedTRC20NotesByOvkServlet.doPost(request, response); + Assert.assertNotEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + Assert.assertFalse(response.getContentAsString().contains(EVENTS_DEPRECATED_MSG)); + } + + @Test + public void testIvkPostWithoutEventsPassesGuard() throws Exception { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + request.setContentType("application/json"); + request.setContent("{\"start_block_index\":0,\"end_block_index\":1}".getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + scanShieldedTRC20NotesByIvkServlet.doPost(request, response); + Assert.assertNotEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + Assert.assertFalse(response.getContentAsString().contains(EVENTS_DEPRECATED_MSG)); + } + + @Test + public void testOvkPostWithoutEventsPassesGuard() throws Exception { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + request.setContentType("application/json"); + request.setContent("{\"start_block_index\":0,\"end_block_index\":1}".getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + scanShieldedTRC20NotesByOvkServlet.doPost(request, response); + Assert.assertNotEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus()); + Assert.assertFalse(response.getContentAsString().contains(EVENTS_DEPRECATED_MSG)); + } + +} diff --git a/protocol/src/main/protos/api/api.proto b/protocol/src/main/protos/api/api.proto index d66d8aa6263..9d5a144f6af 100644 --- a/protocol/src/main/protos/api/api.proto +++ b/protocol/src/main/protos/api/api.proto @@ -1498,7 +1498,7 @@ message IvkDecryptTRC20Parameters { bytes ivk = 4; bytes ak = 5; bytes nk = 6; - repeated string events = 7; + repeated string events = 7 [deprecated = true]; } message OvkDecryptTRC20Parameters { @@ -1506,7 +1506,7 @@ message OvkDecryptTRC20Parameters { int64 end_block_index = 2; bytes ovk = 3; bytes shielded_TRC20_contract_address = 4; - repeated string events = 5; + repeated string events = 5 [deprecated = true]; } message DecryptNotesTRC20 {