├── .gitignore ├── config.conf ├── src ├── main │ ├── java │ │ └── org │ │ │ └── tron │ │ │ ├── common │ │ │ ├── utils │ │ │ │ ├── LogConfig.java │ │ │ │ ├── ByteArray.java │ │ │ │ ├── Base58.java │ │ │ │ ├── Sha256Hash.java │ │ │ │ └── ByteUtil.java │ │ │ ├── runtime │ │ │ │ ├── utils │ │ │ │ │ └── MUtil.java │ │ │ │ └── vm │ │ │ │ │ ├── LogInfo.java │ │ │ │ │ └── DataWord.java │ │ │ └── crypto │ │ │ │ ├── cryptohash │ │ │ │ ├── Keccak256.java │ │ │ │ ├── Keccak512.java │ │ │ │ ├── Digest.java │ │ │ │ ├── DigestEngine.java │ │ │ │ └── KeccakCore.java │ │ │ │ ├── jce │ │ │ │ └── TronCastleProvider.java │ │ │ │ ├── Hash.java │ │ │ │ └── Crypto.java │ │ │ ├── trongeventquery │ │ │ ├── response │ │ │ │ └── Response.java │ │ │ ├── contractlogs │ │ │ │ ├── DataWordEntity.java │ │ │ │ ├── LogInfoEntity.java │ │ │ │ ├── ContractLogTriggerEntity.java │ │ │ │ ├── ContractWithAbiController.java │ │ │ │ └── ContractLogController.java │ │ │ ├── monitor │ │ │ │ ├── MonitorController.java │ │ │ │ ├── MonitorService.java │ │ │ │ └── MonitorInfo.java │ │ │ ├── solidityevents │ │ │ │ └── SolidityTriggerEntity.java │ │ │ ├── transactions │ │ │ │ ├── InternalTransactionPojo.java │ │ │ │ ├── TransactionController.java │ │ │ │ └── TransactionTriggerEntity.java │ │ │ ├── blocks │ │ │ │ ├── BlockTriggerEntity.java │ │ │ │ └── BlockController.java │ │ │ ├── TronEventApplication.java │ │ │ ├── transfers │ │ │ │ └── TransferController.java │ │ │ ├── EventLogEntity.java │ │ │ ├── contractevents │ │ │ │ └── ContractEventTriggerEntity.java │ │ │ ├── query │ │ │ │ ├── ContractEventParserJson.java │ │ │ │ ├── ContractEventParser.java │ │ │ │ └── QueryFactory.java │ │ │ └── filter │ │ │ │ └── CommonFilter.java │ │ │ └── core │ │ │ └── Wallet.java │ └── main.iml └── test │ └── test.iml ├── deploy.sh ├── deleteData.sh ├── insertIndex.sh ├── pom.xml ├── mvnw.cmd ├── mvnw └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | target/* 2 | .idea/* 3 | troneventquery.iml 4 | .classpath 5 | .factorypath 6 | .settings/* 7 | .vscode/* 8 | -------------------------------------------------------------------------------- /config.conf: -------------------------------------------------------------------------------- 1 | mongo.host=127.0.0.1 2 | mongo.port=18883 3 | mongo.dbname=eventlog 4 | mongo.username=tron 5 | mongo.password=123456 6 | 7 | mongo.connectionsPerHost=200 8 | mongo.threadsAllowedToBlockForConnectionMultiplier=10 9 | mongo.deadline=10 10 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/utils/LogConfig.java: -------------------------------------------------------------------------------- 1 | package org.tron.common.utils; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class LogConfig { 9 | public static final Logger LOG = LoggerFactory.getLogger(LogConfig.class); 10 | } -------------------------------------------------------------------------------- /src/main/main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/test/test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/response/Response.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.response; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | 5 | 6 | public class Response { 7 | public Response(boolean result, String msg) { 8 | jsonObject = new JSONObject(); 9 | jsonObject.put("success", result); 10 | jsonObject.put("error", msg); 11 | } 12 | 13 | public JSONObject toJSONObject() { 14 | return jsonObject; 15 | } 16 | 17 | private JSONObject jsonObject; 18 | 19 | } -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/contractlogs/DataWordEntity.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.contractlogs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Getter; 5 | import org.springframework.data.mongodb.core.mapping.Field; 6 | 7 | public class DataWordEntity { 8 | 9 | @Field(value = "data") 10 | @JsonProperty(value = "data") 11 | @Getter 12 | private String data; 13 | 14 | public DataWordEntity(String data) { 15 | this.data = data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/runtime/utils/MUtil.java: -------------------------------------------------------------------------------- 1 | package org.tron.common.runtime.utils; 2 | 3 | import org.tron.core.Wallet; 4 | 5 | public class MUtil { 6 | 7 | private MUtil() { 8 | } 9 | 10 | public static byte[] convertToTronAddress(byte[] address) { 11 | if (address.length == 20) { 12 | byte[] newAddress = new byte[21]; 13 | byte[] temp = new byte[]{Wallet.getAddressPreFixByte()}; 14 | System.arraycopy(temp, 0, newAddress, 0, temp.length); 15 | System.arraycopy(address, 0, newAddress, temp.length, address.length); 16 | address = newAddress; 17 | } 18 | return address; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | while true; do 3 | pid=`ps -ef | grep troneventquery | grep -v grep | awk '{print $2}'` 4 | if [ -n "$pid" ]; then 5 | kill -15 $pid 6 | echo "ending tron event query process" 7 | sleep 1 8 | else 9 | echo "tron event query killed successfully!" 10 | break 11 | fi 12 | done 13 | total=`cat /proc/meminfo |grep MemTotal |awk -F ' ' '{print $2}'` 14 | xmx=`echo "$total/1024/1024*0.6" | bc |awk -F. '{print $1"g"}'` 15 | logtime=`date +%Y-%m-%d_%H-%M-%S` 16 | nohup java -Xmx$xmx -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -Xloggc:./gc.log\ 17 | -XX:+PrintGCDateStamps -XX:+CMSParallelRemarkEnabled -XX:ReservedCodeCacheSize=256m\ 18 | -XX:+CMSScavengeBeforeRemark -jar target/troneventquery-1.0.0-SNAPSHOT.jar >> query.log 2>&1 & 19 | 20 | sleep 10 21 | echo "ok!" 22 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/contractlogs/LogInfoEntity.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.contractlogs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import lombok.Getter; 7 | import org.springframework.data.mongodb.core.mapping.Field; 8 | 9 | public class LogInfoEntity { 10 | 11 | @Field(value = "address") 12 | @JsonProperty(value = "address") 13 | @Getter 14 | private String address; 15 | 16 | @Field(value = "topics") 17 | @JsonProperty(value = "topics") 18 | @Getter 19 | private List topics = new ArrayList(); 20 | 21 | @Field(value = "data") 22 | @JsonProperty(value = "data") 23 | @Getter 24 | private String data; 25 | 26 | public LogInfoEntity(String address, List topics, 27 | String data) { 28 | this.address = address; 29 | this.topics = topics; 30 | this.data = data; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/monitor/MonitorController.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.monitor; 2 | 3 | 4 | import com.alibaba.fastjson.JSON; 5 | import com.alibaba.fastjson.JSONObject; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | @RestController 15 | public class MonitorController { 16 | 17 | @Autowired 18 | MonitorService monitorService; 19 | 20 | @RequestMapping(method = RequestMethod.GET, value = "/monitor") 21 | public String getMonitor(){ 22 | 23 | MonitorInfo monitorInfo = monitorService.getMonitorInfo(); 24 | String monitorInfoString = JSON.toJSONString(monitorInfo); 25 | // Object parse = JSONObject.parse(monitorInfoString); 26 | return monitorInfoString; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /deleteData.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mongoIp=`cat config.conf | grep mongo.host | awk -F '=' '{print $2}'` 3 | mongoPort=`cat config.conf | grep mongo.port | awk -F '=' '{print $2}'` 4 | dbname=`cat config.conf | grep mongo.dbname | awk -F '=' '{print $2}'` 5 | userName=`cat config.conf | grep mongo.username | awk -F '=' '{print $2}'` 6 | password=`cat config.conf | grep mongo.password | awk -F '=' '{print $2}'` 7 | deadline=`cat config.conf | grep mongo.deadline | awk -F '=' '{print $2}'` 8 | historyTimeStamp=0 9 | if [[ $foo != *[!0-9]* ]]; 10 | then 11 | let historyTimeStamp=$(date +%s)*1000 12 | let historyTimeStamp=historyTimeStamp-24*3600*deadline*1000 13 | fi 14 | echo $historyTimeStamp 15 | mongodb='mongo '$mongoIp':'$mongoPort 16 | $mongodb < ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.crypto.cryptohash; 20 | 21 | public class Keccak256 extends KeccakCore { 22 | 23 | /** 24 | * Create the engine. 25 | */ 26 | public Keccak256() { 27 | super("tron-keccak-256"); 28 | } 29 | 30 | public Digest copy() { 31 | return copyState(new Keccak256()); 32 | } 33 | 34 | public int engineGetDigestLength() { 35 | return 32; 36 | } 37 | 38 | @Override 39 | protected byte[] engineDigest() { 40 | return null; 41 | } 42 | 43 | @Override 44 | protected void engineUpdate(byte arg0) { 45 | } 46 | 47 | @Override 48 | protected void engineUpdate(byte[] arg0, int arg1, int arg2) { 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.crypto.cryptohash; 20 | 21 | public class Keccak512 extends KeccakCore { 22 | 23 | /** 24 | * Create the engine. 25 | */ 26 | public Keccak512() { 27 | super("tron-keccak-512"); 28 | } 29 | 30 | public Digest copy() { 31 | return copyState(new Keccak512()); 32 | } 33 | 34 | public int engineGetDigestLength() { 35 | return 64; 36 | } 37 | 38 | @Override 39 | protected byte[] engineDigest() { 40 | return null; 41 | } 42 | 43 | @Override 44 | protected void engineUpdate(byte input) { 45 | } 46 | 47 | @Override 48 | protected void engineUpdate(byte[] input, int offset, int len) { 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.crypto.jce; 20 | 21 | import java.security.Provider; 22 | import java.security.Security; 23 | import org.spongycastle.jce.provider.BouncyCastleProvider; 24 | import org.tron.common.crypto.cryptohash.Keccak256; 25 | import org.tron.common.crypto.cryptohash.Keccak512; 26 | 27 | public final class TronCastleProvider { 28 | 29 | public static Provider getInstance() { 30 | return Holder.INSTANCE; 31 | } 32 | 33 | private static class Holder { 34 | 35 | private static final Provider INSTANCE; 36 | 37 | static { 38 | Provider p = Security.getProvider("SC"); 39 | 40 | INSTANCE = (p != null) ? p : new BouncyCastleProvider(); 41 | INSTANCE.put("MessageDigest.TRON-KECCAK-256", Keccak256.class.getName()); 42 | INSTANCE.put("MessageDigest.TRON-KECCAK-512", Keccak512.class.getName()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/transactions/InternalTransactionPojo.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.transactions; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import org.springframework.data.mongodb.core.mapping.Field; 7 | 8 | public class InternalTransactionPojo { 9 | @Field(value = "hash") 10 | @JsonProperty(value = "hash") 11 | private String hash; 12 | /* the amount of trx to transfer (calculated as sun) */ 13 | @Field(value = "callValue") 14 | @JsonProperty(value = "callValue") 15 | private long callValue; 16 | private Map tokenInfo = new HashMap<>(); 17 | 18 | /* the address of the destination account (for message) 19 | * In creation transaction the receive address is - 0 */ 20 | @Field(value = "transferTo_address") 21 | @JsonProperty(value = "transferTo_address") 22 | private String transferTo_address; 23 | 24 | /* An unlimited size byte array specifying 25 | * input [data] of the message call or 26 | * Initialization code for a new contract */ 27 | @Field(value = "data") 28 | @JsonProperty(value = "data") 29 | private String data; 30 | 31 | /* Message sender address */ 32 | @Field(value = "caller_address") 33 | @JsonProperty(value = "caller_address") 34 | private String caller_address; 35 | 36 | @Field(value = "rejected") 37 | @JsonProperty(value = "rejected") 38 | private boolean rejected; 39 | 40 | @Field(value = "note") 41 | @JsonProperty(value = "note") 42 | private String note; 43 | 44 | public InternalTransactionPojo(String hash, long callValue, 45 | String transferTo_address, String data, 46 | String caller_address, boolean rejected,String note) { 47 | this.hash = hash; 48 | this.callValue = callValue; 49 | this.transferTo_address = transferTo_address; 50 | this.data = data; 51 | this.caller_address = caller_address; 52 | this.rejected = rejected; 53 | this.note = note; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /insertIndex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mongoIp=`cat config.conf | grep mongo.host | awk -F '=' '{print $2}'` 3 | mongoPort=`cat config.conf | grep mongo.port | awk -F '=' '{print $2}'` 4 | dbname=`cat config.conf | grep mongo.dbname | awk -F '=' '{print $2}'` 5 | userName=`cat config.conf | grep mongo.username | awk -F '=' '{print $2}'` 6 | password=`cat config.conf | grep mongo.password | awk -F '=' '{print $2}'` 7 | 8 | #mongo ip+port 9 | mongodb='mongo '$mongoIp':'$mongoPort 10 | $mongodb < transactionList; 33 | 34 | @Field(value = "timeStamp") 35 | @JsonProperty(value = "timeStamp") 36 | private Long timeStamp; 37 | 38 | @Field(value = "triggerName") 39 | @JsonProperty(value = "triggerName") 40 | private String triggerName; 41 | 42 | @Field(value = "latestSolidifiedBlockNumber") 43 | @JsonProperty(value = "latestSolidifiedBlockNumber") 44 | private long latestSolidifiedBlockNumber; 45 | 46 | public long getLatestSolidifiedBlockNumber() { 47 | return latestSolidifiedBlockNumber; 48 | } 49 | 50 | public BlockTriggerEntity(long blockNumber, String blockHash, long transactionSize, 51 | List transactionList, Long timeStamp, 52 | String triggerName, long latestSolidifiedBlockNumber) { 53 | this.blockNumber = blockNumber; 54 | this.blockHash = blockHash; 55 | this.transactionSize = transactionSize; 56 | this.transactionList = transactionList; 57 | this.timeStamp = timeStamp; 58 | this.triggerName = triggerName; 59 | this.latestSolidifiedBlockNumber = latestSolidifiedBlockNumber; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/crypto/Hash.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.crypto; 20 | 21 | import static org.tron.common.utils.LogConfig.LOG; 22 | 23 | import java.security.MessageDigest; 24 | import java.security.NoSuchAlgorithmException; 25 | import java.security.Provider; 26 | import java.security.Security; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.tron.common.crypto.jce.TronCastleProvider; 29 | 30 | public class Hash { 31 | 32 | private static final Provider CRYPTO_PROVIDER; 33 | 34 | private static final String HASH_256_ALGORITHM_NAME; 35 | private static final String HASH_512_ALGORITHM_NAME; 36 | 37 | static { 38 | Security.addProvider(TronCastleProvider.getInstance()); 39 | CRYPTO_PROVIDER = Security.getProvider("SC"); 40 | HASH_256_ALGORITHM_NAME = "TRON-KECCAK-256"; 41 | HASH_512_ALGORITHM_NAME = "TRON-KECCAK-512"; 42 | } 43 | 44 | public static byte[] sha3(byte[] input) { 45 | MessageDigest digest; 46 | try { 47 | digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, 48 | CRYPTO_PROVIDER); 49 | digest.update(input); 50 | return digest.digest(); 51 | } catch (NoSuchAlgorithmException e) { 52 | LOG.error("Can't find such algorithm", e); 53 | throw new RuntimeException(e); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/org/tron/core/Wallet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.core; 20 | 21 | import lombok.extern.slf4j.Slf4j; 22 | import org.springframework.stereotype.Component; 23 | import org.tron.common.utils.Base58; 24 | import org.tron.common.utils.Sha256Hash; 25 | 26 | @Slf4j 27 | @Component 28 | public class Wallet { 29 | 30 | 31 | private static byte addressPreFixByte = (byte) 0x41; //41 + address 32 | 33 | /** 34 | * Creates a new Wallet . 35 | */ 36 | public Wallet() { 37 | } 38 | 39 | public static byte getAddressPreFixByte() { 40 | return addressPreFixByte; 41 | } 42 | 43 | public static String encode58Check(byte[] input) { 44 | byte[] hash0 = Sha256Hash.hash(input); 45 | byte[] hash1 = Sha256Hash.hash(hash0); 46 | byte[] inputCheck = new byte[input.length + 4]; 47 | System.arraycopy(input, 0, inputCheck, 0, input.length); 48 | System.arraycopy(hash1, 0, inputCheck, input.length, 4); 49 | return Base58.encode(inputCheck); 50 | } 51 | 52 | public static byte[] decode58Check(String input) { 53 | byte[] decodeCheck = Base58.decode(input); 54 | if (decodeCheck.length <= 4) { 55 | return null; 56 | } 57 | byte[] decodeData = new byte[decodeCheck.length - 4]; 58 | System.arraycopy(decodeCheck, 0, decodeData, 0, decodeData.length); 59 | byte[] hash0 = Sha256Hash.hash(decodeData); 60 | byte[] hash1 = Sha256Hash.hash(hash0); 61 | if (hash1[0] == decodeCheck[decodeData.length] && 62 | hash1[1] == decodeCheck[decodeData.length + 1] && 63 | hash1[2] == decodeCheck[decodeData.length + 2] && 64 | hash1[3] == decodeCheck[decodeData.length + 3]) { 65 | return decodeData; 66 | } 67 | return null; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/crypto/Crypto.java: -------------------------------------------------------------------------------- 1 | package org.tron.common.crypto; 2 | import static org.tron.common.utils.LogConfig.LOG; 3 | 4 | import java.util.regex.Pattern; 5 | 6 | public class Crypto { 7 | 8 | private final static long SECRET_KEY = 5658116; 9 | private final static String CONVERT_KEY = "DeCATbJIzM"; 10 | private final static String CONFUSED_WORDS_KEY = "FxYNgq"; 11 | private final static int LEN_KEY = 32; 12 | 13 | 14 | static public String encrypt(String str){ 15 | Long time = new Long(157551410); 16 | if(!isNumber(str)){ 17 | LOG.info("not number"); 18 | return null; 19 | } 20 | 21 | long number = Long.parseLong(str); 22 | long newNumber = (number + time) * SECRET_KEY; 23 | String[] numArr = String.valueOf(newNumber).split(""); 24 | String[] initArr = CONVERT_KEY.split(""); 25 | int len = numArr.length; 26 | StringBuffer buffer = new StringBuffer(); 27 | 28 | for(int i = 0; i < len; i++){ 29 | int inx = Integer.parseInt(numArr[i]); 30 | buffer.append(initArr[inx]); 31 | } 32 | 33 | String[] cwkArr = CONFUSED_WORDS_KEY.split(""); 34 | if(len < LEN_KEY){ 35 | int l = LEN_KEY - len; 36 | for(int i = 0; i < l; i++){ 37 | int index = (int)(Math.random()*buffer.length()); 38 | int inx = (int)(Math.random()*(CONFUSED_WORDS_KEY.length())); 39 | buffer.insert(index,cwkArr[inx]); 40 | } 41 | } 42 | String result = buffer.toString(); 43 | return result; 44 | } 45 | 46 | public static int decrypt(String str){ 47 | Long time = new Long(157551410); 48 | if(null == str || "".equals(str)){ 49 | return 0; 50 | } 51 | int l = CONFUSED_WORDS_KEY.length(); 52 | String[] cwkArr = CONFUSED_WORDS_KEY.split(""); 53 | for(int i = 0; i < l; i++){ 54 | str = str.replaceAll(cwkArr[i],""); 55 | } 56 | String[] initArr = str.split(""); 57 | int len = initArr.length; 58 | StringBuffer result = new StringBuffer(); 59 | for(int i = 0; i < len; i++ ){ 60 | int k = CONVERT_KEY.indexOf(initArr[i]); 61 | if(k == -1){ 62 | return 0; 63 | } 64 | result.append(k); 65 | } 66 | Long number; 67 | try { 68 | long total = Long.parseLong(result.toString()); 69 | long sum = total/SECRET_KEY; 70 | number = sum - time; 71 | } catch (NumberFormatException e) { 72 | e.printStackTrace(); 73 | return 0; 74 | } 75 | return number.intValue(); 76 | } 77 | 78 | public static boolean isNumber(String value) { 79 | String pattern = "^[0-9]*[1-9][0-9]*$"; 80 | boolean isMatch = Pattern.matches(pattern, value); 81 | return isMatch; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/monitor/MonitorService.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.monitor; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | import org.tron.trongeventquery.filter.CommonFilter; 8 | 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | @Slf4j(topic = "monitorService") 15 | @Component 16 | public class MonitorService { 17 | 18 | // @Autowired 19 | // private MonitorMetric monitorMetric; 20 | 21 | public MonitorInfo getMonitorInfo() { 22 | MonitorInfo monitorInfo = new MonitorInfo(); 23 | monitorInfo.setStatus(1); 24 | monitorInfo.setMsg("success"); 25 | MonitorInfo.DataInfo data = new MonitorInfo.DataInfo(); 26 | setNetInfo(data); 27 | monitorInfo.setDataInfo(data); 28 | 29 | // return monitorInfo.ToProtoEntity(); 30 | return monitorInfo; 31 | } 32 | 33 | public void setNetInfo(MonitorInfo.DataInfo data) { 34 | MonitorInfo.DataInfo.NetInfo netInfo = new MonitorInfo.DataInfo.NetInfo(); 35 | 36 | // set api request info 37 | MonitorInfo.DataInfo.NetInfo.ApiInfo apiInfo = new MonitorInfo.DataInfo.NetInfo.ApiInfo(); 38 | CommonFilter commonFilter=new CommonFilter(); 39 | apiInfo.setTotalCount(commonFilter.getInstance().getTotalCount()); 40 | apiInfo.setTotalCount2xx(commonFilter.getInstance().getOkCount()); 41 | apiInfo.setTotalFailCount(commonFilter.getInstance().getFailCount()); 42 | apiInfo.setTotalCount4xx(commonFilter.getInstance().getCount4xx()); 43 | apiInfo.setTotalCount5xx(commonFilter.getInstance().getCount5xx()); 44 | List apiDetails = new ArrayList<>(); 45 | for(Map.Entry entry: commonFilter.getInstance().getEndpointMap().entrySet()){ 46 | MonitorInfo.DataInfo.NetInfo.ApiInfo.ApiDetailInfo apiDetail = 47 | new MonitorInfo.DataInfo.NetInfo.ApiInfo.ApiDetailInfo(); 48 | apiDetail.setName(entry.getKey()); 49 | apiDetail.setCount((int)entry.getValue().get(CommonFilter.TOTAL_REQUST)); 50 | apiDetail.setFailCount((int)entry.getValue().get(CommonFilter.FAIL_REQUST)); 51 | apiDetail.setCount2xx((int)entry.getValue().get(CommonFilter.OK_REQUST)); 52 | apiDetail.setCount4xx((int)entry.getValue().get(CommonFilter.FAIL4XX_REQUST)); 53 | apiDetail.setCount5xx((int)entry.getValue().get(CommonFilter.FAIL5XX_REQUST)); 54 | apiDetails.add(apiDetail); 55 | } 56 | apiInfo.setApiDetailInfo(apiDetails); 57 | netInfo.setApi(apiInfo); 58 | 59 | data.setNetInfo(netInfo); 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/runtime/vm/LogInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | package org.tron.common.runtime.vm; 19 | 20 | import java.util.ArrayList; 21 | import java.util.LinkedList; 22 | import java.util.List; 23 | import org.spongycastle.util.encoders.Hex; 24 | import org.tron.common.utils.ByteUtil; 25 | 26 | /** 27 | * @author Roman Mandeleil 28 | * @since 19.11.2014 29 | */ 30 | public class LogInfo { 31 | 32 | private byte[] address = new byte[]{}; 33 | private List topics = new ArrayList<>(); 34 | private byte[] data = new byte[]{}; 35 | 36 | public LogInfo(byte[] address, List topics, byte[] data) { 37 | this.address = (address != null) ? address : new byte[]{}; 38 | this.topics = (topics != null) ? topics : new ArrayList(); 39 | this.data = (data != null) ? data : new byte[]{}; 40 | } 41 | 42 | public byte[] getAddress() { 43 | return address; 44 | } 45 | 46 | public List getTopics() { 47 | return topics; 48 | } 49 | 50 | public List getHexTopics() { 51 | List list = new LinkedList<>(); 52 | if (topics != null && !topics.isEmpty()) { 53 | for (DataWord bytes : topics) { 54 | list.add(bytes.toHexString()); 55 | } 56 | } 57 | return list; 58 | } 59 | 60 | public List getClonedTopics() { 61 | List list = new LinkedList<>(); 62 | if (topics != null && topics.size() > 0) { 63 | for (DataWord dataword : topics) { 64 | list.add(dataword.getClonedData()); 65 | } 66 | } 67 | return list; 68 | } 69 | 70 | public String getHexData() { 71 | return Hex.toHexString(data); 72 | } 73 | 74 | public byte[] getClonedData() { 75 | return ByteUtil.cloneBytes(data); 76 | } 77 | 78 | public byte[] getData() { 79 | return data; 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | 85 | StringBuilder topicsStr = new StringBuilder(); 86 | topicsStr.append("["); 87 | 88 | for (DataWord topic : topics) { 89 | String topicStr = Hex.toHexString(topic.getData()); 90 | topicsStr.append(topicStr).append(" "); 91 | } 92 | topicsStr.append("]"); 93 | 94 | return "LogInfo{" 95 | + "address=" + Hex.toHexString(address) 96 | + ", topics=" + topicsStr 97 | + ", data=" + Hex.toHexString(data) 98 | + '}'; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/transactions/TransactionController.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.transactions; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.data.mongodb.core.MongoTemplate; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | import org.springframework.web.bind.annotation.RestController; 15 | import org.tron.trongeventquery.query.QueryFactory; 16 | 17 | @RestController 18 | @Component 19 | public class TransactionController { 20 | @Autowired(required = false) 21 | MongoTemplate mongoTemplate; 22 | 23 | @RequestMapping(method = RequestMethod.GET, value = "/transactions/total") 24 | public Long totaltransaction() { 25 | QueryFactory query = new QueryFactory(); 26 | long number = mongoTemplate.count(query.getQuery(), TransactionTriggerEntity.class); 27 | return number; 28 | } 29 | 30 | @RequestMapping(method = RequestMethod.GET, value = "/transactions") 31 | public JSONObject getTranssactions( 32 | /******************* Page Parameters ****************************************************/ 33 | @RequestParam(value = "limit", required = false, defaultValue = "25") int limit, 34 | @RequestParam(value = "sort", required = false, defaultValue = "-timeStamp") String sort, 35 | @RequestParam(value = "start", required = false, defaultValue = "0") int start, 36 | @RequestParam(value = "contractType", required = false, defaultValue = "") String contractType, 37 | /****************** Filter parameters *****************************************************/ 38 | @RequestParam(value = "block", required = false, defaultValue = "-1") long block 39 | ) { 40 | QueryFactory query = new QueryFactory(); 41 | if (block > 0) { 42 | query.setBlockNumGte(block); 43 | } 44 | if (contractType.length() != 0) { 45 | query.setContractTypeEqual(contractType); 46 | } 47 | query.setPageniate(QueryFactory.setPagniateVariable(start, limit, sort)); 48 | List queryResult = mongoTemplate.find(query.getQuery(), 49 | TransactionTriggerEntity.class); 50 | Map map = new HashMap(); 51 | map.put("total", queryResult.size()); 52 | map.put("data", queryResult); 53 | return new JSONObject(map); 54 | } 55 | 56 | @RequestMapping(method = RequestMethod.GET, value = "/transactions/{hash}") 57 | public JSONObject getTransactionbyHash( 58 | @PathVariable String hash 59 | ) { 60 | 61 | QueryFactory query = new QueryFactory(); 62 | query.setTransactionIdEqual(hash); 63 | List queryResult = mongoTemplate.find(query.getQuery(), 64 | TransactionTriggerEntity.class); 65 | if (queryResult.size() == 0) { 66 | return null; 67 | } 68 | Map map = new HashMap(); 69 | map.put("transaction", queryResult.get(0)); 70 | 71 | return new JSONObject(map); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/blocks/BlockController.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.blocks; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.data.mongodb.core.MongoTemplate; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | import org.springframework.web.bind.annotation.RestController; 15 | import org.tron.trongeventquery.query.QueryFactory; 16 | 17 | @RestController 18 | @Component 19 | public class BlockController { 20 | @Autowired(required = false) 21 | MongoTemplate mongoTemplate; 22 | 23 | @RequestMapping(method = RequestMethod.GET, value = "/blocks/total") 24 | public Long totalblock() { 25 | QueryFactory query = new QueryFactory(); 26 | long number = mongoTemplate.count(query.getQuery(), BlockTriggerEntity.class); 27 | return number; 28 | } 29 | 30 | @RequestMapping(method = RequestMethod.GET, value = "/blocks") 31 | public JSONObject getBlocks( 32 | /******************* Page Parameters ****************************************************/ 33 | @RequestParam(value = "limit", required = false, defaultValue = "25") int limit, 34 | @RequestParam(value = "sort", required = false, defaultValue = "-timeStamp") String sort, 35 | @RequestParam(value = "start", required = false, defaultValue = "0") int start, 36 | /****************** Filter parameters *****************************************************/ 37 | @RequestParam(value = "block", required = false, defaultValue = "-1") long block 38 | ) { 39 | QueryFactory query = new QueryFactory(); 40 | if (block > 0) { 41 | query.setBlockNumGte(block); 42 | } 43 | query.setPageniate(QueryFactory.setPagniateVariable(start, limit, sort)); 44 | List queryResult = mongoTemplate.find(query.getQuery(), 45 | BlockTriggerEntity.class); 46 | Map map = new HashMap(); 47 | map.put("total", queryResult.size()); 48 | map.put("data", queryResult); 49 | return new JSONObject(map); 50 | } 51 | 52 | @RequestMapping(method = RequestMethod.GET, value = "/blocks/{hash}") 53 | public JSONObject getBlockbyHash( 54 | @PathVariable String hash 55 | ) { 56 | 57 | QueryFactory query = new QueryFactory(); 58 | query.setBlockHashEqual(hash); 59 | List queryResult = mongoTemplate.find(query.getQuery(), 60 | BlockTriggerEntity.class); 61 | if (queryResult.size() == 0) { 62 | return null; 63 | } 64 | Map map = new HashMap(); 65 | map.put("block", queryResult.get(0)); 66 | 67 | return new JSONObject(map); 68 | } 69 | 70 | @RequestMapping(method = RequestMethod.GET, value = "/blocks/latestSolidifiedBlockNumber") 71 | public long getLatestSolidifiedBlockNumber() { 72 | QueryFactory query = new QueryFactory(); 73 | query.setPageniate(QueryFactory.setPagniateVariable(0, 1, "-latestSolidifiedBlockNumber")); 74 | List blockTriggerEntityList = mongoTemplate.find(query.getQuery(), 75 | BlockTriggerEntity.class); 76 | if (blockTriggerEntityList.isEmpty()) { 77 | return 0; 78 | } 79 | return blockTriggerEntityList.get(0).getLatestSolidifiedBlockNumber(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/contractlogs/ContractLogTriggerEntity.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.contractlogs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import java.util.List; 5 | import lombok.Getter; 6 | import org.springframework.data.mongodb.core.mapping.Document; 7 | import org.springframework.data.mongodb.core.mapping.Field; 8 | 9 | @Document(collection = "contractlog") 10 | public class ContractLogTriggerEntity { 11 | 12 | @Field(value = "topicList") 13 | @JsonProperty(value = "topicList") 14 | private List topicList; 15 | 16 | @Field(value = "data") 17 | @JsonProperty(value = "data") 18 | private String data; 19 | 20 | @Field(value = "transactionId") 21 | @JsonProperty(value = "transactionId") 22 | @Getter 23 | private String transactionId; 24 | 25 | @Field(value = "contractAddress") 26 | @JsonProperty(value = "contractAddress") 27 | @Getter 28 | private String contractAddress; 29 | 30 | @Field(value = "callerAddress") 31 | @JsonProperty(value = "callerAddress") 32 | @Getter 33 | private String callerAddress; 34 | 35 | @Field(value = "originAddress") 36 | @JsonProperty(value = "originAddress") 37 | @Getter 38 | private String originAddress; 39 | 40 | @Field(value = "creatorAddress") 41 | @JsonProperty(value = "creatorAddress") 42 | @Getter 43 | private String creatorAddress; 44 | 45 | @Field(value = "blockNumber") 46 | @JsonProperty(value = "blockNumber") 47 | @Getter 48 | private Long blockNumber; 49 | 50 | @Field(value = "removed") 51 | @JsonProperty(value = "removed") 52 | @Getter 53 | private String removed; 54 | 55 | @Field(value = "latestSolidifiedBlockNumber") 56 | @JsonProperty(value = "latestSolidifiedBlockNumber") 57 | @Getter 58 | private long latestSolidifiedBlockNumber; 59 | 60 | @Field(value = "timeStamp") 61 | @JsonProperty(value = "timeStamp") 62 | @Getter 63 | protected long timeStamp; 64 | 65 | @Field(value = "triggerName") 66 | @JsonProperty(value = "triggerName") 67 | @Getter 68 | private String triggerName; 69 | 70 | @Field(value = "uniqueId") 71 | @JsonProperty(value = "uniqueId") 72 | @Getter 73 | private String uniqueId; 74 | 75 | @Field(value = "abiString") 76 | @JsonProperty(value = "abiString") 77 | @Getter 78 | private String abiString; 79 | 80 | @Field(value = "rawData") 81 | @JsonProperty(value = "rawData") 82 | @Getter 83 | private LogInfoEntity rawData; 84 | 85 | 86 | public ContractLogTriggerEntity( 87 | List topicList, String data, String transactionId, 88 | String contractAddress, String callerAddress, String originAddress, 89 | String creatorAddress, Long blockNumber, String removed, 90 | long latestSolidifiedBlockNumber, long timeStamp, String triggerName, String uniqueId, 91 | LogInfoEntity rawData, String abiString 92 | ) { 93 | this.topicList = topicList; 94 | this.data = data; 95 | this.transactionId = transactionId; 96 | this.contractAddress = contractAddress; 97 | this.callerAddress = callerAddress; 98 | this.originAddress = originAddress; 99 | this.creatorAddress = creatorAddress; 100 | this.blockNumber = blockNumber; 101 | this.removed = removed; 102 | this.latestSolidifiedBlockNumber = latestSolidifiedBlockNumber; 103 | this.timeStamp = timeStamp; 104 | this.triggerName = triggerName; 105 | this.uniqueId = uniqueId; 106 | this.rawData = rawData; 107 | this.abiString = abiString; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.tron 8 | troneventquery 9 | 1.0.0-SNAPSHOT 10 | jar 11 | 12 | trongeventquery 13 | Demo project for Spring Boot 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-starter-parent 18 | 2.0.4.RELEASE 19 | 20 | 21 | 22 | 23 | UTF-8 24 | UTF-8 25 | 1.8 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-data-mongodb 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-data-rest 36 | 37 | 38 | 39 | 40 | com.alibaba 41 | fastjson 42 | 2.0.16 43 | 44 | 45 | 46 | 47 | org.projectlombok 48 | lombok 49 | 1.18.6 50 | provided 51 | 52 | 53 | 54 | 55 | org.pf4j 56 | pf4j 57 | 2.6.0 58 | 59 | 60 | 61 | 62 | org.apache.commons 63 | commons-lang3 64 | 3.4 65 | 66 | 67 | 68 | 69 | com.madgag.spongycastle 70 | core 71 | 1.58.0.0 72 | 73 | 74 | 75 | 76 | com.madgag.spongycastle 77 | prov 78 | 1.58.0.0 79 | 80 | 81 | 82 | 83 | com.google.protobuf 84 | protobuf-java 85 | 3.16.1 86 | 87 | 88 | 89 | 90 | com.google.guava 91 | guava 92 | [30.0-jre,) 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | org.springframework.boot 101 | spring-boot-maven-plugin 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/TronEventApplication.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery; 2 | 3 | import static org.tron.common.utils.LogConfig.LOG; 4 | import static org.tron.trongeventquery.contractevents.ContractEventController.isRunRePushThread; 5 | 6 | import com.mongodb.MongoClient; 7 | import com.mongodb.MongoClientOptions; 8 | import com.mongodb.MongoCredential; 9 | import com.mongodb.ServerAddress; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import org.apache.catalina.connector.Connector; 13 | import org.springframework.beans.factory.annotation.Value; 14 | import org.springframework.boot.SpringApplication; 15 | import org.springframework.boot.autoconfigure.SpringBootApplication; 16 | import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; 17 | import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; 18 | import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; 19 | import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; 20 | import org.springframework.boot.web.servlet.ServletComponentScan; 21 | import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; 22 | import org.springframework.context.annotation.Bean; 23 | import org.springframework.context.annotation.PropertySource; 24 | import org.springframework.data.mongodb.core.MongoTemplate; 25 | 26 | 27 | @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) 28 | @ServletComponentScan("org.tron.trongeventquery.filter") //Scan Filter 29 | @PropertySource(value = {"file:./config.conf"}, ignoreResourceNotFound = true) 30 | public class TronEventApplication { 31 | 32 | public static void main(String[] args) { 33 | SpringApplication.run(TronEventApplication.class, args); 34 | shutdown(); 35 | } 36 | 37 | @Bean 38 | public MongoTemplate mongoTemplate( 39 | @Value("${mongo.host}")String mongodbIp, @Value("${mongo.dbname}")String mongodbDbName, 40 | @Value("${mongo.connectionsPerHost}")int connectionsPerHost, 41 | @Value("${mongo.threadsAllowedToBlockForConnectionMultiplier}") 42 | int threadsAllowedToBlockForConnectionMultiplier, 43 | @Value("${mongo.port}")int port, @Value("${mongo.username}")String username, 44 | @Value("${mongo.password}")String password 45 | ) { 46 | MongoClientOptions options = MongoClientOptions.builder().connectionsPerHost(connectionsPerHost) 47 | .threadsAllowedToBlockForConnectionMultiplier( 48 | threadsAllowedToBlockForConnectionMultiplier).build(); 49 | String host = mongodbIp; 50 | ServerAddress serverAddress = new ServerAddress(host, port); 51 | List addrs = new ArrayList(); 52 | addrs.add(serverAddress); 53 | MongoCredential credential = MongoCredential.createScramSha1Credential(username, mongodbDbName, 54 | password.toCharArray()); 55 | List credentials = new ArrayList(); 56 | credentials.add(credential); 57 | MongoClient mongo = new MongoClient(addrs, credential, options); 58 | 59 | return new MongoTemplate(mongo, mongodbDbName); 60 | 61 | } 62 | 63 | @Bean 64 | public ConfigurableServletWebServerFactory webServerFactory() { 65 | TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); 66 | factory.addConnectorCustomizers(new TomcatConnectorCustomizer() { 67 | @Override 68 | public void customize(Connector connector) { 69 | connector.setProperty("relaxedQueryChars", "|{}[]"); 70 | } 71 | }); 72 | return factory; 73 | } 74 | 75 | public static void shutdown() { 76 | Runnable stopThread = 77 | () -> isRunRePushThread.set(false); 78 | LOG.info("********register application shutdown hook********"); 79 | Runtime.getRuntime().addShutdownHook(new Thread(stopThread)); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/transfers/TransferController.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.transfers; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.data.mongodb.core.MongoTemplate; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | import org.springframework.web.bind.annotation.RestController; 15 | import org.tron.trongeventquery.query.QueryFactory; 16 | import org.tron.trongeventquery.transactions.TransactionTriggerEntity; 17 | 18 | @RestController 19 | @Component 20 | public class TransferController { 21 | @Autowired(required = false) 22 | MongoTemplate mongoTemplate; 23 | 24 | @RequestMapping(method = RequestMethod.GET, value = "/transfers/total") 25 | public Long totaltransfers() { 26 | QueryFactory query = new QueryFactory(); 27 | query.setTransferType(); 28 | return new Long(mongoTemplate.count(query.getQuery(), TransactionTriggerEntity.class)); 29 | } 30 | 31 | @RequestMapping(method = RequestMethod.GET, value = "/transfers/total/{address}") 32 | public Long addressTotaltransfers( 33 | @PathVariable String address 34 | ) { 35 | QueryFactory query = new QueryFactory(); 36 | query.setTransferType(); 37 | 38 | query.findAllTransferByAddress(address); 39 | return mongoTemplate.count(query.getQuery(), TransactionTriggerEntity.class); 40 | } 41 | 42 | @RequestMapping(method = RequestMethod.GET, value = "/transfers") 43 | public JSONObject getTransfers( 44 | /******************* Page Parameters ****************************************************/ 45 | @RequestParam(value = "limit", required = false, defaultValue = "25") int limit, 46 | @RequestParam(value = "sort", required = false, defaultValue = "-timeStamp") String sort, 47 | @RequestParam(value = "start", required = false, defaultValue = "0") int start, 48 | /****************** Filter parameters *****************************************************/ 49 | @RequestParam(value = "from", required = false, defaultValue = "") String from, 50 | @RequestParam(value = "to", required = false, defaultValue = "") String to, 51 | @RequestParam(value = "token", required = false, defaultValue = "") String token 52 | ) { 53 | QueryFactory query = new QueryFactory(); 54 | query.setTransferType(); 55 | if (from.length() != 0) { 56 | query.setTransactionFromAddr(from); 57 | } 58 | 59 | if (to.length() != 0) { 60 | query.setTransactionToAddr(to); 61 | } 62 | 63 | if (token.length() != 0) { 64 | query.setTransactionToken(token); 65 | } 66 | 67 | query.setPageniate(QueryFactory.setPagniateVariable(start, limit, sort)); 68 | 69 | List queryResult = 70 | mongoTemplate.find(query.getQuery(), TransactionTriggerEntity.class); 71 | Map map = new HashMap(); 72 | map.put("data", queryResult); 73 | map.put("result", queryResult.size()); 74 | 75 | return new JSONObject(map); 76 | } 77 | 78 | @RequestMapping(method = RequestMethod.GET, value = "/transfers/{hash}") 79 | public JSONObject getTrnasferbyHash( 80 | @PathVariable String hash 81 | ) { 82 | QueryFactory query = new QueryFactory(); 83 | query.setTransactionIdEqual(hash); 84 | query.setTransferType(); 85 | List queryResult = mongoTemplate.find(query.getQuery(), 86 | TransactionTriggerEntity.class); 87 | if (queryResult.size() == 0) { 88 | return null; 89 | } 90 | Map map = new HashMap(); 91 | map.put("data", queryResult.get(0)); 92 | return new JSONObject(map); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/EventLogEntity.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery; 2 | 3 | import com.alibaba.fastjson.JSONArray; 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.fasterxml.jackson.annotation.JsonProperty; 6 | import java.io.Serializable; 7 | import org.springframework.data.annotation.Id; 8 | import org.springframework.data.mongodb.core.mapping.Document; 9 | import org.springframework.data.mongodb.core.mapping.Field; 10 | 11 | @Document(collection = "eventLog") 12 | public class EventLogEntity implements Serializable { 13 | 14 | private static final long serialVersionUID = -70777625567836430L; 15 | 16 | @Id 17 | private String id; 18 | 19 | @Field(value = "block_number") 20 | @JsonProperty(value = "block_number") 21 | private long blockNumber; 22 | 23 | @Field(value = "block_timestamp") 24 | @JsonProperty(value = "block_timestamp") 25 | private long blockTimestamp; 26 | 27 | @Field(value = "contract_address") 28 | @JsonProperty(value = "contract_address") 29 | private String contractAddress; 30 | 31 | @Field(value = "event_index") 32 | @JsonProperty(value = "event_index") 33 | private int eventIndex; 34 | 35 | @Field(value = "event_name") 36 | @JsonProperty(value = "event_name") 37 | private String entryName; 38 | 39 | @Field(value = "result") 40 | @JsonProperty(value = "result") 41 | private Object resultJsonArray; 42 | 43 | @Field(value = "result_type") 44 | @JsonProperty(value = "result_type") 45 | private JSONObject resultType; 46 | 47 | @Field(value = "transaction_id") 48 | @JsonProperty(value = "transaction_id") 49 | private String transactionId; 50 | 51 | @Field(value = "resource_Node") 52 | @JsonProperty(value = "resource_Node") 53 | private String resource; 54 | 55 | 56 | 57 | public EventLogEntity(long blockNumber, long blockTimestamp, String contractAddress, 58 | int eventIndex, String entryName, Object resultJsonArray,String transactionId, 59 | JSONObject resultType, String resource 60 | ) { 61 | this.blockNumber = blockNumber; 62 | this.blockTimestamp = blockTimestamp; 63 | this.contractAddress = contractAddress; 64 | this.entryName = entryName; 65 | this.resultJsonArray = resultJsonArray; 66 | this.transactionId = transactionId; 67 | this.resultType = resultType; 68 | this.resource = resource; 69 | this.eventIndex = eventIndex; 70 | 71 | } 72 | 73 | public static long getSerialVersionUID() { 74 | return serialVersionUID; 75 | } 76 | 77 | public long getBlockNumber() { 78 | return blockNumber; 79 | } 80 | 81 | public void setBlockNumber(long blockNumber) { 82 | this.blockNumber = blockNumber; 83 | } 84 | 85 | public long getBlockTimestamp() { 86 | return blockTimestamp; 87 | } 88 | 89 | public void setBlockTimestamp(long blockTimestamp) { 90 | this.blockTimestamp = blockTimestamp; 91 | } 92 | 93 | public String getContractAddress() { 94 | return contractAddress; 95 | } 96 | 97 | public void setContractAddress(String contractAddress) { 98 | this.contractAddress = contractAddress; 99 | } 100 | 101 | public String getEntryName() { 102 | return entryName; 103 | } 104 | 105 | public void setEntryName(String entryName) { 106 | this.entryName = entryName; 107 | } 108 | 109 | public Object getResultJsonArray() { 110 | return resultJsonArray; 111 | } 112 | 113 | public void setResultJsonArray(Object resultJsonArray) { 114 | this.resultJsonArray = resultJsonArray; 115 | } 116 | 117 | public String getTransactionId() { 118 | return transactionId; 119 | } 120 | 121 | public void setTransactionId(String transactionId) { 122 | this.transactionId = transactionId; 123 | } 124 | 125 | public void setResultType(JSONObject res) { 126 | this.resultType = res; 127 | } 128 | 129 | public JSONObject getResultType() { 130 | return this.resultType; 131 | } 132 | 133 | public void setResource(String resource) { 134 | this.resource = resource; 135 | } 136 | 137 | public String getResource() { 138 | return this.resource; 139 | } 140 | 141 | public void setEventIndex(int idx) { 142 | this.eventIndex = idx; 143 | } 144 | 145 | public int getEventIndex() { 146 | return this.eventIndex; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/utils/ByteArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.utils; 20 | 21 | import static org.tron.common.utils.LogConfig.LOG; 22 | 23 | import com.google.common.primitives.Ints; 24 | import com.google.common.primitives.Longs; 25 | import java.io.ByteArrayOutputStream; 26 | import java.io.IOException; 27 | import java.io.ObjectOutputStream; 28 | import java.math.BigInteger; 29 | import lombok.extern.slf4j.Slf4j; 30 | import org.apache.commons.lang3.ArrayUtils; 31 | import org.apache.commons.lang3.StringUtils; 32 | import org.spongycastle.util.encoders.Hex; 33 | 34 | public class ByteArray { 35 | 36 | public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; 37 | 38 | public static String toHexString(byte[] data) { 39 | return data == null ? "" : Hex.toHexString(data); 40 | } 41 | 42 | /** 43 | * get bytes data from hex string data. 44 | */ 45 | public static byte[] fromHexString(String data) { 46 | if (data == null) { 47 | return EMPTY_BYTE_ARRAY; 48 | } 49 | if (data.startsWith("0x")) { 50 | data = data.substring(2); 51 | } 52 | if (data.length() % 2 != 0) { 53 | data = "0" + data; 54 | } 55 | return Hex.decode(data); 56 | } 57 | 58 | /** 59 | * get long data from bytes data. 60 | */ 61 | public static long toLong(byte[] b) { 62 | return ArrayUtils.isEmpty(b) ? 0 : new BigInteger(1, b).longValue(); 63 | } 64 | 65 | /** 66 | * get int data from bytes data. 67 | */ 68 | public static int toInt(byte[] b) { 69 | return ArrayUtils.isEmpty(b) ? 0 : new BigInteger(1, b).intValue(); 70 | } 71 | 72 | /** 73 | * get bytes data from string data. 74 | */ 75 | public static byte[] fromString(String s) { 76 | return StringUtils.isBlank(s) ? null : s.getBytes(); 77 | } 78 | 79 | /** 80 | * get string data from bytes data. 81 | */ 82 | public static String toStr(byte[] b) { 83 | return ArrayUtils.isEmpty(b) ? null : new String(b); 84 | } 85 | 86 | public static byte[] fromLong(long val) { 87 | return Longs.toByteArray(val); 88 | } 89 | 90 | public static byte[] fromInt(int val) { 91 | return Ints.toByteArray(val); 92 | } 93 | 94 | /** 95 | * get bytes data from object data. 96 | */ 97 | public static byte[] fromObject(Object obj) { 98 | byte[] bytes = null; 99 | try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 100 | ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)) { 101 | objectOutputStream.writeObject(obj); 102 | objectOutputStream.flush(); 103 | bytes = byteArrayOutputStream.toByteArray(); 104 | } catch (IOException e) { 105 | LOG.error("objectToByteArray failed: " + e.getMessage(), e); 106 | } 107 | return bytes; 108 | } 109 | 110 | /** 111 | * Generate a subarray of a given byte array. 112 | * 113 | * @param input the input byte array 114 | * @param start the start index 115 | * @param end the end index 116 | * @return a subarray of input, ranging from start (inclusively) to end 117 | * (exclusively) 118 | */ 119 | public static byte[] subArray(byte[] input, int start, int end) { 120 | byte[] result = new byte[end - start]; 121 | System.arraycopy(input, start, result, 0, end - start); 122 | return result; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/contractevents/ContractEventTriggerEntity.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.contractevents; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import java.util.Map; 5 | import lombok.Getter; 6 | import org.springframework.data.annotation.Id; 7 | import org.springframework.data.mongodb.core.mapping.Document; 8 | import org.springframework.data.mongodb.core.mapping.Field; 9 | import org.tron.trongeventquery.contractlogs.LogInfoEntity; 10 | 11 | @Document(collection = "contractevent") 12 | public class ContractEventTriggerEntity { 13 | 14 | private static final long serialVersionUID = -70777625567836430L; 15 | 16 | @Id 17 | private String id; 18 | 19 | @Field(value = "eventSignature") 20 | @JsonProperty(value = "eventSignature") 21 | @Getter 22 | private String eventSignature; 23 | 24 | @Field(value = "topicMap") 25 | @JsonProperty(value = "topicMap") 26 | @Getter 27 | private Map topicMap; 28 | 29 | @Field(value = "dataMap") 30 | @JsonProperty(value = "dataMap") 31 | @Getter 32 | private Map dataMap; 33 | 34 | @Field(value = "transactionId") 35 | @JsonProperty(value = "transactionId") 36 | @Getter 37 | private String transactionId; 38 | 39 | @Field(value = "contractAddress") 40 | @JsonProperty(value = "contractAddress") 41 | @Getter 42 | private String contractAddress; 43 | 44 | @Field(value = "callerAddress") 45 | @JsonProperty(value = "callerAddress") 46 | @Getter 47 | private String callerAddress; 48 | 49 | @Field(value = "originAddress") 50 | @JsonProperty(value = "originAddress") 51 | @Getter 52 | private String originAddress; 53 | 54 | @Field(value = "creatorAddress") 55 | @JsonProperty(value = "creatorAddress") 56 | @Getter 57 | private String creatorAddress; 58 | 59 | @Field(value = "blockNumber") 60 | @JsonProperty(value = "blockNumber") 61 | @Getter 62 | private Long blockNumber; 63 | 64 | @Field(value = "removed") 65 | @JsonProperty(value = "removed") 66 | @Getter 67 | private String removed; 68 | 69 | @Field(value = "latestSolidifiedBlockNumber") 70 | @JsonProperty(value = "latestSolidifiedBlockNumber") 71 | @Getter 72 | private long latestSolidifiedBlockNumber; 73 | 74 | @Field(value = "timeStamp") 75 | @JsonProperty(value = "timeStamp") 76 | @Getter 77 | protected long timeStamp; 78 | 79 | @Field(value = "triggerName") 80 | @JsonProperty(value = "triggerName") 81 | @Getter 82 | private String triggerName; 83 | 84 | @Field(value = "eventSignatureFull") 85 | @JsonProperty(value = "eventSignatureFull") 86 | @Getter 87 | private String eventSignatureFull; 88 | 89 | @Field(value = "eventName") 90 | @JsonProperty(value = "eventName") 91 | @Getter 92 | private String eventName; 93 | 94 | @Field(value = "uniqueId") 95 | @JsonProperty(value = "uniqueId") 96 | @Getter 97 | private String uniqueId; 98 | 99 | @Field(value = "abiString") 100 | @JsonProperty(value = "abiString") 101 | @Getter 102 | private String abiString; 103 | 104 | @Field(value = "rawData") 105 | @JsonProperty(value = "rawData") 106 | @Getter 107 | private LogInfoEntity rawData; 108 | 109 | public ContractEventTriggerEntity(String eventSignature, Map topicMap, 110 | long latestSolidifiedBlockNumber, Map dataMap, 111 | String transactionId, String contractAddress, 112 | String callerAddress, String originAddress, 113 | String creatorAddress, Long blockNumber, String removed, long timeStamp, String triggerName, 114 | String eventSignatureFull, String eventName, String uniqueId, 115 | LogInfoEntity rawData, String abiString) { 116 | this.eventSignature = eventSignature; 117 | this.topicMap = topicMap; 118 | this.dataMap = dataMap; 119 | this.transactionId = transactionId; 120 | this.contractAddress = contractAddress; 121 | this.callerAddress = callerAddress; 122 | this.originAddress = originAddress; 123 | this.creatorAddress = creatorAddress; 124 | this.blockNumber = blockNumber; 125 | this.removed = removed; 126 | this.timeStamp = timeStamp; 127 | this.triggerName = triggerName; 128 | this.eventSignatureFull = eventSignatureFull; 129 | this.eventName = eventName; 130 | this.latestSolidifiedBlockNumber = latestSolidifiedBlockNumber; 131 | this.uniqueId = uniqueId; 132 | this.rawData = rawData; 133 | this.abiString = abiString; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/query/ContractEventParserJson.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.query; 2 | 3 | 4 | import static org.tron.common.utils.LogConfig.LOG; 5 | 6 | import com.alibaba.fastjson.JSONArray; 7 | import com.alibaba.fastjson.JSONObject; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.apache.commons.lang3.ArrayUtils; 13 | import org.pf4j.util.StringUtils; 14 | import org.spongycastle.util.encoders.Hex; 15 | 16 | public class ContractEventParserJson extends ContractEventParser { 17 | 18 | /** 19 | * parse Event Topic into map NOTICE: In solidity, Indexed Dynamic types's topic is just 20 | * EVENT_INDEXED_ARGS 21 | */ 22 | public static Map parseTopics(List topicList, JSONObject entry) { 23 | Map map = new HashMap<>(); 24 | if (topicList == null || topicList.isEmpty()) { 25 | return map; 26 | } 27 | 28 | // the first is the signature. 29 | int index = 1; 30 | JSONArray inputs = entry.getJSONArray("inputs"); 31 | 32 | // in case indexed topics doesn't match 33 | if (topicsMatched(topicList, entry)) { 34 | if (inputs != null) { 35 | for (int i = 0; i < inputs.size(); ++i) { 36 | JSONObject param = inputs.getJSONObject(i); 37 | Boolean indexed = param.getBoolean("indexed"); 38 | if (indexed == null || !indexed) { 39 | continue; 40 | } 41 | if (index >= topicList.size()) { 42 | break; 43 | } 44 | String str = parseTopic(topicList.get(index++), param.getString("type")); 45 | if (StringUtils.isNotNullOrEmpty(param.getString("name"))) { 46 | map.put(param.getString("name"), str); 47 | } 48 | map.put("" + i, str); 49 | } 50 | } 51 | } else { 52 | for (int i = 1; i < topicList.size(); ++i) { 53 | map.put("" + (i - 1), Hex.toHexString(topicList.get(i))); 54 | } 55 | } 56 | return map; 57 | } 58 | 59 | /** 60 | * parse Event Data into map If parser failed, then return {"0", 61 | * Hex.toHexString(data)} Only support basic solidity type, String, Bytes. Fixed Array or dynamic 62 | * Array are not support yet (then return {"0": Hex.toHexString(data)}). 63 | */ 64 | public static Map parseEventData(byte[] data, 65 | List topicList, JSONObject entry) { 66 | Map map = new HashMap<>(); 67 | if (ArrayUtils.isEmpty(data)) { 68 | return map; 69 | } 70 | // in case indexed topics doesn't match 71 | if (!topicsMatched(topicList, entry)) { 72 | map.put("" + (topicList.size() - 1), Hex.toHexString(data)); 73 | return map; 74 | } 75 | 76 | // the first is the signature. 77 | JSONArray inputs = entry.getJSONArray("inputs"); 78 | Integer startIndex = 0; 79 | 80 | try { 81 | // this one starts from the first position. 82 | int index = 0; 83 | if (inputs != null) { 84 | for (Integer i = 0; i < inputs.size(); ++i) { 85 | JSONObject param = inputs.getJSONObject(i); 86 | Boolean indexed = param.getBoolean("indexed"); 87 | if (indexed != null && indexed) { 88 | continue; 89 | } 90 | 91 | if (startIndex == 0) { 92 | startIndex = i; 93 | } 94 | 95 | String str = parseDataBytes(data, param.getString("type"), index++); 96 | if (StringUtils.isNotNullOrEmpty(param.getString("name"))) { 97 | map.put(param.getString("name"), str); 98 | } 99 | map.put("" + i, str); 100 | 101 | } 102 | } else { 103 | map.put("0", Hex.toHexString(data)); 104 | } 105 | } catch (UnsupportedOperationException e) { 106 | LOG.debug("UnsupportedOperationException", e); 107 | map.clear(); 108 | map.put(startIndex.toString(), Hex.toHexString(data)); 109 | } 110 | return map; 111 | } 112 | 113 | private static boolean topicsMatched(List topicList, JSONObject entry) { 114 | if (topicList == null || topicList.isEmpty()) { 115 | return true; 116 | } 117 | int inputSize = 1; 118 | JSONArray inputs = entry.getJSONArray("inputs"); 119 | if (inputs != null) { 120 | for (int i = 0; i < inputs.size(); i++) { 121 | JSONObject param = inputs.getJSONObject(i); 122 | Boolean indexed = param.getBoolean("indexed"); 123 | if (indexed != null && indexed) { 124 | inputSize++; 125 | } 126 | } 127 | } 128 | return inputSize == topicList.size(); 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/utils/Base58.java: -------------------------------------------------------------------------------- 1 | package org.tron.common.utils; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.math.BigInteger; 5 | 6 | public class Base58 { 7 | 8 | public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" 9 | .toCharArray(); 10 | private static final int[] INDEXES = new int[128]; 11 | 12 | static { 13 | for (int i = 0; i < INDEXES.length; i++) { 14 | INDEXES[i] = -1; 15 | } 16 | for (int i = 0; i < ALPHABET.length; i++) { 17 | INDEXES[ALPHABET[i]] = i; 18 | } 19 | } 20 | 21 | /** 22 | * Encodes the given bytes in base58. No checksum is appended. 23 | */ 24 | public static String encode(byte[] input) { 25 | if (input.length == 0) { 26 | return ""; 27 | } 28 | input = copyOfRange(input, 0, input.length); 29 | // Count leading zeroes. 30 | int zeroCount = 0; 31 | while (zeroCount < input.length && input[zeroCount] == 0) { 32 | ++zeroCount; 33 | } 34 | // The actual encoding. 35 | byte[] temp = new byte[input.length * 2]; 36 | int j = temp.length; 37 | 38 | int startAt = zeroCount; 39 | while (startAt < input.length) { 40 | byte mod = divmod58(input, startAt); 41 | if (input[startAt] == 0) { 42 | ++startAt; 43 | } 44 | temp[--j] = (byte) ALPHABET[mod]; 45 | } 46 | 47 | // Strip extra '1' if there are some after decoding. 48 | while (j < temp.length && temp[j] == ALPHABET[0]) { 49 | ++j; 50 | } 51 | // Add as many leading '1' as there were leading zeros. 52 | while (--zeroCount >= 0) { 53 | temp[--j] = (byte) ALPHABET[0]; 54 | } 55 | 56 | byte[] output = copyOfRange(temp, j, temp.length); 57 | try { 58 | return new String(output, "US-ASCII"); 59 | } catch (UnsupportedEncodingException e) { 60 | throw new RuntimeException(e); // Cannot happen. 61 | } 62 | } 63 | 64 | public static byte[] decode(String input) throws IllegalArgumentException { 65 | if (input.length() == 0) { 66 | return new byte[0]; 67 | } 68 | byte[] input58 = new byte[input.length()]; 69 | // Transform the String to a base58 byte sequence 70 | for (int i = 0; i < input.length(); ++i) { 71 | char c = input.charAt(i); 72 | 73 | int digit58 = -1; 74 | if (c >= 0 && c < 128) { 75 | digit58 = INDEXES[c]; 76 | } 77 | if (digit58 < 0) { 78 | throw new IllegalArgumentException("Illegal character " + c + " at " + i); 79 | } 80 | 81 | input58[i] = (byte) digit58; 82 | } 83 | // Count leading zeroes 84 | int zeroCount = 0; 85 | while (zeroCount < input58.length && input58[zeroCount] == 0) { 86 | ++zeroCount; 87 | } 88 | // The encoding 89 | byte[] temp = new byte[input.length()]; 90 | int j = temp.length; 91 | 92 | int startAt = zeroCount; 93 | while (startAt < input58.length) { 94 | byte mod = divmod256(input58, startAt); 95 | if (input58[startAt] == 0) { 96 | ++startAt; 97 | } 98 | 99 | temp[--j] = mod; 100 | } 101 | // Do no add extra leading zeroes, move j to first non null byte. 102 | while (j < temp.length && temp[j] == 0) { 103 | ++j; 104 | } 105 | 106 | return copyOfRange(temp, j - zeroCount, temp.length); 107 | } 108 | 109 | public static BigInteger decodeToBigInteger(String input) throws IllegalArgumentException { 110 | return new BigInteger(1, decode(input)); 111 | } 112 | 113 | // 114 | // number -> number / 58, returns number % 58 115 | // 116 | private static byte divmod58(byte[] number, int startAt) { 117 | int remainder = 0; 118 | for (int i = startAt; i < number.length; i++) { 119 | int digit256 = (int) number[i] & 0xFF; 120 | int temp = remainder * 256 + digit256; 121 | 122 | number[i] = (byte) (temp / 58); 123 | 124 | remainder = temp % 58; 125 | } 126 | 127 | return (byte) remainder; 128 | } 129 | 130 | // 131 | // number -> number / 256, returns number % 256 132 | // 133 | private static byte divmod256(byte[] number58, int startAt) { 134 | int remainder = 0; 135 | for (int i = startAt; i < number58.length; i++) { 136 | int digit58 = (int) number58[i] & 0xFF; 137 | int temp = remainder * 58 + digit58; 138 | 139 | number58[i] = (byte) (temp / 256); 140 | 141 | remainder = temp % 256; 142 | } 143 | 144 | return (byte) remainder; 145 | } 146 | 147 | private static byte[] copyOfRange(byte[] source, int from, int to) { 148 | byte[] range = new byte[to - from]; 149 | System.arraycopy(source, from, range, 0, range.length); 150 | 151 | return range; 152 | } 153 | 154 | } -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/contractlogs/ContractWithAbiController.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.contractlogs; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.mongodb.core.MongoTemplate; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RequestMethod; 14 | import org.springframework.web.bind.annotation.RequestParam; 15 | import org.springframework.web.bind.annotation.RestController; 16 | import org.tron.trongeventquery.contractevents.ContractEventTriggerEntity; 17 | import org.tron.trongeventquery.query.QueryFactory; 18 | 19 | @RestController 20 | public class ContractWithAbiController { 21 | 22 | @Autowired 23 | MongoTemplate mongoTemplate; 24 | 25 | @RequestMapping(method = RequestMethod.POST, 26 | value = "/contract/contractAddress/{contractAddress}") 27 | public JSONObject findByContractAddressAndEntryName( 28 | @PathVariable String contractAddress, 29 | @RequestParam(value = "since", required = false, defaultValue = "0") long timestamp, 30 | @RequestParam(value = "block", required = false, defaultValue = "-1") long blocknum, 31 | @RequestParam(value = "limit", required = false, defaultValue = "25") int limit, 32 | @RequestParam(value = "sort", required = false, defaultValue = "-timeStamp") String sort, 33 | @RequestParam(value = "start", required = false, defaultValue = "0") int start, 34 | @RequestParam(value = "eventName", required = false, defaultValue = "") String eventName, 35 | @RequestBody Map hmap 36 | ) { 37 | 38 | QueryFactory query = new QueryFactory(); 39 | query.setTimestampGreaterEqual(timestamp); 40 | if (blocknum != -1) { 41 | query.setBlockNumGte(blocknum); 42 | } 43 | query.setContractAddress(contractAddress); 44 | 45 | if (eventName.length() != 0) { 46 | query.setEventName(eventName); 47 | } 48 | query.setPageniate(QueryFactory.setPagniateVariable(start, limit, sort)); 49 | 50 | return getContractTrigger(hmap, query); 51 | } 52 | 53 | @RequestMapping(method = RequestMethod.POST, value = "/contract/uniqueId/{uniqueId}") 54 | public JSONObject getEvent( 55 | @PathVariable(value = "uniqueId", required = false) String uniqueId, 56 | @RequestBody Map hmap 57 | ) { 58 | 59 | QueryFactory query = new QueryFactory(); 60 | query.setUniqueIdEqual(uniqueId); 61 | 62 | return getContractTrigger(hmap, query); 63 | } 64 | 65 | @RequestMapping(method = RequestMethod.POST, value = "/contract/transaction/{transactionId}") 66 | public JSONObject findOneByTransaction(@PathVariable String transactionId, 67 | @RequestBody Map hmap) { 68 | QueryFactory query = new QueryFactory(); 69 | query.setTransactionIdEqual(transactionId); 70 | 71 | return getContractTrigger(hmap, query); 72 | } 73 | 74 | private JSONObject getContractTrigger(Map hmap, QueryFactory query) { 75 | 76 | List contractLogTriggerList = mongoTemplate.find(query.getQuery(), 77 | ContractLogTriggerEntity.class); 78 | List contractEventTriggerList = mongoTemplate.find(query.getQuery(), 79 | ContractEventTriggerEntity.class); 80 | Map map = new HashMap(); 81 | 82 | if (contractLogTriggerList.isEmpty() && contractEventTriggerList.isEmpty()) { 83 | return new JSONObject(map); 84 | } 85 | 86 | if (!hmap.containsKey("abi") || hmap.get("abi").length() == 0) { 87 | return new JSONObject(map); 88 | } 89 | 90 | String abi = hmap.get("abi"); 91 | List resLogList = new ArrayList<>(); 92 | List resEventList = new ArrayList<>(); 93 | if (abi.length() != 0) { 94 | resEventList.addAll(QueryFactory.parseEventWithAbiByLog(contractLogTriggerList, abi)); 95 | resLogList.addAll(QueryFactory.parseLogWithAbiByLog(contractLogTriggerList, abi)); 96 | resEventList.addAll(QueryFactory.parseEventWithAbiByEvent(contractEventTriggerList, abi)); 97 | resLogList.addAll(QueryFactory.parseLogWithAbiByEvent(contractEventTriggerList, abi)); 98 | } 99 | 100 | if (resLogList != null && !resLogList.isEmpty()) { 101 | map.put("contractLogTriggers", resLogList); 102 | } 103 | 104 | if (resEventList != null && !resEventList.isEmpty()) { 105 | map.put("contractEventTriggers", resEventList); 106 | } 107 | 108 | return new JSONObject(map); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/contractlogs/ContractLogController.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.contractlogs; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.data.mongodb.core.MongoTemplate; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.RestController; 14 | import org.tron.trongeventquery.contractevents.ContractEventTriggerEntity; 15 | import org.tron.trongeventquery.query.QueryFactory; 16 | 17 | @RestController 18 | public class ContractLogController { 19 | @Autowired 20 | MongoTemplate mongoTemplate; 21 | 22 | @RequestMapping(method = RequestMethod.GET, value = "/contractlogs") 23 | public JSONObject getContractLogs( 24 | /******************* Page Parameters ****************************************************/ 25 | @RequestParam(value = "limit", required = false, defaultValue = "25") int limit, 26 | @RequestParam(value = "sort", required = false, defaultValue = "-timeStamp") String sort, 27 | @RequestParam(value = "start", required = false, defaultValue = "0") int start, 28 | /****************** Filter parameters *****************************************************/ 29 | @RequestParam(value = "block", required = false, defaultValue = "-1") long block 30 | ) { 31 | QueryFactory query = new QueryFactory(); 32 | if (block > 0) { 33 | query.setBlockNumGte(block); 34 | } 35 | query.setPageniate(QueryFactory.setPagniateVariable(start, limit, sort)); 36 | List queryResult = mongoTemplate.find(query.getQuery(), 37 | ContractLogTriggerEntity.class); 38 | 39 | Map map = new HashMap(); 40 | map.put("total", queryResult.size()); 41 | map.put("data", queryResult); 42 | return new JSONObject(map); 43 | } 44 | 45 | @RequestMapping(method = RequestMethod.GET, value = "/contractlogs/transaction/{transactionId}") 46 | public List findOneByTransaction(@PathVariable String transactionId) { 47 | QueryFactory query = new QueryFactory(); 48 | query.setTransactionIdEqual(transactionId); 49 | List queryResult = mongoTemplate.find(query.getQuery(), 50 | ContractLogTriggerEntity.class); 51 | return queryResult; 52 | } 53 | 54 | @RequestMapping(method = RequestMethod.GET, 55 | value = "/contractlogs/contract/{contractAddress}") 56 | public List findByContractAddressAndEntryName( 57 | @PathVariable String contractAddress, 58 | @RequestParam(value = "since", required = false, defaultValue = "0") long timestamp, 59 | @RequestParam(value = "block", required = false, defaultValue = "-1") long blocknum, 60 | @RequestParam(value = "limit", required = false, defaultValue = "25") int limit, 61 | @RequestParam(value = "sort", required = false, defaultValue = "-timeStamp") String sort, 62 | @RequestParam(value = "start", required = false, defaultValue = "0") int start, 63 | @RequestParam(value = "eventName", required = false, defaultValue = "") String eventName 64 | ) { 65 | 66 | QueryFactory query = new QueryFactory(); 67 | query.setTimestampGreaterEqual(timestamp); 68 | if (blocknum != -1) { 69 | query.setBlockNumGte(blocknum); 70 | } 71 | query.setContractAddress(contractAddress); 72 | 73 | if (eventName.length() != 0) { 74 | query.setEventName(eventName); 75 | } 76 | query.setPageniate(QueryFactory.setPagniateVariable(start, limit, sort)); 77 | 78 | List result = mongoTemplate.find(query.getQuery(), 79 | ContractLogTriggerEntity.class); 80 | return result; 81 | } 82 | 83 | @RequestMapping(method = RequestMethod.GET, value = "/contractlogs/uniqueId/{uniqueId}") 84 | public ContractLogTriggerEntity getEvent( 85 | @PathVariable(value = "uniqueId", required = false) String uniqueId 86 | ) { 87 | 88 | QueryFactory query = new QueryFactory(); 89 | query.setUniqueIdEqual(uniqueId); 90 | 91 | List queryResult = mongoTemplate.find(query.getQuery(), 92 | ContractLogTriggerEntity.class); 93 | 94 | if (queryResult.size() == 0) { 95 | return null; 96 | } 97 | return queryResult.get(0); 98 | } 99 | 100 | @RequestMapping(method = RequestMethod.GET, value = "/contractlogs/total") 101 | public Long totalContractLog() { 102 | QueryFactory query = new QueryFactory(); 103 | long total = mongoTemplate.count(query.getQuery(), 104 | ContractLogTriggerEntity.class); 105 | 106 | return total; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/query/ContractEventParser.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.query; 2 | 3 | 4 | import static org.tron.common.utils.LogConfig.LOG; 5 | 6 | import java.math.BigInteger; 7 | import java.util.regex.Pattern; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.apache.commons.lang3.ArrayUtils; 10 | import org.pf4j.util.StringUtils; 11 | import org.spongycastle.crypto.OutputLengthException; 12 | import org.spongycastle.util.Arrays; 13 | import org.spongycastle.util.encoders.Hex; 14 | import org.tron.common.runtime.utils.MUtil; 15 | import org.tron.common.runtime.vm.DataWord; 16 | import org.tron.core.Wallet; 17 | 18 | 19 | public class ContractEventParser { 20 | 21 | private static final int DATAWORD_UNIT_SIZE = 32; 22 | 23 | private enum Type { 24 | UNKNOWN, 25 | INT_NUMBER, 26 | BOOL, 27 | FLOAT_NUMBER, 28 | FIXED_BYTES, 29 | ADDRESS, 30 | STRING, 31 | BYTES, 32 | } 33 | 34 | protected static String parseDataBytes(byte[] data, String typeStr, int index) { 35 | try { 36 | byte[] startBytes = subBytes(data, index * DATAWORD_UNIT_SIZE, DATAWORD_UNIT_SIZE); 37 | Type type = basicType(typeStr); 38 | 39 | if (type == Type.INT_NUMBER) { 40 | return new BigInteger(startBytes).toString(); 41 | } else if (type == Type.BOOL) { 42 | return String.valueOf(!DataWord.isZero(startBytes)); 43 | } else if (type == Type.FIXED_BYTES) { 44 | return Hex.toHexString(startBytes); 45 | } else if (type == Type.ADDRESS) { 46 | byte[] last20Bytes = Arrays.copyOfRange(startBytes, 12, startBytes.length); 47 | return Wallet.encode58Check(MUtil.convertToTronAddress(last20Bytes)); 48 | } else if (type == Type.STRING || type == Type.BYTES) { 49 | int start = intValueExact(startBytes); 50 | byte[] lengthBytes = subBytes(data, start, DATAWORD_UNIT_SIZE); 51 | // this length is byte count. no need X 32 52 | int length = intValueExact(lengthBytes); 53 | byte[] realBytes = 54 | length > 0 ? subBytes(data, start + DATAWORD_UNIT_SIZE, length) : new byte[0]; 55 | return type == Type.STRING ? new String(realBytes) : Hex.toHexString(realBytes); 56 | } 57 | } catch (OutputLengthException | ArithmeticException e) { 58 | LOG.debug("parseDataBytes ", e); 59 | } 60 | throw new UnsupportedOperationException("unsupported type:" + typeStr); 61 | } 62 | 63 | // don't support these type yet : bytes32[10][10] OR bytes32[][10] 64 | protected static Type basicType(String type) { 65 | if (!Pattern.matches("^.*\\[\\d*\\]$", type)) { 66 | // ignore not valide type such as "int92", "bytes33", these types will be compiled failed. 67 | if (type.startsWith("int") || type.startsWith("uint") || type.startsWith("trcToken")) { 68 | return Type.INT_NUMBER; 69 | } else if ("bool".equals(type)) { 70 | return Type.BOOL; 71 | } else if ("address".equals(type)) { 72 | return Type.ADDRESS; 73 | } else if (Pattern.matches("^bytes\\d+$", type)) { 74 | return Type.FIXED_BYTES; 75 | } else if ("string".equals(type)) { 76 | return Type.STRING; 77 | } else if ("bytes".equals(type)) { 78 | return Type.BYTES; 79 | } 80 | } 81 | return Type.UNKNOWN; 82 | } 83 | 84 | protected static Integer intValueExact(byte[] data) { 85 | return new BigInteger(data).intValueExact(); 86 | } 87 | 88 | protected static byte[] subBytes(byte[] src, int start, int length) { 89 | if (ArrayUtils.isEmpty(src) || start >= src.length || length < 0) { 90 | throw new OutputLengthException("data start:" + start + ", length:" + length); 91 | } 92 | byte[] dst = new byte[length]; 93 | System.arraycopy(src, start, dst, 0, Math.min(length, src.length - start)); 94 | return dst; 95 | } 96 | 97 | /** 98 | * support: uint (m ∈ [8, 256], m % 8 == 0), int (m ∈ [8, 256], m % 8 == 0) uint (solidity 99 | * abi will auto convert to uint256) int (solidity abi will auto convert to int256) bool 100 | * 101 | * otherwise, returns hexString 102 | * 103 | * This is only for decode Topic. Since Topic and Data use different encode methods when deal 104 | * dynamic length types, such as bytes and string. 105 | */ 106 | protected static String parseTopic(byte[] bytes, String typeStr) { 107 | if (ArrayUtils.isEmpty(bytes) || StringUtils.isNullOrEmpty(typeStr)) { 108 | return ""; 109 | } 110 | Type type = basicType(typeStr); 111 | if (type == Type.INT_NUMBER) { 112 | return DataWord.bigIntValue(bytes); 113 | } else if (type == Type.BOOL) { 114 | return String.valueOf(!DataWord.isZero(bytes)); 115 | } else if (type == Type.ADDRESS) { 116 | byte[] last20Bytes = Arrays.copyOfRange(bytes, 12, bytes.length); 117 | return Wallet.encode58Check(MUtil.convertToTronAddress(last20Bytes)); 118 | } 119 | return Hex.toHexString(bytes); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/runtime/vm/DataWord.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | package org.tron.common.runtime.vm; 19 | 20 | import com.fasterxml.jackson.annotation.JsonValue; 21 | import java.math.BigInteger; 22 | import java.nio.ByteBuffer; 23 | import org.spongycastle.util.Arrays; 24 | import org.spongycastle.util.encoders.Hex; 25 | import org.tron.common.utils.ByteUtil; 26 | 27 | /** 28 | * DataWord is the 32-byte array representation of a 256-bit number Calculations can be done on this 29 | * word with other DataWords 30 | * 31 | * @author Roman Mandeleil 32 | * @since 01.06.2014 33 | */ 34 | public class DataWord implements Comparable { 35 | 36 | /* Maximum value of the DataWord */ 37 | public static final int DATAWORD_UNIT_SIZE = 32; 38 | public static final BigInteger _2_256 = BigInteger.valueOf(2).pow(256); 39 | public static final BigInteger MAX_VALUE = _2_256.subtract(BigInteger.ONE); 40 | public static final DataWord ZERO = new DataWord( 41 | new byte[32]); // don't push it in to the stack 42 | public static final DataWord ZERO_EMPTY_ARRAY = new DataWord( 43 | new byte[0]); // don't push it in to the stack 44 | 45 | private byte[] data = new byte[32]; 46 | 47 | public DataWord() { 48 | } 49 | 50 | public DataWord(int num) { 51 | this(ByteBuffer.allocate(4).putInt(num)); 52 | } 53 | 54 | public DataWord(long num) { 55 | this(ByteBuffer.allocate(8).putLong(num)); 56 | } 57 | 58 | private DataWord(ByteBuffer buffer) { 59 | final ByteBuffer targetByteBuffer = ByteBuffer.allocate(32); 60 | final byte[] array = buffer.array(); 61 | System.arraycopy(array, 0, targetByteBuffer.array(), 32 - array.length, array.length); 62 | this.data = targetByteBuffer.array(); 63 | } 64 | 65 | public DataWord(String data) { 66 | this(Hex.decode(data)); 67 | } 68 | 69 | public DataWord(byte[] data) { 70 | if (data == null) { 71 | this.data = ByteUtil.EMPTY_BYTE_ARRAY; 72 | } else if (data.length == 32) { 73 | this.data = data; 74 | } else if (data.length <= 32) { 75 | System.arraycopy(data, 0, this.data, 32 - data.length, data.length); 76 | } else { 77 | throw new RuntimeException("Data word can't exceed 32 bytes: " + data); 78 | } 79 | } 80 | 81 | public byte[] getData() { 82 | return data; 83 | } 84 | 85 | /** 86 | * be careful, this one will not throw Exception when data.length > DATAWORD_UNIT_SIZE 87 | */ 88 | public byte[] getClonedData() { 89 | byte[] ret = ByteUtil.EMPTY_BYTE_ARRAY; 90 | if (data != null) { 91 | ret = new byte[DATAWORD_UNIT_SIZE]; 92 | int dataSize = Math.min(data.length, DATAWORD_UNIT_SIZE); 93 | System.arraycopy(data, 0, ret, 0, dataSize); 94 | } 95 | return ret; 96 | } 97 | 98 | public BigInteger value() { 99 | return new BigInteger(1, data); 100 | } 101 | 102 | public static String bigIntValue(byte[] data) { 103 | return new BigInteger(data).toString(); 104 | } 105 | 106 | public static boolean isZero(byte[] data) { 107 | for (byte tmp : data) { 108 | if (tmp != 0) { 109 | return false; 110 | } 111 | } 112 | return true; 113 | } 114 | 115 | @JsonValue 116 | @Override 117 | public String toString() { 118 | return Hex.toHexString(data); 119 | } 120 | 121 | public DataWord clone() { 122 | return new DataWord(Arrays.clone(data)); 123 | } 124 | 125 | @Override 126 | public boolean equals(Object o) { 127 | if (this == o) { 128 | return true; 129 | } 130 | if (o == null || getClass() != o.getClass()) { 131 | return false; 132 | } 133 | 134 | DataWord dataWord = (DataWord) o; 135 | 136 | return java.util.Arrays.equals(data, dataWord.data); 137 | 138 | } 139 | 140 | @Override 141 | public int hashCode() { 142 | return java.util.Arrays.hashCode(data); 143 | } 144 | 145 | @Override 146 | public int compareTo(DataWord o) { 147 | if (o == null || o.getData() == null) { 148 | return -1; 149 | } 150 | // Convert result into -1, 0 or 1 as is the convention 151 | return (int) Math.signum(0); 152 | } 153 | 154 | public String toHexString() { 155 | return Hex.toHexString(data); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/transactions/TransactionTriggerEntity.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.transactions; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import java.io.Serializable; 5 | import java.util.List; 6 | import org.springframework.data.annotation.Id; 7 | import org.springframework.data.mongodb.core.mapping.Document; 8 | import org.springframework.data.mongodb.core.mapping.Field; 9 | 10 | @Document(collection = "transaction") 11 | public class TransactionTriggerEntity implements Serializable { 12 | 13 | private static final long serialVersionUID = -70777625567836430L; 14 | 15 | @Id 16 | private String id; 17 | 18 | @Field(value = "transactionId") 19 | @JsonProperty(value = "transactionId") 20 | private String transactionId; 21 | 22 | @Field(value = "blockHash") 23 | @JsonProperty(value = "blockHash") 24 | private String blockHash; 25 | 26 | @Field(value = "blockNumber") 27 | @JsonProperty(value = "blockNumber") 28 | private long blockNumber; 29 | 30 | @Field(value = "energyUsage") 31 | @JsonProperty(value = "energyUsage") 32 | private long energyUsage; 33 | 34 | @Field(value = "energyFee") 35 | @JsonProperty(value = "energyFee") 36 | private Long energyFee; 37 | 38 | @Field(value = "originEnergyUsage") 39 | @JsonProperty(value = "originEnergyUsage") 40 | private Long originEnergyUsage; 41 | 42 | @Field(value = "energyUsageTotal") 43 | @JsonProperty(value = "energyUsageTotal") 44 | private Long energyUsageTotal; 45 | 46 | @Field(value = "netUsage") 47 | @JsonProperty(value = "netUsage") 48 | private Long netUsage; 49 | 50 | @Field(value = "netFee") 51 | @JsonProperty(value = "netFee") 52 | private Long netFee; 53 | 54 | @Field(value = "result") 55 | @JsonProperty(value = "result") 56 | private String result; 57 | 58 | @Field(value = "contractAddress") 59 | @JsonProperty(value = "contractAddress") 60 | private String contractAddress; 61 | 62 | @Field(value = "contractType") 63 | @JsonProperty(value = "contractType") 64 | private String contractType; 65 | 66 | @Field(value = "feeLimit") 67 | @JsonProperty(value = "feeLimit") 68 | private long feeLimit; 69 | 70 | @Field(value = "contractCallValue") 71 | @JsonProperty(value = "contractCallValue") 72 | private long contractCallValue; 73 | 74 | @Field(value = "timeStamp") 75 | @JsonProperty(value = "timeStamp") 76 | private long timeStamp; 77 | 78 | @Field(value = "triggerName") 79 | @JsonProperty(value = "triggerName") 80 | private String triggerName; 81 | 82 | @Field(value = "internalTrananctionList") 83 | @JsonProperty(value = "internalTrananctionList") 84 | private List internalTrananctionList; 85 | 86 | @Field(value = "fromAddress") 87 | @JsonProperty(value = "fromAddress") 88 | private String fromAddress; 89 | 90 | @Field(value = "toAddress") 91 | @JsonProperty(value = "toAddress") 92 | private String toAddress; 93 | 94 | @Field(value = "assetName") 95 | @JsonProperty(value = "assetName") 96 | private String assetName; 97 | 98 | @Field(value = "assetAmount") 99 | @JsonProperty(value = "assetAmount") 100 | private long assetAmount; 101 | 102 | @Field(value = "contractResult") 103 | @JsonProperty(value = "contractResult") 104 | private String contractResult; 105 | 106 | @Field(value = "latestSolidifiedBlockNumber") 107 | @JsonProperty(value = "latestSolidifiedBlockNumber") 108 | private long latestSolidifiedBlockNumber; 109 | 110 | @Field(value = "data") 111 | @JsonProperty(value = "data") 112 | private String data; 113 | 114 | public String getContractType() { 115 | return contractType; 116 | } 117 | 118 | public TransactionTriggerEntity(String transactionId, String blockHash, 119 | long blockNumber, long energyUsage, long energyFee, long originEnergyUsage, 120 | long energyUsageTotal, long netUsage, long netFee, 121 | List internalTrananctionList, 122 | String fromAddress, String toAddress, String assetName, long assetAmount, 123 | String contractResult,long contractCallValue, String result, 124 | String contractAddress, String contractType, 125 | long feeLimit,long timeStamp, long latestSolidifiedBlockNumber, String data) { 126 | this.transactionId = transactionId; 127 | this.blockHash = blockHash; 128 | this.blockNumber = blockNumber; 129 | this.energyUsage = energyUsage; 130 | this.energyFee = energyFee; 131 | this.originEnergyUsage = originEnergyUsage; 132 | this.energyUsageTotal = energyUsageTotal; 133 | this.netUsage = netUsage; 134 | this.netFee = netFee; 135 | this.internalTrananctionList = internalTrananctionList; 136 | this.fromAddress = fromAddress; 137 | this.toAddress = toAddress; 138 | this.assetName = assetName; 139 | this.assetAmount = assetAmount; 140 | this.contractResult = contractResult; 141 | this.contractCallValue = contractCallValue; 142 | this.result = result; 143 | this.contractAddress = contractAddress; 144 | this.contractType = contractType; 145 | this.feeLimit = feeLimit; 146 | this.timeStamp = timeStamp; 147 | this.latestSolidifiedBlockNumber = latestSolidifiedBlockNumber; 148 | this.data = data; 149 | } 150 | } -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/filter/CommonFilter.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.filter; 2 | 3 | 4 | import com.alibaba.fastjson.JSONObject; 5 | 6 | import javax.servlet.*; 7 | import javax.servlet.annotation.WebFilter; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | import java.util.HashMap; 12 | 13 | @WebFilter(urlPatterns = "/*") 14 | public class CommonFilter implements Filter { 15 | 16 | 17 | public static String TOTAL_REQUST = "TOTAL_REQUEST"; 18 | public static String FAIL_REQUST = "FAIL_REQUEST"; 19 | public static String FAIL4XX_REQUST = "FAIL4XX_REQUEST"; 20 | public static String FAIL5XX_REQUST = "FAIL5XX_REQUEST"; 21 | public static String OK_REQUST = "OK_REQUEST"; 22 | private static int totalCount = 0; 23 | private static int failCount = 0; 24 | private static int count4xx=0; 25 | private static int count5xx=0; 26 | private static int okCount=0; 27 | private static int interval = 1440; // 24 hour 28 | private static HashMap EndpointCount = new HashMap(); 29 | public String END_POINT = "END_POINT"; 30 | public long gapMilliseconds = interval * 60 * 1000; 31 | private long preciousTime = 0; 32 | 33 | public int getTotalCount() { 34 | return this.totalCount; 35 | } 36 | 37 | public int getInterval() { 38 | return this.interval; 39 | } 40 | 41 | public int getFailCount() { 42 | return this.failCount; 43 | } 44 | 45 | public int getOkCount() { return this.okCount; } 46 | 47 | public int getCount4xx() { 48 | return count4xx; 49 | } 50 | public int getCount5xx() { 51 | return count5xx; 52 | } 53 | 54 | public HashMap getEndpointMap() { 55 | return this.EndpointCount; 56 | } 57 | 58 | public CommonFilter getInstance() { return this; } 59 | 60 | @Override public void init(FilterConfig filterConfig) throws ServletException { 61 | // code here 62 | preciousTime = System.currentTimeMillis(); 63 | } 64 | 65 | 66 | @Override 67 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 68 | throws IOException, ServletException { 69 | // System.out.println("--------------doFilter start--------------"); 70 | long currentTime = System.currentTimeMillis(); 71 | if (currentTime - preciousTime > gapMilliseconds) { //reset every 1 minutes 72 | totalCount = 0; 73 | failCount = 0; 74 | count4xx=0; 75 | count5xx=0; 76 | okCount=0; 77 | preciousTime = currentTime; 78 | EndpointCount.clear(); 79 | } 80 | 81 | if (request instanceof HttpServletRequest) { 82 | String endpoint = ((HttpServletRequest) request).getRequestURI(); 83 | JSONObject obj = new JSONObject(); 84 | if (EndpointCount.containsKey(endpoint)) { 85 | obj = EndpointCount.get(endpoint); 86 | } else { 87 | obj.put(TOTAL_REQUST, 0); 88 | obj.put(FAIL_REQUST, 0); 89 | obj.put(FAIL4XX_REQUST, 0); 90 | obj.put(FAIL5XX_REQUST, 0); 91 | obj.put(OK_REQUST, 0); 92 | obj.put(END_POINT, endpoint); 93 | } 94 | obj.put(TOTAL_REQUST, (int) obj.get(TOTAL_REQUST) + 1); 95 | totalCount++; 96 | System.out.println("--response:"+response); 97 | try { 98 | chain.doFilter(request, response); 99 | HttpServletResponse resp = (HttpServletResponse) response; 100 | // System.out.println("--status:"+resp.getStatus()); 101 | // System.out.println("--response:"+response); 102 | if (resp.getStatus() != 200) { 103 | failCount++; 104 | count5xx=failCount-count4xx; 105 | obj.put(FAIL_REQUST, (int) obj.get(FAIL_REQUST) + 1); 106 | obj.put(FAIL5XX_REQUST, (int) obj.get(FAIL_REQUST)-(int) obj.get(FAIL4XX_REQUST)); 107 | } 108 | if (resp.getStatus() < 500 & resp.getStatus() > 399) { 109 | count4xx++; 110 | count5xx=failCount-count4xx; 111 | obj.put(FAIL4XX_REQUST, (int) obj.get(FAIL4XX_REQUST) + 1); 112 | obj.put(FAIL5XX_REQUST, (int) obj.get(FAIL_REQUST)-(int) obj.get(FAIL4XX_REQUST)); 113 | } 114 | } catch (Exception e) { 115 | failCount++; 116 | count5xx=failCount-count4xx; 117 | obj.put(FAIL_REQUST, (int) obj.get(FAIL_REQUST) + 1); 118 | obj.put(FAIL5XX_REQUST, (int) obj.get(FAIL_REQUST)-(int) obj.get(FAIL4XX_REQUST)); 119 | throw e; 120 | } 121 | obj.put(OK_REQUST, (int) obj.get(TOTAL_REQUST) - (int) obj.get(FAIL_REQUST)); 122 | okCount=totalCount-failCount; 123 | // update map 124 | EndpointCount.put(endpoint, obj); 125 | } else { 126 | chain.doFilter(request, response); 127 | } 128 | // System.out.println("TOTAL_REQUST:"+ totalCount); 129 | // System.out.println("FAIL_REQUST:"+failCount); 130 | // System.out.println("--------------doFilter stop--------------"); 131 | } 132 | 133 | @Override 134 | public void destroy() { 135 | } 136 | } -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/crypto/cryptohash/Digest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.crypto.cryptohash; 20 | 21 | /** 22 | * Copyright (c) 2007-2010 Projet RNRT SAPHIR 23 | * 24 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 25 | * associated documentation files (the "Software"), to deal in the Software without restriction, 26 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, 27 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 28 | * furnished to do so, subject to the following conditions: 29 | * 30 | * The above copyright notice and this permission notice shall be included in all copies or 31 | * substantial portions of the Software. 32 | * 33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 34 | * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 35 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 36 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 37 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 38 | */ 39 | 40 | 41 | public interface Digest { 42 | 43 | /** 44 | * Insert one more input data byte. 45 | * 46 | * @param in the input byte 47 | */ 48 | void update(byte in); 49 | 50 | /** 51 | * Insert some more bytes. 52 | * 53 | * @param inbuf the data bytes 54 | */ 55 | void update(byte[] inbuf); 56 | 57 | /** 58 | * Insert some more bytes. 59 | * 60 | * @param inbuf the data buffer 61 | * @param off the data offset in {@code inbuf} 62 | * @param len the data length (in bytes) 63 | */ 64 | void update(byte[] inbuf, int off, int len); 65 | 66 | /** 67 | * Finalize the current hash computation and return the hash value in a newly-allocated array. The 68 | * object is resetted. 69 | * 70 | * @return the hash output 71 | */ 72 | byte[] digest(); 73 | 74 | /** 75 | * Input some bytes, then finalize the current hash computation and return the hash value in a 76 | * newly-allocated array. The object is resetted. 77 | * 78 | * @param inbuf the input data 79 | * @return the hash output 80 | */ 81 | byte[] digest(byte[] inbuf); 82 | 83 | /** 84 | * Finalize the current hash computation and store the hash value in the provided output buffer. 85 | * The {@code len} parameter contains the maximum number of bytes that should be written; no more 86 | * bytes than the natural hash function output length will be produced. If {@code len} is smaller 87 | * than the natural hash output length, the hash output is truncated to its first {@code len} 88 | * bytes. The object is resetted. 89 | * 90 | * @param outbuf the output buffer 91 | * @param off the output offset within {@code outbuf} 92 | * @param len the requested hash output length (in bytes) 93 | * @return the number of bytes actually written in {@code outbuf} 94 | */ 95 | int digest(byte[] outbuf, int off, int len); 96 | 97 | /** 98 | * Get the natural hash function output length (in bytes). 99 | * 100 | * @return the digest output length (in bytes) 101 | */ 102 | int getDigestLength(); 103 | 104 | /** 105 | * Reset the object: this makes it suitable for a new hash computation. The current computation, 106 | * if any, is discarded. 107 | */ 108 | void reset(); 109 | 110 | /** 111 | * Clone the current state. The returned object evolves independantly of this object. 112 | * 113 | * @return the clone 114 | */ 115 | Digest copy(); 116 | 117 | /** 118 | *

Return the "block length" for the hash function. This value is naturally defined for 119 | * iterated hash functions (Merkle-Damgard). It is used in HMAC (that's what the HMAC specification names the "{@code B}" 121 | * parameter).

If the function is "block-less" then this function may return {@code -n} 122 | * where {@code n} is an integer such that the block length for HMAC ("{@code B}") will be 123 | * inferred from the key length, by selecting the smallest multiple of {@code n} which is no 124 | * smaller than the key length. For instance, for the Fugue-xxx hash functions, this function 125 | * returns -4: the virtual block length B is the HMAC key length, rounded up to the next multiple 126 | * of 4.

127 | * 128 | * @return the internal block length (in bytes), or {@code -n} 129 | */ 130 | int getBlockLength(); 131 | 132 | /** 133 | *

Get the display name for this function (e.g. {@code "SHA-1"} for SHA-1).

134 | * 135 | * @see Object 136 | */ 137 | String toString(); 138 | } 139 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.crypto.cryptohash; 20 | 21 | import java.security.MessageDigest; 22 | 23 | public abstract class DigestEngine extends MessageDigest implements Digest { 24 | 25 | private int digestLen, blockLen, inputLen; 26 | private byte[] inputBuf, outputBuf; 27 | private long blockCount; 28 | 29 | /** 30 | * Instantiate the engine. 31 | */ 32 | public DigestEngine(String alg) { 33 | super(alg); 34 | doInit(); 35 | digestLen = engineGetDigestLength(); 36 | blockLen = getInternalBlockLength(); 37 | inputBuf = new byte[blockLen]; 38 | outputBuf = new byte[digestLen]; 39 | inputLen = 0; 40 | blockCount = 0; 41 | } 42 | 43 | /** 44 | * Reset the hash algorithm state. 45 | */ 46 | protected abstract void engineReset(); 47 | 48 | /** 49 | * Process one block of data. 50 | * 51 | * @param data the data block 52 | */ 53 | protected abstract void processBlock(byte[] data); 54 | 55 | /** 56 | * Perform the final padding and store the result in the provided buffer. This method shall call 57 | * {@link #flush} and then {@link #update} with the appropriate padding data in order to getData 58 | * the full input data. 59 | * 60 | * @param buf the output buffer 61 | * @param off the output offset 62 | */ 63 | protected abstract void doPadding(byte[] buf, int off); 64 | 65 | /** 66 | * This function is called at object creation time; the implementation should use it to perform 67 | * initialization tasks. After this method is called, the implementation should be ready to 68 | * process data or meaningfully honour calls such as {@link #engineGetDigestLength} 69 | */ 70 | protected abstract void doInit(); 71 | 72 | private void adjustDigestLen() { 73 | if (digestLen == 0) { 74 | digestLen = engineGetDigestLength(); 75 | outputBuf = new byte[digestLen]; 76 | } 77 | } 78 | 79 | /** 80 | * @see Digest 81 | */ 82 | public byte[] digest() { 83 | adjustDigestLen(); 84 | byte[] result = new byte[digestLen]; 85 | digest(result, 0, digestLen); 86 | return result; 87 | } 88 | 89 | /** 90 | * @see Digest 91 | */ 92 | public byte[] digest(byte[] input) { 93 | update(input, 0, input.length); 94 | return digest(); 95 | } 96 | 97 | /** 98 | * @see Digest 99 | */ 100 | public int digest(byte[] buf, int offset, int len) { 101 | adjustDigestLen(); 102 | if (len >= digestLen) { 103 | doPadding(buf, offset); 104 | reset(); 105 | return digestLen; 106 | } else { 107 | doPadding(outputBuf, 0); 108 | System.arraycopy(outputBuf, 0, buf, offset, len); 109 | reset(); 110 | return len; 111 | } 112 | } 113 | 114 | /** 115 | * @see Digest 116 | */ 117 | public void reset() { 118 | engineReset(); 119 | inputLen = 0; 120 | blockCount = 0; 121 | } 122 | 123 | /** 124 | * @see Digest 125 | */ 126 | public void update(byte input) { 127 | inputBuf[inputLen++] = input; 128 | if (inputLen == blockLen) { 129 | processBlock(inputBuf); 130 | blockCount++; 131 | inputLen = 0; 132 | } 133 | } 134 | 135 | /** 136 | * @see Digest 137 | */ 138 | public void update(byte[] input) { 139 | update(input, 0, input.length); 140 | } 141 | 142 | /** 143 | * @see Digest 144 | */ 145 | public void update(byte[] input, int offset, int len) { 146 | while (len > 0) { 147 | int copyLen = blockLen - inputLen; 148 | if (copyLen > len) { 149 | copyLen = len; 150 | } 151 | System.arraycopy(input, offset, inputBuf, inputLen, 152 | copyLen); 153 | offset += copyLen; 154 | inputLen += copyLen; 155 | len -= copyLen; 156 | if (inputLen == blockLen) { 157 | processBlock(inputBuf); 158 | blockCount++; 159 | inputLen = 0; 160 | } 161 | } 162 | } 163 | 164 | /** 165 | * Get the internal block length. This is the length (in bytes) of the array which will be passed 166 | * as parameter to {@link #processBlock}. The default implementation of this method calls {@link 167 | * #getBlockLength} and returns the same value. Overriding this method is useful when the 168 | * advertised block length (which is used, for instance, by HMAC) is suboptimal with regards to 169 | * internal buffering needs. 170 | * 171 | * @return the internal block length (in bytes) 172 | */ 173 | protected int getInternalBlockLength() { 174 | return getBlockLength(); 175 | } 176 | 177 | /** 178 | * Flush internal buffers, so that less than a block of data may at most be upheld. 179 | * 180 | * @return the number of bytes still unprocessed after the flush 181 | */ 182 | protected final int flush() { 183 | return inputLen; 184 | } 185 | 186 | /** 187 | * Get a reference to an internal buffer with the same size than a block. The contents of that 188 | * buffer are defined only immediately after a call to {@link #flush()}: if {@link #flush()} 189 | * return the value {@code n}, then the first {@code n} bytes of the array returned by this method 190 | * are the {@code n} bytes of input data which are still unprocessed. The values of the remaining 191 | * bytes are undefined and may be altered at will. 192 | * 193 | * @return a block-sized internal buffer 194 | */ 195 | protected final byte[] getBlockBuffer() { 196 | return inputBuf; 197 | } 198 | 199 | /** 200 | * Get the "block count": this is the number of times the {@link #processBlock} method has been 201 | * invoked for the current hash operation. That counter is incremented after the call to 202 | * {@link #processBlock}. 203 | * 204 | * @return the block count 205 | */ 206 | protected long getBlockCount() { 207 | return blockCount; 208 | } 209 | 210 | /** 211 | * This function copies the internal buffering state to some other instance of a class extending 212 | * {@code DigestEngine}. It returns a reference to the copy. This method is intended to be called 213 | * by the implementation of the {@link #copy} method. 214 | * 215 | * @param dest the copy 216 | * @return the value {@code dest} 217 | */ 218 | protected Digest copyState(DigestEngine dest) { 219 | dest.inputLen = inputLen; 220 | dest.blockCount = blockCount; 221 | System.arraycopy(inputBuf, 0, dest.inputBuf, 0, 222 | inputBuf.length); 223 | adjustDigestLen(); 224 | dest.adjustDigestLen(); 225 | System.arraycopy(outputBuf, 0, dest.outputBuf, 0, 226 | outputBuf.length); 227 | return dest; 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tron Event Query Service 2 | TronEventQuery is implemented with Tron's new event subscribe model. 3 | It uses same query interface with Tron-Grid. Users can also subscribe block trigger, transaction trigger, contract log trigger, and contract event trigger. 4 | TronEvent is independent of a particular branch of java-tron, the new event subscribes model has already be released on version 3.5 of java-tron. 5 | 6 | For more information of tron event subscribe model, please refer to https://github.com/tronprotocol/TIPs/issues/12. 7 | 8 | ## Download sourcecode 9 | git clone https://github.com/tronprotocol/tron-eventquery.git 10 | 11 | cd troneventquery 12 | 13 | ## Build 14 | **mvn package** 15 | 16 | After the build command is executed successfully, troneventquery jar to release will be generated under troneventquery/target directory. 17 | Configuration of mongodb "config.conf" should be created for storing mongodb configuration, such as database name, username, password, and so on. We provided an example in sourcecode, which is " troneventquery/config.conf ". Replace with your specified configuration if needed. 18 | 19 | **Note**: 20 | Make sure the relative path of config.conf and troneventquery jar. The config.conf 's path is the parent of troneventquery jar. 21 | 22 | - mongo.host=IP 23 | - mongo.port=27017 24 | - mongo.dbname=eventlog 25 | - mongo.username=tron 26 | - mongo.password=123456 27 | - mongo.connectionsPerHost=8 28 | - mongo.threadsAllowedToBlockForConnectionMultiplier=4 29 | 30 | Any configuration could be modified except **mongo.dbname**, "**eventlog**" is the specified database name for event subscribe. 31 | 32 | ## Run 33 | - troneventquery/deploy.sh is used to deploy troneventquery 34 | - troneventquery/insertIndex.sh is used to setup mongodb index to speedup query. 35 | (make sure run insertIndex before create collecions) 36 | 37 | ## Delete expire data 38 | - troneventquery/deleteData.sh is used to delete expire data 39 | - using crontable delete regularly mongodb expire data(if not delete, the database will be too big) 40 | 41 | 42 | ## What is the main HTTP service? 43 | baseUrl: https://api.tronex.io 44 | 45 | ## Main HTTP Service 46 | Function: get transaction list 47 | ``` 48 | subpath: $baseUrl/transactions 49 | 50 | parameters 51 | limit: each page size, default is 25 52 | sort: sort Field, default is sort by timeStamp descending order 53 | start: start page, default is 1 54 | block: start block number, default is 0 55 | 56 | Example: https://api.tronex.io/transactions?limit=1&sort=-timeStamp&start=2&block=0 57 | ``` 58 | 59 | Function: get transaction by hash 60 | ``` 61 | subpath: $baseUrl/transactions/{hash} 62 | 63 | parameters 64 | hash: transaction id 65 | 66 | Example: https://api.tronex.io/9a4f096700672d7420889cd76570ea47bfe9ef815bb2137b0d4c71b3d23309e9 67 | ``` 68 | Function: get transfers list 69 | ``` 70 | subpath: $baseUrl/transfers 71 | 72 | parameters 73 | limit: each page size, default is 25 74 | sort: sort Field, default is sort by timeStamp descending order 75 | start: start page, default is 1 76 | from: from address, default is "" 77 | to: to address, default is "" 78 | token: tokenName, default is "" 79 | 80 | Example: https://api.tronex.io/transfers?token=trx&limit=1&sort=timeStamp&start=2&block=0&from=TJ7yJNWS8RmvpXcAyXBhvFDfGpV9ZYc3vt&to=TAEcoD8J7P5QjWT32r31gat8L7Sga2qUy8 81 | ``` 82 | Function: get transfers by transactionId 83 | ``` 84 | subpath: $baseUrl/transfers/{hash} 85 | 86 | parameters 87 | hash: transfer hash 88 | 89 | Example: https://api.tronex.io/transfers/70d655a17e04d6b6b7ee5d53e7f37655974f4e71b0edd6bcb311915a151a4700 90 | ``` 91 | Function: get events list 92 | ``` 93 | subpath: $baseUrl/events 94 | 95 | parameters 96 | limit: each page size, default is 25 97 | sort: sort Field, default is sort by timeStamp descending order 98 | since: start time of event occurrence, timeStamp >= since will be shown 99 | start: start page, default is 1 100 | block: block number, block number >= block will be shown 101 | 102 | Example: https://api.tronex.io/events?limit=1&sort=timeStamp&since=0&block=0&start=0 103 | ``` 104 | Function: get events by transactionId 105 | ``` 106 | subpath: $baseUrl/events/transaction/{transactionId} 107 | 108 | parameters 109 | transactionId 110 | 111 | Example: https://api.tronex.io/events/transaction/cd402e64cad7e69c086649401f6427f5852239f41f51a100abfc7beaa8aa0f9c 112 | ``` 113 | Function: get events by contract address 114 | ``` 115 | subpath: $baseUrl/events/{contractAddress} 116 | 117 | parameters 118 | limit: each page size, default is 25 119 | sort: sort Field, default is sort by timeStamp descending order 120 | since: start time of event occurrence, timeStamp >= since will be shown 121 | block: block number, block number >= block will be shown 122 | contractAddress: contract address 123 | start: start page, default is 1 124 | 125 | Example: https://api.tronex.io/events/TMYcx6eoRXnePKT1jVn25ZNeMNJ6828HWk?limit=1&sort=-timeStamp&since=0&block=0&start=4 126 | ``` 127 | Function: get events by contract address and event name 128 | ``` 129 | subpath: $baseUrl/events/contract/{contractAddress}/{eventName} 130 | 131 | parameters 132 | limit: each page size, default is 25 133 | sort: sort Field, default is sort by timeStamp descending order 134 | since: start time of event occurrence, timeStamp >= since will be shown 135 | contract`Address`: contract address 136 | start: start page, default is 1 137 | eventName: event name 138 | 139 | Example: https://api.tronex.io/events/contract/TMYcx6eoRXnePKT1jVn25ZNeMNJ6828HWk/Bet?limit=1&sort=timeStamp&since=1&start=0 140 | ``` 141 | Function: get events by contract address, event name and block number 142 | ``` 143 | subpath: $baseUrl/events/contract/{contractAddress}/{eventName}/{blockNumber} 144 | 145 | parameters 146 | contractAddress: contract address 147 | blockNumber: block number, block number >= block will be shown 148 | eventName: event name 149 | 150 | 151 | Example: https://api.tronex.io/events/contract/TMYcx6eoRXnePKT1jVn25ZNeMNJ6828HWk/Bet/4835773 152 | ``` 153 | Function: get events by timeStamp 154 | ``` 155 | subpath: $baseUrl/events/timestamp 156 | 157 | parameters 158 | since: start time of event occurrence, timeStamp >= since will be shown 159 | limit: each page size, default is 25 160 | sort: sort Field, default is sort by timeStamp descending order 161 | start: start page, default is 1 162 | contract: contract address 163 | 164 | 165 | Example: https://api.tronex.io/events/timestamp?since=1544483426749&limit=1&start=1&sort=timeStamp 166 | ``` 167 | Function: get confirm events list 168 | ``` 169 | subpath: $baseUrl/events/confirmed 170 | 171 | parameters 172 | since: start time of event occurrence, timeStamp >= since will be shown 173 | limit: each page size, default is 25 174 | sort: sort Field, default is sort by timeStamp descending order 175 | start: start page, default is 1 176 | 177 | 178 | Example: https://api.tronex.io/events/confirmed?since=1544483426749&limit=1&start=1&sort=timeStamp 179 | ``` 180 | Function: get block by block hash 181 | ``` 182 | subpath: $baseUrl/blocks/{hash} 183 | 184 | parameters 185 | hash: block hash 186 | 187 | 188 | Example: https://api.tronex.io/blocks/000000000049c11f15d4e91e988bc950fa9f194d2cb2e04cda76675dbb349009 189 | ``` 190 | Function: get block list 191 | ``` 192 | subpath: $baseUrl/blocks 193 | 194 | parameters 195 | limit: each page size, default is 25 196 | sort: sort Field, default is sort by timeStamp descending order 197 | start: start page, default is 1 198 | block: block number, block number >= block will be shown 199 | 200 | 201 | Example: https://api.tronex.io/blocks?limit=1&sort=timeStamp&start=0&block=0 202 | ``` 203 | Function: get latest block number 204 | ``` 205 | subpath: $baseUrl/blocks/latestSolidifiedBlockNumber 206 | 207 | parameters 208 | none 209 | 210 | Example: https://api.tronex.io/blocks/latestSolidifiedBlockNumber 211 | ``` 212 | Function: get contract log list 213 | ``` 214 | subpath: $baseUrl/contractlogs 215 | 216 | parameters 217 | limit: each page size, default is 25 218 | sort: sort Field, default is sort by timeStamp descending order 219 | start: start page, default is 1 220 | block: block number, block number >= block will be shown 221 | 222 | Example: https://api.tronex.io/contractlogs 223 | ``` 224 | Function: get contract log list based on transactionId 225 | ``` 226 | subpath: $baseUrl/contractlogs/transaction/{transactionId} 227 | 228 | parameters 229 | transactionId 230 | 231 | Example: https://api.tronex.io/contractlogs/transaction/{transactionId} 232 | ``` 233 | Function: post abi string and get contract log list based on transactionId(release on 3.6) 234 | ``` 235 | subpath: $baseUrl/contract/transaction/{transactionId} 236 | 237 | parameters 238 | transactionId 239 | body: 240 | abi: user self upload abi 241 | 242 | Example: https://api.tronex.io/contract/transaction/{transactionId} 243 | ``` 244 | Function: get contract log list based on contractAddress 245 | ``` 246 | subpath: $baseUrl/contractlogs/contract/{contractAddress} 247 | 248 | parameters 249 | contractAddress 250 | 251 | Example: https://api.tronex.io/contractlogs/contract/{contractAddress} 252 | ``` 253 | Function: post abi string and get contract log list based on contractAddress(release on 3.6) 254 | ``` 255 | subpath: $baseUrl/contract/contractAddress/{contractAddress} 256 | 257 | parameters 258 | contractAddress 259 | abi: user self upload abi 260 | 261 | Example: https://api.tronex.io/contract/contractAddress/{contractAddress} 262 | ``` 263 | Function: get contract log list based on uniqueId 264 | ``` 265 | subpath: $baseUrl/contractlogs/uniqueId/{uniqueId} 266 | 267 | parameters 268 | uniqueId 269 | 270 | Example: https://api.tronex.io/contractlogs/uniqueId/{uniqueId} 271 | ``` 272 | Function: post abi string and get contract log list based on uniqueId(release on 3.6) 273 | ``` 274 | subpath: $baseUrl/contract/uniqueId/{uniqueId} 275 | 276 | parameters 277 | uniqueId 278 | abi: user self upload abi 279 | 280 | Example: https://api.tronex.io/contract/uniqueId/{uniqueId} 281 | ``` 282 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/utils/Sha256Hash.java: -------------------------------------------------------------------------------- 1 | package org.tron.common.utils; 2 | 3 | /* 4 | * Copyright 2011 Google Inc. 5 | * Copyright 2014 Andreas Schildbach 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import static com.google.common.base.Preconditions.checkArgument; 21 | 22 | import com.google.common.io.ByteStreams; 23 | import com.google.common.primitives.Ints; 24 | import com.google.common.primitives.Longs; 25 | import com.google.protobuf.ByteString; 26 | import java.io.File; 27 | import java.io.FileInputStream; 28 | import java.io.IOException; 29 | import java.io.Serializable; 30 | import java.math.BigInteger; 31 | import java.security.MessageDigest; 32 | import java.security.NoSuchAlgorithmException; 33 | import java.util.Arrays; 34 | 35 | 36 | /** 37 | * A Sha256Hash just wraps a byte[] so that equals and hashcode work correctly, allowing it to be 38 | * used as keys in a map. It also checks that the length is correct and provides a bit more type 39 | * safety. 40 | */ 41 | public class Sha256Hash implements Serializable, Comparable { 42 | 43 | public static final int LENGTH = 32; // bytes 44 | public static final Sha256Hash ZERO_HASH = wrap(new byte[LENGTH]); 45 | 46 | private final byte[] bytes; 47 | 48 | private byte[] generateBlockId(long blockNum, Sha256Hash blockHash) { 49 | byte[] numBytes = Longs.toByteArray(blockNum); 50 | byte[] hash = new byte[blockHash.getBytes().length]; 51 | System.arraycopy(numBytes, 0, hash, 0, 8); 52 | System.arraycopy(blockHash.getBytes(), 8, hash, 8, blockHash.getBytes().length - 8); 53 | return hash; 54 | } 55 | 56 | private byte[] generateBlockId(long blockNum, byte[] blockHash) { 57 | byte[] numBytes = Longs.toByteArray(blockNum); 58 | byte[] hash = new byte[blockHash.length]; 59 | System.arraycopy(numBytes, 0, hash, 0, 8); 60 | System.arraycopy(blockHash, 8, hash, 8, blockHash.length - 8); 61 | return hash; 62 | } 63 | 64 | public Sha256Hash(long num, byte[] hash) { 65 | byte[] rawHashBytes = this.generateBlockId(num, hash); 66 | checkArgument(rawHashBytes.length == LENGTH); 67 | this.bytes = rawHashBytes; 68 | } 69 | 70 | public Sha256Hash(long num, Sha256Hash hash) { 71 | byte[] rawHashBytes = this.generateBlockId(num, hash); 72 | checkArgument(rawHashBytes.length == LENGTH); 73 | this.bytes = rawHashBytes; 74 | } 75 | 76 | /** 77 | * Use {@link #wrap(byte[])} instead. 78 | */ 79 | @Deprecated 80 | public Sha256Hash(byte[] rawHashBytes) { 81 | checkArgument(rawHashBytes.length == LENGTH); 82 | this.bytes = rawHashBytes; 83 | } 84 | 85 | /** 86 | * Creates a new instance that wraps the given hash value. 87 | * 88 | * @param rawHashBytes the raw hash bytes to wrap 89 | * @return a new instance 90 | * @throws IllegalArgumentException if the given array length is not exactly 32 91 | */ 92 | @SuppressWarnings("deprecation") // the constructor will be made private in the future 93 | public static Sha256Hash wrap(byte[] rawHashBytes) { 94 | return new Sha256Hash(rawHashBytes); 95 | } 96 | 97 | public static Sha256Hash wrap(ByteString rawHashByteString) { 98 | return wrap(rawHashByteString.toByteArray()); 99 | } 100 | 101 | /** 102 | * Use {@link #of(byte[])} instead: this old name is ambiguous. 103 | */ 104 | @Deprecated 105 | public static Sha256Hash create(byte[] contents) { 106 | return of(contents); 107 | } 108 | 109 | /** 110 | * Creates a new instance containing the calculated (one-time) hash of the given bytes. 111 | * 112 | * @param contents the bytes on which the hash value is calculated 113 | * @return a new instance containing the calculated (one-time) hash 114 | */ 115 | public static Sha256Hash of(byte[] contents) { 116 | return wrap(hash(contents)); 117 | } 118 | 119 | /** 120 | * Creates a new instance containing the calculated (one-time) hash of the given file's contents. 121 | * The file contents are read fully into memory, so this method should only be used with small 122 | * files. 123 | * 124 | * @param file the file on which the hash value is calculated 125 | * @return a new instance containing the calculated (one-time) hash 126 | * @throws IOException if an error occurs while reading the file 127 | */ 128 | public static Sha256Hash of(File file) throws IOException { 129 | 130 | try (FileInputStream in = new FileInputStream(file)) { 131 | return of(ByteStreams.toByteArray(in)); 132 | } 133 | } 134 | 135 | /** 136 | * Use {@link #twiceOf(byte[])} instead: this old name is ambiguous. 137 | */ 138 | @Deprecated 139 | public static Sha256Hash createDouble(byte[] contents) { 140 | return twiceOf(contents); 141 | } 142 | 143 | /** 144 | * Creates a new instance containing the hash of the calculated hash of the given bytes. 145 | * 146 | * @param contents the bytes on which the hash value is calculated 147 | * @return a new instance containing the calculated (two-time) hash 148 | */ 149 | public static Sha256Hash twiceOf(byte[] contents) { 150 | return wrap(hashTwice(contents)); 151 | } 152 | 153 | /** 154 | * Returns a new SHA-256 MessageDigest instance. This is a convenience method which wraps the 155 | * checked exception that can never occur with a RuntimeException. 156 | * 157 | * @return a new SHA-256 MessageDigest instance 158 | */ 159 | public static MessageDigest newDigest() { 160 | try { 161 | return MessageDigest.getInstance("SHA-256"); 162 | } catch (NoSuchAlgorithmException e) { 163 | throw new RuntimeException(e); // Can't happen. 164 | } 165 | } 166 | 167 | /** 168 | * Calculates the SHA-256 hash of the given bytes. 169 | * 170 | * @param input the bytes to hash 171 | * @return the hash (in big-endian order) 172 | */ 173 | public static byte[] hash(byte[] input) { 174 | return hash(input, 0, input.length); 175 | } 176 | 177 | /** 178 | * Calculates the SHA-256 hash of the given byte range. 179 | * 180 | * @param input the array containing the bytes to hash 181 | * @param offset the offset within the array of the bytes to hash 182 | * @param length the number of bytes to hash 183 | * @return the hash (in big-endian order) 184 | */ 185 | public static byte[] hash(byte[] input, int offset, int length) { 186 | MessageDigest digest = newDigest(); 187 | digest.update(input, offset, length); 188 | return digest.digest(); 189 | } 190 | 191 | /** 192 | * Calculates the SHA-256 hash of the given bytes, and then hashes the resulting hash again. 193 | * 194 | * @param input the bytes to hash 195 | * @return the double-hash (in big-endian order) 196 | */ 197 | public static byte[] hashTwice(byte[] input) { 198 | return hashTwice(input, 0, input.length); 199 | } 200 | 201 | /** 202 | * Calculates the SHA-256 hash of the given byte range, and then hashes the resulting hash again. 203 | * 204 | * @param input the array containing the bytes to hash 205 | * @param offset the offset within the array of the bytes to hash 206 | * @param length the number of bytes to hash 207 | * @return the double-hash (in big-endian order) 208 | */ 209 | public static byte[] hashTwice(byte[] input, int offset, int length) { 210 | MessageDigest digest = newDigest(); 211 | digest.update(input, offset, length); 212 | return digest.digest(digest.digest()); 213 | } 214 | 215 | /** 216 | * Calculates the hash of hash on the given byte ranges. This is equivalent to concatenating the 217 | * two ranges and then passing the result to {@link #hashTwice(byte[])}. 218 | */ 219 | public static byte[] hashTwice(byte[] input1, int offset1, int length1, 220 | byte[] input2, int offset2, int length2) { 221 | MessageDigest digest = newDigest(); 222 | digest.update(input1, offset1, length1); 223 | digest.update(input2, offset2, length2); 224 | return digest.digest(digest.digest()); 225 | } 226 | 227 | @Override 228 | public boolean equals(Object o) { 229 | if (this == o) { 230 | return true; 231 | } 232 | if (o == null || !(o instanceof Sha256Hash)) { 233 | return false; 234 | } 235 | return Arrays.equals(bytes, ((Sha256Hash) o).bytes); 236 | } 237 | 238 | @Override 239 | public String toString() { 240 | return ByteArray.toHexString(bytes); 241 | } 242 | 243 | /** 244 | * Returns the last four bytes of the wrapped hash. This should be unique enough to be a suitable 245 | * hash code even for blocks, where the goal is to try and get the first bytes to be zeros (i.e. 246 | * the value as a big integer lower than the target value). 247 | */ 248 | @Override 249 | public int hashCode() { 250 | // Use the last 4 bytes, not the first 4 which are often zeros in Bitcoin. 251 | return Ints 252 | .fromBytes(bytes[LENGTH - 4], bytes[LENGTH - 3], bytes[LENGTH - 2], bytes[LENGTH - 1]); 253 | } 254 | 255 | /** 256 | * Returns the bytes interpreted as a positive integer. 257 | */ 258 | public BigInteger toBigInteger() { 259 | return new BigInteger(1, bytes); 260 | } 261 | 262 | /** 263 | * Returns the internal byte array, without defensively copying. Therefore do NOT modify the 264 | * returned array. 265 | */ 266 | public byte[] getBytes() { 267 | return bytes; 268 | } 269 | 270 | /** 271 | * For pb return ByteString. 272 | */ 273 | public ByteString getByteString() { 274 | return ByteString.copyFrom(bytes); 275 | } 276 | 277 | @Override 278 | public int compareTo(final Sha256Hash other) { 279 | for (int i = LENGTH - 1; i >= 0; i--) { 280 | final int thisByte = this.bytes[i] & 0xff; 281 | final int otherByte = other.bytes[i] & 0xff; 282 | if (thisByte > otherByte) { 283 | return 1; 284 | } 285 | if (thisByte < otherByte) { 286 | return -1; 287 | } 288 | } 289 | return 0; 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/utils/ByteUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.utils; 20 | 21 | import com.google.common.base.Preconditions; 22 | import com.google.common.primitives.UnsignedBytes; 23 | import java.math.BigInteger; 24 | import java.nio.ByteBuffer; 25 | import java.util.Arrays; 26 | import org.spongycastle.util.encoders.Hex; 27 | 28 | public class ByteUtil { 29 | 30 | public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; 31 | public static final byte[] ZERO_BYTE_ARRAY = new byte[]{0}; 32 | 33 | 34 | /** 35 | * return a cloned byte array. return null if parameter data is null 36 | */ 37 | public static byte[] cloneBytes(byte[] data) { 38 | if (data == null) { 39 | return null; 40 | } 41 | 42 | int length = data.length; 43 | byte[] rc = new byte[length]; 44 | if (length > 0) { 45 | System.arraycopy(data, 0, rc, 0, length); 46 | } 47 | return rc; 48 | } 49 | 50 | /** 51 | * The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need: 52 | * it appends a leading zero to indicate that the number is positive and may need padding. 53 | * 54 | * @param b the integer to format into a byte array 55 | * @param numBytes the desired size of the resulting byte array 56 | * @return numBytes byte long array. 57 | */ 58 | public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) { 59 | if (b == null) { 60 | return null; 61 | } 62 | byte[] bytes = new byte[numBytes]; 63 | byte[] biBytes = b.toByteArray(); 64 | int start = (biBytes.length == numBytes + 1) ? 1 : 0; 65 | int length = Math.min(biBytes.length, numBytes); 66 | System.arraycopy(biBytes, start, bytes, numBytes - length, length); 67 | return bytes; 68 | } 69 | 70 | /** 71 | * Omitting sign indication byte.

Instead of {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)} 72 | *
we use this custom method to avoid an empty array in case of BigInteger.ZERO 73 | * 74 | * @param value - any big integer number. A null-value will return null 75 | * @return A byte array without a leading zero byte if present in the signed encoding. 76 | * BigInteger.ZERO will return an array with length 1 and byte-value 0. 77 | */ 78 | public static byte[] bigIntegerToBytes(BigInteger value) { 79 | if (value == null) { 80 | return null; 81 | } 82 | 83 | byte[] data = value.toByteArray(); 84 | 85 | if (data.length != 1 && data[0] == 0) { 86 | byte[] tmp = new byte[data.length - 1]; 87 | System.arraycopy(data, 1, tmp, 0, tmp.length); 88 | data = tmp; 89 | } 90 | return data; 91 | } 92 | 93 | /** 94 | * merge arrays. 95 | * 96 | * @param arrays - arrays to merge 97 | * @return - merged array 98 | */ 99 | public static byte[] merge(byte[]... arrays) { 100 | int count = 0; 101 | for (byte[] array : arrays) { 102 | count += array.length; 103 | } 104 | 105 | // Create new array and copy all array contents 106 | byte[] mergedArray = new byte[count]; 107 | int start = 0; 108 | for (byte[] array : arrays) { 109 | System.arraycopy(array, 0, mergedArray, start, array.length); 110 | start += array.length; 111 | } 112 | return mergedArray; 113 | } 114 | 115 | /** 116 | * Creates a copy of bytes and appends b to the end of it. 117 | */ 118 | public static byte[] appendByte(byte[] bytes, byte b) { 119 | byte[] result = Arrays.copyOf(bytes, bytes.length + 1); 120 | result[result.length - 1] = b; 121 | return result; 122 | } 123 | 124 | /** 125 | * Turn nibbles to a pretty looking output string Example. [ 1, 2, 3, 4, 5 ] becomes 126 | * '\x11\x23\x45' 127 | * 128 | * @param nibbles - getting byte of data [ 04 ] and turning it to a '\x04' representation 129 | * @return pretty string of nibbles 130 | */ 131 | public static String nibblesToPrettyString(byte[] nibbles) { 132 | StringBuilder builder = new StringBuilder(); 133 | for (byte nibble : nibbles) { 134 | final String nibbleString = oneByteToHexString(nibble); 135 | builder.append("\\x").append(nibbleString); 136 | } 137 | return builder.toString(); 138 | } 139 | 140 | /** 141 | * get hex string data from byte data. 142 | */ 143 | public static String oneByteToHexString(byte value) { 144 | String retVal = Integer.toString(value & 0xFF, 16); 145 | if (retVal.length() == 1) { 146 | retVal = "0" + retVal; 147 | } 148 | return retVal; 149 | } 150 | 151 | /** 152 | * Convert a byte-array into a hex String.
Works similar to {@link Hex#toHexString} but allows 153 | * for null 154 | * 155 | * @param data - byte-array to convert to a hex-string 156 | * @return hex representation of the data.
Returns an empty String if the input is 157 | * null 158 | * @see Hex#toHexString 159 | */ 160 | public static String toHexString(byte[] data) { 161 | return data == null ? "" : Hex.toHexString(data); 162 | } 163 | 164 | /** 165 | * Cast hex encoded value from byte[] to int Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes) 166 | * 167 | * @param b array contains the values 168 | * @return unsigned positive int value. 169 | */ 170 | public static int byteArrayToInt(byte[] b) { 171 | if (b == null || b.length == 0) { 172 | return 0; 173 | } 174 | return new BigInteger(1, b).intValue(); 175 | } 176 | 177 | public static boolean isSingleZero(byte[] array) { 178 | return (array.length == 1 && array[0] == 0); 179 | } 180 | 181 | /** 182 | * Converts a int value into a byte array. 183 | * 184 | * @param val - int value to convert 185 | * @return value with leading byte that are zeroes striped 186 | */ 187 | public static byte[] intToBytesNoLeadZeroes(int val) { 188 | 189 | if (val == 0) { 190 | return EMPTY_BYTE_ARRAY; 191 | } 192 | 193 | int lenght = 0; 194 | 195 | int tmpVal = val; 196 | while (tmpVal != 0) { 197 | tmpVal = tmpVal >>> 8; 198 | ++lenght; 199 | } 200 | 201 | byte[] result = new byte[lenght]; 202 | 203 | int index = result.length - 1; 204 | while (val != 0) { 205 | 206 | result[index] = (byte) (val & 0xFF); 207 | val = val >>> 8; 208 | index -= 1; 209 | } 210 | 211 | return result; 212 | } 213 | 214 | /** 215 | * Converts int value into a byte array. 216 | * 217 | * @param val - int value to convert 218 | * @return byte[] of length 4, representing the int value 219 | */ 220 | public static byte[] intToBytes(int val) { 221 | return ByteBuffer.allocate(4).putInt(val).array(); 222 | } 223 | 224 | /** 225 | * Cast hex encoded value from byte[] to BigInteger null is parsed like byte[0] 226 | * 227 | * @param bb byte array contains the values 228 | * @return unsigned positive BigInteger value. 229 | */ 230 | public static BigInteger bytesToBigInteger(byte[] bb) { 231 | return (bb == null || bb.length == 0) ? BigInteger.ZERO : new BigInteger(1, bb); 232 | } 233 | 234 | /** 235 | * Cast hex encoded value from byte[] to long null is parsed like byte[0] 236 | * 237 | * Limited to Long.MAX_VALUE: 263-1 (8 bytes) 238 | * 239 | * @param b array contains the values 240 | * @return unsigned positive long value. 241 | */ 242 | public static long byteArrayToLong(byte[] b) { 243 | if (b == null || b.length == 0) { 244 | return 0; 245 | } 246 | return new BigInteger(1, b).longValueExact(); 247 | } 248 | 249 | public static int firstNonZeroByte(byte[] data) { 250 | for (int i = 0; i < data.length; ++i) { 251 | if (data[i] != 0) { 252 | return i; 253 | } 254 | } 255 | return -1; 256 | } 257 | 258 | public static byte[] stripLeadingZeroes(byte[] data) { 259 | 260 | if (data == null) { 261 | return null; 262 | } 263 | 264 | final int firstNonZero = firstNonZeroByte(data); 265 | switch (firstNonZero) { 266 | case -1: 267 | return ZERO_BYTE_ARRAY; 268 | 269 | case 0: 270 | return data; 271 | 272 | default: 273 | byte[] result = new byte[data.length - firstNonZero]; 274 | System.arraycopy(data, firstNonZero, result, 0, data.length - firstNonZero); 275 | 276 | return result; 277 | } 278 | } 279 | 280 | /** 281 | * Utility function to copy a byte array into a new byte array with given size. If the src length 282 | * is smaller than the given size, the result will be left-padded with zeros. 283 | * 284 | * @param value - a BigInteger with a maximum value of 2^256-1 285 | * @return Byte array of given size with a copy of the src 286 | */ 287 | public static byte[] copyToArray(BigInteger value) { 288 | byte[] dest = ByteBuffer.allocate(32).array(); 289 | byte[] src = ByteUtil.bigIntegerToBytes(value); 290 | if (src != null) { 291 | System.arraycopy(src, 0, dest, dest.length - src.length, src.length); 292 | } 293 | return dest; 294 | } 295 | 296 | /** 297 | * Returns a number of zero bits preceding the highest-order ("leftmost") one-bit interpreting 298 | * input array as a big-endian integer value 299 | */ 300 | public static int numberOfLeadingZeros(byte[] bytes) { 301 | 302 | int i = firstNonZeroByte(bytes); 303 | 304 | if (i == -1) { 305 | return bytes.length * 8; 306 | } else { 307 | int byteLeadingZeros = Integer.numberOfLeadingZeros((int) bytes[i] & 0xff) - 24; 308 | return i * 8 + byteLeadingZeros; 309 | } 310 | } 311 | 312 | /** 313 | * Parses fixed number of bytes starting from {@code offset} in {@code input} array. If {@code 314 | * input} has not enough bytes return array will be right padded with zero bytes. I.e. if {@code 315 | * offset} is higher than {@code input.length} then zero byte array of length {@code len} will be 316 | * returned 317 | */ 318 | public static byte[] parseBytes(byte[] input, int offset, int len) { 319 | 320 | if (offset >= input.length || len == 0) { 321 | return EMPTY_BYTE_ARRAY; 322 | } 323 | 324 | byte[] bytes = new byte[len]; 325 | System.arraycopy(input, offset, bytes, 0, Math.min(input.length - offset, len)); 326 | return bytes; 327 | } 328 | 329 | /** 330 | * Parses 32-bytes word from given input. Uses {@link #parseBytes(byte[], int, int)} method, thus, 331 | * result will be right-padded with zero bytes if there is not enough bytes in {@code input} 332 | * 333 | * @param idx an index of the word starting from {@code 0} 334 | */ 335 | public static byte[] parseWord(byte[] input, int idx) { 336 | return parseBytes(input, 32 * idx, 32); 337 | } 338 | 339 | /** 340 | * Parses 32-bytes word from given input. Uses {@link #parseBytes(byte[], int, int)} method, thus, 341 | * result will be right-padded with zero bytes if there is not enough bytes in {@code input} 342 | * 343 | * @param idx an index of the word starting from {@code 0} 344 | * @param offset an offset in {@code input} array to start parsing from 345 | */ 346 | public static byte[] parseWord(byte[] input, int offset, int idx) { 347 | return parseBytes(input, offset + 32 * idx, 32); 348 | } 349 | 350 | public static boolean greater(byte[] bytes1, byte[] bytes2) { 351 | return compare(bytes1, bytes2) > 0; 352 | } 353 | 354 | public static boolean greaterOrEquals(byte[] bytes1, byte[] bytes2) { 355 | return compare(bytes1, bytes2) >= 0; 356 | } 357 | 358 | public static boolean less(byte[] bytes1, byte[] bytes2) { 359 | return compare(bytes1, bytes2) < 0; 360 | } 361 | 362 | public static boolean lessOrEquals(byte[] bytes1, byte[] bytes2) { 363 | return compare(bytes1, bytes2) <= 0; 364 | } 365 | 366 | public static boolean equals(byte[] bytes1, byte[] bytes2) { 367 | return compare(bytes1, bytes2) == 0; 368 | } 369 | 370 | // lexicographical order 371 | public static int compare(byte[] bytes1, byte[] bytes2) { 372 | Preconditions.checkNotNull(bytes1); 373 | Preconditions.checkNotNull(bytes2); 374 | Preconditions.checkArgument(bytes1.length == bytes2.length); 375 | int length = bytes1.length; 376 | for (int i = 0; i < length; ++i) { 377 | int ret = UnsignedBytes.compare(bytes1[i], bytes2[i]); 378 | if (ret != 0) { 379 | return ret; 380 | } 381 | } 382 | 383 | return 0; 384 | } 385 | 386 | } -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/query/QueryFactory.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.query; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONArray; 5 | import com.alibaba.fastjson.JSONObject; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | import org.apache.commons.lang3.ArrayUtils; 11 | import org.pf4j.util.StringUtils; 12 | import org.spongycastle.util.encoders.Hex; 13 | import org.springframework.data.domain.PageRequest; 14 | import org.springframework.data.domain.Pageable; 15 | import org.springframework.data.domain.Sort; 16 | import org.springframework.data.mongodb.core.query.Criteria; 17 | import org.springframework.data.mongodb.core.query.Query; 18 | import org.tron.common.crypto.Hash; 19 | import org.tron.common.runtime.vm.DataWord; 20 | import org.tron.common.runtime.vm.LogInfo; 21 | import org.tron.trongeventquery.contractevents.ContractEventTriggerEntity; 22 | import org.tron.trongeventquery.contractlogs.ContractLogTriggerEntity; 23 | import org.tron.trongeventquery.contractlogs.DataWordEntity; 24 | import org.tron.trongeventquery.contractlogs.LogInfoEntity; 25 | 26 | public class QueryFactory { 27 | 28 | private Query query; 29 | 30 | public static final String findByContractAndEventSinceTimestamp = "{ 'contractAddress' : ?0, " 31 | + "'event_name': ?1, " 32 | + "'$or' : [ {'block_timestamp' : ?2}, {'block_timestamp' : {$gt : ?2}} ], " 33 | + "'resource_Node' : {$exists : true} }"; 34 | 35 | public static final String findByContractSinceTimeStamp = "{ 'contractAddress' : ?0, " 36 | + "'$or' : [ {'block_timestamp' : ?1}, {'block_timestamp' : {$gt : ?1}} ], " 37 | + "'resource_Node' : {$exists : true}}"; 38 | 39 | public static Pageable make_pagination(int pageNum, int pageSize, String sortProperty) { 40 | 41 | if (sortProperty.charAt(0) == '-') { 42 | return PageRequest.of(pageNum, pageSize, Sort.Direction.DESC, sortProperty.substring(1)); 43 | } 44 | 45 | return PageRequest.of(pageNum, pageSize, Sort.Direction.ASC, sortProperty); 46 | } 47 | 48 | public static boolean isBool(String s) { 49 | return s.equalsIgnoreCase("true") || s.equalsIgnoreCase("false"); 50 | } 51 | 52 | public QueryFactory() { 53 | this.query = new Query(); 54 | } 55 | 56 | public void setTransactionIdEqual(String hash) { 57 | this.query.addCriteria(Criteria.where("transactionId").is(hash)); 58 | } 59 | 60 | public void setBlockHashEqual(String hash) { 61 | this.query.addCriteria(Criteria.where("blockHash").is(hash)); 62 | } 63 | 64 | public void setTransferType() { 65 | Criteria criteria = new Criteria(); 66 | criteria.orOperator(Criteria.where("contractType").is("TransferContract"), 67 | Criteria.where("contractType").is("TransferAssetContract")); 68 | this.query.addCriteria(criteria); 69 | } 70 | 71 | public void setContractTypeEqual(String contractType) { 72 | this.query.addCriteria(Criteria.where("contractType").is(contractType)); 73 | } 74 | 75 | public void setTransactionFromAddr(String fromAddr) { 76 | this.query.addCriteria(Criteria.where("fromAddress").is(fromAddr)); 77 | } 78 | 79 | public void setTransactionToAddr(String toAddr) { 80 | this.query.addCriteria(Criteria.where("toAddress").is(toAddr)); 81 | } 82 | 83 | public void setTransactionToken(String token) { 84 | this.query.addCriteria(Criteria.where("assetName").is(token)); 85 | } 86 | 87 | public void setTimestampGreaterEqual(long timestamp) { 88 | this.query.addCriteria(Criteria.where("timeStamp").gte(timestamp)); 89 | } 90 | 91 | public void setUniqueIdEqual(String uniqueId) { 92 | this.query.addCriteria(Criteria.where("uniqueId").is(uniqueId)); 93 | } 94 | 95 | public void setRemovedEqual(boolean removed) { 96 | this.query.addCriteria(Criteria.where("removed").is(removed)); 97 | } 98 | 99 | public void findAllTransferByAddress(String address) { 100 | setTransferType(); 101 | 102 | this.query.addCriteria(Criteria.where("contractAddress").is(address)); 103 | } 104 | 105 | public void setContractAddress(String addr) { 106 | this.query.addCriteria(Criteria.where("contractAddress").is(addr)); 107 | } 108 | 109 | public void setPageniate(Pageable page) { 110 | this.query.with(page); 111 | } 112 | 113 | public void setEventName(String event) { 114 | this.query.addCriteria(Criteria.where("eventName").is(event)); 115 | } 116 | 117 | public void setBlockNum(long block) { 118 | this.query.addCriteria(Criteria.where("blockNumber").is(block)); 119 | } 120 | 121 | public void setBlockNumGte(long block) { 122 | this.query.addCriteria(Criteria.where("blockNumber").gte(block)); 123 | } 124 | 125 | public void setBlockNumGt(long block) { 126 | this.query.addCriteria(Criteria.where("blockNumber").gt(block)); 127 | } 128 | 129 | public void setBlockNumLte(long block) { 130 | this.query.addCriteria(Criteria.where("blockNumber").lte(block)); 131 | } 132 | 133 | public String toString() { 134 | return this.query.toString(); 135 | } 136 | 137 | public Query getQuery() { 138 | return this.query; 139 | } 140 | 141 | public static List parseLogWithAbiByLog( 142 | List triggers, 143 | String abi) { 144 | List result = new ArrayList<>(); 145 | Map abiStrMap = new HashMap<>(); 146 | Map abiJsonMap = new HashMap<>(); 147 | 148 | parseAbi(abi, abiStrMap, abiJsonMap); 149 | 150 | for (ContractLogTriggerEntity trigger : triggers) { 151 | LogInfoEntity logInfoEntity = trigger.getRawData(); 152 | if (logInfoEntity == null){ 153 | result.add(trigger); 154 | continue; 155 | } 156 | List topics = logInfoEntity.getTopics(); 157 | List mTopics = new ArrayList<>(); 158 | for (DataWordEntity t : topics) { 159 | mTopics.add(new DataWord(t.getData())); 160 | } 161 | LogInfo logInfo = new LogInfo(Hex.decode(logInfoEntity.getAddress()), mTopics, Hex.decode(logInfoEntity.getData())); 162 | String logHash = getLogHash(logInfo); 163 | 164 | if (abiStrMap.get(logHash) == null) { 165 | ContractLogTriggerEntity event = new ContractLogTriggerEntity( 166 | logInfo.getHexTopics(), 167 | logInfo.getHexData(), 168 | trigger.getTransactionId(), 169 | trigger.getContractAddress(), 170 | trigger.getCallerAddress(), 171 | trigger.getOriginAddress(), 172 | trigger.getCreatorAddress(), 173 | trigger.getBlockNumber(), 174 | trigger.getRemoved(), 175 | trigger.getLatestSolidifiedBlockNumber(), 176 | trigger.getTimeStamp(), 177 | trigger.getTriggerName(), 178 | trigger.getUniqueId(), 179 | trigger.getRawData(), 180 | trigger.getAbiString() 181 | ); 182 | 183 | result.add(event); 184 | } 185 | } 186 | 187 | return result; 188 | } 189 | 190 | public static List parseEventWithAbiByLog( 191 | List triggers, 192 | String abi) { 193 | List result = new ArrayList<>(); 194 | Map abiStrMap = new HashMap<>(); 195 | Map abiJsonMap = new HashMap<>(); 196 | 197 | parseAbi(abi, abiStrMap, abiJsonMap); 198 | 199 | for (ContractLogTriggerEntity trigger : triggers) { 200 | LogInfoEntity logInfoEntity = trigger.getRawData(); 201 | if (logInfoEntity == null){ 202 | continue; 203 | } 204 | List topics = logInfoEntity.getTopics(); 205 | List mTopics = new ArrayList<>(); 206 | for (DataWordEntity t : topics) { 207 | mTopics.add(new DataWord(t.getData())); 208 | } 209 | LogInfo logInfo = new LogInfo(Hex.decode(logInfoEntity.getAddress()), mTopics, Hex.decode(logInfoEntity.getData())); 210 | String logHash = getLogHash(logInfo); 211 | 212 | if (abiStrMap.get(logHash) != null) { 213 | List topicList = logInfo.getClonedTopics(); 214 | byte[] data = logInfo.getClonedData(); 215 | 216 | Map topicMap = ContractEventParserJson 217 | .parseTopics(topicList, abiJsonMap.get(logHash)); 218 | Map dataMap = ContractEventParserJson 219 | .parseEventData(data, topicList, abiJsonMap.get(logHash)); 220 | ContractEventTriggerEntity event = new ContractEventTriggerEntity( 221 | abiStrMap.get(logHash), 222 | topicMap, 223 | trigger.getLatestSolidifiedBlockNumber(), 224 | dataMap, 225 | trigger.getTransactionId(), 226 | trigger.getContractAddress(), 227 | trigger.getCallerAddress(), 228 | trigger.getOriginAddress(), 229 | trigger.getCreatorAddress(), 230 | trigger.getBlockNumber(), 231 | trigger.getRemoved(), 232 | trigger.getTimeStamp(), 233 | trigger.getTriggerName(), 234 | abiStrMap.get(logHash + "_full"), 235 | abiStrMap.get(logHash + "_name"), 236 | trigger.getUniqueId(), 237 | trigger.getRawData(), 238 | trigger.getAbiString() 239 | ); 240 | result.add(event); 241 | } 242 | } 243 | 244 | return result; 245 | } 246 | 247 | public static List parseLogWithAbiByEvent( 248 | List triggers, 249 | String abi) { 250 | List result = new ArrayList<>(); 251 | Map abiStrMap = new HashMap<>(); 252 | Map abiJsonMap = new HashMap<>(); 253 | 254 | parseAbi(abi, abiStrMap, abiJsonMap); 255 | 256 | for (ContractEventTriggerEntity trigger : triggers) { 257 | LogInfoEntity logInfoEntity = trigger.getRawData(); 258 | if (logInfoEntity == null){ 259 | continue; 260 | } 261 | List topics = logInfoEntity.getTopics(); 262 | List mTopics = new ArrayList<>(); 263 | for (DataWordEntity t : topics) { 264 | mTopics.add(new DataWord(t.getData())); 265 | } 266 | LogInfo logInfo = new LogInfo(Hex.decode(logInfoEntity.getAddress()), mTopics, Hex.decode(logInfoEntity.getData())); 267 | String logHash = getLogHash(logInfo); 268 | 269 | if (abiStrMap.get(logHash) == null) { 270 | ContractLogTriggerEntity event = new ContractLogTriggerEntity( 271 | logInfo.getHexTopics(), 272 | logInfo.getHexData(), 273 | trigger.getTransactionId(), 274 | trigger.getContractAddress(), 275 | trigger.getCallerAddress(), 276 | trigger.getOriginAddress(), 277 | trigger.getCreatorAddress(), 278 | trigger.getBlockNumber(), 279 | trigger.getRemoved(), 280 | trigger.getLatestSolidifiedBlockNumber(), 281 | trigger.getTimeStamp(), 282 | trigger.getTriggerName(), 283 | trigger.getUniqueId(), 284 | trigger.getRawData(), 285 | trigger.getAbiString() 286 | ); 287 | 288 | result.add(event); 289 | } 290 | } 291 | 292 | return result; 293 | } 294 | 295 | public static List parseEventWithAbiByEvent( 296 | List triggers, 297 | String abi) { 298 | List result = new ArrayList<>(); 299 | Map abiStrMap = new HashMap<>(); 300 | Map abiJsonMap = new HashMap<>(); 301 | 302 | parseAbi(abi, abiStrMap, abiJsonMap); 303 | 304 | for (ContractEventTriggerEntity trigger : triggers) { 305 | LogInfoEntity logInfoEntity = trigger.getRawData(); 306 | if (logInfoEntity == null){ 307 | result.add(trigger); 308 | continue; 309 | } 310 | List topics = logInfoEntity.getTopics(); 311 | List mTopics = new ArrayList<>(); 312 | for (DataWordEntity t : topics) { 313 | mTopics.add(new DataWord(t.getData())); 314 | } 315 | LogInfo logInfo = new LogInfo(Hex.decode(logInfoEntity.getAddress()), mTopics, Hex.decode(logInfoEntity.getData())); 316 | String logHash = getLogHash(logInfo); 317 | 318 | if (abiStrMap.get(logHash) != null) { 319 | List topicList = logInfo.getClonedTopics(); 320 | byte[] data = logInfo.getClonedData(); 321 | 322 | Map topicMap = ContractEventParserJson 323 | .parseTopics(topicList, abiJsonMap.get(logHash)); 324 | Map dataMap = ContractEventParserJson 325 | .parseEventData(data, topicList, abiJsonMap.get(logHash)); 326 | ContractEventTriggerEntity event = new ContractEventTriggerEntity( 327 | abiStrMap.get(logHash), 328 | topicMap, 329 | trigger.getLatestSolidifiedBlockNumber(), 330 | dataMap, 331 | trigger.getTransactionId(), 332 | trigger.getContractAddress(), 333 | trigger.getCallerAddress(), 334 | trigger.getOriginAddress(), 335 | trigger.getCreatorAddress(), 336 | trigger.getBlockNumber(), 337 | trigger.getRemoved(), 338 | trigger.getTimeStamp(), 339 | trigger.getTriggerName(), 340 | abiStrMap.get(logHash + "_full"), 341 | abiStrMap.get(logHash + "_name"), 342 | trigger.getUniqueId(), 343 | trigger.getRawData(), 344 | trigger.getAbiString() 345 | ); 346 | result.add(event); 347 | } 348 | } 349 | 350 | return result; 351 | } 352 | 353 | public static void parseAbi(String abiString, 354 | Map abiStrMap, 355 | Map abiJsonMap) { 356 | 357 | JSONObject abi = null; 358 | JSONArray entrys = null; 359 | 360 | Object abiObj = JSON.parse(abiString); 361 | if (abiObj instanceof JSONObject) { 362 | abi = (JSONObject) abiObj; 363 | entrys = abi.getJSONArray("entrys"); 364 | } else if (abiObj instanceof JSONArray) { 365 | entrys = (JSONArray) abiObj; 366 | } 367 | 368 | if (entrys != null) { 369 | for (int i = 0; i < entrys.size(); i++) { 370 | JSONObject entry = entrys.getJSONObject(i); 371 | 372 | String funcType = entry.getString("type"); 373 | Boolean anonymous = entry.getBoolean("anonymous"); 374 | if (funcType == null || !funcType.equalsIgnoreCase("event")) { 375 | continue; 376 | } 377 | 378 | if (anonymous != null && anonymous) { 379 | continue; 380 | } 381 | 382 | String inputStr = entry.getString("name") + "("; 383 | String inputFullStr = entry.getString("name") + "("; 384 | StringBuilder inputBuilder = new StringBuilder(); 385 | StringBuilder inputFullBuilder = new StringBuilder(); 386 | JSONArray inputs = entry.getJSONArray("inputs"); 387 | if (inputs != null) { 388 | for (int j = 0; j < inputs.size(); j++) { 389 | if (inputBuilder.length() > 0) { 390 | inputBuilder.append(","); 391 | inputFullBuilder.append(","); 392 | } 393 | String type = inputs.getJSONObject(j).getString("type"); 394 | String name = inputs.getJSONObject(j).getString("name"); 395 | inputBuilder.append(type); 396 | inputFullBuilder.append(type); 397 | if (StringUtils.isNotNullOrEmpty(name)) { 398 | inputFullBuilder.append(" ").append(name); 399 | } 400 | } 401 | } 402 | inputStr += inputBuilder.toString() + ")"; 403 | inputFullStr += inputFullBuilder.toString() + ")"; 404 | String inputSha3 = Hex.toHexString(Hash.sha3(inputStr.getBytes())); 405 | 406 | abiStrMap.put(inputSha3, inputStr); 407 | abiStrMap.put(inputSha3 + "_full", inputFullStr); 408 | abiStrMap.put(inputSha3 + "_name", entry.getString("name")); 409 | abiJsonMap.put(inputSha3, entry); 410 | } 411 | } 412 | } 413 | 414 | public static String getLogHash(LogInfo logInfo) { 415 | String logHash = ""; 416 | List topics = logInfo.getTopics(); 417 | if (topics != null && !topics.isEmpty() && !ArrayUtils.isEmpty(topics.get(0).getData())) { 418 | logHash = topics.get(0).toString(); 419 | } 420 | 421 | return logHash; 422 | } 423 | 424 | public static Pageable setPagniateVariable(int start, int size, String sort) { 425 | int page = start; 426 | int pageSize = size; 427 | return make_pagination(Math.max(0, page - 1), Math.min(200, pageSize), sort); 428 | } 429 | } 430 | -------------------------------------------------------------------------------- /src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) [2016] [ ] 3 | * This file is part of the ethereumJ library. 4 | * 5 | * The ethereumJ library is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The ethereumJ library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with the ethereumJ library. If not, see . 17 | */ 18 | 19 | package org.tron.common.crypto.cryptohash; 20 | 21 | abstract class KeccakCore extends DigestEngine { 22 | 23 | private static final long[] RC = { 24 | 0x0000000000000001L, 0x0000000000008082L, 25 | 0x800000000000808AL, 0x8000000080008000L, 26 | 0x000000000000808BL, 0x0000000080000001L, 27 | 0x8000000080008081L, 0x8000000000008009L, 28 | 0x000000000000008AL, 0x0000000000000088L, 29 | 0x0000000080008009L, 0x000000008000000AL, 30 | 0x000000008000808BL, 0x800000000000008BL, 31 | 0x8000000000008089L, 0x8000000000008003L, 32 | 0x8000000000008002L, 0x8000000000000080L, 33 | 0x000000000000800AL, 0x800000008000000AL, 34 | 0x8000000080008081L, 0x8000000000008080L, 35 | 0x0000000080000001L, 0x8000000080008008L 36 | }; 37 | private long[] A; 38 | private byte[] tmpOut; 39 | 40 | KeccakCore(String alg) { 41 | super(alg); 42 | } 43 | 44 | /** 45 | * Encode the 64-bit word {@code val} into the array {@code buf} at offset {@code off}, in 46 | * little-endian convention (least significant byte first). 47 | * 48 | * @param val the value to encode 49 | * @param buf the destination buffer 50 | * @param off the destination offset 51 | */ 52 | private static void encodeLELong(long val, byte[] buf, int off) { 53 | buf[off + 0] = (byte) val; 54 | buf[off + 1] = (byte) (val >>> 8); 55 | buf[off + 2] = (byte) (val >>> 16); 56 | buf[off + 3] = (byte) (val >>> 24); 57 | buf[off + 4] = (byte) (val >>> 32); 58 | buf[off + 5] = (byte) (val >>> 40); 59 | buf[off + 6] = (byte) (val >>> 48); 60 | buf[off + 7] = (byte) (val >>> 56); 61 | } 62 | 63 | /** 64 | * Decode a 64-bit little-endian word from the array {@code buf} at offset {@code off}. 65 | * 66 | * @param buf the source buffer 67 | * @param off the source offset 68 | * @return the decoded value 69 | */ 70 | private static long decodeLELong(byte[] buf, int off) { 71 | return (buf[off + 0] & 0xFFL) 72 | | ((buf[off + 1] & 0xFFL) << 8) 73 | | ((buf[off + 2] & 0xFFL) << 16) 74 | | ((buf[off + 3] & 0xFFL) << 24) 75 | | ((buf[off + 4] & 0xFFL) << 32) 76 | | ((buf[off + 5] & 0xFFL) << 40) 77 | | ((buf[off + 6] & 0xFFL) << 48) 78 | | ((buf[off + 7] & 0xFFL) << 56); 79 | } 80 | 81 | protected void engineReset() { 82 | doReset(); 83 | } 84 | 85 | protected void processBlock(byte[] data) { 86 | /* Input block */ 87 | for (int i = 0; i < data.length; i += 8) { 88 | A[i >>> 3] ^= decodeLELong(data, i); 89 | } 90 | 91 | long t0, t1, t2, t3, t4; 92 | long tt0, tt1, tt2, tt3, tt4; 93 | long t, kt; 94 | long c0, c1, c2, c3, c4, bnn; 95 | 96 | /* 97 | * Unrolling four rounds kills performance big time 98 | * on Intel x86 Core2, in both 32-bit and 64-bit modes 99 | * (less than 1 MB/s instead of 55 MB/s on x86-64). 100 | * Unrolling two rounds appears to be fine. 101 | */ 102 | for (int j = 0; j < 24; j += 2) { 103 | 104 | tt0 = A[1] ^ A[6]; 105 | tt1 = A[11] ^ A[16]; 106 | tt0 ^= A[21] ^ tt1; 107 | tt0 = (tt0 << 1) | (tt0 >>> 63); 108 | tt2 = A[4] ^ A[9]; 109 | tt3 = A[14] ^ A[19]; 110 | tt0 ^= A[24]; 111 | tt2 ^= tt3; 112 | t0 = tt0 ^ tt2; 113 | 114 | tt0 = A[2] ^ A[7]; 115 | tt1 = A[12] ^ A[17]; 116 | tt0 ^= A[22] ^ tt1; 117 | tt0 = (tt0 << 1) | (tt0 >>> 63); 118 | tt2 = A[0] ^ A[5]; 119 | tt3 = A[10] ^ A[15]; 120 | tt0 ^= A[20]; 121 | tt2 ^= tt3; 122 | t1 = tt0 ^ tt2; 123 | 124 | tt0 = A[3] ^ A[8]; 125 | tt1 = A[13] ^ A[18]; 126 | tt0 ^= A[23] ^ tt1; 127 | tt0 = (tt0 << 1) | (tt0 >>> 63); 128 | tt2 = A[1] ^ A[6]; 129 | tt3 = A[11] ^ A[16]; 130 | tt0 ^= A[21]; 131 | tt2 ^= tt3; 132 | t2 = tt0 ^ tt2; 133 | 134 | tt0 = A[4] ^ A[9]; 135 | tt1 = A[14] ^ A[19]; 136 | tt0 ^= A[24] ^ tt1; 137 | tt0 = (tt0 << 1) | (tt0 >>> 63); 138 | tt2 = A[2] ^ A[7]; 139 | tt3 = A[12] ^ A[17]; 140 | tt0 ^= A[22]; 141 | tt2 ^= tt3; 142 | t3 = tt0 ^ tt2; 143 | 144 | tt0 = A[0] ^ A[5]; 145 | tt1 = A[10] ^ A[15]; 146 | tt0 ^= A[20] ^ tt1; 147 | tt0 = (tt0 << 1) | (tt0 >>> 63); 148 | tt2 = A[3] ^ A[8]; 149 | tt3 = A[13] ^ A[18]; 150 | tt0 ^= A[23]; 151 | tt2 ^= tt3; 152 | t4 = tt0 ^ tt2; 153 | 154 | A[0] = A[0] ^ t0; 155 | A[5] = A[5] ^ t0; 156 | A[10] = A[10] ^ t0; 157 | A[15] = A[15] ^ t0; 158 | A[20] = A[20] ^ t0; 159 | A[1] = A[1] ^ t1; 160 | A[6] = A[6] ^ t1; 161 | A[11] = A[11] ^ t1; 162 | A[16] = A[16] ^ t1; 163 | A[21] = A[21] ^ t1; 164 | A[2] = A[2] ^ t2; 165 | A[7] = A[7] ^ t2; 166 | A[12] = A[12] ^ t2; 167 | A[17] = A[17] ^ t2; 168 | A[22] = A[22] ^ t2; 169 | A[3] = A[3] ^ t3; 170 | A[8] = A[8] ^ t3; 171 | A[13] = A[13] ^ t3; 172 | A[18] = A[18] ^ t3; 173 | A[23] = A[23] ^ t3; 174 | A[4] = A[4] ^ t4; 175 | A[9] = A[9] ^ t4; 176 | A[14] = A[14] ^ t4; 177 | A[19] = A[19] ^ t4; 178 | A[24] = A[24] ^ t4; 179 | A[5] = (A[5] << 36) | (A[5] >>> (64 - 36)); 180 | A[10] = (A[10] << 3) | (A[10] >>> (64 - 3)); 181 | A[15] = (A[15] << 41) | (A[15] >>> (64 - 41)); 182 | A[20] = (A[20] << 18) | (A[20] >>> (64 - 18)); 183 | A[1] = (A[1] << 1) | (A[1] >>> (64 - 1)); 184 | A[6] = (A[6] << 44) | (A[6] >>> (64 - 44)); 185 | A[11] = (A[11] << 10) | (A[11] >>> (64 - 10)); 186 | A[16] = (A[16] << 45) | (A[16] >>> (64 - 45)); 187 | A[21] = (A[21] << 2) | (A[21] >>> (64 - 2)); 188 | A[2] = (A[2] << 62) | (A[2] >>> (64 - 62)); 189 | A[7] = (A[7] << 6) | (A[7] >>> (64 - 6)); 190 | A[12] = (A[12] << 43) | (A[12] >>> (64 - 43)); 191 | A[17] = (A[17] << 15) | (A[17] >>> (64 - 15)); 192 | A[22] = (A[22] << 61) | (A[22] >>> (64 - 61)); 193 | A[3] = (A[3] << 28) | (A[3] >>> (64 - 28)); 194 | A[8] = (A[8] << 55) | (A[8] >>> (64 - 55)); 195 | A[13] = (A[13] << 25) | (A[13] >>> (64 - 25)); 196 | A[18] = (A[18] << 21) | (A[18] >>> (64 - 21)); 197 | A[23] = (A[23] << 56) | (A[23] >>> (64 - 56)); 198 | A[4] = (A[4] << 27) | (A[4] >>> (64 - 27)); 199 | A[9] = (A[9] << 20) | (A[9] >>> (64 - 20)); 200 | A[14] = (A[14] << 39) | (A[14] >>> (64 - 39)); 201 | A[19] = (A[19] << 8) | (A[19] >>> (64 - 8)); 202 | A[24] = (A[24] << 14) | (A[24] >>> (64 - 14)); 203 | bnn = ~A[12]; 204 | kt = A[6] | A[12]; 205 | c0 = A[0] ^ kt; 206 | kt = bnn | A[18]; 207 | c1 = A[6] ^ kt; 208 | kt = A[18] & A[24]; 209 | c2 = A[12] ^ kt; 210 | kt = A[24] | A[0]; 211 | c3 = A[18] ^ kt; 212 | kt = A[0] & A[6]; 213 | c4 = A[24] ^ kt; 214 | A[0] = c0; 215 | A[6] = c1; 216 | A[12] = c2; 217 | A[18] = c3; 218 | A[24] = c4; 219 | bnn = ~A[22]; 220 | kt = A[9] | A[10]; 221 | c0 = A[3] ^ kt; 222 | kt = A[10] & A[16]; 223 | c1 = A[9] ^ kt; 224 | kt = A[16] | bnn; 225 | c2 = A[10] ^ kt; 226 | kt = A[22] | A[3]; 227 | c3 = A[16] ^ kt; 228 | kt = A[3] & A[9]; 229 | c4 = A[22] ^ kt; 230 | A[3] = c0; 231 | A[9] = c1; 232 | A[10] = c2; 233 | A[16] = c3; 234 | A[22] = c4; 235 | bnn = ~A[19]; 236 | kt = A[7] | A[13]; 237 | c0 = A[1] ^ kt; 238 | kt = A[13] & A[19]; 239 | c1 = A[7] ^ kt; 240 | kt = bnn & A[20]; 241 | c2 = A[13] ^ kt; 242 | kt = A[20] | A[1]; 243 | c3 = bnn ^ kt; 244 | kt = A[1] & A[7]; 245 | c4 = A[20] ^ kt; 246 | A[1] = c0; 247 | A[7] = c1; 248 | A[13] = c2; 249 | A[19] = c3; 250 | A[20] = c4; 251 | bnn = ~A[17]; 252 | kt = A[5] & A[11]; 253 | c0 = A[4] ^ kt; 254 | kt = A[11] | A[17]; 255 | c1 = A[5] ^ kt; 256 | kt = bnn | A[23]; 257 | c2 = A[11] ^ kt; 258 | kt = A[23] & A[4]; 259 | c3 = bnn ^ kt; 260 | kt = A[4] | A[5]; 261 | c4 = A[23] ^ kt; 262 | A[4] = c0; 263 | A[5] = c1; 264 | A[11] = c2; 265 | A[17] = c3; 266 | A[23] = c4; 267 | bnn = ~A[8]; 268 | kt = bnn & A[14]; 269 | c0 = A[2] ^ kt; 270 | kt = A[14] | A[15]; 271 | c1 = bnn ^ kt; 272 | kt = A[15] & A[21]; 273 | c2 = A[14] ^ kt; 274 | kt = A[21] | A[2]; 275 | c3 = A[15] ^ kt; 276 | kt = A[2] & A[8]; 277 | c4 = A[21] ^ kt; 278 | A[2] = c0; 279 | A[8] = c1; 280 | A[14] = c2; 281 | A[15] = c3; 282 | A[21] = c4; 283 | A[0] = A[0] ^ RC[j + 0]; 284 | 285 | tt0 = A[6] ^ A[9]; 286 | tt1 = A[7] ^ A[5]; 287 | tt0 ^= A[8] ^ tt1; 288 | tt0 = (tt0 << 1) | (tt0 >>> 63); 289 | tt2 = A[24] ^ A[22]; 290 | tt3 = A[20] ^ A[23]; 291 | tt0 ^= A[21]; 292 | tt2 ^= tt3; 293 | t0 = tt0 ^ tt2; 294 | 295 | tt0 = A[12] ^ A[10]; 296 | tt1 = A[13] ^ A[11]; 297 | tt0 ^= A[14] ^ tt1; 298 | tt0 = (tt0 << 1) | (tt0 >>> 63); 299 | tt2 = A[0] ^ A[3]; 300 | tt3 = A[1] ^ A[4]; 301 | tt0 ^= A[2]; 302 | tt2 ^= tt3; 303 | t1 = tt0 ^ tt2; 304 | 305 | tt0 = A[18] ^ A[16]; 306 | tt1 = A[19] ^ A[17]; 307 | tt0 ^= A[15] ^ tt1; 308 | tt0 = (tt0 << 1) | (tt0 >>> 63); 309 | tt2 = A[6] ^ A[9]; 310 | tt3 = A[7] ^ A[5]; 311 | tt0 ^= A[8]; 312 | tt2 ^= tt3; 313 | t2 = tt0 ^ tt2; 314 | 315 | tt0 = A[24] ^ A[22]; 316 | tt1 = A[20] ^ A[23]; 317 | tt0 ^= A[21] ^ tt1; 318 | tt0 = (tt0 << 1) | (tt0 >>> 63); 319 | tt2 = A[12] ^ A[10]; 320 | tt3 = A[13] ^ A[11]; 321 | tt0 ^= A[14]; 322 | tt2 ^= tt3; 323 | t3 = tt0 ^ tt2; 324 | 325 | tt0 = A[0] ^ A[3]; 326 | tt1 = A[1] ^ A[4]; 327 | tt0 ^= A[2] ^ tt1; 328 | tt0 = (tt0 << 1) | (tt0 >>> 63); 329 | tt2 = A[18] ^ A[16]; 330 | tt3 = A[19] ^ A[17]; 331 | tt0 ^= A[15]; 332 | tt2 ^= tt3; 333 | t4 = tt0 ^ tt2; 334 | 335 | A[0] = A[0] ^ t0; 336 | A[3] = A[3] ^ t0; 337 | A[1] = A[1] ^ t0; 338 | A[4] = A[4] ^ t0; 339 | A[2] = A[2] ^ t0; 340 | A[6] = A[6] ^ t1; 341 | A[9] = A[9] ^ t1; 342 | A[7] = A[7] ^ t1; 343 | A[5] = A[5] ^ t1; 344 | A[8] = A[8] ^ t1; 345 | A[12] = A[12] ^ t2; 346 | A[10] = A[10] ^ t2; 347 | A[13] = A[13] ^ t2; 348 | A[11] = A[11] ^ t2; 349 | A[14] = A[14] ^ t2; 350 | A[18] = A[18] ^ t3; 351 | A[16] = A[16] ^ t3; 352 | A[19] = A[19] ^ t3; 353 | A[17] = A[17] ^ t3; 354 | A[15] = A[15] ^ t3; 355 | A[24] = A[24] ^ t4; 356 | A[22] = A[22] ^ t4; 357 | A[20] = A[20] ^ t4; 358 | A[23] = A[23] ^ t4; 359 | A[21] = A[21] ^ t4; 360 | A[3] = (A[3] << 36) | (A[3] >>> (64 - 36)); 361 | A[1] = (A[1] << 3) | (A[1] >>> (64 - 3)); 362 | A[4] = (A[4] << 41) | (A[4] >>> (64 - 41)); 363 | A[2] = (A[2] << 18) | (A[2] >>> (64 - 18)); 364 | A[6] = (A[6] << 1) | (A[6] >>> (64 - 1)); 365 | A[9] = (A[9] << 44) | (A[9] >>> (64 - 44)); 366 | A[7] = (A[7] << 10) | (A[7] >>> (64 - 10)); 367 | A[5] = (A[5] << 45) | (A[5] >>> (64 - 45)); 368 | A[8] = (A[8] << 2) | (A[8] >>> (64 - 2)); 369 | A[12] = (A[12] << 62) | (A[12] >>> (64 - 62)); 370 | A[10] = (A[10] << 6) | (A[10] >>> (64 - 6)); 371 | A[13] = (A[13] << 43) | (A[13] >>> (64 - 43)); 372 | A[11] = (A[11] << 15) | (A[11] >>> (64 - 15)); 373 | A[14] = (A[14] << 61) | (A[14] >>> (64 - 61)); 374 | A[18] = (A[18] << 28) | (A[18] >>> (64 - 28)); 375 | A[16] = (A[16] << 55) | (A[16] >>> (64 - 55)); 376 | A[19] = (A[19] << 25) | (A[19] >>> (64 - 25)); 377 | A[17] = (A[17] << 21) | (A[17] >>> (64 - 21)); 378 | A[15] = (A[15] << 56) | (A[15] >>> (64 - 56)); 379 | A[24] = (A[24] << 27) | (A[24] >>> (64 - 27)); 380 | A[22] = (A[22] << 20) | (A[22] >>> (64 - 20)); 381 | A[20] = (A[20] << 39) | (A[20] >>> (64 - 39)); 382 | A[23] = (A[23] << 8) | (A[23] >>> (64 - 8)); 383 | A[21] = (A[21] << 14) | (A[21] >>> (64 - 14)); 384 | bnn = ~A[13]; 385 | kt = A[9] | A[13]; 386 | c0 = A[0] ^ kt; 387 | kt = bnn | A[17]; 388 | c1 = A[9] ^ kt; 389 | kt = A[17] & A[21]; 390 | c2 = A[13] ^ kt; 391 | kt = A[21] | A[0]; 392 | c3 = A[17] ^ kt; 393 | kt = A[0] & A[9]; 394 | c4 = A[21] ^ kt; 395 | A[0] = c0; 396 | A[9] = c1; 397 | A[13] = c2; 398 | A[17] = c3; 399 | A[21] = c4; 400 | bnn = ~A[14]; 401 | kt = A[22] | A[1]; 402 | c0 = A[18] ^ kt; 403 | kt = A[1] & A[5]; 404 | c1 = A[22] ^ kt; 405 | kt = A[5] | bnn; 406 | c2 = A[1] ^ kt; 407 | kt = A[14] | A[18]; 408 | c3 = A[5] ^ kt; 409 | kt = A[18] & A[22]; 410 | c4 = A[14] ^ kt; 411 | A[18] = c0; 412 | A[22] = c1; 413 | A[1] = c2; 414 | A[5] = c3; 415 | A[14] = c4; 416 | bnn = ~A[23]; 417 | kt = A[10] | A[19]; 418 | c0 = A[6] ^ kt; 419 | kt = A[19] & A[23]; 420 | c1 = A[10] ^ kt; 421 | kt = bnn & A[2]; 422 | c2 = A[19] ^ kt; 423 | kt = A[2] | A[6]; 424 | c3 = bnn ^ kt; 425 | kt = A[6] & A[10]; 426 | c4 = A[2] ^ kt; 427 | A[6] = c0; 428 | A[10] = c1; 429 | A[19] = c2; 430 | A[23] = c3; 431 | A[2] = c4; 432 | bnn = ~A[11]; 433 | kt = A[3] & A[7]; 434 | c0 = A[24] ^ kt; 435 | kt = A[7] | A[11]; 436 | c1 = A[3] ^ kt; 437 | kt = bnn | A[15]; 438 | c2 = A[7] ^ kt; 439 | kt = A[15] & A[24]; 440 | c3 = bnn ^ kt; 441 | kt = A[24] | A[3]; 442 | c4 = A[15] ^ kt; 443 | A[24] = c0; 444 | A[3] = c1; 445 | A[7] = c2; 446 | A[11] = c3; 447 | A[15] = c4; 448 | bnn = ~A[16]; 449 | kt = bnn & A[20]; 450 | c0 = A[12] ^ kt; 451 | kt = A[20] | A[4]; 452 | c1 = bnn ^ kt; 453 | kt = A[4] & A[8]; 454 | c2 = A[20] ^ kt; 455 | kt = A[8] | A[12]; 456 | c3 = A[4] ^ kt; 457 | kt = A[12] & A[16]; 458 | c4 = A[8] ^ kt; 459 | A[12] = c0; 460 | A[16] = c1; 461 | A[20] = c2; 462 | A[4] = c3; 463 | A[8] = c4; 464 | A[0] = A[0] ^ RC[j + 1]; 465 | t = A[5]; 466 | A[5] = A[18]; 467 | A[18] = A[11]; 468 | A[11] = A[10]; 469 | A[10] = A[6]; 470 | A[6] = A[22]; 471 | A[22] = A[20]; 472 | A[20] = A[12]; 473 | A[12] = A[19]; 474 | A[19] = A[15]; 475 | A[15] = A[24]; 476 | A[24] = A[8]; 477 | A[8] = t; 478 | t = A[1]; 479 | A[1] = A[9]; 480 | A[9] = A[14]; 481 | A[14] = A[2]; 482 | A[2] = A[13]; 483 | A[13] = A[23]; 484 | A[23] = A[4]; 485 | A[4] = A[21]; 486 | A[21] = A[16]; 487 | A[16] = A[3]; 488 | A[3] = A[17]; 489 | A[17] = A[7]; 490 | A[7] = t; 491 | } 492 | } 493 | 494 | protected void doPadding(byte[] out, int off) { 495 | int ptr = flush(); 496 | byte[] buf = getBlockBuffer(); 497 | if ((ptr + 1) == buf.length) { 498 | buf[ptr] = (byte) 0x81; 499 | } else { 500 | buf[ptr] = (byte) 0x01; 501 | for (int i = ptr + 1; i < (buf.length - 1); i++) { 502 | buf[i] = 0; 503 | } 504 | buf[buf.length - 1] = (byte) 0x80; 505 | } 506 | processBlock(buf); 507 | A[1] = ~A[1]; 508 | A[2] = ~A[2]; 509 | A[8] = ~A[8]; 510 | A[12] = ~A[12]; 511 | A[17] = ~A[17]; 512 | A[20] = ~A[20]; 513 | int dlen = engineGetDigestLength(); 514 | for (int i = 0; i < dlen; i += 8) { 515 | encodeLELong(A[i >>> 3], tmpOut, i); 516 | } 517 | System.arraycopy(tmpOut, 0, out, off, dlen); 518 | } 519 | 520 | protected void doInit() { 521 | A = new long[25]; 522 | tmpOut = new byte[(engineGetDigestLength() + 7) & ~7]; 523 | doReset(); 524 | } 525 | 526 | public int getBlockLength() { 527 | return 200 - 2 * engineGetDigestLength(); 528 | } 529 | 530 | private final void doReset() { 531 | for (int i = 0; i < 25; i++) { 532 | A[i] = 0; 533 | } 534 | A[1] = 0xFFFFFFFFFFFFFFFFL; 535 | A[2] = 0xFFFFFFFFFFFFFFFFL; 536 | A[8] = 0xFFFFFFFFFFFFFFFFL; 537 | A[12] = 0xFFFFFFFFFFFFFFFFL; 538 | A[17] = 0xFFFFFFFFFFFFFFFFL; 539 | A[20] = 0xFFFFFFFFFFFFFFFFL; 540 | } 541 | 542 | protected Digest copyState(KeccakCore dst) { 543 | System.arraycopy(A, 0, dst.A, 0, 25); 544 | return super.copyState(dst); 545 | } 546 | 547 | public String toString() { 548 | return "Keccak-" + (engineGetDigestLength() << 3); 549 | } 550 | } 551 | -------------------------------------------------------------------------------- /src/main/java/org/tron/trongeventquery/monitor/MonitorInfo.java: -------------------------------------------------------------------------------- 1 | package org.tron.trongeventquery.monitor; 2 | 3 | 4 | import lombok.extern.slf4j.Slf4j; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | @Slf4j 10 | public class MonitorInfo { 11 | private int status; 12 | private String msg; 13 | private DataInfo data; 14 | 15 | public int getStatus() { 16 | return this.status; 17 | } 18 | 19 | public MonitorInfo setStatus(int status) { 20 | this.status = status; 21 | return this; 22 | } 23 | 24 | public String getMsg() { 25 | return this.msg; 26 | } 27 | 28 | public MonitorInfo setMsg(String msg) { 29 | this.msg = msg; 30 | return this; 31 | } 32 | 33 | public DataInfo getDataInfo() { 34 | return this.data; 35 | } 36 | 37 | public MonitorInfo setDataInfo(DataInfo data) { 38 | this.data = data; 39 | return this; 40 | } 41 | 42 | // public MonitorInfo ToProtoEntity() { 43 | // Protocol.MonitorInfo.Builder builder = Protocol.MonitorInfo.newBuilder(); 44 | // builder.setStatus(getStatus()); 45 | // builder.setMsg(getMsg()); 46 | // Protocol.MonitorInfo.DataInfo.Builder dataInfo = Protocol.MonitorInfo.DataInfo.newBuilder(); 47 | // DataInfo data = getDataInfo(); 48 | // dataInfo.setInterval(data.getInterval()); 49 | // 50 | // Protocol.MonitorInfo.DataInfo.NodeInfo.Builder nodeInfo = 51 | // Protocol.MonitorInfo.DataInfo.NodeInfo.newBuilder(); 52 | // DataInfo.NodeInfo node = data.getNodeInfo(); 53 | // nodeInfo.setIp(node.getIp()); 54 | // nodeInfo.setType(node.getType()); 55 | // nodeInfo.setStatus(node.getType()); 56 | // nodeInfo.setVersion(node.getVersion()); 57 | // nodeInfo.setNoUpgradedSRCount(node.getNoUpgradedSRCount()); 58 | // 59 | // for (DataInfo.NodeInfo.NoUpgradedSR noUpgradedSR : node.getNoUpgradedSRList()) { 60 | // Protocol.MonitorInfo.DataInfo.NodeInfo.NoUpgradedSR.Builder noUpgradeSRProto = 61 | // Protocol.MonitorInfo.DataInfo.NodeInfo.NoUpgradedSR.newBuilder(); 62 | // noUpgradeSRProto.setAddress(noUpgradedSR.getAddress()); 63 | // noUpgradeSRProto.setUrl(noUpgradedSR.getUrl()); 64 | // nodeInfo.addNoUpgradedSRList(noUpgradeSRProto.build()); 65 | // } 66 | // // set node info 67 | // dataInfo.setNode(nodeInfo.build()); 68 | // 69 | // Protocol.MonitorInfo.DataInfo.BlockChainInfo.Builder blockChain = 70 | // Protocol.MonitorInfo.DataInfo.BlockChainInfo.newBuilder(); 71 | // DataInfo.BlochainInfo BlockChain = data.getBlockchainInfo(); 72 | // blockChain.setHeadBlockTimestamp(BlockChain.getHeadBlockTimestamp()); 73 | // blockChain.setHeadBlockHash(BlockChain.getHeadBlockHash()); 74 | // blockChain.setBlockProcessTime(BlockChain.getBlockProcessTime()); 75 | // blockChain.setForkCount(BlockChain.getForkCount()); 76 | // blockChain.setHeadBlockNum(BlockChain.getHeadBlockNum()); 77 | // blockChain.setTxCacheSize(BlockChain.getTxCacheSize()); 78 | // blockChain.setMissedTxCount(BlockChain.getMissTxCount()); 79 | // 80 | // Protocol.MonitorInfo.DataInfo.BlockChainInfo.TPSInfo.Builder tpsInfo = 81 | // Protocol.MonitorInfo.DataInfo.BlockChainInfo.TPSInfo.newBuilder(); 82 | // DataInfo.BlochainInfo.TPSInfo TpsInfo = BlockChain.getTPS(); 83 | // tpsInfo.setMeanRate(TpsInfo.getMeanRate()); 84 | // tpsInfo.setOneMinuteRate(TpsInfo.getOneMinuteRate()); 85 | // tpsInfo.setFiveMinuteRate(TpsInfo.getFiveMinuteRate()); 86 | // tpsInfo.setFifteenMinuteRate(TpsInfo.getFifteenMinuteRate()); 87 | // blockChain.setTPS(tpsInfo.build()); 88 | // // set blockchain info 89 | // dataInfo.setBlockchain(blockChain.build()); 90 | // 91 | // 92 | // Protocol.MonitorInfo.DataInfo.NetInfo.Builder netInfo = 93 | // Protocol.MonitorInfo.DataInfo.NetInfo.newBuilder(); 94 | // DataInfo.NetInfo NetInfo = data.getNetInfo(); 95 | // netInfo.setConnectionCount(NetInfo.getConnectionCount()); 96 | // netInfo.setValidConnectionCount(NetInfo.getValidConnectionCount()); 97 | // netInfo.setErrorProtoCount(NetInfo.getErrorProtoCount()); 98 | // netInfo.setTCPInTraffic(NetInfo.getTCPInTraffic()); 99 | // netInfo.setTCPOutTraffic(NetInfo.getTCPOutTraffic()); 100 | // netInfo.setDisconnectionCount(NetInfo.getDisconnectionCount()); 101 | // netInfo.setUDPInTraffic(NetInfo.getUDPInTraffic()); 102 | // netInfo.setUDPOutTraffic(NetInfo.getUDPOutTraffic()); 103 | // 104 | // Protocol.MonitorInfo.DataInfo.NetInfo.ApiInfo.Builder apiInfo = 105 | // Protocol.MonitorInfo.DataInfo.NetInfo.ApiInfo.newBuilder(); 106 | // apiInfo.setTotalCount(NetInfo.getApi().getTotalCount()); 107 | // apiInfo.setTotalFailCount(NetInfo.getApi().getTotalFailCount()); 108 | // for (DataInfo.NetInfo.ApiInfo.ApiDetailInfo ApiDetail : NetInfo.getApi().getApiDetailInfo()) { 109 | // Protocol.MonitorInfo.DataInfo.NetInfo.ApiInfo.ApiDetailInfo.Builder apiDetail = 110 | // Protocol.MonitorInfo.DataInfo.NetInfo.ApiInfo.ApiDetailInfo.newBuilder(); 111 | // apiDetail.setName(ApiDetail.getName()); 112 | // apiDetail.setCount(ApiDetail.getCount()); 113 | // apiDetail.setFailCount(ApiDetail.getFailCount()); 114 | // apiInfo.addDetail(apiDetail.build()); 115 | // } 116 | // netInfo.setApi(apiInfo.build()); 117 | // 118 | // 119 | // for (DataInfo.NetInfo.DisconnectionDetailInfo DisconnectionDetail : NetInfo 120 | // .getDisconnectionDetail()) { 121 | // Protocol.MonitorInfo.DataInfo.NetInfo.DisconnectionDetailInfo.Builder disconnectionDetail = 122 | // Protocol.MonitorInfo.DataInfo.NetInfo.DisconnectionDetailInfo.newBuilder(); 123 | // disconnectionDetail.setReason(DisconnectionDetail.getReason()); 124 | // disconnectionDetail.setCount(DisconnectionDetail.getCount()); 125 | // netInfo.addDisconnectionDetail(disconnectionDetail.build()); 126 | // } 127 | // 128 | // Protocol.MonitorInfo.DataInfo.NetInfo.LatencyInfo.Builder latencyInfo = 129 | // Protocol.MonitorInfo.DataInfo.NetInfo.LatencyInfo.newBuilder(); 130 | // latencyInfo.setDelay1S(NetInfo.getLatency().getDelay1S()); 131 | // latencyInfo.setDelay2S(NetInfo.getLatency().getDelay2S()); 132 | // latencyInfo.setDelay3S(NetInfo.getLatency().getDelay3S()); 133 | // latencyInfo.setTop99(NetInfo.getLatency().getTop99()); 134 | // latencyInfo.setTop95(NetInfo.getLatency().getTop95()); 135 | // latencyInfo.setTotalCount(NetInfo.getLatency().getTotalCount()); 136 | // 137 | // for (DataInfo.NetInfo.LatencyInfo.LatencyDetailInfo LatencyDetailInfo : NetInfo.getLatency() 138 | // .getLatencyDetailInfo()) { 139 | // Protocol.MonitorInfo.DataInfo.NetInfo.LatencyInfo.LatencyDetailInfo.Builder latencyDetail = 140 | // Protocol.MonitorInfo.DataInfo.NetInfo.LatencyInfo.LatencyDetailInfo.newBuilder(); 141 | // latencyDetail.setCount(LatencyDetailInfo.getCount()); 142 | // latencyDetail.setWitness(LatencyDetailInfo.getWitness()); 143 | // latencyDetail.setTop99(LatencyDetailInfo.getTop99()); 144 | // latencyDetail.setTop95(LatencyDetailInfo.getTop95()); 145 | // latencyDetail.setDelay1S(LatencyDetailInfo.getDelay1S()); 146 | // latencyDetail.setDelay2S(LatencyDetailInfo.getDelay2S()); 147 | // latencyDetail.setDelay3S(LatencyDetailInfo.getDelay3S()); 148 | // latencyInfo.addDetail(latencyDetail.build()); 149 | // } 150 | // 151 | // // set latency info 152 | // netInfo.setLatency(latencyInfo.build()); 153 | // // set net info 154 | // dataInfo.setNet(netInfo.build()); 155 | // // set data info 156 | // builder.setData(dataInfo.build()); 157 | // return builder.build(); 158 | // } 159 | 160 | 161 | public static class DataInfo { 162 | private int interval; 163 | private NetInfo net; 164 | 165 | public int getInterval() { 166 | return this.interval; 167 | } 168 | 169 | public DataInfo setInterval(int interval) { 170 | this.interval = interval; 171 | return this; 172 | } 173 | 174 | public NetInfo getNetInfo() { 175 | return this.net; 176 | } 177 | 178 | public DataInfo setNetInfo(NetInfo net) { 179 | this.net = net; 180 | return this; 181 | } 182 | 183 | // network monitor information 184 | public static class NetInfo { 185 | private int errorProtoCount; 186 | private ApiInfo api; 187 | private int connectionCount; 188 | private int validConnectionCount; 189 | private long TCPInTraffic; 190 | private long TCPOutTraffic; 191 | private int disconnectionCount; 192 | private List disconnectionDetail = new ArrayList<>(); 193 | private long UDPInTraffic; 194 | private long UDPOutTraffic; 195 | private LatencyInfo latency; 196 | 197 | public int getErrorProtoCount() { 198 | return this.errorProtoCount; 199 | } 200 | 201 | public NetInfo setErrorProtoCount(int errorProtoCount) { 202 | this.errorProtoCount = errorProtoCount; 203 | return this; 204 | } 205 | 206 | public ApiInfo getApi() { 207 | return this.api; 208 | } 209 | 210 | public NetInfo setApi(ApiInfo api) { 211 | this.api = api; 212 | return this; 213 | } 214 | 215 | public int getConnectionCount() { 216 | return this.connectionCount; 217 | } 218 | 219 | public NetInfo setConnectionCount(int connectionCount) { 220 | this.connectionCount = connectionCount; 221 | return this; 222 | } 223 | 224 | public int getValidConnectionCount() { 225 | return this.validConnectionCount; 226 | } 227 | 228 | public NetInfo setValidConnectionCount(int validConnectionCount) { 229 | this.validConnectionCount = validConnectionCount; 230 | return this; 231 | } 232 | 233 | public long getTCPInTraffic() { 234 | return this.TCPInTraffic; 235 | } 236 | 237 | public NetInfo setTCPInTraffic(long TCPInTraffic) { 238 | this.TCPInTraffic = TCPInTraffic; 239 | return this; 240 | } 241 | 242 | public long getTCPOutTraffic() { 243 | return this.TCPOutTraffic; 244 | } 245 | 246 | public NetInfo setTCPOutTraffic(long TCPOutTraffic) { 247 | this.TCPOutTraffic = TCPOutTraffic; 248 | return this; 249 | } 250 | 251 | public int getDisconnectionCount() { 252 | return this.disconnectionCount; 253 | } 254 | 255 | public NetInfo setDisconnectionCount(int disconnectionCount) { 256 | this.disconnectionCount = disconnectionCount; 257 | return this; 258 | } 259 | 260 | public List getDisconnectionDetail() { 261 | return this.disconnectionDetail; 262 | } 263 | 264 | public NetInfo setDisconnectionDetail(List disconnectionDetail) { 265 | this.disconnectionDetail = disconnectionDetail; 266 | return this; 267 | } 268 | 269 | public long getUDPInTraffic() { 270 | return this.UDPInTraffic; 271 | } 272 | 273 | public NetInfo setUDPInTraffic(long UDPInTraffic) { 274 | this.UDPInTraffic = UDPInTraffic; 275 | return this; 276 | } 277 | 278 | public long getUDPOutTraffic() { 279 | return this.UDPOutTraffic; 280 | } 281 | 282 | public NetInfo setUDPOutTraffic(long UDPOutTraffic) { 283 | this.UDPOutTraffic = UDPOutTraffic; 284 | return this; 285 | } 286 | 287 | public LatencyInfo getLatency() { 288 | return this.latency; 289 | } 290 | 291 | public NetInfo setLatency(LatencyInfo latency) { 292 | this.latency = latency; 293 | return this; 294 | } 295 | 296 | // API monitor information 297 | public static class ApiInfo { 298 | private int totalCount; 299 | private int totalFailCount; 300 | private int totalCount2xx; 301 | private int totalCount4xx; 302 | private int totalCount5xx; 303 | 304 | private List detail = new ArrayList<>(); 305 | 306 | public int getTotalCount() { 307 | return this.totalCount; 308 | } 309 | 310 | public ApiInfo setTotalCount(int totalCount) { 311 | this.totalCount = totalCount; 312 | return this; 313 | } 314 | 315 | public int getTotalFailCount() { 316 | return this.totalFailCount; 317 | } 318 | 319 | public ApiInfo setTotalFailCount(int totalFailCount) { 320 | this.totalFailCount = totalFailCount; 321 | return this; 322 | } 323 | 324 | public int getTotalCount2xx() { 325 | return this.totalCount2xx; 326 | } 327 | 328 | public ApiInfo setTotalCount2xx(int totalCount2xx) { 329 | this.totalCount2xx = totalCount2xx; 330 | return this; 331 | } 332 | 333 | public int getTotalCount4xx() { 334 | return this.totalCount4xx; 335 | } 336 | 337 | public ApiInfo setTotalCount4xx(int totalCount4xx) { 338 | this.totalCount4xx = totalCount4xx; 339 | return this; 340 | } 341 | 342 | public int getTotalCount5xx() { 343 | return this.totalCount5xx; 344 | } 345 | 346 | public ApiInfo setTotalCount5xx(int totalCount5xx) { 347 | this.totalCount5xx = totalCount5xx; 348 | return this; 349 | } 350 | 351 | public List getApiDetailInfo() { 352 | return this.detail; 353 | } 354 | 355 | public ApiInfo setApiDetailInfo(List detail) { 356 | this.detail = detail; 357 | return this; 358 | } 359 | 360 | public static class ApiDetailInfo { 361 | private String name; 362 | private int count; 363 | private int failCount; 364 | private int count4xx; 365 | private int count5xx; 366 | private int count2xx; 367 | 368 | 369 | public String getName() { 370 | return this.name; 371 | } 372 | 373 | public ApiDetailInfo setName(String name) { 374 | this.name = name; 375 | return this; 376 | } 377 | 378 | public int getCount() { 379 | return this.count; 380 | } 381 | 382 | public ApiDetailInfo setCount(int count) { 383 | this.count = count; 384 | return this; 385 | } 386 | 387 | public int getFailCount() { 388 | return this.failCount; 389 | } 390 | 391 | public ApiDetailInfo setFailCount(int failCount) { 392 | this.failCount = failCount; 393 | return this; 394 | } 395 | 396 | public int getCount4xx() { 397 | return this.count4xx; 398 | } 399 | 400 | public ApiDetailInfo setCount4xx(int count4xx) { 401 | this.count4xx = count4xx; 402 | return this; 403 | } 404 | 405 | public int getCount5xx() { 406 | return this.count5xx; 407 | } 408 | 409 | public ApiDetailInfo setCount5xx(int count5xx) { 410 | this.count5xx = count5xx; 411 | return this; 412 | } 413 | public int getCount2xx() { 414 | return this.count2xx; 415 | } 416 | 417 | public ApiDetailInfo setCount2xx(int count2xx) { 418 | this.count2xx = count2xx; 419 | return this; 420 | } 421 | } 422 | } 423 | 424 | // disconnection monitor information 425 | public static class DisconnectionDetailInfo { 426 | private String reason; 427 | private int count; 428 | 429 | public String getReason() { 430 | return this.reason; 431 | } 432 | 433 | public DisconnectionDetailInfo setReason(String reason) { 434 | this.reason = reason; 435 | return this; 436 | } 437 | 438 | public int getCount() { 439 | return this.count; 440 | } 441 | 442 | public DisconnectionDetailInfo setCount(int count) { 443 | this.count = count; 444 | return this; 445 | } 446 | 447 | } 448 | 449 | // latency monitor information 450 | public static class LatencyInfo { 451 | private int top99; 452 | private int top95; 453 | private int totalCount; 454 | private int delay1S; 455 | private int delay2S; 456 | private int delay3S; 457 | private List detail = new ArrayList<>(); 458 | 459 | public int getTop99() { 460 | return this.top99; 461 | } 462 | 463 | public LatencyInfo setTop99(int top99) { 464 | this.top99 = top99; 465 | return this; 466 | } 467 | 468 | public int getTop95() { 469 | return this.top95; 470 | } 471 | 472 | public LatencyInfo setTop95(int top95) { 473 | this.top95 = top95; 474 | return this; 475 | } 476 | 477 | public int getTotalCount() { 478 | return this.totalCount; 479 | } 480 | 481 | public LatencyInfo setTotalCount(int totalCount) { 482 | this.totalCount = totalCount; 483 | return this; 484 | } 485 | 486 | public int getDelay1S() { 487 | return this.delay1S; 488 | } 489 | 490 | public LatencyInfo setDelay1S(int delay1S) { 491 | this.delay1S = delay1S; 492 | return this; 493 | } 494 | 495 | public int getDelay2S() { 496 | return this.delay2S; 497 | } 498 | 499 | public LatencyInfo setDelay2S(int delay2S) { 500 | this.delay2S = delay2S; 501 | return this; 502 | } 503 | 504 | public int getDelay3S() { 505 | return this.delay3S; 506 | } 507 | 508 | public LatencyInfo setDelay3S(int delay3S) { 509 | this.delay3S = delay3S; 510 | return this; 511 | } 512 | 513 | public List getLatencyDetailInfo() { 514 | return this.detail; 515 | } 516 | 517 | public LatencyInfo setLatencyDetailInfo(List detail) { 518 | this.detail = detail; 519 | return this; 520 | } 521 | 522 | public static class LatencyDetailInfo { 523 | private String witness; 524 | private int top99; 525 | private int top95; 526 | private int count; 527 | private int delay1S; 528 | private int delay2S; 529 | private int delay3S; 530 | 531 | public String getWitness() { 532 | return this.witness; 533 | } 534 | 535 | public LatencyDetailInfo setWitness(String witness) { 536 | this.witness = witness; 537 | return this; 538 | } 539 | 540 | public int getTop99() { 541 | return this.top99; 542 | } 543 | 544 | public LatencyDetailInfo setTop99(int top99) { 545 | this.top99 = top99; 546 | return this; 547 | } 548 | 549 | public int getTop95() { 550 | return this.top95; 551 | } 552 | 553 | public LatencyDetailInfo setTop95(int top95) { 554 | this.top95 = top95; 555 | return this; 556 | } 557 | 558 | public int getCount() { 559 | return this.count; 560 | } 561 | 562 | public LatencyDetailInfo setCount(int count) { 563 | this.count = count; 564 | return this; 565 | } 566 | 567 | public int getDelay1S() { 568 | return this.delay1S; 569 | } 570 | 571 | public LatencyDetailInfo setDelay1S(int delay1S) { 572 | this.delay1S = delay1S; 573 | return this; 574 | } 575 | 576 | public int getDelay2S() { 577 | return this.delay2S; 578 | } 579 | 580 | public LatencyDetailInfo setDelay2S(int delay2S) { 581 | this.delay2S = delay2S; 582 | return this; 583 | } 584 | 585 | public int getDelay3S() { 586 | return this.delay3S; 587 | } 588 | 589 | public LatencyDetailInfo setDelay3S(int delay3S) { 590 | this.delay3S = delay3S; 591 | return this; 592 | } 593 | 594 | } 595 | } 596 | 597 | } 598 | 599 | 600 | } 601 | } 602 | --------------------------------------------------------------------------------