diff --git a/chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java b/chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java index 496a0fd09ac..ba6c77d43a2 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java @@ -15,6 +15,8 @@ public abstract class AbstractSnapshot implements Snapshot { protected WeakReference next; + protected boolean isOptimized; + @Override public Snapshot advance() { return new SnapshotImpl(this); @@ -34,4 +36,9 @@ public void setNext(Snapshot next) { public String getDbName() { return db.getDbName(); } + + @Override + public boolean isOptimized(){ + return isOptimized; + } } diff --git a/chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java b/chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java index e1ca149b207..75545dc29b4 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java @@ -46,4 +46,8 @@ static boolean isImpl(Snapshot snapshot) { void updateSolidity(); String getDbName(); + + boolean isOptimized(); + + void reloadToMem(); } diff --git a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java index ae8073f668b..bc31b406b30 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java @@ -30,6 +30,10 @@ public class SnapshotImpl extends AbstractSnapshot { } previous = snapshot; snapshot.setNext(this); + isOptimized = snapshot.isOptimized(); + if (isOptimized && root == previous) { + Streams.stream(root.iterator()).forEach( e -> put(e.getKey(),e.getValue())); + } } @Override @@ -40,6 +44,7 @@ public byte[] get(byte[] key) { private byte[] get(Snapshot head, byte[] key) { Snapshot snapshot = head; Value value; + while (Snapshot.isImpl(snapshot)) { if ((value = ((SnapshotImpl) snapshot).db.get(Key.of(key))) != null) { return value.getBytes(); @@ -83,6 +88,19 @@ public void merge(Snapshot from) { Streams.stream(fromImpl.db).forEach(e -> db.put(e.getKey(), e.getValue())); } + public void mergeAhead(Snapshot from) { + if (from instanceof SnapshotRoot) { + return ; + } + SnapshotImpl fromImpl = (SnapshotImpl) from; + Streams.stream(fromImpl.db).forEach(e -> { + if (db.get(e.getKey()) == null) { + db.put(e.getKey(), e.getValue()); + } + } + ); + } + @Override public Snapshot retreat() { return previous; @@ -177,4 +195,9 @@ public String getDbName() { public Snapshot newInstance() { return new SnapshotImpl(this); } + + @Override + public void reloadToMem() { + mergeAhead(previous); + } } diff --git a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java index f5de96e5587..f0f169ae340 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java @@ -221,6 +221,12 @@ public synchronized void commit() { } --activeSession; + + dbs.forEach(db -> { + if (db.getHead().isOptimized()) { + db.getHead().reloadToMem(); + } + }); } public synchronized void pop() { diff --git a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java index 709e2ae1b62..f95cf68dafe 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java @@ -38,6 +38,7 @@ public SnapshotRoot(DB db) { if (CACHE_DBS.contains(this.db.getDbName())) { this.cache = CacheManager.allocate(CacheType.findByType(this.db.getDbName())); } + isOptimized = "properties".equalsIgnoreCase(db.getDbName()); } private boolean needOptAsset() { @@ -221,4 +222,7 @@ public String getDbName() { public Snapshot newInstance() { return new SnapshotRoot(db.newInstance()); } + + @Override + public void reloadToMem() { } } diff --git a/common/src/main/java/org/tron/common/logsfilter/trigger/TransactionLogTrigger.java b/common/src/main/java/org/tron/common/logsfilter/trigger/TransactionLogTrigger.java index dec4170efb8..a4fb1fddb79 100644 --- a/common/src/main/java/org/tron/common/logsfilter/trigger/TransactionLogTrigger.java +++ b/common/src/main/java/org/tron/common/logsfilter/trigger/TransactionLogTrigger.java @@ -1,6 +1,8 @@ package org.tron.common.logsfilter.trigger; import java.util.List; +import java.util.Map; + import lombok.Getter; import lombok.Setter; @@ -91,6 +93,10 @@ public class TransactionLogTrigger extends Trigger { @Setter private long energyUnitPrice; + @Getter + @Setter + private Map extMap; + public TransactionLogTrigger() { setTriggerName(Trigger.TRANSACTION_TRIGGER_NAME); } diff --git a/framework/src/main/java/org/tron/common/application/Application.java b/framework/src/main/java/org/tron/common/application/Application.java index fdc0abc19e0..3d7e7a10864 100644 --- a/framework/src/main/java/org/tron/common/application/Application.java +++ b/framework/src/main/java/org/tron/common/application/Application.java @@ -34,6 +34,10 @@ public interface Application { void startServices(); + // DO NOT USE THIS METHOD IN TEST CASES MAIN-THREAD + default void blockUntilShutdown() { + } + void shutdownServices(); void addService(Service service); diff --git a/framework/src/main/java/org/tron/common/application/ApplicationImpl.java b/framework/src/main/java/org/tron/common/application/ApplicationImpl.java index b6bcd670a03..9133fddf434 100644 --- a/framework/src/main/java/org/tron/common/application/ApplicationImpl.java +++ b/framework/src/main/java/org/tron/common/application/ApplicationImpl.java @@ -3,11 +3,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.logsfilter.EventPluginLoader; import org.tron.common.parameter.CommonParameter; import org.tron.core.ChainBaseManager; import org.tron.core.config.args.Args; -import org.tron.core.config.args.DynamicArgs; import org.tron.core.consensus.ConsensusService; import org.tron.core.db.Manager; import org.tron.core.metrics.MetricsUtil; @@ -31,9 +29,6 @@ public class ApplicationImpl implements Application { @Autowired private ConsensusService consensusService; - @Autowired - private DynamicArgs dynamicArgs; - @Override public void setOptions(Args args) { // not used @@ -64,28 +59,18 @@ public void startup() { } consensusService.start(); MetricsUtil.init(); - dynamicArgs.init(); + this.initServices(Args.getInstance()); + this.startServices(); } @Override public void shutdown() { - logger.info("******** start to shutdown ********"); + this.shutdownServices(); + consensusService.stop(); if (!Args.getInstance().isSolidityNode() && (!Args.getInstance().p2pDisable)) { tronNetService.close(); } - consensusService.stop(); - synchronized (dbManager.getRevokingStore()) { - dbManager.getSession().reset(); - closeRevokingStore(); - } - dbManager.stopRePushThread(); - dbManager.stopRePushTriggerThread(); - EventPluginLoader.getInstance().stopPlugin(); - dbManager.stopFilterProcessThread(); - dbManager.stopValidateSignThread(); - getChainBaseManager().shutdown(); - dynamicArgs.close(); - logger.info("******** end to shutdown ********"); + dbManager.close(); } @Override @@ -93,6 +78,11 @@ public void startServices() { services.start(); } + @Override + public void blockUntilShutdown() { + services.blockUntilShutdown(); + } + @Override public void shutdownServices() { services.stop(); @@ -108,9 +98,4 @@ public ChainBaseManager getChainBaseManager() { return chainBaseManager; } - private void closeRevokingStore() { - logger.info("******** start to closeRevokingStore ********"); - dbManager.getRevokingStore().shutdown(); - } - } diff --git a/framework/src/main/java/org/tron/common/application/HttpService.java b/framework/src/main/java/org/tron/common/application/HttpService.java new file mode 100644 index 00000000000..76f8e74d65c --- /dev/null +++ b/framework/src/main/java/org/tron/common/application/HttpService.java @@ -0,0 +1,81 @@ +/* + * java-tron is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * java-tron is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.tron.common.application; + +import com.google.common.base.Objects; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.jetty.server.Server; + +@Slf4j(topic = "rpc") +public abstract class HttpService implements Service { + + protected Server apiServer; + protected int port; + + @Override + public void blockUntilShutdown() { + if (apiServer != null) { + try { + apiServer.join(); + } catch (InterruptedException e) { + logger.warn("{}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } + } + + @Override + public void start() { + if (apiServer != null) { + try { + apiServer.start(); + logger.info("{} started, listening on {}", this.getClass().getSimpleName(), port); + } catch (Exception e) { + logger.error("{}", this.getClass().getSimpleName(), e); + } + } + } + + @Override + public void stop() { + if (apiServer != null) { + logger.info("{} shutdown...", this.getClass().getSimpleName()); + try { + apiServer.stop(); + } catch (Exception e) { + logger.warn("{}", this.getClass().getSimpleName(), e); + } + logger.info("{} shutdown complete", this.getClass().getSimpleName()); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + HttpService that = (HttpService) o; + return port == that.port; + } + + @Override + public int hashCode() { + return Objects.hashCode(getClass().getSimpleName(), port); + } +} diff --git a/framework/src/main/java/org/tron/common/application/RpcService.java b/framework/src/main/java/org/tron/common/application/RpcService.java new file mode 100644 index 00000000000..cb89441174a --- /dev/null +++ b/framework/src/main/java/org/tron/common/application/RpcService.java @@ -0,0 +1,85 @@ +/* + * java-tron is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * java-tron is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.tron.common.application; + +import com.google.common.base.Objects; +import io.grpc.Server; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "rpc") +public abstract class RpcService implements Service { + + protected Server apiServer; + protected int port; + + @Override + public void blockUntilShutdown() { + if (apiServer != null) { + try { + apiServer.awaitTermination(); + } catch (InterruptedException e) { + logger.warn("{}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } + } + + @Override + public void start() { + if (apiServer != null) { + try { + apiServer.start(); + logger.info("{} started, listening on {}", this.getClass().getSimpleName(), port); + } catch (IOException e) { + logger.error("{}", this.getClass().getSimpleName(), e); + } + } + } + + @Override + public void stop() { + if (apiServer != null) { + logger.info("{} shutdown...", this.getClass().getSimpleName()); + try { + apiServer.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("{}", this.getClass().getSimpleName(), e); + } + logger.info("{} shutdown complete", this.getClass().getSimpleName()); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RpcService that = (RpcService) o; + return port == that.port; + } + + @Override + public int hashCode() { + return Objects.hashCode(getClass().getSimpleName(), port); + } + +} diff --git a/framework/src/main/java/org/tron/common/application/Service.java b/framework/src/main/java/org/tron/common/application/Service.java index 72cfad9bcc8..67b4e3ce9ae 100644 --- a/framework/src/main/java/org/tron/common/application/Service.java +++ b/framework/src/main/java/org/tron/common/application/Service.java @@ -23,7 +23,14 @@ public interface Service { void init(CommonParameter parameter); + /** + * Start the service. + * {@link Service#init(CommonParameter parameter) init(CommonParameter parameter)} must be called + * before this method. + */ void start(); void stop(); + + void blockUntilShutdown(); } diff --git a/framework/src/main/java/org/tron/common/application/ServiceContainer.java b/framework/src/main/java/org/tron/common/application/ServiceContainer.java index d194360c5ea..2951596add7 100644 --- a/framework/src/main/java/org/tron/common/application/ServiceContainer.java +++ b/framework/src/main/java/org/tron/common/application/ServiceContainer.java @@ -15,17 +15,19 @@ package org.tron.common.application; -import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; import lombok.extern.slf4j.Slf4j; import org.tron.common.parameter.CommonParameter; @Slf4j(topic = "app") public class ServiceContainer { - private ArrayList services; + private final Set services; public ServiceContainer() { - this.services = new ArrayList<>(); + this.services = Collections.synchronizedSet(new LinkedHashSet<>()); } public void add(Service service) { @@ -34,31 +36,38 @@ public void add(Service service) { public void init() { - for (Service service : this.services) { + this.services.forEach(service -> { logger.debug("Initing {}.", service.getClass().getSimpleName()); service.init(); - } + }); } public void init(CommonParameter parameter) { - for (Service service : this.services) { + this.services.forEach(service -> { logger.debug("Initing {}.", service.getClass().getSimpleName()); service.init(parameter); - } + }); } public void start() { - logger.debug("Starting services."); - for (Service service : this.services) { + logger.info("Starting api services."); + this.services.forEach(service -> { logger.debug("Starting {}.", service.getClass().getSimpleName()); service.start(); - } + }); + logger.info("All api services started."); } public void stop() { - for (Service service : this.services) { + logger.info("Stopping api services."); + this.services.forEach(service -> { logger.debug("Stopping {}.", service.getClass().getSimpleName()); service.stop(); - } + }); + logger.info("All api services stopped."); + } + + public void blockUntilShutdown() { + this.services.stream().findFirst().ifPresent(Service::blockUntilShutdown); } } diff --git a/framework/src/main/java/org/tron/common/application/TronApplicationContext.java b/framework/src/main/java/org/tron/common/application/TronApplicationContext.java index 482e9e6219d..64edec77c9c 100644 --- a/framework/src/main/java/org/tron/common/application/TronApplicationContext.java +++ b/framework/src/main/java/org/tron/common/application/TronApplicationContext.java @@ -2,7 +2,7 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.tron.program.FullNode; +import org.tron.core.config.TronLogShutdownHook; public class TronApplicationContext extends AnnotationConfigApplicationContext { @@ -25,10 +25,15 @@ public TronApplicationContext(String... basePackages) { public void doClose() { logger.info("******** start to close ********"); Application appT = ApplicationFactory.create(this); - appT.shutdownServices(); appT.shutdown(); super.doClose(); logger.info("******** close end ********"); - FullNode.shutDownSign = true; + TronLogShutdownHook.shutDown = true; + } + + @Override + public void registerShutdownHook() { + super.registerShutdownHook(); + TronLogShutdownHook.shutDown = false; } } diff --git a/framework/src/main/java/org/tron/common/logsfilter/capsule/TransactionLogTriggerCapsule.java b/framework/src/main/java/org/tron/common/logsfilter/capsule/TransactionLogTriggerCapsule.java index 8600cb6ef8c..ab6ea018cf8 100644 --- a/framework/src/main/java/org/tron/common/logsfilter/capsule/TransactionLogTriggerCapsule.java +++ b/framework/src/main/java/org/tron/common/logsfilter/capsule/TransactionLogTriggerCapsule.java @@ -1,6 +1,7 @@ package org.tron.common.logsfilter.capsule; import static org.tron.protos.Protocol.Transaction.Contract.ContractType.CreateSmartContract; +import static org.tron.protos.contract.Common.ResourceCode.ENERGY; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -26,7 +27,14 @@ import org.tron.protos.Protocol.Transaction.Contract.ContractType; import org.tron.protos.Protocol.TransactionInfo; import org.tron.protos.contract.AssetIssueContractOuterClass.TransferAssetContract; +import org.tron.protos.contract.BalanceContract.CancelAllUnfreezeV2Contract; +import org.tron.protos.contract.BalanceContract.DelegateResourceContract; +import org.tron.protos.contract.BalanceContract.FreezeBalanceV2Contract; import org.tron.protos.contract.BalanceContract.TransferContract; +import org.tron.protos.contract.BalanceContract.UnDelegateResourceContract; +import org.tron.protos.contract.BalanceContract.UnfreezeBalanceContract; +import org.tron.protos.contract.BalanceContract.UnfreezeBalanceV2Contract; +import org.tron.protos.contract.BalanceContract.WithdrawExpireUnfreezeContract; import org.tron.protos.contract.SmartContractOuterClass.CreateSmartContract; import org.tron.protos.contract.SmartContractOuterClass.TriggerSmartContract; @@ -156,6 +164,82 @@ public TransactionLogTriggerCapsule(TransactionCapsule trxCapsule, BlockCapsule StringUtil.encode58Check(createSmartContract.getOwnerAddress().toByteArray())); } break; + case UnfreezeBalanceContract: + UnfreezeBalanceContract unfreezeBalanceContract = contractParameter + .unpack(UnfreezeBalanceContract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(unfreezeBalanceContract.getOwnerAddress().toByteArray())); + if (!ByteString.EMPTY.equals(unfreezeBalanceContract.getReceiverAddress())) { + transactionLogTrigger.setToAddress(StringUtil + .encode58Check(unfreezeBalanceContract.getReceiverAddress().toByteArray())); + } + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount( + transactionInfo.getUnfreezeAmount()); + break; + case FreezeBalanceV2Contract: + FreezeBalanceV2Contract freezeBalanceV2Contract = contractParameter + .unpack(FreezeBalanceV2Contract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(freezeBalanceV2Contract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount(freezeBalanceV2Contract.getFrozenBalance()); + break; + case UnfreezeBalanceV2Contract: + UnfreezeBalanceV2Contract unfreezeBalanceV2Contract = contractParameter + .unpack(UnfreezeBalanceV2Contract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(unfreezeBalanceV2Contract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount( + unfreezeBalanceV2Contract.getUnfreezeBalance()); + break; + case WithdrawExpireUnfreezeContract: + WithdrawExpireUnfreezeContract withdrawExpireUnfreezeContract = contractParameter + .unpack(WithdrawExpireUnfreezeContract.class); + + transactionLogTrigger.setFromAddress(StringUtil.encode58Check( + withdrawExpireUnfreezeContract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount(transactionInfo.getWithdrawExpireAmount()); + break; + case DelegateResourceContract: + DelegateResourceContract delegateResourceContract = contractParameter + .unpack(DelegateResourceContract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(delegateResourceContract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setToAddress(StringUtil + .encode58Check(delegateResourceContract.getReceiverAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount( + delegateResourceContract.getBalance()); + break; + case UnDelegateResourceContract: + UnDelegateResourceContract unDelegateResourceContract = contractParameter + .unpack(UnDelegateResourceContract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(unDelegateResourceContract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setToAddress(StringUtil.encode58Check( + unDelegateResourceContract.getReceiverAddress().toByteArray())); + + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount( + unDelegateResourceContract.getBalance()); + break; + case CancelAllUnfreezeV2Contract: + CancelAllUnfreezeV2Contract cancelAllUnfreezeV2Contract = contractParameter + .unpack(CancelAllUnfreezeV2Contract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(cancelAllUnfreezeV2Contract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setExtMap(transactionInfo.getCancelUnfreezeV2AmountMap()); + break; default: break; } @@ -269,4 +353,5 @@ private List getInternalTransactionList( public void processTrigger() { EventPluginLoader.getInstance().postTransactionTrigger(transactionLogTrigger); } + } diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index c7d1a3f50aa..fdea2a555a8 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -84,6 +84,7 @@ import org.tron.api.GrpcAPI.NoteParameters; import org.tron.api.GrpcAPI.NumberMessage; import org.tron.api.GrpcAPI.PaymentAddressMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.PrivateParameters; import org.tron.api.GrpcAPI.PrivateParametersWithoutAsk; import org.tron.api.GrpcAPI.PrivateShieldedTRC20Parameters; @@ -4295,23 +4296,25 @@ public long getEnergyFee(long timestamp) { } } - public String getEnergyPrices() { + public PricesResponseMessage getEnergyPrices() { + PricesResponseMessage.Builder builder = PricesResponseMessage.newBuilder(); try { - return chainBaseManager.getDynamicPropertiesStore().getEnergyPriceHistory(); + builder.setPrices(chainBaseManager.getDynamicPropertiesStore().getEnergyPriceHistory()); + return builder.build(); } catch (Exception e) { logger.error("GetEnergyPrices failed", e); } - return null; } - public String getBandwidthPrices() { + public PricesResponseMessage getBandwidthPrices() { + PricesResponseMessage.Builder builder = PricesResponseMessage.newBuilder(); try { - return chainBaseManager.getDynamicPropertiesStore().getBandwidthPriceHistory(); + builder.setPrices(chainBaseManager.getDynamicPropertiesStore().getBandwidthPriceHistory()); + return builder.build(); } catch (Exception e) { logger.error("GetBandwidthPrices failed", e); } - return null; } @@ -4426,9 +4429,11 @@ public Block getBlock(GrpcAPI.BlockReq request) { return block.toBuilder().clearTransactions().build(); } - public String getMemoFeePrices() { + public PricesResponseMessage getMemoFeePrices() { + PricesResponseMessage.Builder builder = PricesResponseMessage.newBuilder(); try { - return chainBaseManager.getDynamicPropertiesStore().getMemoFeeHistory(); + builder.setPrices(chainBaseManager.getDynamicPropertiesStore().getMemoFeeHistory()); + return builder.build(); } catch (Exception e) { logger.error("GetMemoFeePrices failed", e); } diff --git a/framework/src/main/java/org/tron/core/config/DefaultConfig.java b/framework/src/main/java/org/tron/core/config/DefaultConfig.java index 6c6a0e2c566..2c4c2a8717e 100755 --- a/framework/src/main/java/org/tron/core/config/DefaultConfig.java +++ b/framework/src/main/java/org/tron/core/config/DefaultConfig.java @@ -42,7 +42,7 @@ public DefaultConfig() { Thread.setDefaultUncaughtExceptionHandler((t, e) -> logger.error("Uncaught exception", e)); } - @Bean + @Bean(destroyMethod = "") public RevokingDatabase revokingDatabase() { try { return new SnapshotManager( diff --git a/framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java b/framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java index f873b88ca44..f497b9a85d8 100644 --- a/framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java +++ b/framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java @@ -20,6 +20,9 @@ public class TronLogShutdownHook extends ShutdownHookBase { */ private final long check_times = 60 * 1000 / CHECK_SHUTDOWN_DELAY.getMilliseconds(); + // if true, shutdown hook will be executed , for example, 'java -jar FullNode.jar -[v|h]'. + public static volatile boolean shutDown = true; + public TronLogShutdownHook() { } @@ -27,7 +30,7 @@ public TronLogShutdownHook() { public void run() { try { for (int i = 0; i < check_times; i++) { - if (FullNode.shutDownSign) { + if (shutDown) { break; } addInfo("Sleeping for " + CHECK_SHUTDOWN_DELAY); diff --git a/framework/src/main/java/org/tron/core/config/args/DynamicArgs.java b/framework/src/main/java/org/tron/core/config/args/DynamicArgs.java index 674ea0f74c6..557b8f1211b 100644 --- a/framework/src/main/java/org/tron/core/config/args/DynamicArgs.java +++ b/framework/src/main/java/org/tron/core/config/args/DynamicArgs.java @@ -9,6 +9,8 @@ import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.tron.common.es.ExecutorServiceManager; @@ -28,6 +30,7 @@ public class DynamicArgs { private ScheduledExecutorService reloadExecutor; private final String esName = "dynamic-reload"; + @PostConstruct public void init() { if (parameter.isDynamicConfigEnable()) { reloadExecutor = ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); @@ -108,6 +111,7 @@ private void updateTrustNodes(Config config) { TronNetService.getP2pConfig().getTrustNodes().toString()); } + @PreDestroy public void close() { ExecutorServiceManager.shutdownAndAwaitTermination(reloadExecutor, esName); } diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index de515fefc90..9a2f53dd69a 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -2416,6 +2416,17 @@ private boolean isBlockWaitingLock() { return blockWaitLock.get() > NO_BLOCK_WAITING_LOCK; } + public void close() { + stopRePushThread(); + stopRePushTriggerThread(); + EventPluginLoader.getInstance().stopPlugin(); + stopFilterProcessThread(); + stopValidateSignThread(); + chainBaseManager.shutdown(); + revokingStore.shutdown(); + session.reset(); + } + private static class ValidateSignTask implements Callable { private TransactionCapsule trx; diff --git a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java index 10615b70ce3..7518b1347a7 100644 --- a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java +++ b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java @@ -38,6 +38,7 @@ import org.tron.p2p.P2pEventHandler; import org.tron.p2p.connection.Channel; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") @Component @@ -232,7 +233,8 @@ private void processException(PeerConnection peer, TronMessage msg, Exception ex code = Protocol.ReasonCode.BAD_BLOCK; break; case NO_SUCH_MESSAGE: - case MESSAGE_WITH_WRONG_LENGTH: + code = Protocol.ReasonCode.NO_SUCH_MESSAGE; + break; case BAD_MESSAGE: code = Protocol.ReasonCode.BAD_PROTOCOL; break; diff --git a/framework/src/main/java/org/tron/core/net/message/sync/ChainInventoryMessage.java b/framework/src/main/java/org/tron/core/net/message/sync/ChainInventoryMessage.java index 4179544ebf7..610a5ff2f11 100644 --- a/framework/src/main/java/org/tron/core/net/message/sync/ChainInventoryMessage.java +++ b/framework/src/main/java/org/tron/core/net/message/sync/ChainInventoryMessage.java @@ -73,6 +73,7 @@ public String toString() { sb.append(", end blockId: ").append(blockIdWeGet.peekLast().getString()); } } + sb.append(", remain_num: ").append(chainInventory.getRemainNum()); return sb.toString(); } } diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerManager.java b/framework/src/main/java/org/tron/core/net/peer/PeerManager.java index a80101d4f3a..537f2083691 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerManager.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerManager.java @@ -16,6 +16,7 @@ import org.tron.common.prometheus.MetricLabels; import org.tron.common.prometheus.Metrics; import org.tron.p2p.connection.Channel; +import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") public class PeerManager { @@ -48,6 +49,7 @@ public static void close() { try { for (PeerConnection p : new ArrayList<>(peers)) { if (!p.isDisconnect()) { + p.disconnect(ReasonCode.PEER_QUITING); p.getChannel().close(); } } diff --git a/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java b/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java index 28725b8737e..ea608c1ea86 100644 --- a/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java +++ b/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java @@ -271,7 +271,7 @@ private void consumerInvToFetch() { } long now = System.currentTimeMillis(); invToFetch.forEach((item, time) -> { - if (time < now - MSG_CACHE_DURATION_IN_BLOCKS * BLOCK_PRODUCED_INTERVAL) { + if (time < now - TIMEOUT) { logger.info("This obj is too late to fetch, type: {} hash: {}", item.getType(), item.getHash()); invToFetch.remove(item); diff --git a/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java b/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java index 9f1b2ef3c37..dfc5f2e89da 100644 --- a/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java +++ b/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java @@ -34,6 +34,7 @@ import org.tron.core.store.WitnessScheduleStore; import org.tron.p2p.connection.Channel; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") @Component @@ -184,6 +185,7 @@ private void disconnect() { TronNetService.getP2pConfig().getActiveNodes().remove(address); TronNetService.getPeers().forEach(peer -> { if (peer.getInetAddress().equals(address.getAddress())) { + peer.disconnect(ReasonCode.NOT_WITNESS); peer.getChannel().close(); } }); diff --git a/framework/src/main/java/org/tron/core/services/RpcApiService.java b/framework/src/main/java/org/tron/core/services/RpcApiService.java index 26861523311..94d5b97decd 100755 --- a/framework/src/main/java/org/tron/core/services/RpcApiService.java +++ b/framework/src/main/java/org/tron/core/services/RpcApiService.java @@ -5,12 +5,10 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import com.google.protobuf.ProtocolStringList; -import io.grpc.Server; import io.grpc.Status; import io.grpc.StatusRuntimeException; import io.grpc.netty.NettyServerBuilder; import io.grpc.stub.StreamObserver; -import java.io.IOException; import java.util.Objects; import java.util.concurrent.TimeUnit; import lombok.Getter; @@ -49,6 +47,7 @@ import org.tron.api.GrpcAPI.OvkDecryptTRC20Parameters; import org.tron.api.GrpcAPI.PaginatedMessage; import org.tron.api.GrpcAPI.PaymentAddressMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.PrivateParameters; import org.tron.api.GrpcAPI.PrivateParametersWithoutAsk; import org.tron.api.GrpcAPI.PrivateShieldedTRC20Parameters; @@ -74,7 +73,7 @@ import org.tron.api.WalletExtensionGrpc; import org.tron.api.WalletGrpc.WalletImplBase; import org.tron.api.WalletSolidityGrpc.WalletSolidityImplBase; -import org.tron.common.application.Service; +import org.tron.common.application.RpcService; import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ByteArray; @@ -163,27 +162,21 @@ @Component @Slf4j(topic = "API") -public class RpcApiService implements Service { +public class RpcApiService extends RpcService { public static final String CONTRACT_VALIDATE_EXCEPTION = "ContractValidateException: {}"; private static final String EXCEPTION_CAUGHT = "exception caught"; private static final String UNKNOWN_EXCEPTION_CAUGHT = "unknown exception caught: "; private static final long BLOCK_LIMIT_NUM = 100; private static final long TRANSACTION_LIMIT_NUM = 1000; - private int port = Args.getInstance().getRpcPort(); - private Server apiServer; @Autowired private Manager dbManager; - @Autowired private ChainBaseManager chainBaseManager; - @Autowired private Wallet wallet; - @Autowired private TransactionUtil transactionUtil; - @Autowired private NodeInfoService nodeInfoService; @Autowired @@ -192,10 +185,8 @@ public class RpcApiService implements Service { private LiteFnQueryGrpcInterceptor liteFnQueryGrpcInterceptor; @Autowired private RpcApiAccessInterceptor apiAccessInterceptor; - @Autowired private MetricsApiService metricsApiService; - @Getter private DatabaseApi databaseApi = new DatabaseApi(); private WalletApi walletApi = new WalletApi(); @@ -213,6 +204,7 @@ public void init() { @Override public void init(CommonParameter args) { + port = Args.getInstance().getRpcPort(); } @Override @@ -260,19 +252,10 @@ public void start() { apiServer = serverBuilder.build(); rateLimiterInterceptor.init(apiServer); - - apiServer.start(); - } catch (IOException e) { + super.start(); + } catch (Exception e) { logger.debug(e.getMessage(), e); } - - logger.info("RpcApiService has started, listening on " + port); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - System.err.println("*** shutting down gRPC server since JVM is shutting down"); - //server.this.stop(); - System.err.println("*** server is shutdown"); - })); } @@ -371,27 +354,6 @@ private void checkSupportShieldedTRC20Transaction() throws ZksnarkException { } } - @Override - public void stop() { - if (apiServer != null) { - apiServer.shutdown(); - } - } - - /** - * ... - */ - public void blockUntilShutdown() { - if (apiServer != null) { - try { - apiServer.awaitTermination(); - } catch (InterruptedException e) { - logger.warn("{}", e); - Thread.currentThread().interrupt(); - } - } - } - /** * DatabaseApi. */ @@ -997,6 +959,28 @@ public void getBlock(GrpcAPI.BlockReq request, StreamObserver responseObserver) { getBlockCommon(request, responseObserver); } + + @Override + public void getBandwidthPrices(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getBandwidthPrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } + + @Override + public void getEnergyPrices(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getEnergyPrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } } /** @@ -2030,6 +2014,39 @@ public void getCanWithdrawUnfreezeAmount(CanWithdrawUnfreezeAmountRequestMessage responseObserver.onCompleted(); } + @Override + public void getBandwidthPrices(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getBandwidthPrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } + + @Override + public void getEnergyPrices(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getEnergyPrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } + + @Override + public void getMemoFee(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getMemoFeePrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } + @Override public void getPaginatedProposalList(PaginatedMessage request, StreamObserver responseObserver) { diff --git a/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java b/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java index 082307fe629..55e6e07b5ec 100644 --- a/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java +++ b/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java @@ -1,13 +1,9 @@ package org.tron.core.services.http; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.util.EnumSet; import javax.servlet.DispatcherType; import javax.servlet.Filter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; import org.eclipse.jetty.server.ConnectionLimit; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.FilterHolder; @@ -16,24 +12,17 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; -import org.tron.common.zksnark.JLibrustzcash; -import org.tron.common.zksnark.LibrustzcashParam.InitZksnarkParams; import org.tron.core.config.args.Args; -import org.tron.core.exception.ZksnarkException; import org.tron.core.services.filter.HttpApiAccessFilter; import org.tron.core.services.filter.HttpInterceptor; import org.tron.core.services.filter.LiteFnQueryHttpFilter; -@Component +@Component("fullNodeHttpApiService") @Slf4j(topic = "API") -public class FullNodeHttpApiService implements Service { - - private int port = Args.getInstance().getFullNodeHttpPort(); - - private Server server; +public class FullNodeHttpApiService extends HttpService { @Autowired private GetAccountServlet getAccountServlet; @@ -305,60 +294,22 @@ public class FullNodeHttpApiService implements Service { @Autowired private CancelAllUnfreezeV2Servlet cancelAllUnfreezeV2Servlet; - private static String getParamsFile(String fileName) { - InputStream in = Thread.currentThread().getContextClassLoader() - .getResourceAsStream("params" + File.separator + fileName); - File fileOut = new File(System.getProperty("java.io.tmpdir") - + File.separator + fileName + "." + System.currentTimeMillis()); - try { - FileUtils.copyToFile(in, fileOut); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - return fileOut.getAbsolutePath(); - } - - public static void librustzcashInitZksnarkParams() { - logger.info("init zk param begin"); - - if (!JLibrustzcash.isOpenZen()) { - logger.info("zen switch is off, zen will not start."); - return; - } - - String spendPath = getParamsFile("sapling-spend.params"); - String spendHash = "25fd9a0d1c1be0526c14662947ae95b758fe9f3d7fb7f55e9b4437830dcc6215a7ce3ea465" - + "914b157715b7a4d681389ea4aa84438190e185d5e4c93574d3a19a"; - - String outputPath = getParamsFile("sapling-output.params"); - String outputHash = "a1cb23b93256adce5bce2cb09cefbc96a1d16572675ceb691e9a3626ec15b5b546926ff1c" - + "536cfe3a9df07d796b32fdfc3e5d99d65567257bf286cd2858d71a6"; - - try { - JLibrustzcash.librustzcashInitZksnarkParams( - new InitZksnarkParams(spendPath, spendHash, outputPath, outputHash)); - } catch (ZksnarkException e) { - logger.error("librustzcashInitZksnarkParams fail!", e); - } - logger.info("init zk param done"); - } - @Override public void init() { } @Override public void init(CommonParameter args) { - librustzcashInitZksnarkParams(); + port = Args.getInstance().getFullNodeHttpPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); context.addServlet(new ServletHolder(getAccountServlet), "/wallet/getaccount"); context.addServlet(new ServletHolder(transferServlet), "/wallet/createtransaction"); @@ -571,7 +522,7 @@ public void start() { int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } // filters the specified APIs @@ -595,17 +546,7 @@ public void start() { .addFilterWithMapping((Class) HttpInterceptor.class, "/*", EnumSet.of(DispatcherType.REQUEST)); context.addFilter(fh, "/*", EnumSet.of(DispatcherType.REQUEST)); - - server.start(); - } catch (Exception e) { - logger.debug("IOException: {}", e.getMessage()); - } - } - - @Override - public void stop() { - try { - server.stop(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetBandwidthPricesServlet.java b/framework/src/main/java/org/tron/core/services/http/GetBandwidthPricesServlet.java index ea4b535af39..09d51cc8635 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetBandwidthPricesServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetBandwidthPricesServlet.java @@ -1,14 +1,13 @@ package org.tron.core.services.http; -import com.alibaba.fastjson.JSONObject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class GetBandwidthPricesServlet extends RateLimiterServlet { @@ -16,21 +15,17 @@ public class GetBandwidthPricesServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { - String reply = wallet.getBandwidthPrices(); - if (reply != null) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("prices", reply); - response.getWriter().println(jsonObject); - } else { - response.getWriter().println("{}"); - } + PricesResponseMessage reply = wallet.getBandwidthPrices(); + response.getWriter().println(reply == null ? "{}" : JsonFormat.printToString(reply)); } catch (Exception e) { Util.processError(e, response); } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetEnergyPricesServlet.java b/framework/src/main/java/org/tron/core/services/http/GetEnergyPricesServlet.java index 36129d8ffdb..b9b6ba0d893 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetEnergyPricesServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetEnergyPricesServlet.java @@ -1,14 +1,13 @@ package org.tron.core.services.http; -import com.alibaba.fastjson.JSONObject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class GetEnergyPricesServlet extends RateLimiterServlet { @@ -16,21 +15,17 @@ public class GetEnergyPricesServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { - String reply = wallet.getEnergyPrices(); - if (reply != null) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("prices", reply); - response.getWriter().println(jsonObject); - } else { - response.getWriter().println("{}"); - } + PricesResponseMessage reply = wallet.getEnergyPrices(); + response.getWriter().println(reply == null ? "{}" : JsonFormat.printToString(reply)); } catch (Exception e) { Util.processError(e, response); } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetMemoFeePricesServlet.java b/framework/src/main/java/org/tron/core/services/http/GetMemoFeePricesServlet.java index 8d5f46d8236..0da52bf9d35 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetMemoFeePricesServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetMemoFeePricesServlet.java @@ -1,14 +1,13 @@ package org.tron.core.services.http; -import com.alibaba.fastjson.JSONObject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class GetMemoFeePricesServlet extends RateLimiterServlet { @@ -16,21 +15,17 @@ public class GetMemoFeePricesServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { - String reply = wallet.getMemoFeePrices(); - if (reply != null) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("prices", reply); - response.getWriter().println(jsonObject); - } else { - response.getWriter().println("{}"); - } + PricesResponseMessage reply = wallet.getMemoFeePrices(); + response.getWriter().println(reply == null ? "{}" : JsonFormat.printToString(reply)); } catch (Exception e) { Util.processError(e, response); } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java b/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java index 534bc504c82..a1808b4fa86 100644 --- a/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java +++ b/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java @@ -10,12 +10,11 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; import org.tron.core.config.args.Args; import org.tron.core.services.filter.HttpApiAccessFilter; import org.tron.core.services.http.EstimateEnergyServlet; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.services.http.GetAccountByIdServlet; import org.tron.core.services.http.GetAccountServlet; import org.tron.core.services.http.GetAssetIssueByIdServlet; @@ -63,11 +62,7 @@ @Component @Slf4j(topic = "API") -public class SolidityNodeHttpApiService implements Service { - - private int port = Args.getInstance().getSolidityHttpPort(); - - private Server server; +public class SolidityNodeHttpApiService extends HttpService { @Autowired private GetAccountServlet getAccountServlet; @@ -176,16 +171,16 @@ public void init() { @Override public void init(CommonParameter args) { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + port = Args.getInstance().getSolidityHttpPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); // same as FullNode context.addServlet(new ServletHolder(getAccountServlet), "/walletsolidity/getaccount"); @@ -294,22 +289,12 @@ public void start() { int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("Exception: {}", e.getMessage()); - } - } - } diff --git a/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnPBFT/JsonRpcServiceOnPBFT.java b/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnPBFT/JsonRpcServiceOnPBFT.java index 96da1515610..1893a46045a 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnPBFT/JsonRpcServiceOnPBFT.java +++ b/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnPBFT/JsonRpcServiceOnPBFT.java @@ -7,16 +7,12 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; @Component @Slf4j(topic = "API") -public class JsonRpcServiceOnPBFT implements Service { - - private int port = CommonParameter.getInstance().getJsonRpcHttpPBFTPort(); - - private Server server; +public class JsonRpcServiceOnPBFT extends HttpService { @Autowired private JsonRpcOnPBFTServlet jsonRpcOnPBFTServlet; @@ -27,36 +23,28 @@ public void init() { @Override public void init(CommonParameter args) { + port = CommonParameter.getInstance().getJsonRpcHttpPBFTPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); context.addServlet(new ServletHolder(jsonRpcOnPBFTServlet), "/jsonrpc"); int maxHttpConnectNumber = CommonParameter.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("IOException: {}", e.getMessage()); - } - } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnSolidity/JsonRpcServiceOnSolidity.java b/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnSolidity/JsonRpcServiceOnSolidity.java index 41357c13dc2..52f5b761ae2 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnSolidity/JsonRpcServiceOnSolidity.java +++ b/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnSolidity/JsonRpcServiceOnSolidity.java @@ -7,16 +7,12 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; @Component @Slf4j(topic = "API") -public class JsonRpcServiceOnSolidity implements Service { - - private int port = CommonParameter.getInstance().getJsonRpcHttpSolidityPort(); - - private Server server; +public class JsonRpcServiceOnSolidity extends HttpService { @Autowired private JsonRpcOnSolidityServlet jsonRpcOnSolidityServlet; @@ -27,34 +23,25 @@ public void init() { @Override public void init(CommonParameter args) { + port = CommonParameter.getInstance().getJsonRpcHttpSolidityPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); context.addServlet(new ServletHolder(jsonRpcOnSolidityServlet), "/jsonrpc"); int maxHttpConnectNumber = CommonParameter.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } + super.start(); - server.start(); - - } catch (Exception e) { - logger.debug("IOException: {}", e.getMessage()); - } - } - - @Override - public void stop() { - try { - server.stop(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java index 2457e5fc891..2f7b1dcc15c 100755 --- a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java @@ -1,9 +1,7 @@ package org.tron.core.services.interfaceOnPBFT; -import io.grpc.Server; import io.grpc.netty.NettyServerBuilder; import io.grpc.stub.StreamObserver; -import java.io.IOException; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -31,16 +29,14 @@ import org.tron.api.GrpcAPI.NumberMessage; import org.tron.api.GrpcAPI.OvkDecryptTRC20Parameters; import org.tron.api.GrpcAPI.PaginatedMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.SpendResult; import org.tron.api.GrpcAPI.TransactionExtention; import org.tron.api.GrpcAPI.WitnessList; import org.tron.api.WalletSolidityGrpc.WalletSolidityImplBase; -import org.tron.common.application.Service; -import org.tron.common.crypto.ECKey; +import org.tron.common.application.RpcService; import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; -import org.tron.common.utils.StringUtil; -import org.tron.common.utils.Utils; import org.tron.core.config.args.Args; import org.tron.core.services.RpcApiService; import org.tron.core.services.filter.LiteFnQueryGrpcInterceptor; @@ -65,10 +61,7 @@ @Slf4j(topic = "API") -public class RpcApiServiceOnPBFT implements Service { - - private int port = Args.getInstance().getRpcOnPBFTPort(); - private Server apiServer; +public class RpcApiServiceOnPBFT extends RpcService { @Autowired private WalletOnPBFT walletOnPBFT; @@ -93,7 +86,7 @@ public void init() { @Override public void init(CommonParameter parameter) { - + port = Args.getInstance().getRpcOnPBFTPort(); } @Override @@ -132,27 +125,10 @@ public void start() { apiServer = serverBuilder.build(); rateLimiterInterceptor.init(apiServer); - - apiServer.start(); - - } catch (IOException e) { + super.start(); + } catch (Exception e) { logger.debug(e.getMessage(), e); } - - logger.info("RpcApiServiceOnPBFT started, listening on " + port); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - System.err.println("*** shutting down gRPC server on PBFT since JVM is shutting down"); - //server.this.stop(); - System.err.println("*** server on PBFT shut down"); - })); - } - - @Override - public void stop() { - if (apiServer != null) { - apiServer.shutdown(); - } } /** @@ -557,5 +533,19 @@ public void getBlock(GrpcAPI.BlockReq request, () -> rpcApiService.getWalletSolidityApi().getBlock(request, responseObserver)); } + @Override + public void getBandwidthPrices(EmptyMessage request, + StreamObserver responseObserver) { + walletOnPBFT.futureGet( + () -> rpcApiService.getWalletSolidityApi().getBandwidthPrices(request, responseObserver)); + } + + @Override + public void getEnergyPrices(EmptyMessage request, + StreamObserver responseObserver) { + walletOnPBFT.futureGet( + () -> rpcApiService.getWalletSolidityApi().getEnergyPrices(request, responseObserver)); + } + } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java index 9b72f11e2bf..7a5fd0cbcde 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java @@ -9,7 +9,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; import org.tron.core.config.args.Args; import org.tron.core.services.filter.HttpApiAccessFilter; @@ -60,11 +60,7 @@ import org.tron.core.services.interfaceOnPBFT.http.TriggerConstantContractOnPBFTServlet; @Slf4j(topic = "API") -public class HttpApiOnPBFTService implements Service { - - private int port = Args.getInstance().getPBFTHttpPort(); - - private Server server; +public class HttpApiOnPBFTService extends HttpService { @Autowired private GetAccountOnPBFTServlet accountOnPBFTServlet; @@ -183,16 +179,16 @@ public void init() { @Override public void init(CommonParameter parameter) { - + port = Args.getInstance().getPBFTHttpPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/walletpbft/"); - server.setHandler(context); + apiServer.setHandler(context); // same as FullNode context.addServlet(new ServletHolder(accountOnPBFTServlet), "/getaccount"); @@ -281,7 +277,7 @@ public void start() { int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } // filters the specified APIs @@ -293,18 +289,9 @@ public void start() { context.addFilter(new FilterHolder(httpApiAccessFilter), "/*", EnumSet.allOf(DispatcherType.class)); - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("Exception: {}", e.getMessage()); - } - } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java index 5bf6f1846e5..68ec79175fa 100755 --- a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java @@ -1,10 +1,8 @@ package org.tron.core.services.interfaceOnSolidity; import com.google.protobuf.ByteString; -import io.grpc.Server; import io.grpc.netty.NettyServerBuilder; import io.grpc.stub.StreamObserver; -import java.io.IOException; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -27,6 +25,7 @@ import org.tron.api.GrpcAPI.NoteParameters; import org.tron.api.GrpcAPI.NumberMessage; import org.tron.api.GrpcAPI.PaginatedMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.Return; import org.tron.api.GrpcAPI.Return.response_code; import org.tron.api.GrpcAPI.SpendResult; @@ -34,14 +33,10 @@ import org.tron.api.GrpcAPI.TransactionInfoList; import org.tron.api.GrpcAPI.WitnessList; import org.tron.api.WalletSolidityGrpc.WalletSolidityImplBase; -import org.tron.common.application.Service; -import org.tron.common.crypto.SignInterface; -import org.tron.common.crypto.SignUtils; +import org.tron.common.application.RpcService; import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.Sha256Hash; -import org.tron.common.utils.StringUtil; -import org.tron.common.utils.Utils; import org.tron.core.capsule.BlockCapsule; import org.tron.core.config.args.Args; import org.tron.core.services.RpcApiService; @@ -67,10 +62,8 @@ @Slf4j(topic = "API") -public class RpcApiServiceOnSolidity implements Service { +public class RpcApiServiceOnSolidity extends RpcService { - private int port = Args.getInstance().getRpcOnSolidityPort(); - private Server apiServer; @Autowired private WalletOnSolidity walletOnSolidity; @@ -95,6 +88,7 @@ public void init() { @Override public void init(CommonParameter args) { + port = Args.getInstance().getRpcOnSolidityPort(); } @Override @@ -132,20 +126,10 @@ public void start() { apiServer = serverBuilder.build(); rateLimiterInterceptor.init(apiServer); - - apiServer.start(); - - } catch (IOException e) { + super.start(); + } catch (Exception e) { logger.debug(e.getMessage(), e); } - - logger.info("RpcApiServiceOnSolidity started, listening on " + port); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - System.err.println("*** shutting down gRPC server on solidity since JVM is shutting down"); - //server.this.stop(); - System.err.println("*** server on solidity shut down"); - })); } private TransactionExtention transaction2Extention(Transaction transaction) { @@ -177,13 +161,6 @@ private BlockExtention block2Extention(Block block) { return builder.build(); } - @Override - public void stop() { - if (apiServer != null) { - apiServer.shutdown(); - } - } - /** * DatabaseApi. */ @@ -540,5 +517,19 @@ public void getBlock(GrpcAPI.BlockReq request, () -> rpcApiService.getWalletSolidityApi().getBlock(request, responseObserver)); } + @Override + public void getBandwidthPrices(EmptyMessage request, + StreamObserver responseObserver) { + walletOnSolidity.futureGet( + () -> rpcApiService.getWalletSolidityApi().getBandwidthPrices(request, responseObserver)); + } + + @Override + public void getEnergyPrices(EmptyMessage request, + StreamObserver responseObserver) { + walletOnSolidity.futureGet( + () -> rpcApiService.getWalletSolidityApi().getEnergyPrices(request, responseObserver)); + } + } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/solidity/HttpApiOnSolidityService.java b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/solidity/HttpApiOnSolidityService.java index ba5ab49ef7a..f89be80c71b 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/solidity/HttpApiOnSolidityService.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/solidity/HttpApiOnSolidityService.java @@ -9,7 +9,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; import org.tron.core.config.args.Args; import org.tron.core.services.filter.HttpApiAccessFilter; @@ -63,11 +63,7 @@ @Slf4j(topic = "API") -public class HttpApiOnSolidityService implements Service { - - private int port = Args.getInstance().getSolidityHttpPort(); - - private Server server; +public class HttpApiOnSolidityService extends HttpService { @Autowired private GetAccountOnSolidityServlet accountOnSolidityServlet; @@ -189,16 +185,16 @@ public void init() { @Override public void init(CommonParameter args) { - + port = Args.getInstance().getSolidityHttpPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); // same as FullNode context.addServlet(new ServletHolder(accountOnSolidityServlet), "/walletsolidity/getaccount"); @@ -315,20 +311,11 @@ public void start() { int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("Exception: {}", e.getMessage()); - } - } } diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java b/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java index c38b9b198c0..ff017f9562e 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java @@ -11,17 +11,13 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; import org.tron.core.services.filter.HttpInterceptor; @Component @Slf4j(topic = "API") -public class FullNodeJsonRpcHttpService implements Service { - - private final int port = CommonParameter.getInstance().getJsonRpcHttpFullNodePort(); - - private Server server; +public class FullNodeJsonRpcHttpService extends HttpService { @Autowired private JsonRpcServlet jsonRpcServlet; @@ -32,21 +28,22 @@ public void init() { @Override public void init(CommonParameter args) { + port = CommonParameter.getInstance().getJsonRpcHttpFullNodePort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); context.addServlet(new ServletHolder(jsonRpcServlet), "/jsonrpc"); int maxHttpConnectNumber = CommonParameter.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } // filter @@ -56,19 +53,10 @@ public void start() { EnumSet.of(DispatcherType.REQUEST)); context.addFilter(fh, "/*", EnumSet.of(DispatcherType.REQUEST)); - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("IOException: {}", e.getMessage()); - } - } } diff --git a/framework/src/main/java/org/tron/core/zen/ZksnarkInitService.java b/framework/src/main/java/org/tron/core/zen/ZksnarkInitService.java new file mode 100644 index 00000000000..2811b50397d --- /dev/null +++ b/framework/src/main/java/org/tron/core/zen/ZksnarkInitService.java @@ -0,0 +1,62 @@ +package org.tron.core.zen; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import javax.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.springframework.context.annotation.DependsOn; +import org.springframework.stereotype.Component; +import org.tron.common.zksnark.JLibrustzcash; +import org.tron.common.zksnark.LibrustzcashParam; +import org.tron.core.exception.ZksnarkException; + +@Slf4j(topic = "API") +@Component +@DependsOn("fullNodeHttpApiService") +public class ZksnarkInitService { + + @PostConstruct + private void init() { + librustzcashInitZksnarkParams(); + } + + public static void librustzcashInitZksnarkParams() { + logger.info("init zk param begin"); + + if (!JLibrustzcash.isOpenZen()) { + logger.info("zen switch is off, zen will not start."); + return; + } + + String spendPath = getParamsFile("sapling-spend.params"); + String spendHash = "25fd9a0d1c1be0526c14662947ae95b758fe9f3d7fb7f55e9b4437830dcc6215a7ce3ea465" + + "914b157715b7a4d681389ea4aa84438190e185d5e4c93574d3a19a"; + + String outputPath = getParamsFile("sapling-output.params"); + String outputHash = "a1cb23b93256adce5bce2cb09cefbc96a1d16572675ceb691e9a3626ec15b5b546926ff1c" + + "536cfe3a9df07d796b32fdfc3e5d99d65567257bf286cd2858d71a6"; + + try { + JLibrustzcash.librustzcashInitZksnarkParams( + new LibrustzcashParam.InitZksnarkParams(spendPath, spendHash, outputPath, outputHash)); + } catch (ZksnarkException e) { + logger.error("librustzcashInitZksnarkParams fail!", e); + } + logger.info("init zk param done"); + } + + private static String getParamsFile(String fileName) { + InputStream in = Thread.currentThread().getContextClassLoader() + .getResourceAsStream("params" + File.separator + fileName); + File fileOut = new File(System.getProperty("java.io.tmpdir") + + File.separator + fileName + "." + System.currentTimeMillis()); + try { + FileUtils.copyToFile(in, fileOut); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + return fileOut.getAbsolutePath(); + } +} \ No newline at end of file diff --git a/framework/src/main/java/org/tron/program/FullNode.java b/framework/src/main/java/org/tron/program/FullNode.java index 5ebf70e0d7a..0fd87eb5de0 100644 --- a/framework/src/main/java/org/tron/program/FullNode.java +++ b/framework/src/main/java/org/tron/program/FullNode.java @@ -30,8 +30,6 @@ public class FullNode { - public static volatile boolean shutDownSign = false; - public static void load(String path) { try { File file = new File(path); @@ -131,11 +129,7 @@ public static void main(String[] args) { JsonRpcServiceOnPBFT jsonRpcServiceOnPBFT = context.getBean(JsonRpcServiceOnPBFT.class); appT.addService(jsonRpcServiceOnPBFT); } - - appT.initServices(parameter); - appT.startServices(); appT.startup(); - - rpcApiService.blockUntilShutdown(); + appT.blockUntilShutdown(); } } diff --git a/framework/src/main/java/org/tron/program/SolidityNode.java b/framework/src/main/java/org/tron/program/SolidityNode.java index 6101db8068c..4cf71177803 100644 --- a/framework/src/main/java/org/tron/program/SolidityNode.java +++ b/framework/src/main/java/org/tron/program/SolidityNode.java @@ -90,14 +90,10 @@ public static void main(String[] args) { appT.addService(httpApiService); } - appT.initServices(parameter); - appT.startServices(); - appT.startup(); - SolidityNode node = new SolidityNode(appT.getDbManager()); node.start(); - - rpcApiService.blockUntilShutdown(); + appT.startup(); + appT.blockUntilShutdown(); } private void start() { diff --git a/framework/src/test/java/org/tron/common/logsfilter/TransactionLogTriggerCapsuleTest.java b/framework/src/test/java/org/tron/common/logsfilter/TransactionLogTriggerCapsuleTest.java new file mode 100644 index 00000000000..d8da2cc540d --- /dev/null +++ b/framework/src/test/java/org/tron/common/logsfilter/TransactionLogTriggerCapsuleTest.java @@ -0,0 +1,159 @@ +package org.tron.common.logsfilter; + +import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; + +import com.google.protobuf.ByteString; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.logsfilter.capsule.TransactionLogTriggerCapsule; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.p2p.utils.ByteArray; +import org.tron.protos.Protocol; +import org.tron.protos.contract.BalanceContract; +import org.tron.protos.contract.Common; + +public class TransactionLogTriggerCapsuleTest { + + private static final String OWNER_ADDRESS = "41548794500882809695a8a687866e76d4271a1abc"; + private static final String RECEIVER_ADDRESS = "41abd4b9367799eaa3197fecb144eb71de1e049150"; + + public TransactionCapsule transactionCapsule; + public BlockCapsule blockCapsule; + + @Before + public void setup() { + blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis(), Sha256Hash.ZERO_HASH.getByteString()); + } + + @Test + public void testConstructorWithUnfreezeBalanceTrxCapsule() { + BalanceContract.UnfreezeBalanceContract.Builder builder2 = + BalanceContract.UnfreezeBalanceContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.UnfreezeBalanceContract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress()); + } + + + @Test + public void testConstructorWithFreezeBalanceV2TrxCapsule() { + BalanceContract.FreezeBalanceV2Contract.Builder builder2 = + BalanceContract.FreezeBalanceV2Contract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setFrozenBalance(TRX_PRECISION + 100000) + .setResource(Common.ResourceCode.BANDWIDTH); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.FreezeBalanceV2Contract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 100000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + @Test + public void testConstructorWithUnfreezeBalanceV2TrxCapsule() { + BalanceContract.UnfreezeBalanceV2Contract.Builder builder2 = + BalanceContract.UnfreezeBalanceV2Contract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setUnfreezeBalance(TRX_PRECISION + 4000) + .setResource(Common.ResourceCode.BANDWIDTH); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.UnfreezeBalanceV2Contract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 4000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + + @Test + public void testConstructorWithWithdrawExpireTrxCapsule() { + BalanceContract.WithdrawExpireUnfreezeContract.Builder builder2 = + BalanceContract.WithdrawExpireUnfreezeContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.WithdrawExpireUnfreezeContract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(0L, triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + + @Test + public void testConstructorWithDelegateResourceTrxCapsule() { + BalanceContract.DelegateResourceContract.Builder builder2 = + BalanceContract.DelegateResourceContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))) + .setBalance(TRX_PRECISION + 2000); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.DelegateResourceContract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 2000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + @Test + public void testConstructorWithUnDelegateResourceTrxCapsule() { + BalanceContract.UnDelegateResourceContract.Builder builder2 = + BalanceContract.UnDelegateResourceContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))) + .setBalance(TRX_PRECISION + 10000); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.UnDelegateResourceContract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 10000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + @Test + public void testConstructorWithCancelAllUnfreezeTrxCapsule() { + BalanceContract.CancelAllUnfreezeV2Contract.Builder builder2 = + BalanceContract.CancelAllUnfreezeV2Contract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.CancelAllUnfreezeV2Contract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + } + +} \ No newline at end of file diff --git a/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsVerifyProofTest.java b/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsVerifyProofTest.java index d97be9581b7..08ce6be57a0 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsVerifyProofTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsVerifyProofTest.java @@ -25,13 +25,13 @@ import org.tron.core.capsule.PedersenHashCapsule; import org.tron.core.config.args.Args; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.vm.PrecompiledContracts.MerkleHash; import org.tron.core.vm.PrecompiledContracts.VerifyBurnProof; import org.tron.core.vm.PrecompiledContracts.VerifyMintProof; import org.tron.core.vm.PrecompiledContracts.VerifyTransferProof; import org.tron.core.zen.ShieldedTRC20ParametersBuilder; import org.tron.core.zen.ShieldedTRC20ParametersBuilder.ShieldedTRC20ParametersType; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -64,7 +64,7 @@ public static void init() { .fromHexString("030c8c2bc59fb3eb8afb047a8ea4b028743d23e7d38c6fa30908358431e2314d"); SHIELDED_CONTRACT_ADDRESS = WalletClient.decodeFromBase58Check(SHIELDED_CONTRACT_ADDRESS_STR); PUBLIC_TO_ADDRESS = WalletClient.decodeFromBase58Check(PUBLIC_TO_ADDRESS_STR); - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } @Test diff --git a/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java b/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java index e7fefd5e121..db62b04e6b0 100644 --- a/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java +++ b/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java @@ -37,10 +37,10 @@ import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.vm.PrecompiledContracts.VerifyBurnProof; import org.tron.core.vm.PrecompiledContracts.VerifyMintProof; import org.tron.core.vm.PrecompiledContracts.VerifyTransferProof; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -69,7 +69,7 @@ public class ShieldedTRC20BuilderTest extends BaseTest { SHIELDED_CONTRACT_ADDRESS = WalletClient.decodeFromBase58Check(SHIELDED_CONTRACT_ADDRESS_STR); DEFAULT_OVK = ByteArray .fromHexString("030c8c2bc59fb3eb8afb047a8ea4b028743d23e7d38c6fa30908358431e2314d"); - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); PUBLIC_TO_ADDRESS = WalletClient.decodeFromBase58Check(PUBLIC_TO_ADDRESS_STR); } diff --git a/framework/src/test/java/org/tron/core/WalletTest.java b/framework/src/test/java/org/tron/core/WalletTest.java index 92bbebb8b37..712a708f822 100644 --- a/framework/src/test/java/org/tron/core/WalletTest.java +++ b/framework/src/test/java/org/tron/core/WalletTest.java @@ -43,6 +43,7 @@ import org.tron.api.GrpcAPI.BlockList; import org.tron.api.GrpcAPI.ExchangeList; import org.tron.api.GrpcAPI.NumberMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.ProposalList; import org.tron.common.BaseTest; import org.tron.common.crypto.ECKey; @@ -930,8 +931,8 @@ public void testGetCanWithdrawUnfreezeAmount() { @Test public void testGetMemoFeePrices() { - String memeFeeList = wallet.getMemoFeePrices(); - Assert.assertEquals("0:0", memeFeeList); + PricesResponseMessage memeFeeList = wallet.getMemoFeePrices(); + Assert.assertEquals("0:0", memeFeeList.getPrices()); } @Test diff --git a/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java index 5e7d33832b4..f84610cc551 100755 --- a/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java @@ -27,8 +27,8 @@ import org.tron.core.exception.PermissionException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.zen.ZenTransactionBuilder; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -91,7 +91,7 @@ public static void init() throws ZksnarkException { } private static void librustzcashInitZksnarkParams() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } /** diff --git a/framework/src/test/java/org/tron/core/db2/SnapshotImplTest.java b/framework/src/test/java/org/tron/core/db2/SnapshotImplTest.java new file mode 100644 index 00000000000..aab6f656b1f --- /dev/null +++ b/framework/src/test/java/org/tron/core/db2/SnapshotImplTest.java @@ -0,0 +1,201 @@ +package org.tron.core.db2; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.File; +import java.lang.reflect.Constructor; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.application.Application; +import org.tron.common.application.ApplicationFactory; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db2.core.Snapshot; +import org.tron.core.db2.core.SnapshotImpl; +import org.tron.core.db2.core.SnapshotManager; +import org.tron.core.db2.core.SnapshotRoot; + +public class SnapshotImplTest { + private RevokingDbWithCacheNewValueTest.TestRevokingTronStore tronDatabase; + private TronApplicationContext context; + private Application appT; + private SnapshotManager revokingDatabase; + + @Before + public void init() { + Args.setParam(new String[]{"-d", "output_revokingStore_test"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + appT = ApplicationFactory.create(context); + + tronDatabase = new RevokingDbWithCacheNewValueTest.TestRevokingTronStore( + "testSnapshotRoot-testMerge"); + revokingDatabase = context.getBean(SnapshotManager.class); + revokingDatabase.enable(); + revokingDatabase.add(tronDatabase.getRevokingDB()); + } + + @After + public void removeDb() { + Args.clearParam(); + context.destroy(); + FileUtil.deleteDir(new File("output_revokingStore_test")); + + tronDatabase.close(); + revokingDatabase.shutdown(); + } + + /** + * linklist is: from -> root + * root:key1=>value1, key2=>value2 + * from:key3=>value3, key4=>value4 + * after construct, getSnapshotImplIns(root); + * from: key1=>value1, key2=>value2, key3=>value3, key4=>value4 + * from: get key1 or key2, traverse 0 times + */ + @Test + public void testMergeRoot() { + // linklist is: from -> root + SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); + //root.setOptimized(true); + + root.put("key1".getBytes(), "value1".getBytes()); + root.put("key2".getBytes(), "value2".getBytes()); + SnapshotImpl from = getSnapshotImplIns(root); + from.put("key3".getBytes(), "value3".getBytes()); + from.put("key4".getBytes(), "value4".getBytes()); + + byte[] s1 = from.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + byte[] s2 = from.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + } + + /** + * linklist is: from2 -> from -> root + * root: + * from:key1=>value1, key2=>value2 + * from2:key3=>value3,key4=>value4 + * before merge: from2.mergeAhead(from); + * from2: get key1 or key2, traverse 1 times + * after merge + * from2:key1=>value1, key2=>value2, value3=>value3,key4=>value4 + * from2: get key1 or key2, traverse 0 times + * + */ + @Test + public void testMergeAhead() { + + // linklist is: from2 -> from -> root + SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); + SnapshotImpl from = getSnapshotImplIns(root); + from.put("key1".getBytes(), "value1".getBytes()); + from.put("key2".getBytes(), "value2".getBytes()); + + SnapshotImpl from2 = getSnapshotImplIns(from); + from2.put("key3".getBytes(), "value3".getBytes()); + from2.put("key4".getBytes(), "value4".getBytes()); + + /* + // before merge get data in from is success,traverse 0 times + byte[] s1 = from.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + byte[] s2 = from.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + // before merge get data in from2 is success, traverse 0 times + byte[] s3 = from2.get("key3".getBytes()); + assertEquals(new String("value3".getBytes()), new String(s3)); + byte[] s4 = from2.get("key4".getBytes()); + assertEquals(new String("value4".getBytes()), new String(s4)); + */ + + // before merge from2 get data is success, traverse 1 times + byte[] s11 = from2.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s11)); + byte[] s12 = from2.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s12)); + // this can not get key3 and key4 + assertNull(from.get("key3".getBytes())); + assertNull(from.get("key4".getBytes())); + + // do mergeAhead + from2.mergeAhead(from); + /* + // after merge get data in from is success, traverse 0 times + s1 = from.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + s2 = from.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + + // after merge get data in from2 is success, traverse 0 times + s3 = from2.get("key3".getBytes()); + assertEquals(new String("value3".getBytes()), new String(s3)); + s4 = from2.get("key4".getBytes()); + assertEquals(new String("value4".getBytes()), new String(s4)); + */ + + // after merge from2 get data is success, traverse 0 times + byte[] s1 = from2.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + byte[] s2 = from2.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + + // this can not get key3 and key4 + assertNull(from.get("key3".getBytes())); + assertNull(from.get("key4".getBytes())); + } + + /** + * from: key1=>value1, key2=>value2, key3=>value31 + * from2: key3=>value32,key4=>value4 + * after merge: from2.mergeAhead(from); + * from2: key1=>value1, key2=>value2, key3=>value32, key4=>value4 + */ + @Test + public void testMergeOverride() { + // linklist is: from2 -> from -> root + SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); + SnapshotImpl from = getSnapshotImplIns(root); + from.put("key1".getBytes(), "value1".getBytes()); + from.put("key2".getBytes(), "value2".getBytes()); + from.put("key3".getBytes(), "value31".getBytes()); + + SnapshotImpl from2 = getSnapshotImplIns(from); + from2.put("key3".getBytes(), "value32".getBytes()); + from2.put("key4".getBytes(), "value4".getBytes()); + // do mergeAhead + from2.mergeAhead(from); + + // after merge from2 get data is success, traverse 0 times + byte[] s1 = from2.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + byte[] s2 = from2.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + byte[] s3 = from2.get("key3".getBytes()); + assertEquals(new String("value32".getBytes()), new String(s3)); + byte[] s4 = from2.get("key4".getBytes()); + assertEquals(new String("value4".getBytes()), new String(s4)); + } + + /** + * The constructor of SnapshotImpl is not public + * so reflection is used to construct the object here. + */ + private SnapshotImpl getSnapshotImplIns(Snapshot snapshot) { + Class clazz = SnapshotImpl.class; + try { + Constructor constructor = clazz.getDeclaredConstructor(Snapshot.class); + constructor.setAccessible(true); + return (SnapshotImpl) constructor.newInstance(snapshot); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java b/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java index f3ad69d09a1..94f9d5e15f2 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java @@ -29,6 +29,8 @@ import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.args.Args; import org.tron.core.services.NodeInfoService; +import org.tron.core.services.interfaceJsonRpcOnPBFT.JsonRpcServiceOnPBFT; +import org.tron.core.services.interfaceJsonRpcOnSolidity.JsonRpcServiceOnSolidity; import org.tron.core.services.jsonrpc.FullNodeJsonRpcHttpService; import org.tron.core.services.jsonrpc.TronJsonRpcImpl; import org.tron.core.services.jsonrpc.types.BlockResult; @@ -55,10 +57,18 @@ public class JsonrpcServiceTest extends BaseTest { @Resource private FullNodeJsonRpcHttpService fullNodeJsonRpcHttpService; + @Resource + private JsonRpcServiceOnPBFT jsonRpcServiceOnPBFT; + + @Resource + private JsonRpcServiceOnSolidity jsonRpcServiceOnSolidity; + static { dbPath = "output_jsonrpc_service_test"; Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); CommonParameter.getInstance().setJsonRpcHttpFullNodeEnable(true); + CommonParameter.getInstance().setJsonRpcHttpPBFTNodeEnable(true); + CommonParameter.getInstance().setJsonRpcHttpSolidityNodeEnable(true); CommonParameter.getInstance().setMetricsPrometheusEnable(true); Metrics.init(); @@ -256,6 +266,7 @@ public void testGetTransactionByHash() { @Test public void testGetBlockByNumber2() { + fullNodeJsonRpcHttpService.init(Args.getInstance()); fullNodeJsonRpcHttpService.start(); JsonArray params = new JsonArray(); params.add(ByteArray.toJsonHex(blockCapsule.getNum())); @@ -290,4 +301,17 @@ public void testGetBlockByNumber2() { } } + @Test + public void testServicesInit() { + try { + jsonRpcServiceOnPBFT.init(Args.getInstance()); + jsonRpcServiceOnPBFT.start(); + jsonRpcServiceOnSolidity.init(Args.getInstance()); + jsonRpcServiceOnSolidity.start(); + } finally { + jsonRpcServiceOnPBFT.stop(); + jsonRpcServiceOnSolidity.stop(); + } + } + } diff --git a/framework/src/test/java/org/tron/core/metrics/MetricsApiServiceTest.java b/framework/src/test/java/org/tron/core/metrics/MetricsApiServiceTest.java index 714faea05d9..d906ba20d63 100644 --- a/framework/src/test/java/org/tron/core/metrics/MetricsApiServiceTest.java +++ b/framework/src/test/java/org/tron/core/metrics/MetricsApiServiceTest.java @@ -52,8 +52,6 @@ public void init() { rpcApiService = context.getBean(RpcApiService.class); metricsApiService = context.getBean(MetricsApiService.class); appT.addService(rpcApiService); - appT.initServices(parameter); - appT.startServices(); appT.startup(); } diff --git a/framework/src/test/java/org/tron/core/net/BaseNet.java b/framework/src/test/java/org/tron/core/net/BaseNet.java index 805f8aa76a4..1eab04fe106 100644 --- a/framework/src/test/java/org/tron/core/net/BaseNet.java +++ b/framework/src/test/java/org/tron/core/net/BaseNet.java @@ -93,8 +93,6 @@ public static void init() throws Exception { appT = ApplicationFactory.create(context); rpcApiService = context.getBean(RpcApiService.class); appT.addService(rpcApiService); - appT.initServices(parameter); - appT.startServices(); appT.startup(); try { Thread.sleep(2000); @@ -102,7 +100,7 @@ public static void init() throws Exception { //ignore } tronNetDelegate = context.getBean(TronNetDelegate.class); - rpcApiService.blockUntilShutdown(); + appT.blockUntilShutdown(); }); int tryTimes = 0; do { diff --git a/framework/src/test/java/org/tron/core/pbft/PbftApiTest.java b/framework/src/test/java/org/tron/core/pbft/PbftApiTest.java index 61ce5ec3625..8363e6028bc 100755 --- a/framework/src/test/java/org/tron/core/pbft/PbftApiTest.java +++ b/framework/src/test/java/org/tron/core/pbft/PbftApiTest.java @@ -59,6 +59,7 @@ public void pbftapi() throws IOException { Assert.assertTrue(dynamicPropertiesStore.getLatestBlockHeaderNumber() >= 10); commonDataBase.saveLatestPbftBlockNum(6); + httpApiOnPBFTService.init(Args.getInstance()); httpApiOnPBFTService.start(); CloseableHttpResponse response; try (CloseableHttpClient httpClient = HttpClients.createDefault()) { diff --git a/framework/src/test/java/org/tron/core/services/WalletApiTest.java b/framework/src/test/java/org/tron/core/services/WalletApiTest.java index 3e8316666e6..5c3ef49d67c 100644 --- a/framework/src/test/java/org/tron/core/services/WalletApiTest.java +++ b/framework/src/test/java/org/tron/core/services/WalletApiTest.java @@ -36,8 +36,6 @@ public void init() { appT = ApplicationFactory.create(context); rpcApiService = context.getBean(RpcApiService.class); appT.addService(rpcApiService); - appT.initServices(Args.getInstance()); - appT.startServices(); appT.startup(); } diff --git a/framework/src/test/java/org/tron/core/services/filter/HttpApiAccessFilterTest.java b/framework/src/test/java/org/tron/core/services/filter/HttpApiAccessFilterTest.java index 46449aab9c4..0be61682b08 100644 --- a/framework/src/test/java/org/tron/core/services/filter/HttpApiAccessFilterTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/HttpApiAccessFilterTest.java @@ -53,8 +53,6 @@ public void init() { appTest.addService(httpApiService); appTest.addService(httpApiOnSolidityService); appTest.addService(httpApiOnPBFTService); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); } diff --git a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryGrpcInterceptorTest.java b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryGrpcInterceptorTest.java index 439bf1f718f..999b37d8fd6 100644 --- a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryGrpcInterceptorTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryGrpcInterceptorTest.java @@ -74,6 +74,7 @@ public static void init() throws IOException { .usePlaintext() .build(); context = new TronApplicationContext(DefaultConfig.class); + context.registerShutdownHook(); blockingStubFull = WalletGrpc.newBlockingStub(channelFull); blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); blockingStubpBFT = WalletSolidityGrpc.newBlockingStub(channelpBFT); @@ -85,8 +86,6 @@ public static void init() throws IOException { appTest.addService(rpcApiService); appTest.addService(rpcOnSolidity); appTest.addService(rpcApiServiceOnPBFT); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); } diff --git a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java index 5c4b955667f..5522c56075d 100644 --- a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java @@ -55,8 +55,6 @@ public void init() { appTest.addService(httpApiService); appTest.addService(httpApiOnSolidityService); appTest.addService(httpApiOnPBFTService); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); } diff --git a/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java b/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java index ac1f21f6160..59c4509c441 100644 --- a/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java @@ -1,5 +1,10 @@ package org.tron.core.services.filter; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.StatusRuntimeException; @@ -11,14 +16,16 @@ import java.util.Objects; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.BeforeClass; import org.junit.ClassRule; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.tron.api.GrpcAPI; +import org.tron.api.GrpcAPI.BlockExtention; +import org.tron.api.GrpcAPI.BlockReq; +import org.tron.api.GrpcAPI.BytesMessage; +import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.NumberMessage; +import org.tron.api.GrpcAPI.TransactionIdList; import org.tron.api.WalletGrpc; import org.tron.api.WalletSolidityGrpc; import org.tron.common.application.Application; @@ -31,20 +38,15 @@ import org.tron.core.services.RpcApiService; import org.tron.core.services.interfaceOnPBFT.RpcApiServiceOnPBFT; import org.tron.core.services.interfaceOnSolidity.RpcApiServiceOnSolidity; +import org.tron.protos.Protocol.Transaction; @Slf4j public class RpcApiAccessInterceptorTest { private static TronApplicationContext context; - private static WalletGrpc.WalletBlockingStub blockingStubFull = null; private static WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; private static WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubPBFT = null; - private static Application appTest; - - @Rule - public ExpectedException thrown = ExpectedException.none(); - @ClassRule public static TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -67,7 +69,7 @@ public static void init() throws IOException { ManagedChannel channelFull = ManagedChannelBuilder.forTarget(fullNode) .usePlaintext() .build(); - ManagedChannel channelpBFT = ManagedChannelBuilder.forTarget(pBFTNode) + ManagedChannel channelPBFT = ManagedChannelBuilder.forTarget(pBFTNode) .usePlaintext() .build(); ManagedChannel channelSolidity = ManagedChannelBuilder.forTarget(solidityNode) @@ -78,19 +80,17 @@ public static void init() throws IOException { blockingStubFull = WalletGrpc.newBlockingStub(channelFull); blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); - blockingStubPBFT = WalletSolidityGrpc.newBlockingStub(channelpBFT); + blockingStubPBFT = WalletSolidityGrpc.newBlockingStub(channelPBFT); RpcApiService rpcApiService = context.getBean(RpcApiService.class); RpcApiServiceOnSolidity rpcApiServiceOnSolidity = context.getBean(RpcApiServiceOnSolidity.class); RpcApiServiceOnPBFT rpcApiServiceOnPBFT = context.getBean(RpcApiServiceOnPBFT.class); - appTest = ApplicationFactory.create(context); + Application appTest = ApplicationFactory.create(context); appTest.addService(rpcApiService); appTest.addService(rpcApiServiceOnSolidity); appTest.addService(rpcApiServiceOnPBFT); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); } @@ -110,59 +110,63 @@ public void testAccessDisabledFullNode() { disabledApiList.add("getblockbynum"); Args.getInstance().setDisabledApiList(disabledApiList); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - thrown.expect(StatusRuntimeException.class); - thrown.expectMessage("this API is unavailable due to config"); - blockingStubFull.getBlockByNum(message); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + () -> blockingStubFull.getBlockByNum(message)); } @Test public void testRpcApiService() { RpcApiService rpcApiService = context.getBean(RpcApiService.class); - ServerCallStreamObserverTest serverCallStreamObserverTest = new ServerCallStreamObserverTest(); - rpcApiService.getBlockCommon(GrpcAPI.BlockReq.getDefaultInstance(), - serverCallStreamObserverTest); - Assert.assertTrue("Get block Common failed!", serverCallStreamObserverTest.isReady()); + ServerCallStreamObserverTest serverCallStreamObserverTest = + new ServerCallStreamObserverTest<>(); + ServerCallStreamObserverTest serverCallStreamObserverTest1 = + new ServerCallStreamObserverTest<>(); + ServerCallStreamObserverTest serverCallStreamObserverTest2 = + new ServerCallStreamObserverTest<>(); + ServerCallStreamObserverTest serverCallStreamObserverTest3 = + new ServerCallStreamObserverTest<>(); + rpcApiService.getBlockCommon(BlockReq.getDefaultInstance(), serverCallStreamObserverTest); + assertTrue("Get block Common failed!", serverCallStreamObserverTest.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getBrokerageInfoCommon(GrpcAPI.BytesMessage.newBuilder().build(), - serverCallStreamObserverTest); - Assert.assertTrue("Get brokerage info Common failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getBrokerageInfoCommon(BytesMessage.newBuilder().build(), + serverCallStreamObserverTest1); + assertTrue("Get brokerage info Common failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getBurnTrxCommon(GrpcAPI.EmptyMessage.newBuilder().build(), - serverCallStreamObserverTest); - Assert.assertTrue("Get burn trx common failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getBurnTrxCommon(EmptyMessage.newBuilder().build(), + serverCallStreamObserverTest1); + assertTrue("Get burn trx common failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getPendingSizeCommon(GrpcAPI.EmptyMessage.getDefaultInstance(), - serverCallStreamObserverTest); - Assert.assertTrue("Get pending size common failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getPendingSizeCommon(EmptyMessage.getDefaultInstance(), + serverCallStreamObserverTest1); + assertTrue("Get pending size common failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getRewardInfoCommon(GrpcAPI.BytesMessage.newBuilder().build(), - serverCallStreamObserverTest); - Assert.assertTrue("Get reward info common failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getRewardInfoCommon(BytesMessage.newBuilder().build(), + serverCallStreamObserverTest1); + assertTrue("Get reward info common failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); rpcApiService.getTransactionCountByBlockNumCommon( - GrpcAPI.NumberMessage.newBuilder().getDefaultInstanceForType(), - serverCallStreamObserverTest); - Assert.assertTrue("Get transaction count by block num failed!", - serverCallStreamObserverTest.isReady()); + NumberMessage.newBuilder().getDefaultInstanceForType(), + serverCallStreamObserverTest1); + assertTrue("Get transaction count by block num failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getTransactionFromPendingCommon(GrpcAPI.BytesMessage.newBuilder().build(), - serverCallStreamObserverTest); - Assert.assertTrue("Get transaction from pending failed!", - serverCallStreamObserverTest.isReady() == false); + rpcApiService.getTransactionFromPendingCommon(BytesMessage.newBuilder().build(), + serverCallStreamObserverTest2); + assertFalse("Get transaction from pending failed!", + serverCallStreamObserverTest2.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getTransactionListFromPendingCommon(GrpcAPI.EmptyMessage.newBuilder() - .getDefaultInstanceForType(), serverCallStreamObserverTest); - Assert.assertTrue("Get transaction list from pending failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getTransactionListFromPendingCommon(EmptyMessage.newBuilder() + .getDefaultInstanceForType(), serverCallStreamObserverTest3); + assertTrue("Get transaction list from pending failed!", + serverCallStreamObserverTest3.isReady()); } - - class ServerCallStreamObserverTest extends ServerCallStreamObserver { + static class ServerCallStreamObserverTest extends ServerCallStreamObserver { Object ret; @@ -223,10 +227,9 @@ public void testAccessDisabledSolidityNode() { disabledApiList.add("getblockbynum"); Args.getInstance().setDisabledApiList(disabledApiList); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - thrown.expect(StatusRuntimeException.class); - thrown.expectMessage("this API is unavailable due to config"); - blockingStubSolidity.getBlockByNum(message); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + () -> blockingStubSolidity.getBlockByNum(message)); } @Test @@ -236,20 +239,19 @@ public void testAccessDisabledPBFTNode() { disabledApiList.add("getblockbynum"); Args.getInstance().setDisabledApiList(disabledApiList); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - thrown.expect(StatusRuntimeException.class); - thrown.expectMessage("this API is unavailable due to config"); - blockingStubPBFT.getBlockByNum(message); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + () -> blockingStubPBFT.getBlockByNum(message)); } @Test public void testAccessNoDisabled() { Args.getInstance().setDisabledApiList(Collections.emptyList()); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - Assert.assertNotNull(blockingStubFull.getBlockByNum(message)); - Assert.assertNotNull(blockingStubSolidity.getBlockByNum(message)); - Assert.assertNotNull(blockingStubPBFT.getBlockByNum(message)); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertNotNull(blockingStubFull.getBlockByNum(message)); + assertNotNull(blockingStubSolidity.getBlockByNum(message)); + assertNotNull(blockingStubPBFT.getBlockByNum(message)); } @Test @@ -258,10 +260,32 @@ public void testAccessDisabledNotIncluded() { disabledApiList.add("getaccount"); Args.getInstance().setDisabledApiList(disabledApiList); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - Assert.assertNotNull(blockingStubFull.getBlockByNum(message)); - Assert.assertNotNull(blockingStubSolidity.getBlockByNum(message)); - Assert.assertNotNull(blockingStubPBFT.getBlockByNum(message)); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertNotNull(blockingStubFull.getBlockByNum(message)); + assertNotNull(blockingStubSolidity.getBlockByNum(message)); + assertNotNull(blockingStubPBFT.getBlockByNum(message)); + } + + @Test + public void testGetBandwidthPrices() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getBandwidthPrices(message)); + assertNotNull(blockingStubSolidity.getBandwidthPrices(message)); + assertNotNull(blockingStubPBFT.getBandwidthPrices(message)); + } + + @Test + public void testGetEnergyPrices() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getEnergyPrices(message)); + assertNotNull(blockingStubSolidity.getEnergyPrices(message)); + assertNotNull(blockingStubPBFT.getEnergyPrices(message)); + } + + @Test + public void testGetMemoFee() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getMemoFee(message)); } } diff --git a/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java new file mode 100644 index 00000000000..90d2794be9a --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java @@ -0,0 +1,62 @@ +package org.tron.core.services.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetBandwidthPricesServletTest extends BaseTest { + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Resource + private GetBandwidthPricesServlet getBandwidthPricesServlet; + + @BeforeClass + public static void init() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getBandwidthPricesServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getBandwidthPricesServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java new file mode 100644 index 00000000000..391f2c2d4a7 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java @@ -0,0 +1,62 @@ +package org.tron.core.services.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetEnergyPricesServletTest extends BaseTest { + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Resource + private GetEnergyPricesServlet getEnergyPricesServlet; + + @BeforeClass + public static void init() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getEnergyPricesServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getEnergyPricesServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java new file mode 100644 index 00000000000..cdfb32cb411 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java @@ -0,0 +1,62 @@ +package org.tron.core.services.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetMemoFeePricesServletTest extends BaseTest { + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Resource + private GetMemoFeePricesServlet getMemoFeePricesServlet; + + @BeforeClass + public static void init() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getMemoFeePricesServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getMemoFeePricesServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/http/TriggerSmartContractServletTest.java b/framework/src/test/java/org/tron/core/services/http/TriggerSmartContractServletTest.java index 8adae9b8c3d..0525ec6e9d0 100644 --- a/framework/src/test/java/org/tron/core/services/http/TriggerSmartContractServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/TriggerSmartContractServletTest.java @@ -55,8 +55,6 @@ public void before() { appT.addService(httpApiService); // start services - appT.initServices(Args.getInstance()); - appT.startServices(); appT.startup(); // create contract for testing diff --git a/framework/src/test/java/org/tron/core/zksnark/LibrustzcashTest.java b/framework/src/test/java/org/tron/core/zksnark/LibrustzcashTest.java index 55223bccb0c..38fdce334b2 100644 --- a/framework/src/test/java/org/tron/core/zksnark/LibrustzcashTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/LibrustzcashTest.java @@ -50,9 +50,9 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.zen.ZenTransactionBuilder; import org.tron.core.zen.ZenTransactionBuilder.SpendDescriptionInfo; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -116,7 +116,7 @@ public static void test(byte[] K, byte[] ovk, byte[] cv, byte[] cm, byte[] epk) } public static void librustzcashInitZksnarkParams() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } @Test diff --git a/framework/src/test/java/org/tron/core/zksnark/SaplingNoteTest.java b/framework/src/test/java/org/tron/core/zksnark/SaplingNoteTest.java index 776e94adc3c..60f6c8c0826 100644 --- a/framework/src/test/java/org/tron/core/zksnark/SaplingNoteTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/SaplingNoteTest.java @@ -8,7 +8,7 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.PaymentAddress; import org.tron.core.zen.address.SpendingKey; @@ -21,7 +21,7 @@ public class SaplingNoteTest { public static void init() { Args.setFullNodeAllowShieldedTransaction(true); // Args.getInstance().setAllowShieldedTransaction(1); - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } @AfterClass diff --git a/framework/src/test/java/org/tron/core/zksnark/SendCoinShieldTest.java b/framework/src/test/java/org/tron/core/zksnark/SendCoinShieldTest.java index 5b480cd0274..5fafe0724dc 100644 --- a/framework/src/test/java/org/tron/core/zksnark/SendCoinShieldTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/SendCoinShieldTest.java @@ -64,9 +64,9 @@ import org.tron.core.exception.VMIllegalException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.zen.ZenTransactionBuilder; import org.tron.core.zen.ZenTransactionBuilder.SpendDescriptionInfo; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -221,7 +221,7 @@ private IncrementalMerkleVoucherContainer createSimpleMerkleVoucherContainer(byt } private void librustzcashInitZksnarkParams() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } @Test diff --git a/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java b/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java index 514a5dfab76..e52021986fc 100755 --- a/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java @@ -66,11 +66,11 @@ import org.tron.core.exception.VMIllegalException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.utils.TransactionUtil; import org.tron.core.zen.ZenTransactionBuilder; import org.tron.core.zen.ZenTransactionBuilder.ReceiveDescriptionInfo; import org.tron.core.zen.ZenTransactionBuilder.SpendDescriptionInfo; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -142,7 +142,7 @@ public void init() { } private static void librustzcashInitZksnarkParams() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } private static byte[] randomUint256() { diff --git a/framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java b/framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java index 205b2fbd30d..c23ab213006 100644 --- a/framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java +++ b/framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java @@ -42,8 +42,6 @@ public void startApp() { appTest = ApplicationFactory.create(context); appTest.addService(context.getBean(RpcApiService.class)); appTest.addService(context.getBean(RpcApiServiceOnSolidity.class)); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); String fullNode = String.format("%s:%d", "127.0.0.1", diff --git a/framework/src/test/java/org/tron/program/SolidityNodeTest.java b/framework/src/test/java/org/tron/program/SolidityNodeTest.java index 422ec5e6876..4d151cda7f0 100755 --- a/framework/src/test/java/org/tron/program/SolidityNodeTest.java +++ b/framework/src/test/java/org/tron/program/SolidityNodeTest.java @@ -35,6 +35,7 @@ public class SolidityNodeTest { */ @BeforeClass public static void init() { + rpcApiService.init(Args.getInstance()); rpcApiService.start(); } diff --git a/protocol/src/main/protos/api/api.proto b/protocol/src/main/protos/api/api.proto index d23d6e01729..9a7534cf6ce 100644 --- a/protocol/src/main/protos/api/api.proto +++ b/protocol/src/main/protos/api/api.proto @@ -767,6 +767,15 @@ service Wallet { rpc GetBlock (BlockReq) returns (BlockExtention) { } + + rpc GetBandwidthPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetEnergyPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetMemoFee (EmptyMessage) returns (PricesResponseMessage) { + } }; service WalletSolidity { @@ -963,6 +972,11 @@ service WalletSolidity { } rpc GetBlock (BlockReq) returns (BlockExtention) { } + rpc GetBandwidthPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetEnergyPrices (EmptyMessage) returns (PricesResponseMessage) { + } }; service WalletExtension { @@ -1107,6 +1121,10 @@ message CanWithdrawUnfreezeAmountResponseMessage { int64 amount = 1; } +message PricesResponseMessage { + string prices = 1; +} + // Gossip node list message NodeList { repeated Node nodes = 1; diff --git a/protocol/src/main/protos/core/Tron.proto b/protocol/src/main/protos/core/Tron.proto index aa6a96ba1b3..2fc08901e93 100644 --- a/protocol/src/main/protos/core/Tron.proto +++ b/protocol/src/main/protos/core/Tron.proto @@ -601,6 +601,8 @@ enum ReasonCode { TOO_MANY_PEERS_WITH_SAME_IP = 0x22; LIGHT_NODE_SYNC_FAIL = 0x23; BELOW_THAN_ME = 0X24; + NOT_WITNESS = 0x25; + NO_SUCH_MESSAGE = 0x26; UNKNOWN = 0xFF; }