diff --git a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java index a389af23044..a1047c4176a 100755 --- a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java @@ -102,6 +102,9 @@ public class TransactionCapsule implements ProtoCapsule { @Getter @Setter private long time; + @Getter + @Setter + private long order; /** * constructor TransactionCapsule. diff --git a/chainbase/src/main/java/org/tron/core/db/TransactionTrace.java b/chainbase/src/main/java/org/tron/core/db/TransactionTrace.java index 984b06c1e76..5a58e331edb 100644 --- a/chainbase/src/main/java/org/tron/core/db/TransactionTrace.java +++ b/chainbase/src/main/java/org/tron/core/db/TransactionTrace.java @@ -181,16 +181,16 @@ public void exec() runtime.execute(transactionContext); setBill(transactionContext.getProgramResult().getEnergyUsed()); - if (TrxType.TRX_PRECOMPILED_TYPE != trxType) { - if (contractResult.OUT_OF_TIME - .equals(receipt.getResult())) { - setTimeResultType(TimeResultType.OUT_OF_TIME); - } else if (System.currentTimeMillis() - txStartTimeInMs - > CommonParameter.getInstance() - .getLongRunningTime()) { - setTimeResultType(TimeResultType.LONG_RUNNING); - } - } +// if (TrxType.TRX_PRECOMPILED_TYPE != trxType) { +// if (contractResult.OUT_OF_TIME +// .equals(receipt.getResult())) { +// setTimeResultType(TimeResultType.OUT_OF_TIME); +// } else if (System.currentTimeMillis() - txStartTimeInMs +// > CommonParameter.getInstance() +// .getLongRunningTime()) { +// setTimeResultType(TimeResultType.LONG_RUNNING); +// } +// } } public void finalization() throws ContractExeException { diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index 5b6203a24dd..532894b678a 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -461,6 +461,13 @@ public class CommonParameter { @Parameter(names = {"--history-balance-lookup"}) public boolean historyBalanceLookup = false; + @Getter + @Setter + public boolean openPrintLog = true; + @Getter + @Setter + public boolean openTransactionSort = false; + private static double calcMaxTimeRatio() { //return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1))); return 5.0; diff --git a/common/src/main/java/org/tron/core/Constant.java b/common/src/main/java/org/tron/core/Constant.java index b7dbd333404..b42d5c0774e 100644 --- a/common/src/main/java/org/tron/core/Constant.java +++ b/common/src/main/java/org/tron/core/Constant.java @@ -273,6 +273,8 @@ public class Constant { public static final String METRICS_REPORT_INTERVAL = "node.metrics.influxdb.metricsReportInterval"; public static final String HISTORY_BALANCE_LOOKUP = "storage.balance.history.lookup"; + public static final String OPEN_PRINT_LOG = "node.openPrintLog"; + public static final String OPEN_TRANSACTION_SORT = "node.openTransactionSort"; public static final String LOCAL_HOST = "127.0.0.1"; } diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 83e9b5d7ccc..9187c519f09 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -185,6 +185,8 @@ public static void clearParam() { PARAMETER.allowTvmStake = 0; PARAMETER.allowTvmAssetIssue = 0; PARAMETER.historyBalanceLookup = false; + PARAMETER.openPrintLog = true; + PARAMETER.openTransactionSort = false; } /** @@ -744,6 +746,11 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.historyBalanceLookup = config.hasPath(Constant.HISTORY_BALANCE_LOOKUP) && config .getBoolean(Constant.HISTORY_BALANCE_LOOKUP); + PARAMETER.openPrintLog = config.hasPath(Constant.OPEN_PRINT_LOG) && config + .getBoolean(Constant.OPEN_PRINT_LOG); + PARAMETER.openTransactionSort = config.hasPath(Constant.OPEN_TRANSACTION_SORT) && config + .getBoolean(Constant.OPEN_TRANSACTION_SORT); + logConfig(); } diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index b233400c85e..ccb8342d722 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -16,9 +16,10 @@ import com.google.protobuf.ByteString; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Objects; @@ -32,9 +33,11 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.LongStream; import javax.annotation.PostConstruct; @@ -205,7 +208,7 @@ public class Manager { @Getter private ChainBaseManager chainBaseManager; // transactions cache - private List pendingTransactions; + private BlockingQueue pendingTransactions; @Getter private AtomicInteger shieldedTransInPendingCounts = new AtomicInteger(0); // transactions popped @@ -224,7 +227,10 @@ public class Manager { TransactionCapsule tx = null; try { tx = getRePushTransactions().peek(); - if (tx != null) { + if (tx != null && System.currentTimeMillis() - tx.getTime() >= Args.getInstance() + .getPendingTransactionTimeout()) { + logger.warn("[timeout] remove tx from rePush, txId:{}", tx.getTransactionId()); + } else if (tx != null) { this.rePush(tx); } else { TimeUnit.MILLISECONDS.sleep(SLEEP_TIME_OUT); @@ -319,7 +325,7 @@ public BlockIndexStore getBlockIndexStore() { return chainBaseManager.getBlockIndexStore(); } - public List getPendingTransactions() { + public BlockingQueue getPendingTransactions() { return this.pendingTransactions; } @@ -339,6 +345,9 @@ public void stopRePushTriggerThread() { isRunTriggerCapsuleProcessThread = false; } + private Comparator downComparator = (Comparator) (o1, o2) -> Long + .compare(o2.getOrder(), o1.getOrder()); + @PostConstruct public void init() { Message.setDynamicPropertiesStore(this.getDynamicPropertiesStore()); @@ -353,8 +362,13 @@ public void init() { this.setMerkleContainer( merkleContainer.createInstance(chainBaseManager.getMerkleTreeStore(), chainBaseManager.getMerkleTreeIndexStore())); - this.pendingTransactions = Collections.synchronizedList(Lists.newArrayList()); - this.rePushTransactions = new LinkedBlockingQueue<>(); + if (Args.getInstance().isOpenTransactionSort()) { + this.pendingTransactions = new PriorityBlockingQueue(2000, downComparator); + this.rePushTransactions = new PriorityBlockingQueue<>(2000, downComparator); + } else { + this.pendingTransactions = new LinkedBlockingQueue<>(); + this.rePushTransactions = new LinkedBlockingQueue<>(); + } this.triggerCapsuleQueue = new LinkedBlockingQueue<>(); chainBaseManager.setMerkleContainer(getMerkleContainer()); chainBaseManager.setMortgageService(mortgageService); @@ -1182,7 +1196,8 @@ public TransactionInfo processTransaction(final TransactionCapsule trxCap, Block trace.getRuntimeResult().getResultCode().name()); chainBaseManager.getBalanceTraceStore().resetCurrentTransactionTrace(); } - + //set the sort order + trxCap.setOrder(transactionInfo.getFee()); return transactionInfo.getInstance(); } @@ -1216,13 +1231,21 @@ public synchronized BlockCapsule generateBlock(Miner miner, long blockTime, long Set accountSet = new HashSet<>(); AtomicInteger shieldedTransCounts = new AtomicInteger(0); - Iterator iterator = pendingTransactions.iterator(); - while (iterator.hasNext() || rePushTransactions.size() > 0) { + while (pendingTransactions.size() > 0 || rePushTransactions.size() > 0) { boolean fromPending = false; TransactionCapsule trx; - if (iterator.hasNext()) { - fromPending = true; - trx = iterator.next(); + if (pendingTransactions.size() > 0) { + trx = pendingTransactions.peek(); + if (Args.getInstance().isOpenTransactionSort()) { + TransactionCapsule trxRepush = rePushTransactions.peek(); + if (trxRepush == null || trx.getOrder() >= trxRepush.getOrder()) { + fromPending = true; + } else { + trx = rePushTransactions.poll(); + } + } else { + fromPending = true; + } } else { trx = rePushTransactions.poll(); } @@ -1268,10 +1291,11 @@ public synchronized BlockCapsule generateBlock(Miner miner, long blockTime, long transactionRetCapsule.addTransactionInfo(result); } if (fromPending) { - iterator.remove(); + pendingTransactions.poll(); } } catch (Exception e) { - logger.error("Process trx failed when generating block: {}", e.getMessage()); + logger.error("Process trx {} failed when generating block: {}", trx.getTransactionId(), + e.getMessage()); } } @@ -1778,4 +1802,42 @@ public Boolean call() throws ValidateSignatureException { return true; } } + + public TransactionCapsule getTxFromPending(String txId) { + AtomicReference transactionCapsule = new AtomicReference<>(); + Sha256Hash txHash = Sha256Hash.wrap(ByteArray.fromHexString(txId)); + pendingTransactions.forEach(tx -> { + if (tx.getTransactionId().equals(txHash)) { + transactionCapsule.set(tx); + return; + } + }); + if (transactionCapsule.get() != null) { + return transactionCapsule.get(); + } + rePushTransactions.forEach(tx -> { + if (tx.getTransactionId().equals(txHash)) { + transactionCapsule.set(tx); + return; + } + }); + return transactionCapsule.get(); + } + + public Collection getTxListFromPending() { + Set result = new HashSet<>(); + pendingTransactions.forEach(tx -> { + result.add(tx.getTransactionId().toString()); + }); + rePushTransactions.forEach(tx -> { + result.add(tx.getTransactionId().toString()); + }); + return result; + } + + public long getPendingSize() { + long value = getPendingTransactions().size() + getRePushTransactions().size() + + getPoppedTransactions().size(); + return value; + } } diff --git a/framework/src/main/java/org/tron/core/db/PendingManager.java b/framework/src/main/java/org/tron/core/db/PendingManager.java index 4098d6b2d70..e7ef3ec077e 100644 --- a/framework/src/main/java/org/tron/core/db/PendingManager.java +++ b/framework/src/main/java/org/tron/core/db/PendingManager.java @@ -1,37 +1,17 @@ package org.tron.core.db; -import java.util.ArrayList; -import java.util.List; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.args.Args; -import org.tron.core.db.TransactionTrace.TimeResultType; -import org.tron.core.metrics.MetricsKey; -import org.tron.core.metrics.MetricsUtil; @Slf4j(topic = "DB") public class PendingManager implements AutoCloseable { - @Getter - private List tmpTransactions = new ArrayList<>(); private Manager dbManager; private long timeout = Args.getInstance().getPendingTransactionTimeout(); public PendingManager(Manager db) { this.dbManager = db; - db.getPendingTransactions().forEach(transactionCapsule -> { - if (System.currentTimeMillis() - transactionCapsule.getTime() < timeout) { - tmpTransactions.add(transactionCapsule); - } - }); - - if (db.getPendingTransactions().size() > tmpTransactions.size()) { - MetricsUtil.meterMark(MetricsKey.BLOCKCHAIN_MISSED_TRANSACTION, - db.getPendingTransactions().size() - tmpTransactions.size()); - } - - db.getPendingTransactions().clear(); db.getSession().reset(); db.getShieldedTransInPendingCounts().set(0); } @@ -39,22 +19,26 @@ public PendingManager(Manager db) { @Override public void close() { - for (TransactionCapsule tx : tmpTransactions) { + for (TransactionCapsule tx : dbManager.getPendingTransactions()) { txIteration(tx); } - tmpTransactions.clear(); - + dbManager.getPendingTransactions().clear(); for (TransactionCapsule tx : dbManager.getPoppedTransactions()) { + tx.setTime(System.currentTimeMillis()); txIteration(tx); } dbManager.getPoppedTransactions().clear(); + if (Args.getInstance().isOpenPrintLog()) { + logger.warn("pending tx size:{}", dbManager.getRePushTransactions().size()); + } } private void txIteration(TransactionCapsule tx) { try { - if (tx.getTrxTrace() != null - && tx.getTrxTrace().getTimeResultType().equals(TimeResultType.NORMAL)) { + if (System.currentTimeMillis() - tx.getTime() < timeout) { dbManager.getRePushTransactions().put(tx); + } else if (Args.getInstance().isOpenPrintLog()) { + logger.warn("[timeout] remove tx from pending, txId:{}", tx.getTransactionId()); } } catch (InterruptedException e) { logger.error(e.getMessage()); diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index 99f088ab323..6b8a8d85c92 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.utils.Sha256Hash; +import org.tron.core.config.args.Args; import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.InventoryMessage; import org.tron.core.net.message.TronMessage; @@ -58,12 +59,18 @@ private boolean check(PeerConnection peer, InventoryMessage inventoryMessage) { if (count > maxCountIn10s) { logger.warn("Drop inv: {} size: {} from Peer {}, Inv count: {} is overload.", type, size, peer.getInetAddress(), count); + if (Args.getInstance().isOpenPrintLog()) { + logger.warn("[overload]Drop tx list is: {}", inventoryMessage.getHashList()); + } return false; } if (transactionsMsgHandler.isBusy()) { logger.warn("Drop inv: {} size: {} from Peer {}, transactionsMsgHandler is busy.", type, size, peer.getInetAddress()); + if (Args.getInstance().isOpenPrintLog()) { + logger.warn("[isBusy]Drop tx list is: {}", inventoryMessage.getHashList()); + } return false; } } 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 2d0183f57f6..bf9e9956f37 100755 --- a/framework/src/main/java/org/tron/core/services/RpcApiService.java +++ b/framework/src/main/java/org/tron/core/services/RpcApiService.java @@ -74,6 +74,7 @@ import org.tron.api.GrpcAPI.SpendResult; import org.tron.api.GrpcAPI.TransactionApprovedList; import org.tron.api.GrpcAPI.TransactionExtention; +import org.tron.api.GrpcAPI.TransactionIdList; import org.tron.api.GrpcAPI.TransactionInfoList; import org.tron.api.GrpcAPI.TransactionList; import org.tron.api.GrpcAPI.TransactionListExtention; @@ -900,7 +901,6 @@ public void getTransactionInfoByBlockNum(NumberMessage request, responseObserver.onCompleted(); } - } /** @@ -2628,6 +2628,24 @@ public void getMarketPairList(EmptyMessage request, } responseObserver.onCompleted(); } + + @Override + public void getTransactionFromPending(BytesMessage request, + StreamObserver responseObserver) { + getTransactionFromPendingCommon(request, responseObserver); + } + + @Override + public void getTransactionListFromPending(EmptyMessage request, + StreamObserver responseObserver) { + getTransactionListFromPendingCommon(request, responseObserver); + } + + @Override + public void getPendingSize(EmptyMessage request, + StreamObserver responseObserver) { + getPendingSizeCommon(request, responseObserver); + } } public class MonitorApi extends MonitorGrpc.MonitorImplBase { @@ -2710,4 +2728,39 @@ public void getTransactionCountByBlockNumCommon(NumberMessage request, responseObserver.onCompleted(); } + public void getTransactionFromPendingCommon(BytesMessage request, + StreamObserver responseObserver) { + try { + String txId = ByteArray.toHexString(request.getValue().toByteArray()); + TransactionCapsule transactionCapsule = dbManager.getTxFromPending(txId); + responseObserver.onNext(transactionCapsule == null ? null : transactionCapsule.getInstance()); + } catch (Exception e) { + responseObserver.onError(e); + } + responseObserver.onCompleted(); + } + + public void getTransactionListFromPendingCommon(EmptyMessage request, + StreamObserver responseObserver) { + try { + TransactionIdList.Builder builder = TransactionIdList.newBuilder(); + builder.addAllTxId(dbManager.getTxListFromPending()); + responseObserver.onNext(builder.build()); + } catch (Exception e) { + responseObserver.onError(e); + } + responseObserver.onCompleted(); + } + + public void getPendingSizeCommon(EmptyMessage request, + StreamObserver responseObserver) { + try { + NumberMessage.Builder builder = NumberMessage.newBuilder(); + builder.setNum(dbManager.getPendingSize()); + responseObserver.onNext(builder.build()); + } catch (Exception e) { + responseObserver.onError(e); + } + responseObserver.onCompleted(); + } } diff --git a/framework/src/main/java/org/tron/core/services/WitnessProductBlockService.java b/framework/src/main/java/org/tron/core/services/WitnessProductBlockService.java index 5668c25b73e..e895923114f 100644 --- a/framework/src/main/java/org/tron/core/services/WitnessProductBlockService.java +++ b/framework/src/main/java/org/tron/core/services/WitnessProductBlockService.java @@ -36,7 +36,7 @@ public void validWitnessProductTwoBlock(BlockCapsule block) { cheatWitnessInfoMap.get(key).clear().setTime(System.currentTimeMillis()) .setLatestBlockNum(block.getNum()).add(block).add(blockCapsule).increment(); } else { - historyBlockCapsuleCache.put(block.getNum(), block); + historyBlockCapsuleCache.put(block.getNum(), new BlockCapsule(block.getInstance())); } } catch (Exception e) { logger.error("valid witness same time product two block fail! blockNum: {}, blockHash: {}", diff --git a/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java b/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java index 944379c8f42..1c219f35bbf 100644 --- a/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java +++ b/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java @@ -278,6 +278,12 @@ public class FullNodeHttpApiService implements Service { @Autowired private LiteFnQueryHttpFilter liteFnQueryHttpFilter; + @Autowired + private GetTransactionFromPendingServlet getTransactionFromPendingServlet; + @Autowired + private GetTransactionListFromPendingServlet getTransactionListFromPendingServlet; + @Autowired + private GetPendingSizeServlet getPendingSizeServlet; private static String getParamsFile(String fileName) { InputStream in = Thread.currentThread().getContextClassLoader() @@ -518,6 +524,11 @@ public void start() { context.addServlet(new ServletHolder(getBlockBalanceServlet), "/wallet/getblockbalance"); context.addServlet(new ServletHolder(getBurnTrxServlet), "/wallet/getburntrx"); + context.addServlet(new ServletHolder(getTransactionFromPendingServlet), + "/wallet/gettransactionfrompending"); + context.addServlet(new ServletHolder(getTransactionListFromPendingServlet), + "/wallet/gettransactionlistfrompending"); + context.addServlet(new ServletHolder(getPendingSizeServlet), "/wallet/getpendingsize"); int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { diff --git a/framework/src/main/java/org/tron/core/services/http/GetPendingSizeServlet.java b/framework/src/main/java/org/tron/core/services/http/GetPendingSizeServlet.java new file mode 100644 index 00000000000..7e1a5f71841 --- /dev/null +++ b/framework/src/main/java/org/tron/core/services/http/GetPendingSizeServlet.java @@ -0,0 +1,36 @@ +package org.tron.core.services.http; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.core.db.Manager; + + +@Component +@Slf4j(topic = "API") +public class GetPendingSizeServlet extends RateLimiterServlet { + + @Autowired + private Manager manager; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + try { + long value = manager.getPendingSize(); + response.getWriter().println("{\"pendingSize\": " + value + "}"); + } catch (Exception e) { + logger.error("", e); + try { + response.getWriter().println(Util.printErrorMsg(e)); + } catch (IOException ioe) { + logger.debug("IOException: {}", ioe.getMessage()); + } + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) { + doGet(request, response); + } +} diff --git a/framework/src/main/java/org/tron/core/services/http/GetTransactionFromPendingServlet.java b/framework/src/main/java/org/tron/core/services/http/GetTransactionFromPendingServlet.java new file mode 100644 index 00000000000..276eff62af8 --- /dev/null +++ b/framework/src/main/java/org/tron/core/services/http/GetTransactionFromPendingServlet.java @@ -0,0 +1,53 @@ +package org.tron.core.services.http; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.BytesMessage; +import org.tron.common.utils.ByteArray; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.db.Manager; + + +@Component +@Slf4j(topic = "API") +public class GetTransactionFromPendingServlet extends RateLimiterServlet { + + @Autowired + private Manager manager; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + try { + boolean visible = Util.getVisible(request); + String input = request.getParameter("value"); + TransactionCapsule reply = manager.getTxFromPending(input); + if (reply != null) { + response.getWriter().println(Util.printTransaction(reply.getInstance(), visible)); + } else { + response.getWriter().println("{}"); + } + } catch (Exception e) { + Util.processError(e, response); + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) { + try { + PostParams params = PostParams.getPostParams(request); + BytesMessage.Builder build = BytesMessage.newBuilder(); + JsonFormat.merge(params.getParams(), build, params.isVisible()); + TransactionCapsule reply = manager + .getTxFromPending(ByteArray.toHexString(build.getValue().toByteArray())); + if (reply != null) { + response.getWriter() + .println(Util.printTransaction(reply.getInstance(), params.isVisible())); + } else { + response.getWriter().println("{}"); + } + } catch (Exception e) { + Util.processError(e, response); + } + } +} diff --git a/framework/src/main/java/org/tron/core/services/http/GetTransactionListFromPendingServlet.java b/framework/src/main/java/org/tron/core/services/http/GetTransactionListFromPendingServlet.java new file mode 100644 index 00000000000..0a70b22eebf --- /dev/null +++ b/framework/src/main/java/org/tron/core/services/http/GetTransactionListFromPendingServlet.java @@ -0,0 +1,44 @@ +package org.tron.core.services.http; + +import java.util.Collection; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.TransactionIdList; +import org.tron.core.db.Manager; + + +@Component +@Slf4j(topic = "API") +public class GetTransactionListFromPendingServlet extends RateLimiterServlet { + + @Autowired + private Manager manager; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + try { + boolean visible = Util.getVisible(request); + Collection result = manager.getTxListFromPending(); + TransactionIdList.Builder builder = TransactionIdList.newBuilder(); + builder.addAllTxId(result); + response.getWriter().println(Util.printTransactionIdList(builder.build(), visible)); + } catch (Exception e) { + Util.processError(e, response); + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) { + try { + PostParams params = PostParams.getPostParams(request); + Collection result = manager.getTxListFromPending(); + TransactionIdList.Builder builder = TransactionIdList.newBuilder(); + builder.addAllTxId(result); + response.getWriter() + .println(Util.printTransactionIdList(builder.build(), params.isVisible())); + } catch (Exception e) { + Util.processError(e, response); + } + } +} 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 1cc6c47ec35..730daaf6223 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 @@ -29,6 +29,7 @@ import org.tron.api.GrpcAPI.EasyTransferResponse; import org.tron.api.GrpcAPI.TransactionApprovedList; import org.tron.api.GrpcAPI.TransactionExtention; +import org.tron.api.GrpcAPI.TransactionIdList; import org.tron.api.GrpcAPI.TransactionList; import org.tron.api.GrpcAPI.TransactionSignWeight; import org.tron.common.crypto.Hash; @@ -112,6 +113,12 @@ public static String printTransactionList(TransactionList list, boolean selfType return jsonObject.toJSONString(); } + public static String printTransactionIdList(TransactionIdList list, boolean selfType) { + JSONObject jsonObject = JSONObject.parseObject(JsonFormat.printToString(list, selfType)); + + return jsonObject.toJSONString(); + } + public static JSONArray printTransactionListToJSON(List list, boolean selfType) { JSONArray transactions = new JSONArray(); diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java index 8519d0bd6de..669414fca35 100755 --- a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java @@ -495,5 +495,6 @@ public void getBurnTrx(EmptyMessage request, StreamObserver respo () -> rpcApiService.getWalletSolidityApi().getBurnTrx(request, responseObserver) ); } + } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java index 751d7d76c4f..ad6d498e38e 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java @@ -238,7 +238,7 @@ public void start() { // filters the specified APIs // when node is lite fullnode and openHistoryQueryWhenLiteFN is false context.addFilter(new FilterHolder(liteFnQueryHttpFilter), "/*", - EnumSet.allOf(DispatcherType.class)); + EnumSet.allOf(DispatcherType.class)); server.start(); } catch (Exception e) { diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java index 4099d101f4b..05f5bc2bbed 100755 --- a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java @@ -491,5 +491,6 @@ public void getBurnTrx(EmptyMessage request, StreamObserver respo () -> rpcApiService.getWalletSolidityApi().getBurnTrx(request, responseObserver) ); } + } } diff --git a/framework/src/main/java/org/tron/program/Version.java b/framework/src/main/java/org/tron/program/Version.java index f0086fb34a3..800f1f47dc1 100644 --- a/framework/src/main/java/org/tron/program/Version.java +++ b/framework/src/main/java/org/tron/program/Version.java @@ -4,7 +4,7 @@ public class Version { public static final String VERSION_NAME = "GreatVoyage-v4.1.1-2046-gc465c9ee4"; public static final String VERSION_CODE = "15262"; - private static final String VERSION = "4.1.2"; + private static final String VERSION = "4.1.3"; public static String getVersion() { return VERSION; diff --git a/framework/src/test/java/org/tron/core/services/WitnessProductBlockServiceTest.java b/framework/src/test/java/org/tron/core/services/WitnessProductBlockServiceTest.java index f35e95ef64d..0b915b766b9 100644 --- a/framework/src/test/java/org/tron/core/services/WitnessProductBlockServiceTest.java +++ b/framework/src/test/java/org/tron/core/services/WitnessProductBlockServiceTest.java @@ -2,6 +2,7 @@ import com.google.protobuf.ByteString; import java.util.HashSet; +import java.util.Iterator; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Assert; @@ -85,8 +86,17 @@ public void validWitnessProductTwoBlockTest() { Assert.assertEquals(blockCapsule2.getNum(), block.getLatestBlockNum()); Assert.assertEquals(block.getBlockCapsuleSet().contains(blockCapsule2), true); - Assert.assertEquals(block.getBlockCapsuleSet().contains(blockCapsule1), true); - + Iterator iterator = block.getBlockCapsuleSet() + .iterator(); + boolean isInner = false; + while (iterator.hasNext()) { + BlockCapsule blockCapsule = iterator.next(); + blockCapsule.getBlockId(); + if (blockCapsule.getBlockId().equals(blockCapsule1.getBlockId())) { + isInner = true; + } + } + Assert.assertTrue(isInner); } } diff --git a/framework/src/test/java/stest/tron/wallet/common/client/utils/HttpMethed.java b/framework/src/test/java/stest/tron/wallet/common/client/utils/HttpMethed.java index 08093aff3c3..920efa039cc 100644 --- a/framework/src/test/java/stest/tron/wallet/common/client/utils/HttpMethed.java +++ b/framework/src/test/java/stest/tron/wallet/common/client/utils/HttpMethed.java @@ -5169,4 +5169,59 @@ public static HttpResponse getMarketPriceByPairFromPbft(String httpPbftNode, return response; } + /** + * constructor. + */ + public static int getTransactionPendingSize(String httpNode) { + try { + String requestUrl = "http://" + httpNode + "/wallet/getpendingsize"; + JsonObject userBaseObj2 = new JsonObject(); + response = createConnect(requestUrl, userBaseObj2); + } catch (Exception e) { + e.printStackTrace(); + httppost.releaseConnection(); + return 0; + } + responseContent = HttpMethed.parseResponseContent(response); + return responseContent.getInteger("pendingSize"); + } + + /** + * constructor. + */ + public static HttpResponse getTransactionListFromPending(String httpNode) { + try { + String requestUrl = "http://" + httpNode + "/wallet/gettransactionlistfrompending"; + JsonObject userBaseObj2 = new JsonObject(); + response = createConnect(requestUrl, userBaseObj2); + } catch (Exception e) { + e.printStackTrace(); + httppost.releaseConnection(); + return null; + } + return response; + } + + + /** + * constructor. + */ + public static HttpResponse getTransactionFromPending(String httpNode,String txid) { + try { + String requestUrl = "http://" + httpNode + "/wallet/gettransactionfrompending"; + JsonObject userBaseObj2 = new JsonObject(); + userBaseObj2.addProperty("value",txid); + response = createConnect(requestUrl, userBaseObj2); + } catch (Exception e) { + e.printStackTrace(); + httppost.releaseConnection(); + return null; + } + return response; + } + + + + + } diff --git a/framework/src/test/java/stest/tron/wallet/common/client/utils/PublicMethed.java b/framework/src/test/java/stest/tron/wallet/common/client/utils/PublicMethed.java index c60b9d2a868..806f4c47c4b 100644 --- a/framework/src/test/java/stest/tron/wallet/common/client/utils/PublicMethed.java +++ b/framework/src/test/java/stest/tron/wallet/common/client/utils/PublicMethed.java @@ -1824,7 +1824,7 @@ public static boolean waitSolidityNodeSynFullNodeData( Integer wait = 0; logger.info("Fullnode block num is " + currentBlock.getBlockHeader().getRawData().getNumber()); while (solidityCurrentBlock.getBlockHeader().getRawData().getNumber() - < currentBlock.getBlockHeader().getRawData().getNumber() + 1 && wait <= 10) { + < currentBlock.getBlockHeader().getRawData().getNumber() + 1 && wait <= 24) { try { Thread.sleep(3000); } catch (InterruptedException e) { @@ -1834,7 +1834,7 @@ public static boolean waitSolidityNodeSynFullNodeData( .getNumber()); solidityCurrentBlock = blockingStubSolidity .getNowBlock(GrpcAPI.EmptyMessage.newBuilder().build()); - if (wait == 10) { + if (wait == 24) { logger.info("Didn't syn,skip to next case."); return false; } @@ -7197,4 +7197,18 @@ public static BalanceContract.BlockBalanceTrace getBlockBalance(Protocol.Block b } + + /** + * 61 constructor. + */ + + public static Optional getTransactionFromPending(String txId, + WalletGrpc.WalletBlockingStub blockingStubFull) { + ByteString bsTxid = ByteString.copyFrom(ByteArray.fromHexString(txId)); + BytesMessage request = BytesMessage.newBuilder().setValue(bsTxid).build(); + Transaction transaction; + transaction = blockingStubFull.getTransactionFromPending(request); + return Optional.ofNullable(transaction); + } + } diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/account/TransactionFee001.java b/framework/src/test/java/stest/tron/wallet/dailybuild/account/TransactionFee001.java index 58f0048057f..dcd8305887e 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/account/TransactionFee001.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/account/TransactionFee001.java @@ -30,6 +30,7 @@ import stest.tron.wallet.common.client.Parameter.CommonConstant; import stest.tron.wallet.common.client.utils.PublicMethed; import stest.tron.wallet.common.client.utils.PublicMethedForMutiSign; +import stest.tron.wallet.common.client.utils.Retry; import stest.tron.wallet.common.client.utils.Sha256Hash; @@ -181,7 +182,8 @@ public void test01DeployContractEnergyFeeToSr() { Assert.assertEquals(beforeBurnTrxAmount,afterBurnTrxAmount); } - @Test(enabled = true, description = "Test update account permission fee to black hole," + @Test(enabled = true, retryAnalyzer = Retry.class, + description = "Test update account permission fee to black hole," + "trans with multi sign and fee to sr") public void test02UpdateAccountPermissionAndMultiSiginTrans() { ECKey ecKey1 = new ECKey(Utils.getRandom()); diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/http/HttpTestTransactionPending001.java b/framework/src/test/java/stest/tron/wallet/dailybuild/http/HttpTestTransactionPending001.java new file mode 100644 index 00000000000..e8fdf17d559 --- /dev/null +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/http/HttpTestTransactionPending001.java @@ -0,0 +1,100 @@ +package stest.tron.wallet.dailybuild.http; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpResponse; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.utils.HttpMethed; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class HttpTestTransactionPending001 { + + private final String testKey002 = Configuration.getByPath("testng.conf") + .getString("foundationAccount.key1"); + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + private JSONObject responseContent; + private HttpResponse response; + private String httpnode = Configuration.getByPath("testng.conf").getStringList("httpnode.ip.list") + .get(0); + private String httpSoliditynode = Configuration.getByPath("testng.conf") + .getStringList("httpnode.ip.list").get(2); + private String httpPbftNode = Configuration.getByPath("testng.conf") + .getStringList("httpnode.ip.list").get(4); + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] receiverAddress = ecKey1.getAddress(); + String receiverKey = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + String txid; + JSONObject transaction; + + /** + * constructor. + */ + @Test(enabled = true, description = "Get transaction pending size by http") + public void test01GetTransactionPendingSize() { + int pendingSize = 0; + int retryTimes = 50; + + while (pendingSize == 0 && retryTimes-- > 0) { + HttpMethed.sendCoin(httpnode,fromAddress,receiverAddress,1L,testKey002); + if (retryTimes % 5 == 0) { + pendingSize = HttpMethed.getTransactionPendingSize(httpnode); + } + } + + Assert.assertNotEquals(pendingSize,0); + } + + /** + * constructor. + */ + @Test(enabled = true, description = "Get pending transaction list by http") + public void test02GetPendingTransactionList() { + int transactionSize = 0; + int retryTimes = 50; + + while (transactionSize == 0 && retryTimes-- > 0) { + HttpMethed.sendCoin(httpnode,fromAddress,receiverAddress,1L,testKey002); + if (retryTimes % 5 == 0) { + response = HttpMethed.getTransactionListFromPending(httpnode); + responseContent = HttpMethed.parseResponseContent(response); + transactionSize = responseContent.getJSONArray("txId").size(); + } + } + Assert.assertNotEquals(transactionSize,0); + + txid = responseContent.getJSONArray("txId").getString(0); + } + + + /** + * constructor. + */ + @Test(enabled = true, description = "Get pending transaction list by http") + public void test03GetPendingTransactionList() { + response = HttpMethed.getTransactionFromPending(httpnode,txid); + responseContent = HttpMethed.parseResponseContent(response); + HttpMethed.printJsonContent(responseContent); + + Assert.assertEquals(txid,responseContent.getString("txID")); + Assert.assertNotEquals(null,responseContent); + } + + + + + /** + * constructor. + */ + + @AfterClass + public void shutdown() throws InterruptedException { + HttpMethed.disConnect(); + } +} \ No newline at end of file diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/internaltransaction/ContractInternalTransaction003.java b/framework/src/test/java/stest/tron/wallet/dailybuild/internaltransaction/ContractInternalTransaction003.java index 3be9601f593..97983643668 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/internaltransaction/ContractInternalTransaction003.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/internaltransaction/ContractInternalTransaction003.java @@ -26,6 +26,7 @@ import stest.tron.wallet.common.client.Parameter.CommonConstant; import stest.tron.wallet.common.client.utils.Base58; import stest.tron.wallet.common.client.utils.PublicMethed; +import stest.tron.wallet.common.client.utils.Retry; @Slf4j @@ -445,7 +446,8 @@ public void testInternalTransaction017() { dupInternalTrsansactionHash(infoById.get().getInternalTransactionsList()); } - @Test(enabled = true, description = "Test maxfeelimit can trigger call create call max time") + @Test(enabled = true,retryAnalyzer = Retry.class, + description = "Test maxfeelimit can trigger call create call max time") public void testInternalTransaction018() { Assert.assertTrue(PublicMethed .sendcoin(internalTxsAddress, 100000000000L, testNetAccountAddress, testNetAccountKey, @@ -486,7 +488,7 @@ public void testInternalTransaction018() { internalTxsAddress, blockingStubFull); PublicMethed.waitProduceNextBlock(blockingStubFull); PublicMethed - .sendcoin(internalTxsAddress, 1000000000L, testNetAccountAddress, testNetAccountKey, + .sendcoin(internalTxsAddress, 2000000000L, testNetAccountAddress, testNetAccountKey, blockingStubFull); PublicMethed.waitProduceNextBlock(blockingStubFull); PublicMethed.waitProduceNextBlock(blockingStubFull); @@ -503,14 +505,19 @@ public void testInternalTransaction018() { infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); logger.info("InfoById:" + infoById); - // retry 1 times - txid = PublicMethed.triggerContract(contractAddress, - "test1(address,address)", initParmes, false, - 100000, maxFeeLimit, internalTxsAddress, testKeyForinternalTxsAddress, blockingStubFull); - PublicMethed.waitProduceNextBlock(blockingStubFull); - PublicMethed.waitProduceNextBlock(blockingStubFull); - infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); - logger.info("InfoById-1" + ": " + infoById); + int retryTimes = 1; + while (retryTimes++ < 5 && infoById.get().getResultValue() != 0) { + // retry 5 times + txid = PublicMethed.triggerContract(contractAddress, + "test1(address,address)", initParmes, false, + 100000, maxFeeLimit, internalTxsAddress, testKeyForinternalTxsAddress, blockingStubFull); + PublicMethed.waitProduceNextBlock(blockingStubFull); + PublicMethed.waitProduceNextBlock(blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + logger.info("InfoById retry " + retryTimes + " : " + infoById); + } + + Assert.assertEquals(0, infoById.get().getResultValue()); int transactionsCount = infoById.get().getInternalTransactionsCount(); diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/manual/RequireException.java b/framework/src/test/java/stest/tron/wallet/dailybuild/manual/RequireException.java index 4880ffc6e53..74940a837ae 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/manual/RequireException.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/manual/RequireException.java @@ -85,11 +85,11 @@ public void test1TestRequireContract() { testKeyForAssetIssue016 = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); logger.info(Long.toString(PublicMethed.queryAccount(testNetAccountKey, blockingStubFull) .getBalance())); - PublicMethed.waitProduceNextBlock(blockingStubFull); + Assert.assertTrue(PublicMethed .sendcoin(asset016Address, 1000000000L, testNetAccountAddress, testNetAccountKey, blockingStubFull)); - + PublicMethed.waitProduceNextBlock(blockingStubFull); String filePath = "src/test/resources/soliditycode/requireExceptiontest1TestRequireContract.sol"; String contractName = "TestThrowsContract"; diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/transaction/TransactionPendingQuery001.java b/framework/src/test/java/stest/tron/wallet/dailybuild/transaction/TransactionPendingQuery001.java new file mode 100644 index 00000000000..49831ca92b0 --- /dev/null +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/transaction/TransactionPendingQuery001.java @@ -0,0 +1,142 @@ +package stest.tron.wallet.dailybuild.transaction; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.TransactionIdList; +import org.tron.api.GrpcAPI.TransactionList; +import org.tron.api.WalletGrpc; +import org.tron.api.WalletSolidityGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Transaction; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; +import stest.tron.wallet.common.client.utils.Sha256Hash; + + +@Slf4j + +public class TransactionPendingQuery001 { + private final String testKey002 = Configuration.getByPath("testng.conf") + .getString("foundationAccount.key1"); + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; + private ManagedChannel channelSolidity = null; + public ManagedChannel channelPbft = null; + public WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubPbft = null; + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] receiverAddress = ecKey1.getAddress(); + final String receiverKey = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + private String soliditynode = Configuration.getByPath("testng.conf") + .getStringList("solidityNode.ip.list").get(0); + private String soliInPbft = Configuration.getByPath("testng.conf") + .getStringList("solidityNode.ip.list").get(2); + String txid = null; + + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + /** + * constructor. + */ + + @BeforeClass(enabled = true) + public void beforeClass() { + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + + channelSolidity = ManagedChannelBuilder.forTarget(soliditynode) + .usePlaintext(true) + .build(); + blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); + + channelPbft = ManagedChannelBuilder.forTarget(soliInPbft) + .usePlaintext(true) + .build(); + blockingStubPbft = WalletSolidityGrpc.newBlockingStub(channelPbft); + + } + + @Test(enabled = true, description = "Test get pending size") + public void test01GetPendingSize() { + long pendingSizeInFullNode = 0; + int retryTimes = 100; + while (pendingSizeInFullNode == 0 && retryTimes-- > 0) { + PublicMethed.sendcoin(receiverAddress,1L,fromAddress,testKey002,blockingStubFull); + if (retryTimes % 5 == 0) { + pendingSizeInFullNode = blockingStubFull + .getPendingSize(EmptyMessage.newBuilder().build()).getNum(); + } + } + Assert.assertNotEquals(pendingSizeInFullNode,0); + } + + + @Test(enabled = true, description = "Test get pending transaction list") + public void test02GetPendingTransactionList() { + int retryTimes = 100; + TransactionIdList transactionList = blockingStubFull + .getTransactionListFromPending(EmptyMessage.newBuilder().build()); + while (transactionList.getTxIdCount() == 0 && retryTimes-- > 0) { + PublicMethed.sendcoin(receiverAddress,1L,fromAddress,testKey002,blockingStubFull); + if (retryTimes % 5 == 0) { + transactionList = blockingStubFull + .getTransactionListFromPending(EmptyMessage.newBuilder().build()); + } + } + Assert.assertNotEquals(transactionList.getTxIdCount(),0); + + txid = transactionList.getTxId(0); + + logger.info("txid:" + txid); + + } + + + @Test(enabled = true, description = "Test transaction from pending") + public void test03GetTransactionFromPending() { + Transaction transaction = PublicMethed.getTransactionFromPending(txid,blockingStubFull).get(); + Assert.assertEquals(ByteArray.toHexString(Sha256Hash + .hash(true, transaction.getRawData().toByteArray())),txid); + } + + + /** + * constructor. + */ + + @AfterClass + public void shutdown() throws InterruptedException { + PublicMethed.unFreezeBalance(receiverAddress, receiverKey, 1, receiverAddress, + blockingStubFull); + PublicMethed.freedResource(receiverAddress, receiverKey, fromAddress, blockingStubFull); + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } + +} diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/create2/Create2Test001.java b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/create2/Create2Test001.java index f635f22a5b0..42522dac823 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/create2/Create2Test001.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/create2/Create2Test001.java @@ -80,6 +80,7 @@ public void test01DeployFactoryContract() { testKey002, blockingStubFull)); Assert.assertTrue(PublicMethed.sendcoin(user001Address, 10000_000_000L, fromAddress, testKey002, blockingStubFull)); + PublicMethed.waitProduceNextBlock(blockingStubFull); String filePath = "./src/test/resources/soliditycode/create2contract.sol"; String contractName = "Factory"; HashMap retMap = PublicMethed.getBycodeAbi(filePath, contractName); diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/shiftcommand/ShiftCommand006.java b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/shiftcommand/ShiftCommand006.java index b43eac1d4fb..371fbd52250 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/shiftcommand/ShiftCommand006.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/shiftcommand/ShiftCommand006.java @@ -86,6 +86,7 @@ public void test1ShiftRightSigned() { Assert.assertTrue(PublicMethed .sendcoin(contractExcAddress, 100000000000L, testNetAccountAddress, testNetAccountKey, blockingStubFull)); + PublicMethed.waitProduceNextBlock(blockingStubFull); String filePath = "src/test/resources/soliditycode/ShiftCommand001.sol"; String contractName = "TestBitwiseShift"; HashMap retMap = PublicMethed.getBycodeAbi(filePath, contractName); diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed001.java b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed001.java index 70715cf0463..df48d857af4 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed001.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed001.java @@ -89,6 +89,7 @@ public void test001TransferTrxInsufficientBalance() { Assert.assertTrue(PublicMethed .sendcoin(contractExcAddress, 10000000000L, testNetAccountAddress, testNetAccountKey, blockingStubFull)); + PublicMethed.waitProduceNextBlock(blockingStubFull); String filePath = "src/test/resources/soliditycode/TransferFailed001.sol"; String contractName = "EnergyOfTransferFailedTest"; HashMap retMap = PublicMethed.getBycodeAbi(filePath, contractName); diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed002.java b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed002.java index 200d6379fd5..4583b44b078 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed002.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed002.java @@ -79,6 +79,7 @@ public void test1SendNotEnough() { Assert.assertTrue(PublicMethed .sendcoin(contractExcAddress, 100000000L, testNetAccountAddress, testNetAccountKey, blockingStubFull)); + PublicMethed.waitProduceNextBlock(blockingStubFull); String filePath = "src/test/resources/soliditycode/TransferFailed001.sol"; String contractName = "EnergyOfTransferFailedTest"; HashMap retMap = PublicMethed.getBycodeAbi(filePath, contractName); diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed004.java b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed004.java index a5250920575..04e11c7e35f 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed004.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/transferfailed/TransferFailed004.java @@ -90,6 +90,7 @@ public void test1SuicideNonexistentTarget() { Assert.assertTrue(PublicMethed .sendcoin(contractExcAddress, 10000000000L, testNetAccountAddress, testNetAccountKey, blockingStubFull)); + PublicMethed.waitProduceNextBlock(blockingStubFull); String filePath = "src/test/resources/soliditycode/TransferFailed001.sol"; String contractName = "EnergyOfTransferFailedTest"; HashMap retMap = PublicMethed.getBycodeAbi(filePath, contractName); diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/tryCatch/tryCatchTest001.java b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/tryCatch/tryCatchTest001.java index 25872dbd324..afcc6cb068a 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/tryCatch/tryCatchTest001.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/tryCatch/tryCatchTest001.java @@ -60,6 +60,7 @@ public void beforeClass() { PublicMethed .sendcoin(testAddress001, 10000_000_000L, testFoundationAddress, testFoundationKey, blockingStubFull); + PublicMethed.waitProduceNextBlock(blockingStubFull); String filePath = "src/test/resources/soliditycode/tryCatch001.sol"; String contractName = "tryTest"; diff --git a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/tryCatch/tryCatchTest002.java b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/tryCatch/tryCatchTest002.java index b4427147611..5e7de366658 100644 --- a/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/tryCatch/tryCatchTest002.java +++ b/framework/src/test/java/stest/tron/wallet/dailybuild/tvmnewcommand/tryCatch/tryCatchTest002.java @@ -59,6 +59,7 @@ public void beforeClass() { .sendcoin(testAddress001, 10000_000_000L, testFoundationAddress, testFoundationKey, blockingStubFull); + PublicMethed.waitProduceNextBlock(blockingStubFull); String filePath = "src/test/resources/soliditycode/tryCatch001.sol"; String contractName = "tryTest"; HashMap retMap = PublicMethed.getBycodeAbi(filePath, contractName); diff --git a/protocol/src/main/protos/api/api.proto b/protocol/src/main/protos/api/api.proto index c56ced503b0..87ddf603d15 100644 --- a/protocol/src/main/protos/api/api.proto +++ b/protocol/src/main/protos/api/api.proto @@ -780,6 +780,15 @@ service Wallet { rpc GetBurnTrx (EmptyMessage) returns (NumberMessage) { } + + rpc GetTransactionFromPending (BytesMessage) returns (Transaction) { + } + + rpc GetTransactionListFromPending (EmptyMessage) returns (TransactionIdList) { + } + + rpc GetPendingSize (EmptyMessage) returns (NumberMessage) { + } }; service WalletSolidity { @@ -1075,6 +1084,9 @@ message BlockList { message TransactionList { repeated Transaction transaction = 1; } +message TransactionIdList { + repeated string txId = 1; +} message DelegatedResourceMessage { bytes fromAddress = 1; bytes toAddress = 2;