diff --git a/.gitignore b/.gitignore index 71092c5d325..b980800f353 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,7 @@ src/main/resources/META-INF/ /output_witness/ output* nodeId.properties -Wallet \ No newline at end of file +Wallet + +# vm_trace +/vm_trace/ diff --git a/.travis.yml b/.travis.yml index ff5915a539b..fc2d449d532 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,3 +25,5 @@ deploy: branch: develop + + diff --git a/README.md b/README.md index 9a72663ee09..677e18b92b5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@


- +
java-tron
@@ -62,6 +62,12 @@ TRON Protocol and the Tron Virtual Machine (TVM) allow anyone to develop decentr * JDK 1.8 (JDK 1.9+ are not supported yet) * On Linux Ubuntu system (e.g. Ubuntu 16.04.4 LTS), ensure that the machine has [__Oracle JDK 8__](https://www.digitalocean.com/community/tutorials/how-to-install-java-with-apt-get-on-ubuntu-16-04), instead of having __Open JDK 8__ in the system. If you are building the source code by using __Open JDK 8__, you will get [__Build Failed__](https://github.com/tronprotocol/java-tron/issues/337) result. +* Open **UDP** ports for connection to the network +* **MINIMUM** 2 ENERGY Cores + +## Build and Deploy automatically using scripts + +- Please take a look at the [Tron Deployment Scripts](https://github.com/tronprotocol/TronDeployment) repository. ## Getting the code with git @@ -126,7 +132,7 @@ cd java-tron * Build in [IntelliJ IDEA](https://www.jetbrains.com/idea/) (community version is enough): - ** Please run ./gradlew build once to build the protocol files ** + **Please run ./gradlew build once to build the protocol files** 1. Start IntelliJ. Select `File` -> `Open`, then locate to the java-tron folder which you have git cloned to your local drive. Then click `Open` button on the right bottom. 2. Check on `Use auto-import` on the `Import Project from Gradle` dialog. Select JDK 1.8 in the `Gradle JVM` option. Then click `OK`. @@ -142,10 +148,54 @@ https://github.com/tronprotocol/Documentation/blob/master/TRX/Solidity_and_Full_ ## Running a local node and connecting to the public testnet -* Ensure that the version number is consistent with the version number of the test network. If it is not consistent, please modify the node.p2p.version in the config.conf file and delete the out-directory directory (if it exists). -* The current p2p.version is **619** +* Use the [Testnet Config](https://github.com/tronprotocol/TronDeployment/blob/master/test_net_config.conf) or use the [Tron Deployment Scripts](https://github.com/tronprotocol/TronDeployment) + + +### Running a Super Representative Node for mainnet + +* Use the executable JAR(Recommended way) + +```bash +java -jar FullNode.jar -p your private key --witness -c your config.conf(Example:/data/java-tron/config.conf) +Example: +java -jar FullNode.jar -p 650950B193DDDDB35B6E48912DD28F7AB0E7140C1BFDEFD493348F02295BD812 --witness -c /data/java-tron/config.conf + +``` + +This is similar to running a private testnet, except that the IPs in the `config.conf` are officially declared by TRON. + +
+Correct output + +```bash + +20:43:18.138 INFO [main] [o.t.p.FullNode](FullNode.java:21) Full node running. +20:43:18.486 INFO [main] [o.t.c.c.a.Args](Args.java:429) Bind address wasn't set, Punching to identify it... +20:43:18.493 INFO [main] [o.t.c.c.a.Args](Args.java:433) UDP local bound to: 10.0.8.146 +20:43:18.495 INFO [main] [o.t.c.c.a.Args](Args.java:448) External IP wasn't set, using checkip.amazonaws.com to identify it... +20:43:19.450 INFO [main] [o.t.c.c.a.Args](Args.java:461) External address identified: 47.74.147.87 +20:43:19.599 INFO [main] [o.s.c.a.AnnotationConfigApplicationContext](AbstractApplicationContext.java:573) Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@124c278f: startup date [Fri Apr 27 20:43:19 CST 2018]; root of context hierarchy +20:43:19.972 INFO [main] [o.s.b.f.a.AutowiredAnnotationBeanPostProcessor](AutowiredAnnotationBeanPostProcessor.java:153) JSR-330 'javax.inject.Inject' annotation found and supported for autowiring +20:43:20.380 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:244) update latest block header timestamp = 0 +20:43:20.383 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:252) update latest block header number = 0 +20:43:20.393 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:260) update latest block header id = 00 +20:43:20.394 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:265) update state flag = 0 +20:43:20.559 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! +20:43:20.567 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! +20:43:20.568 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! +20:43:20.568 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! +20:43:20.569 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! +20:43:20.596 INFO [main] [o.t.c.d.Manager](Manager.java:300) create genesis block +20:43:20.607 INFO [main] [o.t.c.d.Manager](Manager.java:306) save block: BlockCapsule + +``` + +Then observe whether block synchronization success,If synchronization successfully explains the success of the super node + +
+ -### How to run a Super Node +### Running a Super Representative Node for private testnet * use master branch * You should modify the config.conf 1. Replace existing entry in genesis.block.witnesses with your address. @@ -157,17 +207,11 @@ https://github.com/tronprotocol/Documentation/blob/master/TRX/Solidity_and_Full_ ```bash cd build/libs -java -jar java-tron.jar -p yourself private key --witness -c yourself config.conf(Example:/data/java-tron/config.conf) +java -jar FullNode.jar -p your private key --witness -c your config.conf (Example:/data/java-tron/config.conf) Example: -java -jar java-tron.jar -p 650950B193DDDDB35B6E48912DD28F7AB0E7140C1BFDEFD493348F02295BD812 --witness -c /data/java-tron/config.conf +java -jar FullNode.jar -p 650950B193DDDDB35B6E48912DD28F7AB0E7140C1BFDEFD493348F02295BD812 --witness -c /data/java-tron/config.conf ``` - -* In the Terminal - Un the config.conf localwitness add your private key. -```bash -./gradlew run -Pwitness -```
Show Output @@ -286,50 +330,6 @@ In the `Program arguments` option, fill in `--witness`: Then, run `FullNode::main()` again. -### Running a Super Node - -* Use the executable JAR(Recommended way) - -```bash -cd build/libs -java -jar java-tron.jar -p yourself private key --witness -c yourself config.conf(Example:/data/java-tron/config.conf) -Example: -java -jar java-tron.jar -p 650950B193DDDDB35B6E48912DD28F7AB0E7140C1BFDEFD493348F02295BD812 --witness -c /data/java-tron/config.conf - -``` - -This is similar to running a private testnet, except that the IPs in the `config.conf` are officially declared by TRON. - -
-Correct output - -```bash - -20:43:18.138 INFO [main] [o.t.p.FullNode](FullNode.java:21) Full node running. -20:43:18.486 INFO [main] [o.t.c.c.a.Args](Args.java:429) Bind address wasn't set, Punching to identify it... -20:43:18.493 INFO [main] [o.t.c.c.a.Args](Args.java:433) UDP local bound to: 10.0.8.146 -20:43:18.495 INFO [main] [o.t.c.c.a.Args](Args.java:448) External IP wasn't set, using checkip.amazonaws.com to identify it... -20:43:19.450 INFO [main] [o.t.c.c.a.Args](Args.java:461) External address identified: 47.74.147.87 -20:43:19.599 INFO [main] [o.s.c.a.AnnotationConfigApplicationContext](AbstractApplicationContext.java:573) Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@124c278f: startup date [Fri Apr 27 20:43:19 CST 2018]; root of context hierarchy -20:43:19.972 INFO [main] [o.s.b.f.a.AutowiredAnnotationBeanPostProcessor](AutowiredAnnotationBeanPostProcessor.java:153) JSR-330 'javax.inject.Inject' annotation found and supported for autowiring -20:43:20.380 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:244) update latest block header timestamp = 0 -20:43:20.383 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:252) update latest block header number = 0 -20:43:20.393 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:260) update latest block header id = 00 -20:43:20.394 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:265) update state flag = 0 -20:43:20.559 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.567 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.568 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.568 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.569 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.596 INFO [main] [o.t.c.d.Manager](Manager.java:300) create genesis block -20:43:20.607 INFO [main] [o.t.c.d.Manager](Manager.java:306) save block: BlockCapsule - -``` - -Then observe whether block synchronization success,If synchronization successfully explains the success of the super node - -
- # Quick Start Read the [Quick Start](http://wiki.tron.network/en/latest/The_TRON_Network.html#how-to-build). diff --git a/build.gradle b/build.gradle index 1c42dd1d362..7941bff43d8 100755 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,7 @@ repositories { maven { url 'http://mvnrepository.com' } mavenLocal() mavenCentral() + maven { url 'http://repo.spring.io/plugins-release' } } def versions = [ checkstyle: '8.7', @@ -68,6 +69,24 @@ configurations.getByName('checkstyleConfig') { transitive = false } +static def isWindows() { + return org.gradle.internal.os.OperatingSystem.current().isWindows() +} + +if (isWindows()) { + ext { + leveldbGroup = "org.ethereum" + leveldbName = "leveldbjni-all" + leveldbVersion = "1.18.3" + } +} else { + ext { + leveldbGroup = "org.fusesource.leveldbjni" + leveldbName = "leveldbjni-all" + leveldbVersion = "1.8" + } +} + dependencies { //local libraries compile fileTree(dir: 'libs', include: '*.jar') @@ -95,8 +114,7 @@ dependencies { compile "org.iq80.leveldb:leveldb:0.7" - compile group: 'org.fusesource.leveldbjni', name: 'leveldbjni-all', - version: '1.8' + compile group: leveldbGroup, name: leveldbName, version: leveldbVersion compile "org.apache.commons:commons-collections4:4.0" diff --git a/core/Contract.proto b/core/Contract.proto deleted file mode 100644 index 0306580d19f..00000000000 --- a/core/Contract.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; - -package protocol; - -option java_package = "org.tron.protos"; //Specify the name of the package that generated the Java file -option java_outer_classname = "Contract"; //Specify the class name of the generated Java file -option go_package = "github.com/tronprotocol/grpc-gateway/core"; - - -message VoteContract { - bytes address = 1; - repeated bytes voidAddress = 2; - bool support = 3; -} - -message TransferContract { - -} - - -message DeployContract { - bytes address = 1; - bytes script = 2; -} - - -message CustomContract { - -} \ No newline at end of file diff --git a/deploy.sh b/deploy.sh index 7a0486beff9..9576bcc254b 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,3 +1,3 @@ #!/bin/bash ssh tron@47.93.9.236 -p 22008 sh /home/tron/workspace/deploy_all.sh - +./gradlew stest diff --git a/src/main/java/org/tron/common/application/Application.java b/src/main/java/org/tron/common/application/Application.java index c408b4419f9..d9279ddb25b 100644 --- a/src/main/java/org/tron/common/application/Application.java +++ b/src/main/java/org/tron/common/application/Application.java @@ -43,4 +43,5 @@ public interface Application { void addService(Service service); Manager getDbManager(); + } diff --git a/src/main/java/org/tron/common/application/ApplicationFactory.java b/src/main/java/org/tron/common/application/ApplicationFactory.java index 319bb5e8bb6..7c0146afc37 100644 --- a/src/main/java/org/tron/common/application/ApplicationFactory.java +++ b/src/main/java/org/tron/common/application/ApplicationFactory.java @@ -15,22 +15,10 @@ package org.tron.common.application; -import com.google.inject.Guice; -import com.google.inject.Injector; import org.springframework.context.ApplicationContext; public class ApplicationFactory { - /** - * Build a Guice instance. - * - * @return Guice - */ - public Injector buildGuice() { - return Guice.createInjector( - new Module()); - } - /** * Build a new application. */ diff --git a/src/main/java/org/tron/common/application/ApplicationImpl.java b/src/main/java/org/tron/common/application/ApplicationImpl.java index aa94fe96f49..e5961f3f11a 100644 --- a/src/main/java/org/tron/common/application/ApplicationImpl.java +++ b/src/main/java/org/tron/common/application/ApplicationImpl.java @@ -6,7 +6,6 @@ import org.tron.core.config.args.Args; import org.tron.core.db.BlockStore; import org.tron.core.db.Manager; -import org.tron.core.db.RevokingStore; import org.tron.core.net.node.Node; import org.tron.core.net.node.NodeDelegate; import org.tron.core.net.node.NodeDelegateImpl; @@ -25,7 +24,7 @@ public class ApplicationImpl implements Application { @Autowired private Manager dbManager; - + private boolean isProducer; private void resetP2PNode() { @@ -76,6 +75,7 @@ public void shutdown() { closeAllStore(); } closeConnection(); + dbManager.stopRepushThread(); System.err.println("******** end to shutdown ********"); } diff --git a/src/main/java/org/tron/common/application/CliApplication.java b/src/main/java/org/tron/common/application/CliApplication.java index e56093eaa53..9bcffd106b2 100644 --- a/src/main/java/org/tron/common/application/CliApplication.java +++ b/src/main/java/org/tron/common/application/CliApplication.java @@ -75,4 +75,5 @@ public void addService(Service service) { public Manager getDbManager() { return null; } + } diff --git a/src/main/java/org/tron/common/application/Module.java b/src/main/java/org/tron/common/application/Module.java deleted file mode 100644 index 5b50d9173b4..00000000000 --- a/src/main/java/org/tron/common/application/Module.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 static org.tron.core.Constant.BLOCK_DB_NAME; -import static org.tron.core.Constant.TRANSACTION_DB_NAME; - -import com.google.inject.AbstractModule; -import com.google.inject.Provides; -import com.google.inject.Singleton; -import javax.inject.Named; -import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; -import org.tron.core.config.args.Args; - -public class Module extends AbstractModule { - - @Override - protected void configure() { - - } - - /** - * build transaction database. - */ - @Provides - @Singleton - @Named("transaction") - public LevelDbDataSourceImpl buildTransactionDb() { - LevelDbDataSourceImpl db = new LevelDbDataSourceImpl(Args.getInstance().getOutputDirectory(), - TRANSACTION_DB_NAME); - db.initDB(); - return db; - } - - /** - * build block database. - */ - @Provides - @Singleton - @Named("block") - public LevelDbDataSourceImpl buildBlockDb() { - LevelDbDataSourceImpl db = new LevelDbDataSourceImpl(Args.getInstance().getOutputDirectory(), - BLOCK_DB_NAME); - db.initDB(); - return db; - } -} diff --git a/src/main/java/org/tron/common/application/TronApplicationContext.java b/src/main/java/org/tron/common/application/TronApplicationContext.java new file mode 100644 index 00000000000..50cda6935f5 --- /dev/null +++ b/src/main/java/org/tron/common/application/TronApplicationContext.java @@ -0,0 +1,32 @@ +package org.tron.common.application; + +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.core.db.Manager; + +public class TronApplicationContext extends AnnotationConfigApplicationContext { + + public TronApplicationContext() { + } + + public TronApplicationContext(DefaultListableBeanFactory beanFactory) { + super(beanFactory); + } + + public TronApplicationContext(Class... annotatedClasses) { + super(annotatedClasses); + } + + public TronApplicationContext(String... basePackages) { + super(basePackages); + } + + @Override + public void destroy() { + + Manager dbManager = getBean(Manager.class); + dbManager.stopRepushThread(); + + super.destroy(); + } +} diff --git a/src/main/java/org/tron/common/net/udp/handler/MessageHandler.java b/src/main/java/org/tron/common/net/udp/handler/MessageHandler.java index 23660f12939..b497f36f6cf 100644 --- a/src/main/java/org/tron/common/net/udp/handler/MessageHandler.java +++ b/src/main/java/org/tron/common/net/udp/handler/MessageHandler.java @@ -38,8 +38,8 @@ public class MessageHandler extends SimpleChannelInboundHandler private EventHandler eventHandler; - public MessageHandler(NioDatagramChannel ch, EventHandler eventHandler) { - channel = ch; + public MessageHandler(NioDatagramChannel channel, EventHandler eventHandler) { + this.channel = channel; this.eventHandler = eventHandler; } diff --git a/src/main/java/org/tron/common/net/udp/handler/PacketDecoder.java b/src/main/java/org/tron/common/net/udp/handler/PacketDecoder.java index 182f6df35bd..bd239e40550 100644 --- a/src/main/java/org/tron/common/net/udp/handler/PacketDecoder.java +++ b/src/main/java/org/tron/common/net/udp/handler/PacketDecoder.java @@ -29,7 +29,7 @@ public class PacketDecoder extends MessageToMessageDecoder { private static final org.slf4j.Logger logger = LoggerFactory.getLogger("PacketDecoder"); - private int maxSize = 2048; + private final int maxSize = 2048; @Override public void decode(ChannelHandlerContext ctx, DatagramPacket packet, List out) throws Exception { diff --git a/src/main/java/org/tron/common/net/udp/handler/UdpEvent.java b/src/main/java/org/tron/common/net/udp/handler/UdpEvent.java index e7f41bd9616..e6691db6777 100644 --- a/src/main/java/org/tron/common/net/udp/handler/UdpEvent.java +++ b/src/main/java/org/tron/common/net/udp/handler/UdpEvent.java @@ -25,9 +25,9 @@ public class UdpEvent { private Message message; private InetSocketAddress address; - public UdpEvent(Message m, InetSocketAddress a) { - message = m; - address = a; + public UdpEvent(Message message, InetSocketAddress address) { + this.message = message; + this.address = address; } public Message getMessage() { diff --git a/src/main/java/org/tron/common/overlay/discover/node/NodeHandler.java b/src/main/java/org/tron/common/overlay/discover/node/NodeHandler.java index 7daddf77823..0ba03d1323c 100644 --- a/src/main/java/org/tron/common/overlay/discover/node/NodeHandler.java +++ b/src/main/java/org/tron/common/overlay/discover/node/NodeHandler.java @@ -20,7 +20,6 @@ import java.net.InetSocketAddress; import java.util.List; import java.util.concurrent.TimeUnit; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; @@ -99,6 +98,7 @@ public NodeHandler(Node node, NodeManager nodeManager) { this.node = node; this.nodeManager = nodeManager; this.inetSocketAddress = new InetSocketAddress(node.getHost(), node.getPort()); + this.nodeStatistics = new NodeStatistics(node); changeState(State.Discovered); } @@ -127,9 +127,6 @@ public void setNode(Node node) { } public NodeStatistics getNodeStatistics() { - if (nodeStatistics == null) { - nodeStatistics = new NodeStatistics(node); - } return nodeStatistics; } @@ -194,7 +191,6 @@ public void changeState(State newState) { } public void handlePing(PingMessage msg) { - getNodeStatistics().discoverInPing.add(); if (!nodeManager.getTable().getNode().equals(node)) { sendPong(); } @@ -208,7 +204,6 @@ public void handlePing(PingMessage msg) { public void handlePong(PongMessage msg) { if (waitForPong) { waitForPong = false; - getNodeStatistics().discoverInPong.add(); getNodeStatistics().discoverMessageLatency .add((double) System.currentTimeMillis() - pingSent); getNodeStatistics().lastPongReplyTime.set(System.currentTimeMillis()); @@ -227,7 +222,6 @@ public void handleNeighbours(NeighborsMessage msg) { return; } waitForNeighbors = false; - getNodeStatistics().discoverInNeighbours.add(); for (Node n : msg.getNodes()) { if (!nodeManager.getPublicHomeNode().getHexId().equals(n.getHexId())) { nodeManager.getNodeHandler(n); @@ -236,7 +230,6 @@ public void handleNeighbours(NeighborsMessage msg) { } public void handleFindNode(FindNodeMessage msg) { - getNodeStatistics().discoverInFind.add(); List closest = nodeManager.getTable().getClosestNodes(msg.getTargetId()); sendNeighbours(closest); } @@ -261,7 +254,6 @@ public void sendPing() { waitForPong = true; pingSent = System.currentTimeMillis(); sendMessage(ping); - getNodeStatistics().discoverOutPing.add(); if (nodeManager.getPongTimer().isShutdown()) { return; @@ -281,24 +273,22 @@ public void sendPing() { public void sendPong() { Message pong = new PongMessage(nodeManager.getPublicHomeNode()); sendMessage(pong); - getNodeStatistics().discoverOutPong.add(); } public void sendNeighbours(List neighbours) { Message neighbors = new NeighborsMessage(nodeManager.getPublicHomeNode(), neighbours); sendMessage(neighbors); - getNodeStatistics().discoverOutNeighbours.add(); } public void sendFindNode(byte[] target) { waitForNeighbors = true; Message findNode = new FindNodeMessage(nodeManager.getPublicHomeNode(), target); sendMessage(findNode); - getNodeStatistics().discoverOutFind.add(); } private void sendMessage(Message msg) { nodeManager.sendOutbound(new UdpEvent(msg, getInetSocketAddress())); + nodeStatistics.messageStatistics.addUdpOutMessage(msg.getType()); } @Override diff --git a/src/main/java/org/tron/common/overlay/discover/node/NodeManager.java b/src/main/java/org/tron/common/overlay/discover/node/NodeManager.java index dab51430252..c47fe886e45 100644 --- a/src/main/java/org/tron/common/overlay/discover/node/NodeManager.java +++ b/src/main/java/org/tron/common/overlay/discover/node/NodeManager.java @@ -48,21 +48,18 @@ import org.tron.common.net.udp.message.discover.PongMessage; import org.tron.common.overlay.discover.DiscoverListener; import org.tron.common.overlay.discover.node.NodeHandler.State; +import org.tron.common.overlay.discover.node.statistics.MessageStatistics; import org.tron.common.overlay.discover.node.statistics.NodeStatistics; import org.tron.common.overlay.discover.table.NodeTable; import org.tron.common.utils.CollectionUtils; import org.tron.core.config.args.Args; import org.tron.core.db.Manager; -import org.tron.protos.Protocol.ReasonCode; @Component public class NodeManager implements EventHandler { private static final org.slf4j.Logger logger = LoggerFactory.getLogger("NodeManager"); - private Cache badNodes = CacheBuilder.newBuilder().maximumSize(10000) - .expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); - private Args args = Args.getInstance(); private Manager dbManager; @@ -240,10 +237,7 @@ public void handleEvent(UdpEvent udpEvent) { } NodeHandler nodeHandler = getNodeHandler(n); - if (badNodes.getIfPresent(nodeHandler.getInetSocketAddress()) != null){ - logger.warn("Receive packet from bad node {}.", sender.getAddress()); - return; - } + nodeHandler.getNodeStatistics().messageStatistics.addUdpInMessage(m.getType()); switch (m.getType()) { case DISCOVER_PING: @@ -259,7 +253,6 @@ public void handleEvent(UdpEvent udpEvent) { nodeHandler.handleNeighbours((NeighborsMessage) m); break; } - calculateMsgCount(nodeHandler); } public void sendOutbound(UdpEvent udpEvent) { @@ -383,17 +376,4 @@ void checkAll() { } } - private void calculateMsgCount(NodeHandler nodeHandler){ - int interval = 10; - int maxCount = 10; - NodeStatistics statistics = nodeHandler.getNodeStatistics(); - int count = statistics.discoverInPing.getCount(interval) + statistics.discoverInPong.getCount(interval) - + statistics.discoverInFind.getCount(interval) + statistics.discoverInNeighbours.getCount(interval); - if (count > maxCount){ - logger.warn("UDP attack found: {}.", nodeHandler); - badNodes.put(nodeHandler.getInetSocketAddress(), nodeHandler); - table.dropNode(nodeHandler.getNode()); - } - } - } diff --git a/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageCount.java b/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageCount.java new file mode 100644 index 00000000000..43ef657ede6 --- /dev/null +++ b/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageCount.java @@ -0,0 +1,69 @@ +package org.tron.common.overlay.discover.node.statistics; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MessageCount { + + private static int SIZE = 60; + + private int[] szCount = new int[SIZE]; + + private long indexTime = System.currentTimeMillis() / 1000; + + private int index = (int) (indexTime % SIZE); + + private long totalCount = 0; + + private void update() { + long time = System.currentTimeMillis() / 1000; + long gap = time - indexTime; + int k = gap > SIZE ? SIZE : (int) gap; + if (k > 0) { + for (int i = 1; i <= k; i++) { + szCount[(index + i) % SIZE] = 0; + } + index = (int) (time % SIZE); + indexTime = time; + } + } + + public void add() { + update(); + szCount[index]++; + totalCount++; + } + + public void add(int count) { + update(); + szCount[index] += count; + totalCount += count; + } + + public int getCount(int interval) { + if (interval > SIZE) { + logger.warn("Param interval({}) is gt SIZE({})", interval, SIZE); + return 0; + } + update(); + int count = 0; + for (int i = 0; i < interval; i++) { + count += szCount[(SIZE + index - i) % SIZE]; + } + return count; + } + + public long getTotalCount() { + return totalCount; + } + + public void reset() { + totalCount = 0; + } + + @Override + public String toString() { + return String.valueOf(totalCount); + } + +} diff --git a/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageCountStatistics.java b/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageCountStatistics.java deleted file mode 100644 index b205cf7fcee..00000000000 --- a/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageCountStatistics.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.tron.common.overlay.discover.node.statistics; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class MessageCountStatistics { - - private static int SIZE = 60; - - private int [] szCount = new int[SIZE]; - - private long indexTime = System.currentTimeMillis() / 1000; - - private int index = (int)(indexTime % SIZE); - - private long totalCount = 0; - - private void update(){ - long time = System.currentTimeMillis() / 1000; - long gap = time - indexTime; - int k = gap > SIZE ? SIZE : (int)gap; - if (k > 0){ - for (int i = 1; i <= k; i++){ - szCount[(index + i) % SIZE] = 0; - } - index = (int)(time % SIZE); - indexTime = time; - } - } - - public void add() { - update(); - szCount[index]++; - totalCount++; - } - - public int getCount(int interval){ - if (interval > SIZE){ - logger.warn("Param interval({}) is gt SIZE({})", interval, SIZE); - return 0; - } - update(); - int count = 0; - for (int i = 0; i < interval; i++){ - count += szCount[(SIZE + index - i) % SIZE]; - } - return count; - } - - public long getTotalCount() { - return totalCount; - } -} diff --git a/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageStatistics.java b/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageStatistics.java new file mode 100644 index 00000000000..89f92d8a218 --- /dev/null +++ b/src/main/java/org/tron/common/overlay/discover/node/statistics/MessageStatistics.java @@ -0,0 +1,197 @@ +package org.tron.common.overlay.discover.node.statistics; + +import lombok.extern.slf4j.Slf4j; +import org.tron.common.net.udp.message.UdpMessageTypeEnum; +import org.tron.common.overlay.message.Message; +import org.tron.core.net.message.FetchInvDataMessage; +import org.tron.core.net.message.InventoryMessage; +import org.tron.core.net.message.MessageTypes; +import org.tron.core.net.message.TransactionsMessage; + +@Slf4j +public class MessageStatistics { + + //udp discovery + public final MessageCount discoverInPing = new MessageCount(); + public final MessageCount discoverOutPing = new MessageCount(); + public final MessageCount discoverInPong = new MessageCount(); + public final MessageCount discoverOutPong = new MessageCount(); + public final MessageCount discoverInFindNode = new MessageCount(); + public final MessageCount discoverOutFindNode = new MessageCount(); + public final MessageCount discoverInNeighbours = new MessageCount(); + public final MessageCount discoverOutNeighbours = new MessageCount(); + + //tcp p2p + public final MessageCount p2pInHello = new MessageCount(); + public final MessageCount p2pOutHello = new MessageCount(); + public final MessageCount p2pInPing = new MessageCount(); + public final MessageCount p2pOutPing = new MessageCount(); + public final MessageCount p2pInPong = new MessageCount(); + public final MessageCount p2pOutPong = new MessageCount(); + public final MessageCount p2pInDisconnect = new MessageCount(); + public final MessageCount p2pOutDisconnect = new MessageCount(); + + //tcp tron + public final MessageCount tronInMessage = new MessageCount(); + public final MessageCount tronOutMessage = new MessageCount(); + + public final MessageCount tronInSyncBlockChain = new MessageCount(); + public final MessageCount tronOutSyncBlockChain = new MessageCount(); + public final MessageCount tronInBlockChainInventory = new MessageCount(); + public final MessageCount tronOutBlockChainInventory = new MessageCount(); + + public final MessageCount tronInTrxInventory = new MessageCount(); + public final MessageCount tronOutTrxInventory = new MessageCount(); + public final MessageCount tronInTrxInventoryElement = new MessageCount(); + public final MessageCount tronOutTrxInventoryElement = new MessageCount(); + + public final MessageCount tronInBlockInventory = new MessageCount(); + public final MessageCount tronOutBlockInventory = new MessageCount(); + public final MessageCount tronInBlockInventoryElement = new MessageCount(); + public final MessageCount tronOutBlockInventoryElement = new MessageCount(); + + public final MessageCount tronInTrxFetchInvData = new MessageCount(); + public final MessageCount tronOutTrxFetchInvData = new MessageCount(); + public final MessageCount tronInTrxFetchInvDataElement = new MessageCount(); + public final MessageCount tronOutTrxFetchInvDataElement = new MessageCount(); + + public final MessageCount tronInBlockFetchInvData = new MessageCount(); + public final MessageCount tronOutBlockFetchInvData = new MessageCount(); + public final MessageCount tronInBlockFetchInvDataElement = new MessageCount(); + public final MessageCount tronOutBlockFetchInvDataElement = new MessageCount(); + + + public final MessageCount tronInTrx = new MessageCount(); + public final MessageCount tronOutTrx = new MessageCount(); + public final MessageCount tronInTrxs = new MessageCount(); + public final MessageCount tronOutTrxs = new MessageCount(); + public final MessageCount tronInBlock = new MessageCount(); + public final MessageCount tronOutBlock = new MessageCount(); + public final MessageCount tronOutAdvBlock = new MessageCount(); + + public void addUdpInMessage(UdpMessageTypeEnum type){ + addUdpMessage(type, true); + } + + public void addUdpOutMessage(UdpMessageTypeEnum type){ + addUdpMessage(type, false); + } + + public void addTcpInMessage(Message msg){ + addTcpMessage(msg, true); + } + + public void addTcpOutMessage(Message msg){ + addTcpMessage(msg, false); + } + + private void addUdpMessage(UdpMessageTypeEnum type, boolean flag){ + switch (type){ + case DISCOVER_PING: + if (flag) discoverInPing.add(); else discoverOutPing.add(); + break; + case DISCOVER_PONG: + if (flag) discoverInPong.add(); else discoverOutPong.add(); + break; + case DISCOVER_FIND_NODE: + if (flag) discoverInFindNode.add(); else discoverOutFindNode.add(); + break; + case DISCOVER_NEIGHBORS: + if (flag) discoverInNeighbours.add(); else discoverOutNeighbours.add(); + break; + default: + break; + } + } + + private void addTcpMessage(Message msg, boolean flag){ + + if (flag) { + tronInMessage.add(); + } else { + tronOutMessage.add(); + } + + switch (msg.getType()){ + case P2P_HELLO: + if (flag) p2pInHello.add(); else p2pOutHello.add(); + break; + case P2P_PING: + if (flag) p2pInPing.add(); else p2pOutPing.add(); + break; + case P2P_PONG: + if (flag) p2pInPong.add(); else p2pOutPong.add(); + break; + case P2P_DISCONNECT: + if (flag) p2pInDisconnect.add(); else p2pOutDisconnect.add(); + break; + case SYNC_BLOCK_CHAIN: + if (flag) tronInSyncBlockChain.add(); else tronOutSyncBlockChain.add(); + break; + case BLOCK_CHAIN_INVENTORY: + if (flag) tronInBlockChainInventory.add(); else tronOutBlockChainInventory.add(); + break; + case INVENTORY: + InventoryMessage inventoryMessage = (InventoryMessage) msg; + int inventorySize = inventoryMessage.getInventory().getIdsCount(); + if (flag) { + if (inventoryMessage.getInvMessageType() == MessageTypes.TRX){ + tronInTrxInventory.add(); + tronInTrxInventoryElement.add(inventorySize); + }else { + tronInBlockInventory.add(); + tronInBlockInventoryElement.add(inventorySize); + } + } else { + if (inventoryMessage.getInvMessageType() == MessageTypes.TRX){ + tronOutTrxInventory.add(); + tronOutTrxInventoryElement.add(inventorySize); + }else { + tronOutBlockInventory.add(); + tronOutBlockInventoryElement.add(inventorySize); + } + } + break; + case FETCH_INV_DATA: + FetchInvDataMessage fetchInvDataMessage = (FetchInvDataMessage) msg; + int fetchSize = fetchInvDataMessage.getInventory().getIdsCount(); + if (flag) { + if (fetchInvDataMessage.getInvMessageType() == MessageTypes.TRX){ + tronInTrxFetchInvData.add(); + tronInTrxFetchInvDataElement.add(fetchSize); + }else { + tronInBlockFetchInvData.add(); + tronInBlockFetchInvDataElement.add(fetchSize); + } + } else { + if (fetchInvDataMessage.getInvMessageType() == MessageTypes.TRX){ + tronOutTrxFetchInvData.add(); + tronOutTrxFetchInvDataElement.add(fetchSize); + }else { + tronOutBlockFetchInvData.add(); + tronOutBlockFetchInvDataElement.add(fetchSize); + } + } + break; + case TRXS: + TransactionsMessage transactionsMessage = (TransactionsMessage)msg; + if (flag) { + tronInTrxs.add(); + tronInTrx.add(transactionsMessage.getTransactions().getTransactionsCount()); + } else { + tronOutTrxs.add(); + tronOutTrx.add(transactionsMessage.getTransactions().getTransactionsCount()); + } + break; + case TRX: + if (flag) tronInMessage.add(); else tronOutMessage.add(); + break; + case BLOCK: + if (flag) tronInBlock.add(); tronOutBlock.add(); + break; + default: + break; + } + } + +} diff --git a/src/main/java/org/tron/common/overlay/discover/node/statistics/NodeStatistics.java b/src/main/java/org/tron/common/overlay/discover/node/statistics/NodeStatistics.java index d627307de20..e262956375b 100644 --- a/src/main/java/org/tron/common/overlay/discover/node/statistics/NodeStatistics.java +++ b/src/main/java/org/tron/common/overlay/discover/node/statistics/NodeStatistics.java @@ -18,12 +18,10 @@ package org.tron.common.overlay.discover.node.statistics; -import static java.lang.Math.min; - -import java.util.Date; import java.util.concurrent.atomic.AtomicLong; -import org.joda.time.DateTime; +import lombok.Getter; import org.tron.common.overlay.discover.node.Node; +import org.tron.core.config.args.Args; import org.tron.protos.Protocol.ReasonCode; public class NodeStatistics { @@ -31,87 +29,37 @@ public class NodeStatistics { public final static int REPUTATION_PREDEFINED = 100000; public final static long TOO_MANY_PEERS_PENALIZE_TIMEOUT = 60 * 1000L; private static final long CLEAR_CYCLE_TIME = 60 * 60 * 1000L; + private final long MIN_DATA_LENGTH = Args.getInstance().getReceiveTcpMinDataLength(); private boolean isPredefined = false; - private int persistedReputation = 0; - + @Getter private int disconnectTimes = 0; - - // discovery stat - public final MessageCountStatistics discoverInPing = new MessageCountStatistics(); - public final MessageCountStatistics discoverOutPing = new MessageCountStatistics(); - public final MessageCountStatistics discoverInPong = new MessageCountStatistics(); - public final MessageCountStatistics discoverOutPong = new MessageCountStatistics(); - public final MessageCountStatistics discoverInFind = new MessageCountStatistics(); - public final MessageCountStatistics discoverOutFind = new MessageCountStatistics(); - public final MessageCountStatistics discoverInNeighbours = new MessageCountStatistics(); - public final MessageCountStatistics discoverOutNeighbours = new MessageCountStatistics(); - - public final SimpleStatter discoverMessageLatency; - public final AtomicLong lastPongReplyTime = new AtomicLong(0l); // in milliseconds - - // stat - public final MessageCountStatistics p2pInHello = new MessageCountStatistics(); - public final MessageCountStatistics p2pOutHello = new MessageCountStatistics(); - public final MessageCountStatistics tronInMessage = new MessageCountStatistics(); - public final MessageCountStatistics tronOutMessage = new MessageCountStatistics(); - - public final MessageCountStatistics p2pHandShake = new MessageCountStatistics(); - + @Getter private ReasonCode tronLastRemoteDisconnectReason = null; + @Getter private ReasonCode tronLastLocalDisconnectReason = null; private long lastDisconnectedTime = 0; private long firstDisconnectedTime = 0; + public final MessageStatistics messageStatistics = new MessageStatistics(); + public final MessageCount p2pHandShake = new MessageCount(); + public final MessageCount tcpFlow = new MessageCount(); + + public final SimpleStatter discoverMessageLatency; + public final AtomicLong lastPongReplyTime = new AtomicLong(0l); // in milliseconds + + private Reputation reputation; public NodeStatistics(Node node) { discoverMessageLatency = new SimpleStatter(node.getIdString()); - } - - private int getSessionFairReputation() { - int discoverReput = 0; - - discoverReput += - min(discoverInPong.getTotalCount(), 1) * (discoverOutPing.getTotalCount() == discoverInPong.getTotalCount() ? 50 : 1); - - discoverReput += - min(discoverInNeighbours.getTotalCount(), 1) * (discoverOutFind.getTotalCount() == discoverInNeighbours.getTotalCount() ? 50 : 1); - - discoverReput += (int)discoverMessageLatency.getAvrg() == 0 ? 0 : 1000 / discoverMessageLatency.getAvrg(); - - int reput = 0; - reput += p2pHandShake.getTotalCount() > 0 ? 20 : 0; - reput += min(tronInMessage.getTotalCount(), 10) * 3; - - if (wasDisconnected()) { - if (tronLastLocalDisconnectReason == null && tronLastRemoteDisconnectReason == null) { - // means connection was dropped without reporting any reason - bad - reput *= 0.3; - } else if (tronLastLocalDisconnectReason != ReasonCode.REQUESTED) { - // the disconnect was not initiated by discover mode - if (tronLastRemoteDisconnectReason == ReasonCode.TOO_MANY_PEERS) { - // The peer is popular, but we were unlucky - reput *= 0.3; - } else if (tronLastRemoteDisconnectReason != ReasonCode.REQUESTED) { - // other disconnect reasons - reput *= 0.2; - } - } - } - if (disconnectTimes > 20) { - return 0; - } - int score = - discoverReput + 10 * reput - (int) Math.pow(2, disconnectTimes) * (disconnectTimes > 0 ? 10 - : 0); - return score > 0 ? score : 0; + reputation = new Reputation(this); } public int getReputation() { int score = 0; if (!isReputationPenalized()){ - score += persistedReputation / 2 + getSessionFairReputation(); + score += persistedReputation / 5 + reputation.calculate(); } if (isPredefined){ score += REPUTATION_PREDEFINED; @@ -150,9 +98,7 @@ public boolean isReputationPenalized() { firstDisconnectedTime = 0; } - if (tronLastLocalDisconnectReason == ReasonCode.NULL_IDENTITY || - tronLastRemoteDisconnectReason == ReasonCode.NULL_IDENTITY || - tronLastLocalDisconnectReason == ReasonCode.INCOMPATIBLE_PROTOCOL || + if (tronLastLocalDisconnectReason == ReasonCode.INCOMPATIBLE_PROTOCOL || tronLastRemoteDisconnectReason == ReasonCode.INCOMPATIBLE_PROTOCOL || tronLastLocalDisconnectReason == ReasonCode.BAD_PROTOCOL || tronLastRemoteDisconnectReason == ReasonCode.BAD_PROTOCOL || @@ -164,12 +110,12 @@ public boolean isReputationPenalized() { tronLastRemoteDisconnectReason == ReasonCode.FORKED || tronLastLocalDisconnectReason == ReasonCode.UNLINKABLE || tronLastRemoteDisconnectReason == ReasonCode.UNLINKABLE || - tronLastLocalDisconnectReason == ReasonCode.INCOMPATIBLE_VERSION || - tronLastRemoteDisconnectReason == ReasonCode.INCOMPATIBLE_VERSION || tronLastLocalDisconnectReason == ReasonCode.INCOMPATIBLE_CHAIN || tronLastRemoteDisconnectReason == ReasonCode.INCOMPATIBLE_CHAIN || tronLastRemoteDisconnectReason == ReasonCode.SYNC_FAIL || - tronLastLocalDisconnectReason == ReasonCode.SYNC_FAIL) { + tronLastLocalDisconnectReason == ReasonCode.SYNC_FAIL || + tronLastRemoteDisconnectReason == ReasonCode.INCOMPATIBLE_VERSION || + tronLastLocalDisconnectReason == ReasonCode.INCOMPATIBLE_VERSION) { persistedReputation = 0; return true; } @@ -191,6 +137,9 @@ public void notifyDisconnect() { if (firstDisconnectedTime <= 0) { firstDisconnectedTime = lastDisconnectedTime; } + if (tronLastLocalDisconnectReason == ReasonCode.RESET) { + return; + } disconnectTimes++; persistedReputation = persistedReputation / 2; } @@ -203,6 +152,10 @@ public void setPredefined(boolean isPredefined) { this.isPredefined = isPredefined; } + public boolean isPredefined() { + return isPredefined; + } + public void setPersistedReputation(int persistedReputation) { this.persistedReputation = persistedReputation; } @@ -210,16 +163,17 @@ public void setPersistedReputation(int persistedReputation) { @Override public String toString() { return "NodeStat[reput: " + getReputation() + "(" + persistedReputation + "), discover: " + - discoverInPong + "/" + discoverOutPing + " " + - discoverOutPong + "/" + discoverInPing + " " + - discoverInNeighbours + "/" + discoverOutFind + " " + - discoverOutNeighbours + "/" + discoverInFind + " " + + messageStatistics.discoverInPong + "/" + messageStatistics.discoverOutPing + " " + + messageStatistics.discoverOutPong + "/" + messageStatistics.discoverInPing + " " + + messageStatistics.discoverInNeighbours + "/" + messageStatistics.discoverOutFindNode + " " + + messageStatistics.discoverOutNeighbours + "/" + messageStatistics.discoverInFindNode + " " + ((int) discoverMessageLatency.getAvrg()) + "ms" + - ", p2p: " + p2pHandShake + "/" + p2pInHello + "/" + p2pOutHello + " " + - ", tron: " + tronInMessage + "/" + tronOutMessage + " " + + ", p2p: " + p2pHandShake + "/" + messageStatistics.p2pInHello + "/" + messageStatistics.p2pOutHello + " " + + ", tron: " + messageStatistics.tronInMessage + "/" + messageStatistics.tronOutMessage + " " + (wasDisconnected() ? "X " + disconnectTimes : "") + (tronLastLocalDisconnectReason != null ? ("<=" + tronLastLocalDisconnectReason) : " ") + - (tronLastRemoteDisconnectReason != null ? ("=>" + tronLastRemoteDisconnectReason) : " "); + (tronLastRemoteDisconnectReason != null ? ("=>" + tronLastRemoteDisconnectReason) : " ") + + ", tcp flow: " + tcpFlow.getTotalCount(); } public class SimpleStatter { @@ -261,4 +215,12 @@ public String getName() { } + public boolean nodeIsHaveDataTransfer() { + return tcpFlow.getTotalCount() > MIN_DATA_LENGTH; + } + + public void resetTcpFlow() { + tcpFlow.reset(); + } + } diff --git a/src/main/java/org/tron/common/overlay/discover/node/statistics/Reputation.java b/src/main/java/org/tron/common/overlay/discover/node/statistics/Reputation.java new file mode 100644 index 00000000000..e02f447fd4a --- /dev/null +++ b/src/main/java/org/tron/common/overlay/discover/node/statistics/Reputation.java @@ -0,0 +1,167 @@ +package org.tron.common.overlay.discover.node.statistics; + +import static java.lang.Math.min; + +import java.util.ArrayList; +import java.util.List; +import org.tron.protos.Protocol.ReasonCode; + +public class Reputation { + + public abstract class Score implements Comparable { + + protected T t; + + public Score(T t) { + this.t = t; + } + + abstract int calculate(int baseScore); + + public boolean isContinue() { + return true; + } + + public int getOrder() { + return 0; + } + + @Override + public int compareTo(Score score) { + if (getOrder() > score.getOrder()) { + return 1; + } else if (getOrder() < score.getOrder()) { + return -1; + } + return 0; + } + } + + public class DiscoverScore extends Score { + + public DiscoverScore(MessageStatistics messageStatistics) { + super(messageStatistics); + } + + @Override + int calculate(int baseScore) { + int discoverReput = baseScore; + discoverReput += + min(t.discoverInPong.getTotalCount(), 1) * (t.discoverOutPing.getTotalCount() + == t.discoverInPong.getTotalCount() ? 101 : 1); + discoverReput += + min(t.discoverInNeighbours.getTotalCount(), 1) * (t.discoverOutFindNode.getTotalCount() + == t.discoverInNeighbours.getTotalCount() ? 10 : 1); + return discoverReput; + } + + @Override + public boolean isContinue() { + return t.discoverOutPing.getTotalCount() == t.discoverInPong.getTotalCount() + && t.discoverInNeighbours.getTotalCount() <= t.discoverOutFindNode.getTotalCount(); + } + } + + public class TcpScore extends Score { + + public TcpScore(NodeStatistics nodeStatistics) { + super(nodeStatistics); + } + + @Override + int calculate(int baseScore) { + int reput = baseScore; + reput += t.p2pHandShake.getTotalCount() > 0 ? 10 : 0; + reput += min(t.tcpFlow.getTotalCount() / 10240, 20); + reput += t.messageStatistics.p2pOutPing.getTotalCount() == t.messageStatistics.p2pInPong + .getTotalCount() ? 10 : 0; + return reput; + } + } + + public class DisConnectScore extends Score { + + public DisConnectScore(NodeStatistics nodeStatistics) { + super(nodeStatistics); + } + + @Override + int calculate(int baseScore) { + if (t.wasDisconnected()) { + if (t.getTronLastLocalDisconnectReason() == null + && t.getTronLastRemoteDisconnectReason() == null) { + // means connection was dropped without reporting any reason - bad + baseScore *= 0.8; + } else if (t.getTronLastLocalDisconnectReason() != ReasonCode.REQUESTED) { + // the disconnect was not initiated by discover mode + if (t.getTronLastRemoteDisconnectReason() == ReasonCode.TOO_MANY_PEERS + || t.getTronLastLocalDisconnectReason() == ReasonCode.TOO_MANY_PEERS + || t.getTronLastRemoteDisconnectReason() == ReasonCode.TOO_MANY_PEERS_WITH_SAME_IP + || t.getTronLastLocalDisconnectReason() == ReasonCode.TOO_MANY_PEERS_WITH_SAME_IP + || t.getTronLastRemoteDisconnectReason() == ReasonCode.DUPLICATE_PEER + || t.getTronLastLocalDisconnectReason() == ReasonCode.DUPLICATE_PEER + || t.getTronLastRemoteDisconnectReason() == ReasonCode.TIME_OUT + || t.getTronLastLocalDisconnectReason() == ReasonCode.TIME_OUT + || t.getTronLastRemoteDisconnectReason() == ReasonCode.PING_TIMEOUT + || t.getTronLastLocalDisconnectReason() == ReasonCode.PING_TIMEOUT + || t.getTronLastRemoteDisconnectReason() == ReasonCode.CONNECT_FAIL + || t.getTronLastLocalDisconnectReason() == ReasonCode.CONNECT_FAIL) { + // The peer is popular, but we were unlucky + baseScore *= 0.9; + } else if (t.getTronLastLocalDisconnectReason() == ReasonCode.RESET) { + baseScore *= 0.95; + } else if (t.getTronLastRemoteDisconnectReason() != ReasonCode.REQUESTED) { + // other disconnect reasons + baseScore *= 0.7; + } + } + } + if (t.getDisconnectTimes() > 20) { + return 0; + } + int score = baseScore - (int) Math.pow(2, t.getDisconnectTimes()) + * (t.getDisconnectTimes() > 0 ? 10 : 0); + return score; + } + } + + public class OtherScore extends Score { + + public OtherScore(NodeStatistics nodeStatistics) { + super(nodeStatistics); + } + + @Override + int calculate(int baseScore) { + baseScore += (int) t.discoverMessageLatency.getAvrg() == 0 ? 0 + : min(1000 / t.discoverMessageLatency.getAvrg(), 20); + return baseScore; + } + } + + private List scoreList = new ArrayList<>(); + + public Reputation(NodeStatistics nodeStatistics) { + Score discoverScore = new DiscoverScore(nodeStatistics.messageStatistics); + Score otherScore = new OtherScore(nodeStatistics); + Score tcpScore = new TcpScore(nodeStatistics); + Score disconnectScore = new DisConnectScore(nodeStatistics); + + scoreList.add(discoverScore); + scoreList.add(tcpScore); + scoreList.add(otherScore); + scoreList.add(disconnectScore); + } + + public int calculate() { + int scoreNumber = 0; + for (Score score : scoreList) { + scoreNumber = score.calculate(scoreNumber); + if (!score.isContinue()) { + break; + } + } + return scoreNumber > 0 ? scoreNumber : 0; + } + +} diff --git a/src/main/java/org/tron/common/overlay/message/MessageCodec.java b/src/main/java/org/tron/common/overlay/message/MessageCodec.java index 3e3428d57fd..16bba7c035e 100644 --- a/src/main/java/org/tron/common/overlay/message/MessageCodec.java +++ b/src/main/java/org/tron/common/overlay/message/MessageCodec.java @@ -3,14 +3,7 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; -import java.io.IOException; import java.util.List; -import org.apache.commons.lang3.ArrayUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.spongycastle.util.encoders.Hex; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.tron.common.overlay.server.Channel; @@ -28,11 +21,12 @@ public class MessageCodec extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { - byte[] encoded = new byte[buffer.readableBytes()]; + int length = buffer.readableBytes(); + byte[] encoded = new byte[length]; buffer.readBytes(encoded); try { Message msg = createMessage(encoded); - channel.getNodeStatistics().tronInMessage.add(); + channel.getNodeStatistics().tcpFlow.add(length); out.add(msg); } catch (Exception e) { channel.processException(e); diff --git a/src/main/java/org/tron/common/overlay/message/P2pMessageFactory.java b/src/main/java/org/tron/common/overlay/message/P2pMessageFactory.java index 832a638d4c3..dec9d3080ef 100644 --- a/src/main/java/org/tron/common/overlay/message/P2pMessageFactory.java +++ b/src/main/java/org/tron/common/overlay/message/P2pMessageFactory.java @@ -28,7 +28,8 @@ public class P2pMessageFactory extends MessageFactory { @Override public P2pMessage create(byte[] data) throws Exception{ if (data.length <= 1){ - throw new P2pException(TypeEnum.MESSAGE_WITH_WRONG_LENGTH, "len=" + data.length); + throw new P2pException(TypeEnum.MESSAGE_WITH_WRONG_LENGTH, "len=" + data.length + + ", MessageType=" + (data.length == 1 ? data[0] : "unknow")); } try { byte type = data[0]; diff --git a/src/main/java/org/tron/common/overlay/server/Channel.java b/src/main/java/org/tron/common/overlay/server/Channel.java index 1cf1f42a3ae..8cdddf36baa 100644 --- a/src/main/java/org/tron/common/overlay/server/Channel.java +++ b/src/main/java/org/tron/common/overlay/server/Channel.java @@ -98,6 +98,8 @@ public class Channel { private PeerStatistics peerStats = new PeerStatistics(); + private boolean isTrustPeer; + public void init(ChannelPipeline pipeline, String remoteId, boolean discoveryMode, ChannelManager channelManager, PeerConnectionDelegate peerDel) { @@ -107,6 +109,8 @@ public void init(ChannelPipeline pipeline, String remoteId, boolean discoveryMod isActive = remoteId != null && !remoteId.isEmpty(); + startTime = System.currentTimeMillis(); + //TODO: use config here pipeline.addLast("readTimeoutHandler", new ReadTimeoutHandler(60, TimeUnit.SECONDS)); pipeline.addLast(stats.tcp); @@ -131,6 +135,7 @@ public void init(ChannelPipeline pipeline, String remoteId, boolean discoveryMod } public void publicHandshakeFinished(ChannelHandlerContext ctx, HelloMessage msg) { + isTrustPeer = channelManager.getTrustPeers().containsKey(getInetAddress()); ctx.pipeline().remove(handshakeHandler); msgQueue.activate(ctx); ctx.pipeline().addLast("messageCodec", messageCodec); @@ -260,6 +265,10 @@ public boolean isProtocolsInitialized() { return tronState.ordinal() > TronState.INIT.ordinal(); } + public boolean isTrustPeer() { + return isTrustPeer; + } + @Override public boolean equals(Object o) { @@ -291,5 +300,6 @@ public int hashCode() { public String toString() { return String.format("%s | %s", inetSocketAddress, getPeerId()); } + } diff --git a/src/main/java/org/tron/common/overlay/server/ChannelManager.java b/src/main/java/org/tron/common/overlay/server/ChannelManager.java index 3123e536a78..6109c014669 100644 --- a/src/main/java/org/tron/common/overlay/server/ChannelManager.java +++ b/src/main/java/org/tron/common/overlay/server/ChannelManager.java @@ -30,8 +30,6 @@ public class ChannelManager { private static final Logger logger = LoggerFactory.getLogger("ChannelManager"); - private static final int inboundConnectionBanTimeout = 30 * 1000; - private final Map activePeers = new ConcurrentHashMap<>(); private Cache badPeers = CacheBuilder.newBuilder().maximumSize(10000) diff --git a/src/main/java/org/tron/common/overlay/server/HandshakeHandler.java b/src/main/java/org/tron/common/overlay/server/HandshakeHandler.java index 3a9668ba5d1..ffa18d2e86c 100644 --- a/src/main/java/org/tron/common/overlay/server/HandshakeHandler.java +++ b/src/main/java/org/tron/common/overlay/server/HandshakeHandler.java @@ -37,6 +37,7 @@ import org.tron.common.overlay.message.P2pMessageFactory; import org.tron.core.config.args.Args; import org.tron.core.db.Manager; +import org.tron.core.net.message.MessageTypes; import org.tron.core.net.peer.PeerConnection; import org.tron.protos.Protocol.ReasonCode; @@ -119,7 +120,7 @@ private void sendHelloMsg(ChannelHandlerContext ctx, long time){ HelloMessage message = new HelloMessage(nodeManager.getPublicHomeNode(), time, manager.getGenesisBlockId(), manager.getSolidBlockId(), manager.getHeadBlockId()); ctx.writeAndFlush(message.getSendData()); - channel.getNodeStatistics().p2pOutHello.add(); + channel.getNodeStatistics().messageStatistics.addTcpOutMessage(message); logger.info("Handshake Send to {}, {} ", ctx.channel().remoteAddress(), message); } @@ -136,7 +137,7 @@ private void handleHelloMsg(ChannelHandlerContext ctx, HelloMessage msg) { if (msg.getVersion() != Args.getInstance().getNodeP2pVersion()) { logger.info("Peer {} different p2p version, peer->{}, me->{}", ctx.channel().remoteAddress(), msg.getVersion(), Args.getInstance().getNodeP2pVersion()); - channel.disconnect(ReasonCode.INCOMPATIBLE_PROTOCOL); + channel.disconnect(ReasonCode.INCOMPATIBLE_VERSION); return; } @@ -156,7 +157,7 @@ private void handleHelloMsg(ChannelHandlerContext ctx, HelloMessage msg) { ((PeerConnection)channel).setHelloMessage(msg); - channel.getNodeStatistics().p2pInHello.add(); + channel.getNodeStatistics().messageStatistics.addTcpInMessage(msg); channel.publicHandshakeFinished(ctx, msg); if (!channelManager.processPeer(channel)) { diff --git a/src/main/java/org/tron/common/overlay/server/MessageQueue.java b/src/main/java/org/tron/common/overlay/server/MessageQueue.java index 6ef4cf1dd22..20992d75c63 100644 --- a/src/main/java/org/tron/common/overlay/server/MessageQueue.java +++ b/src/main/java/org/tron/common/overlay/server/MessageQueue.java @@ -91,6 +91,7 @@ public boolean sendMessage(Message msg) { return false; } logger.info("Send to {}, {} ", ctx.channel().remoteAddress(), msg); + channel.getNodeStatistics().messageStatistics.addTcpOutMessage(msg); sendTime = System.currentTimeMillis(); if (msg.getAnswerMessage() != null){ requestQueue.add(new MessageRoundtrip(msg)); @@ -102,6 +103,7 @@ public boolean sendMessage(Message msg) { public void receivedMessage(Message msg){ logger.info("Receive from {}, {}", ctx.channel().remoteAddress(), msg); + channel.getNodeStatistics().messageStatistics.addTcpInMessage(msg); MessageRoundtrip messageRoundtrip = requestQueue.peek(); if (messageRoundtrip != null && messageRoundtrip.getMsg().getAnswerMessage() == msg.getClass()){ requestQueue.remove(); diff --git a/src/main/java/org/tron/common/overlay/server/P2pHandler.java b/src/main/java/org/tron/common/overlay/server/P2pHandler.java index 993cf177e35..0e37a53c047 100644 --- a/src/main/java/org/tron/common/overlay/server/P2pHandler.java +++ b/src/main/java/org/tron/common/overlay/server/P2pHandler.java @@ -26,11 +26,16 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import org.tron.common.overlay.discover.node.statistics.MessageStatistics; +import org.tron.common.overlay.discover.node.statistics.NodeStatistics; import org.tron.common.overlay.message.DisconnectMessage; import org.tron.common.overlay.message.P2pMessage; +import org.tron.protos.Protocol.ReasonCode; +@Slf4j @Component @Scope("prototype") public class P2pHandler extends SimpleChannelInboundHandler { @@ -65,12 +70,26 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception { public void channelRead0(final ChannelHandlerContext ctx, P2pMessage msg) throws InterruptedException { msgQueue.receivedMessage(msg); - + MessageStatistics messageStatistics = channel.getNodeStatistics().messageStatistics; switch (msg.getType()) { case P2P_PING: + int count = messageStatistics.p2pInPing.getCount(10); + if (count > 3){ + logger.warn("TCP attack found: {} with ping count({})", ctx.channel().remoteAddress(), count); + channel.disconnect(ReasonCode.BAD_PROTOCOL); + return; + } msgQueue.sendMessage(PONG_MESSAGE); break; case P2P_PONG: + if (messageStatistics.p2pInPong.getTotalCount() > messageStatistics.p2pOutPing.getTotalCount()){ + logger.warn("TCP attack found: {} with ping count({}), pong count({})", + ctx.channel().remoteAddress(), + messageStatistics.p2pOutPing.getTotalCount(), + messageStatistics.p2pInPong.getTotalCount()); + channel.disconnect(ReasonCode.BAD_PROTOCOL); + return; + } hasPing = false; channel.getNodeStatistics().lastPongReplyTime.set(System.currentTimeMillis()); channel.getPeerStats().pong(sendPingTime); diff --git a/src/main/java/org/tron/common/overlay/server/PeerConnectionCheckService.java b/src/main/java/org/tron/common/overlay/server/PeerConnectionCheckService.java new file mode 100644 index 00000000000..cf86f63729e --- /dev/null +++ b/src/main/java/org/tron/common/overlay/server/PeerConnectionCheckService.java @@ -0,0 +1,122 @@ +package org.tron.common.overlay.server; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.Executors; +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.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.tron.common.overlay.discover.node.statistics.NodeStatistics; +import org.tron.common.utils.CollectionUtils; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.net.peer.PeerConnection; +import org.tron.protos.Protocol.ReasonCode; + +@Slf4j +@Service +public class PeerConnectionCheckService { + + public static final long CHECK_TIME = 5 * 60 * 1000L; + private double disconnectNumberFactor = Args.getInstance().getDisconnectNumberFactor(); + private double maxConnectNumberFactor = Args.getInstance().getMaxConnectNumberFactor(); + + @Autowired + private SyncPool pool; + + @Autowired + private ChannelManager channelManager; + + @Autowired + private Manager manager; + + private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2, + r -> new Thread(r, "check-peer-connect")); + + @PostConstruct + public void check() { + logger.info("start the PeerConnectionCheckService"); + scheduledExecutorService + .scheduleWithFixedDelay(new CheckDataTransferTask(), 5, 5, TimeUnit.MINUTES); + if (Args.getInstance().isOpenFullTcpDisconnect()) { + scheduledExecutorService + .scheduleWithFixedDelay(new CheckConnectNumberTask(), 4, 1, TimeUnit.MINUTES); + } + } + + @PreDestroy + public void destroy() { + scheduledExecutorService.shutdown(); + } + + private class CheckDataTransferTask implements Runnable { + + @Override + public void run() { + List peerConnectionList = pool.getActivePeers(); + List willDisconnectPeerList = new ArrayList<>(); + for (PeerConnection peerConnection : peerConnectionList) { + NodeStatistics nodeStatistics = peerConnection.getNodeStatistics(); + if (!nodeStatistics.nodeIsHaveDataTransfer() + && System.currentTimeMillis() - peerConnection.getStartTime() >= CHECK_TIME + && !peerConnection.isTrustPeer() + && !nodeStatistics.isPredefined()) { + //&& !peerConnection.isActive() + //if xxx minutes not have data transfer,disconnect the peer,exclude trust peer and active peer + willDisconnectPeerList.add(peerConnection); + } + nodeStatistics.resetTcpFlow(); + } + if (!willDisconnectPeerList.isEmpty() && peerConnectionList.size() + > Args.getInstance().getNodeMaxActiveNodes() * maxConnectNumberFactor) { + Collections.shuffle(willDisconnectPeerList); + for (int i = 0; i < willDisconnectPeerList.size() * disconnectNumberFactor; i++) { + logger.error("{} not have data transfer, disconnect the peer", + willDisconnectPeerList.get(i).getInetAddress()); + willDisconnectPeerList.get(i).disconnect(ReasonCode.TOO_MANY_PEERS); + } + } +// else if (willDisconnectPeerList.size() == peerConnectionList.size()) { +// for (int i = 0; i < willDisconnectPeerList.size(); i++) { +// logger.error("all peer not have data transfer, disconnect the peer {}", +// willDisconnectPeerList.get(i).getInetAddress()); +// willDisconnectPeerList.get(i).disconnect(ReasonCode.RESET); +// willDisconnectPeerList.get(i).cleanAll(); +// } +// } + } + } + + private class CheckConnectNumberTask implements Runnable { + + @Override + public void run() { + if (pool.getActivePeers().size() >= Args.getInstance().getNodeMaxActiveNodes()) { + logger.warn("connection pool is full"); + List peerList = new ArrayList<>(); + for (PeerConnection peer : pool.getActivePeers()) { + if (!peer.isTrustPeer() && !peer.getNodeStatistics().isPredefined()) { + peerList.add(peer); + } + } + if (peerList.size() >= 2) { + peerList.sort( + Comparator.comparingInt((PeerConnection o) -> o.getNodeStatistics().getReputation())); + peerList = CollectionUtils.truncateRandom(peerList, 2, 1); + } + for (PeerConnection peerConnection : peerList) { + logger.warn("connection pool is full, disconnect the peer : {}", + peerConnection.getInetAddress()); + peerConnection.disconnect(ReasonCode.RESET); + } + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/tron/common/overlay/server/SyncPool.java b/src/main/java/org/tron/common/overlay/server/SyncPool.java index b701a3c0f37..c29e9200520 100644 --- a/src/main/java/org/tron/common/overlay/server/SyncPool.java +++ b/src/main/java/org/tron/common/overlay/server/SyncPool.java @@ -101,7 +101,7 @@ public void init(PeerConnectionDelegate peerDel) { } catch (Throwable t) { logger.error("Exception in sync worker", t); } - }, 30, 3600, TimeUnit.MILLISECONDS); + }, 30000, 3600, TimeUnit.MILLISECONDS); logExecutor.scheduleWithFixedDelay(() -> { try { diff --git a/src/main/java/org/tron/common/runtime/DepositController.java b/src/main/java/org/tron/common/runtime/DepositController.java deleted file mode 100644 index 0a0a75b1289..00000000000 --- a/src/main/java/org/tron/common/runtime/DepositController.java +++ /dev/null @@ -1,165 +0,0 @@ -package org.tron.common.runtime; - -import static org.tron.common.runtime.utils.MUtil.transfer; - -import org.spongycastle.util.encoders.Hex; -import org.tron.common.runtime.vm.program.ProgramResult; -import org.tron.common.runtime.vm.program.invoke.ProgramInvokeFactory; -import org.tron.common.runtime.vm.program.invoke.ProgramInvokeFactoryImpl; -import org.tron.common.storage.Deposit; -import org.tron.common.storage.DepositImpl; -import org.tron.common.storage.DepositQueue; -import org.tron.common.storage.Key; -import org.tron.common.storage.Type; -import org.tron.common.storage.Value; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.db.Manager; -import org.tron.core.db.TransactionTrace; -import org.tron.core.exception.ContractExeException; -import org.tron.core.exception.ContractValidateException; - -/** - * Deposit controller : process pre transaction , block, query contract and etc.. - * - * @author Guo Yonggang - * @since 27.04.2018 - */ -public class DepositController { - - private Manager dbManager; - private ProgramInvokeFactory programInvokeFactory = new ProgramInvokeFactoryImpl(); - ; - private static int QUEUE_SIZE = 4; - private DepositQueue depositQueue = new DepositQueue<>(QUEUE_SIZE); - - private DepositController(Manager dbManager) { - this.dbManager = dbManager; - } - - private Deposit getLastDeposit() { - if (depositQueue.isEmpty()) { - return null; - } - return depositQueue.last(); - } - - /** - * @API roll back one block's data - */ - public Deposit rollback() { - Deposit deposit = depositQueue.removeLast(); - Deposit lastDeposit = getLastDeposit(); - if (lastDeposit != null) { - lastDeposit.setNextDeposit(null); - } - return deposit; - } - - /** - * The trx may be invalid due to check with not newest data. - */ - public int preProcessTransaction(TransactionCapsule trxCap) - throws ContractValidateException, ContractExeException { - DepositImpl deposit = DepositImpl.createRoot(dbManager); - Runtime runtime = new Runtime(trxCap.getInstance(), deposit, programInvokeFactory); - runtime.init(); - runtime.execute(); - runtime.go(); - ProgramResult programResult = runtime.getResult(); - if (programResult.getException() != null) { - return -1; - } - - return 0; - } - - /** - * @param block - * @return - */ - public int processBlock(BlockCapsule block) - throws ContractValidateException, ContractExeException { - Deposit lastDeposit = getLastDeposit(); - Deposit currentDeposit; - if (lastDeposit == null) { - currentDeposit = DepositImpl.createRoot(dbManager); - } else { - currentDeposit = lastDeposit.newDepositNext(); - } - - depositQueue.put(currentDeposit); - for (TransactionCapsule trxCap : block.getTransactions()) { - Deposit trxDeposit = currentDeposit.newDepositChild(); - Runtime runtime = new Runtime(new TransactionTrace(trxCap), block.getInstance(), trxDeposit, - programInvokeFactory); - runtime.init(); - runtime.execute(); - runtime.go(); - - ProgramResult programResult = runtime.getResult(); - if (programResult.getException() != null) { - rollback(); - return -1; - } - - Key key = Key.create(trxCap.getTransactionId().getBytes()); - Value value = Value.create(trxCap.getData(), Type.VALUE_TYPE_CREATE); - currentDeposit.putTransaction(key, value); - } - - Key bKey = Key.create(block.getBlockId().getBytes()); - Value bValue = Value.create(block.getData(), Type.VALUE_TYPE_CREATE); - currentDeposit.putBlock(bKey, bValue); - - // reward witness node - byte[] foundAddress = Hex.decode("FF00"); - byte[] coinBase = block.getWitnessAddress().toByteArray(); - transfer(currentDeposit, foundAddress, coinBase, 36 * 1000000); - - if (depositQueue.size() > QUEUE_SIZE) { - Deposit deposit = depositQueue.get(); - deposit.commit(); - depositQueue.peek().setPrevDeposit(null); - } - - return 0; - } - - /** - * - * @param trxCap - * @return - */ - public ProgramResult processConstantTransaction(TransactionCapsule trxCap) - throws ContractValidateException, ContractExeException { - DepositImpl deposit = DepositImpl.createRoot(dbManager); - Runtime runtime = new Runtime(trxCap.getInstance(), programInvokeFactory, deposit); - runtime.init(); - runtime.execute(); - runtime.go(); - ProgramResult programResult = runtime.getResult(); - return programResult; - } - - public ProgramInvokeFactory getProgramInvokeFactory() { - return programInvokeFactory; - } - - /** - * Single instance - */ - private static DepositController instance = null; - - public static DepositController create(Manager dbManager) { - if (instance != null) { - return instance; - } - instance = new DepositController(dbManager); - return instance; - } - - public static DepositController getInstance() { - return instance; - } -} diff --git a/src/main/java/org/tron/common/runtime/Runtime.java b/src/main/java/org/tron/common/runtime/Runtime.java index 1e58f2ff6b4..c741030683f 100644 --- a/src/main/java/org/tron/common/runtime/Runtime.java +++ b/src/main/java/org/tron/common/runtime/Runtime.java @@ -3,10 +3,13 @@ import static com.google.common.primitives.Longs.max; import static com.google.common.primitives.Longs.min; import static org.apache.commons.lang3.ArrayUtils.isEmpty; -import static org.tron.common.runtime.vm.program.InternalTransaction.ExecuterType.ET_CONSTANT_TYPE; -import static org.tron.common.runtime.vm.program.InternalTransaction.ExecuterType.ET_NORMAL_TYPE; -import static org.tron.common.runtime.vm.program.InternalTransaction.ExecuterType.ET_PRE_TYPE; -import static org.tron.common.runtime.vm.program.InternalTransaction.ExecuterType.ET_UNKNOWN_TYPE; +import static org.tron.common.runtime.utils.MUtil.transfer; +import static org.tron.common.runtime.vm.VMUtils.saveProgramTraceFile; +import static org.tron.common.runtime.vm.VMUtils.zipAndEncode; +import static org.tron.common.runtime.vm.program.InternalTransaction.ExecutorType.ET_CONSTANT_TYPE; +import static org.tron.common.runtime.vm.program.InternalTransaction.ExecutorType.ET_NORMAL_TYPE; +import static org.tron.common.runtime.vm.program.InternalTransaction.ExecutorType.ET_PRE_TYPE; +import static org.tron.common.runtime.vm.program.InternalTransaction.ExecutorType.ET_UNKNOWN_TYPE; import static org.tron.common.runtime.vm.program.InternalTransaction.TrxType.TRX_CONTRACT_CALL_TYPE; import static org.tron.common.runtime.vm.program.InternalTransaction.TrxType.TRX_CONTRACT_CREATION_TYPE; import static org.tron.common.runtime.vm.program.InternalTransaction.TrxType.TRX_PRECOMPILED_TYPE; @@ -14,16 +17,18 @@ import com.google.protobuf.ByteString; import java.math.BigInteger; +import java.util.Arrays; import java.util.List; import java.util.Objects; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; import org.tron.common.runtime.config.SystemProperties; import org.tron.common.runtime.vm.PrecompiledContracts; import org.tron.common.runtime.vm.VM; import org.tron.common.runtime.vm.program.InternalTransaction; +import org.tron.common.runtime.vm.program.InternalTransaction.ExecutorType; import org.tron.common.runtime.vm.program.Program; import org.tron.common.runtime.vm.program.Program.OutOfResourceException; import org.tron.common.runtime.vm.program.ProgramPrecompile; @@ -37,15 +42,15 @@ import org.tron.core.actuator.Actuator; import org.tron.core.actuator.ActuatorFactory; import org.tron.core.capsule.AccountCapsule; -import org.tron.core.capsule.BytesCapsule; import org.tron.core.capsule.ContractCapsule; import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.db.TransactionTrace; import org.tron.core.config.Parameter.ChainConstant; -import org.tron.core.db.CpuProcessor; +import org.tron.core.db.EnergyProcessor; +import org.tron.core.db.StorageMarket; +import org.tron.core.db.TransactionTrace; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; -import org.tron.core.exception.TronException; +import org.tron.core.exception.OutOfSlotTimeException; import org.tron.protos.Contract; import org.tron.protos.Contract.CreateSmartContract; import org.tron.protos.Contract.TriggerSmartContract; @@ -56,15 +61,11 @@ import org.tron.protos.Protocol.Transaction; import org.tron.protos.Protocol.Transaction.Contract.ContractType; -/** - * @author Guo Yonggang - * @since 28.04.2018 - */ +@Slf4j(topic = "Runtime") public class Runtime { - private static final Logger logger = LoggerFactory.getLogger("execute"); - SystemProperties config; + private SystemProperties config = SystemProperties.getInstance(); private Transaction trx; private Block block = null; @@ -73,7 +74,8 @@ public class Runtime { private String runtimeError; private boolean readyToExecute = false; - private CpuProcessor cpuProcessor = null; + private EnergyProcessor energyProcessor = null; + private StorageMarket storageMarket = null; PrecompiledContracts.PrecompiledContract precompiledContract = null; private ProgramResult result = new ProgramResult(); @@ -82,7 +84,7 @@ public class Runtime { private Program program = null; private InternalTransaction.TrxType trxType = TRX_UNKNOWN_TYPE; - private InternalTransaction.ExecuterType executerType = ET_UNKNOWN_TYPE; + private ExecutorType executorType = ET_UNKNOWN_TYPE; //tx trace private TransactionTrace trace; @@ -98,14 +100,15 @@ public Runtime(TransactionTrace trace, Block block, Deposit deosit, if (Objects.nonNull(block)) { this.block = block; - this.executerType = ET_NORMAL_TYPE; + this.executorType = ET_NORMAL_TYPE; } else { this.block = Block.newBuilder().build(); - this.executerType = ET_PRE_TYPE; + this.executorType = ET_PRE_TYPE; } this.deposit = deosit; this.programInvokeFactory = programInvokeFactory; - this.cpuProcessor = new CpuProcessor(deposit.getDbManager()); + this.energyProcessor = new EnergyProcessor(deposit.getDbManager()); + this.storageMarket = new StorageMarket(deposit.getDbManager()); Transaction.Contract.ContractType contractType = this.trx.getRawData().getContract(0).getType(); switch (contractType.getNumber()) { @@ -123,11 +126,12 @@ public Runtime(TransactionTrace trace, Block block, Deposit deosit, /** * For pre trx run */ + @Deprecated public Runtime(Transaction tx, DepositImpl deposit, ProgramInvokeFactory programInvokeFactory) { this.trx = tx; this.deposit = deposit; this.programInvokeFactory = programInvokeFactory; - this.executerType = ET_PRE_TYPE; + this.executorType = ET_PRE_TYPE; Transaction.Contract.ContractType contractType = tx.getRawData().getContract(0).getType(); switch (contractType.getNumber()) { case Transaction.Contract.ContractType.TriggerSmartContract_VALUE: @@ -145,16 +149,43 @@ public Runtime(Transaction tx, DepositImpl deposit, ProgramInvokeFactory program /** * For constant trx */ + @Deprecated public Runtime(Transaction tx, ProgramInvokeFactory programInvokeFactory, Deposit deposit) { trx = tx; this.deposit = deposit; this.programInvokeFactory = programInvokeFactory; - executerType = ET_CONSTANT_TYPE; + executorType = ET_CONSTANT_TYPE; trxType = TRX_CONTRACT_CALL_TYPE; } + /** + * For constant trx with latest block. + */ + public Runtime(Transaction tx, Block block, DepositImpl deposit, + ProgramInvokeFactory programInvokeFactory) { + this.trx = tx; + this.deposit = deposit; + this.programInvokeFactory = programInvokeFactory; + this.executorType = ET_PRE_TYPE; + this.block = block; + this.energyProcessor = new EnergyProcessor(deposit.getDbManager()); + this.storageMarket = new StorageMarket(deposit.getDbManager()); + Transaction.Contract.ContractType contractType = tx.getRawData().getContract(0).getType(); + switch (contractType.getNumber()) { + case Transaction.Contract.ContractType.TriggerSmartContract_VALUE: + trxType = TRX_CONTRACT_CALL_TYPE; + break; + case Transaction.Contract.ContractType.CreateSmartContract_VALUE: + trxType = TRX_CONTRACT_CREATION_TYPE; + break; + default: + trxType = TRX_PRECOMPILED_TYPE; + } + } + + public void precompiled() throws ContractValidateException, ContractExeException { TransactionCapsule trxCap = new TransactionCapsule(trx); final List actuatorList = ActuatorFactory @@ -169,20 +200,22 @@ public void precompiled() throws ContractValidateException, ContractExeException /** */ public void init() { - - switch (trxType) { - case TRX_PRECOMPILED_TYPE: - readyToExecute = true; - break; - case TRX_CONTRACT_CREATION_TYPE: - case TRX_CONTRACT_CALL_TYPE: - if (!curCPULimitReachedBlockCPULimit()) { - readyToExecute = true; - } - break; - default: - break; - } + readyToExecute = true; + // switch (trxType) { + // case TRX_PRECOMPILED_TYPE: + // readyToExecute = true; + // break; + // case TRX_CONTRACT_CREATION_TYPE: + // case TRX_CONTRACT_CALL_TYPE: + // // if (!curENERGYLimitReachedBlockENERGYLimit()) { + // // readyToExecute = true; + // // } + // readyToExecute = true; + // break; + // default: + // readyToExecute = true; + // break; + // } } @@ -191,7 +224,7 @@ public BigInteger getBlockCPULeftInUs() { // insure block is not null BigInteger curBlockHaveElapsedCPUInUs = BigInteger.valueOf( - 1000 * (DateTime.now().getMillis() - block.getBlockHeader().getRawDataOrBuilder() + 1000 * (DateTime.now().getMillis() - block.getBlockHeader().getRawData() .getTimestamp())); // us BigInteger curBlockCPULimitInUs = BigInteger.valueOf((long) (1000 * ChainConstant.BLOCK_PRODUCED_INTERVAL * 0.5 @@ -204,10 +237,10 @@ public BigInteger getBlockCPULeftInUs() { public boolean curCPULimitReachedBlockCPULimit() { - if (executerType == ET_NORMAL_TYPE) { + if (executorType == ET_NORMAL_TYPE) { BigInteger blockCPULeftInUs = getBlockCPULeftInUs(); BigInteger oneTxCPULimitInUs = BigInteger - .valueOf(Constant.CPU_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT); + .valueOf(Constant.MAX_CPU_TIME_OF_ONE_TX); // TODO get from account BigInteger increasedStorageLimit = BigInteger.valueOf(10000000); @@ -224,44 +257,6 @@ public boolean curCPULimitReachedBlockCPULimit() { return false; } - private long getAccountCPULimitInUs(AccountCapsule creator, - CreateSmartContract contract) { - - CpuProcessor cpuProcessor = new CpuProcessor(this.deposit.getDbManager()); - long cpuFromFrozen = cpuProcessor.calculateGlobalCpuLimit( - creator.getAccountResource().getFrozenBalanceForCpu().getFrozenBalance()); - logger.info("cpuFromFrozen: {}", cpuFromFrozen); - - long cpuFromTRX = Constant.CPU_IN_US_PER_TRX * contract.getCpuLimitInTrx(); - - return max(cpuFromFrozen, cpuFromTRX); // us - - } - - private long getAccountCPULimitInUs(AccountCapsule creator, AccountCapsule sender, - TriggerSmartContract contract) { - - CpuProcessor cpuProcessor = new CpuProcessor(this.deposit.getDbManager()); - SmartContract smartContract = this.deposit - .getContract(contract.getContractAddress().toByteArray()).getInstance(); - long consumeUserResourcePercent = smartContract.getConsumeUserResourcePercent(); - - long senderCpuFromTrx = Constant.CPU_IN_US_PER_TRX * contract.getCpuLimitInTrx(); - long senderCpuFromFrozen = cpuProcessor.calculateGlobalCpuLimit( - sender.getAccountResource().getFrozenBalanceForCpu().getFrozenBalance()); - long creatorCpuFromFrozen = cpuProcessor.calculateGlobalCpuLimit( - creator.getAccountResource().getFrozenBalanceForCpu().getFrozenBalance()); - long senderCpuMax = max(senderCpuFromTrx, senderCpuFromFrozen); - if (consumeUserResourcePercent >= 1.0) { - return senderCpuMax; - } else if (consumeUserResourcePercent <= 0.0) { - return creatorCpuFromFrozen; - } else { - return max(min(creatorCpuFromFrozen / (1 - consumeUserResourcePercent), - senderCpuMax / consumeUserResourcePercent), consumeUserResourcePercent); - } - } - public void execute() throws ContractValidateException, ContractExeException { if (!readyToExecute) { @@ -282,62 +277,77 @@ public void execute() throws ContractValidateException, ContractExeException { } } - private void call() - throws ContractExeException { - Contract.TriggerSmartContract contract = ContractCapsule.getTriggerContractFromTransaction(trx); - if (contract == null) { - return; + private long getEnergyLimit(AccountCapsule account, long feeLimit, long callValue) { + + long SUN_PER_ENERGY = deposit.getDbManager().getDynamicPropertiesStore().getEnergyFee() == 0 + ? Constant.SUN_PER_ENERGY : + deposit.getDbManager().getDynamicPropertiesStore().getEnergyFee(); + // can change the calc way + long leftEnergyFromFreeze = energyProcessor.getAccountLeftEnergyFromFreeze(account); + callValue = max(callValue, 0); + long energyFromBalance = Math + .floorDiv(max(account.getBalance() - callValue, 0), SUN_PER_ENERGY); + + long energyFromFeeLimit; + long totalBalanceForEnergyFreeze = account.getAccountResource().getFrozenBalanceForEnergy() + .getFrozenBalance(); + if (0 == totalBalanceForEnergyFreeze) { + energyFromFeeLimit = + feeLimit / SUN_PER_ENERGY; + } else { + long totalEnergyFromFreeze = energyProcessor + .calculateGlobalEnergyLimit(totalBalanceForEnergyFreeze); + long leftBalanceForEnergyFreeze = getEnergyFee(totalBalanceForEnergyFreeze, + leftEnergyFromFreeze, + totalEnergyFromFreeze); + + if (leftBalanceForEnergyFreeze >= feeLimit) { + energyFromFeeLimit = BigInteger.valueOf(totalEnergyFromFreeze) + .multiply(BigInteger.valueOf(feeLimit)) + .divide(BigInteger.valueOf(totalBalanceForEnergyFreeze)).longValue(); + } else { + energyFromFeeLimit = Math + .addExact(leftEnergyFromFreeze, + (feeLimit - leftBalanceForEnergyFreeze) / SUN_PER_ENERGY); + } } - byte[] contractAddress = contract.getContractAddress().toByteArray(); - byte[] code = this.deposit.getCode(contractAddress); - if (isEmpty(code)) { + return min(Math.addExact(leftEnergyFromFreeze, energyFromBalance), energyFromFeeLimit); + } - } else { + private long getEnergyLimit(AccountCapsule creator, AccountCapsule caller, + TriggerSmartContract contract, long feeLimit, long callValue) { - AccountCapsule sender = this.deposit.getAccount(contract.getOwnerAddress().toByteArray()); - AccountCapsule creator = this.deposit.getAccount( - this.deposit.getContract(contractAddress).getInstance() - .getOriginAddress().toByteArray()); + long callerEnergyLimit = getEnergyLimit(caller, feeLimit, callValue); + if (Arrays.equals(creator.getAddress().toByteArray(), caller.getAddress().toByteArray())) { + return callerEnergyLimit; + } - long thisTxCPULimitInUs; - long accountCPULimitInUs = getAccountCPULimitInUs(creator, sender, contract); - if (executerType == ET_NORMAL_TYPE) { - long blockCPULeftInUs = getBlockCPULeftInUs().longValue(); - thisTxCPULimitInUs = min(accountCPULimitInUs, blockCPULeftInUs, - Constant.CPU_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT); - } else { - thisTxCPULimitInUs = min(accountCPULimitInUs, - Constant.CPU_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT); - } + // creatorEnergyFromFreeze + long creatorEnergyLimit = energyProcessor.getAccountLeftEnergyFromFreeze(creator); - long vmStartInUs = System.nanoTime() / 1000; - long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs; + SmartContract smartContract = this.deposit + .getContract(contract.getContractAddress().toByteArray()).getInstance(); + long consumeUserResourcePercent = smartContract.getConsumeUserResourcePercent(); - ProgramInvoke programInvoke = programInvokeFactory - .createProgramInvoke(TRX_CONTRACT_CALL_TYPE, executerType, trx, - block, deposit, vmStartInUs, vmShouldEndInUs); - this.vm = new VM(config); - InternalTransaction internalTransaction = new InternalTransaction(trx); - this.program = new Program(null, code, programInvoke, internalTransaction, config); - } + consumeUserResourcePercent = max(0, min(consumeUserResourcePercent, 100)); - program.getResult().setContractAddress(contractAddress); - //transfer from callerAddress to targetAddress according to callValue - byte[] callerAddress = contract.getOwnerAddress().toByteArray(); - byte[] callValue = contract.getCallValue().toByteArray(); - if (null != callValue && callValue.length != 0) { - long callValueLong = new BigInteger(Hex.toHexString(callValue), 16).longValue(); - this.deposit.addBalance(callerAddress, -callValueLong); - this.deposit.addBalance(contractAddress, callValueLong); + if (consumeUserResourcePercent <= 0) { + return creatorEnergyLimit; } + if (creatorEnergyLimit * consumeUserResourcePercent + >= (100 - consumeUserResourcePercent) * callerEnergyLimit) { + return 100 * Math.floorDiv(callerEnergyLimit, consumeUserResourcePercent); + } else { + return Math.addExact(callerEnergyLimit, creatorEnergyLimit); + } } /* **/ private void create() - throws ContractExeException { + throws ContractExeException, ContractValidateException { CreateSmartContract contract = ContractCapsule.getSmartContractFromTransaction(trx); SmartContract newSmartContract = contract.getNewContract(); @@ -345,52 +355,58 @@ private void create() byte[] contractAddress = Wallet.generateContractAddress(trx); byte[] ownerAddress = contract.getOwnerAddress().toByteArray(); - // insure one owner just have one contract - if (this.deposit.getContractByNormalAccount(ownerAddress) != null) { - logger.error("Trying to create second contract with one account: address: " + Wallet - .encode58Check(ownerAddress)); - return; + long percent = contract.getNewContract().getConsumeUserResourcePercent(); + if (percent < 0 || percent > 100) { + throw new ContractExeException("percent must be >= 0 and <= 100"); } // insure the new contract address haven't exist if (deposit.getAccount(contractAddress) != null) { - logger.error("Trying to create a contract with existing contract address: " + Wallet - .encode58Check(contractAddress)); - return; + throw new ContractExeException( + "Trying to create a contract with existing contract address: " + Wallet + .encode58Check(contractAddress)); } newSmartContract = newSmartContract.toBuilder() .setContractAddress(ByteString.copyFrom(contractAddress)).build(); - + long callValue = newSmartContract.getCallValue(); // create vm to constructor smart contract try { AccountCapsule creator = this.deposit .getAccount(newSmartContract.getOriginAddress().toByteArray()); + // if (executorType == ET_NORMAL_TYPE) { + // long blockENERGYLeftInUs = getBlockENERGYLeftInUs().longValue(); + // thisTxENERGYLimitInUs = min(blockENERGYLeftInUs, + // Constant.ENERGY_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT); + // } else { + // thisTxENERGYLimitInUs = Constant.ENERGY_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT; + // } + long thisTxCPULimitInUs; - long accountCPULimitInUs = getAccountCPULimitInUs(creator, contract); - if (executerType == ET_NORMAL_TYPE) { - long blockCPULeftInUs = getBlockCPULeftInUs().longValue(); - thisTxCPULimitInUs = min(accountCPULimitInUs, blockCPULeftInUs, - Constant.CPU_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT); + if (ET_NORMAL_TYPE == executorType) { + thisTxCPULimitInUs = Constant.MAX_CPU_TIME_OF_ONE_TX_WHEN_VERIFY_BLOCK; } else { - thisTxCPULimitInUs = min(accountCPULimitInUs, - Constant.CPU_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT); + thisTxCPULimitInUs = Constant.MAX_CPU_TIME_OF_ONE_TX; } - long vmStartInUs = System.nanoTime() / 1000; long vmShouldEndInUs = vmStartInUs + thisTxCPULimitInUs; + long feeLimit = trx.getRawData().getFeeLimit(); + long energyLimit = getEnergyLimit(creator, feeLimit, callValue); byte[] ops = newSmartContract.getBytecode().toByteArray(); InternalTransaction internalTransaction = new InternalTransaction(trx); + ProgramInvoke programInvoke = programInvokeFactory - .createProgramInvoke(TRX_CONTRACT_CREATION_TYPE, executerType, trx, - block, deposit, vmStartInUs, vmShouldEndInUs); + .createProgramInvoke(TRX_CONTRACT_CREATION_TYPE, executorType, trx, + block, deposit, vmStartInUs, vmShouldEndInUs, energyLimit); this.vm = new VM(config); this.program = new Program(ops, programInvoke, internalTransaction, config); + Program.setRootTransactionId(new TransactionCapsule(trx).getTransactionId().getBytes()); + Program.resetNonce(); } catch (Exception e) { logger.error(e.getMessage()); - return; + throw new ContractExeException(e.getMessage()); } program.getResult().setContractAddress(contractAddress); @@ -400,21 +416,82 @@ private void create() deposit.createContract(contractAddress, new ContractCapsule(newSmartContract)); deposit.saveCode(contractAddress, ProgramPrecompile.getCode(code)); - deposit.createContractByNormalAccountIndex(ownerAddress, new BytesCapsule(contractAddress)); + // deposit.createContractByNormalAccountIndex(ownerAddress, new BytesCapsule(contractAddress)); // transfer from callerAddress to contractAddress according to callValue byte[] callerAddress = contract.getOwnerAddress().toByteArray(); - byte[] callValue = newSmartContract.getCallValue().toByteArray(); - if (null != callValue && callValue.length != 0) { - long callValueLong = new BigInteger(Hex.toHexString(callValue), 16).longValue(); - this.deposit.addBalance(callerAddress, -callValueLong); - this.deposit.addBalance(contractAddress, callValueLong); + if (callValue > 0) { + transfer(this.deposit, callerAddress, contractAddress, callValue); } } - public void go() { + /** + * ** + */ + + private void call() + throws ContractExeException, ContractValidateException { + Contract.TriggerSmartContract contract = ContractCapsule.getTriggerContractFromTransaction(trx); + if (contract == null) { + return; + } + + byte[] contractAddress = contract.getContractAddress().toByteArray(); + byte[] code = this.deposit.getCode(contractAddress); + long callValue = contract.getCallValue(); + if (isEmpty(code)) { + + } else { + AccountCapsule caller = this.deposit.getAccount(contract.getOwnerAddress().toByteArray()); + AccountCapsule creator = this.deposit.getAccount( + this.deposit.getContract(contractAddress).getInstance() + .getOriginAddress().toByteArray()); + + long thisTxENERGYLimitInUs; + if (ET_NORMAL_TYPE == executorType) { + thisTxENERGYLimitInUs = Constant.MAX_CPU_TIME_OF_ONE_TX_WHEN_VERIFY_BLOCK; + } else { + thisTxENERGYLimitInUs = Constant.MAX_CPU_TIME_OF_ONE_TX; + } + + long vmStartInUs = System.nanoTime() / 1000; + long vmShouldEndInUs = vmStartInUs + thisTxENERGYLimitInUs; + + long feeLimit = trx.getRawData().getFeeLimit(); + long energyLimit; + try { + energyLimit = getEnergyLimit(creator, caller, contract, feeLimit, callValue); + } catch (Exception e) { + logger.error(e.getMessage()); + throw new ContractExeException(e.getMessage()); + } + + if (isCallConstant(contractAddress)) { + energyLimit = Constant.MAX_ENERGY_IN_TX; + } + + ProgramInvoke programInvoke = programInvokeFactory + .createProgramInvoke(TRX_CONTRACT_CALL_TYPE, executorType, trx, + block, deposit, vmStartInUs, vmShouldEndInUs, energyLimit); + this.vm = new VM(config); + InternalTransaction internalTransaction = new InternalTransaction(trx); + this.program = new Program(null, code, programInvoke, internalTransaction, config); + Program.setRootTransactionId(new TransactionCapsule(trx).getTransactionId().getBytes()); + Program.resetNonce(); + } + + program.getResult().setContractAddress(contractAddress); + //transfer from callerAddress to targetAddress according to callValue + byte[] callerAddress = contract.getOwnerAddress().toByteArray(); + if (callValue > 0) { + transfer(this.deposit, callerAddress, contractAddress, callValue); + } + + } + + public void go() throws OutOfSlotTimeException { if (!readyToExecute) { return; } @@ -423,11 +500,17 @@ public void go() { if (vm != null) { vm.play(program); + program.getResult().setRet(result.getRet()); result = program.getResult(); if (isCallConstant()) { + long callValue = TransactionCapsule.getCallValue(trx.getRawData().getContract(0)); + if (callValue > 0) { + runtimeError = "constant cannot set call value."; + } return; } - spendUsage(true); + + // todo: consume bandwidth for successful creating contract if (result.getException() != null || result.isRevert()) { result.getDeleteAccounts().clear(); @@ -435,84 +518,39 @@ public void go() { result.resetFutureRefund(); if (result.getException() != null) { + program.spendAllEnergy(); + runtimeError = result.getException().getMessage(); throw result.getException(); } else { runtimeError = "REVERT opcode executed"; } } else { - - // touchedAccounts.addAll(result.getTouchedAccounts()); - // check storage useage - long useedStorageSize = - deposit.getBeforeRunStorageSize() - deposit.computeAfterRunStorageSize(); - if (useedStorageSize > 1000000) { - result.setException(Program.Exception.notEnoughStorage()); - throw result.getException(); - } - if (executerType == ET_NORMAL_TYPE) { - deposit.commit(); - } + deposit.commit(); } } else { - if (executerType == ET_NORMAL_TYPE) { - deposit.commit(); - } + deposit.commit(); } } catch (OutOfResourceException e) { logger.error(e.getMessage()); - runtimeError = e.getMessage(); - } catch (TronException e) { - spendUsage(false); + throw new OutOfSlotTimeException(e.getMessage()); + } catch (Throwable e) { + result.setException(new RuntimeException("Unknown Throwable")); logger.error(e.getMessage()); - runtimeError = e.getMessage(); + if (StringUtils.isEmpty(runtimeError)) { + runtimeError = e.getMessage(); + } } - //todo catch over resource exception -// catch (Exception e) { -// logger.error(e.getMessage()); -// runtimeError = e.getMessage() -// } - + trace.setBill(result.getEnergyUsed()); } - private void spendUsage(boolean spandStorage) { - cpuProcessor = new CpuProcessor(deposit.getDbManager()); - long cpuUsage, storageUsage; - storageUsage = 0; - long now = System.nanoTime() / 1000; - cpuUsage = now - program.getVmStartInUs(); - if (executerType == ET_NORMAL_TYPE) { - /* - * trx.getCpuRecipt - * - * */ + private long getEnergyFee(long callerEnergyUsage, long callerEnergyFrozen, + long callerEnergyTotal) { + if (callerEnergyTotal <= 0) { + return 0; } - ContractCapsule contract = deposit.getContract(result.getContractAddress()); - ByteString originAddress = contract.getInstance().getOriginAddress(); - AccountCapsule origin = deposit.getAccount(originAddress.toByteArray()); - - byte[] callerAddressBytes = TransactionCapsule.getOwner(trx.getRawData().getContract(0)); - AccountCapsule caller = deposit.getAccount(callerAddressBytes); - - spendCpuUsage(cpuUsage, origin, caller); - if (spandStorage) { - spendStorageUsage(storageUsage, origin, caller); - } - } - - private void spendCpuUsage(long cpuUsage, AccountCapsule origin, AccountCapsule caller) { - - this.cpuProcessor.useCpu(origin, cpuUsage * (100 - 36) / 100, - deposit.getDbManager().getHeadBlockTimeStamp()); - this.cpuProcessor - .useCpu(caller, cpuUsage * 36 / 100, deposit.getDbManager().getHeadBlockTimeStamp()); - - } - - private void spendStorageUsage(long storageUsage, AccountCapsule origin, AccountCapsule caller) { - - origin.setStorageUsage(storageUsage * (100 - 36) / 100); - caller.setStorageUsage(storageUsage * 36 / 100); + return BigInteger.valueOf(callerEnergyFrozen).multiply(BigInteger.valueOf(callerEnergyUsage)) + .divide(BigInteger.valueOf(callerEnergyTotal)).longValue(); } private boolean isCallConstant() { @@ -525,12 +563,38 @@ private boolean isCallConstant() { return false; } - public RuntimeSummary finalization() { - return null; + private boolean isCallConstant(byte[] address) { + if (TRX_CONTRACT_CALL_TYPE.equals(trxType)) { + ABI abi = deposit.getContract(address).getInstance().getAbi(); + if (Wallet.isConstant(abi, ContractCapsule.getTriggerContractFromTransaction(trx))) { + return true; + } + } + return false; + } + + public void finalization() { + if (config.vmTrace() && program != null && result != null) { + String trace = program.getTrace() + .result(result.getHReturn()) + .error(result.getException()) + .toString(); + + if (config.vmTraceCompressed()) { + trace = zipAndEncode(trace); + } + + String txHash = Hex.toHexString(new InternalTransaction(trx).getHash()); + saveProgramTraceFile(config, txHash, trace); + } + } public ProgramResult getResult() { return result; } + public String getRuntimeError() { + return runtimeError; + } } diff --git a/src/main/java/org/tron/common/runtime/config/SystemProperties.java b/src/main/java/org/tron/common/runtime/config/SystemProperties.java index 7bbff85a7b3..77ec2aaf28d 100644 --- a/src/main/java/org/tron/common/runtime/config/SystemProperties.java +++ b/src/main/java/org/tron/common/runtime/config/SystemProperties.java @@ -17,234 +17,43 @@ */ package org.tron.common.runtime.config; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigFactory; -import com.typesafe.config.ConfigRenderOptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Method; -import java.net.URL; -import java.util.*; - -//import org.ethereum.config.blockchain.OlympicConfig; -//import org.ethereum.config.net.*; +/** + * For developer only + */ public class SystemProperties { - private static Logger logger = LoggerFactory.getLogger("general"); - - private static SystemProperties CONFIG; - private static boolean useOnlySpringConfig = true; //false; - /** - * Returns the static config instance. If the config is passed - * as a Spring bean by the application this instance shouldn't - * be used - * This method is mainly used for testing purposes - * (Autowired fields are initialized with this static instance - * but when running within Spring context they replaced with the - * bean config instance) - */ - public static SystemProperties getDefault() { - return useOnlySpringConfig ? null : getSpringDefault(); - } - - static SystemProperties getSpringDefault() { - if (CONFIG == null) { - CONFIG = new SystemProperties(); - } - return CONFIG; - } - - /** - * Used mostly for testing purposes to ensure the application - * refers only to the config passed as a Spring bean. - * If this property is set to true {@link #getDefault()} returns null - */ - public static void setUseOnlySpringConfig(boolean useOnlySpringConfig) { - SystemProperties.useOnlySpringConfig = useOnlySpringConfig; - } - - static boolean isUseOnlySpringConfig() { - return useOnlySpringConfig; - } - - /** - * Marks config accessor methods which need to be called (for value validation) - * upon config creation or modification - */ - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - private @interface ValidateMe {}; - - - private Config config; - - private final ClassLoader classLoader; - - public SystemProperties() { - this(ConfigFactory.empty()); - } - - public SystemProperties(File configFile) { - this(ConfigFactory.parseFile(configFile)); - } - - public SystemProperties(String configResource) { - this(ConfigFactory.parseResources(configResource)); - } - - public SystemProperties(Config apiConfig) { - this(apiConfig, SystemProperties.class.getClassLoader()); - } - - public SystemProperties(Config apiConfig, ClassLoader classLoader) { - try { - this.classLoader = classLoader; - - Config javaSystemProperties = ConfigFactory.load("no-such-resource-only-system-props"); - Config referenceConfig = ConfigFactory.parseResources("ethereumj.conf"); - logger.info("Config (" + (referenceConfig.entrySet().size() > 0 ? " yes " : " no ") + "): default properties from resource 'ethereumj.conf'"); - String res = System.getProperty("ethereumj.conf.res"); - Config cmdLineConfigRes = res != null ? ConfigFactory.parseResources(res) : ConfigFactory.empty(); - logger.info("Config (" + (cmdLineConfigRes.entrySet().size() > 0 ? " yes " : " no ") + "): user properties from -Dethereumj.conf.res resource '" + res + "'"); - Config userConfig = ConfigFactory.parseResources("user.conf"); - logger.info("Config (" + (userConfig.entrySet().size() > 0 ? " yes " : " no ") + "): user properties from resource 'user.conf'"); - File userDirFile = new File(System.getProperty("user.dir"), "/config/ethereumj.conf"); - Config userDirConfig = ConfigFactory.parseFile(userDirFile); - logger.info("Config (" + (userDirConfig.entrySet().size() > 0 ? " yes " : " no ") + "): user properties from file '" + userDirFile + "'"); - Config testConfig = ConfigFactory.parseResources("test-ethereumj.conf"); - logger.info("Config (" + (testConfig.entrySet().size() > 0 ? " yes " : " no ") + "): test properties from resource 'test-ethereumj.conf'"); - Config testUserConfig = ConfigFactory.parseResources("test-user.conf"); - logger.info("Config (" + (testUserConfig.entrySet().size() > 0 ? " yes " : " no ") + "): test properties from resource 'test-user.conf'"); - String file = System.getProperty("ethereumj.conf.file"); - Config cmdLineConfigFile = file != null ? ConfigFactory.parseFile(new File(file)) : ConfigFactory.empty(); - logger.info("Config (" + (cmdLineConfigFile.entrySet().size() > 0 ? " yes " : " no ") + "): user properties from -Dethereumj.conf.file file '" + file + "'"); - logger.info("Config (" + (apiConfig.entrySet().size() > 0 ? " yes " : " no ") + "): config passed via constructor"); - config = apiConfig - .withFallback(cmdLineConfigFile) - .withFallback(testUserConfig) - .withFallback(testConfig) - .withFallback(userDirConfig) - .withFallback(userConfig) - .withFallback(cmdLineConfigRes) - .withFallback(referenceConfig); - - logger.debug("Config trace: " + config.root().render(ConfigRenderOptions.defaults(). - setComments(false).setJson(false))); - - config = javaSystemProperties.withFallback(config) - .resolve(); // substitute variables in config if any - validateConfig(); - - // There could be several files with the same name from other packages, - // "version.properties" is a very common name - List iStreams = loadResources("version.properties", this.getClass().getClassLoader()); - for (InputStream is : iStreams) { - Properties props = new Properties(); - props.load(is); - if (props.getProperty("versionNumber") == null || props.getProperty("databaseVersion") == null) { - continue; - } - break; - } - } catch (Exception e) { - logger.error("Can't read config.", e); - throw new RuntimeException(e); - } - } - /** - * Loads resources using given ClassLoader assuming, there could be several resources - * with the same name - */ - public static List loadResources( - final String name, final ClassLoader classLoader) throws IOException { - final List list = new ArrayList(); - final Enumeration systemResources = - (classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader) - .getResources(name); - while (systemResources.hasMoreElements()) { - list.add(systemResources.nextElement().openStream()); - } - return list; - } + private static Logger logger = LoggerFactory.getLogger("general"); - public Config getConfig() { - return config; - } + private boolean vmTraceCompressed = false; + private boolean vmOn = true; + private boolean vmTrace = false; - public boolean vmOn() { - return true; - } + private SystemProperties() { + } - public boolean vmTrace() { - return false; - } + private static class SystemPropertiesInstance { - /** - * Puts a new config atop of existing stack making the options - * in the supplied config overriding existing options - * Once put this config can't be removed - * - * @param overrideOptions - atop config - */ - public void overrideParams(Config overrideOptions) { - config = overrideOptions.withFallback(config); - validateConfig(); - } + private static final SystemProperties INSTANCE = new SystemProperties(); + } - /** - * Puts a new config atop of existing stack making the options - * in the supplied config overriding existing options - * Once put this config can't be removed - * - * @param keyValuePairs [name] [value] [name] [value] ... - */ - public void overrideParams(String ... keyValuePairs) { - if (keyValuePairs.length % 2 != 0) throw new RuntimeException("Odd argument number"); - Map map = new HashMap<>(); - for (int i = 0; i < keyValuePairs.length; i += 2) { - map.put(keyValuePairs[i], keyValuePairs[i + 1]); - } - overrideParams(map); - } + public static SystemProperties getInstance() { + return SystemPropertiesInstance.INSTANCE; + } - /** - * Puts a new config atop of existing stack making the options - * in the supplied config overriding existing options - * Once put this config can't be removed - * - * @param cliOptions - command line options to take presidency - */ - public void overrideParams(Map cliOptions) { - Config cliConf = ConfigFactory.parseMap(cliOptions); - overrideParams(cliConf); - } + public boolean vmOn() { + return vmOn; + } - private void validateConfig() { - for (Method method : getClass().getMethods()) { - try { - if (method.isAnnotationPresent(ValidateMe.class)) { - method.invoke(this); - } - } catch (Exception e) { - throw new RuntimeException("Error validating config method: " + method, e); - } - } - } + public boolean vmTrace() { + return vmTrace; + } - public T getProperty(String propName, T defaultValue) { - if (!config.hasPath(propName)) return defaultValue; - String string = config.getString(propName); - if (string.trim().isEmpty()) return defaultValue; - return (T) config.getAnyRef(propName); - } + public boolean vmTraceCompressed() { + return vmTraceCompressed; + } } diff --git a/src/main/java/org/tron/common/runtime/utils/MUtil.java b/src/main/java/org/tron/common/runtime/utils/MUtil.java index 56e19d54a86..b2675fbc3a2 100644 --- a/src/main/java/org/tron/common/runtime/utils/MUtil.java +++ b/src/main/java/org/tron/common/runtime/utils/MUtil.java @@ -5,16 +5,17 @@ import org.tron.common.crypto.Hash; import org.tron.common.storage.Deposit; import org.tron.core.Wallet; -import org.tron.core.exception.ContractExeException; +import org.tron.core.actuator.TransferActuator; +import org.tron.core.exception.ContractValidateException; -/** - * @author Guo Yonggang - * @since 02.05.2018 - */ public class MUtil { public static void transfer(Deposit deposit, byte[] fromAddress, byte[] toAddress, long amount) - throws ContractExeException { + throws ContractValidateException { + if (0 == amount) { + return; + } + TransferActuator.validateForSmartContract(deposit, fromAddress, toAddress, amount); if (deposit.getBalance(fromAddress) < amount) { throw new RuntimeException( Hex.toHexString(fromAddress).toUpperCase() + " not enough balance!"); @@ -26,8 +27,8 @@ public static void transfer(Deposit deposit, byte[] fromAddress, byte[] toAddres deposit.addBalance(fromAddress, -amount); } - public static void burn(Deposit deposit, byte[] address, long amount) - throws ContractExeException { + + public static void burn(Deposit deposit, byte[] address, long amount) { if (deposit.getBalance(address) < amount) { throw new RuntimeException("Not enough balance!"); } @@ -48,4 +49,18 @@ public static byte[] convertToTronAddress(byte[] address) { public static String get4BytesSha3HexString(String data) { return Hex.toHexString(Arrays.copyOf(Hash.sha3(data.getBytes()), 4)); } + + public static byte[] generateByteArray(byte[] ...parameters){ + int length =0; + for(int i=0;i topics = Lists.newArrayList(); + logInfo.getTopics().forEach(topic -> { + topics.add(ByteString.copyFrom(topic.getData())); + }); + ByteString address = ByteString.copyFrom(logInfo.getAddress()); + ByteString data = ByteString.copyFrom(logInfo.getData()); + return Log.newBuilder().setAddress(address).addAllTopics(topics).setData(data).build(); + } + } diff --git a/src/main/java/org/tron/common/runtime/vm/MessageCall.java b/src/main/java/org/tron/common/runtime/vm/MessageCall.java index 7655a4ef5d7..88a50c5fe97 100644 --- a/src/main/java/org/tron/common/runtime/vm/MessageCall.java +++ b/src/main/java/org/tron/common/runtime/vm/MessageCall.java @@ -29,9 +29,9 @@ public class MessageCall { private final OpCode type; /** - * gas to pay for the call, remaining gas will be refunded to the caller + * energy to pay for the call, remaining energy will be refunded to the caller */ - private final DataWord gas; + private final DataWord energy; /** * address of account which code to call */ @@ -57,20 +57,20 @@ public class MessageCall { */ private DataWord outDataSize; - public MessageCall(OpCode type, DataWord gas, DataWord codeAddress, + public MessageCall(OpCode type, DataWord energy, DataWord codeAddress, DataWord endowment, DataWord inDataOffs, DataWord inDataSize) { this.type = type; - this.gas = gas; + this.energy = energy; this.codeAddress = codeAddress; this.endowment = endowment; this.inDataOffs = inDataOffs; this.inDataSize = inDataSize; } - public MessageCall(OpCode type, DataWord gas, DataWord codeAddress, + public MessageCall(OpCode type, DataWord energy, DataWord codeAddress, DataWord endowment, DataWord inDataOffs, DataWord inDataSize, DataWord outDataOffs, DataWord outDataSize) { - this(type, gas, codeAddress, endowment, inDataOffs, inDataSize); + this(type, energy, codeAddress, endowment, inDataOffs, inDataSize); this.outDataOffs = outDataOffs; this.outDataSize = outDataSize; } @@ -79,8 +79,8 @@ public OpCode getType() { return type; } - public DataWord getGas() { - return gas; + public DataWord getEnergy() { + return energy; } public DataWord getCodeAddress() { diff --git a/src/main/java/org/tron/common/runtime/vm/PrecompiledContracts.java b/src/main/java/org/tron/common/runtime/vm/PrecompiledContracts.java index 27b843f63e1..6388fddfd9f 100644 --- a/src/main/java/org/tron/common/runtime/vm/PrecompiledContracts.java +++ b/src/main/java/org/tron/common/runtime/vm/PrecompiledContracts.java @@ -56,14 +56,12 @@ import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.protos.Contract; -import org.tron.protos.Contract.FreezeBalanceContract; import org.tron.protos.Contract.ProposalApproveContract; import org.tron.protos.Contract.ProposalCreateContract; import org.tron.protos.Contract.ProposalDeleteContract; -import org.tron.protos.Contract.UnfreezeBalanceContract; +import org.tron.protos.Contract.TransferAssetContract; import org.tron.protos.Contract.VoteWitnessContract; import org.tron.protos.Contract.WithdrawBalanceContract; -import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction.Contract.ContractType; /** @@ -91,6 +89,8 @@ public class PrecompiledContracts { private static final ProposalDeleteNative proposalDelete = new ProposalDeleteNative(); private static final ConvertFromTronBytesAddressNative convertFromTronBytesAddress = new ConvertFromTronBytesAddressNative(); private static final ConvertFromTronBase58AddressNative convertFromTronBase58Address = new ConvertFromTronBase58AddressNative(); + private static final TransferAssetNative transferAsset = new TransferAssetNative(); + private static final GetTransferAssetNative getTransferAssetAmount = new GetTransferAssetNative(); private static final DataWord ecRecoverAddr = new DataWord( @@ -127,6 +127,10 @@ public class PrecompiledContracts { "0000000000000000000000000000000000000000000000000000000000010008"); private static final DataWord convertFromTronBase58AddressAddr = new DataWord( "0000000000000000000000000000000000000000000000000000000000010009"); + private static final DataWord transferAssetAddr = new DataWord( + "000000000000000000000000000000000000000000000000000000000001000a"); + private static final DataWord getTransferAssetAmountAddr = new DataWord( + "000000000000000000000000000000000000000000000000000000000001000b"); public static PrecompiledContract getContractForAddress(DataWord address) { @@ -172,6 +176,12 @@ public static PrecompiledContract getContractForAddress(DataWord address) { if (address.equals(convertFromTronBase58AddressAddr)) { return convertFromTronBase58Address; } + if (address.equals(transferAssetAddr)) { + return transferAsset; + } + if (address.equals(getTransferAssetAmountAddr)) { + return getTransferAssetAmount; + } /* @@ -199,7 +209,7 @@ private static byte[] encodeRes(byte[] w1, byte[] w2) { public static abstract class PrecompiledContract { - public abstract long getGasForData(byte[] data); + public abstract long getEnergyForData(byte[] data); public abstract Pair execute(byte[] data); @@ -240,9 +250,9 @@ public Identity() { } @Override - public long getGasForData(byte[] data) { + public long getEnergyForData(byte[] data) { - // gas charge for the execution: + // energy charge for the execution: // minimum 1 and additional 1 for each 32 bytes word (round up) if (data == null) { return 15; @@ -260,9 +270,9 @@ public static class Sha256 extends PrecompiledContract { @Override - public long getGasForData(byte[] data) { + public long getEnergyForData(byte[] data) { - // gas charge for the execution: + // energy charge for the execution: // minimum 50 and additional 50 for each 32 bytes word (round up) if (data == null) { return 60; @@ -285,10 +295,10 @@ public static class Ripempd160 extends PrecompiledContract { @Override - public long getGasForData(byte[] data) { + public long getEnergyForData(byte[] data) { // TODO #POC9 Replace magic numbers with constants - // gas charge for the execution: + // energy charge for the execution: // minimum 50 and additional 50 for each 32 bytes word (round up) if (data == null) { return 600; @@ -313,7 +323,7 @@ public Pair execute(byte[] data) { public static class ECRecover extends PrecompiledContract { @Override - public long getGasForData(byte[] data) { + public long getEnergyForData(byte[] data) { return 3000; } @@ -375,7 +385,7 @@ public static class ModExp extends PrecompiledContract { private static final int ARGS_OFFSET = 32 * 3; // addresses length part @Override - public long getGasForData(byte[] data) { + public long getEnergyForData(byte[] data) { if (data == null) { data = EMPTY_BYTE_ARRAY; @@ -391,11 +401,12 @@ public long getGasForData(byte[] data) { long adjExpLen = getAdjustedExponentLength(expHighBytes, expLen); // use big numbers to stay safe in case of overflow - BigInteger gas = BigInteger.valueOf(multComplexity) + BigInteger energy = BigInteger.valueOf(multComplexity) .multiply(BigInteger.valueOf(Math.max(adjExpLen, 1))) .divide(GQUAD_DIVISOR); - return isLessThan(gas, BigInteger.valueOf(Long.MAX_VALUE)) ? gas.longValue() : Long.MAX_VALUE; + return isLessThan(energy, BigInteger.valueOf(Long.MAX_VALUE)) ? energy.longValue() + : Long.MAX_VALUE; } @Override @@ -488,7 +499,7 @@ private BigInteger parseArg(byte[] data, int offset, int len) { public static class BN128Addition extends PrecompiledContract { @Override - public long getGasForData(byte[] data) { + public long getEnergyForData(byte[] data) { return 500; } @@ -535,7 +546,7 @@ public Pair execute(byte[] data) { public static class BN128Multiplication extends PrecompiledContract { @Override - public long getGasForData(byte[] data) { + public long getEnergyForData(byte[] data) { return 40000; } @@ -581,7 +592,7 @@ public static class BN128Pairing extends PrecompiledContract { private static final int PAIR_SIZE = 192; @Override - public long getGasForData(byte[] data) { + public long getEnergyForData(byte[] data) { if (data == null) { return 100000; @@ -665,8 +676,8 @@ public static class VoteWitnessNative extends PrecompiledContract { @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -703,9 +714,11 @@ public Pair execute(byte[] data) { } catch (ContractExeException e) { logger.debug("ContractExeException when calling voteWitness in vm"); logger.debug("ContractExeException: {}", e.getMessage()); + return null; } catch (ContractValidateException e) { logger.debug("ContractValidateException when calling voteWitness in vm"); logger.debug("ContractValidateException: {}", e.getMessage()); + return null; } return Pair.of(true, new DataWord(count).getData()); } @@ -722,8 +735,8 @@ public static class FreezeBalanceNative extends PrecompiledContract { @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -733,40 +746,42 @@ public Pair execute(byte[] data) { data = EMPTY_BYTE_ARRAY; } - byte[] frozenBalance = new byte[32]; - System.arraycopy(data, 0, frozenBalance, 0, 32); - byte[] frozenDuration = new byte[32]; - System.arraycopy(data, 32, frozenDuration, 0, 32); - - if (getDeposit().getDbManager().getAccountStore().get(getCallerAddress()).getType() - == AccountType.Contract) { - logger.debug("caller can't be a contract"); - // TODO: or exception here. - return Pair.of(false, null); - } - - Contract.FreezeBalanceContract.Builder builder = Contract.FreezeBalanceContract.newBuilder(); - ByteString byteAddress = ByteString.copyFrom(getCallerAddress()); - builder.setOwnerAddress(byteAddress).setFrozenBalance(ByteArray.toLong(frozenBalance)) - .setFrozenDuration(ByteArray.toLong(frozenDuration)); - FreezeBalanceContract contract = builder.build(); - - TransactionCapsule trx = new TransactionCapsule(contract, ContractType.FreezeBalanceContract); - - final List actuatorList = ActuatorFactory - .createActuator(trx, getDeposit().getDbManager()); - try { - actuatorList.get(0).validate(); - actuatorList.get(0).execute(getResult().getRet()); - getDeposit() - .syncCacheFromAccountStore(ByteString.copyFrom(getCallerAddress()).toByteArray()); - } catch (ContractExeException e) { - logger.debug("ContractExeException when calling freezeBalance in vm"); - logger.debug("ContractExeException: {}", e.getMessage()); - } catch (ContractValidateException e) { - logger.debug("ContractValidateException when calling freezeBalance in vm"); - logger.debug("ContractValidateException: {}", e.getMessage()); - } +// byte[] frozenBalance = new byte[32]; +// System.arraycopy(data, 0, frozenBalance, 0, 32); +// byte[] frozenDuration = new byte[32]; +// System.arraycopy(data, 32, frozenDuration, 0, 32); +// +// if (getDeposit().getDbManager().getAccountStore().get(getCallerAddress()).getType() +// == AccountType.Contract) { +// logger.debug("caller can't be a contract"); +// // TODO: or exception here. +// return Pair.of(false, null); +// } +// +// Contract.FreezeBalanceContract.Builder builder = Contract.FreezeBalanceContract.newBuilder(); +// ByteString byteAddress = ByteString.copyFrom(getCallerAddress()); +// builder.setOwnerAddress(byteAddress).setFrozenBalance(ByteArray.toLong(frozenBalance)) +// .setFrozenDuration(ByteArray.toLong(frozenDuration)); +// FreezeBalanceContract contract = builder.build(); +// +// TransactionCapsule trx = new TransactionCapsule(contract, ContractType.FreezeBalanceContract); +// +// final List actuatorList = ActuatorFactory +// .createActuator(trx, getDeposit().getDbManager()); +// try { +// actuatorList.get(0).validate(); +// actuatorList.get(0).execute(getResult().getRet()); +// getDeposit() +// .syncCacheFromAccountStore(ByteString.copyFrom(getCallerAddress()).toByteArray()); +// } catch (ContractExeException e) { +// logger.debug("ContractExeException when calling freezeBalance in vm"); +// logger.debug("ContractExeException: {}", e.getMessage()); +// return null; +// } catch (ContractValidateException e) { +// logger.debug("ContractValidateException when calling freezeBalance in vm"); +// logger.debug("ContractValidateException: {}", e.getMessage()); +// return null; +// } return Pair.of(true, new DataWord(1).getData()); } } @@ -782,8 +797,8 @@ public static class UnfreezeBalanceNative extends PrecompiledContract { @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -793,30 +808,39 @@ public Pair execute(byte[] data) { data = EMPTY_BYTE_ARRAY; } - Contract.UnfreezeBalanceContract.Builder builder = Contract.UnfreezeBalanceContract - .newBuilder(); - ByteString byteAddress = ByteString.copyFrom(getCallerAddress()); - builder.setOwnerAddress(byteAddress); - UnfreezeBalanceContract contract = builder.build(); - - TransactionCapsule trx = new TransactionCapsule(contract, - ContractType.UnfreezeBalanceContract); - - final List actuatorList = ActuatorFactory - .createActuator(trx, getDeposit().getDbManager()); - try { - actuatorList.get(0).validate(); - actuatorList.get(0).execute(getResult().getRet()); - getDeposit() - .syncCacheFromAccountStore(ByteString.copyFrom(getCallerAddress()).toByteArray()); - getDeposit().syncCacheFromVotesStore(ByteString.copyFrom(getCallerAddress()).toByteArray()); - } catch (ContractExeException e) { - logger.debug("ContractExeException when calling unfreezeBalance in vm"); - logger.debug("ContractExeException: {}", e.getMessage()); - } catch (ContractValidateException e) { - logger.debug("ContractValidateException when calling unfreezeBalance in vm"); - logger.debug("ContractValidateException: {}", e.getMessage()); - } +// if (getDeposit().getDbManager().getAccountStore().get(getCallerAddress()).getType() +// == AccountType.Contract) { +// logger.debug("caller can't be a contract"); +// // TODO: or exception here. +// return Pair.of(false, null); +// } +// +// Contract.UnfreezeBalanceContract.Builder builder = Contract.UnfreezeBalanceContract +// .newBuilder(); +// ByteString byteAddress = ByteString.copyFrom(getCallerAddress()); +// builder.setOwnerAddress(byteAddress); +// UnfreezeBalanceContract contract = builder.build(); +// +// TransactionCapsule trx = new TransactionCapsule(contract, +// ContractType.UnfreezeBalanceContract); +// +// final List actuatorList = ActuatorFactory +// .createActuator(trx, getDeposit().getDbManager()); +// try { +// actuatorList.get(0).validate(); +// actuatorList.get(0).execute(getResult().getRet()); +// getDeposit() +// .syncCacheFromAccountStore(ByteString.copyFrom(getCallerAddress()).toByteArray()); +// getDeposit().syncCacheFromVotesStore(ByteString.copyFrom(getCallerAddress()).toByteArray()); +// } catch (ContractExeException e) { +// logger.debug("ContractExeException when calling unfreezeBalance in vm"); +// logger.debug("ContractExeException: {}", e.getMessage()); +// return null; +// } catch (ContractValidateException e) { +// logger.debug("ContractValidateException when calling unfreezeBalance in vm"); +// logger.debug("ContractValidateException: {}", e.getMessage()); +// return null; +// } return Pair.of(true, new DataWord(1).getData()); } } @@ -832,8 +856,8 @@ public static class WithdrawBalanceNative extends PrecompiledContract { @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -862,9 +886,11 @@ public Pair execute(byte[] data) { } catch (ContractExeException e) { logger.debug("ContractExeException when calling withdrawBalanceNative in vm"); logger.debug("ContractExeException: {}", e.getMessage()); + return null; } catch (ContractValidateException e) { logger.debug("ContractValidateException when calling withdrawBalanceNative in vm"); logger.debug("ContractValidateException: {}", e.getMessage()); + return null; } return Pair.of(true, new DataWord(1).getData()); } @@ -881,8 +907,8 @@ public static class ProposalApproveNative extends PrecompiledContract { @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -918,9 +944,11 @@ public Pair execute(byte[] data) { } catch (ContractExeException e) { logger.debug("ContractExeException when calling proposalApproveNative in vm"); logger.debug("ContractExeException: {}", e.getMessage()); + return null; } catch (ContractValidateException e) { logger.debug("ContractValidateException when calling proposalApproveNative in vm"); logger.debug("ContractValidateException: {}", e.getMessage()); + return null; } return Pair.of(true, new DataWord(1).getData()); } @@ -938,8 +966,8 @@ public static class ProposalCreateNative extends PrecompiledContract { @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -981,9 +1009,11 @@ public Pair execute(byte[] data) { } catch (ContractExeException e) { logger.debug("ContractExeException when calling proposalCreateNative in vm"); logger.debug("ContractExeException: {}", e.getMessage()); + return null; } catch (ContractValidateException e) { logger.debug("ContractValidateException when calling proposalCreateNative in vm"); logger.debug("ContractValidateException: {}", e.getMessage()); + return null; } return Pair.of(true, new DataWord(id).getData()); } @@ -1000,8 +1030,8 @@ public static class ProposalDeleteNative extends PrecompiledContract { @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -1028,9 +1058,11 @@ public Pair execute(byte[] data) { } catch (ContractExeException e) { logger.debug("ContractExeException when calling proposalDeleteContract in vm"); logger.debug("ContractExeException: {}", e.getMessage()); + return null; } catch (ContractValidateException e) { logger.debug("ContractValidateException when calling proposalDeleteContract in vm"); logger.debug("ContractValidateException: {}", e.getMessage()); + return null; } return Pair.of(true, new DataWord(1).getData()); } @@ -1048,8 +1080,8 @@ public static class ConvertFromTronBytesAddressNative extends PrecompiledContrac @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -1075,8 +1107,8 @@ public static class ConvertFromTronBase58AddressNative extends PrecompiledContra @Override // TODO: Please re-implement this function after Tron cost is well designed. - public long getGasForData(byte[] data) { - return 0; + public long getEnergyForData(byte[] data) { + return 200; } @Override @@ -1090,7 +1122,115 @@ public Pair execute(byte[] data) { byte[] resultBytes = Wallet.decodeFromBase58Check(addressBase58); String hexString = Hex.toHexString(resultBytes); - return Pair.of(true, new DataWord(hexString).getData()); + return Pair.of(true, new DataWord(new DataWord(hexString).getLast20Bytes()).getData()); + } + } + + /** + * Native function for transferring Asset to another account.
+ *
+ * + * Input data[]:
toAddress, amount, assetName
+ * + * Output:
transfer asset operation success or not
+ */ + public static class TransferAssetNative extends PrecompiledContract { + + @Override + public long getEnergyForData(byte[] data) { + return 200; + } + + @Override + public Pair execute(byte[] data) { + + if (data == null) { + data = EMPTY_BYTE_ARRAY; + } + + byte[] toAddress = new byte[32]; + System.arraycopy(data, 0, toAddress, 0, 32); + byte[] amount = new byte[32]; + System.arraycopy(data, 32 + 16 + 8, amount, 0, 8); + // we already have a restrict for token name length, no more than 32 bytes. don't need to check again + byte[] name = new byte[32]; + System.arraycopy(data, 64, name, 0, data.length-64); + int length =name.length; + while(length>0 && name[length -1] ==0){ + length--; + } + name = ByteArray.subArray(name,0,length); + Contract.TransferAssetContract.Builder builder = Contract.TransferAssetContract + .newBuilder(); + builder.setOwnerAddress(ByteString.copyFrom(getCallerAddress())); + builder.setToAddress(ByteString.copyFrom(convertToTronAddress(new DataWord(toAddress).getLast20Bytes()))); + builder.setAmount(Longs.fromByteArray(amount)); + builder.setAssetName(ByteString.copyFrom(name)); + + + TransferAssetContract contract = builder.build(); + + TransactionCapsule trx = new TransactionCapsule(contract, + ContractType.TransferAssetContract); + + final List actuatorList = ActuatorFactory + .createActuator(trx, getDeposit().getDbManager()); + try { + actuatorList.get(0).validate(); + actuatorList.get(0).execute(getResult().getRet()); + } catch (ContractExeException e) { + logger.debug("ContractExeException when calling transferAssetContract in vm"); + logger.debug("ContractExeException: {}", e.getMessage()); + return null; + } catch (ContractValidateException e) { + logger.debug("ContractValidateException when calling transferAssetContract in vm"); + logger.debug("ContractValidateException: {}", e.getMessage()); + return null; + } + return Pair.of(true, new DataWord(1).getData()); + } + } + + + + /** + * Native function for check Asset balance basing on targetAddress and Asset name.
+ *
+ * + * Input data[]:
address targetAddress, byte[] assetName
+ * + * Output:
balance
+ */ + public static class GetTransferAssetNative extends PrecompiledContract { + + @Override + public long getEnergyForData(byte[] data) { + return 200; + } + + @Override + public Pair execute(byte[] data) { + + if (data == null) { + data = EMPTY_BYTE_ARRAY; + } + + byte[] targetAddress = new byte[32]; + System.arraycopy(data, 0, targetAddress, 0, 32); + // we already have a restrict for token name length, no more than 32 bytes. don't need to check again + byte[] name = new byte[32]; + System.arraycopy(data, 32, name, 0, 32); + int length =name.length; + while(length>0 && name[length -1] ==0){ + length--; + } + name = ByteArray.subArray(name,0,length); + + long assetBalance = this.getDeposit().getDbManager().getAccountStore(). + get(convertToTronAddress(new DataWord(targetAddress).getLast20Bytes())). + getAssetMap().get(ByteArray.toStr(name)); + + return Pair.of(true, new DataWord(Longs.toByteArray(assetBalance)).getData()); } } } diff --git a/src/main/java/org/tron/common/runtime/vm/VM.java b/src/main/java/org/tron/common/runtime/vm/VM.java index 0cd5a56ffe8..48c09f6ad09 100644 --- a/src/main/java/org/tron/common/runtime/vm/VM.java +++ b/src/main/java/org/tron/common/runtime/vm/VM.java @@ -1,6 +1,7 @@ package org.tron.common.runtime.vm; import static org.tron.common.crypto.Hash.sha3; +import static org.tron.common.runtime.utils.MUtil.convertToTronAddress; import static org.tron.common.runtime.vm.OpCode.CALL; import static org.tron.common.runtime.vm.OpCode.PUSH1; import static org.tron.common.runtime.vm.OpCode.REVERT; @@ -9,22 +10,22 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.spongycastle.util.encoders.Hex; import org.springframework.beans.factory.annotation.Autowired; import org.tron.common.runtime.config.SystemProperties; import org.tron.common.runtime.vm.program.Program; -import org.tron.common.runtime.vm.program.Program.OutOfResourceException; +import org.tron.common.runtime.vm.program.Program.OutOfEnergyException; import org.tron.common.runtime.vm.program.Stack; -import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; + +@Slf4j(topic = "VM") public class VM { - private static final Logger logger = LoggerFactory.getLogger("TronVM"); - private static final Logger dumpLogger = LoggerFactory.getLogger("dump"); + // private static final Logger logger = LoggerFactory.getLogger("TronVM"); private static BigInteger _32_ = BigInteger.valueOf(32); - private static final String logString = "{} Op: [{}] Gas: [{}] Deep: [{}] Hint: [{}]"; + private static final String logString = "{} Op: [{}] Energy: [{}] Deep: [{}] Hint: [{}]"; // max mem size which couldn't be paid for ever // used to reduce expensive BigInt arithmetic @@ -42,7 +43,7 @@ public class VM { private final SystemProperties config; public VM() { - this(SystemProperties.getDefault()); + config = SystemProperties.getInstance(); } @Autowired @@ -53,23 +54,25 @@ public VM(SystemProperties config) { } private void checkMemorySize(OpCode op, BigInteger newMemSize) { + // todo: add TVMruntime error if (newMemSize.compareTo(MEM_LIMIT) > 0) { throw Program.Exception.memoryOverflow(op); } } - private long calcMemDrop(DropCost dropCosts, long oldMemSize, BigInteger newMemSize, + private long calcMemEnergy(EnergyCost energyCosts, long oldMemSize, BigInteger newMemSize, long copySize) { - long dropConsume = 0; + //todo: simpfy this calc, just use energy relative to energy time + + long energyCost = 0; // Avoid overflows if (newMemSize.compareTo(MAX_MEM_SIZE) > 0) { -// throw VMMemoryOverflowException(); - - throw Program.Exception.gasOverflow(newMemSize, MAX_MEM_SIZE); -// -// throw Program.Exception.memoryOverflow() + // throw VMMemoryOverflowException(); + throw Program.Exception.energyOverflow(newMemSize, MAX_MEM_SIZE); + // todo: add memory overflow + // throw Program.Exception.memoryOverflow(); } // memory drop consume calc @@ -78,21 +81,21 @@ private long calcMemDrop(DropCost dropCosts, long oldMemSize, BigInteger newMemS long memWords = (memoryUsage / 32); long memWordsOld = (oldMemSize / 32); //TODO #POC9 c_quadCoeffDiv = 512, this should be a constant, not magic number - long memDrop = (dropCosts.getMEMORY() * memWords + memWords * memWords / 512) - - (dropCosts.getMEMORY() * memWordsOld + memWordsOld * memWordsOld / 512); - dropConsume += memDrop; + long memEnergy = (energyCosts.getMEMORY() * memWords + memWords * memWords / 512) + - (energyCosts.getMEMORY() * memWordsOld + memWordsOld * memWordsOld / 512); + energyCost += memEnergy; } if (copySize > 0) { - long copyDrop = dropCosts.getCOPY_GAS() * ((copySize + 31) / 32); - dropConsume += copyDrop; + long copyEnergy = energyCosts.getCOPY_ENERGY() * ((copySize + 31) / 32); + energyCost += copyEnergy; } - return dropConsume; + return energyCost; } public void step(Program program) - throws ContractExeException, OutOfResourceException { - if (vmTrace) { + throws ContractValidateException { + if (config.vmTrace()) { program.saveOpTrace(); } @@ -132,84 +135,93 @@ public void step(Program program) Stack stack = program.getStack(); String hint = ""; - long callGas = 0, memWords = 0; // parameters for logging - long dropCost = op.getTier().asInt(); - long dropBefore = program.getDroplimitLong(); - int stepBefore = program.getPC(); - DropCost dropCosts = DropCost.getInstance(); - DataWord adjustedCallGas = null; - - // Calculate fees and spend drops + long callEnergy = 0, memWords = 0; // parameters for logging + long energyCost = op.getTier().asInt(); + EnergyCost energyCosts = EnergyCost.getInstance(); + DataWord adjustedCallEnergy = null; + + // Calculate fees and spend energy switch (op) { case STOP: - dropCost = dropCosts.getSTOP(); + energyCost = energyCosts.getSTOP(); break; case SUICIDE: - dropCost = dropCosts.getSUICIDE(); + energyCost = energyCosts.getSUICIDE(); + DataWord suicideAddressWord = stack.get(stack.size() - 1); + if (isDeadAccount(program, suicideAddressWord) && + !program.getBalance(program.getOwnerAddress()).isZero()) { + energyCost += energyCosts.getNEW_ACCT_SUICIDE(); + } break; case SSTORE: + // todo: check the reset to 0, refund or not DataWord newValue = stack.get(stack.size() - 2); DataWord oldValue = program.storageLoad(stack.peek()); if (oldValue == null && !newValue.isZero()) { - dropCost = dropCosts.getSET_SSTORE(); + // set a new not-zero value + energyCost = energyCosts.getSET_SSTORE(); } else if (oldValue != null && newValue.isZero()) { - // todo: GASREFUND counter policy - - // refund step cost policy. - program.futureRefundGas(dropCosts.getREFUND_SSTORE()); - dropCost = dropCosts.getCLEAR_SSTORE(); + // set zero to an old value + program.futureRefundEnergy(energyCosts.getREFUND_SSTORE()); + energyCost = energyCosts.getCLEAR_SSTORE(); } else { - dropCost = dropCosts.getRESET_SSTORE(); + // include: + // [1] oldValue == null && newValue == 0 + // [2] oldValue != null && newValue != 0 + energyCost = energyCosts.getRESET_SSTORE(); } break; case SLOAD: - dropCost = dropCosts.getSLOAD(); + energyCost = energyCosts.getSLOAD(); break; case BALANCE: - dropCost = dropCosts.getBALANCE(); + energyCost = energyCosts.getBALANCE(); break; // These all operate on memory and therefore potentially expand it: case MSTORE: - dropCost += calcMemDrop(dropCosts, oldMemSize, memNeeded(stack.peek(), new DataWord(32)), + energyCost = calcMemEnergy(energyCosts, oldMemSize, + memNeeded(stack.peek(), new DataWord(32)), 0); break; case MSTORE8: - dropCost += calcMemDrop(dropCosts, oldMemSize, memNeeded(stack.peek(), new DataWord(1)), + energyCost = calcMemEnergy(energyCosts, oldMemSize, + memNeeded(stack.peek(), new DataWord(1)), 0); break; case MLOAD: - dropCost += calcMemDrop(dropCosts, oldMemSize, memNeeded(stack.peek(), new DataWord(32)), + energyCost = calcMemEnergy(energyCosts, oldMemSize, + memNeeded(stack.peek(), new DataWord(32)), 0); break; case RETURN: case REVERT: - dropCost = dropCosts.getSTOP() + calcMemDrop(dropCosts, oldMemSize, + energyCost = energyCosts.getSTOP() + calcMemEnergy(energyCosts, oldMemSize, memNeeded(stack.peek(), stack.get(stack.size() - 2)), 0); break; case SHA3: - dropCost = dropCosts.getSHA3() + calcMemDrop(dropCosts, oldMemSize, + energyCost = energyCosts.getSHA3() + calcMemEnergy(energyCosts, oldMemSize, memNeeded(stack.peek(), stack.get(stack.size() - 2)), 0); DataWord size = stack.get(stack.size() - 2); long chunkUsed = (size.longValueSafe() + 31) / 32; - dropCost += chunkUsed * dropCosts.getSHA3_WORD(); + energyCost += chunkUsed * energyCosts.getSHA3_WORD(); break; case CALLDATACOPY: case RETURNDATACOPY: - dropCost += calcMemDrop(dropCosts, oldMemSize, + energyCost = calcMemEnergy(energyCosts, oldMemSize, memNeeded(stack.peek(), stack.get(stack.size() - 3)), stack.get(stack.size() - 3).longValueSafe()); break; case CODECOPY: - dropCost += calcMemDrop(dropCosts, oldMemSize, + energyCost = calcMemEnergy(energyCosts, oldMemSize, memNeeded(stack.peek(), stack.get(stack.size() - 3)), stack.get(stack.size() - 3).longValueSafe()); break; case EXTCODESIZE: - dropCost = dropCosts.getEXT_CODE_SIZE(); + energyCost = energyCosts.getEXT_CODE_SIZE(); break; case EXTCODECOPY: - dropCost = dropCosts.getEXT_CODE_COPY() + calcMemDrop(dropCosts, oldMemSize, + energyCost = energyCosts.getEXT_CODE_COPY() + calcMemEnergy(energyCosts, oldMemSize, memNeeded(stack.get(stack.size() - 2), stack.get(stack.size() - 4)), stack.get(stack.size() - 4).longValueSafe()); break; @@ -217,23 +229,24 @@ public void step(Program program) case CALLCODE: case DELEGATECALL: case STATICCALL: - - dropCost = dropCosts.getCALL(); - DataWord callGasWord = stack.get(stack.size() - 1); - + // here, contract call an other contract, or a library, and so on + // todo: check the callvalue here + energyCost = energyCosts.getCALL(); + DataWord callEnergyWord = stack.get(stack.size() - 1); DataWord callAddressWord = stack.get(stack.size() - 2); - DataWord value = op.callHasValue() ? stack.get(stack.size() - 3) : DataWord.ZERO; //check to see if account does not exist and is not a precompiled contract if (op == CALL) { - dropCost = dropCosts.getNEW_ACCT_CALL(); + if (isDeadAccount(program, callAddressWord) && !value.isZero()) { + energyCost += energyCosts.getNEW_ACCT_CALL(); + } } - //TODO #POC9 Make sure this is converted to BigInteger (256num support) + // TODO #POC9 Make sure this is converted to BigInteger (256num support) if (!value.isZero()) { - dropCost += dropCosts.getVT_CALL(); + energyCost += energyCosts.getVT_CALL(); } int opOff = op.callHasValue() ? 4 : 3; @@ -241,24 +254,23 @@ public void step(Program program) stack.get(stack.size() - opOff - 1)); // in offset+size BigInteger out = memNeeded(stack.get(stack.size() - opOff - 2), stack.get(stack.size() - opOff - 3)); // out offset+size - // dropCost += calcMemDrop(dropCosts, oldMemSize, in.max(out), 0); + energyCost += calcMemEnergy(energyCosts, oldMemSize, in.max(out), 0); checkMemorySize(op, in.max(out)); - //TODO: recover this or give similar logic when tron cost mechanism is ready. -// if (dropCost > program.getDroplimit().longValueSafe()) { -// throw Program.Exception.notEnoughOpGas(op, callGasWord, program.getDroplimit()); -// } - - DataWord gasLeft = program.getDroplimit().clone(); - gasLeft.sub(new DataWord(dropCost)); - //adjustedCallGas = tronConfig.getCallGas(op, callGasWord, gasLeft); - //adjustedCallGas = new DataWord(tronConfig.getDropCost().getCALL()); - //TODO: remove below and recover above statment when config is ready - adjustedCallGas = new DataWord(); - dropCost += adjustedCallGas.longValueSafe(); + if (energyCost > program.getEnergyLimitLeft().longValueSafe()) { + throw new OutOfEnergyException( + "Not enough energy for '%s' operation executing: opEnergy[%d], programEnergy[%d]", + op.name(), + energyCost, program.getEnergyLimitLeft().longValueSafe()); + } + DataWord getEnergyLimitLeft = program.getEnergyLimitLeft().clone(); + getEnergyLimitLeft.sub(new DataWord(energyCost)); + + adjustedCallEnergy = program.getCallEnergy(op, callEnergyWord, getEnergyLimitLeft); + energyCost += adjustedCallEnergy.longValueSafe(); break; case CREATE: - dropCost = dropCosts.getCREATE() + calcMemDrop(dropCosts, oldMemSize, + energyCost = energyCosts.getCREATE() + calcMemEnergy(energyCosts, oldMemSize, memNeeded(stack.get(stack.size() - 2), stack.get(stack.size() - 3)), 0); break; case LOG0: @@ -266,39 +278,39 @@ public void step(Program program) case LOG2: case LOG3: case LOG4: - int nTopics = op.val() - OpCode.LOG0.val(); - BigInteger dataSize = stack.get(stack.size() - 2).value(); BigInteger dataCost = dataSize - .multiply(BigInteger.valueOf(dropCosts.getLOG_DATA_GAS())); -// if (program.getDroplimit().value().compareTo(dataCost) < 0) { -// throw Program.Exception.notEnoughOpGas(op, dataCost, program.getDroplimit().value()); -// } - - dropCost = dropCosts.getLOG_GAS() + - dropCosts.getLOG_TOPIC_GAS() * nTopics + - dropCosts.getLOG_DATA_GAS() * stack.get(stack.size() - 2).longValue() + - calcMemDrop(dropCosts, oldMemSize, - memNeeded(stack.peek(), stack.get(stack.size() - 2)), 0); - checkMemorySize(op, - memNeeded(stack.peek(), stack.get(stack.size() - 2))); + .multiply(BigInteger.valueOf(energyCosts.getLOG_DATA_ENERGY())); + if (program.getEnergyLimitLeft().value().compareTo(dataCost) < 0) { + throw new OutOfEnergyException( + "Not enough energy for '%s' operation executing: opEnergy[%d], programEnergy[%d]", + op.name(), + dataCost.longValue(), program.getEnergyLimitLeft().longValueSafe()); + } + energyCost = energyCosts.getLOG_ENERGY() + + energyCosts.getLOG_TOPIC_ENERGY() * nTopics + + energyCosts.getLOG_DATA_ENERGY() * stack.get(stack.size() - 2).longValue() + + calcMemEnergy(energyCosts, oldMemSize, + memNeeded(stack.peek(), stack.get(stack.size() - 2)), + 0); + + checkMemorySize(op, memNeeded(stack.peek(), stack.get(stack.size() - 2))); break; case EXP: DataWord exp = stack.get(stack.size() - 2); int bytesOccupied = exp.bytesOccupied(); - dropCost = dropCosts.getEXP_GAS() + dropCosts.getEXP_BYTE_GAS() * bytesOccupied; + energyCost = + energyCosts.getEXP_ENERGY() + energyCosts.getEXP_BYTE_ENERGY() * bytesOccupied; break; default: break; } - // DEBUG System.out.println(" OP IS " + op.name() + " GASCOST IS " + gasCost + " NUM IS " + op.asInt()); - // program.spendDrop(dropCost, op.name()); - - //TODO: recover this after it is ready. - // program.checkCPULimit(op.name()); + // DEBUG System.out.println(" OP IS " + op.name() + " ENERGYCOST IS " + energyCost + " NUM IS " + op.asInt()); + program.spendEnergy(energyCost, op.name()); + program.checkCPUTimeLimit(op.name()); // logger.info("after opName: {}, {}", op.name(), System.nanoTime() / 1000 - lastTime); // Execute operation @@ -848,13 +860,13 @@ public void step(Program program) } break; case GASPRICE: { - DataWord gasPrice = new DataWord(0); + DataWord energyPrice = new DataWord(0); if (logger.isInfoEnabled()) { - hint = "price: " + gasPrice.toString(); + hint = "price: " + energyPrice.toString(); } - program.stackPush(gasPrice); + program.stackPush(energyPrice); program.step(); } break; @@ -921,13 +933,14 @@ public void step(Program program) } break; case GASLIMIT: { - DataWord droplimit = new DataWord(0); + // todo: this energylimit is the block's energy limit + DataWord energyLimit = new DataWord(0); if (logger.isInfoEnabled()) { - hint = "gaslimit: " + droplimit; + hint = "energylimit: " + energyLimit; } - program.stackPush(droplimit); + program.stackPush(energyLimit); program.step(); } break; @@ -1137,13 +1150,12 @@ public void step(Program program) } break; case GAS: { - DataWord gas = new DataWord(0); - + DataWord energy = program.getEnergyLimitLeft(); if (logger.isInfoEnabled()) { - hint = "" + gas; + hint = "" + energy; } - program.stackPush(gas); + program.stackPush(energy); program.step(); } break; @@ -1221,8 +1233,10 @@ public void step(Program program) case CALLCODE: case DELEGATECALL: case STATICCALL: { - program.stackPop(); // use adjustedCallGas instead of requested + program.stackPop(); // use adjustedCallEnergy instead of requested DataWord codeAddress = program.stackPop(); + + // todo: check the callvalue >= 0 DataWord value = op.callHasValue() ? program.stackPop() : DataWord.ZERO; @@ -1231,7 +1245,7 @@ public void step(Program program) } if (!value.isZero()) { - adjustedCallGas.add(new DataWord(dropCosts.getSTIPEND_CALL())); + adjustedCallEnergy.add(new DataWord(energyCosts.getSTIPEND_CALL())); } DataWord inDataOffs = program.stackPop(); @@ -1242,19 +1256,19 @@ public void step(Program program) if (logger.isInfoEnabled()) { hint = "addr: " + Hex.toHexString(codeAddress.getLast20Bytes()) - + " gas: " + adjustedCallGas.shortHex() + + " energy: " + adjustedCallEnergy.shortHex() + " inOff: " + inDataOffs.shortHex() + " inSize: " + inDataSize.shortHex(); logger.info(logString, String.format("%5s", "[" + program.getPC() + "]"), String.format("%-12s", op.name()), - program.getDroplimit().value(), + program.getEnergyLimitLeft().value(), program.getCallDeep(), hint); } program.memoryExpand(outDataOffs, outDataSize); MessageCall msg = new MessageCall( - op, adjustedCallGas, codeAddress, value, inDataOffs, inDataSize, + op, adjustedCallEnergy, codeAddress, value, inDataOffs, inDataSize, outDataOffs, outDataSize); PrecompiledContracts.PrecompiledContract contract = @@ -1325,8 +1339,8 @@ public void step(Program program) */ vmCounter++; } catch (RuntimeException e) { - logger.warn("VM halted: [{}]", e); - program.spendAllGas(); + logger.warn("VM halted: [{}]", e.getMessage()); + program.spendAllEnergy(); program.resetFutureRefund(); program.stop(); throw e; @@ -1335,8 +1349,7 @@ public void step(Program program) } } - public void play(Program program) - throws ContractExeException { + public void play(Program program) { try { if (program.byTestingSuite()) { return; @@ -1348,6 +1361,8 @@ public void play(Program program) } catch (RuntimeException e) { program.setRuntimeFailure(e); + } catch (ContractValidateException e) { + program.setRuntimeFailure(new RuntimeException(e.getMessage())); } catch (StackOverflowError soe) { logger .error("\n !!! StackOverflowError: update your java run command with -Xss2M !!!\n", soe); @@ -1357,6 +1372,10 @@ public void play(Program program) } } + private boolean isDeadAccount(Program program, DataWord address) { + return program.getContractState().getAccount(convertToTronAddress(address.getLast20Bytes())) + == null; + } /** * Utility to calculate new total memory size needed for an operation.
Basically just offset diff --git a/src/main/java/org/tron/common/runtime/vm/program/ContractState.java b/src/main/java/org/tron/common/runtime/vm/program/ContractState.java new file mode 100644 index 00000000000..24b964fca45 --- /dev/null +++ b/src/main/java/org/tron/common/runtime/vm/program/ContractState.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ +package org.tron.common.runtime.vm.program; + +import org.tron.common.runtime.vm.DataWord; +import org.tron.common.runtime.vm.program.invoke.ProgramInvoke; +import org.tron.common.runtime.vm.program.listener.ProgramListener; +import org.tron.common.runtime.vm.program.listener.ProgramListenerAware; +import org.tron.common.storage.Deposit; +import org.tron.common.storage.Key; +import org.tron.common.storage.Value; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.capsule.ContractCapsule; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.db.Manager; +import org.tron.protos.Protocol; +import org.tron.protos.Protocol.AccountType; + +public class ContractState implements Deposit, ProgramListenerAware { + + private Deposit deposit; + private final DataWord address; // contract address + private ProgramListener programListener; + + public ContractState(ProgramInvoke programInvoke) { + this.address = programInvoke.getOwnerAddress(); // contract address + this.deposit = programInvoke.getDeposit(); + } + + @Override + public Manager getDbManager() { + return deposit.getDbManager(); + } + + @Override + public void setProgramListener(ProgramListener listener) { + this.programListener = listener; + } + + @Override + public AccountCapsule createAccount(byte[] addr, Protocol.AccountType type) { + return deposit.createAccount(addr, type); + } + + @Override + public AccountCapsule createAccount(byte[] address, String accountName, AccountType type) { + return deposit.createAccount(address, accountName, type); + } + + + @Override + public AccountCapsule getAccount(byte[] addr) { + return deposit.getAccount(addr); + } + + @Override + public void createContract(byte[] codeHash, ContractCapsule contractCapsule) { + deposit.createContract(codeHash, contractCapsule); + } + + @Override + public ContractCapsule getContract(byte[] codeHash) { + return deposit.getContract(codeHash); + } + + @Override + public void saveCode(byte[] addr, byte[] code) { + deposit.saveCode(addr, code); + } + + @Override + public byte[] getCode(byte[] addr) { + return deposit.getCode(addr); + } + + /* + @Override + public byte[] getCodeHash(byte[] addr) { + return deposit.getCodeHash(addr); + } + */ + + @Override + public void putStorageValue(byte[] addr, DataWord key, DataWord value) { + if (canListenTrace(addr)) { + programListener.onStoragePut(key, value); + } + deposit.putStorageValue(addr, key, value); + } + + private boolean canListenTrace(byte[] address) { + return (programListener != null) && this.address.equals(new DataWord(address)); + } + + @Override + public DataWord getStorageValue(byte[] addr, DataWord key) { + return deposit.getStorageValue(addr, key); + } + + @Override + public long getBalance(byte[] addr) { + return deposit.getBalance(addr); + } + + @Override + public long addBalance(byte[] addr, long value) { + return deposit.addBalance(addr, value); + } + + @Override + public Deposit newDepositChild() { + return deposit.newDepositChild(); + } + + @Override + public Deposit newDepositNext() { + return deposit.newDepositNext(); + } + + @Override + public void flush() { + deposit.flush(); + } + + @Override + public void commit() { + deposit.commit(); + } + +// @Override +// public StorageCapsule getContractState(byte[] address) { +// return deposit.getContractState(address); +// } + + @Override + public Storage getStorage(byte[] address) { + return deposit.getStorage(address); + } + + @Override + public void putAccount(Key key, Value value) { + deposit.putAccount(key, value); + } + + @Override + public void putTransaction(Key key, Value value) { + deposit.putTransaction(key, value); + } + + @Override + public void putBlock(Key key, Value value) { + deposit.putBlock(key, value); + } + + @Override + public void putWitness(Key key, Value value) { + deposit.putWitness(key, value); + } + + @Override + public void putCode(Key key, Value value) { + deposit.putCode(key, value); + } + + @Override + public void putContract(Key key, Value value) { + deposit.putContract(key, value); + } + + @Override + public void putStorage(Key key, Storage cache) { + deposit.putStorage(key, cache); + } + + @Override + public void putVotes(Key key, Value value) { + deposit.putVotes(key, value); + } + + @Override + public void setParent(Deposit deposit) { + this.deposit.setParent(deposit); + } + + @Override + public void setPrevDeposit(Deposit deposit) { + this.deposit.setPrevDeposit(deposit); + } + + @Override + public void setNextDeposit(Deposit deposit) { + this.deposit.setNextDeposit(deposit); + } + + @Override + public TransactionCapsule getTransaction(byte[] trxHash) { + return this.deposit.getTransaction(trxHash); + } + + @Override + // Do nothing + public void syncCacheFromAccountStore(byte[] address) { + } + + @Override + // Do nothing + public void syncCacheFromVotesStore(byte[] address) { + } + + @Override + public BlockCapsule getBlock(byte[] blockHash) { + return this.deposit.getBlock(blockHash); + } + + @Override + public long computeAfterRunStorageSize() { + return this.deposit.computeAfterRunStorageSize(); + } + + @Override + public long getBeforeRunStorageSize() { + return this.deposit.getBeforeRunStorageSize(); + } +} diff --git a/src/main/java/org/tron/common/runtime/vm/program/InternalTransaction.java b/src/main/java/org/tron/common/runtime/vm/program/InternalTransaction.java index 2264270ac85..05b0a79f157 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/InternalTransaction.java +++ b/src/main/java/org/tron/common/runtime/vm/program/InternalTransaction.java @@ -21,22 +21,43 @@ import static org.apache.commons.lang3.ArrayUtils.nullToEmpty; import static org.tron.common.utils.ByteUtil.toHexString; +import com.google.common.primitives.Longs; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.Arrays; import org.tron.common.crypto.ECKey; +import org.tron.common.crypto.ECKey.ECDSASignature; +import org.tron.common.crypto.Hash; import org.tron.common.runtime.vm.DataWord; import org.tron.common.utils.ByteUtil; +import org.tron.core.capsule.TransactionCapsule; import org.tron.protos.Protocol.Transaction; -//import org.tron.common.utils.RLP; - -public class InternalTransaction extends VMTransaction { +public class InternalTransaction { + private Transaction transaction; + private byte[] hash; private byte[] parentHash; + /* the amount of trx to transfer (calculated as sun) */ + private long value; + + /* the address of the destination account + * In creation transaction the receive address is - 0 */ + private byte[] receiveAddress; + + /* An unlimited size byte array specifying + * input [data] of the message call or + * Initialization code for a new contract */ + private byte[] data; + + protected byte[] sendAddress; private int deep; private int index; private boolean rejected = false; private String note; + private boolean parsed; + private byte[] protoEncoded; + public enum TrxType { TRX_PRECOMPILED_TYPE, @@ -45,38 +66,47 @@ public enum TrxType { TRX_UNKNOWN_TYPE, } - ; - - public enum ExecuterType { + public enum ExecutorType { ET_PRE_TYPE, ET_NORMAL_TYPE, ET_CONSTANT_TYPE, ET_UNKNOWN_TYPE, } - public InternalTransaction(byte[] rawData) { - super(rawData); - } - public InternalTransaction(Transaction tx) { - super(tx); + /** + * Construct an un-encoded InternalTransaction + */ + public InternalTransaction(Transaction trx) { + this.transaction = trx; + this.protoEncoded = new TransactionCapsule(trx).getData(); + this.parsed = false; } + /** + * Construct an encoded InternalTransaction + */ + public InternalTransaction(byte[] parentHash, int deep, int index, byte[] sendAddress, byte[] receiveAddress, long value, byte[] data, String note) { - super(receiveAddress, value, nullToEmpty(data)); - this.parentHash = parentHash; this.deep = deep; this.index = index; - this.sendAddress = nullToEmpty(sendAddress); this.note = note; + this.sendAddress = nullToEmpty(sendAddress); + this.receiveAddress = nullToEmpty(receiveAddress); + this.value = value; + this.data = nullToEmpty(data); this.parsed = true; } - private static byte[] getData(DataWord gasPrice) { - return (gasPrice == null) ? ByteUtil.EMPTY_BYTE_ARRAY : gasPrice.getData(); + public Transaction getTransaction() { + return transaction; + } + + public void setTransaction(Transaction transaction) { + this.transaction = transaction; } public void reject() { @@ -104,7 +134,6 @@ public String getNote() { return note; } - @Override public byte[] getSender() { protoParse(); return sendAddress; @@ -115,87 +144,67 @@ public byte[] getParentHash() { return parentHash; } -// @Override -// public byte[] getEncoded() { -// if (protoEncoded == null) { -// /* -// this.protoEncoded = RLP.encodeList( -// RLP.encodeElement(isEmptyNonce ? null : nonce), -// RLP.encodeElement(this.parentHash), -// RLP.encodeElement(getSender()), -// RLP.encodeElement(getReceiveAddress()), -// RLP.encodeElement(getValue()), -// RLP.encodeElement(getGasPrice()), -// RLP.encodeElement(getGasLimit()), -// RLP.encodeElement(getData()), -// RLP.encodeString(this.note), -// encodeInt(this.deep), -// encodeInt(this.index), -// encodeInt(this.rejected ? 1 : 0) -// ); -// */ -// } -// -// return protoEncoded; -// } + public long getValue() { + protoParse(); + return value; + } - @Override - public byte[] getEncodedRaw() { - return getEncoded(); - } - -// @Override -// public synchronized void protoParse() { -// if (parsed) return; -// /* -// RLPList decodedTxList = RLP.decode2(rlpEncoded); -// RLPList transaction = (RLPList) decodedTxList.get(0); -// -// this.parentHash = transaction.get(1).getRLPData(); -// this.sendAddress = transaction.get(2).getRLPData(); -// setReceiveAddress(transaction.get(3).getRLPData()); -// setValue(transaction.get(4).getRLPData()); -// setGasPrice(transaction.get(5).getRLPData()); -// setGasLimit(transaction.get(6).getRLPData()); -// setData(transaction.get(7).getRLPData()); -// this.note = new String(transaction.get(8).getRLPData()); -// this.deep = decodeInt(transaction.get(9).getRLPData()); -// this.index = decodeInt(transaction.get(10).getRLPData()); -// this.rejected = decodeInt(transaction.get(11).getRLPData()) == 1; -// */ -// this.parsed = true; -// } - - - private static byte[] intToBytes(int value) { - return ByteBuffer.allocate(Integer.SIZE / Byte.SIZE) - .order(ByteOrder.LITTLE_ENDIAN) - .putInt(value) - .array(); - } - - private static int bytesToInt(byte[] bytes) { - return isEmpty(bytes) ? 0 : ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); - } - - /* - private static byte[] encodeInt(int value) { - return RLP.encodeElement(intToBytes(value)); - } - */ + public byte[] getData() { + protoParse(); + return data.clone(); + } - private static int decodeInt(byte[] encoded) { - return bytesToInt(encoded); + protected void setValue(long value) { + this.value = value; + parsed = true; } - @Override - public ECKey getKey() { - throw new UnsupportedOperationException("Cannot sign internal transaction."); + public byte[] getReceiveAddress() { + protoParse(); + return receiveAddress.clone(); } - @Override - public void sign(byte[] privKeyBytes) throws ECKey.MissingPrivateKeyException { - throw new UnsupportedOperationException("Cannot sign internal transaction."); + private void protoParse() { + if (parsed) { + return; + } + try { + this.hash = Hash.sha3(protoEncoded); + this.parsed = true; + } catch (Exception e) { + throw new RuntimeException("Error on parsing proto", e); + } + } + + public byte[] getHash() { + if (!isEmpty(hash)) { + return Arrays.copyOf(hash, hash.length); + } + + protoParse(); + byte[] plainMsg = this.getEncoded(); + return Hash.sha3(plainMsg); + } + + + public byte[] getEncoded() { + + if (protoEncoded != null) { + if (null == this.hash) { + this.hash = Hash.sha3(protoEncoded); + } + return protoEncoded.clone(); + } + + byte[] valueByte = Longs.toByteArray(this.value); + byte[] raw = new byte[this.receiveAddress.length + this.data.length + valueByte.length]; + System.arraycopy(this.receiveAddress, 0, raw, 0, this.receiveAddress.length); + System.arraycopy(this.data, 0, raw, this.receiveAddress.length, this.data.length); + System.arraycopy(valueByte, 0, raw, this.data.length, valueByte.length); + this.protoEncoded = raw; + this.hash = Hash.sha3(protoEncoded); + + return protoEncoded.clone(); } @Override diff --git a/src/main/java/org/tron/common/runtime/vm/program/Memory.java b/src/main/java/org/tron/common/runtime/vm/program/Memory.java index 21c880c48e0..486be28ec09 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/Memory.java +++ b/src/main/java/org/tron/common/runtime/vm/program/Memory.java @@ -121,8 +121,7 @@ public void extend(int address, int size) { return; } - final int newSize = address + size; - + final int newSize = Math.addExact(address,size); int toAllocate = newSize - internalSize(); if (toAllocate > 0) { addChunks((int) ceil((double) toAllocate / CHUNK_SIZE)); @@ -131,7 +130,7 @@ public void extend(int address, int size) { toAllocate = newSize - softSize; if (toAllocate > 0) { toAllocate = (int) ceil((double) toAllocate / WORD_SIZE) * WORD_SIZE; - softSize += toAllocate; + softSize = Math.addExact(softSize , toAllocate ); if (programListener != null) { programListener.onMemoryExtend(toAllocate); diff --git a/src/main/java/org/tron/common/runtime/vm/program/Program.java b/src/main/java/org/tron/common/runtime/vm/program/Program.java index 3952ea41946..7fb128a50be 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/Program.java +++ b/src/main/java/org/tron/common/runtime/vm/program/Program.java @@ -29,6 +29,7 @@ import static org.tron.common.utils.BIUtil.isPositive; import static org.tron.common.utils.BIUtil.toBI; +import com.google.protobuf.ByteString; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.util.Arrays; @@ -37,16 +38,13 @@ import java.util.Map; import java.util.NavigableSet; import java.util.TreeSet; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; -import org.tron.common.crypto.ECKey; -import org.tron.common.runtime.config.DefaultConfig; import org.tron.common.runtime.config.SystemProperties; import org.tron.common.runtime.vm.DataWord; -import org.tron.common.runtime.vm.DropCost; import org.tron.common.runtime.vm.MessageCall; import org.tron.common.runtime.vm.OpCode; import org.tron.common.runtime.vm.PrecompiledContracts; @@ -65,23 +63,50 @@ import org.tron.common.utils.FastByteComparisons; import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.core.actuator.TransferActuator; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; -import org.tron.core.exception.ContractExeException; +import org.tron.core.capsule.ContractCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.exception.ContractValidateException; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.SmartContract; /** * @author Roman Mandeleil * @since 01.06.2014 */ + +@Slf4j(topic = "Program") + public class Program { - private static final Logger logger = LoggerFactory.getLogger("VM"); + // private static final Logger logger = LoggerFactory.getLogger("VM"); private static final int MAX_DEPTH = 1024; //Max size for stack checks private static final int MAX_STACKSIZE = 1024; + public static byte[] getRootTransactionId() { + return rootTransactionId.clone(); + } + + public static void setRootTransactionId(byte[] rootTransactionId) { + Program.rootTransactionId = rootTransactionId.clone(); + } + + public static long getNonce() { + return nonce; + } + + public static void setNonce(long nonceValue) { + nonce = nonceValue; + } + + private static long nonce = 0; + private static byte[] rootTransactionId = null; + private InternalTransaction transaction; private ProgramInvoke invoke; @@ -94,7 +119,7 @@ public class Program { private Stack stack; private Memory memory; - private Storage storage; + private ContractState contractState; private byte[] returnDataBuffer; private ProgramResult result = new ProgramResult(); @@ -112,12 +137,14 @@ public class Program { private final SystemProperties config; + //private byte[] transactionHash; + public Program(byte[] ops, ProgramInvoke programInvoke) { this(ops, programInvoke, null); } public Program(byte[] ops, ProgramInvoke programInvoke, InternalTransaction transaction) { - this(ops, programInvoke, transaction, SystemProperties.getDefault()); + this(ops, programInvoke, transaction, SystemProperties.getInstance()); } public Program(byte[] ops, ProgramInvoke programInvoke, InternalTransaction transaction, @@ -134,11 +161,13 @@ public Program(byte[] codeHash, byte[] ops, ProgramInvoke programInvoke, //this.codeHash = codeHash; this.ops = nullToEmpty(ops); - //traceListener = new ProgramTraceListener(config.vmTrace()); + traceListener = new ProgramTraceListener(config.vmTrace()); this.memory = setupProgramListener(new Memory()); this.stack = setupProgramListener(new Stack()); - this.storage = setupProgramListener(new Storage(programInvoke)); - //this.trace = new ProgramTrace(config, programInvoke); + this.contractState = setupProgramListener(new ContractState(programInvoke)); + this.trace = new ProgramTrace(config, programInvoke); + + //this.transactionHash = transaction.getHash(); } public ProgramPrecompile getProgramPrecompile() { @@ -166,15 +195,16 @@ public int getCallDeep() { return invoke.getCallDeep(); } - private InternalTransaction addInternalTx(DataWord dropLimit, byte[] senderAddress, + private InternalTransaction addInternalTx(DataWord energyLimit, byte[] senderAddress, byte[] receiveAddress, long value, byte[] data, String note) { + // todo: now, internal transaction needn't energylimit InternalTransaction result = null; if (transaction != null) { //data = config.recordInternalTransactionsData() ? data : null; //result = getResult().addInternalTransaction(transaction.getHash(), getCallDeep(), - // getGasPrice(), gasLimit, senderAddress, receiveAddress, value.toByteArray(), data, note); + // getEnergyPrice(), energyLimit, senderAddress, receiveAddress, value.toByteArray(), data, note); result = getResult().addInternalTransaction(transaction.getHash(), getCallDeep(), senderAddress, receiveAddress, value, data, note); } @@ -184,7 +214,7 @@ private InternalTransaction addInternalTx(DataWord dropLimit, byte[] senderAddre private T setupProgramListener(T programListenerAware) { if (programListener.isEmpty()) { - //programListener.addListener(traceListener); + programListener.addListener(traceListener); programListener.addListener(storageDiffListener); } @@ -376,11 +406,11 @@ public void allocateMemory(int offset, int size) { public void suicide(DataWord obtainerAddress) - throws ContractExeException { + throws ContractValidateException { byte[] owner = convertToTronAddress(getOwnerAddress().getLast20Bytes()); byte[] obtainer = convertToTronAddress(obtainerAddress.getLast20Bytes()); - long balance = getStorage().getBalance(owner); + long balance = getContractState().getBalance(owner); if (logger.isInfoEnabled()) { logger.info("Transfer to: [{}] heritage: [{}]", @@ -392,21 +422,20 @@ public void suicide(DataWord obtainerAddress) if (FastByteComparisons.compareTo(owner, 0, 20, obtainer, 0, 20) == 0) { // if owner == obtainer just zeroing account according to Yellow Paper - getStorage().addBalance(owner, -balance); + getContractState().addBalance(owner, -balance); } else { - transfer(getStorage(), owner, obtainer, balance); + transfer(getContractState(), owner, obtainer, balance); } - getResult().addDeleteAccount(this.getOwnerAddress()); } - public Deposit getStorage() { - return this.storage; + public Deposit getContractState() { + return this.contractState; } @SuppressWarnings("ThrowableResultOfMethodCallIgnored") public void createContract(DataWord value, DataWord memStart, DataWord memSize) - throws ContractExeException { + throws ContractValidateException { returnDataBuffer = null; // reset return buffer right before the call if (getCallDeep() == MAX_DEPTH) { @@ -415,9 +444,11 @@ public void createContract(DataWord value, DataWord memStart, DataWord memSize) } byte[] senderAddress = convertToTronAddress(this.getOwnerAddress().getLast20Bytes()); + // todo: need check the value > 0? long endowment = value.value().longValue(); - if (getStorage().getBalance(senderAddress) < endowment) { + if (getContractState().getBalance(senderAddress) < endowment) { stackPushZero(); + // todo: need inform to outside? return; } @@ -429,19 +460,18 @@ public void createContract(DataWord value, DataWord memStart, DataWord memSize) Hex.toHexString(senderAddress)); } - //BlockchainConfig blockchainConfig = config.getBlockchainConfig().getConfigForBlock(getNumber().longValue()); - // actual gas subtract - //DataWord gasLimit = blockchainConfig.getCreateGas(getGas()); - //spendGas(gasLimit.longValue(), "internal call"); - DataWord gasLimit = new DataWord(DropCost.getInstance().getCREATE()); - // [2] CREATE THE CONTRACT ADDRESS // byte[] newAddress = HashUtil.calcNewAddr(getOwnerAddress().getLast20Bytes() nonce); - byte[] privKey = Sha256Hash.hash(getOwnerAddress().getData()); - ECKey ecKey = ECKey.fromPrivate(privKey); - byte[] newAddress = ecKey.getAddress(); + // todo: modify this contract generate way + +// byte[] privKey = Sha256Hash.hash(getOwnerAddress().getData()); +// ECKey ecKey = ECKey.fromPrivate(privKey); + this.increaseNonce(); + //this.transactionHash = Sha256Hash.hash(transactionHash); + byte[] newAddress = Wallet + .generateContractAddress(rootTransactionId,nonce); - AccountCapsule existingAddr = getStorage().getAccount(newAddress); + AccountCapsule existingAddr = getContractState().getAccount(newAddress); //boolean contractAlreadyExists = existingAddr != null && existingAddr.isContractExist(blockchainConfig); boolean contractAlreadyExists = existingAddr != null; @@ -449,40 +479,50 @@ public void createContract(DataWord value, DataWord memStart, DataWord memSize) if (byTestingSuite()) { // This keeps track of the contracts created for a test getResult().addCallCreate(programCode, EMPTY_BYTE_ARRAY, - gasLimit.getNoLeadZeroesData(), + energyLimit.getNoLeadZeroesData(), value.getNoLeadZeroesData()); } */ - Deposit deposit = getStorage(); + Deposit deposit = getContractState(); //In case of hashing collisions, check for any balance before createAccount() long oldBalance = deposit.getBalance(newAddress); - deposit.createAccount(newAddress, Protocol.AccountType.Contract); - deposit.addBalance(newAddress, oldBalance); + SmartContract newSmartContract = SmartContract.newBuilder() + .setContractAddress(ByteString.copyFrom(newAddress)).setConsumeUserResourcePercent(100) + .setOriginAddress(ByteString.copyFrom(senderAddress)).build(); + deposit.createContract(newAddress, new ContractCapsule(newSmartContract)); + deposit.createAccount(newAddress, "CreatedByContract", + Protocol.AccountType.Contract); + deposit.addBalance(newAddress, oldBalance); // [4] TRANSFER THE BALANCE long newBalance = 0L; - if (!byTestingSuite()) { + if (!byTestingSuite() && endowment > 0) { + TransferActuator.validateForSmartContract(deposit, senderAddress, newAddress, endowment); deposit.addBalance(senderAddress, -endowment); newBalance = deposit.addBalance(newAddress, endowment); } - checkCPULimit("BEFORE CREATE"); + // BlockchainConfig blockchainConfig = config.getBlockchainConfig().getConfigForBlock(getNumber().longValue()); + // actual energy subtract + DataWord energyLimit = this.getCreateEnergy(getEnergyLimitLeft()); + spendEnergy(energyLimit.longValue(), "internal call"); // [5] COOK THE INVOKE AND EXECUTE - InternalTransaction internalTx = addInternalTx(getDroplimit(), senderAddress, null, endowment, + InternalTransaction internalTx = addInternalTx(null, senderAddress, null, endowment, programCode, "create"); long vmStartInUs = System.nanoTime() / 1000; ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke( this, new DataWord(newAddress), getOwnerAddress(), value, newBalance, null, deposit, false, byTestingSuite(), vmStartInUs, - getVmShouldEndInUs()); + getVmShouldEndInUs(), energyLimit.longValueSafe()); ProgramResult result = ProgramResult.createEmpty(); if (contractAlreadyExists) { + // todo: this exception must lead to rollback this function modification at least result.setException(new BytecodeExecutionException( "Trying to create a contract with existing contract address: 0x" + Hex .toHexString(newAddress))); @@ -492,23 +532,26 @@ this, new DataWord(newAddress), getOwnerAddress(), value, vm.play(program); result = program.getResult(); + getTrace().merge(program.getTrace()); getResult().merge(result); } - checkCPULimit("AFTER CREATE"); // 4. CREATE THE CONTRACT OUT OF RETURN byte[] code = result.getHReturn(); - //long storageCost = getLength(code) * getBlockchainConfig().getGasCost().getCREATE_DATA(); - long storageCost = getLength(code) * DropCost.getInstance().getCREATE_DATA(); - // todo storage cost? - // long afterSpend = programInvoke.getDroplimit().longValue() - storageCost - result.getDropUsed(); - if (getLength(code) > DefaultConfig.getMaxCodeLength()) { - result.setException(Exception - .notEnoughSpendingGas("Contract size too large: " + getLength(result.getHReturn()), - storageCost, this)); - } else if (!result.isRevert()) { - result.spendDrop(storageCost); + //long storageCost = getLength(code) * getBlockchainConfig().getenergyCost().getCREATE_DATA(); + // todo: delete this energy, because this is not relative to the cpu time, but need add to storage cost + // long storageCost = getLength(code) * EnergyCost.getInstance().getCREATE_DATA(); + // // long afterSpend = programInvoke.getDroplimit().longValue() - storageCost - result.getDropUsed(); + // if (getLength(code) > DefaultConfig.getMaxCodeLength()) { + // result.setException(Exception + // .notEnoughSpendingEnergy("Contract size too large: " + getLength(result.getHReturn()), + // storageCost, this)); + // } else if (!result.isRevert()) { + // result.spendDrop(storageCost); + // deposit.saveCode(newAddress, code); + // } + if (!result.isRevert()) { deposit.saveCode(newAddress, code); } @@ -524,6 +567,7 @@ this, new DataWord(newAddress), getOwnerAddress(), value, stackPushZero(); if (result.getException() != null) { + refundEnergyAfterVM(energyLimit, result); return; } else { returnDataBuffer = result.getHReturn(); @@ -537,14 +581,19 @@ this, new DataWord(newAddress), getOwnerAddress(), value, stackPush(new DataWord(newAddress)); } - // 5. REFUND THE REMAIN GAS - long refundGas = gasLimit.longValue() - result.getDropUsed(); - if (refundGas > 0) { - refundGas(refundGas, "remain gas from the internal call"); + // 5. REFUND THE REMAIN Energy + refundEnergyAfterVM(energyLimit, result); + } + + public void refundEnergyAfterVM(DataWord energyLimit, ProgramResult result) { + + long refundEnergy = energyLimit.longValueSafe() - result.getEnergyUsed(); + if (refundEnergy > 0) { + refundEnergy(refundEnergy, "remain energy from the internal call"); if (logger.isInfoEnabled()) { - logger.info("The remaining gas is refunded, account: [{}], gas: [{}] ", + logger.info("The remaining energy is refunded, account: [{}], energy: [{}] ", Hex.toHexString(convertToTronAddress(getOwnerAddress().getLast20Bytes())), - refundGas); + refundEnergy); } } } @@ -558,12 +607,12 @@ this, new DataWord(newAddress), getOwnerAddress(), value, * @param msg is the message call object */ public void callToAddress(MessageCall msg) - throws ContractExeException, OutOfResourceException { + throws ContractValidateException { returnDataBuffer = null; // reset return buffer right before the call if (getCallDeep() == MAX_DEPTH) { stackPushZero(); - refundGas(msg.getGas().longValue(), " call deep limit reach"); + refundEnergy(msg.getEnergy().longValue(), " call deep limit reach"); return; } @@ -581,41 +630,42 @@ public void callToAddress(MessageCall msg) msg.getOutDataSize().longValue()); } - //Repository track = getStorage().startTracking(); - Deposit deposit = getStorage().newDepositChild(); + //Repository track = getContractState().startTracking(); + Deposit deposit = getContractState().newDepositChild(); // 2.1 PERFORM THE VALUE (endowment) PART + // todo: need to check value >= 0? long endowment = msg.getEndowment().value().longValue(); long senderBalance = deposit.getBalance(senderAddress); if (senderBalance < endowment) { stackPushZero(); - refundGas(msg.getGas().longValue(), "refund gas from message call"); + refundEnergy(msg.getEnergy().longValue(), "refund energy from message call"); return; } // FETCH THE CODE - AccountCapsule accountCapsule = getStorage().getAccount(codeAddress); + AccountCapsule accountCapsule = getContractState().getAccount(codeAddress); byte[] programCode = - accountCapsule != null ? getStorage().getCode(codeAddress) : EMPTY_BYTE_ARRAY; + accountCapsule != null ? getContractState().getCode(codeAddress) : EMPTY_BYTE_ARRAY; long contextBalance = 0L; if (byTestingSuite()) { // This keeps track of the calls created for a test getResult().addCallCreate(data, contextAddress, - msg.getGas().getNoLeadZeroesData(), + msg.getEnergy().getNoLeadZeroesData(), msg.getEndowment().getNoLeadZeroesData()); - } else { + } else if (!ArrayUtils.isEmpty(senderAddress) && !ArrayUtils.isEmpty(contextAddress) + && senderAddress != contextAddress && endowment > 0) { + TransferActuator.validateForSmartContract(deposit, senderAddress, contextAddress, endowment); deposit.addBalance(senderAddress, -endowment); contextBalance = deposit.addBalance(contextAddress, endowment); } // CREATE CALL INTERNAL TRANSACTION - InternalTransaction internalTx = addInternalTx(getDroplimit(), senderAddress, contextAddress, + InternalTransaction internalTx = addInternalTx(null, senderAddress, contextAddress, endowment, data, "call"); - checkCPULimit("BEFORE CALL"); - ProgramResult result = null; if (isNotEmpty(programCode)) { long vmStartInUs = System.nanoTime() / 1000; @@ -624,7 +674,7 @@ this, new DataWord(contextAddress), msg.getType().callIsDelegate() ? getCallerAddress() : getOwnerAddress(), msg.getType().callIsDelegate() ? getCallValue() : msg.getEndowment(), contextBalance, data, deposit, msg.getType().callIsStatic() || isStaticCall(), - byTestingSuite(), vmStartInUs, getVmShouldEndInUs()); + byTestingSuite(), vmStartInUs, getVmShouldEndInUs(), msg.getEnergy().longValueSafe()); VM vm = new VM(config); Program program = new Program(null, programCode, programInvoke, internalTx, config); @@ -646,6 +696,7 @@ this, new DataWord(contextAddress), stackPushZero(); if (result.getException() != null) { + refundEnergyAfterVM(msg.getEnergy(), result); return; } } else { @@ -656,15 +707,15 @@ this, new DataWord(contextAddress), if (byTestingSuite()) { logger.info("Testing run, skipping storage diff listener"); - } else if (Arrays.equals(transaction.getReceiveAddress(), internalTx.getReceiveAddress())) { - storageDiffListener.merge(program.getStorageDiff()); } +// else if (Arrays.equals(transaction.getReceiveAddress(), internalTx.getReceiveAddress())) { +// storageDiffListener.merge(program.getStorageDiff()); +// } } else { // 4. THE FLAG OF SUCCESS IS ONE PUSHED INTO THE STACK deposit.commit(); stackPushOne(); } - checkCPULimit("AFTER CALL"); // 3. APPLY RESULTS: result.getHReturn() into out_memory allocated if (result != null) { @@ -677,50 +728,60 @@ this, new DataWord(contextAddress), returnDataBuffer = buffer; } - // 5. REFUND THE REMAIN GAS + // 5. REFUND THE REMAIN ENERGY if (result != null) { - BigInteger refundGas = msg.getGas().value().subtract(toBI(result.getDropUsed())); - if (isPositive(refundGas)) { - refundGas(refundGas.longValue(), "remaining gas from the internal call"); + BigInteger refundEnergy = msg.getEnergy().value().subtract(toBI(result.getEnergyUsed())); + if (isPositive(refundEnergy)) { + refundEnergy(refundEnergy.longValue(), "remaining energy from the internal call"); if (logger.isInfoEnabled()) { - logger.info("The remaining gas refunded, account: [{}], gas: [{}] ", + logger.info("The remaining energy refunded, account: [{}], energy: [{}] ", Hex.toHexString(senderAddress), - refundGas.toString()); + refundEnergy.toString()); } } } else { - refundGas(msg.getGas().longValue(), "remaining gas from the internal call"); + refundEnergy(msg.getEnergy().longValue(), "remaining esnergy from the internal call"); } + } + public static void increaseNonce(){ + nonce++; } - public void spendDrop(long dropValue, String cause) { -// if (getDroplimitLong() < dropValue) { -// throw Exception.notEnoughSpendingGas(cause, dropValue, this); -// } - getResult().spendDrop(dropValue); + public static void resetNonce(){ + nonce=0; } - public void checkCPULimit(String opName) throws OutOfResourceException { + public void spendEnergy(long energyValue, String opName) { + if (getEnergylimitLeftLong() < energyValue) { + throw new OutOfEnergyException( + "Not enough energy for '%s' operation executing: curInvokeEnergyLimit[%d], curOpEnergy[%d], usedEnergy[%d]", + opName, invoke.getEnergyLimit(), energyValue, getResult().getEnergyUsed()); + } + getResult().spendEnergy(energyValue); + } - long vmNowInUs = System.nanoTime() / 1000; - if (vmNowInUs > getVmShouldEndInUs()) { - throw Exception.notEnoughCPU(opName); + public void checkCPUTimeLimit(String opName) { + if (!Args.getInstance().isDebug()) { + long vmNowInUs = System.nanoTime() / 1000; + if (vmNowInUs > getVmShouldEndInUs()) { + throw Exception.notEnoughTime(opName); + } } } - public void spendAllGas() { - spendDrop(getDroplimit().longValue(), "Spending all remaining"); + public void spendAllEnergy() { + spendEnergy(getEnergyLimitLeft().longValue(), "Spending all remaining"); } - public void refundGas(long gasValue, String cause) { - logger.info("[{}] Refund for cause: [{}], gas: [{}]", invoke.hashCode(), cause, gasValue); - getResult().refundGas(gasValue); + public void refundEnergy(long energyValue, String cause) { + logger.info("[{}] Refund for cause: [{}], energy: [{}]", invoke.hashCode(), cause, energyValue); + getResult().refundEnergy(energyValue); } - public void futureRefundGas(long gasValue) { - logger.info("Future refund added: [{}]", gasValue); - getResult().addFutureRefund(gasValue); + public void futureRefundEnergy(long energyValue) { + logger.info("Future refund added: [{}]", energyValue); + getResult().addFutureRefund(energyValue); } public void resetFutureRefund() { @@ -728,21 +789,13 @@ public void resetFutureRefund() { } public void storageSave(DataWord word1, DataWord word2) { - //storageSave(word1.getData(), word2.getData()); DataWord keyWord = word1.clone(); DataWord valWord = word2.clone(); - getStorage().addStorageValue(convertToTronAddress(getOwnerAddress().getLast20Bytes()), keyWord, - valWord); + getContractState() + .putStorageValue(convertToTronAddress(getOwnerAddress().getLast20Bytes()), keyWord, + valWord); } - /* - public void storageSave(byte[] key, byte[] val) { - DataWord keyWord = new DataWord(key); - DataWord valWord = new DataWord(val); - getStorage().addStorageRow(getOwnerAddress().getLast20Bytes(), keyWord, valWord); - } - */ - public byte[] getCode() { return ops; } @@ -779,7 +832,7 @@ public DataWord getBlockHash(int index) { } public DataWord getBalance(DataWord address) { - long balance = getStorage().getBalance(convertToTronAddress(address.getLast20Bytes())); + long balance = getContractState().getBalance(convertToTronAddress(address.getLast20Bytes())); return new DataWord(balance); } @@ -795,12 +848,12 @@ public DataWord getDropPrice() { return new DataWord(1); } - public long getDroplimitLong() { - return invoke.getDroplimitLong() - getResult().getDropUsed(); + public long getEnergylimitLeftLong() { + return invoke.getEnergyLimit() - getResult().getEnergyUsed(); } - public DataWord getDroplimit() { - return new DataWord(invoke.getDroplimitLong() - getResult().getDropUsed()); + public DataWord getEnergyLimitLeft() { + return new DataWord(invoke.getEnergyLimit() - getResult().getEnergyUsed()); } public long getVmShouldEndInUs() { @@ -841,7 +894,7 @@ public byte[] getReturnDataBufferData(DataWord off, DataWord size) { } public DataWord storageLoad(DataWord key) { - DataWord ret = getStorage() + DataWord ret = getContractState() .getStorageValue(convertToTronAddress(getOwnerAddress().getLast20Bytes()), key.clone()); return ret == null ? null : ret.clone(); } @@ -863,7 +916,7 @@ public DataWord getNumber() { } public DataWord getDifficulty() { - return null; //invoke.getDifficulty().clone(); + return new DataWord(0); //invoke.getDifficulty().clone(); } public boolean isStaticCall() { @@ -950,10 +1003,10 @@ public void fullTrace() { logger.trace(" -- OPS -- {}", opsString); logger.trace(" -- STACK -- {}", stackData); logger.trace(" -- MEMORY -- {}", memoryData); - logger.trace("\n Spent Drop: [{}]/[{}]\n Left Gas: [{}]\n", - getResult().getDropUsed(), - invoke.getDroplimit().longValue(), - getDroplimit().longValue()); + logger.trace("\n Spent Drop: [{}]/[{}]\n Left Energy: [{}]\n", + getResult().getEnergyUsed(), + invoke.getEnergyLimit(), + getEnergyLimitLeft().longValue()); StringBuilder globalOutput = new StringBuilder("\n"); if (stackData.length() > 0) { @@ -979,7 +1032,7 @@ public void fullTrace() { if (!Arrays.equals(txData, ops)) { globalOutput.append("\n msg.data: ").append(Hex.toHexString(txData)); } - globalOutput.append("\n\n Spent Gas: ").append(getResult().getDropUsed()); + globalOutput.append("\n\n Spent Energy: ").append(getResult().getEnergyUsed()); if (listener != null) { listener.output(globalOutput.toString()); @@ -989,7 +1042,7 @@ public void fullTrace() { public void saveOpTrace() { if (this.pc < ops.length) { - trace.addOp(ops[pc], pc, getCallDeep(), getDroplimit(), traceListener.resetActions()); + trace.addOp(ops[pc], pc, getCallDeep(), getEnergyLimitLeft(), traceListener.resetActions()); } } @@ -1195,27 +1248,28 @@ public int verifyJumpDest(DataWord nextPC) { public void callToPrecompiledAddress(MessageCall msg, PrecompiledContracts.PrecompiledContract contract) - throws ContractExeException { + throws ContractValidateException { returnDataBuffer = null; // reset return buffer right before the call if (getCallDeep() == MAX_DEPTH) { stackPushZero(); - this.refundGas(msg.getGas().longValue(), " call deep limit reach"); + this.refundEnergy(msg.getEnergy().longValue(), " call deep limit reach"); return; } - // Repository track = getStorage().startTracking(); - Deposit deposit = getStorage(); + // Repository track = getContractState().startTracking(); + Deposit deposit = getContractState(); byte[] senderAddress = convertToTronAddress(this.getOwnerAddress().getLast20Bytes()); byte[] codeAddress = convertToTronAddress(msg.getCodeAddress().getLast20Bytes()); byte[] contextAddress = msg.getType().callIsStateless() ? senderAddress : codeAddress; + // todo: need check endowment > 0 and not exceed?? because of "senderBalance < endowment" long endowment = msg.getEndowment().value().longValue(); long senderBalance = deposit.getBalance(senderAddress); if (senderBalance < endowment) { stackPushZero(); - this.refundGas(msg.getGas().longValue(), "refund gas from message call"); + this.refundEnergy(msg.getEnergy().longValue(), "refund energy from message call"); return; } @@ -1223,31 +1277,35 @@ public void callToPrecompiledAddress(MessageCall msg, msg.getInDataSize().intValue()); // Charge for endowment - is not reversible by rollback - transfer(deposit, senderAddress, contextAddress, msg.getEndowment().value().longValue()); - - long requiredGas = contract.getGasForData(data); - if (requiredGas > msg.getGas().longValue()) { + if (!ArrayUtils.isEmpty(senderAddress) && !ArrayUtils.isEmpty(contextAddress) + && senderAddress != contextAddress && msg.getEndowment().value().longValue() > 0) { + transfer(deposit, senderAddress, contextAddress, msg.getEndowment().value().longValue()); + } - this.refundGas(0, "call pre-compiled"); //matches cpp logic + long requiredEnergy = contract.getEnergyForData(data); + if (requiredEnergy > msg.getEnergy().longValue()) { + // todo: new throw?? because it has done nothing, but outside don't know this + // regard as consumed the energy + this.refundEnergy(0, "call pre-compiled"); //matches cpp logic this.stackPushZero(); // deposit.rollback(); } else { // Delegate or not. if is delegated, we will use msg sender, otherwise use contract address contract.setCallerAddress(convertToTronAddress(msg.getType().callIsDelegate() ? getCallerAddress().getLast20Bytes() : getOwnerAddress().getLast20Bytes())); - // this is the depositImpl, not storage as above + // this is the depositImpl, not contractState as above contract.setDeposit(this.invoke.getDeposit()); contract.setResult(this.result); Pair out = contract.execute(data); if (out.getLeft()) { // success - this.refundGas(msg.getGas().longValue() - requiredGas, "call pre-compiled"); + this.refundEnergy(msg.getEnergy().longValue() - requiredEnergy, "call pre-compiled"); this.stackPushOne(); returnDataBuffer = out.getRight(); deposit.commit(); } else { - // spend all gas on failure, push zero and revert state changes - this.refundGas(0, "call pre-compiled"); + // spend all energy on failure, push zero and revert state changes + this.refundEnergy(0, "call pre-compiled"); this.stackPushZero(); // deposit.rollback(); } @@ -1279,9 +1337,9 @@ public BytecodeExecutionException(String message) { } @SuppressWarnings("serial") - public static class OutOfGasException extends BytecodeExecutionException { + public static class OutOfEnergyException extends BytecodeExecutionException { - public OutOfGasException(String message, Object... args) { + public OutOfEnergyException(String message, Object... args) { super(format(message, args)); } } @@ -1356,48 +1414,38 @@ public StaticCallModificationException() { public static class Exception { - public static OutOfGasException notEnoughOpGas(OpCode op, long opGas, long programGas) { - return new OutOfGasException( - "Not enough gas for '%s' operation executing: opGas[%d], programGas[%d];", op, opGas, - programGas); + public static OutOfEnergyException notEnoughOpEnergy(OpCode op, long opEnergy, + long programEnergy) { + return new OutOfEnergyException( + "Not enough energy for '%s' operation executing: opEnergy[%d], programEnergy[%d];", op, + opEnergy, + programEnergy); } - public static OutOfGasException notEnoughOpGas(OpCode op, DataWord opGas, - DataWord programGas) { - return notEnoughOpGas(op, opGas.longValue(), programGas.longValue()); + public static OutOfEnergyException notEnoughOpEnergy(OpCode op, DataWord opEnergy, + DataWord programEnergy) { + return notEnoughOpEnergy(op, opEnergy.longValue(), programEnergy.longValue()); } - public static OutOfResourceException notEnoughCPU(String op) { + public static OutOfResourceException notEnoughTime(String op) { return new OutOfResourceException( - "Not enough CPU resource when '%s' operation executing", op); + "CPU timeout for '%s' operation executing", op); } + public static OutOfMemoryException memoryOverflow(OpCode op) { return new OutOfMemoryException("Out of Memory when '%s' operation executing", op); } public static OutOfStorageException notEnoughStorage() { - return new OutOfStorageException("Not enough Storage resource"); + return new OutOfStorageException("Not enough ContractState resource"); } - - public static OutOfGasException notEnoughOpGas(OpCode op, BigInteger opGas, - BigInteger programGas) { - return notEnoughOpGas(op, opGas.longValue(), programGas.longValue()); - } - - public static OutOfGasException notEnoughSpendingGas(String cause, long gasValue, - Program program) { - return new OutOfGasException( - "Not enough gas for '%s' cause spending: invokeGas[%d], gas[%d], usedGas[%d];", - cause, program.invoke.getDroplimit().longValue(), gasValue, - program.getResult().getDropUsed()); - } - - public static OutOfGasException gasOverflow(BigInteger actualGas, BigInteger gasLimit) { - return new OutOfGasException("Gas value overflow: actualGas[%d], gasLimit[%d];", - actualGas.longValue(), gasLimit.longValue()); + public static OutOfEnergyException energyOverflow(BigInteger actualEnergy, + BigInteger energyLimit) { + return new OutOfEnergyException("Energy value overflow: actualEnergy[%d], energyLimit[%d];", + actualEnergy.longValue(), energyLimit.longValue()); } public static IllegalOperationException invalidOpCode(byte... opCode) { @@ -1423,6 +1471,22 @@ public StackTooLargeException(String message) { } } + public DataWord getCallEnergy(OpCode op, DataWord requestedEnergy, DataWord availableEnergy) { + + // if (requestedEnergy.compareTo(availableEnergy) > 0) { + // throw new Program.OutOfEnergyException( + // "Not enough energy for '%s' operation executing: opEnergy[%d], programEnergy[%d]", op.name(), + // requestedEnergy, availableEnergy); + // } + // + // return requestedEnergy.clone(); + return requestedEnergy.compareTo(availableEnergy) > 0 ? availableEnergy : requestedEnergy; + } + + public DataWord getCreateEnergy(DataWord availableEnergy) { + return availableEnergy; + } + /** * used mostly for testing reasons */ diff --git a/src/main/java/org/tron/common/runtime/vm/program/ProgramPrecompile.java b/src/main/java/org/tron/common/runtime/vm/program/ProgramPrecompile.java index 8b73b0762e8..76f729ec4e8 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/ProgramPrecompile.java +++ b/src/main/java/org/tron/common/runtime/vm/program/ProgramPrecompile.java @@ -19,16 +19,17 @@ import java.util.HashSet; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.tron.common.runtime.vm.OpCode; + +@Slf4j(topic = "ProgramPrecompile") /** * Created by Anton Nashatyrev on 06.02.2017. */ public class ProgramPrecompile { - private static final Logger logger = LoggerFactory.getLogger("PP"); + // private static final Logger logger = LoggerFactory.getLogger("PP"); private static final int version = 1; private Set jumpdest = new HashSet<>(); diff --git a/src/main/java/org/tron/common/runtime/vm/program/ProgramResult.java b/src/main/java/org/tron/common/runtime/vm/program/ProgramResult.java index 0da96338fa6..09410c92e73 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/ProgramResult.java +++ b/src/main/java/org/tron/common/runtime/vm/program/ProgramResult.java @@ -17,12 +17,8 @@ public class ProgramResult { - private long ownerCpuUsed; - private long senderCpuUsed; - private long ownerStorageUsed; - private long senderStorageUsed; - - private long dropUsed; + private long energyUsed = 0; + private long futureRefund = 0; private byte[] hReturn = EMPTY_BYTE_ARRAY; private byte[] contractAddress = EMPTY_BYTE_ARRAY; @@ -33,7 +29,6 @@ public class ProgramResult { private ByteArraySet touchedAccounts = new ByteArraySet(); private List internalTransactions; private List logInfoList; - private long futureRefund = 0; private TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -45,8 +40,8 @@ public class ProgramResult { */ private List callCreateList; - public void spendDrop(long drops) { - dropUsed += drops; + public void spendEnergy(long energy) { + energyUsed += energy; } public void setRevert() { @@ -57,8 +52,8 @@ public boolean isRevert() { return revert; } - public void refundGas(long drops) { - dropUsed -= drops; + public void refundEnergy(long energy) { + energyUsed -= energy; } public void setContractAddress(byte[] contractAddress) { @@ -82,12 +77,16 @@ public TransactionResultCapsule getRet() { return ret; } + public void setRet(TransactionResultCapsule ret) { + this.ret = ret; + } + public RuntimeException getException() { return exception; } - public long getDropUsed() { - return dropUsed; + public long getEnergyUsed() { + return energyUsed; } public void setException(RuntimeException exception) { @@ -149,8 +148,8 @@ public List getCallCreateList() { return callCreateList; } - public void addCallCreate(byte[] data, byte[] destination, byte[] gasLimit, byte[] value) { - getCallCreateList().add(new CallCreate(data, destination, gasLimit, value)); + public void addCallCreate(byte[] data, byte[] destination, byte[] energyLimit, byte[] value) { + getCallCreateList().add(new CallCreate(data, destination, energyLimit, value)); } public List getInternalTransactions() { @@ -178,8 +177,8 @@ public void rejectInternalTransactions() { } } - public void addFutureRefund(long gasValue) { - futureRefund += gasValue; + public void addFutureRefund(long energyValue) { + futureRefund += energyValue; } public long getFutureRefund() { diff --git a/src/main/java/org/tron/common/runtime/vm/program/Storage.java b/src/main/java/org/tron/common/runtime/vm/program/Storage.java index 043d47a5e9f..32664ce5b22 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/Storage.java +++ b/src/main/java/org/tron/common/runtime/vm/program/Storage.java @@ -1,256 +1,96 @@ -/* - * Copyright (c) [2016] [ ] - * This file is part of the ethereumJ library. - * - * The ethereumJ library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The ethereumJ library 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the ethereumJ library. If not, see . - */ package org.tron.common.runtime.vm.program; -import com.google.protobuf.ByteString; +import static java.lang.System.arraycopy; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; +import org.tron.common.crypto.Hash; import org.tron.common.runtime.vm.DataWord; -import org.tron.common.runtime.vm.program.invoke.ProgramInvoke; -import org.tron.common.runtime.vm.program.listener.ProgramListener; -import org.tron.common.runtime.vm.program.listener.ProgramListenerAware; -import org.tron.common.storage.Deposit; -import org.tron.common.storage.Key; -import org.tron.common.storage.Value; -import org.tron.core.capsule.AccountCapsule; -import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.BytesCapsule; -import org.tron.core.capsule.ContractCapsule; -import org.tron.core.capsule.StorageCapsule; -import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.capsule.StorageRowCapsule; import org.tron.core.db.Manager; -import org.tron.core.exception.ContractExeException; -import org.tron.protos.Protocol; - -public class Storage implements Deposit, ProgramListenerAware { - - private Deposit deposit; - private final DataWord address; // contract address - private ProgramListener programListener; - - public Storage(ProgramInvoke programInvoke) { - this.address = programInvoke.getOwnerAddress(); // contract address - this.deposit = programInvoke.getDeposit(); - } - - @Override - public Manager getDbManager() { - return deposit.getDbManager(); - } - - @Override - public void setProgramListener(ProgramListener listener) { - this.programListener = listener; - } - - @Override - public AccountCapsule createAccount(byte[] addr, Protocol.AccountType type) { - return deposit.createAccount(addr, type); - } - - @Override - public AccountCapsule createAccount(byte[] address, ByteString accountName, - Protocol.AccountType type) { - return deposit.createAccount(address, accountName, type); - } - - - @Override - public AccountCapsule getAccount(byte[] addr) { - return deposit.getAccount(addr); - } - - @Override - public BytesCapsule getContractByNormalAccount(byte[] address) { - return deposit.getContractByNormalAccount(address); - } - - @Override - public void createContractByNormalAccountIndex(byte[] address, - BytesCapsule contractAddress) { - deposit.createContractByNormalAccountIndex(address, contractAddress); - } - - @Override - public void createContract(byte[] codeHash, ContractCapsule contractCapsule) { - deposit.createContract(codeHash, contractCapsule); - } - - @Override - public ContractCapsule getContract(byte[] codeHash) { - return deposit.getContract(codeHash); - } - - @Override - public void saveCode(byte[] addr, byte[] code) { - deposit.saveCode(addr, code); - } - - @Override - public byte[] getCode(byte[] addr) { - return deposit.getCode(addr); - } - - /* - @Override - public byte[] getCodeHash(byte[] addr) { - return deposit.getCodeHash(addr); +import org.tron.core.db.StorageRowStore; + +public class Storage { + + private byte[] addrHash; // contract address + private Manager manager; + private final Map rowCache = new HashMap<>(); + private long beforeUseSize = 0; + + private static final int PREFIX_BYTES = 16; + + public Storage(byte[] address, Manager manager) { + addrHash = addrHash(address); + this.manager = manager; + } + + public DataWord getValue(DataWord key) { + if (rowCache.containsKey(key)) { + return rowCache.get(key).getValue(); + } else { + StorageRowStore store = manager.getStorageRowStore(); + StorageRowCapsule row = store.get(compose(key.getData(), addrHash)); + if (row == null || row.getInstance() == null) { + return null; + } else { + beforeUseSize += row.getInstance().length; + } + rowCache.put(key, row); + return row.getValue(); } - */ - - @Override - public void addStorageValue(byte[] addr, DataWord key, DataWord value) { - if (canListenTrace(addr)) { - programListener.onStoragePut(key, value); - } - deposit.addStorageValue(addr, key, value); } - private boolean canListenTrace(byte[] address) { - return (programListener != null) && this.address.equals(new DataWord(address)); - } - - @Override - public DataWord getStorageValue(byte[] addr, DataWord key) { - return deposit.getStorageValue(addr, key); - } - - @Override - public long getBalance(byte[] addr) { - return deposit.getBalance(addr); + public void put(DataWord key, DataWord value) { + if (rowCache.containsKey(key)) { + rowCache.get(key).setValue(value); + } else { + StorageRowStore store = manager.getStorageRowStore(); + byte[] rowKey = compose(key.getData(), addrHash); + StorageRowCapsule row = store.get(rowKey); + if (row == null || row.getInstance() == null) { + row = new StorageRowCapsule(rowKey, value.getData()); + } else { + beforeUseSize += row.getInstance().length; + } + rowCache.put(key, row); + } } - @Override - public long addBalance(byte[] addr, long value) - throws ContractExeException { - return deposit.addBalance(addr, value); + private static byte[] compose(byte[] key, byte[] addrHash) { + byte[] result = new byte[key.length]; + arraycopy(addrHash, 0, result, 0, PREFIX_BYTES); + arraycopy(key, PREFIX_BYTES, result, PREFIX_BYTES, PREFIX_BYTES); + return result; } - @Override - public Deposit newDepositChild() { - return deposit.newDepositChild(); + // 32 bytes + private static byte[] addrHash(byte[] address) { + return Hash.sha3(address); } - @Override - public Deposit newDepositNext() { - return deposit.newDepositNext(); + public long computeSize() { + AtomicLong size = new AtomicLong(); + rowCache.forEach((key, value) -> { + if (!value.getValue().isZero()) { + size.getAndAdd(value.getInstance().length); + } + }); + return size.get(); } - @Override - public void flush() { - deposit.flush(); + public long getBeforeUseSize() { + return this.beforeUseSize; } - @Override public void commit() { - deposit.commit(); - } - - @Override - public StorageCapsule getStorage(byte[] address) { - return deposit.getStorage(address); - } - - @Override - public void putAccount(Key key, Value value) { - deposit.putAccount(key, value); - } - - @Override - public void putTransaction(Key key, Value value) { - deposit.putTransaction(key, value); - } - - @Override - public void putBlock(Key key, Value value) { - deposit.putBlock(key, value); - } - - @Override - public void putWitness(Key key, Value value) { - deposit.putWitness(key, value); - } - - @Override - public void putCode(Key key, Value value) { - deposit.putCode(key, value); - } - - @Override - public void putContract(Key key, Value value) { - deposit.putContract(key, value); - } - - @Override - public void putContractByNormalAccountIndex(Key key, Value value) { - deposit.putContractByNormalAccountIndex(key, value); - } - - @Override - public void putStorage(Key key, Value value) { - deposit.putStorage(key, value); - } - - @Override - public void putVotes(Key key, Value value) { - deposit.putVotes(key, value); - } - - @Override - public void setParent(Deposit deposit) { - this.deposit.setParent(deposit); - } - - @Override - public void setPrevDeposit(Deposit deposit) { - this.deposit.setPrevDeposit(deposit); - } - - @Override - public void setNextDeposit(Deposit deposit) { - this.deposit.setNextDeposit(deposit); - } - - @Override - public TransactionCapsule getTransaction(byte[] trxHash) { - return this.deposit.getTransaction(trxHash); - } - - @Override - // Do nothing - public void syncCacheFromAccountStore(byte[] address) { - } - - @Override - // Do nothing - public void syncCacheFromVotesStore(byte[] address) { - } - - @Override - public BlockCapsule getBlock(byte[] blockHash) { - return this.deposit.getBlock(blockHash); - } - - @Override - public long computeAfterRunStorageSize() { - return this.deposit.computeAfterRunStorageSize(); - } - - @Override - public long getBeforeRunStorageSize() { - return this.deposit.getBeforeRunStorageSize(); + rowCache.forEach((key, value) -> { + if (value.isDirty()) { + if (value.getValue().isZero()) { + manager.getStorageRowStore().delete(value.getRowKey()); + } else { + manager.getStorageRowStore().put(value.getRowKey(), value); + } + } + }); } } diff --git a/src/main/java/org/tron/common/runtime/vm/program/VMTransaction.java b/src/main/java/org/tron/common/runtime/vm/program/VMTransaction.java deleted file mode 100644 index 7ebf4e6f7bc..00000000000 --- a/src/main/java/org/tron/common/runtime/vm/program/VMTransaction.java +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (c) [2016] [ ] - * This file is part of the ethereumJ library. - * - * The ethereumJ library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The ethereumJ library 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the ethereumJ library. If not, see . - */ -package org.tron.common.runtime.vm.program; - -import static org.apache.commons.lang3.ArrayUtils.isEmpty; - -import com.google.common.primitives.Longs; -import java.math.BigInteger; -import java.security.SignatureException; -import java.util.Arrays; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.spongycastle.util.BigIntegers; -import org.spongycastle.util.encoders.Hex; -import org.tron.common.crypto.ECKey; -import org.tron.common.crypto.ECKey.ECDSASignature; -import org.tron.common.crypto.ECKey.MissingPrivateKeyException; -import org.tron.common.crypto.Hash; -import org.tron.common.runtime.vm.DataWord; -import org.tron.common.utils.ByteUtil; -import org.tron.common.utils.Sha256Hash; -import org.tron.core.capsule.TransactionCapsule; -import org.tron.protos.Protocol; - -public class VMTransaction { - - private static final Logger logger = LoggerFactory.getLogger("VMTransaction"); - private static final BigInteger DEFAULT_GAS_PRICE = new BigInteger("10000000000000"); - private static final BigInteger DEFAULT_BALANCE_GAS = new BigInteger("21000"); - - public static final int HASH_LENGTH = 32; - public static final int ADDRESS_LENGTH = 20; - - /* SHA3 hash of the RLP encoded transaction */ - private byte[] hash; - - /* the amount of ether to transfer (calculated as wei) */ - private long value; - - /* the address of the destination account - * In creation transaction the receive address is - 0 */ - private byte[] receiveAddress; - - /* An unlimited size byte array specifying - * input [data] of the message call or - * Initialization code for a new contract */ - private byte[] data; - - /** - * Since EIP-155, we could encode chainId in V - */ - private static final int CHAIN_ID_INC = 35; - private static final int LOWER_REAL_V = 27; - private Integer chainId = null; - - /* the elliptic curve signature - * (including public key recovery bits) */ - private ECDSASignature signature; - - protected byte[] sendAddress; - - /* Tx in encoded form */ - protected byte[] protoEncoded; - private byte[] protoRaw; - /* Indicates if this transaction has been parsed - * from the RLP-encoded data */ - protected boolean parsed = false; - - ///////////////////////////// - Protocol.Transaction trx; - - public VMTransaction(byte[] rawData) { - this.protoEncoded = rawData; - parsed = false; - } - - public VMTransaction(Protocol.Transaction tx) { - this.trx = tx; - TransactionCapsule trxCap = new TransactionCapsule(tx); - this.protoEncoded = trxCap.getData(); - parsed = false; - } - - - public VMTransaction(byte[] receiveAddress, long value, byte[] data, - Integer chainId) { - this.receiveAddress = receiveAddress; - if (value == 0L) { - this.value = 0L; - } else { - this.value = value; - } - this.data = data; - this.chainId = chainId; - - if (receiveAddress == null) { - this.receiveAddress = ByteUtil.EMPTY_BYTE_ARRAY; - } - - parsed = true; - } - - public VMTransaction(byte[] receiveAddress, long value, byte[] data) { - this(receiveAddress, value, data, null); - } - - public VMTransaction(byte[] receiveAddress, long value, byte[] data, - byte[] r, byte[] s, byte v, Integer chainId) { - this(receiveAddress, value, data, chainId); - this.signature = ECDSASignature.fromComponents(r, s, v); - } - - public VMTransaction(byte[] receiveAddress, long value, byte[] data, - byte[] r, byte[] s, byte v) { - this(receiveAddress, value, data, r, s, v, null); - } - - - private Integer extractChainIdFromV(BigInteger bv) { - if (bv.bitLength() > 31) { - return Integer.MAX_VALUE; // chainId is limited to 31 bits, longer are not valid for now - } - long v = bv.longValue(); - if (v == LOWER_REAL_V || v == (LOWER_REAL_V + 1)) { - return null; - } - return (int) ((v - CHAIN_ID_INC) / 2); - } - - private byte getRealV(BigInteger bv) { - if (bv.bitLength() > 31) { - return 0; // chainId is limited to 31 bits, longer are not valid for now - } - long v = bv.longValue(); - if (v == LOWER_REAL_V || v == (LOWER_REAL_V + 1)) { - return (byte) v; - } - byte realV = LOWER_REAL_V; - int inc = 0; - if ((int) v % 2 == 0) { - inc = 1; - } - return (byte) (realV + inc); - } - - public long transactionCost(Protocol.Block block) { - - protoParse(); - - //return config.getConfigForBlock(block.getNumber()). - // getTransactionCost(this); - return 0; - } - - public synchronized void verify() { - protoParse(); - validate(); - } - - public synchronized void protoParse() { - if (parsed) { - return; - } - try { - //RLPList decodedTxList = RLP.decode2(rlpEncoded); - //RLPList transaction = (RLPList) decodedTxList.get(0); - - // Basic verification - /*if (transaction.size() > 9 ) throw new RuntimeException("Too many RLP elements"); - for (RLPElement rlpElement : transaction) { - if (!(rlpElement instanceof RLPItem)) - throw new RuntimeException("Transaction RLP elements shouldn't be lists"); - } - - this.gasPrice = transaction.get(1).getRLPData(); - this.gasLimit = transaction.get(2).getRLPData(); - this.receiveAddress = transaction.get(3).getRLPData(); - this.value = transaction.get(4).getRLPData(); - this.data = transaction.get(5).getRLPData(); - // only parse signature in case tx is signed - if (transaction.get(6).getRLPData() != null) { - byte[] vData = transaction.get(6).getRLPData(); - BigInteger v = ByteUtil.bytesToBigInteger(vData); - this.chainId = extractChainIdFromV(v); - byte[] r = transaction.get(7).getRLPData(); - byte[] s = transaction.get(8).getRLPData(); - this.signature = ECDSASignature.fromComponents(r, s, getRealV(v)); - } else { - logger.debug("RLP encoded tx is not signed!"); - } - this.parsed = true; - this.hash = getHash(); - */ - - /// - - //use protoEncoded directly and it should never be null - this.hash = Hash.sha3(protoEncoded); - this.parsed = true; - TransactionCapsule transaction = new TransactionCapsule(protoEncoded); - } catch (Exception e) { - throw new RuntimeException("Error on parsing proto", e); - } - } - - private void validate() { - if (receiveAddress != null && receiveAddress.length != 0 - && receiveAddress.length != ADDRESS_LENGTH) { - throw new RuntimeException("Receive address is not valid"); - } - - if (getSignature() != null) { - if (BigIntegers.asUnsignedByteArray(signature.r).length > HASH_LENGTH) { - throw new RuntimeException("Signature R is not valid"); - } - if (BigIntegers.asUnsignedByteArray(signature.s).length > HASH_LENGTH) { - throw new RuntimeException("Signature S is not valid"); - } - if (getSender() != null && getSender().length != ADDRESS_LENGTH) { - throw new RuntimeException("Sender is not valid"); - } - } - } - - public boolean isParsed() { - return parsed; - } - - public byte[] getHash() { - if (!isEmpty(hash)) { - return Arrays.copyOf(hash, hash.length); - } - - protoParse(); - byte[] plainMsg = this.getEncoded(); - return Hash.sha3(plainMsg); - } - - public byte[] getRawHash() { - protoParse(); - byte[] plainMsg = this.getEncodedRaw(); - return Hash.sha3(plainMsg); - } - - public long getValue() { - protoParse(); - return value; - } - - protected void setValue(long value) { - this.value = value; - parsed = true; - } - - public byte[] getReceiveAddress() { - protoParse(); - return receiveAddress; - } - - protected void setReceiveAddress(byte[] receiveAddress) { - this.receiveAddress = receiveAddress; - parsed = true; - } - - - public long nonZeroDataBytes() { - if (data == null) { - return 0; - } - int counter = 0; - for (final byte aData : data) { - if (aData != 0) { - ++counter; - } - } - return counter; - } - - public long zeroDataBytes() { - if (data == null) { - return 0; - } - int counter = 0; - for (final byte aData : data) { - if (aData == 0) { - ++counter; - } - } - return counter; - } - - - public byte[] getData() { - protoParse(); - return data; - } - - protected void setData(byte[] data) { - this.data = data; - parsed = true; - } - - public ECDSASignature getSignature() { - protoParse(); - return signature; - } - - public byte[] getContractAddress() { - if (!isContractCreation()) { - return null; - } - // return HashUtil.calcNewAddr(this.getSender(), this.getNonce()); - DataWord addr = new DataWord(this.getSender()); - byte[] privKey = Sha256Hash.hash(addr.getData()); - ECKey ecKey = ECKey.fromPrivate(privKey); - byte[] newAddress = ecKey.getAddress(); - return newAddress; - } - - public boolean isContractCreation() { - protoParse(); - return this.receiveAddress == null || Arrays - .equals(this.receiveAddress, ByteUtil.EMPTY_BYTE_ARRAY); - } - - /* - * Crypto - */ - - public ECKey getKey() { - byte[] hash = getRawHash(); - return ECKey.recoverFromSignature(signature.v, signature, hash); - } - - public synchronized byte[] getSender() { - try { - if (sendAddress == null && getSignature() != null) { - sendAddress = ECKey.signatureToAddress(getRawHash(), getSignature()); - } - return sendAddress; - } catch (SignatureException e) { - logger.error(e.getMessage(), e); - } - return null; - } - - public Integer getChainId() { - protoParse(); - return chainId == null ? null : (int) chainId; - } - - /** - * @deprecated should prefer #sign(ECKey) over this method - */ - public void sign(byte[] privKeyBytes) throws MissingPrivateKeyException { - sign(ECKey.fromPrivate(privKeyBytes)); - } - - public void sign(ECKey key) throws MissingPrivateKeyException { - this.signature = key.sign(this.getRawHash()); - this.protoEncoded = null; - } - - @Override - public String toString() { - return toString(Integer.MAX_VALUE); - } - - public String toString(int maxDataSize) { - protoParse(); - String dataS; - if (data == null) { - dataS = ""; - } else if (data.length < maxDataSize) { - dataS = ByteUtil.toHexString(data); - } else { - dataS = ByteUtil.toHexString(Arrays.copyOfRange(data, 0, maxDataSize)) + - "... (" + data.length + " bytes)"; - } - return "TransactionData [" + "hash=" + ByteUtil.toHexString(hash) + - ", receiveAddress=" + ByteUtil.toHexString(receiveAddress) + - ", sendAddress=" + ByteUtil.toHexString(getSender()) + - ", value=" + value + - ", data=" + dataS + - ", signatureV=" + (signature == null ? "" : signature.v) + - ", signatureR=" + (signature == null ? "" - : ByteUtil.toHexString(BigIntegers.asUnsignedByteArray(signature.r))) + - ", signatureS=" + (signature == null ? "" - : ByteUtil.toHexString(BigIntegers.asUnsignedByteArray(signature.s))) + - "]"; - } - - /** - * For signatures you have to keep also RLP of the transaction without any signature data - */ - public byte[] getEncodedRaw() { - protoParse(); - if (protoRaw != null) { - return Arrays.copyOf(protoRaw, protoRaw.length); - } - - return this.protoEncoded.clone(); - /* - // parse null as 0 for nonce - byte[] gasPrice = RLP.encodeElement(this.gasPrice); - byte[] gasLimit = RLP.encodeElement(this.gasLimit); - byte[] receiveAddress = RLP.encodeElement(this.receiveAddress); - byte[] value = longToBytes(this.value); - byte[] data = RLP.encodeElement(this.data); - - // Since EIP-155 use chainId for v - if (chainId == null) { - protoRaw = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, - value, data); - } else { - byte[] v, r, s; - v = RLP.encodeInt(chainId); - r = RLP.encodeElement(EMPTY_BYTE_ARRAY); - s = RLP.encodeElement(EMPTY_BYTE_ARRAY); - rlpRaw = RLP.encodeList(nonce, gasPrice, gasLimit, receiveAddress, - value, data, v, r, s); - } - return rlpRaw; - */ - } - - public byte[] getEncoded() { - - if (protoEncoded != null) { - if (null == this.hash) { - this.hash = Hash.sha3(protoEncoded); - } - return protoEncoded; - } - /* - byte[] gasPrice = RLP.encodeElement(this.gasPrice); - byte[] gasLimit = RLP.encodeElement(this.gasLimit); - byte[] receiveAddress = RLP.encodeElement(this.receiveAddress); - byte[] value = RLP.encodeElement(this.value); - byte[] data = RLP.encodeElement(this.data); - - byte[] v, r, s; - - if (signature != null) { - int encodeV; - if (chainId == null) { - encodeV = signature.v; - } else { - encodeV = signature.v - LOWER_REAL_V; - encodeV += chainId * 2 + CHAIN_ID_INC; - } - v = RLP.encodeInt(encodeV); - r = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.r)); - s = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.s)); - } else { - // Since EIP-155 use chainId for v - v = chainId == null ? RLP.encodeElement(EMPTY_BYTE_ARRAY) : RLP.encodeInt(chainId); - r = RLP.encodeElement(EMPTY_BYTE_ARRAY); - s = RLP.encodeElement(EMPTY_BYTE_ARRAY); - } - - this.rlpEncoded = RLP.encodeList(nonce, gasPrice, gasLimit, - receiveAddress, value, data, v, r, s); - - this.hash = this.getHash(); - */ - - byte[] value = Longs.toByteArray(this.value); - byte[] raw = new byte[this.receiveAddress.length + this.data.length + value.length]; - System.arraycopy(this.receiveAddress, 0, raw, 0, this.receiveAddress.length); - System.arraycopy(this.data, 0, raw, this.receiveAddress.length, this.data.length); - System.arraycopy(value, 0, raw, this.data.length, value.length); - this.protoEncoded = raw; - this.hash = Hash.sha3(protoEncoded); - - return protoEncoded; - } - - @Override - public int hashCode() { - - byte[] hash = this.getHash(); - int hashCode = 0; - - for (int i = 0; i < hash.length; ++i) { - hashCode += hash[i] * i; - } - - return hashCode; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || !(o.getClass() == getClass())) { - return false; - } - VMTransaction tx = (VMTransaction) o; - - return tx.hashCode() == this.hashCode(); - } - - /** - * @deprecated Use {@link VMTransaction#createDefault(String, long)} instead - */ - public static VMTransaction createDefault(String to, long amount) { - return create(to, amount); - } - - public static VMTransaction createDefault(String to, long amount, Integer chainId) { - return create(to, amount, chainId); - } - - - public static VMTransaction create(String to, long amount) { - return new VMTransaction( - Hex.decode(to), - amount, - null); - } - - public static VMTransaction create(String to, long amount, Integer chainId) { - return new VMTransaction( - Hex.decode(to), - amount, - null, - chainId); - } -} diff --git a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvoke.java b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvoke.java index a929e62c7a1..ca715165422 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvoke.java +++ b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvoke.java @@ -53,10 +53,6 @@ public interface ProgramInvoke { DataWord getDifficulty(); - DataWord getDroplimit(); - - long getDroplimitLong(); - boolean byTransaction(); boolean byTestingSuite(); @@ -72,4 +68,6 @@ public interface ProgramInvoke { long getVmShouldEndInUs(); long getVmStartInUs(); + + long getEnergyLimit(); } diff --git a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeFactory.java b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeFactory.java index ad55c13200d..5b39c4c1342 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeFactory.java +++ b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeFactory.java @@ -19,6 +19,7 @@ import org.tron.common.runtime.vm.DataWord; import org.tron.common.runtime.vm.program.InternalTransaction; +import org.tron.common.runtime.vm.program.InternalTransaction.ExecutorType; import org.tron.common.runtime.vm.program.Program; import org.tron.common.storage.Deposit; import org.tron.protos.Protocol.Block; @@ -30,14 +31,14 @@ */ public interface ProgramInvokeFactory { - ProgramInvoke createProgramInvoke(InternalTransaction.TrxType trxType, - InternalTransaction.ExecuterType executerType, - Transaction tx, Block block, Deposit deposit, long vmStartInUs, long vmShouldEndInUs); + ProgramInvoke createProgramInvoke(InternalTransaction.TrxType trxType, ExecutorType executorType, + Transaction tx, Block block, Deposit deposit, long vmStartInUs, long vmShouldEndInUs, + long energyLimit); ProgramInvoke createProgramInvoke(Program program, DataWord toAddress, DataWord callerAddress, DataWord inValue, long balanceInt, byte[] dataIn, Deposit deposit, boolean staticCall, boolean byTestingSuite, - long vmStartInUs, long vmShouldEndInUs); + long vmStartInUs, long vmShouldEndInUs, long energyLimit); } diff --git a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeFactoryImpl.java b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeFactoryImpl.java index 769afa446bc..3b0655c4717 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeFactoryImpl.java +++ b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeFactoryImpl.java @@ -25,6 +25,7 @@ import org.springframework.stereotype.Component; import org.tron.common.runtime.vm.DataWord; import org.tron.common.runtime.vm.program.InternalTransaction; +import org.tron.common.runtime.vm.program.InternalTransaction.ExecutorType; import org.tron.common.runtime.vm.program.Program; import org.tron.common.storage.Deposit; import org.tron.common.utils.ByteUtil; @@ -47,8 +48,8 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory { // Invocation by the wire tx @Override public ProgramInvoke createProgramInvoke(InternalTransaction.TrxType trxType, - InternalTransaction.ExecuterType executerType, - Transaction tx, Block block, Deposit deposit, long vmStartInUs, long vmShouldEndInUs) { + ExecutorType executorType, Transaction tx, Block block, Deposit deposit, long vmStartInUs, + long vmShouldEndInUs, long energyLimit) { byte[] contractAddress; byte[] ownerAddress; long balance; @@ -64,22 +65,26 @@ public ProgramInvoke createProgramInvoke(InternalTransaction.TrxType trxType, ownerAddress = contract.getOwnerAddress().toByteArray(); balance = deposit.getBalance(ownerAddress); data = ByteUtil.EMPTY_BYTE_ARRAY; + long callValue = contract.getNewContract().getCallValue(); - switch (executerType) { + switch (executorType) { case ET_NORMAL_TYPE: - lastHash = block.getBlockHeader().getRawDataOrBuilder().getParentHash().toByteArray(); - coinbase = block.getBlockHeader().getRawDataOrBuilder().getWitnessAddress().toByteArray(); - timestamp = block.getBlockHeader().getRawDataOrBuilder().getTimestamp(); - number = block.getBlockHeader().getRawDataOrBuilder().getNumber(); - break; case ET_PRE_TYPE: + if (null != block) { + lastHash = block.getBlockHeader().getRawDataOrBuilder().getParentHash().toByteArray(); + coinbase = block.getBlockHeader().getRawDataOrBuilder().getWitnessAddress().toByteArray(); + timestamp = block.getBlockHeader().getRawDataOrBuilder().getTimestamp(); + number = block.getBlockHeader().getRawDataOrBuilder().getNumber(); + } break; default: return null; } - return new ProgramInvokeImpl(contractAddress, ownerAddress, ownerAddress, balance, null, data, - lastHash, coinbase, timestamp, number, deposit, vmStartInUs, vmShouldEndInUs); + + return new ProgramInvokeImpl(contractAddress, ownerAddress, ownerAddress, balance, callValue, data, + lastHash, coinbase, timestamp, number, deposit, vmStartInUs, vmShouldEndInUs, + energyLimit); } else if (trxType == TRX_CONTRACT_CALL_TYPE) { Contract.TriggerSmartContract contract = ContractCapsule @@ -105,7 +110,7 @@ public ProgramInvoke createProgramInvoke(InternalTransaction.TrxType trxType, /*** CALLVALUE op ***/ // byte[] callValue = nullToEmpty(tx.getValue()); - byte[] callValue = contract.getCallValue().toByteArray(); + long callValue = contract.getCallValue(); /*** CALLDATALOAD op ***/ /*** CALLDATACOPY op ***/ @@ -113,28 +118,30 @@ public ProgramInvoke createProgramInvoke(InternalTransaction.TrxType trxType, // byte[] data = tx.isContractCreation() ? ByteUtil.EMPTY_BYTE_ARRAY : nullToEmpty(tx.getData()); data = contract.getData().toByteArray(); - // dropLimit = contract.getTrxCpuLimitInUs().toByteArray(); - switch (executerType) { + // dropLimit = contract.getTrxEnergyLimitInUs().toByteArray(); + switch (executorType) { case ET_CONSTANT_TYPE: break; case ET_PRE_TYPE: - break; case ET_NORMAL_TYPE: - /*** PREVHASH op ***/ - lastHash = block.getBlockHeader().getRawDataOrBuilder().getParentHash().toByteArray(); - /*** COINBASE op ***/ - coinbase = block.getBlockHeader().getRawDataOrBuilder().getWitnessAddress().toByteArray(); - /*** TIMESTAMP op ***/ - timestamp = block.getBlockHeader().getRawDataOrBuilder().getTimestamp(); - /*** NUMBER op ***/ - number = block.getBlockHeader().getRawDataOrBuilder().getNumber(); + if (null != block) { + /*** PREVHASH op ***/ + lastHash = block.getBlockHeader().getRawDataOrBuilder().getParentHash().toByteArray(); + /*** COINBASE op ***/ + coinbase = block.getBlockHeader().getRawDataOrBuilder().getWitnessAddress().toByteArray(); + /*** TIMESTAMP op ***/ + timestamp = block.getBlockHeader().getRawDataOrBuilder().getTimestamp(); + /*** NUMBER op ***/ + number = block.getBlockHeader().getRawDataOrBuilder().getNumber(); + } break; default: break; } return new ProgramInvokeImpl(address, origin, caller, balance, callValue, data, - lastHash, coinbase, timestamp, number, deposit, vmStartInUs, vmShouldEndInUs); + lastHash, coinbase, timestamp, number, deposit, vmStartInUs, vmShouldEndInUs, + energyLimit); } else { return null; } @@ -149,7 +156,7 @@ public ProgramInvoke createProgramInvoke(Program program, DataWord toAddress, DataWord callerAddress, DataWord inValue, long balanceInt, byte[] dataIn, Deposit deposit, boolean isStaticCall, boolean byTestingSuite, long vmStartInUs, - long vmShouldEndInUs) { + long vmShouldEndInUs, long energyLimit) { DataWord address = toAddress; DataWord origin = program.getOriginAddress(); @@ -167,7 +174,7 @@ public ProgramInvoke createProgramInvoke(Program program, DataWord toAddress, return new ProgramInvokeImpl(address, origin, caller, balance, callValue, data, lastHash, coinbase, timestamp, number, difficulty, deposit, program.getCallDeep() + 1, isStaticCall, byTestingSuite, vmStartInUs, - vmShouldEndInUs); + vmShouldEndInUs, energyLimit); } } diff --git a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeImpl.java b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeImpl.java index 07bcd605bf0..6b5470001f1 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeImpl.java +++ b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeImpl.java @@ -19,13 +19,13 @@ import java.math.BigInteger; import java.util.Arrays; +import java.util.Objects; import lombok.extern.slf4j.Slf4j; import org.tron.common.runtime.vm.DataWord; import org.tron.common.storage.Deposit; import org.tron.core.db.BlockStore; @Slf4j - public class ProgramInvokeImpl implements ProgramInvoke { // private BlockStore blockStore; @@ -36,6 +36,7 @@ public class ProgramInvokeImpl implements ProgramInvoke { private long vmStartInUs; private long vmShouldEndInUs; + private long energyLimit; /* BLOCK env **/ private final DataWord prevHash, coinbase, timestamp, number; @@ -51,19 +52,22 @@ public ProgramInvokeImpl(DataWord address, DataWord origin, DataWord caller, Dat DataWord lastHash, DataWord coinbase, DataWord timestamp, DataWord number, DataWord difficulty, Deposit deposit, int callDeep, boolean isStaticCall, boolean byTestingSuite, - long vmStartInUs, long vmShouldEndInUs) { + long vmStartInUs, long vmShouldEndInUs, long energyLimit) { this.address = address; this.origin = origin; this.caller = caller; this.balance = balance; this.callValue = callValue; - this.msgData = Arrays.copyOf(msgData, msgData.length); + if (Objects.nonNull(msgData)) { + this.msgData = Arrays.copyOf(msgData, msgData.length); + } // last Block env this.prevHash = lastHash; this.coinbase = coinbase; this.timestamp = timestamp; this.number = number; + this.callDeep = callDeep; this.deposit = deposit; this.byTransaction = false; @@ -71,21 +75,22 @@ public ProgramInvokeImpl(DataWord address, DataWord origin, DataWord caller, Dat this.byTestingSuite = byTestingSuite; this.vmStartInUs = vmStartInUs; this.vmShouldEndInUs = vmShouldEndInUs; + this.energyLimit = energyLimit; } public ProgramInvokeImpl(byte[] address, byte[] origin, byte[] caller, long balance, - byte[] callValue, byte[] msgData, + long callValue, byte[] msgData, byte[] lastHash, byte[] coinbase, long timestamp, long number, Deposit deposit, - long vmStartInUs, long vmShouldEndInUs, boolean byTestingSuite) { + long vmStartInUs, long vmShouldEndInUs, boolean byTestingSuite, long energyLimit) { this(address, origin, caller, balance, callValue, msgData, lastHash, coinbase, - timestamp, number, deposit, vmStartInUs, vmShouldEndInUs); + timestamp, number, deposit, vmStartInUs, vmShouldEndInUs, energyLimit); this.byTestingSuite = byTestingSuite; } public ProgramInvokeImpl(byte[] address, byte[] origin, byte[] caller, long balance, - byte[] callValue, byte[] msgData, byte[] lastHash, byte[] coinbase, long timestamp, - long number, Deposit deposit, long vmStartInUs, long vmShouldEndInUs) { + long callValue, byte[] msgData, byte[] lastHash, byte[] coinbase, long timestamp, + long number, Deposit deposit, long vmStartInUs, long vmShouldEndInUs, long energyLimit) { // Transaction env this.address = new DataWord(address); @@ -105,6 +110,7 @@ public ProgramInvokeImpl(byte[] address, byte[] origin, byte[] caller, long bala // calc should end time this.vmStartInUs = vmStartInUs; this.vmShouldEndInUs = vmShouldEndInUs; + this.energyLimit = energyLimit; // logger.info("vmStartInUs: {}", vmStartInUs); // logger.info("vmShouldEndInUs: {}", vmShouldEndInUs); @@ -222,36 +228,17 @@ public DataWord getDifficulty() { return null; //difficulty; } - /* GASLIMIT op */ - @Override - public DataWord getDroplimit() { - return DataWord.ZERO; - } - - @Override - public long getDroplimitLong() { - return 0; - } - public long getVmShouldEndInUs() { return vmShouldEndInUs; } - /* Storage */ - /* - public Map getStorage() { - return storage; - } - */ - public Deposit getDeposit() { return deposit; } @Override public BlockStore getBlockStore() { - return null; - //return deposit.getBlockStore(); + return deposit.getDbManager().getBlockStore(); } @Override @@ -313,8 +300,8 @@ public boolean equals(Object o) { return false; } //if (difficulty != null ? !difficulty.equals(that.difficulty) : that.difficulty != null) return false; - //if (gas != null ? !gas.equals(that.gas) : that.gas != null) return false; - //if (gasPrice != null ? !gasPrice.equals(that.gasPrice) : that.gasPrice != null) return false; + //if (energy != null ? !energy.equals(that.energy) : that.energy != null) return false; + //if (energyPrice != null ? !energyPrice.equals(that.energyPrice) : that.energyPrice != null) return false; //if (dropLimit != null ? !dropLimit.equals(that.dropLimit) : that.dropLimit != null) { // return false; // } @@ -377,4 +364,9 @@ public String toString() { ", callDeep=" + callDeep + '}'; } + + public long getEnergyLimit() { + return energyLimit; + } + } diff --git a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeMockImpl.java b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeMockImpl.java index 8503aadbec0..cef34074b2a 100644 --- a/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeMockImpl.java +++ b/src/main/java/org/tron/common/runtime/vm/program/invoke/ProgramInvokeMockImpl.java @@ -40,9 +40,6 @@ public class ProgramInvokeMockImpl implements ProgramInvoke { private byte[] ownerAddress = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); private final byte[] contractAddress = Hex.decode("471fd3ad3e9eeadeec4608b92d16ce6b500704cc"); - // default for most tests. This can be overwritten by the test - private long dropLimit = 1000000; - public ProgramInvokeMockImpl(byte[] msgDataRaw) { this(); this.msgData = msgDataRaw; @@ -96,21 +93,11 @@ public DataWord getCallerAddress() { return new DataWord(addr); } - /* GASPRICE op */ - public DataWord getMinGasPrice() { - - byte[] minGasPrice = Hex.decode("09184e72a000"); - return new DataWord(minGasPrice); - } - - /* GAS op */ - public DataWord getGas() { + /* ENERGYPRICE op */ + public DataWord getMinEnergyPrice() { - return new DataWord(dropLimit); - } - - public void setGas(long gasLimit) { - this.dropLimit = gasLimit; + byte[] minEnergyPrice = Hex.decode("09184e72a000"); + return new DataWord(minEnergyPrice); } /* CALLVALUE op */ @@ -119,14 +106,6 @@ public DataWord getCallValue() { return new DataWord(balance); } - public DataWord getDroplimit() { - return null; - } - - public long getDroplimitLong() { - return dropLimit; - } - /*****************/ /*** msg data ***/ /** @@ -239,6 +218,11 @@ public long getVmStartInUs() { return 0; } + @Override + public long getEnergyLimit() { + return 0; + } + @Override public boolean byTestingSuite() { return false; diff --git a/src/main/java/org/tron/common/runtime/vm/trace/Op.java b/src/main/java/org/tron/common/runtime/vm/trace/Op.java index bc96720f017..5e450628996 100644 --- a/src/main/java/org/tron/common/runtime/vm/trace/Op.java +++ b/src/main/java/org/tron/common/runtime/vm/trace/Op.java @@ -17,16 +17,15 @@ */ package org.tron.common.runtime.vm.trace; -import org.tron.common.runtime.vm.OpCode; - import java.math.BigInteger; +import org.tron.common.runtime.vm.OpCode; public class Op { private OpCode code; private int deep; private int pc; - private BigInteger gas; + private BigInteger energy; private OpActions actions; public OpCode getCode() { @@ -53,12 +52,12 @@ public void setPc(int pc) { this.pc = pc; } - public BigInteger getGas() { - return gas; + public BigInteger getEnergy() { + return energy; } - public void setGas(BigInteger gas) { - this.gas = gas; + public void setEnergy(BigInteger energy) { + this.energy = energy; } public OpActions getActions() { diff --git a/src/main/java/org/tron/common/runtime/vm/trace/ProgramTrace.java b/src/main/java/org/tron/common/runtime/vm/trace/ProgramTrace.java index 1f03d7bf08c..90938eb2fa7 100644 --- a/src/main/java/org/tron/common/runtime/vm/trace/ProgramTrace.java +++ b/src/main/java/org/tron/common/runtime/vm/trace/ProgramTrace.java @@ -17,19 +17,19 @@ */ package org.tron.common.runtime.vm.trace; +import static java.lang.String.format; +import static org.tron.common.runtime.utils.MUtil.convertToTronAddress; +import static org.tron.common.runtime.vm.trace.Serializers.serializeFieldsOnly; +import static org.tron.common.utils.ByteUtil.toHexString; + +import java.util.ArrayList; +import java.util.List; import org.spongycastle.util.encoders.Hex; import org.tron.common.runtime.config.SystemProperties; import org.tron.common.runtime.vm.DataWord; import org.tron.common.runtime.vm.OpCode; import org.tron.common.runtime.vm.program.invoke.ProgramInvoke; -import java.util.ArrayList; -import java.util.List; - -import static java.lang.String.format; -import static org.tron.common.runtime.vm.trace.Serializers.serializeFieldsOnly; -import static org.tron.common.utils.ByteUtil.toHexString; - public class ProgramTrace { private List ops = new ArrayList<>(); @@ -43,7 +43,7 @@ public ProgramTrace() { public ProgramTrace(SystemProperties config, ProgramInvoke programInvoke) { if (programInvoke != null && config.vmTrace()) { - contractAddress = Hex.toHexString(programInvoke.getOwnerAddress().getLast20Bytes()); + contractAddress = Hex.toHexString(convertToTronAddress(programInvoke.getOwnerAddress().getLast20Bytes())); } } @@ -89,12 +89,12 @@ public ProgramTrace error(Exception error) { return this; } - public Op addOp(byte code, int pc, int deep, DataWord gas, OpActions actions) { + public Op addOp(byte code, int pc, int deep, DataWord energy, OpActions actions) { Op op = new Op(); op.setActions(actions); op.setCode(OpCode.code(code)); op.setDeep(deep); - op.setGas(gas.value()); + op.setEnergy(energy.value()); op.setPc(pc); ops.add(op); diff --git a/src/main/java/org/tron/common/runtime/vm/trace/Serializers.java b/src/main/java/org/tron/common/runtime/vm/trace/Serializers.java index 12f0a86da8f..5f1775c8912 100644 --- a/src/main/java/org/tron/common/runtime/vm/trace/Serializers.java +++ b/src/main/java/org/tron/common/runtime/vm/trace/Serializers.java @@ -25,14 +25,13 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.introspect.VisibilityChecker; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; import org.tron.common.runtime.vm.DataWord; import org.tron.common.runtime.vm.OpCode; -import java.io.IOException; - public final class Serializers { private static final Logger LOGGER = LoggerFactory.getLogger("vmtrace"); @@ -40,8 +39,9 @@ public final class Serializers { public static class DataWordSerializer extends JsonSerializer { @Override - public void serialize(DataWord gas, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { - jgen.writeString(gas.value().toString()); + public void serialize(DataWord energy, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeString(energy.value().toString()); } } diff --git a/src/main/java/org/tron/common/storage/Deposit.java b/src/main/java/org/tron/common/storage/Deposit.java index b66059751b2..57397181e53 100644 --- a/src/main/java/org/tron/common/storage/Deposit.java +++ b/src/main/java/org/tron/common/storage/Deposit.java @@ -1,35 +1,27 @@ package org.tron.common.storage; -import com.google.protobuf.ByteString; import org.tron.common.runtime.vm.DataWord; +import org.tron.common.runtime.vm.program.Storage; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BytesCapsule; import org.tron.core.capsule.ContractCapsule; -import org.tron.core.capsule.StorageCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.db.Manager; -import org.tron.core.exception.ContractExeException; import org.tron.protos.Protocol; -/** - * @author Guo Yonggang - * @since 2018.04 - */ public interface Deposit { Manager getDbManager(); AccountCapsule createAccount(byte[] address, Protocol.AccountType type); - AccountCapsule createAccount(byte[] address, ByteString accountName, Protocol.AccountType type); + AccountCapsule createAccount(byte[] address, String accountName, Protocol.AccountType type); AccountCapsule getAccount(byte[] address); void createContract(byte[] address, ContractCapsule contractCapsule); - void createContractByNormalAccountIndex(byte[] address, BytesCapsule contractAddress); - ContractCapsule getContract(byte[] address); void saveCode(byte[] codeHash, byte[] code); @@ -38,15 +30,15 @@ public interface Deposit { //byte[] getCodeHash(byte[] address); - void addStorageValue(byte[] address, DataWord key, DataWord value); + void putStorageValue(byte[] address, DataWord key, DataWord value); DataWord getStorageValue(byte[] address, DataWord key); - StorageCapsule getStorage(byte[] address); + Storage getStorage(byte[] address); long getBalance(byte[] address); - long addBalance(byte[] address, long value) throws ContractExeException; + long addBalance(byte[] address, long value); Deposit newDepositChild(); @@ -75,9 +67,7 @@ public interface Deposit { void putContract(Key key, Value value); - void putContractByNormalAccountIndex(Key key, Value value); - - void putStorage(Key key, Value value); + void putStorage(Key key, Storage cache); void putVotes(Key key, Value value); @@ -89,8 +79,6 @@ public interface Deposit { BlockCapsule getBlock(byte[] blockHash); - BytesCapsule getContractByNormalAccount(byte[] address); - long computeAfterRunStorageSize(); long getBeforeRunStorageSize(); diff --git a/src/main/java/org/tron/common/storage/DepositImpl.java b/src/main/java/org/tron/common/storage/DepositImpl.java index e7e44c05c59..8f27f4a90e0 100644 --- a/src/main/java/org/tron/common/storage/DepositImpl.java +++ b/src/main/java/org/tron/common/storage/DepositImpl.java @@ -6,32 +6,27 @@ import java.util.HashMap; import java.util.concurrent.atomic.AtomicLong; import org.tron.common.runtime.vm.DataWord; +import org.tron.common.runtime.vm.program.Storage; import org.tron.common.utils.StringUtil; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BytesCapsule; import org.tron.core.capsule.ContractCapsule; -import org.tron.core.capsule.StorageCapsule; import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.db.AccountContractIndexStore; import org.tron.core.db.AccountStore; import org.tron.core.db.AssetIssueStore; import org.tron.core.db.BlockStore; import org.tron.core.db.CodeStore; import org.tron.core.db.ContractStore; import org.tron.core.db.Manager; -import org.tron.core.db.StorageStore; +import org.tron.core.db.StorageRowStore; import org.tron.core.db.TransactionStore; import org.tron.core.db.VotesStore; import org.tron.core.db.WitnessStore; import org.tron.core.exception.BadItemException; -import org.tron.core.exception.ContractExeException; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.AccountType; -/** - * @author Guo Yonggang - * @since 27.04.2018 - */ public class DepositImpl implements Deposit { private Manager dbManager; @@ -39,7 +34,6 @@ public class DepositImpl implements Deposit { private Deposit prevDeposit = null; private Deposit nextDeposit = null; - private long beforeRunStorageSize = 0; private HashMap accounCache = new HashMap<>(); private HashMap transactionCache = new HashMap<>(); private HashMap blockCache = new HashMap<>(); @@ -47,10 +41,10 @@ public class DepositImpl implements Deposit { private HashMap blockIndexCache = new HashMap<>(); private HashMap codeCache = new HashMap<>(); private HashMap contractCache = new HashMap<>(); - private HashMap storageCache = new HashMap<>(); + private HashMap votesCache = new HashMap<>(); - private HashMap assetIssueCache = new HashMap<>(); private HashMap accountContractIndexCache = new HashMap<>(); + private HashMap storageCache = new HashMap<>(); private DepositImpl(Manager dbManager, DepositImpl parent, DepositImpl prev) { init(dbManager, parent, prev); @@ -96,18 +90,14 @@ private CodeStore getCodeStore() { return dbManager.getCodeStore(); } - private StorageStore getStorageStore() { - return dbManager.getStorageStore(); + private StorageRowStore getStorageRowStore() { + return dbManager.getStorageRowStore(); } private AssetIssueStore getAssetIssueStore() { return dbManager.getAssetIssueStore(); } - private AccountContractIndexStore getAccountContractIndexStore() { - return dbManager.getAccountContractIndexStore(); - } - @Override public Deposit newDepositChild() { return new DepositImpl(dbManager, this, null); @@ -127,10 +117,10 @@ public synchronized AccountCapsule createAccount(byte[] address, Protocol.Accoun } @Override - public synchronized AccountCapsule createAccount(byte[] address, ByteString accountName, - Protocol.AccountType type) { + public AccountCapsule createAccount(byte[] address, String accountName, AccountType type) { Key key = new Key(address); - AccountCapsule account = new AccountCapsule(ByteString.copyFrom(address), accountName, + AccountCapsule account = new AccountCapsule(ByteString.copyFrom(address), + ByteString.copyFromUtf8(accountName), type); accounCache.put(key, new Value(account.getData(), Type.VALUE_TYPE_CREATE)); @@ -159,29 +149,6 @@ public synchronized AccountCapsule getAccount(byte[] address) { return accountCapsule; } - - public synchronized BytesCapsule getContractByNormalAccount(byte[] address) { - - Key key = new Key(address); - if (accountContractIndexCache.containsKey(key)) { - return accountContractIndexCache.get(key).getBytes(); - } - - BytesCapsule contract; - if (parent != null) { - contract = parent.getContractByNormalAccount(address); - } else if (prevDeposit != null) { - contract = prevDeposit.getContractByNormalAccount(address); - } else { - contract = getAccountContractIndexStore().get(address); - } - - if (contract != null) { - accountContractIndexCache.put(key, Value.create(contract.getData())); - } - return contract; - } - @Override public synchronized void createContract(byte[] address, ContractCapsule contractCapsule) { Key key = Key.create(address); @@ -189,14 +156,6 @@ public synchronized void createContract(byte[] address, ContractCapsule contract contractCache.put(key, value); } - @Override - public synchronized void createContractByNormalAccountIndex(byte[] address, - BytesCapsule contractAddress) { - Key key = new Key(address); - accountContractIndexCache - .put(key, Value.create(contractAddress.getData(), Type.VALUE_TYPE_CREATE)); - } - @Override public synchronized ContractCapsule getContract(byte[] address) { Key key = Key.create(address); @@ -230,7 +189,7 @@ public synchronized void saveCode(byte[] codeHash, byte[] code) { public synchronized byte[] getCode(byte[] codeHash) { Key key = Key.create(codeHash); if (codeCache.containsKey(key)) { - codeCache.get(key).getCode().getData(); + return codeCache.get(key).getCode().getData(); } byte[] code; @@ -245,78 +204,45 @@ public synchronized byte[] getCode(byte[] codeHash) { code = getCodeStore().get(codeHash).getData(); } } - if (code != null) { codeCache.put(key, Value.create(code)); } return code; } - /* - @Override - public byte[] getCodeHash(byte[] address) { - AccountCapsule accountCapsule = getAccount(address); - return accountCapsule != null ? accountCapsule.getCodeHash() : null; - } - */ - @Override - public synchronized StorageCapsule getStorage(byte[] address) { + public synchronized Storage getStorage(byte[] address) { Key key = Key.create(address); if (storageCache.containsKey(key)) { - return storageCache.get(key).getStorage(); + return storageCache.get(key); } - // first access the storageCapsule - StorageCapsule storageCapsule; + Storage storage; if (this.parent != null) { - storageCapsule = parent.getStorage(address); + storage = parent.getStorage(address); } else if (prevDeposit != null) { - storageCapsule = prevDeposit.getStorage(address); + storage = prevDeposit.getStorage(address); } else { - storageCapsule = getStorageStore().get(address); - } - - if (storageCapsule != null) { - storageCache.put(key, Value.create(storageCapsule.getData(), Type.VALUE_TYPE_NORMAL)); - this.beforeRunStorageSize += storageCapsule.getInstance().getSerializedSize(); + storage = new Storage(address, dbManager); } - return storageCapsule; + return storage; } @Override - public synchronized void addStorageValue(byte[] address, DataWord key, DataWord value) { + public synchronized void putStorageValue(byte[] address, DataWord key, DataWord value) { address = convertToTronAddress(address); if (getAccount(address) == null) { return; } Key addressKey = Key.create(address); + Storage storage; if (storageCache.containsKey(addressKey)) { - StorageCapsule storageCapsule = storageCache.get(addressKey).getStorage(); - - if (storageCapsule != null) { - storageCapsule.put(key, value); - Value V = Value.create(storageCapsule.getData(), - Type.VALUE_TYPE_DIRTY | storageCache.get(addressKey).getType().getType()); - storageCache.put(addressKey, V); - } + storage = storageCache.get(addressKey); } else { - StorageCapsule storageCapsule = getStorage(address); - if (storageCapsule == null) { - Protocol.StorageItem.Builder builder = Protocol.StorageItem.newBuilder(); - builder.setContractAddress(ByteString.copyFrom(address)); - Protocol.StorageItem storageItem = builder.build(); - storageCapsule = new StorageCapsule(storageItem); - storageCapsule.put(key, value); - Value V = Value.create(storageCapsule.getData(), Type.VALUE_TYPE_CREATE); - storageCache.put(addressKey, V); - } else { - storageCapsule.put(key, value); - Value V = Value.create(storageCapsule.getData(), - Type.VALUE_TYPE_DIRTY | storageCache.get(addressKey).getType().getType()); - storageCache.put(addressKey, V); - } + storage = getStorage(address); + storageCache.put(addressKey, storage); } + storage.put(key, value); } @Override @@ -326,25 +252,14 @@ public synchronized DataWord getStorageValue(byte[] address, DataWord key) { return null; } Key addressKey = Key.create(address); + Storage storage; if (storageCache.containsKey(addressKey)) { - StorageCapsule storageCapsule = storageCache.get(addressKey).getStorage(); - return storageCapsule.get(key); - } - - StorageCapsule storageCapsule = getStorage(address); - if (storageCapsule != null) { - Value V = Value.create(storageCapsule.getData(), Type.VALUE_TYPE_NORMAL); - storageCache.put(addressKey, V); - return storageCapsule.get(key); + storage = storageCache.get(addressKey); } else { - Protocol.StorageItem.Builder builder = Protocol.StorageItem.newBuilder(); - builder.setContractAddress(ByteString.copyFrom(address)); - Protocol.StorageItem storageItem = builder.build(); - storageCapsule = new StorageCapsule(storageItem); - Value V = Value.create(storageCapsule.getData(), Type.VALUE_TYPE_CREATE); - storageCache.put(addressKey, V); - return storageCapsule.get(key); + storage = getStorage(address); + storageCache.put(addressKey, storage); } + return storage.getValue(key); } @Override @@ -354,8 +269,7 @@ public synchronized long getBalance(byte[] address) { } @Override - public synchronized long addBalance(byte[] address, long value) - throws ContractExeException { + public synchronized long addBalance(byte[] address, long value) { AccountCapsule accountCapsule = getAccount(address); if (accountCapsule == null) { accountCapsule = createAccount(address, Protocol.AccountType.Normal); @@ -367,7 +281,7 @@ public synchronized long addBalance(byte[] address, long value) } if (value < 0 && balance < -value) { - throw new ContractExeException( + throw new RuntimeException( StringUtil.createReadableString(accountCapsule.createDbKey()) + " insufficient balance"); } @@ -434,15 +348,19 @@ public BlockCapsule getBlock(byte[] blockHash) { @Override public long computeAfterRunStorageSize() { AtomicLong afterRunStorageSize = new AtomicLong(); - storageCache.forEach(((key, value) -> { - afterRunStorageSize.addAndGet(value.getStorage().getInstance().getSerializedSize()); - })); + storageCache.forEach((key, value) -> { + afterRunStorageSize.getAndAdd(value.computeSize()); + }); return afterRunStorageSize.get(); } @Override public long getBeforeRunStorageSize() { - return beforeRunStorageSize; + AtomicLong beforeRunStorageSize = new AtomicLong(); + storageCache.forEach((key, value) -> { + beforeRunStorageSize.getAndAdd(value.getBeforeUseSize()); + }); + return beforeRunStorageSize.get(); } @@ -476,14 +394,14 @@ public void putContract(Key key, Value value) { contractCache.put(key, value); } - @Override - public void putContractByNormalAccountIndex(Key key, Value value) { - accountContractIndexCache.put(key, value); - } +// @Override +// public void putStorage(Key key, Value value) { +// storageCache.put(key, value); +// } @Override - public void putStorage(Key key, Value value) { - storageCache.put(key, value); + public void putStorage(Key key, Storage cache) { + storageCache.put(key, cache); } @Override @@ -564,15 +482,16 @@ private void commitContractCache(Deposit deposit) { } private void commitStorageCache(Deposit deposit) { - storageCache.forEach(((key, value) -> { - if (value.getType().isDirty() || value.getType().isCreate()) { - if (deposit != null) { - deposit.putStorage(key, value); - } else { - getStorageStore().put(key.getData(), value.getStorage()); - } + storageCache.forEach((key, value) -> { + if (deposit != null) { + // write to parent cache + deposit.putStorage(key, value); + } else { + // persistence + value.commit(); } - })); + }); + } private void commitVoteCache(Deposit deposit) { @@ -587,18 +506,6 @@ private void commitVoteCache(Deposit deposit) { })); } - private void commitAccountContractIndex(Deposit deposit) { - accountContractIndexCache.forEach(((key, value) -> { - if (value.getType().isDirty() || value.getType().isCreate()) { - if (deposit != null) { - deposit.putContractByNormalAccountIndex(key, value); - } else { - getAccountContractIndexStore().put(key.getData(), value.getBytes()); - } - } - })); - } - @Override public void syncCacheFromAccountStore(byte[] address) { Key key = Key.create(address); @@ -642,7 +549,7 @@ public synchronized void commit() { commitContractCache(deposit); commitStorageCache(deposit); commitVoteCache(deposit); - + // commitAccountContractIndex(deposit); } @Override diff --git a/src/main/java/org/tron/common/storage/DepositQueue.java b/src/main/java/org/tron/common/storage/DepositQueue.java deleted file mode 100644 index 4d4c07abfad..00000000000 --- a/src/main/java/org/tron/common/storage/DepositQueue.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.tron.common.storage; - -import java.util.LinkedList; - -/** - * Deposit Queue (FIFO) based on LinkedList - * - * @author Guo Yonggang - * @since 28.04.2018 - */ -public class DepositQueue { - - public static int MAX_DEPOSIT_SIZE = 100; - public static int DEFAULT_DEPOSIT_SIZE = 20; - - private int maxDepositSize = 0; - private LinkedList list = new LinkedList<>(); - - public DepositQueue(int maxSize) { - if (maxSize <= 0 || maxSize > MAX_DEPOSIT_SIZE) { - maxDepositSize = DEFAULT_DEPOSIT_SIZE; - } else { - maxDepositSize = maxSize; - } - } - - /** - * - * @param obj - */ - public void put(E obj) { - list.addLast(obj); - } - - /** - * - * @return - */ - public E get() { - if (list.isEmpty()) return null; - - return list.removeFirst(); - } - - /** - * - * @return - */ - public E peek() { - if (list.isEmpty()) return null; - return list.getFirst(); - } - - /** - * - * @return - */ - public E last() { - if (list.isEmpty()) return null; - return list.getLast(); - } - - /** - * - * @return - */ - public boolean isEmpty() { - return list.isEmpty(); - } - - /** - * - * @return - */ - public int size() { - return list.size(); - } - - /** - * - */ - public E removeLast() { - if (list.isEmpty()) return null; - return list.removeLast(); - } - -} diff --git a/src/main/java/org/tron/common/storage/Key.java b/src/main/java/org/tron/common/storage/Key.java index 3859b2fdeaf..fe2f2343dd4 100644 --- a/src/main/java/org/tron/common/storage/Key.java +++ b/src/main/java/org/tron/common/storage/Key.java @@ -4,10 +4,6 @@ import java.util.Arrays; -/** - * @author Guo Yongang - * @since 27.04.2018 - */ public class Key { private static int MAX_KEY_LENGTH = 32; diff --git a/src/main/java/org/tron/common/storage/Type.java b/src/main/java/org/tron/common/storage/Type.java index ab76627dd24..af745b25767 100644 --- a/src/main/java/org/tron/common/storage/Type.java +++ b/src/main/java/org/tron/common/storage/Type.java @@ -1,9 +1,5 @@ package org.tron.common.storage; -/** - * @author Guo Yonggang - * @since 27.04.2018 - */ public class Type { /** * Default Mode : VALUE_TYPE_NORMAL diff --git a/src/main/java/org/tron/common/storage/Value.java b/src/main/java/org/tron/common/storage/Value.java index f6112f102ee..7e029ea1c72 100644 --- a/src/main/java/org/tron/common/storage/Value.java +++ b/src/main/java/org/tron/common/storage/Value.java @@ -8,16 +8,11 @@ import org.tron.core.capsule.BytesCapsule; import org.tron.core.capsule.CodeCapsule; import org.tron.core.capsule.ContractCapsule; -import org.tron.core.capsule.StorageCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.VotesCapsule; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.exception.BadItemException; -/** - * @author Guo Yonggang - * @since 27.04.2018 - */ public class Value { private Type type; @@ -179,13 +174,6 @@ public ContractCapsule getContract() { return new ContractCapsule(any); } - /** - * @return - */ - public StorageCapsule getStorage() { - if (ArrayUtils.isEmpty(any)) return null; - return new StorageCapsule(any); - } public AssetIssueCapsule getAssetIssue() { if (ArrayUtils.isEmpty(any)) return null; diff --git a/src/main/java/org/tron/common/utils/BIUtil.java b/src/main/java/org/tron/common/utils/BIUtil.java index 886ac519993..6b72a169f74 100644 --- a/src/main/java/org/tron/common/utils/BIUtil.java +++ b/src/main/java/org/tron/common/utils/BIUtil.java @@ -98,25 +98,10 @@ public static boolean isPositive(BigInteger value){ return value.signum() > 0; } - public static boolean isCovers(BigInteger covers, BigInteger value){ - return !isNotCovers(covers, value); - } - public static boolean isNotCovers(BigInteger covers, BigInteger value){ return covers.compareTo(value) < 0; } - public static boolean exitLong(BigInteger value){ - - return (value.compareTo(new BigInteger(Long.MAX_VALUE + ""))) > -1; - } - - public static boolean isIn20PercentRange(BigInteger first, BigInteger second) { - BigInteger five = BigInteger.valueOf(5); - BigInteger limit = first.add(first.divide(five)); - return !isMoreThan(second, limit); - } - public static BigInteger max(BigInteger first, BigInteger second) { return first.compareTo(second) < 0 ? second : first; } diff --git a/src/main/java/org/tron/common/utils/ByteUtil.java b/src/main/java/org/tron/common/utils/ByteUtil.java index f8ec18d1b5f..d50cd9cceec 100644 --- a/src/main/java/org/tron/common/utils/ByteUtil.java +++ b/src/main/java/org/tron/common/utils/ByteUtil.java @@ -214,18 +214,6 @@ public static byte[] intToBytes(int val) { return ByteBuffer.allocate(4).putInt(val).array(); } - public static byte[] bigIntegerToBytesSigned(BigInteger b, int numBytes) { - if (b == null) - return null; - byte[] bytes = new byte[numBytes]; - Arrays.fill(bytes, b.signum() < 0 ? (byte) 0xFF : 0x00); - byte[] biBytes = b.toByteArray(); - int start = (biBytes.length == numBytes + 1) ? 1 : 0; - int length = Math.min(biBytes.length, numBytes); - System.arraycopy(biBytes, start, bytes, numBytes - length, length); - return bytes; - } - /** * Cast hex encoded value from byte[] to BigInteger * null is parsed like byte[0] @@ -237,66 +225,6 @@ public static BigInteger bytesToBigInteger(byte[] bb) { return (bb == null || bb.length == 0) ? BigInteger.ZERO : new BigInteger(1, bb); } - /** - * Returns the amount of nibbles that match each other from 0 ... - * amount will never be larger than smallest input - * - * @param a - first input - * @param b - second input - * @return Number of bytes that match - */ - public static int matchingNibbleLength(byte[] a, byte[] b) { - int i = 0; - int length = a.length < b.length ? a.length : b.length; - while (i < length) { - if (a[i] != b[i]) - return i; - i++; - } - return i; - } - - /** - * Converts a long value into a byte array. - * - * @param val - long value to convert - * @return byte[] of length 8, representing the long value - */ - public static byte[] longToBytes(long val) { - return ByteBuffer.allocate(Long.BYTES).putLong(val).array(); - } - - /** - * Converts a long value into a byte array. - * - * @param val - long value to convert - * @return decimal value with leading byte that are zeroes striped - */ - public static byte[] longToBytesNoLeadZeroes(long val) { - - // todo: improve performance by while strip numbers until (long >> 8 == 0) - if (val == 0) return EMPTY_BYTE_ARRAY; - - byte[] data = ByteBuffer.allocate(Long.BYTES).putLong(val).array(); - - return stripLeadingZeroes(data); - } - - /** - * Calculate packet length - * - * @param msg byte[] - * @return byte-array with 4 elements - */ - public static byte[] calcPacketLength(byte[] msg) { - int msgLen = msg.length; - return new byte[]{ - (byte) ((msgLen >> 24) & 0xFF), - (byte) ((msgLen >> 16) & 0xFF), - (byte) ((msgLen >> 8) & 0xFF), - (byte) ((msgLen) & 0xFF)}; - } - /** * Cast hex encoded value from byte[] to long * null is parsed like byte[0] @@ -312,76 +240,6 @@ public static long byteArrayToLong(byte[] b) { return new BigInteger(1, b).longValue(); } - /** - * Calculate the number of bytes need - * to encode the number - * - * @param val - number - * @return number of min bytes used to encode the number - */ - public static int numBytes(String val) { - - BigInteger bInt = new BigInteger(val); - int bytes = 0; - - while (!bInt.equals(BigInteger.ZERO)) { - bInt = bInt.shiftRight(8); - ++bytes; - } - if (bytes == 0) ++bytes; - return bytes; - } - - /** - * @param arg - not more that 32 bits - * @return - bytes of the value pad with complete to 32 zeroes - */ - public static byte[] encodeValFor32Bits(Object arg) { - - byte[] data; - - // check if the string is numeric - if (arg.toString().trim().matches("-?\\d+(\\.\\d+)?")) - data = new BigInteger(arg.toString().trim()).toByteArray(); - // check if it's hex number - else if (arg.toString().trim().matches("0[xX][0-9a-fA-F]+")) - data = new BigInteger(arg.toString().trim().substring(2), 16).toByteArray(); - else - data = arg.toString().trim().getBytes(); - - - if (data.length > 32) - throw new RuntimeException("values can't be more than 32 byte"); - - byte[] val = new byte[32]; - - int j = 0; - for (int i = data.length; i > 0; --i) { - val[31 - j] = data[i - 1]; - ++j; - } - return val; - } - - /** - * encode the values and concatenate together - * - * @param args Object - * @return byte[] - */ - public static byte[] encodeDataList(Object... args) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (Object arg : args) { - byte[] val = encodeValFor32Bits(arg); - try { - baos.write(val); - } catch (IOException e) { - throw new Error("Happen something that should never happen ", e); - } - } - return baos.toByteArray(); - } - public static int firstNonZeroByte(byte[] data) { for (int i = 0; i < data.length; ++i) { if (data[i] != 0) { @@ -412,24 +270,6 @@ public static byte[] stripLeadingZeroes(byte[] data) { } } - /** - * increment byte array as a number until max is reached - * - * @param bytes byte[] - * @return boolean - */ - public static boolean increment(byte[] bytes) { - final int startIndex = 0; - int i; - for (i = bytes.length - 1; i >= startIndex; i--) { - bytes[i]++; - if (bytes[i] != 0) - break; - } - // we return false when all bytes are 0 again - return (i >= startIndex || bytes[startIndex] != 0); - } - /** * Utility function to copy a byte array into a new byte array with given size. * If the src length is smaller than the given size, the result will be left-padded @@ -447,230 +287,6 @@ public static byte[] copyToArray(BigInteger value) { return dest; } - - public static ByteArrayWrapper wrap(byte[] data) { - return new ByteArrayWrapper(data); - } - - public static byte[] setBit(byte[] data, int pos, int val) { - - if ((data.length * 8) - 1 < pos) - throw new Error("outside byte array limit, pos: " + pos); - - int posByte = data.length - 1 - (pos) / 8; - int posBit = (pos) % 8; - byte setter = (byte) (1 << (posBit)); - byte toBeSet = data[posByte]; - byte result; - if (val == 1) - result = (byte) (toBeSet | setter); - else - result = (byte) (toBeSet & ~setter); - - data[posByte] = result; - return data; - } - - public static int getBit(byte[] data, int pos) { - - if ((data.length * 8) - 1 < pos) - throw new Error("outside byte array limit, pos: " + pos); - - int posByte = data.length - 1 - pos / 8; - int posBit = pos % 8; - byte dataByte = data[posByte]; - return Math.min(1, ((dataByte & 0xff) & (1 << (posBit)))); - } - - public static byte[] and(byte[] b1, byte[] b2) { - if (b1.length != b2.length) throw new RuntimeException("Array sizes differ"); - byte[] ret = new byte[b1.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = (byte) (b1[i] & b2[i]); - } - return ret; - } - - public static byte[] or(byte[] b1, byte[] b2) { - if (b1.length != b2.length) throw new RuntimeException("Array sizes differ"); - byte[] ret = new byte[b1.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = (byte) (b1[i] | b2[i]); - } - return ret; - } - - public static byte[] xor(byte[] b1, byte[] b2) { - if (b1.length != b2.length) throw new RuntimeException("Array sizes differ"); - byte[] ret = new byte[b1.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = (byte) (b1[i] ^ b2[i]); - } - return ret; - } - - /** - * XORs byte arrays of different lengths by aligning length of the shortest via adding zeros at beginning - */ - public static byte[] xorAlignRight(byte[] b1, byte[] b2) { - if (b1.length > b2.length) { - byte[] b2_ = new byte[b1.length]; - System.arraycopy(b2, 0, b2_, b1.length - b2.length, b2.length); - b2 = b2_; - } else if (b2.length > b1.length) { - byte[] b1_ = new byte[b2.length]; - System.arraycopy(b1, 0, b1_, b2.length - b1.length, b1.length); - b1 = b1_; - } - - return xor(b1, b2); - } - - public static Set difference(Set setA, Set setB){ - - Set result = new HashSet<>(); - - for (byte[] elementA : setA){ - boolean found = false; - for (byte[] elementB : setB){ - - if (Arrays.equals(elementA, elementB)){ - found = true; - break; - } - } - if (!found) result.add(elementA); - } - - return result; - } - - public static int length(byte[]... bytes) { - int result = 0; - for (byte[] array : bytes) { - result += (array == null) ? 0 : array.length; - } - return result; - } - - public static byte[] intsToBytes(int[] arr, boolean bigEndian) { - byte[] ret = new byte[arr.length * 4]; - intsToBytes(arr, ret, bigEndian); - return ret; - } - - public static int[] bytesToInts(byte[] arr, boolean bigEndian) { - int[] ret = new int[arr.length / 4]; - bytesToInts(arr, ret, bigEndian); - return ret; - } - - public static void bytesToInts(byte[] b, int[] arr, boolean bigEndian) { - if (!bigEndian) { - int off = 0; - for (int i = 0; i < arr.length; i++) { - int ii = b[off++] & 0x000000FF; - ii |= (b[off++] << 8) & 0x0000FF00; - ii |= (b[off++] << 16) & 0x00FF0000; - ii |= (b[off++] << 24); - arr[i] = ii; - } - } else { - int off = 0; - for (int i = 0; i < arr.length; i++) { - int ii = b[off++] << 24; - ii |= (b[off++] << 16) & 0x00FF0000; - ii |= (b[off++] << 8) & 0x0000FF00; - ii |= b[off++] & 0x000000FF; - arr[i] = ii; - } - } - } - - public static void intsToBytes(int[] arr, byte[] b, boolean bigEndian) { - if (!bigEndian) { - int off = 0; - for (int i = 0; i < arr.length; i++) { - int ii = arr[i]; - b[off++] = (byte) (ii & 0xFF); - b[off++] = (byte) ((ii >> 8) & 0xFF); - b[off++] = (byte) ((ii >> 16) & 0xFF); - b[off++] = (byte) ((ii >> 24) & 0xFF); - } - } else { - int off = 0; - for (int i = 0; i < arr.length; i++) { - int ii = arr[i]; - b[off++] = (byte) ((ii >> 24) & 0xFF); - b[off++] = (byte) ((ii >> 16) & 0xFF); - b[off++] = (byte) ((ii >> 8) & 0xFF); - b[off++] = (byte) (ii & 0xFF); - } - } - } - - public static short bigEndianToShort(byte[] bs) { - return bigEndianToShort(bs, 0); - } - - public static short bigEndianToShort(byte[] bs, int off) { - int n = bs[off] << 8; - ++off; - n |= bs[off] & 0xFF; - return (short) n; - } - - public static byte[] shortToBytes(short n) { - return ByteBuffer.allocate(2).putShort(n).array(); - } - - /** - * Converts string hex representation to data bytes - * Accepts following hex: - * - with or without 0x prefix - * - with no leading 0, like 0xabc -> 0x0abc - * @param data String like '0xa5e..' or just 'a5e..' - * @return decoded bytes array - */ - public static byte[] hexStringToBytes(String data) { - if (data == null) return EMPTY_BYTE_ARRAY; - if (data.startsWith("0x")) data = data.substring(2); - if (data.length() % 2 == 1) data = "0" + data; - return Hex.decode(data); - } - - /** - * Converts string representation of host/ip to 4-bytes byte[] IPv4 - */ - public static byte[] hostToBytes(String ip) { - byte[] bytesIp; - try { - bytesIp = InetAddress.getByName(ip).getAddress(); - } catch (UnknownHostException e) { - bytesIp = new byte[4]; // fall back to invalid 0.0.0.0 address - } - - return bytesIp; - } - - /** - * Converts 4 bytes IPv4 IP to String representation - */ - public static String bytesToIp(byte[] bytesIp) { - - StringBuilder sb = new StringBuilder(); - sb.append(bytesIp[0] & 0xFF); - sb.append("."); - sb.append(bytesIp[1] & 0xFF); - sb.append("."); - sb.append(bytesIp[2] & 0xFF); - sb.append("."); - sb.append(bytesIp[3] & 0xFF); - - String ip = sb.toString(); - return ip; - } - /** * Returns a number of zero bits preceding the highest-order ("leftmost") one-bit * interpreting input array as a big-endian integer value diff --git a/src/main/java/org/tron/common/utils/CollectionUtils.java b/src/main/java/org/tron/common/utils/CollectionUtils.java index 6191e637bb7..cae99905f0f 100644 --- a/src/main/java/org/tron/common/utils/CollectionUtils.java +++ b/src/main/java/org/tron/common/utils/CollectionUtils.java @@ -1,6 +1,11 @@ package org.tron.common.utils; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; @@ -36,6 +41,31 @@ public static List truncate(List items, int limit) { return truncated; } + public static List truncateRandom(List items, int limit, int confirm) { + if (limit > items.size()) { + return new ArrayList<>(items); + } + List truncated = new ArrayList<>(limit); + if (confirm >= limit) { + for (T item : items) { + truncated.add(item); + if (truncated.size() == limit) { + break; + } + } + } else { + if (confirm > 0) { + truncated.addAll(items.subList(0, confirm)); + } + List endList = items.subList(confirm, items.size()); + Collections.shuffle(endList); + for (int i = 0; i < limit - confirm; i++) { + truncated.add(endList.get(i)); + } + } + return truncated; + } + public static List selectList(Collection items, Predicate predicate) { List selected = new ArrayList<>(); for(T item : items) { diff --git a/src/main/java/org/tron/common/utils/ForkController.java b/src/main/java/org/tron/common/utils/ForkController.java new file mode 100644 index 00000000000..333b181c507 --- /dev/null +++ b/src/main/java/org/tron/common/utils/ForkController.java @@ -0,0 +1,90 @@ +package org.tron.common.utils; + +import com.google.protobuf.ByteString; +import java.util.Arrays; +import java.util.List; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.config.Parameter.ChainConstant; +import org.tron.core.db.Manager; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; + +@Slf4j +@Component +public class ForkController { + + public static final int DISCARD_SCOPE = ContractType.UpdateAssetContract.getNumber(); + + @Getter + private Manager manager; + private volatile int[] slots = new int[0]; + private boolean forked; + + public void init(Manager manager) { + this.manager = manager; + forked = manager.getDynamicPropertiesStore().getForked(); + } + + public synchronized boolean shouldBeForked() { + if (forked) { + logger.info("*****shouldBeForked:" + true); + return true; + } + + for (int version : slots) { + if (version != ChainConstant.version) { + logger.info("*****shouldBeForked:" + false); + return false; + } + } + + // todo add Maintenance or block number + forked = true; + manager.getDynamicPropertiesStore().forked(); + logger.info("*****shouldBeForked:" + true); + return true; + } + + public synchronized boolean forkOrNot(TransactionCapsule capsule) { + logger.info("*****forkOrNot:" + (shouldBeForked() + || capsule.getInstance().getRawData().getContractList().get(0).getType().getNumber() + <= DISCARD_SCOPE)); + return shouldBeForked() + || capsule.getInstance().getRawData().getContractList().get(0).getType().getNumber() + <= DISCARD_SCOPE; + } + + public synchronized void update(BlockCapsule blockCapsule) { + if (forked) { + return; + } + + List witnesses = manager.getWitnessController().getActiveWitnesses(); + if (witnesses.size() != slots.length) { + slots = new int[witnesses.size()]; + } + + ByteString witness = blockCapsule.getWitnessAddress(); + int slot = witnesses.indexOf(witness); + if (slot < 0) { + return; + } + slots[slot] = blockCapsule.getInstance().getBlockHeader().getRawData().getVersion(); + + logger.info( + "*******update:" + Arrays.toString(slots) + + ",witness size:" + witnesses.size() + + "," + slots + + ",slot:" + slot + + ",version:" + blockCapsule.getInstance().getBlockHeader().getRawData().getVersion() + ); + } + + public void reset() { + Arrays.fill(slots, 0); + } + +} diff --git a/src/main/java/org/tron/common/utils/Utils.java b/src/main/java/org/tron/common/utils/Utils.java index 587f5666246..b273b48fe23 100755 --- a/src/main/java/org/tron/common/utils/Utils.java +++ b/src/main/java/org/tron/common/utils/Utils.java @@ -40,7 +40,7 @@ static byte[] getBytes(char[] chars) { return bb.array(); } - public static String getIdShort(String Id) { + static String getIdShort(String Id) { return Id == null ? "" : Id.substring(0, 8); } @@ -67,14 +67,14 @@ static String sizeToStr(long size) { return String.format("%dGb", size / (1L << 30)); } - public static String align(String s, char fillChar, int targetLen, boolean alignRight) { + static String align(String s, char fillChar, int targetLen, boolean alignRight) { if (targetLen <= s.length()) return s; String alignString = repeat("" + fillChar, targetLen - s.length()); return alignRight ? alignString + s : s + alignString; } - public static String repeat(String s, int n) { + static String repeat(String s, int n) { if (s.length() == 1) { byte[] bb = new byte[n]; Arrays.fill(bb, s.getBytes()[0]); diff --git a/src/main/java/org/tron/core/Constant.java b/src/main/java/org/tron/core/Constant.java index 94659c1a9fc..7020256d3bc 100644 --- a/src/main/java/org/tron/core/Constant.java +++ b/src/main/java/org/tron/core/Constant.java @@ -48,7 +48,13 @@ public class Constant { // config for smart contract public static final long MEM_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT = 32 * 1024 * 1024L; // 32MB - public static final long CPU_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT = 100000; // 100 ms = 100000 us + public static final long MAX_CPU_TIME_OF_ONE_TX_WHEN_VERIFY_BLOCK = 500000; // 500 ms = 500000 us + public static final long MAX_CPU_TIME_OF_ONE_TX = 100000; // 100 ms = 100000 us public static final long STORAGE_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT = 32 * 1024 * 1024L; // 32MB - public static final long CPU_IN_US_PER_TRX = 1000000 / 30; // 1 us <-> 30 SUN <-> 30 * 10^-6 TRX + public static final long SUN_PER_ENERGY = 100; // 1 us = 100 DROP = 100 * 10^-6 TRX + public static final long MAX_ENERGY_IN_TX = 3000000; // ref: 1 us = 1 energy + public static final long MAX_CONSUME_USER_RESOURCE_PERCENT = 100L; + public static final long MIN_CONSUME_USER_RESOURCE_PERCENT = 0L; + public static final long ACCORD_RANGE_PERCENT = 0L; + } diff --git a/src/main/java/org/tron/core/SpendableOutputs.java b/src/main/java/org/tron/core/SpendableOutputs.java deleted file mode 100644 index a8c83194c6d..00000000000 --- a/src/main/java/org/tron/core/SpendableOutputs.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.core; - -import java.util.HashMap; - -public class SpendableOutputs { - private long amount; - private HashMap unspentOutputs = null; - - public HashMap getUnspentOutputs() { - return unspentOutputs; - } - - public void setUnspentOutputs(HashMap unspentOutputs) { - this.unspentOutputs = unspentOutputs; - } - - public long getAmount() { - return amount; - } - - public void setAmount(long amount) { - this.amount = amount; - } -} diff --git a/src/main/java/org/tron/core/Wallet.java b/src/main/java/org/tron/core/Wallet.java index 56db2c0c244..3bb2ecd3a3c 100755 --- a/src/main/java/org/tron/core/Wallet.java +++ b/src/main/java/org/tron/core/Wallet.java @@ -18,6 +18,7 @@ package org.tron.core; +import com.google.common.primitives.Longs; import com.google.protobuf.ByteString; import java.util.Arrays; import java.util.HashMap; @@ -37,11 +38,14 @@ import org.tron.api.GrpcAPI.Address; import org.tron.api.GrpcAPI.AssetIssueList; import org.tron.api.GrpcAPI.BlockList; +import org.tron.api.GrpcAPI.ExchangeList; import org.tron.api.GrpcAPI.Node; import org.tron.api.GrpcAPI.NodeList; import org.tron.api.GrpcAPI.NumberMessage; import org.tron.api.GrpcAPI.ProposalList; +import org.tron.api.GrpcAPI.Return; import org.tron.api.GrpcAPI.Return.response_code; +import org.tron.api.GrpcAPI.TransactionExtention.Builder; import org.tron.api.GrpcAPI.WitnessList; import org.tron.common.crypto.ECKey; import org.tron.common.crypto.Hash; @@ -62,6 +66,7 @@ import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.ContractCapsule; +import org.tron.core.capsule.ExchangeCapsule; import org.tron.core.capsule.ProposalCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.TransactionResultCapsule; @@ -71,8 +76,8 @@ import org.tron.core.db.AccountStore; import org.tron.core.db.BandwidthProcessor; import org.tron.core.db.ContractStore; -import org.tron.core.db.CpuProcessor; import org.tron.core.db.DynamicPropertiesStore; +import org.tron.core.db.EnergyProcessor; import org.tron.core.db.Manager; import org.tron.core.db.PendingManager; import org.tron.core.exception.AccountResourceInsufficientException; @@ -94,6 +99,7 @@ import org.tron.protos.Protocol; import org.tron.protos.Protocol.Account; import org.tron.protos.Protocol.Block; +import org.tron.protos.Protocol.Exchange; import org.tron.protos.Protocol.Proposal; import org.tron.protos.Protocol.SmartContract; import org.tron.protos.Protocol.SmartContract.ABI; @@ -223,6 +229,25 @@ public static byte[] generateContractAddress(Transaction trx) { } + public static byte[] generateContractAddress(byte[] ownerAddress, byte[] txRawDataHash) { + + byte[] combined = new byte[txRawDataHash.length + ownerAddress.length]; + System.arraycopy(txRawDataHash, 0, combined, 0, txRawDataHash.length); + System.arraycopy(ownerAddress, 0, combined, txRawDataHash.length, ownerAddress.length); + + return Hash.sha3omit12(combined); + + } + + public static byte[] generateContractAddress(byte[] transactionRootId, long nonce) { + byte[] nonceBytes = Longs.toByteArray(nonce); + byte[] combined = new byte[transactionRootId.length + nonceBytes.length]; + System.arraycopy(transactionRootId, 0, combined, 0, transactionRootId.length); + System.arraycopy(nonceBytes, 0, combined, transactionRootId.length, nonceBytes.length); + + return Hash.sha3omit12(combined); + } + public static byte[] decodeFromBase58Check(String addressBase58) { if (StringUtils.isEmpty(addressBase58)) { logger.warn("Warning: Address is empty !!"); @@ -249,6 +274,10 @@ public Account getAccount(Account account) { } BandwidthProcessor processor = new BandwidthProcessor(dbManager); processor.updateUsage(accountCapsule); + + EnergyProcessor energyProcessor = new EnergyProcessor(dbManager); + energyProcessor.updateUsage(accountCapsule); + return accountCapsule.getInstance(); } @@ -265,6 +294,10 @@ public Account getAccountById(Account account) { } BandwidthProcessor processor = new BandwidthProcessor(dbManager); processor.updateUsage(accountCapsule); + + EnergyProcessor energyProcessor = new EnergyProcessor(dbManager); + energyProcessor.updateUsage(accountCapsule); + return accountCapsule.getInstance(); } @@ -289,10 +322,24 @@ public Transaction createTransaction(TransferContract contract) { public TransactionCapsule createTransactionCapsule(com.google.protobuf.Message message, ContractType contractType) throws ContractValidateException { TransactionCapsule trx = new TransactionCapsule(message, contractType); - List actList = ActuatorFactory.createActuator(trx, dbManager); - for (Actuator act : actList) { - act.validate(); + if (contractType != ContractType.CreateSmartContract + && contractType != ContractType.TriggerSmartContract) { + List actList = ActuatorFactory.createActuator(trx, dbManager); + for (Actuator act : actList) { + act.validate(); + } } + + if (contractType == ContractType.CreateSmartContract) { + + CreateSmartContract contract = ContractCapsule + .getSmartContractFromTransaction(trx.getInstance()); + long percent = contract.getNewContract().getConsumeUserResourcePercent(); + if (percent < 0 || percent > 100) { + throw new ContractValidateException("percent must be >= 0 and <= 100"); + } + } + try { BlockCapsule headBlock = null; List blockList = dbManager.getBlockStore().getBlockByLatestNum(1); @@ -341,8 +388,11 @@ public GrpcAPI.Return broadcastTransaction(Transaction signaturedTransaction) { dbManager.getTransactionIdCache().put(trx.getTransactionId(), true); } - dbManager.pushTransactions(trx); - p2pNode.broadcast(message); + if (dbManager.getForkController().forkOrNot(trx)) { + dbManager.pushTransaction(trx); + p2pNode.broadcast(message); + } + return builder.setResult(true).setCode(response_code.SUCCESS).build(); } catch (ValidateSignatureException e) { logger.info(e.getMessage()); @@ -443,6 +493,14 @@ public ProposalList getProposalList() { return builder.build(); } + public ExchangeList getExchangeList() { + ExchangeList.Builder builder = ExchangeList.newBuilder(); + List exchangeCapsuleList = dbManager.getExchangeStore().getAllExchanges(); + exchangeCapsuleList + .forEach(exchangeCapsule -> builder.addExchanges(exchangeCapsule.getInstance())); + return builder.build(); + } + public Protocol.ChainParameters getChainParameters() { Protocol.ChainParameters.Builder builder = Protocol.ChainParameters.newBuilder(); DynamicPropertiesStore dynamicPropertiesStore = dbManager.getDynamicPropertiesStore(); @@ -496,8 +554,15 @@ public Protocol.ChainParameters getChainParameters() { dynamicPropertiesStore.getCreateNewAccountBandwidthRate()) .build()); + builder.addChainParameter(builder1 + .setKey(ChainParameters.ALLOW_CREATION_OF_CONTRACTS.name()) + .setValue( + dynamicPropertiesStore.getAllowCreationOfContracts()) + .build()); + return builder.build(); } + public AssetIssueList getAssetIssueList() { AssetIssueList.Builder builder = AssetIssueList.newBuilder(); dbManager.getAssetIssueStore().getAllAssetIssues() @@ -582,16 +647,17 @@ public AccountResourceMessage getAccountResource(ByteString accountAddress) { BandwidthProcessor processor = new BandwidthProcessor(dbManager); processor.updateUsage(accountCapsule); - CpuProcessor cpuProcessor = new CpuProcessor(dbManager); - cpuProcessor.updateUsage(accountCapsule); + EnergyProcessor energyProcessor = new EnergyProcessor(dbManager); + energyProcessor.updateUsage(accountCapsule); long netLimit = processor.calculateGlobalNetLimit(accountCapsule.getFrozenBalance()); long freeNetLimit = dbManager.getDynamicPropertiesStore().getFreeNetLimit(); long totalNetLimit = dbManager.getDynamicPropertiesStore().getTotalNetLimit(); long totalNetWeight = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); - long cpuLimit = cpuProcessor.calculateGlobalCpuLimit(accountCapsule.getCpuFrozenBalance()); - long totalCpuLimit = dbManager.getDynamicPropertiesStore().getTotalCpuLimit(); - long totalCpuWeight = dbManager.getDynamicPropertiesStore().getTotalCpuWeight(); + long energyLimit = energyProcessor + .calculateGlobalEnergyLimit(accountCapsule.getEnergyFrozenBalance()); + long totalEnergyLimit = dbManager.getDynamicPropertiesStore().getTotalEnergyLimit(); + long totalEnergyWeight = dbManager.getDynamicPropertiesStore().getTotalEnergyWeight(); long storageLimit = accountCapsule.getAccountResource().getStorageLimit(); long storageUsage = accountCapsule.getAccountResource().getStorageUsage(); @@ -608,10 +674,10 @@ public AccountResourceMessage getAccountResource(ByteString accountAddress) { .setNetLimit(netLimit) .setTotalNetLimit(totalNetLimit) .setTotalNetWeight(totalNetWeight) - .setCpuLimit(cpuLimit) - .setCpuUsed(accountCapsule.getAccountResource().getCpuUsage()) - .setTotalCpuLimit(totalCpuLimit) - .setTotalCpuWeight(totalCpuWeight) + .setEnergyLimit(energyLimit) + .setEnergyUsed(accountCapsule.getAccountResource().getEnergyUsage()) + .setTotalEnergyLimit(totalEnergyLimit) + .setTotalEnergyWeight(totalEnergyWeight) .setStorageLimit(storageLimit) .setStorageUsed(storageUsage) .putAllAssetNetUsed(accountCapsule.getAllFreeAssetNetUsage()) @@ -701,6 +767,22 @@ public Proposal getProposalById(ByteString proposalId) { return null; } + public Exchange getExchangeById(ByteString exchangeId) { + if (Objects.isNull(exchangeId)) { + return null; + } + ExchangeCapsule exchangeCapsule = null; + try { + exchangeCapsule = dbManager.getExchangeStore() + .get(exchangeId.toByteArray()); + } catch (StoreException e) { + } + if (exchangeCapsule != null) { + return exchangeCapsule.getInstance(); + } + return null; + } + public NodeList listNodes() { List handlerList = nodeManager.dumpActiveNodes(); @@ -733,18 +815,21 @@ public Transaction deployContract(CreateSmartContract createSmartContract, } public Transaction triggerContract(TriggerSmartContract triggerSmartContract, - TransactionCapsule trxCap) { + TransactionCapsule trxCap, Builder builder, + Return.Builder retBuilder) { ContractStore contractStore = dbManager.getContractStore(); byte[] contractAddress = triggerSmartContract.getContractAddress().toByteArray(); SmartContract.ABI abi = contractStore.getABI(contractAddress); if (abi == null) { + // FIXME return null; } try { byte[] selector = getSelector(triggerSmartContract.getData().toByteArray()); if (selector == null) { + // FIXME return null; } @@ -752,19 +837,36 @@ public Transaction triggerContract(TriggerSmartContract triggerSmartContract, return trxCap.getInstance(); } else { DepositImpl deposit = DepositImpl.createRoot(dbManager); - Runtime runtime = new Runtime(trxCap.getInstance(), deposit, + + Block headBlock; + List blockCapsuleList = dbManager.getBlockStore().getBlockByLatestNum(1); + if (CollectionUtils.isEmpty(blockCapsuleList)) { + throw new HeaderNotFound("latest block not found"); + } else { + headBlock = blockCapsuleList.get(0).getInstance(); + } + + Runtime runtime = new Runtime(trxCap.getInstance(), headBlock, deposit, new ProgramInvokeFactoryImpl()); runtime.init(); runtime.execute(); runtime.go(); + runtime.finalization(); + // TODO exception if (runtime.getResult().getException() != null) { +// runtime.getResult().getException().printStackTrace(); throw new RuntimeException("Runtime exe failed!"); } ProgramResult result = runtime.getResult(); TransactionResultCapsule ret = new TransactionResultCapsule(); - ret.setConstantResult(result.getHReturn()); + + builder.addConstantResult(ByteString.copyFrom(result.getHReturn())); ret.setStatus(0, code.SUCESS); + if (StringUtils.isNoneEmpty(runtime.getRuntimeError())) { + ret.setStatus(0, code.FAILED); + retBuilder.setMessage(ByteString.copyFromUtf8(runtime.getRuntimeError())).build(); + } trxCap.setResult(ret); return trxCap.getInstance(); } @@ -785,7 +887,10 @@ public SmartContract getContract(GrpcAPI.BytesMessage bytesMessage) { ContractCapsule contractCapsule = dbManager.getContractStore() .get(bytesMessage.getValue().toByteArray()); - return contractCapsule.getInstance(); + if (Objects.nonNull(contractCapsule)) { + return contractCapsule.getInstance(); + } + return null; } private static byte[] getSelector(byte[] data) { @@ -800,6 +905,10 @@ private static byte[] getSelector(byte[] data) { } private static boolean isConstant(SmartContract.ABI abi, byte[] selector) throws Exception { + + if (abi.getEntrysList().size() == 0) { + return false; + } if (selector == null || selector.length != 4) { throw new Exception("Selector's length or selector itself is invalid"); } @@ -812,11 +921,11 @@ private static boolean isConstant(SmartContract.ABI abi, byte[] selector) throws int inputCount = entry.getInputsCount(); StringBuffer sb = new StringBuffer(); - sb.append(entry.getName().toStringUtf8()); + sb.append(entry.getName()); sb.append("("); for (int k = 0; k < inputCount; k++) { ABI.Entry.Param param = entry.getInputs(k); - sb.append(param.getType().toStringUtf8()); + sb.append(param.getType()); if (k + 1 < inputCount) { sb.append(","); } diff --git a/src/main/java/org/tron/core/actuator/ActuatorFactory.java b/src/main/java/org/tron/core/actuator/ActuatorFactory.java index b0280e87f78..f545e8efd86 100644 --- a/src/main/java/org/tron/core/actuator/ActuatorFactory.java +++ b/src/main/java/org/tron/core/actuator/ActuatorFactory.java @@ -59,8 +59,6 @@ private static Actuator getActuatorByContract(Contract contract, Manager manager return new AssetIssueActuator(contract.getParameter(), manager); case UnfreezeAssetContract: return new UnfreezeAssetActuator(contract.getParameter(), manager); - case CreateSmartContract: - break; case WitnessUpdateContract: return new WitnessUpdateActuator(contract.getParameter(), manager); case ParticipateAssetIssueContract: @@ -81,11 +79,24 @@ private static Actuator getActuatorByContract(Contract contract, Manager manager return new ProposalDeleteActuator(contract.getParameter(), manager); case SetAccountIdContract: return new SetAccountIdActuator(contract.getParameter(), manager); - case BuyStorageContract: - return new BuyStorageActuator(contract.getParameter(), manager); - case SellStorageContract: - return new SellStorageActuator(contract.getParameter(), manager); +// case BuyStorageContract: +// return new BuyStorageActuator(contract.getParameter(), manager); +// case BuyStorageBytesContract: +// return new BuyStorageBytesActuator(contract.getParameter(), manager); +// case SellStorageContract: +// return new SellStorageActuator(contract.getParameter(), manager); + case UpdateSettingContract: + return new UpdateSettingContractActuator(contract.getParameter(), manager); + case ExchangeCreateContract: + return new ExchangeCreateActuator(contract.getParameter(), manager); + case ExchangeInjectContract: + return new ExchangeInjectActuator(contract.getParameter(), manager); + case ExchangeWithdrawContract: + return new ExchangeWithdrawActuator(contract.getParameter(), manager); + case ExchangeTransactionContract: + return new ExchangeTransactionActuator(contract.getParameter(), manager); default: + break; } return null; diff --git a/src/main/java/org/tron/core/actuator/BuyStorageActuator.java b/src/main/java/org/tron/core/actuator/BuyStorageActuator.java index c8815bc11c2..9a14364b20c 100755 --- a/src/main/java/org/tron/core/actuator/BuyStorageActuator.java +++ b/src/main/java/org/tron/core/actuator/BuyStorageActuator.java @@ -94,6 +94,11 @@ public boolean validate() throws ContractValidateException { if (quant > accountCapsule.getBalance()) { throw new ContractValidateException("quantity must be less than accountBalance"); } + long storage_bytes = storageMarket.tryBuyStorage(quant); + if (storage_bytes < 1L) { + throw new ContractValidateException( + "storage_bytes must be larger than 1,current storage_bytes[" + storage_bytes + "]"); + } // long storageBytes = storageMarket.exchange(quant, true); // if (storageBytes > dbManager.getDynamicPropertiesStore().getTotalStorageReserved()) { diff --git a/src/main/java/org/tron/core/actuator/BuyStorageBytesActuator.java b/src/main/java/org/tron/core/actuator/BuyStorageBytesActuator.java new file mode 100755 index 00000000000..ccff0b9dc62 --- /dev/null +++ b/src/main/java/org/tron/core/actuator/BuyStorageBytesActuator.java @@ -0,0 +1,123 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.utils.StringUtil; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.db.Manager; +import org.tron.core.db.StorageMarket; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.protos.Contract.BuyStorageBytesContract; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j +public class BuyStorageBytesActuator extends AbstractActuator { + + private StorageMarket storageMarket; + + BuyStorageBytesActuator(Any contract, Manager dbManager) { + super(contract, dbManager); + storageMarket = new StorageMarket(dbManager); + } + + @Override + public boolean execute(TransactionResultCapsule ret) throws ContractExeException { + long fee = calcFee(); + final BuyStorageBytesContract BuyStorageBytesContract; + try { + BuyStorageBytesContract = contract.unpack(BuyStorageBytesContract.class); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } + + AccountCapsule accountCapsule = dbManager.getAccountStore() + .get(BuyStorageBytesContract.getOwnerAddress().toByteArray()); + long bytes = BuyStorageBytesContract.getBytes(); + + storageMarket.buyStorageBytes(accountCapsule, bytes); + + ret.setStatus(fee, code.SUCESS); + + return true; + } + + + @Override + public boolean validate() throws ContractValidateException { + if (this.contract == null) { + throw new ContractValidateException("No contract!"); + } + if (this.dbManager == null) { + throw new ContractValidateException("No dbManager!"); + } + if (!contract.is(BuyStorageBytesContract.class)) { + throw new ContractValidateException( + "contract type error,expected type [BuyStorageBytesContract],real type[" + contract + .getClass() + "]"); + } + + final BuyStorageBytesContract BuyStorageBytesContract; + try { + BuyStorageBytesContract = this.contract.unpack(BuyStorageBytesContract.class); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + throw new ContractValidateException(e.getMessage()); + } + byte[] ownerAddress = BuyStorageBytesContract.getOwnerAddress().toByteArray(); + if (!Wallet.addressValid(ownerAddress)) { + throw new ContractValidateException("Invalid address"); + } + + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + if (accountCapsule == null) { + String readableOwnerAddress = StringUtil.createReadableString(ownerAddress); + throw new ContractValidateException( + "Account[" + readableOwnerAddress + "] not exists"); + } + + long bytes = BuyStorageBytesContract.getBytes(); + if (bytes < 0) { + throw new ContractValidateException("bytes must be positive"); + } + + if (bytes < 1L) { + throw new ContractValidateException( + "bytes must be larger than 1, current storage_bytes[" + bytes + "]"); + } + + long quant = storageMarket.tryBuyStorageBytes(bytes); + + if (quant < 1_000_000L) { + throw new ContractValidateException("quantity must be larger than 1TRX"); + } + + if (quant > accountCapsule.getBalance()) { + throw new ContractValidateException("quantity must be less than accountBalance"); + } + +// long storageBytes = storageMarket.exchange(quant, true); +// if (storageBytes > dbManager.getDynamicPropertiesStore().getTotalStorageReserved()) { +// throw new ContractValidateException("storage is not enough"); +// } + + return true; + } + + @Override + public ByteString getOwnerAddress() throws InvalidProtocolBufferException { + return contract.unpack(BuyStorageBytesContract.class).getOwnerAddress(); + } + + @Override + public long calcFee() { + return 0; + } + +} diff --git a/src/main/java/org/tron/core/actuator/CreateAccountActuator.java b/src/main/java/org/tron/core/actuator/CreateAccountActuator.java index 48dbf0385a0..06958ac51b5 100755 --- a/src/main/java/org/tron/core/actuator/CreateAccountActuator.java +++ b/src/main/java/org/tron/core/actuator/CreateAccountActuator.java @@ -39,7 +39,7 @@ public boolean execute(TransactionResultCapsule ret) logger.debug(e.getMessage(), e); ret.setStatus(fee, code.FAILED); throw new ContractExeException(e.getMessage()); - }catch (InvalidProtocolBufferException e) { + } catch (InvalidProtocolBufferException e) { logger.debug(e.getMessage(), e); ret.setStatus(fee, code.FAILED); throw new ContractExeException(e.getMessage()); diff --git a/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java b/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java new file mode 100755 index 00000000000..7f31961519c --- /dev/null +++ b/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java @@ -0,0 +1,173 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.utils.StringUtil; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.config.Parameter.ChainParameters; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.protos.Contract.ExchangeCreateContract; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j +public class ExchangeCreateActuator extends AbstractActuator { + + ExchangeCreateActuator(final Any contract, final Manager dbManager) { + super(contract, dbManager); + } + + @Override + public boolean execute(TransactionResultCapsule ret) throws ContractExeException { + long fee = calcFee(); + try { + final ExchangeCreateContract exchangeCreateContract = this.contract + .unpack(ExchangeCreateContract.class); + AccountCapsule accountCapsule = dbManager.getAccountStore() + .get(exchangeCreateContract.getOwnerAddress().toByteArray()); + + byte[] firstTokenID = exchangeCreateContract.getFirstTokenId().toByteArray(); + byte[] secondTokenID = exchangeCreateContract.getSecondTokenId().toByteArray(); + long firstTokenBalance = exchangeCreateContract.getFirstTokenBalance(); + long secondTokenBalance = exchangeCreateContract.getSecondTokenBalance(); + + long newBalance = accountCapsule.getBalance() - calcFee(); + + if (firstTokenID == "_".getBytes()) { + accountCapsule.setBalance(newBalance - firstTokenBalance); + } else { + accountCapsule.reduceAssetAmount(firstTokenID, firstTokenBalance); + } + + if (secondTokenID == "_".getBytes()) { + accountCapsule.setBalance(newBalance - secondTokenBalance); + } else { + accountCapsule.reduceAssetAmount(secondTokenID, secondTokenBalance); + } + + long id = dbManager.getDynamicPropertiesStore().getLatestExchangeNum() + 1; + long now = dbManager.getHeadBlockTimeStamp(); + ExchangeCapsule exchangeCapsule = + new ExchangeCapsule( + exchangeCreateContract.getOwnerAddress(), + id, + now, + firstTokenID, + secondTokenID + ); + + exchangeCapsule.setBalance(firstTokenBalance, secondTokenBalance); + + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + dbManager.getExchangeStore().put(exchangeCapsule.createDbKey(), exchangeCapsule); + dbManager.getDynamicPropertiesStore().saveLatestExchangeNum(id); + + ret.setStatus(fee, code.SUCESS); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } + return true; + } + + @Override + public boolean validate() throws ContractValidateException { + if (this.contract == null) { + throw new ContractValidateException("No contract!"); + } + if (this.dbManager == null) { + throw new ContractValidateException("No dbManager!"); + } + if (!this.contract.is(ExchangeCreateContract.class)) { + throw new ContractValidateException( + "contract type error,expected type [ExchangeCreateContract],real type[" + contract + .getClass() + "]"); + } + final ExchangeCreateContract contract; + try { + contract = this.contract.unpack(ExchangeCreateContract.class); + } catch (InvalidProtocolBufferException e) { + throw new ContractValidateException(e.getMessage()); + } + + byte[] ownerAddress = contract.getOwnerAddress().toByteArray(); + String readableOwnerAddress = StringUtil.createReadableString(ownerAddress); + + if (!Wallet.addressValid(ownerAddress)) { + throw new ContractValidateException("Invalid address"); + } + + if (!this.dbManager.getAccountStore().has(ownerAddress)) { + throw new ContractValidateException("account[" + readableOwnerAddress + "] not exists"); + } + + AccountCapsule accountCapsule = this.dbManager.getAccountStore().get(ownerAddress); + + if (accountCapsule.getBalance() < calcFee()) { + throw new ContractValidateException("No enough balance for exchange create fee!"); + } + + byte[] firstTokenID = contract.getFirstTokenId().toByteArray(); + byte[] secondTokenID = contract.getSecondTokenId().toByteArray(); + long firstTokenBalance = contract.getFirstTokenBalance(); + long secondTokenBalance = contract.getSecondTokenBalance(); + + if (firstTokenID == secondTokenID) { + throw new ContractValidateException("cannot exchange same tokens"); + } + + if (firstTokenBalance <= 0 || secondTokenBalance <= 0) { + throw new ContractValidateException("token balance must greater than zero"); + } + + long balanceLimit = dbManager.getDynamicPropertiesStore().getExchangeBalanceLimit(); + if (firstTokenBalance > balanceLimit || secondTokenBalance > balanceLimit) { + throw new ContractValidateException("token balance must less than " + balanceLimit); + } + + if (firstTokenID == "_".getBytes()) { + if (accountCapsule.getBalance() < (firstTokenBalance + calcFee())) { + throw new ContractValidateException("balance is not enough"); + } + } else { + if (!accountCapsule.assetBalanceEnough(firstTokenID, firstTokenBalance)) { + throw new ContractValidateException("first token balance is not enough"); + } + } + + if (secondTokenID == "_".getBytes()) { + if (accountCapsule.getBalance() < (secondTokenBalance + calcFee())) { + throw new ContractValidateException("balance is not enough"); + } + } else { + if (!accountCapsule.assetBalanceEnough(secondTokenID, secondTokenBalance)) { + throw new ContractValidateException("second token balance is not enough"); + } + } + + return true; + } + + + @Override + public ByteString getOwnerAddress() throws InvalidProtocolBufferException { + return contract.unpack(ExchangeCreateContract.class).getOwnerAddress(); + } + + @Override + public long calcFee() { + return dbManager.getDynamicPropertiesStore().getExchangeCreateFee(); + } + + private boolean validKey(long idx) { + return idx >= 0 && idx < ChainParameters.values().length; + } + +} diff --git a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java new file mode 100755 index 00000000000..24b97b11e3b --- /dev/null +++ b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java @@ -0,0 +1,232 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.StringUtil; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.config.Parameter.ChainParameters; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.protos.Contract.ExchangeInjectContract; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j +public class ExchangeInjectActuator extends AbstractActuator { + + ExchangeInjectActuator(final Any contract, final Manager dbManager) { + super(contract, dbManager); + } + + @Override + public boolean execute(TransactionResultCapsule ret) throws ContractExeException { + long fee = calcFee(); + try { + final ExchangeInjectContract exchangeInjectContract = this.contract + .unpack(ExchangeInjectContract.class); + AccountCapsule accountCapsule = dbManager.getAccountStore() + .get(exchangeInjectContract.getOwnerAddress().toByteArray()); + + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore(). + get(ByteArray.fromLong(exchangeInjectContract.getExchangeId())); + + byte[] firstTokenID = exchangeCapsule.getFirstTokenId(); + byte[] secondTokenID = exchangeCapsule.getSecondTokenId(); + long firstTokenBalance = exchangeCapsule.getFirstTokenBalance(); + long secondTokenBalance = exchangeCapsule.getSecondTokenBalance(); + + byte[] tokenID = exchangeInjectContract.getTokenId().toByteArray(); + long tokenQuant = exchangeInjectContract.getQuant(); + + byte[] anotherTokenID; + long anotherTokenQuant; + + if (Arrays.equals(tokenID, firstTokenID)) { + anotherTokenID = secondTokenID; + anotherTokenQuant = Math + .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); + exchangeCapsule.setBalance(firstTokenBalance + tokenQuant, + secondTokenBalance + anotherTokenQuant); + } else { + anotherTokenID = firstTokenID; + anotherTokenQuant = Math + .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); + exchangeCapsule.setBalance(firstTokenBalance + anotherTokenQuant, + secondTokenBalance + tokenQuant); + } + + long newBalance = accountCapsule.getBalance() - calcFee(); + + if (tokenID == "_".getBytes()) { + accountCapsule.setBalance(newBalance - tokenQuant); + } else { + accountCapsule.reduceAssetAmount(tokenID, tokenQuant); + } + + if (anotherTokenID == "_".getBytes()) { + accountCapsule.setBalance(newBalance - anotherTokenQuant); + } else { + accountCapsule.reduceAssetAmount(anotherTokenID, anotherTokenQuant); + } + + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + dbManager.getExchangeStore().put(exchangeCapsule.createDbKey(), exchangeCapsule); + + ret.setStatus(fee, code.SUCESS); + } catch (ItemNotFoundException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } + return true; + } + + + @Override + public boolean validate() throws ContractValidateException { + if (this.contract == null) { + throw new ContractValidateException("No contract!"); + } + if (this.dbManager == null) { + throw new ContractValidateException("No dbManager!"); + } + if (!this.contract.is(ExchangeInjectContract.class)) { + throw new ContractValidateException( + "contract type error,expected type [ExchangeInjectContract],real type[" + contract + .getClass() + "]"); + } + final ExchangeInjectContract contract; + try { + contract = this.contract.unpack(ExchangeInjectContract.class); + } catch (InvalidProtocolBufferException e) { + throw new ContractValidateException(e.getMessage()); + } + + byte[] ownerAddress = contract.getOwnerAddress().toByteArray(); + String readableOwnerAddress = StringUtil.createReadableString(ownerAddress); + + if (!Wallet.addressValid(ownerAddress)) { + throw new ContractValidateException("Invalid address"); + } + + if (!this.dbManager.getAccountStore().has(ownerAddress)) { + throw new ContractValidateException("account[" + readableOwnerAddress + "] not exists"); + } + + AccountCapsule accountCapsule = this.dbManager.getAccountStore().get(ownerAddress); + + if (accountCapsule.getBalance() < calcFee()) { + throw new ContractValidateException("No enough balance for exchange inject fee!"); + } + + ExchangeCapsule exchangeCapsule; + try { + exchangeCapsule = dbManager.getExchangeStore(). + get(ByteArray.fromLong(contract.getExchangeId())); + } catch (ItemNotFoundException ex) { + throw new ContractValidateException("Exchange[" + contract.getExchangeId() + "] not exists"); + } + + if (!accountCapsule.getAddress().equals(exchangeCapsule.getCreatorAddress())) { + throw new ContractValidateException("account[" + readableOwnerAddress + "] is not creator"); + } + + byte[] firstTokenID = exchangeCapsule.getFirstTokenId(); + byte[] secondTokenID = exchangeCapsule.getSecondTokenId(); + long firstTokenBalance = exchangeCapsule.getFirstTokenBalance(); + long secondTokenBalance = exchangeCapsule.getSecondTokenBalance(); + + byte[] tokenID = contract.getTokenId().toByteArray(); + long tokenQuant = contract.getQuant(); + + byte[] anotherTokenID; + long anotherTokenQuant; + + if (!Arrays.equals(tokenID, firstTokenID) && !Arrays.equals(tokenID, secondTokenID)) { + throw new ContractValidateException("token is not in exchange"); + } + + if (firstTokenBalance == 0 || secondTokenBalance == 0) { + throw new ContractValidateException("Token balance in exchange is equal with 0," + + "the exchange has been closed"); + } + + if (tokenQuant <= 0) { + throw new ContractValidateException("injected token balance must greater than zero"); + } + + long newTokenBalance, newAnotherTokenBalance; + if (Arrays.equals(tokenID, firstTokenID)) { + anotherTokenID = secondTokenID; + anotherTokenQuant = Math + .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); + newTokenBalance = firstTokenBalance + tokenQuant; + newAnotherTokenBalance = secondTokenBalance + anotherTokenQuant; + } else { + anotherTokenID = firstTokenID; + anotherTokenQuant = Math + .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); + newTokenBalance = secondTokenBalance + tokenQuant; + newAnotherTokenBalance = firstTokenBalance + anotherTokenQuant; + } + + if (anotherTokenQuant <= 0) { + throw new ContractValidateException(" The calculated Token Quant must be larger than 0"); + } + + long balanceLimit = dbManager.getDynamicPropertiesStore().getExchangeBalanceLimit(); + if (newTokenBalance > balanceLimit || newAnotherTokenBalance > balanceLimit) { + throw new ContractValidateException("token balance must less than " + balanceLimit); + } + + if (tokenID == "_".getBytes()) { + if (accountCapsule.getBalance() < (tokenQuant + calcFee())) { + throw new ContractValidateException("balance is not enough"); + } + } else { + if (!accountCapsule.assetBalanceEnough(tokenID, tokenQuant)) { + throw new ContractValidateException("token balance is not enough"); + } + } + + if (anotherTokenID == "_".getBytes()) { + if (accountCapsule.getBalance() < (anotherTokenQuant + calcFee())) { + throw new ContractValidateException("balance is not enough"); + } + } else { + if (!accountCapsule.assetBalanceEnough(anotherTokenID, anotherTokenQuant)) { + throw new ContractValidateException("another token balance is not enough"); + } + } + + return true; + } + + + @Override + public ByteString getOwnerAddress() throws InvalidProtocolBufferException { + return contract.unpack(ExchangeInjectContract.class).getOwnerAddress(); + } + + @Override + public long calcFee() { + return 0; + } + + private boolean validKey(long idx) { + return idx >= 0 && idx < ChainParameters.values().length; + } + +} diff --git a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java new file mode 100755 index 00000000000..3361ca973d3 --- /dev/null +++ b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java @@ -0,0 +1,188 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.StringUtil; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.config.Parameter.ChainParameters; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.protos.Contract.ExchangeTransactionContract; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j +public class ExchangeTransactionActuator extends AbstractActuator { + + ExchangeTransactionActuator(final Any contract, final Manager dbManager) { + super(contract, dbManager); + } + + @Override + public boolean execute(TransactionResultCapsule ret) throws ContractExeException { + long fee = calcFee(); + try { + final ExchangeTransactionContract exchangeTransactionContract = this.contract + .unpack(ExchangeTransactionContract.class); + AccountCapsule accountCapsule = dbManager.getAccountStore() + .get(exchangeTransactionContract.getOwnerAddress().toByteArray()); + + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore(). + get(ByteArray.fromLong(exchangeTransactionContract.getExchangeId())); + + byte[] firstTokenID = exchangeCapsule.getFirstTokenId(); + byte[] secondTokenID = exchangeCapsule.getSecondTokenId(); + + byte[] tokenID = exchangeTransactionContract.getTokenId().toByteArray(); + long tokenQuant = exchangeTransactionContract.getQuant(); + + byte[] anotherTokenID; + long anotherTokenQuant = exchangeCapsule.transaction(tokenID, tokenQuant); + + if (Arrays.equals(tokenID, firstTokenID)) { + anotherTokenID = secondTokenID; + } else { + anotherTokenID = firstTokenID; + } + + long newBalance = accountCapsule.getBalance() - calcFee(); + + if (tokenID == "_".getBytes()) { + accountCapsule.setBalance(newBalance - tokenQuant); + } else { + accountCapsule.reduceAssetAmount(tokenID, tokenQuant); + } + + if (anotherTokenID == "_".getBytes()) { + accountCapsule.setBalance(newBalance + anotherTokenQuant); + } else { + accountCapsule.addAssetAmount(anotherTokenID, anotherTokenQuant); + } + + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + dbManager.getExchangeStore().put(exchangeCapsule.createDbKey(), exchangeCapsule); + + ret.setStatus(fee, code.SUCESS); + } catch (ItemNotFoundException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } + return true; + } + + + @Override + public boolean validate() throws ContractValidateException { + if (this.contract == null) { + throw new ContractValidateException("No contract!"); + } + if (this.dbManager == null) { + throw new ContractValidateException("No dbManager!"); + } + if (!this.contract.is(ExchangeTransactionContract.class)) { + throw new ContractValidateException( + "contract type error,expected type [ExchangeTransactionContract],real type[" + contract + .getClass() + "]"); + } + final ExchangeTransactionContract contract; + try { + contract = this.contract.unpack(ExchangeTransactionContract.class); + } catch (InvalidProtocolBufferException e) { + throw new ContractValidateException(e.getMessage()); + } + + byte[] ownerAddress = contract.getOwnerAddress().toByteArray(); + String readableOwnerAddress = StringUtil.createReadableString(ownerAddress); + + if (!Wallet.addressValid(ownerAddress)) { + throw new ContractValidateException("Invalid address"); + } + + if (!this.dbManager.getAccountStore().has(ownerAddress)) { + throw new ContractValidateException("account[" + readableOwnerAddress + "] not exists"); + } + + AccountCapsule accountCapsule = this.dbManager.getAccountStore().get(ownerAddress); + + if (accountCapsule.getBalance() < calcFee()) { + throw new ContractValidateException("No enough balance for exchange transaction fee!"); + } + + ExchangeCapsule exchangeCapsule; + try { + exchangeCapsule = dbManager.getExchangeStore(). + get(ByteArray.fromLong(contract.getExchangeId())); + } catch (ItemNotFoundException ex) { + throw new ContractValidateException("Exchange[" + contract.getExchangeId() + "] not exists"); + } + + byte[] firstTokenID = exchangeCapsule.getFirstTokenId(); + byte[] secondTokenID = exchangeCapsule.getSecondTokenId(); + long firstTokenBalance = exchangeCapsule.getFirstTokenBalance(); + long secondTokenBalance = exchangeCapsule.getSecondTokenBalance(); + + byte[] tokenID = contract.getTokenId().toByteArray(); + long tokenQuant = contract.getQuant(); + + if (!Arrays.equals(tokenID, firstTokenID) && !Arrays.equals(tokenID, secondTokenID)) { + throw new ContractValidateException("token is not in exchange"); + } + + if (tokenQuant <= 0) { + throw new ContractValidateException("transaction token balance must greater than zero"); + } + + long balanceLimit = dbManager.getDynamicPropertiesStore().getExchangeBalanceLimit(); + long tokenBalance = (tokenID == firstTokenID ? firstTokenBalance : secondTokenBalance); + tokenBalance += tokenQuant; + if (tokenBalance > balanceLimit) { + throw new ContractValidateException("token balance must less than " + balanceLimit); + } + + if (tokenID == "_".getBytes()) { + if (accountCapsule.getBalance() < (tokenQuant + calcFee())) { + throw new ContractValidateException("balance is not enough"); + } + } else { + if (!accountCapsule.assetBalanceEnough(tokenID, tokenQuant)) { + throw new ContractValidateException("token balance is not enough"); + } + } + + long anotherTokenQuant = exchangeCapsule.transaction(tokenID, tokenQuant); + if (anotherTokenQuant < 1) { + throw new ContractValidateException("token quant is not enough to buy 1 another token"); + } + + return true; + } + + + @Override + public ByteString getOwnerAddress() throws InvalidProtocolBufferException { + return contract.unpack(ExchangeTransactionContract.class).getOwnerAddress(); + } + + @Override + public long calcFee() { + return 0; + } + + private boolean validKey(long idx) { + return idx >= 0 && idx < ChainParameters.values().length; + } + +} diff --git a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java new file mode 100755 index 00000000000..301931445cd --- /dev/null +++ b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java @@ -0,0 +1,200 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.StringUtil; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.config.Parameter.ChainParameters; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.protos.Contract.ExchangeWithdrawContract; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j +public class ExchangeWithdrawActuator extends AbstractActuator { + + ExchangeWithdrawActuator(final Any contract, final Manager dbManager) { + super(contract, dbManager); + } + + @Override + public boolean execute(TransactionResultCapsule ret) throws ContractExeException { + long fee = calcFee(); + try { + final ExchangeWithdrawContract exchangeWithdrawContract = this.contract + .unpack(ExchangeWithdrawContract.class); + AccountCapsule accountCapsule = dbManager.getAccountStore() + .get(exchangeWithdrawContract.getOwnerAddress().toByteArray()); + + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore(). + get(ByteArray.fromLong(exchangeWithdrawContract.getExchangeId())); + + byte[] firstTokenID = exchangeCapsule.getFirstTokenId(); + byte[] secondTokenID = exchangeCapsule.getSecondTokenId(); + long firstTokenBalance = exchangeCapsule.getFirstTokenBalance(); + long secondTokenBalance = exchangeCapsule.getSecondTokenBalance(); + + byte[] tokenID = exchangeWithdrawContract.getTokenId().toByteArray(); + long tokenQuant = exchangeWithdrawContract.getQuant(); + + byte[] anotherTokenID; + long anotherTokenQuant; + + if (Arrays.equals(tokenID, firstTokenID)) { + anotherTokenID = secondTokenID; + anotherTokenQuant = Math + .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); + exchangeCapsule.setBalance(firstTokenBalance - tokenQuant, + secondTokenBalance - anotherTokenQuant); + } else { + anotherTokenID = firstTokenID; + anotherTokenQuant = Math + .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); + exchangeCapsule.setBalance(firstTokenBalance - anotherTokenQuant, + secondTokenBalance - tokenQuant); + } + + long newBalance = accountCapsule.getBalance() - calcFee(); + + if (tokenID == "_".getBytes()) { + accountCapsule.setBalance(newBalance + tokenQuant); + } else { + accountCapsule.addAssetAmount(tokenID, tokenQuant); + } + + if (anotherTokenID == "_".getBytes()) { + accountCapsule.setBalance(newBalance + anotherTokenQuant); + } else { + accountCapsule.addAssetAmount(anotherTokenID, anotherTokenQuant); + } + + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + dbManager.getExchangeStore().put(exchangeCapsule.createDbKey(), exchangeCapsule); + + ret.setStatus(fee, code.SUCESS); + } catch (ItemNotFoundException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } + return true; + } + + + @Override + public boolean validate() throws ContractValidateException { + if (this.contract == null) { + throw new ContractValidateException("No contract!"); + } + if (this.dbManager == null) { + throw new ContractValidateException("No dbManager!"); + } + if (!this.contract.is(ExchangeWithdrawContract.class)) { + throw new ContractValidateException( + "contract type error,expected type [ExchangeWithdrawContract],real type[" + contract + .getClass() + "]"); + } + final ExchangeWithdrawContract contract; + try { + contract = this.contract.unpack(ExchangeWithdrawContract.class); + } catch (InvalidProtocolBufferException e) { + throw new ContractValidateException(e.getMessage()); + } + + byte[] ownerAddress = contract.getOwnerAddress().toByteArray(); + String readableOwnerAddress = StringUtil.createReadableString(ownerAddress); + + if (!Wallet.addressValid(ownerAddress)) { + throw new ContractValidateException("Invalid address"); + } + + if (!this.dbManager.getAccountStore().has(ownerAddress)) { + throw new ContractValidateException("account[" + readableOwnerAddress + "] not exists"); + } + + AccountCapsule accountCapsule = this.dbManager.getAccountStore().get(ownerAddress); + + if (accountCapsule.getBalance() < calcFee()) { + throw new ContractValidateException("No enough balance for exchange withdraw fee!"); + } + + ExchangeCapsule exchangeCapsule; + try { + exchangeCapsule = dbManager.getExchangeStore(). + get(ByteArray.fromLong(contract.getExchangeId())); + } catch (ItemNotFoundException ex) { + throw new ContractValidateException("Exchange[" + contract.getExchangeId() + "] not exists"); + } + + if (!accountCapsule.getAddress().equals(exchangeCapsule.getCreatorAddress())) { + throw new ContractValidateException("account[" + readableOwnerAddress + "] is not creator"); + } + + byte[] firstTokenID = exchangeCapsule.getFirstTokenId(); + byte[] secondTokenID = exchangeCapsule.getSecondTokenId(); + long firstTokenBalance = exchangeCapsule.getFirstTokenBalance(); + long secondTokenBalance = exchangeCapsule.getSecondTokenBalance(); + + byte[] tokenID = contract.getTokenId().toByteArray(); + long tokenQuant = contract.getQuant(); + + long anotherTokenQuant; + + if (!Arrays.equals(tokenID, firstTokenID) && !Arrays.equals(tokenID, secondTokenID)) { + throw new ContractValidateException("token is not in exchange"); + } + + if (tokenQuant <= 0) { + throw new ContractValidateException("withdraw token balance must greater than zero"); + } + + if (firstTokenBalance == 0 || secondTokenBalance == 0) { + throw new ContractValidateException("Token balance in exchange is equal with 0,the exchange has been closed"); + } + + if (Arrays.equals(tokenID, firstTokenID)) { + anotherTokenQuant = Math + .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); + if (firstTokenBalance < tokenQuant || secondTokenBalance < anotherTokenQuant) { + throw new ContractValidateException("exchange balance is not enough"); + } + } else { + anotherTokenQuant = Math + .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); + if (secondTokenBalance < tokenQuant || firstTokenBalance < anotherTokenQuant) { + throw new ContractValidateException("exchange balance is not enough"); + } + } + + return true; + } + + + @Override + public ByteString getOwnerAddress() throws InvalidProtocolBufferException { + return contract.unpack(ExchangeWithdrawContract.class).getOwnerAddress(); + } + + @Override + public long calcFee() { + return 0; + } + + private boolean validKey(long idx) { + return idx >= 0 && idx < ChainParameters.values().length; + } + +} diff --git a/src/main/java/org/tron/core/actuator/FreezeBalanceActuator.java b/src/main/java/org/tron/core/actuator/FreezeBalanceActuator.java index 82e02da2e3f..fd54ac1df3c 100755 --- a/src/main/java/org/tron/core/actuator/FreezeBalanceActuator.java +++ b/src/main/java/org/tron/core/actuator/FreezeBalanceActuator.java @@ -12,7 +12,6 @@ import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.protos.Contract.FreezeBalanceContract; -import org.tron.protos.Contract.ResourceCode; import org.tron.protos.Protocol.Account.AccountResource; import org.tron.protos.Protocol.Account.Frozen; import org.tron.protos.Protocol.Transaction.Result.code; @@ -69,31 +68,32 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException dbManager.getDynamicPropertiesStore() .addTotalNetWeight(freezeBalanceContract.getFrozenBalance() / 1000_000L); break; - case CPU: - long currentFrozenBalanceForCpu = accountCapsule.getAccountResource().getFrozenBalanceForCpu() + case ENERGY: + long currentFrozenBalanceForEnergy = accountCapsule.getAccountResource() + .getFrozenBalanceForEnergy() .getFrozenBalance(); - long newFrozenBalanceForCpu = freezeBalanceContract.getFrozenBalance() + currentFrozenBalanceForCpu; + long newFrozenBalanceForEnergy = + freezeBalanceContract.getFrozenBalance() + currentFrozenBalanceForEnergy; - Frozen newFrozenForCpu = Frozen.newBuilder() - .setFrozenBalance(newFrozenBalanceForCpu) + Frozen newFrozenForEnergy = Frozen.newBuilder() + .setFrozenBalance(newFrozenBalanceForEnergy) .setExpireTime(now + duration) .build(); AccountResource newAccountResource = accountCapsule.getAccountResource().toBuilder() - .setFrozenBalanceForCpu(newFrozenForCpu).build(); + .setFrozenBalanceForEnergy(newFrozenForEnergy).build(); accountCapsule.setInstance(accountCapsule.getInstance().toBuilder() .setAccountResource(newAccountResource) .setBalance(newBalance) .build()); dbManager.getDynamicPropertiesStore() - .addTotalCpuWeight(freezeBalanceContract.getFrozenBalance() / 1000_000L); + .addTotalEnergyWeight(freezeBalanceContract.getFrozenBalance() / 1000_000L); break; } dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); - ret.setStatus(fee, code.SUCESS); return true; @@ -164,14 +164,14 @@ public boolean validate() throws ContractValidateException { + "and more than " + minFrozenTime + " days"); } - switch (freezeBalanceContract.getResource()) { case BANDWIDTH: break; - case CPU: + case ENERGY: break; - default: throw new ContractValidateException( - "ResourceCode error,valid ResourceCode[BANDWIDTH、CPU]"); + default: + throw new ContractValidateException( + "ResourceCode error,valid ResourceCode[BANDWIDTH、ENERGY]"); } return true; diff --git a/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java b/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java index 4a3f76da25e..58a796099e3 100755 --- a/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java +++ b/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java @@ -25,7 +25,6 @@ import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.capsule.TransactionResultCapsule; -import org.tron.core.capsule.utils.TransactionUtil; import org.tron.core.db.Manager; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; diff --git a/src/main/java/org/tron/core/actuator/ProposalCreateActuator.java b/src/main/java/org/tron/core/actuator/ProposalCreateActuator.java index 5663fe8a490..46f1da38ccb 100755 --- a/src/main/java/org/tron/core/actuator/ProposalCreateActuator.java +++ b/src/main/java/org/tron/core/actuator/ProposalCreateActuator.java @@ -129,6 +129,17 @@ private void validateValue(Map.Entry entry) throws ContractValidateE } return; } + case (10):{ + if(dbManager.getDynamicPropertiesStore().getRemoveThePowerOfTheGr() == -1){ + throw new ContractValidateException( + "This proposal has been executed before and is only allowed to be executed once"); + } + + if(entry.getValue() != 1){ + throw new ContractValidateException( + "This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); + } + } default: break; } diff --git a/src/main/java/org/tron/core/actuator/ProposalDeleteActuator.java b/src/main/java/org/tron/core/actuator/ProposalDeleteActuator.java index 7f710c36e2c..b65537afd4b 100755 --- a/src/main/java/org/tron/core/actuator/ProposalDeleteActuator.java +++ b/src/main/java/org/tron/core/actuator/ProposalDeleteActuator.java @@ -92,7 +92,7 @@ public boolean validate() throws ContractValidateException { } long now = dbManager.getHeadBlockTimeStamp(); - if (!proposalCapsule.getProposalAddress().equals(contract.getOwnerAddress()) ) { + if (!proposalCapsule.getProposalAddress().equals(contract.getOwnerAddress())) { throw new ContractValidateException("Proposal[" + contract.getProposalId() + "] " + "is not proposed by " + readableOwnerAddress); } diff --git a/src/main/java/org/tron/core/actuator/SellStorageActuator.java b/src/main/java/org/tron/core/actuator/SellStorageActuator.java index 1d0e53fab53..57c72e3e9e2 100755 --- a/src/main/java/org/tron/core/actuator/SellStorageActuator.java +++ b/src/main/java/org/tron/core/actuator/SellStorageActuator.java @@ -40,7 +40,6 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException AccountCapsule accountCapsule = dbManager.getAccountStore() .get(sellStorageContract.getOwnerAddress().toByteArray()); - long bytes = sellStorageContract.getStorageBytes(); storageMarket.sellStorage(accountCapsule, bytes); @@ -89,17 +88,18 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("bytes must be positive"); } - long now = dbManager.getHeadBlockTimeStamp(); - - long latestExchangeStorageTime = accountCapsule.getLatestExchangeStorageTime(); long currentStorageLimit = accountCapsule.getStorageLimit(); long currentUnusedStorage = currentStorageLimit - accountCapsule.getStorageUsage(); - long duration = now - latestExchangeStorageTime; - long storageTax = storageMarket.calculateTax(duration, currentStorageLimit); + if (bytes > currentUnusedStorage) { + throw new ContractValidateException( + "bytes must be less than currentUnusedStorage[" + currentUnusedStorage + "]"); + } - if (bytes > (currentUnusedStorage - storageTax)) { - throw new ContractValidateException("bytes must be less than currentUnusedStorage minus tax"); + long quantity = storageMarket.trySellStorage(bytes); + if (quantity <= 1_000_000L) { + throw new ContractValidateException( + "quantity must be larger than 1TRX,current quantity[" + quantity + "]"); } return true; diff --git a/src/main/java/org/tron/core/actuator/TransferActuator.java b/src/main/java/org/tron/core/actuator/TransferActuator.java index 7845f561bbc..eb5f87451c2 100755 --- a/src/main/java/org/tron/core/actuator/TransferActuator.java +++ b/src/main/java/org/tron/core/actuator/TransferActuator.java @@ -5,6 +5,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import java.util.Arrays; import lombok.extern.slf4j.Slf4j; +import org.tron.common.storage.Deposit; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.TransactionResultCapsule; @@ -118,7 +119,8 @@ public boolean validate() throws ContractValidateException { } if (balance < Math.addExact(amount, fee)) { - throw new ContractValidateException("Validate TransferContract error, balance is not sufficient."); + throw new ContractValidateException( + "Validate TransferContract error, balance is not sufficient."); } if (toAccount != null) { @@ -129,7 +131,52 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException(e.getMessage()); } + return true; + } + + public static boolean validateForSmartContract(Deposit deposit, byte[] ownerAddress, + byte[] toAddress, long amount) throws ContractValidateException { + if (!Wallet.addressValid(ownerAddress)) { + throw new ContractValidateException("Invalid ownerAddress"); + } + if (!Wallet.addressValid(toAddress)) { + throw new ContractValidateException("Invalid toAddress"); + } + + if (Arrays.equals(toAddress, ownerAddress)) { + throw new ContractValidateException("Cannot transfer trx to yourself."); + } + + AccountCapsule ownerAccount = deposit.getAccount(ownerAddress); + if (ownerAccount == null) { + throw new ContractValidateException("Validate InternalTransfer error, no OwnerAccount."); + } + + AccountCapsule toAccount = deposit.getAccount(toAddress); + if (toAccount == null) { + throw new ContractValidateException( + "Validate InternalTransfer error, no ToAccount. And not allowed to create account in smart contract."); + } + long balance = ownerAccount.getBalance(); + + if (amount < 0) { + throw new ContractValidateException("Amount must greater than or equals 0."); + } + + try { + if (balance < amount) { + throw new ContractValidateException( + "Validate InternalTransfer error, balance is not sufficient."); + } + + if (toAccount != null) { + long toAddressBalance = Math.addExact(toAccount.getBalance(), amount); + } + } catch (ArithmeticException e) { + logger.debug(e.getMessage(), e); + throw new ContractValidateException(e.getMessage()); + } return true; } @@ -143,4 +190,5 @@ public ByteString getOwnerAddress() throws InvalidProtocolBufferException { public long calcFee() { return ChainConstant.TRANSFER_FEE; } + } \ No newline at end of file diff --git a/src/main/java/org/tron/core/actuator/UnfreezeBalanceActuator.java b/src/main/java/org/tron/core/actuator/UnfreezeBalanceActuator.java index 4bfc5388d49..208edbe1792 100755 --- a/src/main/java/org/tron/core/actuator/UnfreezeBalanceActuator.java +++ b/src/main/java/org/tron/core/actuator/UnfreezeBalanceActuator.java @@ -1,7 +1,5 @@ package org.tron.core.actuator; -import static org.tron.protos.Contract.ResourceCode.BANDWIDTH; - import com.google.common.collect.Lists; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -66,17 +64,17 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException dbManager.getDynamicPropertiesStore().addTotalNetWeight(-unfreezeBalance / 1000_000L); break; - case CPU: - unfreezeBalance = accountCapsule.getAccountResource().getFrozenBalanceForCpu() + case ENERGY: + unfreezeBalance = accountCapsule.getAccountResource().getFrozenBalanceForEnergy() .getFrozenBalance(); AccountResource newAccountResource = accountCapsule.getAccountResource().toBuilder() - .clearFrozenBalanceForCpu().build(); + .clearFrozenBalanceForEnergy().build(); accountCapsule.setInstance(accountCapsule.getInstance().toBuilder() .setBalance(oldBalance + unfreezeBalance) .setAccountResource(newAccountResource).build()); - dbManager.getDynamicPropertiesStore().addTotalCpuWeight(-unfreezeBalance / 1000_000L); + dbManager.getDynamicPropertiesStore().addTotalEnergyWeight(-unfreezeBalance / 1000_000L); break; } @@ -94,6 +92,7 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException dbManager.getVotesStore().put(ownerAddress, votesCapsule); + ret.setUnfreezeAmount(unfreezeBalance); ret.setStatus(fee, code.SUCESS); return true; @@ -145,19 +144,20 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("It's not time to unfreeze."); } break; - case CPU: - Frozen frozenBalanceForCpu = accountCapsule.getAccountResource().getFrozenBalanceForCpu(); - if (frozenBalanceForCpu.getFrozenBalance() <= 0) { + case ENERGY: + Frozen frozenBalanceForEnergy = accountCapsule.getAccountResource() + .getFrozenBalanceForEnergy(); + if (frozenBalanceForEnergy.getFrozenBalance() <= 0) { throw new ContractValidateException("no frozenBalance"); } - if (frozenBalanceForCpu.getExpireTime() > now) { + if (frozenBalanceForEnergy.getExpireTime() > now) { throw new ContractValidateException("It's not time to unfreeze."); } break; default: throw new ContractValidateException( - "ResourceCode error.valid ResourceCode[BANDWIDTH、CPU]"); + "ResourceCode error.valid ResourceCode[BANDWIDTH、ENERGY]"); } return true; diff --git a/src/main/java/org/tron/core/actuator/UpdateSettingContractActuator.java b/src/main/java/org/tron/core/actuator/UpdateSettingContractActuator.java new file mode 100755 index 00000000000..d6941d4290a --- /dev/null +++ b/src/main/java/org/tron/core/actuator/UpdateSettingContractActuator.java @@ -0,0 +1,120 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.utils.StringUtil; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ContractCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.db.AccountStore; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.protos.Contract.UpdateSettingContract; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j +public class UpdateSettingContractActuator extends AbstractActuator { + + UpdateSettingContractActuator(Any contract, Manager dbManager) { + super(contract, dbManager); + } + + @Override + public boolean execute(TransactionResultCapsule ret) throws ContractExeException { + long fee = calcFee(); + try { + UpdateSettingContract usContract = contract + .unpack(UpdateSettingContract.class); + long newPercent = usContract.getConsumeUserResourcePercent(); + byte[] contractAddress = usContract.getContractAddress().toByteArray(); + ContractCapsule deployedContract = dbManager.getContractStore().get(contractAddress); + + dbManager.getContractStore().put(contractAddress, new ContractCapsule( + deployedContract.getInstance().toBuilder().setConsumeUserResourcePercent(newPercent) + .build())); + + ret.setStatus(fee, code.SUCESS); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + ret.setStatus(fee, code.FAILED); + throw new ContractExeException(e.getMessage()); + } + return true; + } + + @Override + public boolean validate() throws ContractValidateException { + if (this.contract == null) { + throw new ContractValidateException("No contract!"); + } + if (this.dbManager == null) { + throw new ContractValidateException("No dbManager!"); + } + if (!this.contract.is(UpdateSettingContract.class)) { + throw new ContractValidateException( + "contract type error,expected type [UpdateSettingContract],real type[" + + contract + .getClass() + "]"); + } + final UpdateSettingContract contract; + try { + contract = this.contract.unpack(UpdateSettingContract.class); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + throw new ContractValidateException(e.getMessage()); + } + if (!Wallet.addressValid(contract.getOwnerAddress().toByteArray())) { + throw new ContractValidateException("Invalid address"); + } + byte[] ownerAddress = contract.getOwnerAddress().toByteArray(); + String readableOwnerAddress = StringUtil.createReadableString(ownerAddress); + + AccountStore accountStore = dbManager.getAccountStore(); + + AccountCapsule accountCapsule = accountStore.get(ownerAddress); + if (accountCapsule == null) { + throw new ContractValidateException( + "Account[" + readableOwnerAddress + "] not exists"); + } + + long newPercent = contract.getConsumeUserResourcePercent(); + if (newPercent > 100 || newPercent < 0) { + throw new ContractValidateException( + "percent not in [0, 100]"); + } + + byte[] contractAddress = contract.getContractAddress().toByteArray(); + ContractCapsule deployedContract = dbManager.getContractStore().get(contractAddress); + + if (deployedContract == null) { + throw new ContractValidateException( + "Contract not exists"); + } + + byte[] deployedContractOwnerAddress = deployedContract.getInstance().getOriginAddress() + .toByteArray(); + + if (!Arrays.equals(ownerAddress, deployedContractOwnerAddress)) { + throw new ContractValidateException( + "Account[" + readableOwnerAddress + "] is not the owner of the contract"); + } + + return true; + } + + @Override + public ByteString getOwnerAddress() throws InvalidProtocolBufferException { + return contract.unpack(UpdateSettingContract.class).getOwnerAddress(); + } + + @Override + public long calcFee() { + return 0; + } + +} diff --git a/src/main/java/org/tron/core/actuator/VoteWitnessActuator.java b/src/main/java/org/tron/core/actuator/VoteWitnessActuator.java index 5f0b50c4cc2..9cda4b68543 100755 --- a/src/main/java/org/tron/core/actuator/VoteWitnessActuator.java +++ b/src/main/java/org/tron/core/actuator/VoteWitnessActuator.java @@ -140,7 +140,8 @@ private void countVoteAccount(VoteWitnessContract voteContract) { AccountCapsule accountCapsule = accountStore.get(ownerAddress); if (!votesStore.has(ownerAddress)) { - votesCapsule = new VotesCapsule(voteContract.getOwnerAddress(), accountCapsule.getVotesList()); + votesCapsule = new VotesCapsule(voteContract.getOwnerAddress(), + accountCapsule.getVotesList()); } else { votesCapsule = votesStore.get(ownerAddress); } diff --git a/src/main/java/org/tron/core/actuator/WithdrawBalanceActuator.java b/src/main/java/org/tron/core/actuator/WithdrawBalanceActuator.java index 232c628706b..981457f70a4 100755 --- a/src/main/java/org/tron/core/actuator/WithdrawBalanceActuator.java +++ b/src/main/java/org/tron/core/actuator/WithdrawBalanceActuator.java @@ -49,6 +49,7 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException .setLatestWithdrawTime(now) .build()); dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + ret.setWithdrawAmount(allowance); ret.setStatus(fee, code.SUCESS); return true; diff --git a/src/main/java/org/tron/core/capsule/AccountCapsule.java b/src/main/java/org/tron/core/capsule/AccountCapsule.java index 33f2f7cbc33..05cc545f169 100644 --- a/src/main/java/org/tron/core/capsule/AccountCapsule.java +++ b/src/main/java/org/tron/core/capsule/AccountCapsule.java @@ -249,7 +249,7 @@ public long getTronPower() { tp += account.getFrozen(i).getFrozenBalance(); } - tp += account.getAccountResource().getFrozenBalanceForCpu().getFrozenBalance(); + tp += account.getAccountResource().getFrozenBalanceForEnergy().getFrozenBalance(); return tp; } @@ -447,14 +447,14 @@ public AccountResource getAccountResource() { } - public void setFrozenForCpu(long newFrozenBalanceForCpu, long time) { - Frozen newFrozenForCpu = Frozen.newBuilder() - .setFrozenBalance(newFrozenBalanceForCpu) + public void setFrozenForEnergy(long newFrozenBalanceForEnergy, long time) { + Frozen newFrozenForEnergy = Frozen.newBuilder() + .setFrozenBalance(newFrozenBalanceForEnergy) .setExpireTime(time) .build(); AccountResource newAccountResource = getAccountResource().toBuilder() - .setFrozenBalanceForCpu(newFrozenForCpu).build(); + .setFrozenBalanceForEnergy(newFrozenForEnergy).build(); this.account = this.account.toBuilder() .setAccountResource(newAccountResource) @@ -462,24 +462,25 @@ public void setFrozenForCpu(long newFrozenBalanceForCpu, long time) { } - public long getCpuFrozenBalance() { - return this.account.getAccountResource().getFrozenBalanceForCpu().getFrozenBalance(); + public long getEnergyFrozenBalance() { + return this.account.getAccountResource().getFrozenBalanceForEnergy().getFrozenBalance(); } - public long getCpuUsage() { - return this.account.getAccountResource().getCpuUsage(); + public long getEnergyUsage() { + return this.account.getAccountResource().getEnergyUsage(); } - public void setCpuUsage(long cpuUsage) { + public void setEnergyUsage(long energyUsage) { this.account = this.account.toBuilder() .setAccountResource( - this.account.getAccountResource().toBuilder().setCpuUsage(cpuUsage).build()).build(); + this.account.getAccountResource().toBuilder().setEnergyUsage(energyUsage).build()) + .build(); } - public void setLatestConsumeTimeForCpu(long latest_time) { + public void setLatestConsumeTimeForEnergy(long latest_time) { this.account = this.account.toBuilder() .setAccountResource( - this.account.getAccountResource().toBuilder().setLatestConsumeTimeForCpu(latest_time) + this.account.getAccountResource().toBuilder().setLatestConsumeTimeForEnergy(latest_time) .build()).build(); } @@ -522,6 +523,10 @@ public long getStorageUsage() { return this.account.getAccountResource().getStorageUsage(); } + public long getStorageLeft() { + return getStorageLimit() - getStorageUsage(); + } + public void setStorageUsage(long usage) { AccountResource accountResource = this.account.getAccountResource(); accountResource = accountResource.toBuilder().setStorageUsage(usage).build(); @@ -544,4 +549,16 @@ public void setLatestExchangeStorageTime(long time) { .build(); } + public void addStorageUsage(long storageUsage) { + if (storageUsage <= 0) { + return; + } + AccountResource accountResource = this.account.getAccountResource(); + accountResource = accountResource.toBuilder() + .setStorageUsage(accountResource.getStorageUsage() + storageUsage).build(); + + this.account = this.account.toBuilder() + .setAccountResource(accountResource) + .build(); + } } diff --git a/src/main/java/org/tron/core/capsule/BlockCapsule.java b/src/main/java/org/tron/core/capsule/BlockCapsule.java index 0a7ecf0b683..5e5346ebb62 100755 --- a/src/main/java/org/tron/core/capsule/BlockCapsule.java +++ b/src/main/java/org/tron/core/capsule/BlockCapsule.java @@ -33,6 +33,7 @@ import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.Time; import org.tron.core.capsule.utils.MerkleTree; +import org.tron.core.config.Parameter.ChainConstant; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ValidateSignatureException; import org.tron.protos.Protocol.Block; @@ -128,7 +129,9 @@ public BlockCapsule(long number, Sha256Hash hash, long when, ByteString witnessA .setNumber(number) .setParentHash(hash.getByteString()) .setTimestamp(when) - .setWitnessAddress(witnessAddress).build(); + .setVersion(ChainConstant.version) + .setWitnessAddress(witnessAddress) + .build(); // block header BlockHeader.Builder blockHeaderBuild = BlockHeader.newBuilder(); diff --git a/src/main/java/org/tron/core/capsule/CodeCapsule.java b/src/main/java/org/tron/core/capsule/CodeCapsule.java index 8e1aa32ddee..d1bcd78816b 100644 --- a/src/main/java/org/tron/core/capsule/CodeCapsule.java +++ b/src/main/java/org/tron/core/capsule/CodeCapsule.java @@ -15,20 +15,11 @@ package org.tron.core.capsule; -import com.google.protobuf.Any; -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import java.util.Arrays; import lombok.extern.slf4j.Slf4j; -import org.tron.common.crypto.ECKey.ECDSASignature; import org.tron.common.utils.Sha256Hash; -import org.tron.protos.Contract.TriggerSmartContract; -import org.tron.protos.Protocol.SmartContract; -import org.tron.protos.Protocol.Transaction; -/** - * Created by Guo Yonggang on 04.14.2018 - */ +import java.util.Arrays; + @Slf4j public class CodeCapsule implements ProtoCapsule { @@ -38,49 +29,10 @@ public CodeCapsule(byte[] code) { this.code = code; } - public CodeCapsule(ByteString bs) { - this.code = bs.toByteArray(); - } - - public static SmartContract getCreationContractFromTransaction(Transaction trx) { - try { - Any any = trx.getRawData().getContract(0).getParameter(); - SmartContract contractCreationContract = any.unpack(SmartContract.class); - return contractCreationContract; - } catch (InvalidProtocolBufferException e) { - return null; - } - } - - public static TriggerSmartContract getCallContractFromTransaction(Transaction trx) { - try { - Any any = trx.getRawData().getContract(0).getParameter(); - TriggerSmartContract contractCallContract = any.unpack(TriggerSmartContract.class); - return contractCallContract; - } catch (InvalidProtocolBufferException e) { - return null; - } - } - - public Sha256Hash getHash() { - return Sha256Hash.of(this.code); - } - public Sha256Hash getCodeHash() { return Sha256Hash.of(this.code); } - public static String getBase64FromByteString(ByteString sign) { - byte[] r = sign.substring(0, 32).toByteArray(); - byte[] s = sign.substring(32, 64).toByteArray(); - byte v = sign.byteAt(64); - if (v < 27) { - v += 27; //revId -> v - } - ECDSASignature signature = ECDSASignature.fromComponents(r, s, v); - return signature.toBase64(); - } - @Override public byte[] getData() { return this.code; diff --git a/src/main/java/org/tron/core/capsule/ContractCapsule.java b/src/main/java/org/tron/core/capsule/ContractCapsule.java index f7e5a7d1ebc..8de8347594e 100644 --- a/src/main/java/org/tron/core/capsule/ContractCapsule.java +++ b/src/main/java/org/tron/core/capsule/ContractCapsule.java @@ -88,4 +88,12 @@ public SmartContract getInstance() { public String toString() { return this.smartContract.toString(); } + + public byte[] getOriginAddress() { + return this.smartContract.getOriginAddress().toByteArray(); + } + + public long getConsumeUserResourcePercent() { + return this.smartContract.getConsumeUserResourcePercent(); + } } diff --git a/src/main/java/org/tron/core/capsule/ExchangeCapsule.java b/src/main/java/org/tron/core/capsule/ExchangeCapsule.java new file mode 100644 index 00000000000..aba8f24fb91 --- /dev/null +++ b/src/main/java/org/tron/core/capsule/ExchangeCapsule.java @@ -0,0 +1,139 @@ +package org.tron.core.capsule; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.utils.ByteArray; +import org.tron.core.capsule.utils.ExchangeProcessor; +import org.tron.protos.Protocol.Exchange; + +@Slf4j +public class ExchangeCapsule implements ProtoCapsule { + + private Exchange exchange; + + public ExchangeCapsule(final Exchange exchange) { + this.exchange = exchange; + } + + public ExchangeCapsule(final byte[] data) { + try { + this.exchange = Exchange.parseFrom(data); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage(), e); + } + } + + public ExchangeCapsule(ByteString address, final long id, long createTime, + byte[] firstTokenID, byte[] secondTokenID) { + this.exchange = Exchange.newBuilder() + .setExchangeId(id) + .setCreatorAddress(address) + .setCreateTime(createTime) + .setFirstTokenId(ByteString.copyFrom(firstTokenID)) + .setSecondTokenId(ByteString.copyFrom(secondTokenID)) + .build(); + } + + public long getID() { + return this.exchange.getExchangeId(); + } + + public void setID(long id) { + this.exchange = this.exchange.toBuilder() + .setExchangeId(id) + .build(); + } + + public ByteString getCreatorAddress() { + return this.exchange.getCreatorAddress(); + } + + public void setExchangeAddress(ByteString address) { + this.exchange = this.exchange.toBuilder() + .setCreatorAddress(address) + .build(); + } + + public void setBalance(long firstTokenBalance, long secondTokenBalance) { + this.exchange = this.exchange.toBuilder() + .setFirstTokenBalance(firstTokenBalance) + .setSecondTokenBalance(secondTokenBalance) + .build(); + } + + public long getCreateTime() { + return this.exchange.getCreateTime(); + } + + public void setCreateTime(long time) { + this.exchange = this.exchange.toBuilder() + .setCreateTime(time) + .build(); + } + + public byte[] getFirstTokenId() { + return this.exchange.getFirstTokenId().toByteArray(); + } + + public byte[] getSecondTokenId() { + return this.exchange.getSecondTokenId().toByteArray(); + } + + public long getFirstTokenBalance() { + return this.exchange.getFirstTokenBalance(); + } + + public long getSecondTokenBalance() { + return this.exchange.getSecondTokenBalance(); + } + + + public byte[] createDbKey() { + return calculateDbKey(getID()); + } + + public static byte[] calculateDbKey(long number) { + return ByteArray.fromLong(number); + } + + public long transaction(byte[] sellTokenID, long sellTokenQuant) { + long supply = 1_000_000_000_000_000_000L; + ExchangeProcessor processor = new ExchangeProcessor(supply); + + long buyTokenQuant = 0; + long firstTokenBalance = this.exchange.getFirstTokenBalance(); + long secondTokenBalance = this.exchange.getSecondTokenBalance(); + + if (this.exchange.getFirstTokenId().equals(ByteString.copyFrom(sellTokenID))) { + buyTokenQuant = processor.exchange(firstTokenBalance, + secondTokenBalance, + sellTokenQuant); + this.exchange = this.exchange.toBuilder() + .setFirstTokenBalance(firstTokenBalance + sellTokenQuant) + .setSecondTokenBalance(secondTokenBalance - buyTokenQuant) + .build(); + } else { + buyTokenQuant = processor.exchange(secondTokenBalance, + firstTokenBalance, + sellTokenQuant); + this.exchange = this.exchange.toBuilder() + .setFirstTokenBalance(firstTokenBalance - buyTokenQuant) + .setSecondTokenBalance(secondTokenBalance + sellTokenQuant) + .build(); + } + + return buyTokenQuant; + } + + @Override + public byte[] getData() { + return this.exchange.toByteArray(); + } + + @Override + public Exchange getInstance() { + return this.exchange; + } + +} diff --git a/src/main/java/org/tron/core/capsule/ReceiptCapsule.java b/src/main/java/org/tron/core/capsule/ReceiptCapsule.java index 6d5c6054c4c..dccb0417248 100644 --- a/src/main/java/org/tron/core/capsule/ReceiptCapsule.java +++ b/src/main/java/org/tron/core/capsule/ReceiptCapsule.java @@ -1,44 +1,135 @@ package org.tron.core.capsule; import org.tron.common.utils.Sha256Hash; +import org.tron.core.Constant; +import org.tron.core.db.EnergyProcessor; +import org.tron.core.db.Manager; import org.tron.protos.Protocol.ResourceReceipt; public class ReceiptCapsule { + private ResourceReceipt receipt; private Sha256Hash receiptAddress; public ReceiptCapsule(ResourceReceipt data, Sha256Hash receiptAddress) { - receipt = data; + this.receipt = data; this.receiptAddress = receiptAddress; } public ReceiptCapsule(Sha256Hash receiptAddress) { - receipt = ResourceReceipt.newBuilder().build(); + this.receipt = ResourceReceipt.newBuilder().build(); this.receiptAddress = receiptAddress; } - public void setCpuUsage(long usage) { - receipt.toBuilder().setCpuFee(usage); + public void setReceipt(ResourceReceipt receipt) { + this.receipt = receipt; + } + + public ResourceReceipt getReceipt() { + return this.receipt; + } + + public Sha256Hash getReceiptAddress() { + return this.receiptAddress; + } + + public void setNetUsage(long netUsage) { + this.receipt = this.receipt.toBuilder().setNetUsage(netUsage).build(); } - public void calculateCpuFee() { - //TODO: calculate + public void setNetFee(long netFee) { + this.receipt = this.receipt.toBuilder().setNetFee(netFee).build(); } - public void setStorageDelta(long delta) { - receipt.toBuilder().setCpuFee(delta); + public long getEnergyUsage() { + return this.receipt.getEnergyUsage(); } - public void payCpuBill() { - //TODO: pay cpu bill + public long getEnergyFee() { + return this.receipt.getEnergyFee(); } - public void payStorageBill() { - //TODO: pay storage bill + public void setEnergyUsage(long energyUsage) { + this.receipt = this.receipt.toBuilder().setEnergyUsage(energyUsage).build(); + } + + public void setEnergyFee(long energyFee) { + this.receipt = this.receipt.toBuilder().setEnergyFee(energyFee).build(); + } + + public long getOriginEnergyUsage() { + return this.receipt.getOriginEnergyUsage(); + } + + public long getEnergyUsageTotal() { + return this.receipt.getEnergyUsageTotal(); + } + + public void setOriginEnergyUsage(long energyUsage) { + this.receipt = this.receipt.toBuilder().setOriginEnergyUsage(energyUsage).build(); + } + + public void setEnergyUsageTotal(long energyUsage) { + this.receipt = this.receipt.toBuilder().setEnergyUsageTotal(energyUsage).build(); + } + + public long getNetUsage() { + return this.receipt.getNetUsage(); + } + + public long getNetFee() { + return this.receipt.getNetFee(); + } + + /** + * payEnergyBill pay receipt energy bill by energy processor. + */ + public void payEnergyBill(Manager manager, AccountCapsule origin, AccountCapsule caller, + long percent, EnergyProcessor energyProcessor, long now) { + if (0 == receipt.getEnergyUsageTotal()) { + return; + } + + if (caller.getAddress().equals(origin.getAddress())) { + payEnergyBill(manager, caller, receipt.getEnergyUsageTotal(), energyProcessor, now); + } else { + long originUsage = Math.multiplyExact(receipt.getEnergyUsageTotal(), percent) / 100; + originUsage = Math + .min(originUsage, energyProcessor.getAccountLeftEnergyFromFreeze(origin)); + long callerUsage = receipt.getEnergyUsageTotal() - originUsage; + energyProcessor.useEnergy(origin, originUsage, now); + this.setOriginEnergyUsage(originUsage); + payEnergyBill(manager, caller, callerUsage, energyProcessor, now); + } + } + + private void payEnergyBill( + Manager manager, + AccountCapsule account, + long usage, + EnergyProcessor energyProcessor, + long now) { + long accountEnergyLeft = energyProcessor.getAccountLeftEnergyFromFreeze(account); + if (accountEnergyLeft >= usage) { + energyProcessor.useEnergy(account, usage, now); + this.setEnergyUsage(usage); + } else { + energyProcessor.useEnergy(account, accountEnergyLeft, now); + long SUN_PER_ENERGY = manager.getDynamicPropertiesStore().getEnergyFee() == 0 + ? Constant.SUN_PER_ENERGY + : manager.getDynamicPropertiesStore().getEnergyFee(); + long energyFee = + (usage - accountEnergyLeft) * SUN_PER_ENERGY; + this.setEnergyUsage(accountEnergyLeft); + this.setEnergyFee(energyFee); + account.setBalance(account.getBalance() - energyFee); + } + + manager.getAccountStore().put(account.getAddress().toByteArray(), account); } - public void buyStorage(long storage) { - //TODO: buy the min storage + public static ResourceReceipt copyReceipt(ReceiptCapsule origin) { + return origin.getReceipt().toBuilder().build(); } } diff --git a/src/main/java/org/tron/core/capsule/StorageCapsule.java b/src/main/java/org/tron/core/capsule/StorageCapsule.java deleted file mode 100644 index f75337d1f99..00000000000 --- a/src/main/java/org/tron/core/capsule/StorageCapsule.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.core.capsule; - -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import lombok.extern.slf4j.Slf4j; -import org.tron.common.crypto.ECKey.ECDSASignature; -import org.tron.common.runtime.vm.DataWord; -import org.tron.common.utils.Sha256Hash; -import org.tron.protos.Protocol.StorageItem; - - -/** - * @author Guo Yonggang - * @since 28.04.2018 - */ -@Slf4j -public class StorageCapsule implements ProtoCapsule { - - private StorageItem storage; - - public StorageCapsule(byte[] code) { - try { - this.storage = StorageItem.parseFrom(code); - } catch (InvalidProtocolBufferException e) { - // - } - } - - public StorageCapsule(StorageItem cache) { - this.storage = cache; - } - - public Sha256Hash getHash() { - byte[] storageBytes = this.storage.toByteArray(); - return Sha256Hash.of(storageBytes); - } - - public Sha256Hash getRawHash() { - return Sha256Hash.of(this.storage.toByteArray()); - } - - public static String getBase64FromByteString(ByteString sign) { - byte[] r = sign.substring(0, 32).toByteArray(); - byte[] s = sign.substring(32, 64).toByteArray(); - byte v = sign.byteAt(64); - if (v < 27) { - v += 27; //revId -> v - } - ECDSASignature signature = ECDSASignature.fromComponents(r, s, v); - return signature.toBase64(); - } - - public DataWord get(DataWord key) { - if (!this.storage.containsItems(key.toHexString())) { - return null; - } - - DataWord value = new DataWord(this.storage.getItemsMap().get(key.toHexString()).toByteArray()); - return value; - } - - public void put(DataWord key, DataWord value) { - this.storage = this.storage.toBuilder(). - putItems(key.toHexString(), ByteString.copyFrom(value.getData())).build(); - } - - @Override - public byte[] getData() { - return this.storage.toByteArray(); - } - - @Override - public StorageItem getInstance() { - return this.storage; - } - - @Override - public String toString() { - return this.storage.toString(); - } -} diff --git a/src/main/java/org/tron/core/capsule/StorageRowCapsule.java b/src/main/java/org/tron/core/capsule/StorageRowCapsule.java new file mode 100644 index 00000000000..d73da7b234e --- /dev/null +++ b/src/main/java/org/tron/core/capsule/StorageRowCapsule.java @@ -0,0 +1,84 @@ +/* + * 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.core.capsule; + +import java.util.Arrays; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.runtime.vm.DataWord; +import org.tron.common.utils.Sha256Hash; + + +@Slf4j +public class StorageRowCapsule implements ProtoCapsule { + + private byte[] rowValue; + @Setter + @Getter + private byte[] rowKey; + + @Getter + private boolean dirty = false; + + private void markDirty() { + dirty = true; + } + + private StorageRowCapsule() { + } + + public StorageRowCapsule(byte[] rowKey, byte[] rowValue) { + this.rowKey = rowKey; + this.rowValue = rowValue; + markDirty(); + } + + public StorageRowCapsule(byte[] rowValue) { + this.rowValue = rowValue; + } + + + public Sha256Hash getHash() { + return Sha256Hash.of(this.rowValue); + } + + + public DataWord getValue() { + return new DataWord(this.rowValue); + } + + public void setValue(DataWord value) { + this.rowValue = value.getData(); + markDirty(); + } + + @Override + public byte[] getData() { + return this.rowValue; + } + + @Override + public byte[] getInstance() { + return this.rowValue; + } + + @Override + public String toString() { + return Arrays.toString(rowValue); + } +} diff --git a/src/main/java/org/tron/core/capsule/TransactionCapsule.java b/src/main/java/org/tron/core/capsule/TransactionCapsule.java index 7275b00b3f8..209423bcf07 100755 --- a/src/main/java/org/tron/core/capsule/TransactionCapsule.java +++ b/src/main/java/org/tron/core/capsule/TransactionCapsule.java @@ -1,501 +1,526 @@ -/* - * 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.core.capsule; - -import static org.tron.protos.Contract.AssetIssueContract; -import static org.tron.protos.Contract.VoteAssetContract; -import static org.tron.protos.Contract.VoteWitnessContract; -import static org.tron.protos.Contract.WitnessCreateContract; -import static org.tron.protos.Contract.WitnessUpdateContract; - -import com.google.protobuf.Any; -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import java.security.SignatureException; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.tron.common.crypto.ECKey; -import org.tron.common.crypto.ECKey.ECDSASignature; -import org.tron.common.utils.ByteArray; -import org.tron.common.utils.Sha256Hash; -import org.tron.core.Wallet; -import org.tron.core.db.AccountStore; -import org.tron.core.exception.BadItemException; -import org.tron.core.exception.ValidateSignatureException; -import org.tron.protos.Contract; -import org.tron.protos.Contract.AccountCreateContract; -import org.tron.protos.Contract.AccountUpdateContract; -import org.tron.protos.Contract.BuyStorageContract; -import org.tron.protos.Contract.CreateSmartContract; -import org.tron.protos.Contract.FreezeBalanceContract; -import org.tron.protos.Contract.ParticipateAssetIssueContract; -import org.tron.protos.Contract.ProposalApproveContract; -import org.tron.protos.Contract.ProposalCreateContract; -import org.tron.protos.Contract.ProposalDeleteContract; -import org.tron.protos.Contract.SellStorageContract; -import org.tron.protos.Contract.SetAccountIdContract; -import org.tron.protos.Contract.TransferAssetContract; -import org.tron.protos.Contract.TransferContract; -import org.tron.protos.Contract.TriggerSmartContract; -import org.tron.protos.Contract.UnfreezeAssetContract; -import org.tron.protos.Contract.UnfreezeBalanceContract; -import org.tron.protos.Contract.UpdateAssetContract; -import org.tron.protos.Contract.WithdrawBalanceContract; -import org.tron.protos.Protocol.Transaction; -import org.tron.protos.Protocol.Transaction.Contract.ContractType; - -@Slf4j -public class TransactionCapsule implements ProtoCapsule { - - private Transaction transaction; - @Setter - private boolean isVerified = false; - - /** - * constructor TransactionCapsule. - */ - public TransactionCapsule(Transaction trx) { - this.transaction = trx; - } - - /** - * get account from bytes data. - */ - public TransactionCapsule(byte[] data) throws BadItemException { - try { - this.transaction = Transaction.parseFrom(data); - } catch (InvalidProtocolBufferException e) { - throw new BadItemException("Transaction proto data parse exception"); - } - } - - /*lll - public TransactionCapsule(byte[] key, long value) throws IllegalArgumentException { - if (!Wallet.addressValid(key)) { - throw new IllegalArgumentException("Invalid address"); - } - TransferContract transferContract = TransferContract.newBuilder() - .setAmount(value) - .setOwnerAddress(ByteString.copyFrom("0x0000000000000000000".getBytes())) - .setToAddress(ByteString.copyFrom(key)) - .build(); - Transaction.raw.Builder transactionBuilder = Transaction.raw.newBuilder().addContract( - Transaction.Contract.newBuilder().setType(ContractType.TransferContract).setParameter( - Any.pack(transferContract)).build()); - logger.info("Transaction create succeeded!"); - transaction = Transaction.newBuilder().setRawData(transactionBuilder.build()).build(); - }*/ - - public TransactionCapsule(AccountCreateContract contract, AccountStore accountStore) { - AccountCapsule account = accountStore.get(contract.getOwnerAddress().toByteArray()); - if (account != null && account.getType() == contract.getType()) { - return; // Account isexit - } - - createTransaction(contract, ContractType.AccountCreateContract); - } - - public TransactionCapsule(TransferContract contract, AccountStore accountStore) { - Transaction.Contract.Builder contractBuilder = Transaction.Contract.newBuilder(); - - AccountCapsule owner = accountStore.get(contract.getOwnerAddress().toByteArray()); - if (owner == null || owner.getBalance() < contract.getAmount()) { - return; //The balance is not enough - } - - createTransaction(contract, ContractType.TransferContract); - } - - public TransactionCapsule(VoteWitnessContract voteWitnessContract) { - createTransaction(voteWitnessContract, ContractType.VoteWitnessContract); - } - - public TransactionCapsule(WitnessCreateContract witnessCreateContract) { - createTransaction(witnessCreateContract, ContractType.WitnessCreateContract); - } - - public TransactionCapsule(WitnessUpdateContract witnessUpdateContract) { - createTransaction(witnessUpdateContract, ContractType.WitnessUpdateContract); - } - - public TransactionCapsule(TransferAssetContract transferAssetContract) { - createTransaction(transferAssetContract, ContractType.TransferAssetContract); - } - - public TransactionCapsule(ParticipateAssetIssueContract participateAssetIssueContract) { - createTransaction(participateAssetIssueContract, ContractType.ParticipateAssetIssueContract); - } - - public void resetResult() { - if (this.getInstance().getRetCount() > 0) { - this.transaction = this.getInstance().toBuilder().clearRet().build(); - } - } - - public void setResult(TransactionResultCapsule transactionResultCapsule) { - this.transaction = this.getInstance().toBuilder().addRet(transactionResultCapsule.getInstance()) - .build(); - } - - public void setReference(long blockNum, byte[] blockHash) { - byte[] refBlockNum = ByteArray.fromLong(blockNum); - Transaction.raw rawData = this.transaction.getRawData().toBuilder() - .setRefBlockHash(ByteString.copyFrom(ByteArray.subArray(blockHash, 8, 16))) - .setRefBlockBytes(ByteString.copyFrom(ByteArray.subArray(refBlockNum, 6, 8))) - .build(); - this.transaction = this.transaction.toBuilder().setRawData(rawData).build(); - } - - /** - * @param expiration must be in milliseconds format - */ - public void setExpiration(long expiration) { - Transaction.raw rawData = this.transaction.getRawData().toBuilder().setExpiration(expiration) - .build(); - this.transaction = this.transaction.toBuilder().setRawData(rawData).build(); - } - - public long getExpiration() { - return transaction.getRawData().getExpiration(); - } - - public void setTimestamp() { - Transaction.raw rawData = this.transaction.getRawData().toBuilder() - .setTimestamp(System.currentTimeMillis()) - .build(); - this.transaction = this.transaction.toBuilder().setRawData(rawData).build(); - } - - public long getTimestamp() { - return transaction.getRawData().getTimestamp(); - } - - @Deprecated - public TransactionCapsule(AssetIssueContract assetIssueContract) { - createTransaction(assetIssueContract, ContractType.AssetIssueContract); - } - - public TransactionCapsule(com.google.protobuf.Message message, ContractType contractType) { - Transaction.raw.Builder transactionBuilder = Transaction.raw.newBuilder().addContract( - Transaction.Contract.newBuilder().setType(contractType).setParameter( - Any.pack(message)).build()); - transaction = Transaction.newBuilder().setRawData(transactionBuilder.build()).build(); - } - - @Deprecated - public void createTransaction(com.google.protobuf.Message message, ContractType contractType) { - Transaction.raw.Builder transactionBuilder = Transaction.raw.newBuilder().addContract( - Transaction.Contract.newBuilder().setType(contractType).setParameter( - Any.pack(message)).build()); - transaction = Transaction.newBuilder().setRawData(transactionBuilder.build()).build(); - } - - public Sha256Hash getMerkleHash() { - byte[] transBytes = this.transaction.toByteArray(); - return Sha256Hash.of(transBytes); - } - - private Sha256Hash getRawHash() { - return Sha256Hash.of(this.transaction.getRawData().toByteArray()); - } - - /** - * check balance of the address. - */ - public boolean checkBalance(byte[] address, byte[] to, long amount, long balance) { - if (!Wallet.addressValid(address)) { - logger.error("address invalid"); - return false; - } - - if (!Wallet.addressValid(to)) { - logger.error("address invalid"); - return false; - } - - if (amount <= 0) { - logger.error("amount required a positive number"); - return false; - } - - if (amount > balance) { - logger.error("don't have enough money"); - return false; - } - - return true; - } - - public void sign(byte[] privateKey) { - ECKey ecKey = ECKey.fromPrivate(privateKey); - ECDSASignature signature = ecKey.sign(getRawHash().getBytes()); - ByteString sig = ByteString.copyFrom(signature.toByteArray()); - this.transaction = this.transaction.toBuilder().addSignature(sig).build(); - } - - // todo mv this static function to capsule util - public static byte[] getOwner(Transaction.Contract contract) { - ByteString owner; - try { - Any contractParameter = contract.getParameter(); - switch (contract.getType()) { - case AccountCreateContract: - owner = contractParameter.unpack(AccountCreateContract.class).getOwnerAddress(); - break; - case TransferContract: - owner = contractParameter.unpack(TransferContract.class).getOwnerAddress(); - break; - case TransferAssetContract: - owner = contractParameter.unpack(TransferAssetContract.class).getOwnerAddress(); - break; - case VoteAssetContract: - owner = contractParameter.unpack(VoteAssetContract.class).getOwnerAddress(); - break; - case VoteWitnessContract: - owner = contractParameter.unpack(VoteWitnessContract.class).getOwnerAddress(); - break; - case WitnessCreateContract: - owner = contractParameter.unpack(WitnessCreateContract.class).getOwnerAddress(); - break; - case AssetIssueContract: - owner = contractParameter.unpack(AssetIssueContract.class).getOwnerAddress(); - break; - case WitnessUpdateContract: - owner = contractParameter.unpack(WitnessUpdateContract.class).getOwnerAddress(); - break; - case ParticipateAssetIssueContract: - owner = contractParameter.unpack(ParticipateAssetIssueContract.class).getOwnerAddress(); - break; - case AccountUpdateContract: - owner = contractParameter.unpack(AccountUpdateContract.class).getOwnerAddress(); - break; - case FreezeBalanceContract: - owner = contractParameter.unpack(FreezeBalanceContract.class).getOwnerAddress(); - break; - case UnfreezeBalanceContract: - owner = contractParameter.unpack(UnfreezeBalanceContract.class).getOwnerAddress(); - break; - case UnfreezeAssetContract: - owner = contractParameter.unpack(UnfreezeAssetContract.class).getOwnerAddress(); - break; - case WithdrawBalanceContract: - owner = contractParameter.unpack(WithdrawBalanceContract.class).getOwnerAddress(); - break; - case CreateSmartContract: - owner = contractParameter.unpack(Contract.CreateSmartContract.class).getOwnerAddress(); - break; - case TriggerSmartContract: - owner = contractParameter.unpack(Contract.TriggerSmartContract.class).getOwnerAddress(); - break; - case UpdateAssetContract: - owner = contractParameter.unpack(UpdateAssetContract.class).getOwnerAddress(); - break; - case ProposalCreateContract: - owner = contractParameter.unpack(ProposalCreateContract.class).getOwnerAddress(); - break; - case ProposalApproveContract: - owner = contractParameter.unpack(ProposalApproveContract.class).getOwnerAddress(); - break; - case ProposalDeleteContract: - owner = contractParameter.unpack(ProposalDeleteContract.class).getOwnerAddress(); - break; - case SetAccountIdContract: - owner = contractParameter.unpack(SetAccountIdContract.class).getOwnerAddress(); - break; - case BuyStorageContract: - owner = contractParameter.unpack(BuyStorageContract.class).getOwnerAddress(); - break; - case SellStorageContract: - owner = contractParameter.unpack(SellStorageContract.class).getOwnerAddress(); - break; - // todo add other contract - default: - return null; - } - return owner.toByteArray(); - } catch (Exception ex) { - logger.error(ex.getMessage()); - return null; - } - } - - // todo mv this static function to capsule util - public static byte[] getToAddress(Transaction.Contract contract) { - ByteString to; - try { - Any contractParameter = contract.getParameter(); - switch (contract.getType()) { - case TransferContract: - to = contractParameter.unpack(TransferContract.class).getToAddress(); - break; - case TransferAssetContract: - to = contractParameter.unpack(TransferAssetContract.class).getToAddress(); - break; - case ParticipateAssetIssueContract: - to = contractParameter.unpack(ParticipateAssetIssueContract.class).getToAddress(); - break; - // todo add other contract - - default: - return null; - } - return to.toByteArray(); - } catch (Exception ex) { - logger.error(ex.getMessage()); - return null; - } - } - - // todo mv this static function to capsule util - public static long getCpuLimitInTrx(Transaction.Contract contract) { - int cpuForTrx; - try { - Any contractParameter = contract.getParameter(); - switch (contract.getType()) { - case TriggerSmartContract: - return contractParameter.unpack(TriggerSmartContract.class).getCpuLimitInTrx(); - case CreateSmartContract: - return contractParameter.unpack(CreateSmartContract.class).getCpuLimitInTrx(); - default: - return 0; - } - } catch (Exception ex) { - logger.error(ex.getMessage()); - return 0; - } - } - - public static String getBase64FromByteString(ByteString sign) { - byte[] r = sign.substring(0, 32).toByteArray(); - byte[] s = sign.substring(32, 64).toByteArray(); - byte v = sign.byteAt(64); - if (v < 27) { - v += 27; //revId -> v - } - ECDSASignature signature = ECDSASignature.fromComponents(r, s, v); - return signature.toBase64(); - } - - - /** - * validate signature - */ - public boolean validateSignature() throws ValidateSignatureException { - if (isVerified == true) { - return true; - } - - if (this.getInstance().getSignatureCount() != - this.getInstance().getRawData().getContractCount()) { - throw new ValidateSignatureException("miss sig or contract"); - } - - List listContract = this.transaction.getRawData().getContractList(); - for (int i = 0; i < this.transaction.getSignatureCount(); ++i) { - try { - Transaction.Contract contract = listContract.get(i); - byte[] owner = getOwner(contract); - byte[] address = ECKey.signatureToAddress(getRawHash().getBytes(), - getBase64FromByteString(this.transaction.getSignature(i))); - if (!Arrays.equals(owner, address)) { - isVerified = false; - throw new ValidateSignatureException("sig error"); - } - } catch (SignatureException e) { - isVerified = false; - throw new ValidateSignatureException(e.getMessage()); - } - } - - isVerified = true; - return true; - } - - public Sha256Hash getTransactionId() { - return getRawHash(); - } - - @Override - public byte[] getData() { - return this.transaction.toByteArray(); - } - - public long getSerializedSize() { - return this.transaction.getSerializedSize(); - } - - @Override - public Transaction getInstance() { - return this.transaction; - } - - private StringBuffer toStringBuff = new StringBuffer(); - - @Override - public String toString() { - - toStringBuff.setLength(0); - toStringBuff.append("TransactionCapsule \n[ "); - - toStringBuff.append("hash=").append(getTransactionId()).append("\n"); - AtomicInteger i = new AtomicInteger(); - if (!getInstance().getRawData().getContractList().isEmpty()) { - toStringBuff.append("contract list:{ "); - getInstance().getRawData().getContractList().forEach(contract -> { - toStringBuff.append("[" + i + "] ").append("type: ").append(contract.getType()) - .append("\n"); - toStringBuff.append("from address=").append(getOwner(contract)).append("\n"); - toStringBuff.append("to address=").append(getToAddress(contract)).append("\n"); - if (contract.getType().equals(ContractType.TransferContract)) { - TransferContract transferContract; - try { - transferContract = contract.getParameter() - .unpack(TransferContract.class); - toStringBuff.append("transfer amount=").append(transferContract.getAmount()) - .append("\n"); - } catch (InvalidProtocolBufferException e) { - e.printStackTrace(); - } - } else if (contract.getType().equals(ContractType.TransferAssetContract)) { - TransferAssetContract transferAssetContract; - try { - transferAssetContract = contract.getParameter() - .unpack(TransferAssetContract.class); - toStringBuff.append("transfer asset=").append(transferAssetContract.getAssetName()) - .append("\n"); - toStringBuff.append("transfer amount=").append(transferAssetContract.getAmount()) - .append("\n"); - } catch (InvalidProtocolBufferException e) { - e.printStackTrace(); - } - } - if (this.transaction.getSignatureList().size() >= i.get() + 1) { - toStringBuff.append("sign=").append(getBase64FromByteString( - this.transaction.getSignature(i.getAndIncrement()))).append("\n"); - } - }); - toStringBuff.append("}\n"); - } else { - toStringBuff.append("contract list is empty\n"); - } - - toStringBuff.append("]"); - return toStringBuff.toString(); - } -} +/* + * 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.core.capsule; + +import static org.tron.protos.Contract.AssetIssueContract; +import static org.tron.protos.Contract.VoteAssetContract; +import static org.tron.protos.Contract.VoteWitnessContract; +import static org.tron.protos.Contract.WitnessCreateContract; +import static org.tron.protos.Contract.WitnessUpdateContract; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import java.security.SignatureException; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.crypto.ECKey; +import org.tron.common.crypto.ECKey.ECDSASignature; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.Wallet; +import org.tron.core.db.AccountStore; +import org.tron.core.exception.BadItemException; +import org.tron.core.exception.ValidateSignatureException; +import org.tron.protos.Contract; +import org.tron.protos.Contract.AccountCreateContract; +import org.tron.protos.Contract.AccountUpdateContract; +import org.tron.protos.Contract.CreateSmartContract; +import org.tron.protos.Contract.ExchangeCreateContract; +import org.tron.protos.Contract.ExchangeInjectContract; +import org.tron.protos.Contract.ExchangeTransactionContract; +import org.tron.protos.Contract.ExchangeWithdrawContract; +import org.tron.protos.Contract.FreezeBalanceContract; +import org.tron.protos.Contract.ParticipateAssetIssueContract; +import org.tron.protos.Contract.ProposalApproveContract; +import org.tron.protos.Contract.ProposalCreateContract; +import org.tron.protos.Contract.ProposalDeleteContract; +import org.tron.protos.Contract.SetAccountIdContract; +import org.tron.protos.Contract.TransferAssetContract; +import org.tron.protos.Contract.TransferContract; +import org.tron.protos.Contract.TriggerSmartContract; +import org.tron.protos.Contract.UnfreezeAssetContract; +import org.tron.protos.Contract.UnfreezeBalanceContract; +import org.tron.protos.Contract.UpdateAssetContract; +import org.tron.protos.Contract.UpdateSettingContract; +import org.tron.protos.Contract.WithdrawBalanceContract; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; + +@Slf4j +public class TransactionCapsule implements ProtoCapsule { + + private Transaction transaction; + @Setter + private boolean isVerified = false; + + /** + * constructor TransactionCapsule. + */ + public TransactionCapsule(Transaction trx) { + this.transaction = trx; + } + + /** + * get account from bytes data. + */ + public TransactionCapsule(byte[] data) throws BadItemException { + try { + this.transaction = Transaction.parseFrom(data); + } catch (InvalidProtocolBufferException e) { + throw new BadItemException("Transaction proto data parse exception"); + } + } + + /*lll + public TransactionCapsule(byte[] key, long value) throws IllegalArgumentException { + if (!Wallet.addressValid(key)) { + throw new IllegalArgumentException("Invalid address"); + } + TransferContract transferContract = TransferContract.newBuilder() + .setAmount(value) + .setOwnerAddress(ByteString.copyFrom("0x0000000000000000000".getBytes())) + .setToAddress(ByteString.copyFrom(key)) + .build(); + Transaction.raw.Builder transactionBuilder = Transaction.raw.newBuilder().addContract( + Transaction.Contract.newBuilder().setType(ContractType.TransferContract).setParameter( + Any.pack(transferContract)).build()); + logger.info("Transaction create succeeded!"); + transaction = Transaction.newBuilder().setRawData(transactionBuilder.build()).build(); + }*/ + + public TransactionCapsule(AccountCreateContract contract, AccountStore accountStore) { + AccountCapsule account = accountStore.get(contract.getOwnerAddress().toByteArray()); + if (account != null && account.getType() == contract.getType()) { + return; // Account isexit + } + + createTransaction(contract, ContractType.AccountCreateContract); + } + + public TransactionCapsule(TransferContract contract, AccountStore accountStore) { + Transaction.Contract.Builder contractBuilder = Transaction.Contract.newBuilder(); + + AccountCapsule owner = accountStore.get(contract.getOwnerAddress().toByteArray()); + if (owner == null || owner.getBalance() < contract.getAmount()) { + return; //The balance is not enough + } + + createTransaction(contract, ContractType.TransferContract); + } + + public TransactionCapsule(VoteWitnessContract voteWitnessContract) { + createTransaction(voteWitnessContract, ContractType.VoteWitnessContract); + } + + public TransactionCapsule(WitnessCreateContract witnessCreateContract) { + createTransaction(witnessCreateContract, ContractType.WitnessCreateContract); + } + + public TransactionCapsule(WitnessUpdateContract witnessUpdateContract) { + createTransaction(witnessUpdateContract, ContractType.WitnessUpdateContract); + } + + public TransactionCapsule(TransferAssetContract transferAssetContract) { + createTransaction(transferAssetContract, ContractType.TransferAssetContract); + } + + public TransactionCapsule(ParticipateAssetIssueContract participateAssetIssueContract) { + createTransaction(participateAssetIssueContract, ContractType.ParticipateAssetIssueContract); + } + + public void resetResult() { + if (this.getInstance().getRetCount() > 0) { + this.transaction = this.getInstance().toBuilder().clearRet().build(); + } + } + + public void setResult(TransactionResultCapsule transactionResultCapsule) { + this.transaction = this.getInstance().toBuilder().addRet(transactionResultCapsule.getInstance()) + .build(); + } + + public void setReference(long blockNum, byte[] blockHash) { + byte[] refBlockNum = ByteArray.fromLong(blockNum); + Transaction.raw rawData = this.transaction.getRawData().toBuilder() + .setRefBlockHash(ByteString.copyFrom(ByteArray.subArray(blockHash, 8, 16))) + .setRefBlockBytes(ByteString.copyFrom(ByteArray.subArray(refBlockNum, 6, 8))) + .build(); + this.transaction = this.transaction.toBuilder().setRawData(rawData).build(); + } + + /** + * @param expiration must be in milliseconds format + */ + public void setExpiration(long expiration) { + Transaction.raw rawData = this.transaction.getRawData().toBuilder().setExpiration(expiration) + .build(); + this.transaction = this.transaction.toBuilder().setRawData(rawData).build(); + } + + public long getExpiration() { + return transaction.getRawData().getExpiration(); + } + + public void setTimestamp() { + Transaction.raw rawData = this.transaction.getRawData().toBuilder() + .setTimestamp(System.currentTimeMillis()) + .build(); + this.transaction = this.transaction.toBuilder().setRawData(rawData).build(); + } + + public long getTimestamp() { + return transaction.getRawData().getTimestamp(); + } + + @Deprecated + public TransactionCapsule(AssetIssueContract assetIssueContract) { + createTransaction(assetIssueContract, ContractType.AssetIssueContract); + } + + public TransactionCapsule(com.google.protobuf.Message message, ContractType contractType) { + Transaction.raw.Builder transactionBuilder = Transaction.raw.newBuilder().addContract( + Transaction.Contract.newBuilder().setType(contractType).setParameter( + Any.pack(message)).build()); + transaction = Transaction.newBuilder().setRawData(transactionBuilder.build()).build(); + } + + @Deprecated + public void createTransaction(com.google.protobuf.Message message, ContractType contractType) { + Transaction.raw.Builder transactionBuilder = Transaction.raw.newBuilder().addContract( + Transaction.Contract.newBuilder().setType(contractType).setParameter( + Any.pack(message)).build()); + transaction = Transaction.newBuilder().setRawData(transactionBuilder.build()).build(); + } + + public Sha256Hash getMerkleHash() { + byte[] transBytes = this.transaction.toByteArray(); + return Sha256Hash.of(transBytes); + } + + private Sha256Hash getRawHash() { + return Sha256Hash.of(this.transaction.getRawData().toByteArray()); + } + + /** + * check balance of the address. + */ + public boolean checkBalance(byte[] address, byte[] to, long amount, long balance) { + if (!Wallet.addressValid(address)) { + logger.error("address invalid"); + return false; + } + + if (!Wallet.addressValid(to)) { + logger.error("address invalid"); + return false; + } + + if (amount <= 0) { + logger.error("amount required a positive number"); + return false; + } + + if (amount > balance) { + logger.error("don't have enough money"); + return false; + } + + return true; + } + + public void sign(byte[] privateKey) { + ECKey ecKey = ECKey.fromPrivate(privateKey); + ECDSASignature signature = ecKey.sign(getRawHash().getBytes()); + ByteString sig = ByteString.copyFrom(signature.toByteArray()); + this.transaction = this.transaction.toBuilder().addSignature(sig).build(); + } + + // todo mv this static function to capsule util + public static byte[] getOwner(Transaction.Contract contract) { + ByteString owner; + try { + Any contractParameter = contract.getParameter(); + switch (contract.getType()) { + case AccountCreateContract: + owner = contractParameter.unpack(AccountCreateContract.class).getOwnerAddress(); + break; + case TransferContract: + owner = contractParameter.unpack(TransferContract.class).getOwnerAddress(); + break; + case TransferAssetContract: + owner = contractParameter.unpack(TransferAssetContract.class).getOwnerAddress(); + break; + case VoteAssetContract: + owner = contractParameter.unpack(VoteAssetContract.class).getOwnerAddress(); + break; + case VoteWitnessContract: + owner = contractParameter.unpack(VoteWitnessContract.class).getOwnerAddress(); + break; + case WitnessCreateContract: + owner = contractParameter.unpack(WitnessCreateContract.class).getOwnerAddress(); + break; + case AssetIssueContract: + owner = contractParameter.unpack(AssetIssueContract.class).getOwnerAddress(); + break; + case WitnessUpdateContract: + owner = contractParameter.unpack(WitnessUpdateContract.class).getOwnerAddress(); + break; + case ParticipateAssetIssueContract: + owner = contractParameter.unpack(ParticipateAssetIssueContract.class).getOwnerAddress(); + break; + case AccountUpdateContract: + owner = contractParameter.unpack(AccountUpdateContract.class).getOwnerAddress(); + break; + case FreezeBalanceContract: + owner = contractParameter.unpack(FreezeBalanceContract.class).getOwnerAddress(); + break; + case UnfreezeBalanceContract: + owner = contractParameter.unpack(UnfreezeBalanceContract.class).getOwnerAddress(); + break; + case UnfreezeAssetContract: + owner = contractParameter.unpack(UnfreezeAssetContract.class).getOwnerAddress(); + break; + case WithdrawBalanceContract: + owner = contractParameter.unpack(WithdrawBalanceContract.class).getOwnerAddress(); + break; + case CreateSmartContract: + owner = contractParameter.unpack(Contract.CreateSmartContract.class).getOwnerAddress(); + break; + case TriggerSmartContract: + owner = contractParameter.unpack(Contract.TriggerSmartContract.class).getOwnerAddress(); + break; + case UpdateAssetContract: + owner = contractParameter.unpack(UpdateAssetContract.class).getOwnerAddress(); + break; + case ProposalCreateContract: + owner = contractParameter.unpack(ProposalCreateContract.class).getOwnerAddress(); + break; + case ProposalApproveContract: + owner = contractParameter.unpack(ProposalApproveContract.class).getOwnerAddress(); + break; + case ProposalDeleteContract: + owner = contractParameter.unpack(ProposalDeleteContract.class).getOwnerAddress(); + break; + case SetAccountIdContract: + owner = contractParameter.unpack(SetAccountIdContract.class).getOwnerAddress(); + break; +// case BuyStorageContract: +// owner = contractParameter.unpack(BuyStorageContract.class).getOwnerAddress(); +// break; +// case BuyStorageBytesContract: +// owner = contractParameter.unpack(BuyStorageBytesContract.class).getOwnerAddress(); +// break; +// case SellStorageContract: +// owner = contractParameter.unpack(SellStorageContract.class).getOwnerAddress(); +// break; + case UpdateSettingContract: + owner = contractParameter.unpack(UpdateSettingContract.class) + .getOwnerAddress(); + break; + case ExchangeCreateContract: + owner = contractParameter.unpack(ExchangeCreateContract.class).getOwnerAddress(); + break; + case ExchangeInjectContract: + owner = contractParameter.unpack(ExchangeInjectContract.class).getOwnerAddress(); + break; + case ExchangeWithdrawContract: + owner = contractParameter.unpack(ExchangeWithdrawContract.class).getOwnerAddress(); + break; + case ExchangeTransactionContract: + owner = contractParameter.unpack(ExchangeTransactionContract.class).getOwnerAddress(); + break; + // todo add other contract + default: + return null; + } + return owner.toByteArray(); + } catch (Exception ex) { + logger.error(ex.getMessage()); + return null; + } + } + + // todo mv this static function to capsule util + public static byte[] getToAddress(Transaction.Contract contract) { + ByteString to; + try { + Any contractParameter = contract.getParameter(); + switch (contract.getType()) { + case TransferContract: + to = contractParameter.unpack(TransferContract.class).getToAddress(); + break; + case TransferAssetContract: + to = contractParameter.unpack(TransferAssetContract.class).getToAddress(); + break; + case ParticipateAssetIssueContract: + to = contractParameter.unpack(ParticipateAssetIssueContract.class).getToAddress(); + break; + // todo add other contract + + default: + return null; + } + return to.toByteArray(); + } catch (Exception ex) { + logger.error(ex.getMessage()); + return null; + } + } + + // todo mv this static function to capsule util + public static long getCallValue(Transaction.Contract contract) { + int energyForTrx; + try { + Any contractParameter = contract.getParameter(); + long callValue; + switch (contract.getType()) { + case TriggerSmartContract: + return contractParameter.unpack(TriggerSmartContract.class).getCallValue(); + + case CreateSmartContract: + return contractParameter.unpack(CreateSmartContract.class).getNewContract() + .getCallValue(); + default: + return 0L; + } + } catch (Exception ex) { + logger.error(ex.getMessage()); + return 0L; + } + } + + public static String getBase64FromByteString(ByteString sign) { + byte[] r = sign.substring(0, 32).toByteArray(); + byte[] s = sign.substring(32, 64).toByteArray(); + byte v = sign.byteAt(64); + if (v < 27) { + v += 27; //revId -> v + } + ECDSASignature signature = ECDSASignature.fromComponents(r, s, v); + return signature.toBase64(); + } + + + /** + * validate signature + */ + public boolean validateSignature() throws ValidateSignatureException { + if (isVerified == true) { + return true; + } + + if (this.getInstance().getSignatureCount() != + this.getInstance().getRawData().getContractCount()) { + throw new ValidateSignatureException("miss sig or contract"); + } + + List listContract = this.transaction.getRawData().getContractList(); + for (int i = 0; i < this.transaction.getSignatureCount(); ++i) { + try { + Transaction.Contract contract = listContract.get(i); + byte[] owner = getOwner(contract); + byte[] address = ECKey.signatureToAddress(getRawHash().getBytes(), + getBase64FromByteString(this.transaction.getSignature(i))); + if (!Arrays.equals(owner, address)) { + isVerified = false; + throw new ValidateSignatureException("sig error"); + } + } catch (SignatureException e) { + isVerified = false; + throw new ValidateSignatureException(e.getMessage()); + } + } + + isVerified = true; + return true; + } + + public Sha256Hash getTransactionId() { + return getRawHash(); + } + + @Override + public byte[] getData() { + return this.transaction.toByteArray(); + } + + public long getSerializedSize() { + return this.transaction.getSerializedSize(); + } + + @Override + public Transaction getInstance() { + return this.transaction; + } + + private StringBuffer toStringBuff = new StringBuffer(); + + @Override + public String toString() { + + toStringBuff.setLength(0); + toStringBuff.append("TransactionCapsule \n[ "); + + toStringBuff.append("hash=").append(getTransactionId()).append("\n"); + AtomicInteger i = new AtomicInteger(); + if (!getInstance().getRawData().getContractList().isEmpty()) { + toStringBuff.append("contract list:{ "); + getInstance().getRawData().getContractList().forEach(contract -> { + toStringBuff.append("[" + i + "] ").append("type: ").append(contract.getType()) + .append("\n"); + toStringBuff.append("from address=").append(getOwner(contract)).append("\n"); + toStringBuff.append("to address=").append(getToAddress(contract)).append("\n"); + if (contract.getType().equals(ContractType.TransferContract)) { + TransferContract transferContract; + try { + transferContract = contract.getParameter() + .unpack(TransferContract.class); + toStringBuff.append("transfer amount=").append(transferContract.getAmount()) + .append("\n"); + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + } else if (contract.getType().equals(ContractType.TransferAssetContract)) { + TransferAssetContract transferAssetContract; + try { + transferAssetContract = contract.getParameter() + .unpack(TransferAssetContract.class); + toStringBuff.append("transfer asset=").append(transferAssetContract.getAssetName()) + .append("\n"); + toStringBuff.append("transfer amount=").append(transferAssetContract.getAmount()) + .append("\n"); + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + } + if (this.transaction.getSignatureList().size() >= i.get() + 1) { + toStringBuff.append("sign=").append(getBase64FromByteString( + this.transaction.getSignature(i.getAndIncrement()))).append("\n"); + } + }); + toStringBuff.append("}\n"); + } else { + toStringBuff.append("contract list is empty\n"); + } + + toStringBuff.append("]"); + return toStringBuff.toString(); + } +} diff --git a/src/main/java/org/tron/core/capsule/TransactionInfoCapsule.java b/src/main/java/org/tron/core/capsule/TransactionInfoCapsule.java index 8ed29ac6c5e..4670d9067f5 100644 --- a/src/main/java/org/tron/core/capsule/TransactionInfoCapsule.java +++ b/src/main/java/org/tron/core/capsule/TransactionInfoCapsule.java @@ -2,9 +2,19 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.tron.common.runtime.Runtime; +import org.tron.common.runtime.vm.LogInfo; +import org.tron.common.runtime.vm.program.ProgramResult; import org.tron.core.exception.BadItemException; +import org.tron.protos.Protocol.Block; import org.tron.protos.Protocol.TransactionInfo; +import org.tron.protos.Protocol.TransactionInfo.Log; +import org.tron.protos.Protocol.TransactionInfo.code; @Slf4j public class TransactionInfoCapsule implements ProtoCapsule { @@ -43,10 +53,36 @@ public byte[] getId() { return transactionInfo.getId().toByteArray(); } + + public void setUnfreezeAmount(long amount) { + this.transactionInfo = this.transactionInfo.toBuilder().setUnfreezeAmount(amount).build(); + } + + public long getUnfreezeAmount() { + return transactionInfo.getUnfreezeAmount(); + } + + public void setWithdrawAmount(long amount) { + this.transactionInfo = this.transactionInfo.toBuilder().setWithdrawAmount(amount).build(); + } + + public long getWithdrawAmount() { + return transactionInfo.getWithdrawAmount(); + } + public void setFee(long fee) { this.transactionInfo = this.transactionInfo.toBuilder().setFee(fee).build(); } + public void setResult(code result) { + this.transactionInfo = this.transactionInfo.toBuilder().setResult(result).build(); + } + + public void setResMessage(String message) { + this.transactionInfo = this.transactionInfo.toBuilder() + .setResMessage(ByteString.copyFromUtf8(message)).build(); + } + public void addFee(long fee) { this.transactionInfo = this.transactionInfo.toBuilder() .setFee(this.transactionInfo.getFee() + fee).build(); @@ -78,8 +114,21 @@ public void setContractResult(byte[] ret) { public void setContractAddress(byte[] contractAddress) { this.transactionInfo = this.transactionInfo.toBuilder() - .setContractAddress(ByteString.copyFrom(contractAddress)) - .build(); + .setContractAddress(ByteString.copyFrom(contractAddress)) + .build(); + } + + public void setReceipt(ReceiptCapsule receipt) { + this.transactionInfo = this.transactionInfo.toBuilder() + .setReceipt(receipt.getReceipt()) + .build(); + } + + + public void addAllLog(List logs) { + this.transactionInfo = this.transactionInfo.toBuilder() + .addAllLog(logs) + .build(); } @Override @@ -91,4 +140,45 @@ public byte[] getData() { public TransactionInfo getInstance() { return this.transactionInfo; } + + public static TransactionInfoCapsule buildInstance(TransactionCapsule trxCap, Block block, + Runtime runtime, ReceiptCapsule traceReceipt) { + + TransactionInfo.Builder builder = TransactionInfo.newBuilder(); + + builder.setResult(code.SUCESS); + if (StringUtils.isNoneEmpty(runtime.getRuntimeError())) { + builder.setResult(code.FAILED); + builder.setResMessage(ByteString.copyFromUtf8(runtime.getRuntimeError())); + } + builder.setId(ByteString.copyFrom(trxCap.getTransactionId().getBytes())); + + ProgramResult programResult = runtime.getResult(); + long fee = programResult.getRet().getFee() + traceReceipt.getEnergyFee(); + ByteString contractResult = ByteString.copyFrom(programResult.getHReturn()); + ByteString ContractAddress = ByteString.copyFrom(programResult.getContractAddress()); + + builder.setFee(fee); + builder.addContractResult(contractResult); + builder.setContractAddress(ContractAddress); + builder.setUnfreezeAmount(programResult.getRet().getUnfreezeAmount()); + builder.setWithdrawAmount(programResult.getRet().getWithdrawAmount()); + + List logList = new ArrayList<>(); + programResult.getLogInfoList().forEach( + logInfo -> { + logList.add(LogInfo.buildLog(logInfo)); + } + ); + builder.addAllLog(logList); + + if (Objects.nonNull(block)) { + builder.setBlockNumber(block.getBlockHeader().getRawData().getNumber()); + builder.setBlockTimeStamp(block.getBlockHeader().getRawData().getTimestamp()); + } + + builder.setReceipt(traceReceipt.getReceipt()); + + return new TransactionInfoCapsule(builder.build()); + } } \ No newline at end of file diff --git a/src/main/java/org/tron/core/capsule/TransactionResultCapsule.java b/src/main/java/org/tron/core/capsule/TransactionResultCapsule.java index 13e79f763e7..5582b679445 100644 --- a/src/main/java/org/tron/core/capsule/TransactionResultCapsule.java +++ b/src/main/java/org/tron/core/capsule/TransactionResultCapsule.java @@ -46,17 +46,24 @@ public long getFee() { return transactionResult.getFee(); } - public void setFee(long fee) { - this.transactionResult = this.transactionResult.toBuilder().setFee(fee).build(); + public void setUnfreezeAmount(long amount) { + this.transactionResult = this.transactionResult.toBuilder().setUnfreezeAmount(amount).build(); } - public byte[] getConstantResult() { - return transactionResult.getConstantResult().toByteArray(); + public long getUnfreezeAmount() { + return transactionResult.getUnfreezeAmount(); } - public void setConstantResult(byte[] constantResult) { - this.transactionResult = this.transactionResult.toBuilder() - .setConstantResult(ByteString.copyFrom(constantResult)).build(); + public void setWithdrawAmount(long amount) { + this.transactionResult = this.transactionResult.toBuilder().setWithdrawAmount(amount).build(); + } + + public long getWithdrawAmount() { + return transactionResult.getWithdrawAmount(); + } + + public void setFee(long fee) { + this.transactionResult = this.transactionResult.toBuilder().setFee(fee).build(); } public void addFee(long fee) { diff --git a/src/main/java/org/tron/core/capsule/utils/ExchangeProcessor.java b/src/main/java/org/tron/core/capsule/utils/ExchangeProcessor.java new file mode 100644 index 00000000000..65a46f1a876 --- /dev/null +++ b/src/main/java/org/tron/core/capsule/utils/ExchangeProcessor.java @@ -0,0 +1,62 @@ +package org.tron.core.capsule.utils; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ExchangeProcessor { + + private long supply; + + public ExchangeProcessor(long supply) { + this.supply = supply; + } + + private long exchange_to_supply(long balance, long quant) { + logger.info("balance: " + balance); + long newBalance = balance + quant; + logger.info("balance + quant: " + newBalance); + + double issuedSupply = -supply * (1.0 - Math.pow(1.0 + (double) quant / newBalance, 0.0005)); + logger.info("issuedSupply: " + issuedSupply); + long out = (long) issuedSupply; + supply += out; + + return out; + } + + private long exchange_to_supply2(long balance, long quant) { + logger.info("balance: " + balance); + long newBalance = balance - quant; + logger.info("balance - quant: " + (balance - quant)); + + double issuedSupply = -supply * (1.0 - Math.pow(1.0 + (double) quant / newBalance, 0.0005)); + logger.info("issuedSupply: " + issuedSupply); + long out = (long) issuedSupply; + supply += out; + + return out; + } + + private long exchange_from_supply(long balance, long supplyQuant) { + supply -= supplyQuant; + + double exchangeBalance = + balance * (Math.pow(1.0 + (double) supplyQuant / supply, 2000.0) - 1.0); + logger.info("exchangeBalance: " + exchangeBalance); + long out = (long) exchangeBalance; + long newBalance = balance - out; + +// if (isTRX) { +// out = Math.round(exchangeBalance / 100000) * 100000; +// logger.info("---out: " + out); +// } + + return out; + } + + public long exchange(long sellTokenBalance, long buyTokenBalance, long sellTokenQuant) { + long relay = exchange_to_supply(sellTokenBalance, sellTokenQuant); + return exchange_from_supply(buyTokenBalance, relay); + } + +} diff --git a/src/main/java/org/tron/core/config/Parameter.java b/src/main/java/org/tron/core/config/Parameter.java index ba844f71b78..7b0cdfc7a95 100644 --- a/src/main/java/org/tron/core/config/Parameter.java +++ b/src/main/java/org/tron/core/config/Parameter.java @@ -23,7 +23,7 @@ interface ChainConstant { int BLOCK_FILLED_SLOTS_NUMBER = 128; int MAX_VOTE_NUMBER = 30; int MAX_FROZEN_NUMBER = 1; - + int version = 1; } interface NodeConstant { @@ -57,15 +57,17 @@ interface DatabaseConstants { } enum ChainParameters { - MAINTENANCE_TIME_INTERVAL, //ms - ACCOUNT_UPGRADE_COST, //drop - CREATE_ACCOUNT_FEE, //drop - TRANSACTION_FEE, //drop - ASSET_ISSUE_FEE, //drop - WITNESS_PAY_PER_BLOCK, //drop - WITNESS_STANDBY_ALLOWANCE, //drop - CREATE_NEW_ACCOUNT_FEE_IN_SYSTEM_CONTRACT, //drop - CREATE_NEW_ACCOUNT_BANDWIDTH_RATE, // 1 ~ + MAINTENANCE_TIME_INTERVAL, //ms ,0 + ACCOUNT_UPGRADE_COST, //drop ,1 + CREATE_ACCOUNT_FEE, //drop ,2 + TRANSACTION_FEE, //drop ,3 + ASSET_ISSUE_FEE, //drop ,4 + WITNESS_PAY_PER_BLOCK, //drop ,5 + WITNESS_STANDBY_ALLOWANCE, //drop ,6 + CREATE_NEW_ACCOUNT_FEE_IN_SYSTEM_CONTRACT, //drop ,7 + CREATE_NEW_ACCOUNT_BANDWIDTH_RATE, // 1 ~ ,8 + ALLOW_CREATION_OF_CONTRACTS, // 0 / >0 ,9 + REMOVE_THE_POWER_OF_THE_GR // 1 ,10 // ONE_DAY_NET_LIMIT, // MAX_FROZEN_TIME, // MIN_FROZEN_TIME, diff --git a/src/main/java/org/tron/core/config/args/Args.java b/src/main/java/org/tron/core/config/args/Args.java index b96c2a6bff3..09248fd33ae 100644 --- a/src/main/java/org/tron/core/config/args/Args.java +++ b/src/main/java/org/tron/core/config/args/Args.java @@ -34,7 +34,6 @@ import org.tron.common.crypto.ECKey; import org.tron.common.overlay.discover.node.Node; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.StringUtil; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.config.Configuration; @@ -66,6 +65,11 @@ public class Args { @Parameter(names = {"-w", "--witness"}) private boolean witness = false; + @Getter + @Setter + @Parameter(names = {"--debug"}) + private boolean debug = false; + @Getter @Parameter(description = "--seed-nodes") private List seedNodes = new ArrayList<>(); @@ -273,6 +277,22 @@ public class Args { @Setter private double activeConnectFactor; + @Getter + @Setter + private double disconnectNumberFactor; + + @Getter + @Setter + private double maxConnectNumberFactor; + + @Getter + @Setter + private long receiveTcpMinDataLength; + + @Getter + @Setter + private boolean isOpenFullTcpDisconnect; + public static void clearParam() { INSTANCE.outputDirectory = "output-directory"; INSTANCE.help = false; @@ -324,6 +344,10 @@ public static void clearParam() { INSTANCE.walletExtensionApi = false; INSTANCE.connectFactor = 0.3; INSTANCE.activeConnectFactor = 0.1; + INSTANCE.disconnectNumberFactor = 0.4; + INSTANCE.maxConnectNumberFactor = 0.8; + INSTANCE.receiveTcpMinDataLength = 2048; + INSTANCE.isOpenFullTcpDisconnect = false; } /** @@ -545,6 +569,15 @@ public static void setParam(final String[] args, final String confFileName) { INSTANCE.activeConnectFactor = config.hasPath("node.activeConnectFactor") ? config.getDouble("node.activeConnectFactor") : 0.1; + INSTANCE.disconnectNumberFactor = config.hasPath("node.disconnectNumberFactor") ? + config.getDouble("node.disconnectNumberFactor") : 0.4; + INSTANCE.maxConnectNumberFactor = config.hasPath("node.maxConnectNumberFactor") ? + config.getDouble("node.maxConnectNumberFactor") : 0.8; + INSTANCE.receiveTcpMinDataLength = config.hasPath("node.receiveTcpMinDataLength") ? + config.getLong("node.receiveTcpMinDataLength") : 2048; + INSTANCE.isOpenFullTcpDisconnect = config.hasPath("node.isOpenFullTcpDisconnect") && config + .getBoolean("node.isOpenFullTcpDisconnect"); + initBackupProperty(config); logConfig(); diff --git a/src/main/java/org/tron/core/db/AccountContractIndexStore.java b/src/main/java/org/tron/core/db/AccountContractIndexStore.java deleted file mode 100644 index 044ed4bbafa..00000000000 --- a/src/main/java/org/tron/core/db/AccountContractIndexStore.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.tron.core.db; - -import java.util.Objects; -import org.apache.commons.lang3.ArrayUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.tron.core.capsule.BytesCapsule; - -@Component -public class AccountContractIndexStore extends TronStoreWithRevoking { - - @Autowired - public AccountContractIndexStore(@Value("account-contract-index") String dbName) { - super(dbName); - } - - @Override - public BytesCapsule get(byte[] key) { - byte[] value = revokingDB.getUnchecked(key); - if (Objects.nonNull(value)) { - return new BytesCapsule(value); - } - return null; - } - - public void put(BytesCapsule normalAccountAddress, BytesCapsule contractAddress) { - super.put(normalAccountAddress.getData(), contractAddress); - } - - @Override - public boolean has(byte[] key) { - byte[] value = revokingDB.getUnchecked(key); - if (ArrayUtils.isEmpty(value)) { - return false; - } - return true; - } - -} \ No newline at end of file diff --git a/src/main/java/org/tron/core/db/BandwidthProcessor.java b/src/main/java/org/tron/core/db/BandwidthProcessor.java index 553213db348..e3169e0fecd 100644 --- a/src/main/java/org/tron/core/db/BandwidthProcessor.java +++ b/src/main/java/org/tron/core/db/BandwidthProcessor.java @@ -12,9 +12,7 @@ import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.TransactionResultCapsule; -import org.tron.core.config.Parameter.ChainConstant; import org.tron.core.exception.AccountResourceInsufficientException; -import org.tron.core.exception.BalanceInsufficientException; import org.tron.core.exception.ContractValidateException; import org.tron.protos.Contract.TransferAssetContract; import org.tron.protos.Contract.TransferContract; @@ -50,7 +48,8 @@ private void updateUsage(AccountCapsule accountCapsule, long now) { } @Override - public void consume(TransactionCapsule trx, TransactionResultCapsule ret) + public void consume(TransactionCapsule trx, TransactionResultCapsule ret, + TransactionTrace trace) throws ContractValidateException, AccountResourceInsufficientException { List contracts = trx.getInstance().getRawData().getContractList(); @@ -58,15 +57,17 @@ public void consume(TransactionCapsule trx, TransactionResultCapsule ret) for (Contract contract : contracts) { long bytes = trx.getSerializedSize(); logger.debug("trxId {},bandwidth cost :{}", trx.getTransactionId(), bytes); + trace.setNetBill(bytes, 0); byte[] address = TransactionCapsule.getOwner(contract); AccountCapsule accountCapsule = dbManager.getAccountStore().get(address); - if (accountCapsule == null) { + if (accountCapsule == null) { throw new ContractValidateException("account not exists"); } long now = dbManager.getWitnessController().getHeadSlot(); if (contractCreateNewAccount(contract)) { consumeForCreateNewAccount(accountCapsule, bytes, now, ret); + trace.setNetBill(0, ret.getFee()); continue; } @@ -85,6 +86,7 @@ public void consume(TransactionCapsule trx, TransactionResultCapsule ret) } if (useTransactionFee(accountCapsule, bytes, ret)) { + trace.setNetBill(0, ret.getFee()); continue; } @@ -135,7 +137,8 @@ public boolean consumeBandwidthForCreateNewAccount(AccountCapsule accountCapsule if (bytes * createNewAccountBandwidthRatio <= (netLimit - newNetUsage)) { latestConsumeTime = now; long latestOperationTime = dbManager.getHeadBlockTimeStamp(); - newNetUsage = increase(newNetUsage, bytes * createNewAccountBandwidthRatio, latestConsumeTime, now); + newNetUsage = increase(newNetUsage, bytes * createNewAccountBandwidthRatio, latestConsumeTime, + now); accountCapsule.setLatestConsumeTime(latestConsumeTime); accountCapsule.setLatestOperationTime(latestOperationTime); accountCapsule.setNetUsage(newNetUsage); diff --git a/src/main/java/org/tron/core/db/DynamicPropertiesStore.java b/src/main/java/org/tron/core/db/DynamicPropertiesStore.java index ea8a04d4982..3d273c66b46 100755 --- a/src/main/java/org/tron/core/db/DynamicPropertiesStore.java +++ b/src/main/java/org/tron/core/db/DynamicPropertiesStore.java @@ -9,7 +9,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import org.tron.common.runtime.vm.PrecompiledContracts; import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.BytesCapsule; @@ -32,6 +31,8 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking private static final byte[] LATEST_PROPOSAL_NUM = "LATEST_PROPOSAL_NUM".getBytes(); + private static final byte[] LATEST_EXCHANGE_NUM = "LATEST_EXCHANGE_NUM".getBytes(); + private static final byte[] BLOCK_FILLED_SLOTS = "BLOCK_FILLED_SLOTS".getBytes(); private static final byte[] BLOCK_FILLED_SLOTS_INDEX = "BLOCK_FILLED_SLOTS_INDEX".getBytes(); @@ -74,9 +75,11 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking //ONE_DAY_NET_LIMIT - PUBLIC_NET_LIMIT private static final byte[] TOTAL_NET_LIMIT = "TOTAL_NET_LIMIT".getBytes(); - private static final byte[] TOTAL_CPU_WEIGHT = "TOTAL_CPU_WEIGHT".getBytes(); + private static final byte[] TOTAL_ENERGY_WEIGHT = "TOTAL_ENERGY_WEIGHT".getBytes(); + + private static final byte[] TOTAL_ENERGY_LIMIT = "TOTAL_ENERGY_LIMIT".getBytes(); - private static final byte[] TOTAL_CPU_LIMIT = "TOTAL_CPU_LIMIT".getBytes(); + private static final byte[] ENERGY_FEE = "ENERGY_FEE".getBytes(); //abandon private static final byte[] CREATE_ACCOUNT_FEE = "CREATE_ACCOUNT_FEE".getBytes(); @@ -91,6 +94,10 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking private static final byte[] ASSET_ISSUE_FEE = "ASSET_ISSUE_FEE".getBytes(); + private static final byte[] EXCHANGE_CREATE_FEE = "EXCHANGE_CREATE_FEE".getBytes(); + + private static final byte[] EXCHANGE_BALANCE_LIMIT = "EXCHANGE_BALANCE_LIMIT".getBytes(); + private static final byte[] TOTAL_TRANSACTION_COST = "TOTAL_TRANSACTION_COST".getBytes(); private static final byte[] TOTAL_CREATE_ACCOUNT_COST = "TOTAL_CREATE_ACCOUNT_COST".getBytes(); @@ -105,6 +112,16 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking private static final byte[] STORAGE_EXCHANGE_TAX_RATE = "STORAGE_EXCHANGE_TAX_RATE".getBytes(); + private static final byte[] FORK_CONTROLLER = "FORK_CONTROLLER".getBytes(); + + //This value is only allowed to be 0, 1, -1 + private static final byte[] REMOVE_THE_POWER_OF_THE_GR = "REMOVE_THE_POWER_OF_THE_GR".getBytes(); + + //If the parameter is larger than 0, the contract is allowed to be created. + private static final byte[] ALLOW_CREATION_OF_CONTRACTS = "ALLOW_CREATION_OF_CONTRACTS" + .getBytes(); + + @Autowired private DynamicPropertiesStore(@Value("properties") String dbName) { super(dbName); @@ -145,6 +162,12 @@ private DynamicPropertiesStore(@Value("properties") String dbName) { this.saveLatestProposalNum(0); } + try { + this.getLatestExchangeNum(); + } catch (IllegalArgumentException e) { + this.saveLatestExchangeNum(0); + } + try { this.getBlockFilledSlotsIndex(); } catch (IllegalArgumentException e) { @@ -254,15 +277,21 @@ private DynamicPropertiesStore(@Value("properties") String dbName) { } try { - this.getTotalCpuWeight(); + this.getTotalEnergyWeight(); + } catch (IllegalArgumentException e) { + this.saveTotalEnergyWeight(0L); + } + + try { + this.getTotalEnergyLimit(); } catch (IllegalArgumentException e) { - this.saveTotalCpuWeight(0L); + this.saveTotalEnergyLimit(50_000_000_000L); } try { - this.getTotalCpuLimit(); + this.getEnergyFee(); } catch (IllegalArgumentException e) { - this.saveTotalCpuLimit(32400_000_000L); + this.saveEnergyFee(100L);// 100 sun per energy } try { @@ -286,7 +315,7 @@ private DynamicPropertiesStore(@Value("properties") String dbName) { try { this.getTransactionFee(); } catch (IllegalArgumentException e) { - this.saveTransactionFee(10L); // 10Drop/byte + this.saveTransactionFee(10L); // 10sun/byte } try { @@ -295,6 +324,18 @@ private DynamicPropertiesStore(@Value("properties") String dbName) { this.saveAssetIssueFee(1024000000L); } + try { + this.getExchangeCreateFee(); + } catch (IllegalArgumentException e) { + this.saveExchangeCreateFee(1024000000L); + } + + try { + this.getExchangeBalanceLimit(); + } catch (IllegalArgumentException e) { + this.saveExchangeBalanceLimit(1_000_000_000_000_000L); + } + try { this.getTotalTransactionCost(); } catch (IllegalArgumentException e) { @@ -337,6 +378,18 @@ private DynamicPropertiesStore(@Value("properties") String dbName) { this.saveStorageExchangeTaxRate(10); } + try { + this.getRemoveThePowerOfTheGr(); + } catch (IllegalArgumentException e) { + this.saveRemoveThePowerOfTheGr(0); + } + + try { + this.getAllowCreationOfContracts(); + } catch (IllegalArgumentException e) { + this.saveAllowCreationOfContracts(0L); + } + try { this.getBlockFilledSlots(); } catch (IllegalArgumentException e) { @@ -603,17 +656,17 @@ public long getTotalNetWeight() { () -> new IllegalArgumentException("not found TOTAL_NET_WEIGHT")); } - public void saveTotalCpuWeight(long totalCpuWeight) { - this.put(TOTAL_CPU_WEIGHT, - new BytesCapsule(ByteArray.fromLong(totalCpuWeight))); + public void saveTotalEnergyWeight(long totalEnergyWeight) { + this.put(TOTAL_ENERGY_WEIGHT, + new BytesCapsule(ByteArray.fromLong(totalEnergyWeight))); } - public long getTotalCpuWeight() { - return Optional.ofNullable(getUnchecked(TOTAL_CPU_WEIGHT)) + public long getTotalEnergyWeight() { + return Optional.ofNullable(getUnchecked(TOTAL_ENERGY_WEIGHT)) .map(BytesCapsule::getData) .map(ByteArray::toLong) .orElseThrow( - () -> new IllegalArgumentException("not found TOTAL_CPU_WEIGHT")); + () -> new IllegalArgumentException("not found TOTAL_ENERGY_WEIGHT")); } @@ -630,17 +683,31 @@ public long getTotalNetLimit() { () -> new IllegalArgumentException("not found TOTAL_NET_LIMIT")); } - public void saveTotalCpuLimit(long totalCpuLimit) { - this.put(TOTAL_CPU_LIMIT, - new BytesCapsule(ByteArray.fromLong(totalCpuLimit))); + public void saveTotalEnergyLimit(long totalEnergyLimit) { + this.put(TOTAL_ENERGY_LIMIT, + new BytesCapsule(ByteArray.fromLong(totalEnergyLimit))); } - public long getTotalCpuLimit() { - return Optional.ofNullable(getUnchecked(TOTAL_CPU_LIMIT)) + public long getTotalEnergyLimit() { + return Optional.ofNullable(getUnchecked(TOTAL_ENERGY_LIMIT)) .map(BytesCapsule::getData) .map(ByteArray::toLong) .orElseThrow( - () -> new IllegalArgumentException("not found TOTAL_CPU_LIMIT")); + () -> new IllegalArgumentException("not found TOTAL_ENERGY_LIMIT")); + } + + + public void saveEnergyFee(long totalEnergyFee) { + this.put(ENERGY_FEE, + new BytesCapsule(ByteArray.fromLong(totalEnergyFee))); + } + + public long getEnergyFee() { + return Optional.ofNullable(getUnchecked(ENERGY_FEE)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found ENERGY_FEE")); } public void saveCreateAccountFee(long fee) { @@ -709,6 +776,32 @@ public long getAssetIssueFee() { () -> new IllegalArgumentException("not found ASSET_ISSUE_FEE")); } + public void saveExchangeCreateFee(long fee) { + this.put(EXCHANGE_CREATE_FEE, + new BytesCapsule(ByteArray.fromLong(fee))); + } + + public long getExchangeCreateFee() { + return Optional.ofNullable(getUnchecked(EXCHANGE_CREATE_FEE)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found EXCHANGE_CREATE_FEE")); + } + + public void saveExchangeBalanceLimit(long limit) { + this.put(EXCHANGE_BALANCE_LIMIT, + new BytesCapsule(ByteArray.fromLong(limit))); + } + + public long getExchangeBalanceLimit() { + return Optional.ofNullable(getUnchecked(EXCHANGE_BALANCE_LIMIT)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found EXCHANGE_BALANCE_LIMIT")); + } + public void saveTotalTransactionCost(long value) { this.put(TOTAL_TRANSACTION_COST, new BytesCapsule(ByteArray.fromLong(value))); @@ -800,6 +893,38 @@ public long getStorageExchangeTaxRate() { () -> new IllegalArgumentException("not found STORAGE_EXCHANGE_TAX_RATE")); } + public void saveRemoveThePowerOfTheGr(long rate) { + this.put(REMOVE_THE_POWER_OF_THE_GR, + new BytesCapsule(ByteArray.fromLong(rate))); + } + + public long getRemoveThePowerOfTheGr() { + return Optional.ofNullable(getUnchecked(REMOVE_THE_POWER_OF_THE_GR)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found REMOVE_THE_POWER_OF_THE_GR")); + } + + + + public void saveAllowCreationOfContracts(long allowCreationOfContracts) { + this.put(DynamicPropertiesStore.ALLOW_CREATION_OF_CONTRACTS, + new BytesCapsule(ByteArray.fromLong(allowCreationOfContracts))); + } + + public long getAllowCreationOfContracts() { + return Optional.ofNullable(getUnchecked(ALLOW_CREATION_OF_CONTRACTS)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found ALLOW_CREATION_OF_CONTRACTS")); + } + + public boolean supportVM() { + return getAllowCreationOfContracts() == 1L; + } + public void saveBlockFilledSlots(int[] blockFilledSlots) { logger.debug("blockFilledSlots:" + intArrayToString(blockFilledSlots)); this.put(BLOCK_FILLED_SLOTS, @@ -857,6 +982,18 @@ public long getLatestProposalNum() { () -> new IllegalArgumentException("not found latest PROPOSAL_NUM")); } + public void saveLatestExchangeNum(long number) { + this.put(LATEST_EXCHANGE_NUM, new BytesCapsule(ByteArray.fromLong(number))); + } + + public long getLatestExchangeNum() { + return Optional.ofNullable(getUnchecked(LATEST_EXCHANGE_NUM)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found latest EXCHANGE_NUM")); + } + /** * get timestamp of creating global latest block. */ @@ -968,10 +1105,10 @@ public void addTotalNetWeight(long amount) { } //The unit is trx - public void addTotalCpuWeight(long amount) { - long totalCpuWeight = getTotalCpuWeight(); - totalCpuWeight += amount; - saveTotalCpuWeight(totalCpuWeight); + public void addTotalEnergyWeight(long amount) { + long totalEnergyWeight = getTotalEnergyWeight(); + totalEnergyWeight += amount; + saveTotalEnergyWeight(totalEnergyWeight); } public void addTotalCreateAccountCost(long fee) { @@ -988,4 +1125,13 @@ public void addTotalTransactionCost(long fee) { long newValue = getTotalTransactionCost() + fee; saveTotalTransactionCost(newValue); } + + public void forked() { + put(FORK_CONTROLLER, new BytesCapsule(Boolean.toString(true).getBytes())); + } + + public boolean getForked() { + byte[] value = revokingDB.getUnchecked(FORK_CONTROLLER); + return value == null ? Boolean.FALSE : Boolean.valueOf(new String(value)); + } } diff --git a/src/main/java/org/tron/core/db/CpuProcessor.java b/src/main/java/org/tron/core/db/EnergyProcessor.java similarity index 51% rename from src/main/java/org/tron/core/db/CpuProcessor.java rename to src/main/java/org/tron/core/db/EnergyProcessor.java index 25d5907d001..94cd460fce3 100644 --- a/src/main/java/org/tron/core/db/CpuProcessor.java +++ b/src/main/java/org/tron/core/db/EnergyProcessor.java @@ -1,6 +1,8 @@ package org.tron.core.db; +import static java.lang.Long.max; + import java.util.List; import lombok.extern.slf4j.Slf4j; import org.tron.core.capsule.AccountCapsule; @@ -12,9 +14,9 @@ import org.tron.protos.Protocol.Transaction.Contract; @Slf4j -public class CpuProcessor extends ResourceProcessor { +public class EnergyProcessor extends ResourceProcessor { - public CpuProcessor(Manager manager) { + public EnergyProcessor(Manager manager) { super(manager); } @@ -27,15 +29,16 @@ public void updateUsage(AccountCapsule accountCapsule) { private void updateUsage(AccountCapsule accountCapsule, long now) { AccountResource accountResource = accountCapsule.getAccountResource(); - long oldCpuUsage = accountResource.getCpuUsage(); - long latestConsumeTime = accountResource.getLatestConsumeTimeForCpu(); + long oldEnergyUsage = accountResource.getEnergyUsage(); + long latestConsumeTime = accountResource.getLatestConsumeTimeForEnergy(); - accountCapsule.setCpuUsage(increase(oldCpuUsage, 0, latestConsumeTime, now)); + accountCapsule.setEnergyUsage(increase(oldEnergyUsage, 0, latestConsumeTime, now)); } @Override - public void consume(TransactionCapsule trx, TransactionResultCapsule ret) + public void consume(TransactionCapsule trx, TransactionResultCapsule ret, + TransactionTrace trace) throws ContractValidateException, AccountResourceInsufficientException { List contracts = trx.getInstance().getRawData().getContractList(); @@ -47,9 +50,9 @@ public void consume(TransactionCapsule trx, TransactionResultCapsule ret) // continue; // } //todo -// long cpuTime = trx.getReceipt().getCpuTime(); - long cpuTime = 100L; - logger.debug("trxId {},cpu cost :{}", trx.getTransactionId(), cpuTime); +// long energy = trx.getReceipt().getEnergy(); + long energy = 100L; + logger.debug("trxId {},energy cost :{}", trx.getTransactionId(), energy); byte[] address = TransactionCapsule.getOwner(contract); AccountCapsule accountCapsule = dbManager.getAccountStore().get(address); if (accountCapsule == null) { @@ -58,29 +61,30 @@ public void consume(TransactionCapsule trx, TransactionResultCapsule ret) long now = dbManager.getWitnessController().getHeadSlot(); //todo -// int creatorRatio = contract.getUserCpuConsumeRatio(); +// int creatorRatio = contract.getUserEnergyConsumeRatio(); int creatorRatio = 50; - long creatorCpuTime = cpuTime * creatorRatio / 100; + long creatorEnergy = energy * creatorRatio / 100; AccountCapsule contractProvider = dbManager.getAccountStore() .get(contract.getProvider().toByteArray()); - if (!useCpu(contractProvider, creatorCpuTime, now)) { - throw new ContractValidateException("creator has not enough cpu[" + creatorCpuTime + "]"); + if (!useEnergy(contractProvider, creatorEnergy, now)) { + throw new ContractValidateException( + "creator has not enough energy[" + creatorEnergy + "]"); } - long userCpuTime = cpuTime * (100 - creatorRatio) / 100; + long userEnergy = energy * (100 - creatorRatio) / 100; //1.The creator and the use of this have sufficient resources - if (useCpu(accountCapsule, userCpuTime, now)) { + if (useEnergy(accountCapsule, userEnergy, now)) { continue; } // todo long feeLimit = getUserFeeLimit(); long feeLimit = 1000000;//sun - long fee = calculateFee(userCpuTime); + long fee = calculateFee(userEnergy); if (fee > feeLimit) { throw new AccountResourceInsufficientException( - "Account has Insufficient Cpu[" + userCpuTime + "] and feeLimit[" + feeLimit + "Account has Insufficient Energy[" + userEnergy + "] and feeLimit[" + feeLimit + "] is not enough to trigger this contract"); } @@ -90,13 +94,13 @@ public void consume(TransactionCapsule trx, TransactionResultCapsule ret) } throw new AccountResourceInsufficientException( - "Account has insufficient Cpu[" + userCpuTime + "] and balance[" + fee + "Account has insufficient Energy[" + userEnergy + "] and balance[" + fee + "] to trigger this contract"); } } - private long calculateFee(long userCpuTime) { - return userCpuTime * 30;// 30 drop / macroSecond, move to dynamicStore later + private long calculateFee(long userEnergy) { + return userEnergy * 30;// 30 drop / macroSecond, move to dynamicStore later } @@ -110,41 +114,56 @@ private boolean useFee(AccountCapsule accountCapsule, long fee, } } - public boolean useCpu(AccountCapsule accountCapsule, long cpuTime, long now) { + public boolean useEnergy(AccountCapsule accountCapsule, long energy, long now) { - long cpuUsage = accountCapsule.getCpuUsage(); - long latestConsumeTime = accountCapsule.getAccountResource().getLatestConsumeTimeForCpu(); - long cpuLimit = calculateGlobalCpuLimit( - accountCapsule.getAccountResource().getFrozenBalanceForCpu().getFrozenBalance()); + long energyUsage = accountCapsule.getEnergyUsage(); + long latestConsumeTime = accountCapsule.getAccountResource().getLatestConsumeTimeForEnergy(); + long energyLimit = calculateGlobalEnergyLimit( + accountCapsule.getAccountResource().getFrozenBalanceForEnergy().getFrozenBalance()); - long newCpuUsage = increase(cpuUsage, 0, latestConsumeTime, now); + long newEnergyUsage = increase(energyUsage, 0, latestConsumeTime, now); - if (cpuTime > (cpuLimit - newCpuUsage)) { + if (energy > (energyLimit - newEnergyUsage)) { return false; } latestConsumeTime = now; long latestOperationTime = dbManager.getHeadBlockTimeStamp(); - newCpuUsage = increase(newCpuUsage, cpuTime, latestConsumeTime, now); - accountCapsule.setCpuUsage(newCpuUsage); + newEnergyUsage = increase(newEnergyUsage, energy, latestConsumeTime, now); + accountCapsule.setEnergyUsage(newEnergyUsage); accountCapsule.setLatestOperationTime(latestOperationTime); - accountCapsule.setLatestConsumeTimeForCpu(latestConsumeTime); + accountCapsule.setLatestConsumeTimeForEnergy(latestConsumeTime); dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); return true; } - public long calculateGlobalCpuLimit(long frozeBalance) { + public long calculateGlobalEnergyLimit(long frozeBalance) { if (frozeBalance < 1000_000L) { return 0; } - long cpuWeight = frozeBalance / 1000_000L; - long totalCpuLimit = dbManager.getDynamicPropertiesStore().getTotalCpuLimit(); - long totalCpuWeight = dbManager.getDynamicPropertiesStore().getTotalCpuWeight(); - assert totalCpuWeight > 0; - return (long) (cpuWeight * ((double) totalCpuLimit / totalCpuWeight)); + long energyWeight = frozeBalance / 1000_000L; + long totalEnergyLimit = dbManager.getDynamicPropertiesStore().getTotalEnergyLimit(); + long totalEnergyWeight = dbManager.getDynamicPropertiesStore().getTotalEnergyWeight(); + assert totalEnergyWeight > 0; + return (long) (energyWeight * ((double) totalEnergyLimit / totalEnergyWeight)); } + + public long getAccountLeftEnergyFromFreeze(AccountCapsule accountCapsule) { + + long now = dbManager.getWitnessController().getHeadSlot(); + + long energyUsage = accountCapsule.getEnergyUsage(); + long latestConsumeTime = accountCapsule.getAccountResource().getLatestConsumeTimeForEnergy(); + long energyLimit = calculateGlobalEnergyLimit( + accountCapsule.getAccountResource().getFrozenBalanceForEnergy().getFrozenBalance()); + + long newEnergyUsage = increase(energyUsage, 0, latestConsumeTime, now); + + return max(energyLimit - newEnergyUsage, 0); // us + } + } diff --git a/src/main/java/org/tron/core/db/ExchangeStore.java b/src/main/java/org/tron/core/db/ExchangeStore.java new file mode 100644 index 00000000000..7dac15d2bca --- /dev/null +++ b/src/main/java/org/tron/core/db/ExchangeStore.java @@ -0,0 +1,38 @@ +package org.tron.core.db; + +import com.google.common.collect.Streams; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.exception.ItemNotFoundException; + +@Component +public class ExchangeStore extends TronStoreWithRevoking { + + @Autowired + public ExchangeStore(@Value("exchange") String dbName) { + super(dbName); + } + + @Override + public ExchangeCapsule get(byte[] key) throws ItemNotFoundException { + byte[] value = revokingDB.get(key); + return new ExchangeCapsule(value); + } + + /** + * get all exchanges. + */ + public List getAllExchanges() { + return Streams.stream(iterator()) + .map(Map.Entry::getValue) + .sorted( + (ExchangeCapsule a, ExchangeCapsule b) -> a.getCreateTime() <= b.getCreateTime() ? 1 + : -1) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/src/main/java/org/tron/core/db/Manager.java b/src/main/java/org/tron/core/db/Manager.java index cd7b6c53f19..357fbd78883 100644 --- a/src/main/java/org/tron/core/db/Manager.java +++ b/src/main/java/org/tron/core/db/Manager.java @@ -16,12 +16,15 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import javafx.util.Pair; import javax.annotation.PostConstruct; @@ -38,6 +41,7 @@ import org.tron.common.runtime.vm.program.invoke.ProgramInvokeFactoryImpl; import org.tron.common.storage.DepositImpl; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.ForkController; import org.tron.common.utils.SessionOptional; import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.StringUtil; @@ -47,6 +51,7 @@ import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.capsule.BytesCapsule; +import org.tron.core.capsule.ReceiptCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.TransactionInfoCapsule; import org.tron.core.capsule.TransactionResultCapsule; @@ -71,10 +76,14 @@ import org.tron.core.exception.HighFreqException; import org.tron.core.exception.ItemNotFoundException; import org.tron.core.exception.NonCommonBlockException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.ReceiptException; import org.tron.core.exception.TaposException; import org.tron.core.exception.TooBigTransactionException; import org.tron.core.exception.TransactionExpirationException; +import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.UnLinkedBlockException; +import org.tron.core.exception.UnsupportVMException; import org.tron.core.exception.ValidateScheduleException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.witness.ProposalController; @@ -83,6 +92,7 @@ import org.tron.protos.Protocol.Block; import org.tron.protos.Protocol.Transaction; + @Slf4j @Component public class Manager { @@ -95,8 +105,6 @@ public class Manager { @Autowired private BlockStore blockStore; @Autowired - private UtxoStore utxoStore; - @Autowired private WitnessStore witnessStore; @Autowired private AssetIssueStore assetIssueStore; @@ -107,8 +115,6 @@ public class Manager { @Autowired private AccountIdIndexStore accountIdIndexStore; @Autowired - private AccountContractIndexStore accountContractIndexStore; - @Autowired private WitnessScheduleStore witnessScheduleStore; @Autowired private RecentBlockStore recentBlockStore; @@ -117,13 +123,16 @@ public class Manager { @Autowired private ProposalStore proposalStore; @Autowired + private ExchangeStore exchangeStore; + @Autowired private TransactionHistoryStore transactionHistoryStore; @Autowired private CodeStore codeStore; @Autowired private ContractStore contractStore; @Autowired - private StorageStore storageStore; + @Getter + private StorageRowStore storageRowStore; // for network @Autowired @@ -160,10 +169,18 @@ public class Manager { private ExecutorService validateSignService; + private Thread repushThread; + + private boolean isRunRepushThread = true; + @Getter private Cache transactionIdCache = CacheBuilder .newBuilder().maximumSize(100_000).recordStats().build(); + @Getter + @Autowired + private ForkController forkController; + public WitnessStore getWitnessStore() { return this.witnessStore; } @@ -188,10 +205,6 @@ public void setWitnessScheduleStore(final WitnessScheduleStore witnessScheduleSt this.witnessScheduleStore = witnessScheduleStore; } - public StorageStore getStorageStore() { - return storageStore; - } - public CodeStore getCodeStore() { return codeStore; } @@ -208,6 +221,10 @@ public ProposalStore getProposalStore() { return this.proposalStore; } + public ExchangeStore getExchangeStore() { + return this.exchangeStore; + } + public List getPendingTransactions() { return this.pendingTransactions; } @@ -216,6 +233,10 @@ public List getPoppedTransactions() { return this.popedTransactions; } + public BlockingQueue getRepushTransactions() { + return repushTransactions; + } + // transactions cache private List pendingTransactions; @@ -223,6 +244,9 @@ public List getPoppedTransactions() { private List popedTransactions = Collections.synchronizedList(Lists.newArrayList()); + // the capacity is equal to Integer.MAX_VALUE default + private BlockingQueue repushTransactions; + // for test only public List getWitnesses() { return witnessController.getActiveWitnesses(); @@ -285,15 +309,36 @@ public void clearAndWriteNeighbours(Set nodes) { this.peersStore.put("neighbours".getBytes(), nodes); } - - public AccountContractIndexStore getAccountContractIndexStore() { - return accountContractIndexStore; - } - public Set readNeighbours() { return this.peersStore.get("neighbours".getBytes()); } + /** + * Cycle thread to repush Transactions + */ + private Runnable repushLoop = + () -> { + while (isRunRepushThread) { + try { + TransactionCapsule tx = this.getRepushTransactions().poll(1, TimeUnit.SECONDS); + if (tx != null) { + this.rePush(tx); + } + } catch (InterruptedException ex) { + logger.error(ex.getMessage()); + Thread.currentThread().interrupt(); + } catch (Exception ex) { + logger.error("unknown exception happened in witness loop", ex); + } catch (Throwable throwable) { + logger.error("unknown throwable happened in witness loop", throwable); + } + } + }; + + public void stopRepushThread() { + isRunRepushThread = false; + } + @PostConstruct public void init() { revokingStore.disable(); @@ -301,6 +346,8 @@ public void init() { this.setWitnessController(WitnessController.createInstance(this)); this.setProposalController(ProposalController.createInstance(this)); this.pendingTransactions = Collections.synchronizedList(Lists.newArrayList()); + this.repushTransactions = new LinkedBlockingQueue<>(); + this.initGenesis(); try { this.khaosDb.start(getBlockById(getDynamicPropertiesStore().getLatestBlockHeaderHash())); @@ -321,6 +368,7 @@ public void init() { Args.getInstance().getOutputDirectory()); System.exit(1); } + forkController.init(this); revokingStore.enable(); // this.codeStore = CodeStore.create("code"); @@ -329,6 +377,9 @@ public void init() { validateSignService = Executors .newFixedThreadPool(Args.getInstance().getValidateSignThreadNum()); + + repushThread = new Thread(repushLoop); + repushThread.start(); } public BlockId getGenesisBlockId() { @@ -519,19 +570,21 @@ void validateCommon(TransactionCapsule transactionCapsule) } void validateDup(TransactionCapsule transactionCapsule) throws DupTransactionException { - if (getTransactionStore().getUnchecked(transactionCapsule.getTransactionId().getBytes()) != null) { - logger.debug(ByteArray.toHexString(transactionCapsule.getTransactionId().getBytes())); - throw new DupTransactionException("dup trans"); - } + if (getTransactionStore().getUnchecked(transactionCapsule.getTransactionId().getBytes()) + != null) { + logger.debug(ByteArray.toHexString(transactionCapsule.getTransactionId().getBytes())); + throw new DupTransactionException("dup trans"); + } } /** - * push transaction into db. + * push transaction into pending. */ - public boolean pushTransactions(final TransactionCapsule trx) + public boolean pushTransaction(final TransactionCapsule trx) throws ValidateSignatureException, ContractValidateException, ContractExeException, AccountResourceInsufficientException, DupTransactionException, TaposException, - TooBigTransactionException, TransactionExpirationException { + TooBigTransactionException, TransactionExpirationException, ReceiptException, + TransactionTraceException, OutOfSlotTimeException, UnsupportVMException { if (!trx.validateSignature()) { throw new ValidateSignatureException("trans sig validate failed"); @@ -553,16 +606,18 @@ public boolean pushTransactions(final TransactionCapsule trx) } - public void consumeBandwidth(TransactionCapsule trx, TransactionResultCapsule ret) + public void consumeBandwidth(TransactionCapsule trx, TransactionResultCapsule ret, + TransactionTrace trace) throws ContractValidateException, AccountResourceInsufficientException { BandwidthProcessor processor = new BandwidthProcessor(this); - processor.consume(trx, ret); + processor.consume(trx, ret, trace); } - public void consumeCpu(TransactionCapsule trx, TransactionResultCapsule ret) + public void consumeEnergy(TransactionCapsule trx, TransactionResultCapsule ret, + TransactionTrace trace) throws ContractValidateException, AccountResourceInsufficientException { - CpuProcessor processor = new CpuProcessor(this); - processor.consume(trx, ret); + EnergyProcessor processor = new EnergyProcessor(this); + processor.consume(trx, ret, trace); } @Deprecated @@ -612,6 +667,9 @@ public void eraseBlock() { revokingStore.pop(); logger.info("end to erase block:" + oldHeadBlock); popedTransactions.addAll(oldHeadBlock.getTransactions()); + // todo: need add ?? + // repushTransactions.addAll(oldHeadBlock.getTransactions()); + // } catch (ItemNotFoundException | BadItemException e) { logger.warn(e.getMessage(), e); } @@ -619,8 +677,9 @@ public void eraseBlock() { private void applyBlock(BlockCapsule block) throws ContractValidateException, ContractExeException, ValidateSignatureException, AccountResourceInsufficientException, - TransactionExpirationException, TooBigTransactionException, DupTransactionException, - TaposException, ValidateScheduleException { + TransactionExpirationException, TooBigTransactionException, DupTransactionException, ReceiptException, + TaposException, ValidateScheduleException, TransactionTraceException, OutOfSlotTimeException, + UnsupportVMException { processBlock(block); this.blockStore.put(block.getBlockId().getBytes(), block); this.blockIndexStore.put(block.getBlockId()); @@ -630,7 +689,8 @@ private void switchFork(BlockCapsule newHead) throws ValidateSignatureException, ContractValidateException, ContractExeException, ValidateScheduleException, AccountResourceInsufficientException, TaposException, TooBigTransactionException, DupTransactionException, TransactionExpirationException, - NonCommonBlockException { + NonCommonBlockException, ReceiptException, TransactionTraceException, OutOfSlotTimeException, + UnsupportVMException { Pair, LinkedList> binaryTree; try { binaryTree = @@ -671,8 +731,12 @@ private void switchFork(BlockCapsule newHead) | TaposException | DupTransactionException | TransactionExpirationException + | TransactionTraceException + | ReceiptException + | OutOfSlotTimeException | TooBigTransactionException - | ValidateScheduleException e) { + | ValidateScheduleException + | UnsupportVMException e) { logger.warn(e.getMessage(), e); exception = e; throw e; @@ -727,8 +791,9 @@ public synchronized void pushBlock(final BlockCapsule block) throws ValidateSignatureException, ContractValidateException, ContractExeException, UnLinkedBlockException, ValidateScheduleException, AccountResourceInsufficientException, TaposException, TooBigTransactionException, DupTransactionException, TransactionExpirationException, - BadNumberBlockException, BadBlockException, NonCommonBlockException { - try (PendingManager pm = new PendingManager(this)) { + BadNumberBlockException, BadBlockException, NonCommonBlockException, ReceiptException, TransactionTraceException, + OutOfSlotTimeException, UnsupportVMException { + try (PendingManager pm = new PendingManager(this)) { if (!block.generatedByMyself) { if (!block.validateSignature()) { @@ -829,7 +894,8 @@ public void updateDynamicProperties(BlockCapsule block) { for (int i = 1; i < slot; ++i) { if (!witnessController.getScheduledWitness(i).equals(block.getWitnessAddress())) { WitnessCapsule w = - this.witnessStore.getUnchecked(StringUtil.createDbKey(witnessController.getScheduledWitness(i))); + this.witnessStore + .getUnchecked(StringUtil.createDbKey(witnessController.getScheduledWitness(i))); w.setTotalMissed(w.getTotalMissed() + 1); this.witnessStore.put(w.createDbKey(), w); logger.info( @@ -937,10 +1003,9 @@ public boolean hasBlocks() { * Process transaction. */ public boolean processTransaction(final TransactionCapsule trxCap, Block block) - throws ValidateSignatureException, ContractValidateException, ContractExeException, + throws ValidateSignatureException, ContractValidateException, ContractExeException, ReceiptException, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, - DupTransactionException, TaposException { - + DupTransactionException, TaposException, TransactionTraceException, OutOfSlotTimeException, UnsupportVMException { if (trxCap == null) { return false; } @@ -958,41 +1023,30 @@ public boolean processTransaction(final TransactionCapsule trxCap, Block block) throw new ValidateSignatureException("trans sig validate failed"); } - TransactionTrace trace = new TransactionTrace(trxCap); - trace.init(); + TransactionTrace trace = new TransactionTrace(trxCap, this); +// TODO vm switch +// if (!this.dynamicPropertiesStore.supportVM() && trace.needVM()) { +// throw new UnsupportVMException("this node doesn't support vm, trx id: " + trxCap.getTransactionId().toString()); +// } DepositImpl deposit = DepositImpl.createRoot(this); - Runtime runtime; - - runtime = new Runtime(trace, block, deposit, + Runtime runtime = new Runtime(trace, block, deposit, new ProgramInvokeFactoryImpl()); - consumeBandwidth(trxCap, runtime.getResult().getRet()); + consumeBandwidth(trxCap, runtime.getResult().getRet(), trace); - runtime.init(); - - //exec + trace.init(); trace.exec(runtime); + trace.pay(); - //check SR's bill and ours. - if(block != null) { - trace.checkBill(); - } + transactionStore.put(trxCap.getTransactionId().getBytes(), trxCap); - trace.finalize(); + RuntimeException runtimeException = runtime.getResult().getException(); + ReceiptCapsule traceReceipt = trace.getReceipt(); + TransactionInfoCapsule transactionInfo = TransactionInfoCapsule + .buildInstance(trxCap, block, runtime, traceReceipt); - if (runtime.getResult().getException() != null) { - throw new RuntimeException("Runtime exe failed!"); - } - // todo judge result in runtime same as block,trx,recipt - // todo 一个账户只能一个合约账户 - transactionStore.put(trxCap.getTransactionId().getBytes(), trxCap); - TransactionInfoCapsule transactionInfoCapsule = new TransactionInfoCapsule(); - transactionInfoCapsule.setId(trxCap.getTransactionId().getBytes()); - transactionInfoCapsule.setFee(runtime.getResult().getRet().getFee()); - transactionInfoCapsule.setContractResult(runtime.getResult().getHReturn()); - transactionInfoCapsule.setContractAddress(runtime.getResult().getContractAddress()); - transactionHistoryStore.put(trxCap.getTransactionId().getBytes(), transactionInfoCapsule); + transactionHistoryStore.put(trxCap.getTransactionId().getBytes(), transactionInfo); return true; } @@ -1015,7 +1069,8 @@ public BlockCapsule getBlockByNum(final long num) throws ItemNotFoundException, public synchronized BlockCapsule generateBlock( final WitnessCapsule witnessCapsule, final long when, final byte[] privateKey) throws ValidateSignatureException, ContractValidateException, ContractExeException, - UnLinkedBlockException, ValidateScheduleException, AccountResourceInsufficientException { + + UnLinkedBlockException, ValidateScheduleException, AccountResourceInsufficientException, TransactionTraceException { final long timestamp = this.dynamicPropertiesStore.getLatestBlockHeaderTimestamp(); final long number = this.dynamicPropertiesStore.getLatestBlockHeaderNumber(); @@ -1032,6 +1087,7 @@ public synchronized BlockCapsule generateBlock( new BlockCapsule(number + 1, preHash, when, witnessCapsule.getAddress()); session.reset(); session.setValue(revokingStore.buildSession()); + Iterator iterator = pendingTransactions.iterator(); while (iterator.hasNext()) { TransactionCapsule trx = (TransactionCapsule) iterator.next(); @@ -1049,11 +1105,13 @@ public synchronized BlockCapsule generateBlock( } // apply transaction try (ISession tmpSeesion = revokingStore.buildSession()) { - processTransaction(trx, null); + if (forkController.forkOrNot(trx)) { + processTransaction(trx, null); // trx.resetResult(); - tmpSeesion.merge(); - // push into block - blockCapsule.addTransaction(trx); + tmpSeesion.merge(); + // push into block + blockCapsule.addTransaction(trx); + } iterator.remove(); } catch (ContractExeException e) { logger.info("contract not processed during execute"); @@ -1079,6 +1137,14 @@ public synchronized BlockCapsule generateBlock( } catch (ValidateSignatureException e) { logger.info("contract not processed during ValidateSignatureException"); logger.debug(e.getMessage(), e); + } catch (ReceiptException e) { + logger.info("receipt exception: {}", e.getMessage()); + logger.debug(e.getMessage(), e); + } catch (OutOfSlotTimeException e) { + logger.info("OutOfSlotTime exception: {}", e.getMessage()); + logger.debug(e.getMessage(), e); + } catch (UnsupportVMException e) { + logger.warn(e.getMessage(), e); } } @@ -1094,6 +1160,7 @@ public synchronized BlockCapsule generateBlock( blockCapsule.setMerkleRoot(); blockCapsule.sign(privateKey); blockCapsule.generatedByMyself = true; + try { this.pushBlock(blockCapsule); return blockCapsule; @@ -1111,6 +1178,14 @@ public synchronized BlockCapsule generateBlock( logger.info("block exception"); } catch (NonCommonBlockException e) { logger.info("non common exception"); + } catch (ReceiptException e) { + logger.info("receipt exception: {}", e.getMessage()); + logger.debug(e.getMessage(), e); + } catch (OutOfSlotTimeException e) { + logger.info("OutOfSlotTime exception: {}", e.getMessage()); + logger.debug(e.getMessage(), e); + } catch (UnsupportVMException e) { + logger.warn(e.getMessage(), e); } return null; @@ -1144,21 +1219,14 @@ private void setBlockStore(final BlockStore blockStore) { this.blockStore = blockStore; } - public UtxoStore getUtxoStore() { - return this.utxoStore; - } - - private void setUtxoStore(final UtxoStore utxoStore) { - this.utxoStore = utxoStore; - } - /** * process block. */ public void processBlock(BlockCapsule block) throws ValidateSignatureException, ContractValidateException, ContractExeException, AccountResourceInsufficientException, TaposException, TooBigTransactionException, - DupTransactionException, TransactionExpirationException, ValidateScheduleException { + DupTransactionException, TransactionExpirationException, ValidateScheduleException, + ReceiptException, TransactionTraceException, OutOfSlotTimeException, UnsupportVMException { // todo set revoking db max size. // checkWitness @@ -1188,6 +1256,7 @@ public void processBlock(BlockCapsule block) updateMaintenanceState(needMaint); //witnessController.updateWitnessSchedule(); updateRecentBlock(block); + } private void updateTransHashCache(BlockCapsule block) { @@ -1231,6 +1300,12 @@ public void updateLatestSolidifiedBlock() { } getDynamicPropertiesStore().saveLatestSolidifiedBlockNum(latestSolidifiedBlockNum); logger.info("update solid block, num = {}", latestSolidifiedBlockNum); + try { + BlockCapsule solidifiedBlock = getBlockByNum(latestSolidifiedBlockNum); + forkController.update(solidifiedBlock); + } catch (ItemNotFoundException | BadItemException e) { + logger.error("solidified block not found"); + } } public long getSyncBeginNumber() { @@ -1265,6 +1340,7 @@ private void processMaintenance(BlockCapsule block) { proposalController.processProposals(); witnessController.updateWitness(); this.dynamicPropertiesStore.updateNextMaintenanceTime(block.getTimeStamp()); + forkController.reset(); } /** @@ -1352,10 +1428,9 @@ public void closeAllStore() { closeOneStore(assetIssueStore); closeOneStore(dynamicPropertiesStore); closeOneStore(transactionStore); - closeOneStore(utxoStore); closeOneStore(codeStore); closeOneStore(contractStore); - closeOneStore(storageStore); + closeOneStore(storageRowStore); System.err.println("******** end to close db ********"); } @@ -1371,7 +1446,8 @@ private void closeOneStore(ITronChainBase database) { } public boolean isTooManyPending() { - if (getPendingTransactions().size() + PendingManager.getTmpTransactions().size() + // if (getPendingTransactions().size() + PendingManager.getTmpTransactions().size() + if (getPendingTransactions().size() + getRepushTransactions().size() > MAX_TRANSACTION_PENDING) { return true; } @@ -1431,4 +1507,45 @@ public synchronized void preValidateTransactionSign(BlockCapsule block) } } } + + public void rePush(TransactionCapsule tx) { + + try { + if (transactionStore.get(tx.getTransactionId().getBytes()) != null) { + return; + } + } catch (BadItemException e) { + // do nothing + } + + try { + this.pushTransaction(tx); + } catch (ValidateSignatureException e) { + logger.debug(e.getMessage(), e); + } catch (ContractValidateException e) { + logger.debug(e.getMessage(), e); + } catch (ContractExeException e) { + logger.debug(e.getMessage(), e); + } catch (AccountResourceInsufficientException e) { + logger.debug(e.getMessage(), e); + } catch (DupTransactionException e) { + logger.debug("pending manager: dup trans", e); + } catch (TaposException e) { + logger.debug("pending manager: tapos exception", e); + } catch (TooBigTransactionException e) { + logger.debug("too big transaction"); + } catch (ReceiptException e) { + logger.info("Receipt exception," + e.getMessage()); + } catch (TransactionExpirationException e) { + logger.debug("expiration transaction"); + } catch (TransactionTraceException e) { + logger.debug("transactionTrace transaction"); + } catch (OutOfSlotTimeException e) { + logger.debug("outOfSlotTime transaction"); + } catch (UnsupportVMException e) { + logger.debug(e.getMessage(), e); + } + } + + } diff --git a/src/main/java/org/tron/core/db/PendingManager.java b/src/main/java/org/tron/core/db/PendingManager.java index 03308e4e193..3b56be4e423 100644 --- a/src/main/java/org/tron/core/db/PendingManager.java +++ b/src/main/java/org/tron/core/db/PendingManager.java @@ -5,15 +5,6 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.exception.BadItemException; -import org.tron.core.exception.AccountResourceInsufficientException; -import org.tron.core.exception.ContractExeException; -import org.tron.core.exception.ContractValidateException; -import org.tron.core.exception.DupTransactionException; -import org.tron.core.exception.TaposException; -import org.tron.core.exception.TooBigTransactionException; -import org.tron.core.exception.TransactionExpirationException; -import org.tron.core.exception.ValidateSignatureException; @Slf4j public class PendingManager implements AutoCloseable { @@ -23,6 +14,7 @@ public class PendingManager implements AutoCloseable { Manager dbManager; public PendingManager(Manager db) { + this.dbManager = db; tmpTransactions.addAll(db.getPendingTransactions()); db.getPendingTransactions().clear(); @@ -31,43 +23,26 @@ public PendingManager(Manager db) { @Override public void close() { - rePush(this.tmpTransactions); - rePush(dbManager.getPoppedTransactions()); - dbManager.getPoppedTransactions().clear(); + + for (TransactionCapsule tx : this.tmpTransactions) { + try { + dbManager.getRepushTransactions().put(tx); + } catch (InterruptedException e) { + logger.error(e.getMessage()); + Thread.currentThread().interrupt(); + } + } tmpTransactions.clear(); - } - private void rePush(List txs) { - txs.stream() - .filter( - trx -> { - try { - return - dbManager.getTransactionStore().get(trx.getTransactionId().getBytes()) == null; - } catch (BadItemException e) { - return true; - } - }) - .forEach(trx -> { - try { - dbManager.pushTransactions(trx); - } catch (ValidateSignatureException e) { - logger.debug(e.getMessage(), e); - } catch (ContractValidateException e) { - logger.debug(e.getMessage(), e); - } catch (ContractExeException e) { - logger.debug(e.getMessage(), e); - } catch (AccountResourceInsufficientException e) { - logger.debug(e.getMessage(), e); - } catch (DupTransactionException e) { - logger.debug("pending manager: dup trans", e); - } catch (TaposException e) { - logger.debug("pending manager: tapos exception", e); - } catch (TooBigTransactionException e) { - logger.debug("too big transaction"); - } catch (TransactionExpirationException e) { - logger.debug("expiration transaction"); - } - }); + for (TransactionCapsule tx : dbManager.getPoppedTransactions()) { + try { + dbManager.getRepushTransactions().put(tx); + } catch (InterruptedException e) { + logger.error(e.getMessage()); + Thread.currentThread().interrupt(); + } + } + dbManager.getPoppedTransactions().clear(); + } } diff --git a/src/main/java/org/tron/core/db/ProposalStore.java b/src/main/java/org/tron/core/db/ProposalStore.java index b941d2edb27..e31c0146cd2 100644 --- a/src/main/java/org/tron/core/db/ProposalStore.java +++ b/src/main/java/org/tron/core/db/ProposalStore.java @@ -25,7 +25,7 @@ public ProposalCapsule get(byte[] key) throws ItemNotFoundException { } /** - * get all witnesses. + * get all proposals. */ public List getAllProposals() { return Streams.stream(iterator()) diff --git a/src/main/java/org/tron/core/db/ResourceProcessor.java b/src/main/java/org/tron/core/db/ResourceProcessor.java index e6ef7097ffe..2e62e445dba 100644 --- a/src/main/java/org/tron/core/db/ResourceProcessor.java +++ b/src/main/java/org/tron/core/db/ResourceProcessor.java @@ -22,7 +22,8 @@ public ResourceProcessor(Manager manager) { abstract void updateUsage(AccountCapsule accountCapsule); - abstract void consume(TransactionCapsule trx, TransactionResultCapsule ret) + abstract void consume(TransactionCapsule trx, TransactionResultCapsule ret, + TransactionTrace trace) throws ContractValidateException, AccountResourceInsufficientException; protected long increase(long lastUsage, long usage, long lastTime, long now) { diff --git a/src/main/java/org/tron/core/db/StorageMarket.java b/src/main/java/org/tron/core/db/StorageMarket.java index 4384fd63627..206ce2ec611 100644 --- a/src/main/java/org/tron/core/db/StorageMarket.java +++ b/src/main/java/org/tron/core/db/StorageMarket.java @@ -22,6 +22,28 @@ private long exchange_to_supply(boolean isTRX, long quant) { long newBalance = balance + quant; logger.info("balance + quant: " + (balance + quant)); +// if (isTRX) { +// dbManager.getDynamicPropertiesStore().saveTotalStoragePool(newBalance); +// } else { +// dbManager.getDynamicPropertiesStore().saveTotalStorageReserved(newBalance); +// } + + double issuedSupply = -supply * (1.0 - Math.pow(1.0 + (double) quant / newBalance, 0.0005)); + logger.info("issuedSupply: " + issuedSupply); + long out = (long) issuedSupply; + supply += out; + + return out; + } + + private long exchange_to_supply2(boolean isTRX, long quant) { + logger.info("isTRX: " + isTRX); + long balance = isTRX ? dbManager.getDynamicPropertiesStore().getTotalStoragePool() : + dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + logger.info("balance: " + balance); + long newBalance = balance - quant; + logger.info("balance - quant: " + (balance - quant)); + // if (isTRX) { // dbManager.getDynamicPropertiesStore().saveTotalStoragePool(newBalance); // } else { @@ -47,11 +69,10 @@ private long exchange_from_supply(boolean isTRX, long supplyQuant) { long out = (long) exchangeBalance; long newBalance = balance - out; -// if (isTRX) { -// dbManager.getDynamicPropertiesStore().saveTotalStoragePool(newBalance); -// } else { -// dbManager.getDynamicPropertiesStore().saveTotalStorageReserved(newBalance); -// } + if (isTRX) { + out = Math.round(exchangeBalance / 100000) * 100000; + logger.info("---out: " + out); + } return out; } @@ -71,6 +92,26 @@ public long calculateTax(long duration, long limit) { return storageTax; } + + public long tryPayTax(long duration, long limit) { + long storageTax = calculateTax(duration, limit); + long tax = exchange(storageTax, false); + logger.info("tax: " + tax); + + long newTotalTax = dbManager.getDynamicPropertiesStore().getTotalStorageTax() + tax; + long newTotalPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool() - tax; + long newTotalReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved() + + storageTax; + logger.info("reserved: " + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + boolean eq = dbManager.getDynamicPropertiesStore().getTotalStorageReserved() + == 128L * 1024 * 1024 * 1024; + logger.info("reserved == 128GB: " + eq); + logger.info("newTotalTax: " + newTotalTax + " newTotalPool: " + newTotalPool + + " newTotalReserved: " + newTotalReserved); + + return storageTax; + } + public long payTax(long duration, long limit) { long storageTax = calculateTax(duration, limit); long tax = exchange(storageTax, false); @@ -93,22 +134,61 @@ public long payTax(long duration, long limit) { return storageTax; } - public void buyStorage(AccountCapsule accountCapsule, long quant) { - long now = dbManager.getHeadBlockTimeStamp(); + public long tryBuyStorageBytes(long storageBought) { + long relay = exchange_to_supply2(false, storageBought); + return exchange_from_supply(true, relay); + } + + public long tryBuyStorage(long quant) { + return exchange(quant, true); + } - long latestExchangeStorageTime = accountCapsule.getLatestExchangeStorageTime(); + public long trySellStorage(long bytes) { + return exchange(bytes, false); + } + + public AccountCapsule buyStorageBytes(AccountCapsule accountCapsule, long storageBought) { + long now = dbManager.getHeadBlockTimeStamp(); long currentStorageLimit = accountCapsule.getStorageLimit(); - long currentUnusedStorage = currentStorageLimit - accountCapsule.getStorageUsage(); - long duration = now - latestExchangeStorageTime; - long storageTax = payTax(duration, currentUnusedStorage); + long relay = exchange_to_supply2(false, storageBought); + long quant = exchange_from_supply(true, relay); + + long newBalance = accountCapsule.getBalance() - quant; + logger.info("newBalance: " + newBalance); + + long newStorageLimit = currentStorageLimit + storageBought; + logger.info( + "storageBought: " + storageBought + " newStorageLimit: " + + newStorageLimit); + + accountCapsule.setLatestExchangeStorageTime(now); + accountCapsule.setStorageLimit(newStorageLimit); + accountCapsule.setBalance(newBalance); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + long newTotalPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool() + quant; + long newTotalReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved() + - storageBought; + logger.info("newTotalPool: " + newTotalPool + " newTotalReserved: " + newTotalReserved); + dbManager.getDynamicPropertiesStore().saveTotalStoragePool(newTotalPool); + dbManager.getDynamicPropertiesStore().saveTotalStorageReserved(newTotalReserved); + return accountCapsule; + } + + + public void buyStorage(AccountCapsule accountCapsule, long quant) { + long now = dbManager.getHeadBlockTimeStamp(); + long currentStorageLimit = accountCapsule.getStorageLimit(); long newBalance = accountCapsule.getBalance() - quant; logger.info("newBalance: " + newBalance); long storageBought = exchange(quant, true); - long newStorageLimit = currentStorageLimit - storageTax + storageBought; - logger.info("storageBought: " + storageBought + " newStorageLimit: " + newStorageLimit); + long newStorageLimit = currentStorageLimit + storageBought; + logger.info( + "storageBought: " + storageBought + " newStorageLimit: " + + newStorageLimit); accountCapsule.setLatestExchangeStorageTime(now); accountCapsule.setStorageLimit(newStorageLimit); @@ -126,18 +206,12 @@ public void buyStorage(AccountCapsule accountCapsule, long quant) { public void sellStorage(AccountCapsule accountCapsule, long bytes) { long now = dbManager.getHeadBlockTimeStamp(); - - long latestExchangeStorageTime = accountCapsule.getLatestExchangeStorageTime(); long currentStorageLimit = accountCapsule.getStorageLimit(); - long currentUnusedStorage = currentStorageLimit - accountCapsule.getStorageUsage(); - - long duration = now - latestExchangeStorageTime; - long storageTax = payTax(duration, currentUnusedStorage); long quant = exchange(bytes, false); long newBalance = accountCapsule.getBalance() + quant; - long newStorageLimit = currentStorageLimit - storageTax - bytes; + long newStorageLimit = currentStorageLimit - bytes; logger.info("quant: " + quant + " newStorageLimit: " + newStorageLimit); accountCapsule.setLatestExchangeStorageTime(now); @@ -154,4 +228,7 @@ public void sellStorage(AccountCapsule accountCapsule, long bytes) { } + public long getAccountLeftStorageInByteFromBought(AccountCapsule accountCapsule) { + return accountCapsule.getStorageLimit() - accountCapsule.getStorageUsage(); + } } diff --git a/src/main/java/org/tron/core/db/StorageRowStore.java b/src/main/java/org/tron/core/db/StorageRowStore.java new file mode 100644 index 00000000000..1b9bc124a31 --- /dev/null +++ b/src/main/java/org/tron/core/db/StorageRowStore.java @@ -0,0 +1,30 @@ +package org.tron.core.db; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.tron.core.capsule.StorageRowCapsule; + +@Slf4j +@Component +public class StorageRowStore extends TronStoreWithRevoking { + + private static StorageRowStore instance; + + @Autowired + private StorageRowStore(@Value("storage-row") String dbName) { + super(dbName); + } + + @Override + public StorageRowCapsule get(byte[] key) { + StorageRowCapsule row = getUnchecked(key); + row.setRowKey(key); + return row; + } + + void destory() { + instance = null; + } +} diff --git a/src/main/java/org/tron/core/db/StorageStore.java b/src/main/java/org/tron/core/db/StorageStore.java deleted file mode 100755 index c2503ddbe72..00000000000 --- a/src/main/java/org/tron/core/db/StorageStore.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.tron.core.db; - -import com.google.common.collect.Streams; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ArrayUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.tron.core.capsule.StorageCapsule; - -@Slf4j -@Component -public class StorageStore extends TronStoreWithRevoking { - - @Autowired - private StorageStore(@Value("storage") String dbName) { - super(dbName); - } - - @Override - public StorageCapsule get(byte[] key) { - return getUnchecked(key); - } - - /** - * get total storages. - */ - public long getTotalStorages() { - return Streams.stream(revokingDB.iterator()).count(); - } - - private static StorageStore instance; - - public static void destory() { - instance = null; - } - - void destroy() { - instance = null; - } - - /** - * find a storage by it's key. - */ - public byte[] findStorageByKey(byte[] key) { - return revokingDB.getUnchecked(key); - } - -} diff --git a/src/main/java/org/tron/core/db/TransactionTrace.java b/src/main/java/org/tron/core/db/TransactionTrace.java index 796ffea40ef..63bf59c52ed 100644 --- a/src/main/java/org/tron/core/db/TransactionTrace.java +++ b/src/main/java/org/tron/core/db/TransactionTrace.java @@ -1,61 +1,143 @@ package org.tron.core.db; +import static org.tron.common.runtime.vm.program.InternalTransaction.TrxType.TRX_CONTRACT_CALL_TYPE; +import static org.tron.common.runtime.vm.program.InternalTransaction.TrxType.TRX_CONTRACT_CREATION_TYPE; +import static org.tron.common.runtime.vm.program.InternalTransaction.TrxType.TRX_PRECOMPILED_TYPE; + import org.tron.common.runtime.Runtime; +import org.tron.common.runtime.vm.program.InternalTransaction; import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ContractCapsule; import org.tron.core.capsule.ReceiptCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Contract.TriggerSmartContract; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; public class TransactionTrace { + private TransactionCapsule trx; private ReceiptCapsule receipt; + private Manager dbManager; + + private EnergyProcessor energyProcessor; + + private InternalTransaction.TrxType trxType; + public TransactionCapsule getTrx() { return trx; } - public TransactionTrace(TransactionCapsule trx) { + public TransactionTrace(TransactionCapsule trx, Manager dbManager) { this.trx = trx; + Transaction.Contract.ContractType contractType = this.trx.getInstance().getRawData() + .getContract(0).getType(); + switch (contractType.getNumber()) { + case ContractType.TriggerSmartContract_VALUE: + trxType = TRX_CONTRACT_CALL_TYPE; + break; + case ContractType.CreateSmartContract_VALUE: + trxType = TRX_CONTRACT_CREATION_TYPE; + break; + default: + trxType = TRX_PRECOMPILED_TYPE; + } + //TODO: set bill owner receipt = new ReceiptCapsule(Sha256Hash.ZERO_HASH); + this.dbManager = dbManager; + this.receipt = new ReceiptCapsule(Sha256Hash.ZERO_HASH); + + this.energyProcessor = new EnergyProcessor(this.dbManager); + } + + public boolean needVM() { + return this.trxType == TRX_CONTRACT_CALL_TYPE || this.trxType == TRX_CONTRACT_CREATION_TYPE; } //pre transaction check - public void init() { - //TODO: check -// receipt.payCpuBill(); - checkStorage(); + public void init() throws TransactionTraceException { + + // switch (trxType) { + // case TRX_PRECOMPILED_TYPE: + // break; + // case TRX_CONTRACT_CREATION_TYPE: + // case TRX_CONTRACT_CALL_TYPE: + // // checkForSmartContract(); + // break; + // default: + // break; + // } + } //set bill - public void setBill(long cpuUseage, long storageDelta) { - receipt.setCpuUsage(cpuUseage); - receipt.setStorageDelta(storageDelta); + public void setBill(long energyUseage) { + receipt.setEnergyUsageTotal(energyUseage); } - private void checkStorage() { - //TODO if not enough buy some storage auto - receipt.buyStorage(0); + //set net bill + public void setNetBill(long netUsage, long netFee) { + receipt.setNetUsage(netUsage); + receipt.setNetFee(netFee); } - public void exec(Runtime runtime) throws ContractExeException, ContractValidateException { + public void exec(Runtime runtime) + throws ContractExeException, ContractValidateException, OutOfSlotTimeException { /** VM execute **/ + runtime.init(); runtime.execute(); runtime.go(); + runtime.finalization(); } - public void finalize() { - //TODO: if SR package this this trx, use their receipt - //ReceiptCapsule witReceipt = trx.getInstance().getRet(0).getReceipt() - receipt.payCpuBill(); - receipt.payStorageBill(); - //TODO: pay bill - } + /** + * pay actually bill(include ENERGY and storage). + */ + public void pay() { + byte[] originAccount; + byte[] callerAccount; + long percent = 0; + switch (trxType) { + case TRX_CONTRACT_CREATION_TYPE: + callerAccount = TransactionCapsule.getOwner(trx.getInstance().getRawData().getContract(0)); + originAccount = callerAccount; + break; + case TRX_CONTRACT_CALL_TYPE: + TriggerSmartContract callContract = ContractCapsule + .getTriggerContractFromTransaction(trx.getInstance()); + callerAccount = callContract.getOwnerAddress().toByteArray(); + + ContractCapsule contract = + dbManager.getContractStore().get(callContract.getContractAddress().toByteArray()); + originAccount = contract.getInstance().getOriginAddress().toByteArray(); + percent = Math.max(100 - contract.getConsumeUserResourcePercent(), 0); + percent = Math.min(percent, 100); + break; + default: + return; + } - public void checkBill() { - //TODO: check SR's bill and ours. + // originAccount Percent = 30% + AccountCapsule origin = dbManager.getAccountStore().get(originAccount); + AccountCapsule caller = dbManager.getAccountStore().get(callerAccount); + receipt.payEnergyBill( + dbManager, + origin, + caller, + percent, + energyProcessor, + dbManager.getWitnessController().getHeadSlot()); } + public ReceiptCapsule getReceipt() { + return receipt; + } } diff --git a/src/main/java/org/tron/core/db/UtxoStore.java b/src/main/java/org/tron/core/db/UtxoStore.java deleted file mode 100755 index d56579d0ef5..00000000000 --- a/src/main/java/org/tron/core/db/UtxoStore.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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.core.db; - -import com.google.protobuf.InvalidProtocolBufferException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ArrayUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.tron.common.crypto.ECKey; -import org.tron.common.utils.ByteArray; -import org.tron.core.SpendableOutputs; -import org.tron.protos.Protocol.TXOutput; -import org.tron.protos.Protocol.TXOutputs; - -@Slf4j -@Component -public class UtxoStore extends TronDatabase { - - @Autowired - private UtxoStore(@Value("utxo") String dbName) { - super(dbName); - } - - - public byte[] find(byte[] key) { - return dbSource.getData(key); - } - - - public Set getKeys() { - return dbSource.allKeys(); - } - - /** - * save utxo. - */ - public void saveUtxo(byte[] utxoKey, byte[] utxoData) { - dbSource.putData(utxoKey, utxoData); - } - - /** - * Find spendable outputs. - */ - public SpendableOutputs findSpendableOutputs(byte[] pubKeyHash, long amount) { - SpendableOutputs spendableOutputs = new SpendableOutputs(); - HashMap unspentOutputs = new HashMap<>(); - long accumulated = 0L; - - for (byte[] key : getDbSource().allKeys()) { - try { - TXOutputs txOutputs = TXOutputs.parseFrom(getDbSource().getData(key)); - String keyToHexString = ByteArray.toHexString(key); - - for (int i = 0, len = txOutputs.getOutputsCount(); i < len; i++) { - TXOutput txOutput = txOutputs.getOutputs(i); - if (ByteArray.toHexString(ECKey.computeAddress(pubKeyHash)) - .equals(ByteArray.toHexString(txOutput.getPubKeyHash().toByteArray())) - && accumulated < amount) { - - accumulated += txOutput.getValue(); - long[] v = ArrayUtils.nullToEmpty(unspentOutputs.get(keyToHexString)); - unspentOutputs.put(keyToHexString, ArrayUtils.add(v, i)); - } - } - } catch (InvalidProtocolBufferException e) { - logger.debug(e.getMessage(), e); - } - } - - spendableOutputs.setAmount(accumulated); - spendableOutputs.setUnspentOutputs(unspentOutputs); - - return spendableOutputs; - } - - /** - * Find related UTXOs. - */ - public ArrayList findUtxo(byte[] address) { - return getDbSource().allKeys().stream() - .map(key -> { - try { - return TXOutputs.parseFrom(getDbSource().getData(key)); - } catch (InvalidProtocolBufferException e) { - logger.debug(e.getMessage(), e); - return null; - } - }) - .filter(Objects::nonNull) - .map(TXOutputs::getOutputsList) - .flatMap(List::stream) - .filter(txOutput -> ByteArray.toHexString(ECKey.computeAddress(address)) - .equals(ByteArray.toHexString(txOutput.getPubKeyHash().toByteArray()))) - .collect(Collectors.toCollection(ArrayList::new)); - } - - @Override - public void put(byte[] key, Object item) { - - } - - @Override - public void delete(byte[] key) { - - } - - @Override - public Object get(byte[] key) { - return null; - } - - @Override - public boolean has(byte[] key) { - return false; - } - -} \ No newline at end of file diff --git a/src/main/java/org/tron/core/db/api/StoreAPI.java b/src/main/java/org/tron/core/db/api/StoreAPI.java index 8c170c9ad75..ffcd4ff87fd 100644 --- a/src/main/java/org/tron/core/db/api/StoreAPI.java +++ b/src/main/java/org/tron/core/db/api/StoreAPI.java @@ -1,12 +1,9 @@ package org.tron.core.db.api; -import static com.googlecode.cqengine.query.QueryFactory.applyThresholds; import static com.googlecode.cqengine.query.QueryFactory.ascending; import static com.googlecode.cqengine.query.QueryFactory.equal; import static com.googlecode.cqengine.query.QueryFactory.orderBy; import static com.googlecode.cqengine.query.QueryFactory.queryOptions; -import static com.googlecode.cqengine.query.QueryFactory.threshold; -import static com.googlecode.cqengine.query.option.EngineThresholds.INDEX_ORDERING_SELECTIVITY; import static org.tron.core.config.Parameter.DatabaseConstants.TRANSACTIONS_COUNT_LIMIT_MAX; import com.google.common.collect.ImmutableList; @@ -103,8 +100,7 @@ public List getTransactionsFromThis(String address, long offset, lo index.retrieve( equal(TransactionIndex.OWNERS, address), queryOptions( - orderBy(ascending(TransactionIndex.TIMESTAMP)), - applyThresholds(threshold(INDEX_ORDERING_SELECTIVITY, 1.0))))) { + orderBy(ascending(TransactionIndex.TIMESTAMP))))) { if (limit > TRANSACTIONS_COUNT_LIMIT_MAX) { limit = TRANSACTIONS_COUNT_LIMIT_MAX; } @@ -122,8 +118,7 @@ public List getTransactionsToThis(String address, long offset, long index.retrieve( equal(TransactionIndex.TOS, address), queryOptions( - orderBy(ascending(TransactionIndex.TIMESTAMP)), - applyThresholds(threshold(INDEX_ORDERING_SELECTIVITY, 1.0))))) { + orderBy(ascending(TransactionIndex.TIMESTAMP))))) { if (limit > TRANSACTIONS_COUNT_LIMIT_MAX) { limit = TRANSACTIONS_COUNT_LIMIT_MAX; } diff --git a/src/main/java/org/tron/core/db/api/index/TransactionIndex.java b/src/main/java/org/tron/core/db/api/index/TransactionIndex.java index e4695b7ccd5..32eeded7024 100644 --- a/src/main/java/org/tron/core/db/api/index/TransactionIndex.java +++ b/src/main/java/org/tron/core/db/api/index/TransactionIndex.java @@ -64,6 +64,5 @@ protected void setAttribute() { .collect(Collectors.toList())); TIMESTAMP = attribute("timestamp", bytes -> getObject(bytes).getRawData().getTimestamp()); - } } diff --git a/src/main/java/org/tron/core/events/BlockchainListener.java b/src/main/java/org/tron/core/events/BlockchainListener.java deleted file mode 100644 index 3562702b411..00000000000 --- a/src/main/java/org/tron/core/events/BlockchainListener.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.core.events; - -import org.tron.protos.Protocol.Block; - -public interface BlockchainListener { - - /** - * New block added to blockchain. - */ - void addBlock(Block block); - - /** - * Genesis block added to blockchain. - */ - void addGenesisBlock(Block block); -} diff --git a/src/main/java/org/tron/core/exception/OutOfSlotTimeException.java b/src/main/java/org/tron/core/exception/OutOfSlotTimeException.java new file mode 100644 index 00000000000..644d37cd6d2 --- /dev/null +++ b/src/main/java/org/tron/core/exception/OutOfSlotTimeException.java @@ -0,0 +1,17 @@ +package org.tron.core.exception; + +public class OutOfSlotTimeException extends Exception { + + public OutOfSlotTimeException() { + super(); + } + + public OutOfSlotTimeException(String message) { + super(message); + } + + public OutOfSlotTimeException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/java/org/tron/core/exception/ReceiptException.java b/src/main/java/org/tron/core/exception/ReceiptException.java new file mode 100644 index 00000000000..89c99ce3700 --- /dev/null +++ b/src/main/java/org/tron/core/exception/ReceiptException.java @@ -0,0 +1,13 @@ +package org.tron.core.exception; + +public class ReceiptException extends TronException { + + public ReceiptException() { + super(); + } + + public ReceiptException(String message) { + super(message); + } +} + diff --git a/src/main/java/org/tron/core/exception/TransactionTraceException.java b/src/main/java/org/tron/core/exception/TransactionTraceException.java new file mode 100644 index 00000000000..ffbb7a480dc --- /dev/null +++ b/src/main/java/org/tron/core/exception/TransactionTraceException.java @@ -0,0 +1,13 @@ +package org.tron.core.exception; + +public class TransactionTraceException extends TronException { + + public TransactionTraceException() { + super(); + } + + public TransactionTraceException(String message) { + super(message); + } + +} \ No newline at end of file diff --git a/src/main/java/org/tron/core/exception/UnsupportVMException.java b/src/main/java/org/tron/core/exception/UnsupportVMException.java new file mode 100644 index 00000000000..26255a1e076 --- /dev/null +++ b/src/main/java/org/tron/core/exception/UnsupportVMException.java @@ -0,0 +1,13 @@ +package org.tron.core.exception; + +public class UnsupportVMException extends TronException { + + public UnsupportVMException() { + super(); + } + + public UnsupportVMException(String message) { + super(message); + } + +} diff --git a/src/main/java/org/tron/core/facade/TronBlockChain.java b/src/main/java/org/tron/core/facade/TronBlockChain.java deleted file mode 100644 index c03c802584e..00000000000 --- a/src/main/java/org/tron/core/facade/TronBlockChain.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.core.facade; - -import org.tron.protos.Protocol.Block; - -public interface TronBlockChain { - - /** - * last added block from blockchain. - */ - Block getBestBlock(); -} diff --git a/src/main/java/org/tron/core/net/message/TransactionMessage.java b/src/main/java/org/tron/core/net/message/TransactionMessage.java index bd47baf9c10..8a9a3aa222c 100644 --- a/src/main/java/org/tron/core/net/message/TransactionMessage.java +++ b/src/main/java/org/tron/core/net/message/TransactionMessage.java @@ -38,7 +38,7 @@ public Class getAnswerMessage() { } public TransactionCapsule getTransactionCapsule() { - this.transactionCapsule.resetResult(); + //this.transactionCapsule.resetResult(); return this.transactionCapsule; } } diff --git a/src/main/java/org/tron/core/net/message/TronMessageFactory.java b/src/main/java/org/tron/core/net/message/TronMessageFactory.java index e71a1b3e7d4..be4eedd8343 100644 --- a/src/main/java/org/tron/core/net/message/TronMessageFactory.java +++ b/src/main/java/org/tron/core/net/message/TronMessageFactory.java @@ -3,7 +3,6 @@ import org.apache.commons.lang3.ArrayUtils; import org.tron.common.overlay.message.MessageFactory; import org.tron.core.exception.P2pException; -import org.tron.core.exception.P2pException.TypeEnum; /** * msg factory. @@ -12,9 +11,6 @@ public class TronMessageFactory extends MessageFactory { @Override public TronMessage create(byte[] data) throws Exception { - if (data.length <= 1){ - throw new P2pException(TypeEnum.MESSAGE_WITH_WRONG_LENGTH, "len=" + data.length); - } try { byte type = data[0]; byte[] rawData = ArrayUtils.subarray(data, 1, data.length); diff --git a/src/main/java/org/tron/core/net/node/NodeDelegate.java b/src/main/java/org/tron/core/net/node/NodeDelegate.java index 2453c7dbe43..f485e13317c 100644 --- a/src/main/java/org/tron/core/net/node/NodeDelegate.java +++ b/src/main/java/org/tron/core/net/node/NodeDelegate.java @@ -49,4 +49,6 @@ Deque getBlockChainSummary(BlockId beginBLockId, Deque blockId BlockCapsule getGenesisBlock(); boolean canChainRevoke(long num); + + boolean forkOrNot(TransactionCapsule transactionCapsule); } diff --git a/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java b/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java index 93942289324..c12c38df432 100755 --- a/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java +++ b/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java @@ -30,12 +30,16 @@ import org.tron.core.exception.DupTransactionException; import org.tron.core.exception.ItemNotFoundException; import org.tron.core.exception.NonCommonBlockException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.ReceiptException; import org.tron.core.exception.StoreException; import org.tron.core.exception.TaposException; import org.tron.core.exception.TooBigTransactionException; import org.tron.core.exception.TransactionExpirationException; +import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.TronException; import org.tron.core.exception.UnLinkedBlockException; +import org.tron.core.exception.UnsupportVMException; import org.tron.core.exception.ValidateScheduleException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.net.message.BlockMessage; @@ -95,8 +99,16 @@ public synchronized LinkedList handleBlock(BlockCapsule block, boole throw new BadBlockException("TooBigTransaction exception," + e.getMessage()); } catch (TransactionExpirationException e) { throw new BadBlockException("Expiration exception," + e.getMessage()); + } catch (ReceiptException e) { + throw new BadBlockException("Receipt exception," + e.getMessage()); } catch (BadNumberBlockException e) { throw new BadBlockException("bad number exception," + e.getMessage()); + } catch (TransactionTraceException e) { + throw new BadBlockException("TransactionTrace Exception," + e.getMessage()); + } catch (OutOfSlotTimeException e) { + throw new BadBlockException("TransactionTrace Exception," + e.getMessage()); + } catch (UnsupportVMException e) { + throw new BadBlockException(e.getMessage()); } } @@ -112,8 +124,8 @@ public boolean handleTransaction(TransactionCapsule trx) throws BadTransactionEx dbManager.getTransactionIdCache().put(trx.getTransactionId(), true); } try { - dbManager.pushTransactions(trx); - } catch (ContractSizeNotEqualToOneException e){ + dbManager.pushTransaction(trx); + } catch (ContractSizeNotEqualToOneException e) { logger.info("Contract validate failed" + e.getMessage()); throw new BadTransactionException(); } catch (ContractValidateException e) { @@ -136,13 +148,25 @@ public boolean handleTransaction(TransactionCapsule trx) throws BadTransactionEx } catch (TaposException e) { logger.info("tapos error" + e.getMessage()); return false; + } catch (ReceiptException e) { + logger.info("Receipt exception," + e.getMessage()); } catch (TooBigTransactionException e) { logger.info("too big transaction" + e.getMessage()); return false; } catch (TransactionExpirationException e) { logger.info("expiration transaction" + e.getMessage()); return false; + } catch (TransactionTraceException e) { + logger.info("TransactionTrace Exception" + e.getMessage()); + return false; + } catch (OutOfSlotTimeException e) { + logger.info("OutOfSlotTimeException Exception" + e.getMessage()); + return false; + } catch (UnsupportVMException e) { + logger.warn(e.getMessage()); + return false; } + return true; } @@ -365,4 +389,9 @@ public BlockCapsule getGenesisBlock() { public boolean canChainRevoke(long num) { return num >= dbManager.getSyncBeginNumber(); } + + @Override + public boolean forkOrNot(TransactionCapsule transactionCapsule) { + return dbManager.getForkController().forkOrNot(transactionCapsule); + } } diff --git a/src/main/java/org/tron/core/net/node/NodeImpl.java b/src/main/java/org/tron/core/net/node/NodeImpl.java index e30b48300cb..1c2eab5b107 100644 --- a/src/main/java/org/tron/core/net/node/NodeImpl.java +++ b/src/main/java/org/tron/core/net/node/NodeImpl.java @@ -4,8 +4,6 @@ import static org.tron.core.config.Parameter.NetConstants.MAX_TRX_PER_PEER; import static org.tron.core.config.Parameter.NetConstants.MSG_CACHE_DURATION_IN_BLOCKS; import static org.tron.core.config.Parameter.NetConstants.NET_MAX_TRX_PER_SECOND; -import static org.tron.core.config.Parameter.NodeConstant.MAX_BLOCKS_ALREADY_FETCHED; -import static org.tron.core.config.Parameter.NodeConstant.MAX_BLOCKS_IN_PROCESS; import static org.tron.core.config.Parameter.NodeConstant.MAX_BLOCKS_SYNC_FROM_ONE_PEER; import com.google.common.cache.Cache; @@ -29,7 +27,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -39,6 +36,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.overlay.discover.node.statistics.MessageCount; import org.tron.common.overlay.message.Message; import org.tron.common.overlay.server.Channel.TronState; import org.tron.common.overlay.server.SyncPool; @@ -83,6 +81,8 @@ public class NodeImpl extends PeerConnectionDelegate implements Node { @Autowired private SyncPool pool; + private MessageCount trxCount = new MessageCount(); + private Cache TrxCache = CacheBuilder.newBuilder() .maximumSize(100_000).expireAfterWrite(1, TimeUnit.HOURS).initialCapacity(100_000) .recordStats().build(); @@ -144,29 +144,23 @@ public void clear() { } public void add(Entry id, PeerConnection peer) { - if (send.containsKey(peer) && send.get(peer).containsKey(id.getValue())) { - send.get(peer).get(id.getValue()).offer(id.getKey()); - } else if (send.containsKey(peer)) { + if (send.containsKey(peer) && !send.get(peer).containsKey(id.getValue())) { send.get(peer).put(id.getValue(), new LinkedList<>()); - send.get(peer).get(id.getValue()).offer(id.getKey()); - } else { + } else if (!send.containsKey(peer)) { send.put(peer, new HashMap<>()); send.get(peer).put(id.getValue(), new LinkedList<>()); - send.get(peer).get(id.getValue()).offer(id.getKey()); } + send.get(peer).get(id.getValue()).offer(id.getKey()); } public void add(PriorItem id, PeerConnection peer) { - if (send.containsKey(peer) && send.get(peer).containsKey(id.getType())) { - send.get(peer).get(id.getType()).offer(id.getHash()); - } else if (send.containsKey(peer)) { + if (send.containsKey(peer) && !send.get(peer).containsKey(id.getType())) { send.get(peer).put(id.getType(), new LinkedList<>()); - send.get(peer).get(id.getType()).offer(id.getHash()); - } else { + } else if (!send.containsKey(peer)) { send.put(peer, new HashMap<>()); send.get(peer).put(id.getType(), new LinkedList<>()); - send.get(peer).get(id.getType()).offer(id.getHash()); } + send.get(peer).get(id.getType()).offer(id.getHash()); } public int getSize(PeerConnection peer) { @@ -205,9 +199,6 @@ void sendFetch() { new ThreadFactoryBuilder() .setNameFormat("TrxsHandlePool-%d").build()); - //public - //TODO:need auto erase oldest block - private Queue freshBlockId = new ConcurrentLinkedQueue() { @Override public boolean offer(BlockId blockId) { @@ -245,7 +236,7 @@ public boolean offer(BlockId blockId) { private ExecutorService broadPool = Executors.newFixedThreadPool(2, new ThreadFactory() { @Override public Thread newThread(Runnable r) { - return new Thread(r, "broad-msg-"); + return new Thread(r, "broad-msg"); } }); @@ -269,9 +260,6 @@ public Thread newThread(Runnable r) { private ExecutorLoop loopAdvertiseInv; - private ExecutorService handleBackLogBlocksPool = Executors.newCachedThreadPool(); - - private ScheduledExecutorService fetchSyncBlocksExecutor = Executors .newSingleThreadScheduledExecutor(); @@ -528,6 +516,11 @@ private void consumerAdvObjToSpread() { spread.putAll(advObjToSpread); advObjToSpread.clear(); } + for (InventoryType type : spread.values()){ + if (type == InventoryType.TRX){ + trxCount.add(); + } + } getActivePeer().stream() .filter(peer -> !peer.isNeedSyncFromUs()) .forEach(peer -> @@ -543,10 +536,7 @@ private void consumerAdvObjToSpread() { } private synchronized void handleSyncBlock() { - if (((ThreadPoolExecutor) handleBackLogBlocksPool).getActiveCount() > MAX_BLOCKS_IN_PROCESS) { - logger.info("we're already processing too many blocks"); - return; - } else if (isSuspendFetch) { + if (isSuspendFetch) { isSuspendFetch = false; } @@ -594,14 +584,6 @@ private synchronized void handleSyncBlock() { } }); - if (((ThreadPoolExecutor) handleBackLogBlocksPool).getActiveCount() > MAX_BLOCKS_IN_PROCESS) { - logger.info("we're already processing too many blocks"); - if (blockWaitToProc.size() >= MAX_BLOCKS_ALREADY_FETCHED) { - isSuspendFetch = true; - } - break; - } - } } @@ -632,37 +614,20 @@ private synchronized void logNodeStatus() { } public synchronized void disconnectInactive() { - //logger.debug("size of activePeer: " + getActivePeer().size()); + getActivePeer().forEach(peer -> { final boolean[] isDisconnected = {false}; - final ReasonCode[] reasonCode = {ReasonCode.USER_REASON}; peer.getAdvObjWeRequested().values().stream() .filter(time -> time < Time.getCurrentMillis() - NetConstants.ADV_TIME_OUT) - .findFirst().ifPresent(time -> { - isDisconnected[0] = true; - reasonCode[0] = ReasonCode.FETCH_FAIL; - }); + .findFirst().ifPresent(time -> isDisconnected[0] = true); if (!isDisconnected[0]) { peer.getSyncBlockRequested().values().stream() .filter(time -> time < Time.getCurrentMillis() - NetConstants.SYNC_TIME_OUT) - .findFirst().ifPresent(time -> { - isDisconnected[0] = true; - reasonCode[0] = ReasonCode.SYNC_FAIL; - }); + .findFirst().ifPresent(time -> isDisconnected[0] = true); } -// TODO:optimize here -// if (!isDisconnected[0]) { -// if (del.getHeadBlockId().getNum() - peer.getHeadBlockWeBothHave().getNum() -// > 2 * NetConstants.HEAD_NUM_CHECK_TIME / ChainConstant.BLOCK_PRODUCED_INTERVAL -// && peer.getConnectTime() < Time.getCurrentMillis() - NetConstants.HEAD_NUM_CHECK_TIME -// && peer.getSyncBlockRequested().isEmpty()) { -// isDisconnected[0] = true; -// } -// } - if (isDisconnected[0]) { disconnectPeer(peer, ReasonCode.TIME_OUT); } @@ -697,6 +662,7 @@ private void onHandleInventoryMessage(PeerConnection peer, InventoryMessage msg) && (peer.isAdvInvFull() || isFlooded())) { logger.warn("A peer is flooding us, stop handle inv, the peer is: " + peer); + //todo,should be disconnect the peer? return; } @@ -769,6 +735,10 @@ private void onHandleBlockMessage(PeerConnection peer, BlockMessage blkMsg) { processAdvBlock(peer, blkMsg.getBlockCapsule()); startFetchItem(); } + } else { + if (!syncFlag) {//not we request and not sync,disconnect + banTraitorPeer(peer, ReasonCode.BAD_PROTOCOL); + } } } @@ -885,7 +855,8 @@ private void onHandleTransactionMessage(PeerConnection peer, TransactionMessage peer.getNode().getHost()); return; } - if(del.handleTransaction(trxMsg.getTransactionCapsule())){ + if (del.forkOrNot(trxMsg.getTransactionCapsule()) + && del.handleTransaction(trxMsg.getTransactionCapsule())) { broadcast(trxMsg); } } catch (TraitorPeerException e) { @@ -903,18 +874,32 @@ private void onHandleTransactionsMessage(PeerConnection peer, TransactionsMessag } } + private boolean checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage syncMsg){ + long lastBlockNum = syncMsg.getBlockIds().get(syncMsg.getBlockIds().size() - 1).getNum(); + BlockId lastSyncBlockId = peer.getLastSyncBlockId(); + if (lastSyncBlockId != null && lastBlockNum < lastSyncBlockId.getNum()){ + logger.warn("Peer {} receive bad SyncBlockChain message, firstNum {} lastSyncNum {}.", peer.getInetAddress(), lastBlockNum, lastSyncBlockId.getNum()); + return false; + } + return true; + } + private void onHandleSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage syncMsg) { peer.setTronState(TronState.SYNCING); + BlockId headBlockId = del.getHeadBlockId(); + long remainNum = 0; LinkedList blockIds = new LinkedList<>(); List summaryChainIds = syncMsg.getBlockIds(); - long remainNum = 0; - + if (!checkSyncBlockChainMessage(peer, syncMsg)){ + disconnectPeer(peer, ReasonCode.BAD_PROTOCOL); + return; + } try { blockIds = del.getLostBlockIds(summaryChainIds); } catch (StoreException e) { logger.error(e.getMessage()); } - + if (blockIds.isEmpty()) { if (CollectionUtils.isNotEmpty(summaryChainIds) && !del .canChainRevoke(summaryChainIds.get(0).getNum())) { @@ -943,15 +928,80 @@ private void onHandleSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMe startSyncWithPeer(peer); } + if (blockIds.peekLast() == null){ + peer.setLastSyncBlockId(headBlockId); + }else { + peer.setLastSyncBlockId(blockIds.peekLast()); + } + peer.setRemainNum(remainNum); peer.sendMessage(new ChainInventoryMessage(blockIds, remainNum)); } + private boolean checkFetchInvDataMsg(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg){ + MessageTypes type = fetchInvDataMsg.getInvMessageType(); + if (type == MessageTypes.TRX) { + int elementCount = peer.getNodeStatistics().messageStatistics.tronInTrxFetchInvDataElement.getCount(10); + int maxCount = trxCount.getCount(60); + if (elementCount > maxCount){ + logger.warn("Check FetchInvDataMsg failed: Peer {} request count {} in 10s gt trx count {} generate in 60s", peer.getInetAddress(), elementCount, maxCount); + return false; + } + for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { + if (!peer.getAdvObjWeSpread().containsKey(hash)){ + logger.warn("Check FetchInvDataMsg failed: Peer {} get trx {} we not spread.", peer.getInetAddress(), hash); + return false; + } + } + }else { + boolean isAdv = true; + for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { + if (!peer.getAdvObjWeSpread().containsKey(hash)){ + isAdv = false; + break; + } + } + if (isAdv){ + MessageCount tronOutAdvBlock = peer.getNodeStatistics().messageStatistics.tronOutAdvBlock; + tronOutAdvBlock.add(fetchInvDataMsg.getHashList().size()); + int outBlockCountIn1min = tronOutAdvBlock.getCount(60); + int producedBlockIn2min = 120_000 / ChainConstant.BLOCK_PRODUCED_INTERVAL; + if (outBlockCountIn1min > producedBlockIn2min){ + logger.warn("Check FetchInvDataMsg failed: Peer {} outBlockCount {} producedBlockIn2min {}", + peer.getInetAddress(), outBlockCountIn1min, producedBlockIn2min); + return false; + } + }else { + if (!peer.isNeedSyncFromUs()){ + logger.warn("Check FetchInvDataMsg failed: Peer {} not need sync from us.", peer.getInetAddress()); + return false; + } + for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { + long blockNum = new BlockId(hash).getNum(); + long minBlockNum = peer.getLastSyncBlockId().getNum() - 2 * NodeConstant.SYNC_FETCH_BATCH_NUM; + if (blockNum < minBlockNum){ + logger.warn("Check FetchInvDataMsg failed: Peer {} blockNum {} lt minBlockNum {}", peer.getInetAddress(), blockNum, minBlockNum); + return false; + } + if (peer.getSyncBlockIdCache().getIfPresent(hash) != null){ + logger.warn("Check FetchInvDataMsg failed: Peer {} blockNum {} hash {} is exist", peer.getInetAddress(), blockNum, hash); + return false; + } + peer.getSyncBlockIdCache().put(hash, 1); + } + } + } + return true; + } + private void onHandleFetchDataMessage(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) { - MessageTypes type = fetchInvDataMsg.getInvMessageType(); + if (!checkFetchInvDataMsg(peer, fetchInvDataMsg)){ + disconnectPeer(peer, ReasonCode.BAD_PROTOCOL); + return; + } + MessageTypes type = fetchInvDataMsg.getInvMessageType(); BlockCapsule block = null; - List transactions = Lists.newArrayList(); int size = 0; @@ -973,6 +1023,7 @@ private void onHandleFetchDataMessage(PeerConnection peer, FetchInvDataMessage f if (msg == null) { logger.error("fetch message {} {} failed.", type, hash); peer.sendMessage(new ItemNotFound()); + //todo,should be disconnect? return; } @@ -1181,8 +1232,7 @@ private synchronized void startFetchSyncBlock() { if (!send.containsKey(peer)) { //TODO: Attention multi thread here send.put(peer, new LinkedList<>()); } - for (BlockId blockId : - peer.getSyncBlockToFetch()) { + for (BlockId blockId : peer.getSyncBlockToFetch()) { if (!request.contains(blockId) //TODO: clean processing block && (syncBlockIdWeRequested.getIfPresent(blockId) == null)) { send.get(peer).add(blockId); @@ -1303,7 +1353,6 @@ public void shutDown() { loopSyncBlockChain.shutdown(); loopFetchBlocks.shutdown(); loopAdvertiseInv.shutdown(); - handleBackLogBlocksPool.shutdown(); fetchSyncBlocksExecutor.shutdown(); handleSyncBlockExecutor.shutdown(); } diff --git a/src/main/java/org/tron/core/net/peer/PeerConnection.java b/src/main/java/org/tron/core/net/peer/PeerConnection.java index 79dec0fa556..233adcaab93 100644 --- a/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -3,8 +3,9 @@ import static org.tron.core.config.Parameter.NetConstants.MAX_INVENTORY_SIZE_IN_MINUTES; import static org.tron.core.config.Parameter.NetConstants.NET_MAX_TRX_PER_SECOND; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.util.Deque; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; @@ -15,6 +16,8 @@ import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.LinkedBlockingQueue; import javafx.util.Pair; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -24,6 +27,7 @@ import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.Time; import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.Parameter.NodeConstant; import org.tron.core.net.node.Item; @Slf4j @@ -31,6 +35,17 @@ @Scope("prototype") public class PeerConnection extends Channel { + private Cache syncBlockIdCache = CacheBuilder.newBuilder() + .maximumSize(2 * NodeConstant.SYNC_FETCH_BATCH_NUM).build(); + + @Setter + @Getter + private BlockId lastSyncBlockId; + + @Setter + @Getter + private long remainNum; + private volatile boolean syncFlag = true; private HelloMessage helloMessage; @@ -52,19 +67,10 @@ public Map getAdvObjSpreadToUs() { return advObjSpreadToUs; } - public void setAdvObjSpreadToUs( - HashMap advObjSpreadToUs) { - this.advObjSpreadToUs = advObjSpreadToUs; - } - public Map getAdvObjWeSpread() { return advObjWeSpread; } - public void setAdvObjWeSpread(HashMap advObjWeSpread) { - this.advObjWeSpread = advObjWeSpread; - } - public boolean isAdvInhibit() { return advInhibit; } @@ -88,6 +94,10 @@ public Pair, Long> getSyncChainRequested() { return syncChainRequested; } + public Cache getSyncBlockIdCache() { + return syncBlockIdCache; + } + public void setSyncChainRequested( Pair, Long> syncChainRequested) { this.syncChainRequested = syncChainRequested; @@ -168,7 +178,7 @@ private void removeIterator(Iterator> iterator, long old } public boolean isAdvInvFull() { - return advObjSpreadToUs.size() > MAX_INVENTORY_SIZE_IN_MINUTES * 60 * NET_MAX_TRX_PER_SECOND; + return advObjSpreadToUs.size() > MAX_INVENTORY_SIZE_IN_MINUTES * 60 * NET_MAX_TRX_PER_SECOND; } public boolean isBanned() { @@ -280,6 +290,5 @@ public boolean idle() { public void sendMessage(Message message) { msgQueue.sendMessage(message); - nodeStatistics.tronOutMessage.add(); } } diff --git a/src/main/java/org/tron/core/services/RpcApiService.java b/src/main/java/org/tron/core/services/RpcApiService.java index a9c4f8ee1d2..3e7c44ec12a 100755 --- a/src/main/java/org/tron/core/services/RpcApiService.java +++ b/src/main/java/org/tron/core/services/RpcApiService.java @@ -17,7 +17,6 @@ import org.apache.commons.codec.binary.Hex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; import org.tron.api.DatabaseGrpc.DatabaseImplBase; import org.tron.api.GrpcAPI; import org.tron.api.GrpcAPI.AccountNetMessage; @@ -36,6 +35,7 @@ import org.tron.api.GrpcAPI.EasyTransferMessage; import org.tron.api.GrpcAPI.EasyTransferResponse; import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.ExchangeList; import org.tron.api.GrpcAPI.Node; import org.tron.api.GrpcAPI.NodeList; import org.tron.api.GrpcAPI.NumberMessage; @@ -58,36 +58,32 @@ import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.StringUtil; import org.tron.common.utils.Utils; -import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.WalletSolidity; -import org.tron.core.actuator.Actuator; -import org.tron.core.actuator.ActuatorFactory; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; -import org.tron.core.capsule.ContractCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.config.args.Args; import org.tron.core.db.BandwidthProcessor; import org.tron.core.db.Manager; import org.tron.core.exception.ContractValidateException; -import org.tron.core.exception.HeaderNotFound; import org.tron.core.exception.StoreException; import org.tron.protos.Contract; import org.tron.protos.Contract.AccountCreateContract; import org.tron.protos.Contract.AssetIssueContract; -import org.tron.protos.Contract.CreateSmartContract; import org.tron.protos.Contract.ParticipateAssetIssueContract; import org.tron.protos.Contract.TransferAssetContract; import org.tron.protos.Contract.TransferContract; import org.tron.protos.Contract.UnfreezeAssetContract; +import org.tron.protos.Contract.UpdateSettingContract; import org.tron.protos.Contract.VoteWitnessContract; import org.tron.protos.Contract.WitnessCreateContract; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Account; import org.tron.protos.Protocol.Block; import org.tron.protos.Protocol.DynamicProperties; +import org.tron.protos.Protocol.Exchange; import org.tron.protos.Protocol.Proposal; import org.tron.protos.Protocol.Transaction; import org.tron.protos.Protocol.Transaction.Contract.ContractType; @@ -577,50 +573,7 @@ private void createTransactionExtention(Message request, ContractType contractTy private TransactionCapsule createTransactionCapsule(com.google.protobuf.Message message, ContractType contractType) throws ContractValidateException { - TransactionCapsule trx = new TransactionCapsule(message, contractType); - if (contractType != ContractType.CreateSmartContract - && contractType != ContractType.TriggerSmartContract) { - List actList = ActuatorFactory.createActuator(trx, dbManager); - for (Actuator act : actList) { - act.validate(); - } - } - - if (contractType == ContractType.CreateSmartContract) { - // insure one owner just have one contract - CreateSmartContract contract = ContractCapsule - .getSmartContractFromTransaction(trx.getInstance()); - byte[] ownerAddress = contract.getOwnerAddress().toByteArray(); - if (dbManager.getAccountContractIndexStore().get(ownerAddress) != null) { - throw new ContractValidateException( - "Trying to create second contract with one account: address: " + Wallet - .encode58Check(ownerAddress)); - } - -// // insure the new contract address haven't exist -// if (deposit.getAccount(contractAddress) != null) { -// logger.error("Trying to create a contract with existing contract address: " + Wallet -// .encode58Check(contractAddress)); -// return; -// } - } - - try { - BlockCapsule headBlock = null; - List blockList = dbManager.getBlockStore().getBlockByLatestNum(1); - if (CollectionUtils.isEmpty(blockList)) { - throw new HeaderNotFound("latest block not found"); - } else { - headBlock = blockList.get(0); - } - trx.setReference(headBlock.getNum(), headBlock.getBlockId().getBytes()); - long expiration = headBlock.getTimeStamp() + Constant.TRANSACTION_DEFAULT_EXPIRATION_TIME; - trx.setExpiration(expiration); - trx.setTimestamp(); - } catch (HeaderNotFound headerNotFound) { - headerNotFound.printStackTrace(); - } - return trx; + return wallet.createTransactionCapsule(message, contractType); } @Override @@ -805,6 +758,13 @@ public void voteWitnessAccount2(VoteWitnessContract request, createTransactionExtention(request, ContractType.VoteWitnessContract, responseObserver); } + @Override + public void updateSetting(UpdateSettingContract request, + StreamObserver responseObserver) { + createTransactionExtention(request, ContractType.UpdateSettingContract, + responseObserver); + } + @Override public void createWitness(WitnessCreateContract request, StreamObserver responseObserver) { @@ -1001,16 +961,48 @@ public void proposalDelete(Contract.ProposalDeleteContract request, createTransactionExtention(request, ContractType.ProposalDeleteContract, responseObserver); } +// @Override +// public void buyStorage(Contract.BuyStorageContract request, +// StreamObserver responseObserver) { +// createTransactionExtention(request, ContractType.BuyStorageContract, responseObserver); +// } +// +// @Override +// public void buyStorageBytes(Contract.BuyStorageBytesContract request, +// StreamObserver responseObserver) { +// createTransactionExtention(request, ContractType.BuyStorageBytesContract, responseObserver); +// } +// +// @Override +// public void sellStorage(Contract.SellStorageContract request, +// StreamObserver responseObserver) { +// createTransactionExtention(request, ContractType.SellStorageContract, responseObserver); +// } + + @Override + public void exchangeCreate(Contract.ExchangeCreateContract request, + StreamObserver responseObserver) { + createTransactionExtention(request, ContractType.ExchangeCreateContract, responseObserver); + } + + @Override - public void buyStorage(Contract.BuyStorageContract request, + public void exchangeInject(Contract.ExchangeInjectContract request, StreamObserver responseObserver) { - createTransactionExtention(request, ContractType.BuyStorageContract, responseObserver); + createTransactionExtention(request, ContractType.ExchangeInjectContract, responseObserver); } @Override - public void sellStorage(Contract.SellStorageContract request, + public void exchangeWithdraw(Contract.ExchangeWithdrawContract request, StreamObserver responseObserver) { - createTransactionExtention(request, ContractType.SellStorageContract, responseObserver); + createTransactionExtention(request, ContractType.ExchangeWithdrawContract, responseObserver); + } + + @Override + public void exchangeTransaction(Contract.ExchangeTransactionContract request, + StreamObserver responseObserver) { + createTransactionExtention(request, ContractType.ExchangeTransactionContract, + responseObserver); } @Override @@ -1201,6 +1193,19 @@ public void getProposalById(BytesMessage request, responseObserver.onCompleted(); } + @Override + public void getExchangeById(BytesMessage request, + StreamObserver responseObserver) { + ByteString exchangeId = request.getValue(); + + if (Objects.nonNull(exchangeId)) { + responseObserver.onNext(wallet.getExchangeById(exchangeId)); + } else { + responseObserver.onNext(null); + } + responseObserver.onCompleted(); + } + @Override public void getBlockByLimitNext(BlockLimit request, StreamObserver responseObserver) { @@ -1304,7 +1309,7 @@ public void triggerContract(Contract.TriggerSmartContract request, try { TransactionCapsule trxCap = createTransactionCapsule(request, ContractType.TriggerSmartContract); - trx = wallet.triggerContract(request, trxCap); + trx = wallet.triggerContract(request, trxCap, trxExtBuilder, retBuilder); trxExtBuilder.setTransaction(trx); trxExtBuilder.setTxid(trxCap.getTransactionId().getByteString()); retBuilder.setResult(true).setCode(response_code.SUCCESS); @@ -1312,6 +1317,7 @@ public void triggerContract(Contract.TriggerSmartContract request, retBuilder.setResult(false).setCode(response_code.CONTRACT_VALIDATE_ERROR) .setMessage(ByteString.copyFromUtf8("contract validate error : " + e.getMessage())); logger.debug("ContractValidateException: {}", e.getMessage()); + // FIXME return; } catch (Exception e) { retBuilder.setResult(false).setCode(response_code.OTHER_ERROR) @@ -1353,6 +1359,13 @@ public void listProposals(EmptyMessage request, responseObserver.onCompleted(); } + @Override + public void listExchanges(EmptyMessage request, + StreamObserver responseObserver) { + responseObserver.onNext(wallet.getExchangeList()); + responseObserver.onCompleted(); + } + @Override public void getChainParameters(EmptyMessage request, StreamObserver responseObserver) { diff --git a/src/main/java/org/tron/core/services/WitnessService.java b/src/main/java/org/tron/core/services/WitnessService.java index 4bfeb902082..5003a42bcdc 100755 --- a/src/main/java/org/tron/core/services/WitnessService.java +++ b/src/main/java/org/tron/core/services/WitnessService.java @@ -8,9 +8,9 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.joda.time.DateTime; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.Service; +import org.tron.common.application.TronApplicationContext; import org.tron.common.backup.BackupManager; import org.tron.common.backup.BackupManager.BackupStatusEnum; import org.tron.common.backup.BackupServer; @@ -24,6 +24,8 @@ import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ReceiptException; +import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.TronException; import org.tron.core.exception.UnLinkedBlockException; import org.tron.core.exception.ValidateScheduleException; @@ -43,13 +45,14 @@ public class WitnessService implements Service { protected Map localWitnessStateMap = Maps .newHashMap(); // private Thread generateThread; + private volatile boolean isRunning = false; private Map privateKeyMap = Maps.newHashMap(); private volatile boolean needSyncCheck = Args.getInstance().isNeedSyncCheck(); private WitnessController controller; - private AnnotationConfigApplicationContext context; + private TronApplicationContext context; private BackupManager backupManager; @@ -58,18 +61,19 @@ public class WitnessService implements Service { /** * Construction method. */ - public WitnessService(Application tronApp, AnnotationConfigApplicationContext context) { + public WitnessService(Application tronApp, TronApplicationContext context) { this.tronApp = tronApp; this.context = context; backupManager = context.getBean(BackupManager.class); backupServer = context.getBean(BackupServer.class); generateThread = new Thread(scheduleProductionLoop); controller = tronApp.getDbManager().getWitnessController(); - new Thread(()->{ - while (needSyncCheck){ - try{ + new Thread(() -> { + while (needSyncCheck) { + try { Thread.sleep(100); - }catch (Exception e){} + } catch (Exception e) { + } } backupServer.initServer(); }).start(); @@ -136,7 +140,7 @@ private void blockProductionLoop() throws InterruptedException { */ private BlockProductionCondition tryProduceBlock() throws InterruptedException { logger.info("Try Produce Block"); - if (!backupManager.getStatus().equals(BackupStatusEnum.MASTER)){ + if (!backupManager.getStatus().equals(BackupStatusEnum.MASTER)) { return BlockProductionCondition.BACKUP_STATUS_IS_NOT_MASTER; } long now = DateTime.now().getMillis() + 50L; @@ -218,6 +222,7 @@ private BlockProductionCondition tryProduceBlock() throws InterruptedException { } try { + controller.setGeneratingBlock(true); BlockCapsule block = generateBlock(scheduledTime, scheduledWitness); @@ -248,7 +253,6 @@ private BlockProductionCondition tryProduceBlock() throws InterruptedException { } finally { controller.setGeneratingBlock(false); } - } private void broadcastBlock(BlockCapsule block) { @@ -260,7 +264,7 @@ private void broadcastBlock(BlockCapsule block) { } private BlockCapsule generateBlock(long when, ByteString witnessAddress) - throws ValidateSignatureException, ContractValidateException, ContractExeException, UnLinkedBlockException, ValidateScheduleException, AccountResourceInsufficientException { + throws ValidateSignatureException, ContractValidateException, ContractExeException, UnLinkedBlockException, ValidateScheduleException, AccountResourceInsufficientException, ReceiptException, TransactionTraceException { return tronApp.getDbManager().generateBlock(this.localWitnessStateMap.get(witnessAddress), when, this.privateKeyMap.get(witnessAddress)); } @@ -298,6 +302,7 @@ public void init(Args args) { public void start() { isRunning = true; generateThread.start(); + } @Override diff --git a/src/main/java/org/tron/core/services/http/DeployContractServlet.java b/src/main/java/org/tron/core/services/http/DeployContractServlet.java new file mode 100644 index 00000000000..b4d0ecb44dd --- /dev/null +++ b/src/main/java/org/tron/core/services/http/DeployContractServlet.java @@ -0,0 +1,87 @@ +package org.tron.core.services.http; + +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.Strings; +import com.google.protobuf.ByteString; +import java.io.IOException; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.utils.ByteArray; +import org.tron.core.Wallet; +import org.tron.protos.Contract.CreateSmartContract; +import org.tron.protos.Protocol.SmartContract; +import org.tron.protos.Protocol.SmartContract.ABI; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; + + +@Component +@Slf4j +public class DeployContractServlet extends HttpServlet { + + @Autowired + private Wallet wallet; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) { + try { + String contract = request.getReader().lines() + .collect(Collectors.joining(System.lineSeparator())); + CreateSmartContract.Builder build = CreateSmartContract.newBuilder(); + JSONObject jsonObject = JSONObject.parseObject(contract); + byte[] ownerAddress = ByteArray.fromHexString(jsonObject.getString("owner_address")); + build.setOwnerAddress(ByteString.copyFrom(ownerAddress)); + + String abi = jsonObject.getString("abi"); + StringBuffer abiSB = new StringBuffer("{"); + abiSB.append("\"entrys\":"); + abiSB.append(abi); + abiSB.append("}"); + ABI.Builder abiBuilder = ABI.newBuilder(); + JsonFormat.merge(abiSB.toString(), abiBuilder); + + long feeLimit = jsonObject.getLongValue("fee_limit"); + + SmartContract.Builder smartBuilder = SmartContract.newBuilder(); + smartBuilder.setAbi(abiBuilder) + .setCallValue(jsonObject.getLongValue("call_value")) + .setConsumeUserResourcePercent(jsonObject.getLongValue("consume_user_resource_percent")); + if (!ArrayUtils.isEmpty(ownerAddress)) { + smartBuilder.setOriginAddress(ByteString.copyFrom(ownerAddress)); + } + + byte[] byteCode = ByteArray.fromHexString(jsonObject.getString("bytecode")); + if (!ArrayUtils.isEmpty(byteCode)) { + smartBuilder.setBytecode(ByteString.copyFrom(byteCode)); + } + String name = jsonObject.getString("name"); + if (!Strings.isNullOrEmpty(name)) { + smartBuilder.setName(name); + } + + build.setNewContract(smartBuilder); + Transaction tx = wallet + .createTransactionCapsule(build.build(), ContractType.CreateSmartContract).getInstance(); + Transaction.Builder txBuilder = tx.toBuilder(); + Transaction.raw.Builder rawBuilder = tx.getRawData().toBuilder(); + rawBuilder.setFeeLimit(feeLimit); + txBuilder.setRawData(rawBuilder); + response.getWriter().println(Util.printTransaction(txBuilder.build())); + } catch (Exception e) { + logger.debug("Exception: {}", e.getMessage()); + try { + response.getWriter().println(Util.printErrorMsg(e)); + } catch (IOException ioe) { + logger.debug("IOException: {}", ioe.getMessage()); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java b/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java index ff23e337949..66ba259f493 100644 --- a/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java +++ b/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java @@ -91,6 +91,12 @@ public class FullNodeHttpApiService implements Service { private GenerateAddressServlet generateAddressServlet; @Autowired private ValidateAddressServlet validateAddressServlet; + @Autowired + private DeployContractServlet deployContractServlet; + @Autowired + private TriggerSmartContractServlet triggerSmartContractServlet; + @Autowired + private GetContractServlet getContractServlet; @Override public void init() { @@ -149,6 +155,9 @@ public void start() { context.addServlet(new ServletHolder(easyTransferByPrivateServlet), "/easytransferbyprivate"); context.addServlet(new ServletHolder(generateAddressServlet), "/generateaddress"); context.addServlet(new ServletHolder(validateAddressServlet), "/validateaddress"); + context.addServlet(new ServletHolder(deployContractServlet), "/deploycontract"); + context.addServlet(new ServletHolder(triggerSmartContractServlet), "/triggersmartcontract"); + context.addServlet(new ServletHolder(getContractServlet), "/getcontract"); server.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); diff --git a/src/main/java/org/tron/core/services/http/GetContractServlet.java b/src/main/java/org/tron/core/services/http/GetContractServlet.java new file mode 100644 index 00000000000..fa310ba585b --- /dev/null +++ b/src/main/java/org/tron/core/services/http/GetContractServlet.java @@ -0,0 +1,62 @@ +package org.tron.core.services.http; + +import com.alibaba.fastjson.JSONObject; +import java.io.IOException; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.BytesMessage; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; + + +@Component +@Slf4j +public class GetContractServlet extends HttpServlet { + + @Autowired + private Wallet wallet; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + try { + String input = request.getParameter("value"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("value", input); + BytesMessage.Builder build = BytesMessage.newBuilder(); + JsonFormat.merge(jsonObject.toJSONString(), build); + SmartContract smartContract = wallet.getContract(build.build()); + JSONObject jsonSmartContract = JSONObject.parseObject(JsonFormat.printToString(smartContract)); + response.getWriter().println(jsonSmartContract.toJSONString()); + } catch (Exception e) { + logger.debug("Exception: {}", e.getMessage()); + try { + response.getWriter().println(Util.printErrorMsg(e)); + } catch (IOException ioe) { + logger.debug("IOException: {}", ioe.getMessage()); + } + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) { + try { + String input = request.getReader().lines() + .collect(Collectors.joining(System.lineSeparator())); + BytesMessage.Builder build = BytesMessage.newBuilder(); + JsonFormat.merge(input, build); + SmartContract smartContract = wallet.getContract(build.build()); + JSONObject jsonSmartContract = JSONObject.parseObject(JsonFormat.printToString(smartContract)); + response.getWriter().println(jsonSmartContract.toJSONString()); + } catch (Exception e) { + logger.debug("Exception: {}", e.getMessage()); + try { + response.getWriter().println(Util.printErrorMsg(e)); + } catch (IOException ioe) { + logger.debug("IOException: {}", ioe.getMessage()); + } + } + } +} diff --git a/src/main/java/org/tron/core/services/http/JsonFormat.java b/src/main/java/org/tron/core/services/http/JsonFormat.java index af4eb7132c6..7f2143820ce 100644 --- a/src/main/java/org/tron/core/services/http/JsonFormat.java +++ b/src/main/java/org/tron/core/services/http/JsonFormat.java @@ -49,6 +49,7 @@ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; import org.tron.common.utils.ByteArray; @@ -625,6 +626,12 @@ private static Object handlePrimitive(Tokenizer tokenizer, FieldDescriptor field } } else { String id = tokenizer.consumeIdentifier(); + if (StringUtils.isAllLowerCase(id)){ + char b = id.charAt(0); + b = (char)(b + 'A' - 'a'); + String s = id.substring(1); + id = b + s; + } value = enumType.findValueByName(id); if (value == null) { throw tokenizer.parseExceptionPreviousToken("Enum type \"" diff --git a/src/main/java/org/tron/core/services/http/TriggerSmartContractServlet.java b/src/main/java/org/tron/core/services/http/TriggerSmartContractServlet.java new file mode 100644 index 00000000000..be56103c193 --- /dev/null +++ b/src/main/java/org/tron/core/services/http/TriggerSmartContractServlet.java @@ -0,0 +1,91 @@ +package org.tron.core.services.http; + +import com.alibaba.fastjson.JSONObject; +import com.google.protobuf.ByteString; +import java.io.IOException; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.spongycastle.util.encoders.Hex; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.Return; +import org.tron.api.GrpcAPI.Return.response_code; +import org.tron.api.GrpcAPI.TransactionExtention; +import org.tron.common.crypto.Hash; +import org.tron.common.utils.ByteArray; +import org.tron.core.Wallet; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.exception.ContractValidateException; +import org.tron.protos.Contract.TriggerSmartContract; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; + + +@Component +@Slf4j +public class TriggerSmartContractServlet extends HttpServlet { + + @Autowired + private Wallet wallet; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + } + + public static String parseMethod(String methodSign, String params) { + byte[] selector = new byte[4]; + System.arraycopy(Hash.sha3(methodSign.getBytes()), 0, selector, 0, 4); + System.out.println(methodSign + ":" + Hex.toHexString(selector)); + if (StringUtils.isEmpty(params)) { + return Hex.toHexString(selector); + } + String result = Hex.toHexString(selector) + params; + return result; + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException { + TriggerSmartContract.Builder build = TriggerSmartContract.newBuilder(); + TransactionExtention.Builder trxExtBuilder = TransactionExtention.newBuilder(); + Return.Builder retBuilder = Return.newBuilder(); + + try { + String contract = request.getReader().lines() + .collect(Collectors.joining(System.lineSeparator())); + JsonFormat.merge(contract, build); + JSONObject jsonObject = JSONObject.parseObject(contract); + String selector = jsonObject.getString("function_selector"); + String parameter = jsonObject.getString("parameter"); + String data = parseMethod(selector, parameter); + build.setData(ByteString.copyFrom(ByteArray.fromHexString(data))); + + long feeLimit = jsonObject.getLongValue("fee_limit"); + + TransactionCapsule trxCap = wallet + .createTransactionCapsule(build.build(), ContractType.TriggerSmartContract); + + Transaction.Builder txBuilder = trxCap.getInstance().toBuilder(); + Transaction.raw.Builder rawBuilder = trxCap.getInstance().getRawData().toBuilder(); + rawBuilder.setFeeLimit(feeLimit); + txBuilder.setRawData(rawBuilder); + + Transaction trx = wallet + .triggerContract(build.build(), new TransactionCapsule(txBuilder.build()), trxExtBuilder, + retBuilder); + trxExtBuilder.setTransaction(trx); + trxExtBuilder.setTxid(trxCap.getTransactionId().getByteString()); + retBuilder.setResult(true).setCode(response_code.SUCCESS); + } catch (ContractValidateException e) { + retBuilder.setResult(false).setCode(response_code.CONTRACT_VALIDATE_ERROR) + .setMessage(ByteString.copyFromUtf8(e.getMessage())); + } catch (Exception e) { + retBuilder.setResult(false).setCode(response_code.OTHER_ERROR) + .setMessage(ByteString.copyFromUtf8(e.getClass() + " : " + e.getMessage())); + } + trxExtBuilder.setResult(retBuilder); + response.getWriter().println(Util.printTransactionExtention(trxExtBuilder.build())); + } +} \ No newline at end of file diff --git a/src/main/java/org/tron/core/services/http/Util.java b/src/main/java/org/tron/core/services/http/Util.java index 188d7c66675..499e028bd96 100644 --- a/src/main/java/org/tron/core/services/http/Util.java +++ b/src/main/java/org/tron/core/services/http/Util.java @@ -8,7 +8,9 @@ import lombok.extern.slf4j.Slf4j; import org.tron.api.GrpcAPI.BlockList; import org.tron.api.GrpcAPI.EasyTransferResponse; +import org.tron.api.GrpcAPI.TransactionExtention; import org.tron.api.GrpcAPI.TransactionList; +import org.tron.common.crypto.Hash; import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.BlockCapsule; @@ -41,7 +43,7 @@ public class Util { public static String printErrorMsg(Exception e) { JSONObject jsonObject = new JSONObject(); - jsonObject.put("Error", e.getMessage()); + jsonObject.put("Error", e.getClass() + " : " + e.getMessage()); return jsonObject.toJSONString(); } @@ -102,6 +104,27 @@ public static String printTransaction(Transaction transaction) { return printTransactionToJSON(transaction).toJSONString(); } + public static String printTransactionExtention(TransactionExtention transactionExtention) { + String string = JsonFormat.printToString(transactionExtention); + JSONObject jsonObject = JSONObject.parseObject(string); + if (transactionExtention.getResult().getResult()) { + jsonObject.put("transaction", printTransactionToJSON(transactionExtention.getTransaction())); + } + return jsonObject.toJSONString(); + } + + public static byte[] generateContractAddress(Transaction trx, byte[] ownerAddress) { + // get tx hash + byte[] txRawDataHash = Sha256Hash.of(trx.getRawData().toByteArray()).getBytes(); + + // combine + byte[] combined = new byte[txRawDataHash.length + ownerAddress.length]; + System.arraycopy(txRawDataHash, 0, combined, 0, txRawDataHash.length); + System.arraycopy(ownerAddress, 0, combined, txRawDataHash.length, ownerAddress.length); + + return Hash.sha3omit12(combined); + } + public static JSONObject printTransactionToJSON(Transaction transaction) { JSONObject jsonTransaction = JSONObject.parseObject(JsonFormat.printToString(transaction)); JSONArray contracts = new JSONArray(); @@ -190,6 +213,9 @@ public static JSONObject printTransactionToJSON(Transaction transaction) { CreateSmartContract deployContract = contractParameter .unpack(CreateSmartContract.class); contractJson = JSONObject.parseObject(JsonFormat.printToString(deployContract)); + byte[] ownerAddress = deployContract.getOwnerAddress().toByteArray(); + byte[] contractAddress = generateContractAddress(transaction, ownerAddress); + jsonTransaction.put("contract_address", ByteArray.toHexString(contractAddress)); break; case TriggerSmartContract: TriggerSmartContract triggerSmartContract = contractParameter @@ -348,6 +374,14 @@ public static Transaction packTransaction(String strTransaction) { triggerSmartContractBuilder); any = Any.pack(triggerSmartContractBuilder.build()); break; + case "CreateSmartContract": + CreateSmartContract.Builder CreateSmartContractBuilder = CreateSmartContract + .newBuilder(); + JsonFormat + .merge(parameter.getJSONObject("value").toJSONString(), + CreateSmartContractBuilder); + any = Any.pack(CreateSmartContractBuilder.build()); + break; // todo add other contract default: } diff --git a/src/main/java/org/tron/core/witness/ProposalController.java b/src/main/java/org/tron/core/witness/ProposalController.java index b4829944a54..1d4e5a9effd 100644 --- a/src/main/java/org/tron/core/witness/ProposalController.java +++ b/src/main/java/org/tron/core/witness/ProposalController.java @@ -130,6 +130,14 @@ public void setDynamicParameters(ProposalCapsule proposalCapsule) { manager.getDynamicPropertiesStore().saveCreateNewAccountBandwidthRate(entry.getValue()); break; } + case (9): { + manager.getDynamicPropertiesStore().saveAllowCreationOfContracts(entry.getValue()); + break; + } + case (10): { + manager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(entry.getValue()); + break; + } default: break; } diff --git a/src/main/java/org/tron/core/witness/WitnessController.java b/src/main/java/org/tron/core/witness/WitnessController.java index 97aafa39298..697d5442d1d 100644 --- a/src/main/java/org/tron/core/witness/WitnessController.java +++ b/src/main/java/org/tron/core/witness/WitnessController.java @@ -23,6 +23,7 @@ import org.tron.core.capsule.VotesCapsule; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.config.Parameter.ChainConstant; +import org.tron.core.config.args.Args; import org.tron.core.db.AccountStore; import org.tron.core.db.Manager; import org.tron.core.db.VotesStore; @@ -156,6 +157,14 @@ public boolean validateWitnessSchedule(BlockCapsule block) { if (manager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() == 0) { return true; } + long blockAbSlot = getAbSlotAtTime(block.getTimeStamp()); + long headBlockAbSlot = getAbSlotAtTime( + manager.getDynamicPropertiesStore().getLatestBlockHeaderTimestamp()); + if (blockAbSlot <= headBlockAbSlot) { + logger.warn("blockAbSlot is equals with headBlockAbSlot[" + blockAbSlot + "]"); + return false; + } + long slot = getSlotAtTime(block.getTimeStamp()); final ByteString scheduledWitness = getScheduledWitness(slot); if (!scheduledWitness.equals(witnessAddress)) { @@ -297,6 +306,8 @@ public void updateWitness() { VotesStore votesStore = manager.getVotesStore(); AccountStore accountStore = manager.getAccountStore(); + tryRemoveThePowerOfTheGr(); + Map countWitness = countVote(votesStore); //Only possible during the initialization phase @@ -366,6 +377,22 @@ public void updateWitness() { } } + public void tryRemoveThePowerOfTheGr(){ + if(manager.getDynamicPropertiesStore().getRemoveThePowerOfTheGr() == 1){ + + WitnessStore witnessStore = manager.getWitnessStore(); + + Args.getInstance().getGenesisBlock().getWitnesses().forEach(witnessInGenesisBlock -> { + WitnessCapsule witnessCapsule = witnessStore.get(witnessInGenesisBlock.getAddress()); + witnessCapsule.setVoteCount(witnessCapsule.getVoteCount() - witnessInGenesisBlock.getVoteCount()); + + witnessStore.put(witnessCapsule.createDbKey(), witnessCapsule); + }); + + manager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); + } + } + private static boolean witnessSetChanged(List list1, List list2) { return !CollectionUtils.isEqualCollection(list1, list2); } diff --git a/src/main/java/org/tron/program/FullNode.java b/src/main/java/org/tron/program/FullNode.java index 1a664713dff..af3b7b9be8b 100644 --- a/src/main/java/org/tron/program/FullNode.java +++ b/src/main/java/org/tron/program/FullNode.java @@ -2,13 +2,12 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; +import org.tron.common.application.TronApplicationContext; import org.tron.core.Constant; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; -import org.tron.core.db.RevokingDatabase; import org.tron.core.services.RpcApiService; import org.tron.core.services.WitnessService; import org.tron.core.services.http.FullNodeHttpApiService; @@ -29,21 +28,30 @@ public static void main(String[] args) throws InterruptedException { return; } + if (Args.getInstance().isDebug()) { + logger.info("in debug mode, it won't check energy time"); + } else { + logger.info("not in debug mode, it will check energy time"); + } + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); beanFactory.setAllowCircularReferences(false); - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(beanFactory); + TronApplicationContext context = + new TronApplicationContext(beanFactory); context.register(DefaultConfig.class); + context.refresh(); Application appT = ApplicationFactory.create(context); shutdown(appT); - //appT.init(cfgArgs); + // grpc api server RpcApiService rpcApiService = context.getBean(RpcApiService.class); appT.addService(rpcApiService); if (cfgArgs.isWitness()) { appT.addService(new WitnessService(appT, context)); } - //http + + // http api server FullNodeHttpApiService httpApiService = context.getBean(FullNodeHttpApiService.class); appT.addService(httpApiService); diff --git a/src/main/java/org/tron/program/SolidityNode.java b/src/main/java/org/tron/program/SolidityNode.java index 3b3730861f8..c940ac6eff4 100644 --- a/src/main/java/org/tron/program/SolidityNode.java +++ b/src/main/java/org/tron/program/SolidityNode.java @@ -5,10 +5,10 @@ import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.util.StringUtils; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; +import org.tron.common.application.TronApplicationContext; import org.tron.common.overlay.client.DatabaseGrpcClient; import org.tron.common.overlay.discover.DiscoverServer; import org.tron.common.overlay.discover.node.NodeManager; @@ -20,7 +20,6 @@ import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.db.Manager; -import org.tron.core.db2.core.SnapshotManager; import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.BadBlockException; import org.tron.core.exception.BadItemException; @@ -29,10 +28,14 @@ import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.DupTransactionException; import org.tron.core.exception.NonCommonBlockException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.ReceiptException; import org.tron.core.exception.TaposException; import org.tron.core.exception.TooBigTransactionException; import org.tron.core.exception.TransactionExpirationException; +import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.UnLinkedBlockException; +import org.tron.core.exception.UnsupportVMException; import org.tron.core.exception.ValidateScheduleException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.services.RpcApiService; @@ -138,8 +141,16 @@ private void syncSolidityBlock() throws BadBlockException { throw new BadBlockException("expiration exception"); } catch (BadNumberBlockException e) { throw new BadBlockException("bad number exception"); + } catch (ReceiptException e) { + throw new BadBlockException("Receipt exception"); } catch (NonCommonBlockException e) { throw new BadBlockException("non common exception"); + } catch (TransactionTraceException e) { + throw new BadBlockException("TransactionTrace Exception"); + } catch (OutOfSlotTimeException e) { + throw new BadBlockException("OutOfSlotTime Exception"); + } catch (UnsupportVMException e) { + throw new BadBlockException(e.getMessage()); } } else { @@ -176,9 +187,7 @@ public static void main(String[] args) throws InterruptedException { } cfgArgs.setSolidityNode(true); - ApplicationContext context = new AnnotationConfigApplicationContext(DefaultConfig.class); - SnapshotManager snapshotManager = context.getBean(SnapshotManager.class); - snapshotManager.check(); + ApplicationContext context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/main/protos/api/api.proto b/src/main/protos/api/api.proto index c657aa469d0..a84e460b38f 100644 --- a/src/main/protos/api/api.proto +++ b/src/main/protos/api/api.proto @@ -91,6 +91,11 @@ service Wallet { } }; }; + + //modify the consume_user_resource_percent + rpc UpdateSetting (UpdateSettingContract) returns (TransactionExtention) { + }; + //Use this function instead of VoteWitnessAccount. rpc VoteWitnessAccount2 (VoteWitnessContract) returns (TransactionExtention) { }; @@ -250,9 +255,24 @@ service Wallet { rpc BuyStorage (BuyStorageContract) returns (TransactionExtention) { } + rpc BuyStorageBytes (BuyStorageBytesContract) returns (TransactionExtention) { + } + rpc SellStorage (SellStorageContract) returns (TransactionExtention) { } + rpc ExchangeCreate (ExchangeCreateContract) returns (TransactionExtention) { + } + + rpc ExchangeInject (ExchangeInjectContract) returns (TransactionExtention) { + } + + rpc ExchangeWithdraw (ExchangeWithdrawContract) returns (TransactionExtention) { + } + + rpc ExchangeTransaction (ExchangeTransactionContract) returns (TransactionExtention) { + } + rpc ListNodes (EmptyMessage) returns (NodeList) { option (google.api.http) = { post: "/wallet/listnodes" @@ -406,6 +426,26 @@ service Wallet { }; }; + rpc ListExchanges (EmptyMessage) returns (ExchangeList) { + option (google.api.http) = { + post: "/wallet/listexchanges" + body: "*" + additional_bindings { + get: "/wallet/listexchanges" + } + }; + }; + + rpc GetExchangeById (BytesMessage) returns (Exchange) { + option (google.api.http) = { + post: "/wallet/getexchangebyid" + body: "*" + additional_bindings { + get: "/wallet/getexchangebyid" + } + }; + }; + rpc GetChainParameters (EmptyMessage) returns (ChainParameters) { option (google.api.http) = { post: "/wallet/getchainparameters" @@ -711,6 +751,9 @@ message WitnessList { message ProposalList { repeated Proposal proposals = 1; } +message ExchangeList { + repeated Exchange exchanges = 1; +} message AssetIssueList { repeated AssetIssueContract assetIssue = 1; } @@ -788,10 +831,10 @@ message AccountResourceMessage { int64 TotalNetLimit = 7; int64 TotalNetWeight = 8; - int64 CpuUsed = 13; - int64 CpuLimit = 14; - int64 TotalCpuLimit = 15; - int64 TotalCpuWeight = 16; + int64 EnergyUsed = 13; + int64 EnergyLimit = 14; + int64 TotalEnergyLimit = 15; + int64 TotalEnergyWeight = 16; int64 storageUsed = 21; int64 storageLimit = 22; @@ -828,7 +871,8 @@ message AddressPrKeyPairMessage { message TransactionExtention { Transaction transaction = 1; bytes txid = 2; //transaction id = sha256(transaction.rowdata) - Return result = 3; + repeated bytes constant_result = 3; + Return result = 4; } message BlockExtention { diff --git a/src/main/protos/core/Contract.proto b/src/main/protos/core/Contract.proto index 1549273b316..5d5c1421f9a 100644 --- a/src/main/protos/core/Contract.proto +++ b/src/main/protos/core/Contract.proto @@ -72,6 +72,12 @@ message VoteWitnessContract { bool support = 3; } +message UpdateSettingContract { + bytes owner_address = 1; + bytes contract_address = 2; + int64 consume_user_resource_percent = 3; +} + message WitnessCreateContract { bytes owner_address = 1; bytes url = 2; @@ -116,7 +122,7 @@ message ParticipateAssetIssueContract { enum ResourceCode { BANDWIDTH = 0x00; - CPU = 0x01; + ENERGY = 0x01; } message FreezeBalanceContract { @@ -168,23 +174,13 @@ message ProposalDeleteContract { message CreateSmartContract { bytes owner_address = 1; SmartContract new_contract = 2; - int64 cpu_limit_in_trx = 3; - int64 storage_limit_in_trx = 4; - int64 max_cpu_usage = 15; - int64 max_net_usage = 16; - int64 max_storage = 17; } message TriggerSmartContract { bytes owner_address = 1; bytes contract_address = 2; - bytes call_value = 3; + int64 call_value = 3; bytes data = 4; - int64 cpu_limit_in_trx = 5; - int64 storage_limit_in_trx = 6; - int64 max_cpu_usage = 17; - int64 max_net_usage = 18; - int64 max_storage = 19; } message BuyStorageContract { @@ -192,7 +188,41 @@ message BuyStorageContract { int64 quant = 2; // trx quantity for buy storage (sun) } +message BuyStorageBytesContract { + bytes owner_address = 1; + int64 bytes = 2; // storage bytes for buy +} + message SellStorageContract { bytes owner_address = 1; int64 storage_bytes = 2; +} + +message ExchangeCreateContract { + bytes owner_address = 1; + bytes first_token_id = 2; + int64 first_token_balance = 3; + bytes second_token_id = 4; + int64 second_token_balance = 5; +} + +message ExchangeInjectContract { + bytes owner_address = 1; + int64 exchange_id = 2; + bytes token_id = 3; + int64 quant = 4; +} + +message ExchangeWithdrawContract { + bytes owner_address = 1; + int64 exchange_id = 2; + bytes token_id = 3; + int64 quant = 4; +} + +message ExchangeTransactionContract { + bytes owner_address = 1; + int64 exchange_id = 2; + bytes token_id = 3; + int64 quant = 4; } \ No newline at end of file diff --git a/src/main/protos/core/Tron.proto b/src/main/protos/core/Tron.proto index 09c3c7fb758..d568183f911 100644 --- a/src/main/protos/core/Tron.proto +++ b/src/main/protos/core/Tron.proto @@ -47,6 +47,17 @@ message Proposal { State state = 7; } +// Exchange +message Exchange { + int64 exchange_id = 1; + bytes creator_address = 2; + int64 create_time = 3; + bytes first_token_id = 6; + int64 first_token_balance = 7; + bytes second_token_id = 8; + int64 second_token_balance = 9; +} + message ChainParameters { repeated ChainParameter chainParameter = 1; message ChainParameter { @@ -105,11 +116,11 @@ message Account { bytes account_id = 23; message AccountResource { - // cpu resource, get from frozen - int64 cpu_usage = 1; - // the frozen balance for cpu - Frozen frozen_balance_for_cpu = 2; - int64 latest_consume_time_for_cpu = 3; + // energy resource, get from frozen + int64 energy_usage = 1; + // the frozen balance for energy + Frozen frozen_balance_for_energy = 2; + int64 latest_consume_time_for_energy = 3; // storage resource, get from market int64 storage_limit = 6; @@ -172,12 +183,16 @@ message TXOutputs { } message ResourceReceipt { - int64 cpu_usage = 1; - int64 cpu_fee = 2; - int64 net_usage = 3; - int64 net_fee = 4; - int64 storage_delta = 5; - int64 storage_fee = 6; + enum code { + SUCCESS = 0; + FAILED = 1; + } + int64 energy_usage = 1; + int64 energy_fee = 2; + int64 origin_energy_usage = 3; + int64 energy_usage_total = 4; + int64 net_usage = 5; + int64 net_fee = 6; } message Transaction { @@ -203,11 +218,17 @@ message Transaction { ProposalDeleteContract = 18; SetAccountIdContract = 19; CustomContract = 20; - BuyStorageContract = 21; - SellStorageContract = 23; + // BuyStorageContract = 21; + // BuyStorageBytesContract = 22; + // SellStorageContract = 23; CreateSmartContract = 30; TriggerSmartContract = 31; GetContract = 32; + UpdateSettingContract = 33; + ExchangeCreateContract = 41; + ExchangeInjectContract = 42; + ExchangeWithdrawContract = 43; + ExchangeTransactionContract = 44; } ContractType type = 1; google.protobuf.Any parameter = 2; @@ -223,8 +244,9 @@ message Transaction { } int64 fee = 1; code ret = 2; - bytes constant_result = 3; - ResourceReceipt receipt = 4; + + int64 withdraw_amount = 15; + int64 unfreeze_amount = 16; } message raw { @@ -240,9 +262,7 @@ message Transaction { // scripts not used bytes scripts = 12; int64 timestamp = 14; - int64 max_cpu_usage = 15; - int64 max_net_usage = 16; - int64 max_storage = 17; + int64 fee_limit = 18; } raw raw_data = 1; @@ -252,14 +272,28 @@ message Transaction { } message TransactionInfo { + enum code { + SUCESS = 0; + FAILED = 1; + } + message Log { + bytes address = 1; + repeated bytes topics = 2; + bytes data = 3; + } bytes id = 1; int64 fee = 2; int64 blockNumber = 3; int64 blockTimeStamp = 4; repeated bytes contractResult = 5; bytes contract_address = 6; - Transaction.Result result = 7; - repeated bytes log = 8; + ResourceReceipt receipt = 7; + repeated Log log = 8; + code result = 9; + bytes resMessage = 10; + + int64 withdraw_amount = 15; + int64 unfreeze_amount = 16; } message Transactions { @@ -281,6 +315,7 @@ message BlockHeader { int64 number = 7; int64 witness_id = 8; bytes witness_address = 9; + int32 version = 10; } raw raw_data = 1; bytes witness_signature = 2; @@ -390,12 +425,6 @@ message HelloMessage { BlockId headBlockId = 6; } -message StorageItem { - bytes contract_address = 1; - map items = 2; -} - - message SmartContract { message ABI { message Entry { @@ -408,8 +437,8 @@ message SmartContract { } message Param { bool indexed = 1; - bytes name = 2; - bytes type = 3; + string name = 2; + string type = 3; // SolidityType type = 3; } enum StateMutabilityType { @@ -422,23 +451,21 @@ message SmartContract { bool anonymous = 1; bool constant = 2; - bytes name = 3; + string name = 3; repeated Param inputs = 4; repeated Param outputs = 5; EntryType type = 6; bool payable = 7; StateMutabilityType stateMutability = 8; } - repeated Entry entrys = 1; } bytes origin_address = 1; bytes contract_address = 2; ABI abi = 3; bytes bytecode = 4; - bytes call_value = 5; - bytes data = 6; - int64 consume_user_resource_percent = 7; - bytes name = 8; + int64 call_value = 5; + int64 consume_user_resource_percent = 6; + string name = 7; } \ No newline at end of file diff --git a/src/main/resources/config-localtest.conf b/src/main/resources/config-localtest.conf index 95187d9937d..060b8a08199 100644 --- a/src/main/resources/config-localtest.conf +++ b/src/main/resources/config-localtest.conf @@ -5,7 +5,7 @@ net { storage { # Directory for storing persistent data - + db.version = 1, db.directory = "database", index.directory = "index", diff --git a/src/main/resources/config.conf b/src/main/resources/config.conf index a8c6dbe0750..81f9856ad9a 100644 --- a/src/main/resources/config.conf +++ b/src/main/resources/config.conf @@ -90,6 +90,12 @@ node { minParticipationRate = 15 + # check the peer data transfer ,disconnect factor + disconnectNumberFactor = 0.4 + maxConnectNumberFactor = 0.8 + receiveTcpMinDataLength = 2048 + isOpenFullTcpDisconnect = true + p2p { version = 11111 # 11111: mainnet; 20180622: testnet } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 39fa5b16a4b..0e4c7ff47fa 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -20,10 +20,10 @@ - ./logs/tron-%d{yyyy-MM-dd}.%i.log.tar.gz + ./logs/tron-%d{yyyy-MM-dd}.%i.log.gz 500MB - 720 + 30 50GB @@ -88,6 +88,10 @@ + + + + diff --git a/src/test/java/org/tron/common/runtime/InheritanceTest.java b/src/test/java/org/tron/common/runtime/InheritanceTest.java new file mode 100644 index 00000000000..0e256980442 --- /dev/null +++ b/src/test/java/org/tron/common/runtime/InheritanceTest.java @@ -0,0 +1,141 @@ +package org.tron.common.runtime; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.application.TronApplicationContext; +import org.testng.Assert; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Protocol.AccountType; + +@Slf4j +public class InheritanceTest { + private static Runtime runtime; + private static Manager dbManager; + private static TronApplicationContext context; + private static DepositImpl deposit; + private static final String dbPath = "output_InheritanceTest"; + private static final String OWNER_ADDRESS; + + static { + Args.setParam(new String[]{"--output-directory", dbPath,"--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + deposit = DepositImpl.createRoot(dbManager); + deposit.createAccount(Hex.decode(OWNER_ADDRESS),AccountType.Normal); + deposit.addBalance(Hex.decode(OWNER_ADDRESS),100000000); + } + + + + /** + * pragma solidity ^0.4.19; + * + * contract foo { + * uint256 public id=10; + * function getNumber() returns (uint256){return 100;} + * function getName() returns (string){ + * return "foo"; + * } + * } + * + * contract bar is foo { + * function getName() returns (string) { return "bar"; } + * function getId() returns(uint256){return id;} + * } + */ + @Test + public void inheritanceTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "barContract"; + byte[] callerAddress = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":false,\"inputs\":[],\"name\":\"getName\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}]," + + "\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[]," + + "\"name\":\"getId\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\"," + + "\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"id\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}]," + + "\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"getNumber\"," + + "\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + String code = "6080604052600a60005534801561001557600080fd5b506101f9806100256000396000f300608060405260043610610062576000357c01" + + "00000000000000000000000000000000000000000000000000000000900463ffffffff16806317d7de7c146100675780635d1ca631146100f757806" + + "3af640d0f14610122578063f2c9ecd81461014d575b600080fd5b34801561007357600080fd5b5061007c610178565b6040518080602001828103825" + + "283818151815260200191508051906020019080838360005b838110156100bc5780820151818401526020810190506100a1565b505050509050908101" + + "90601f1680156100e95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561010357600080fd" + + "5b5061010c6101b5565b6040518082815260200191505060405180910390f35b34801561012e57600080fd5b506101376101be565b60405180828152602" + + "00191505060405180910390f35b34801561015957600080fd5b506101626101c4565b6040518082815260200191505060405180910390f35b6060604080" + + "5190810160405280600381526020017f6261720000000000000000000000000000000000000000000000000000000000815250905090565b60008054905" + + "090565b60005481565b600060649050905600a165627a7a72305820dfe79cf7f4a8a342b754cad8895b13f85de7daa11803925cf392263397653e7f0029"; + long value = 0; + long fee = 100000000; + long consumeUserResourcePercent = 0; + + byte[] contractAddress = TVMTestUtils.deployContractWholeProcessReturnContractAddress( + contractName,callerAddress,ABI,code,value,fee,consumeUserResourcePercent,null,deposit,null); + + + /* =================================== CALL getName() return child value =================================== */ + byte[] triggerData1 = TVMTestUtils.parseABI("getName()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(callerAddress,contractAddress,triggerData1, + 0,1000000,deposit,null); + + //0x20 => pointer position, 0x3 => size, 626172 => "bar" + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()), + "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "6261720000000000000000000000000000000000000000000000000000000000"); + + /* =================================== CALL getNumber() return parent value=================================== */ + byte[] triggerData2 = TVMTestUtils.parseABI("getNumber()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(callerAddress,contractAddress,triggerData2, + 0,1000000,deposit,null); + + //0x64 =>100 + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()), + "0000000000000000000000000000000000000000000000000000000000000064"); + + /* =================================== CALL getId() call child function return parent field value=================================== */ + byte[] triggerData3 = TVMTestUtils.parseABI("getId()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(callerAddress,contractAddress,triggerData3, + 0,1000000,deposit,null); + + //0x64 =>100 + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()), + "000000000000000000000000000000000000000000000000000000000000000a"); + } + + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + +} diff --git a/src/test/java/org/tron/common/runtime/InternalTransactionComplexTest.java b/src/test/java/org/tron/common/runtime/InternalTransactionComplexTest.java new file mode 100644 index 00000000000..fd18fe664bb --- /dev/null +++ b/src/test/java/org/tron/common/runtime/InternalTransactionComplexTest.java @@ -0,0 +1,178 @@ +package org.tron.common.runtime; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.application.TronApplicationContext; +import org.testng.Assert; +import org.tron.common.runtime.vm.DataWord; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Protocol.AccountType; + +@Slf4j +public class InternalTransactionComplexTest { + + private static Runtime runtime; + private static Manager dbManager; + private static TronApplicationContext context; + private static DepositImpl deposit; + private static final String dbPath = "output_InternalTransactionComplexTest"; + private static final String OWNER_ADDRESS; + + static { + Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + deposit = DepositImpl.createRoot(dbManager); + deposit.createAccount(Hex.decode(OWNER_ADDRESS), AccountType.Normal); + deposit.addBalance(Hex.decode(OWNER_ADDRESS), 100000000); + } + + /** + * pragma solidity 0.4.24; + * + * // this is to test wither the TVM is returning vars from one contract calling another // + * contract's functions. + * + * contract callerContract { // lets set up our instance of the new contract calledContract + * CALLED_INSTANCE; // lets set the contract instance address in the constructor + * constructor(address _addr) public { CALLED_INSTANCE = calledContract(_addr); } // lets create a + * few public vars to store results so we know if we are // getting the callback return struct + * SomeStruct { bool someBool; uint256 someUint; bytes32 someBytes32; } SomeStruct public + * testCallbackReturns_; // create the function call to external contract. store return in vars + * created // above. function makeTheCall() public { // lets call the contract and store returns + * in to temp vars (bool _bool, uint256 _uint, bytes32 _bytes32) = CALLED_INSTANCE.testReturns(); + * // lets write those temp vars to state testCallbackReturns_.someBool = _bool; + * testCallbackReturns_.someUint = _uint; testCallbackReturns_.someBytes32 = _bytes32; } } + * + * contract calledContract { function testReturns() external pure returns(bool, uint256, bytes32) + * { return(true, 314159, 0x123456); } } + */ + @Test + public void internalTransactionAsInstanceTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + byte[] calledContractAddress = deployCalledContractandGetItsAddress(); + byte[] callerContractAddress = deployCallerContractAndGetItsAddress(calledContractAddress); + + /* =================================== CALL makeTheCall =================================== */ + byte[] triggerData1 = TVMTestUtils.parseABI("makeTheCall()", ""); + runtime = TVMTestUtils + .triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS), + callerContractAddress, triggerData1, + 0, 100000000, deposit, null); + + /* =================================== CALL testCallbackReturns_ to check data =================================== */ + byte[] triggerData2 = TVMTestUtils.parseABI("testCallbackReturns_()", ""); + runtime = TVMTestUtils + .triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS), + callerContractAddress, triggerData2, + 0, 100000000, deposit, null); + + // bool true => 0000000000000000000000000000000000000000000000000000000000000001, + // uint256 314159 =>000000000000000000000000000000000000000000000000000000000004cb2f, + // byte32 0x123456 => 0000000000000000000000000000000000000000000000000000000000123456 + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()), + "0000000000000000000000000000000000000000000000000000000000000001" + + "000000000000000000000000000000000000000000000000000000000004cb2f" + + "0000000000000000000000000000000000000000000000000000000000123456"); + + + } + + + // Just for the caller/called example above + private byte[] deployCalledContractandGetItsAddress() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "calledContract"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = + "[{\"constant\":true,\"inputs\":[],\"name\":\"testReturns\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}," + + "{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\"," + + "\"type\":\"function\"}]"; + String code = + "608060405234801561001057600080fd5b5060d58061001f6000396000f300608060405260043610603f576000357c0" + + "100000000000000000000000000000000000000000000000000000000900463ffffffff1680631a483b8c146044575b600080fd5" + + "b348015604f57600080fd5b5060566086565b60405180841515151581526020018381526020018260001916600019168152602001" + + "935050505060405180910390f35b600080600060016204cb2f621234568191508060010290509250925092509091925600a165627a" + + "7a72305820040808e22827b01e497bf99a0ddd72084c95a3fa9bc8737fb022594c7656f00a0029"; + long value = 0; + long feeLimit = 1000000000; + long consumeUserResourcePercent = 0; + + return TVMTestUtils + .deployContractWholeProcessReturnContractAddress(contractName, address, ABI, code, value, + feeLimit, consumeUserResourcePercent, null, + deposit, null); + } + + // Just for the caller/called example above + private byte[] deployCallerContractAndGetItsAddress(byte[] calledContractAddress) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "calledContract"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = + "[{\"constant\":false,\"inputs\":[],\"name\":\"makeTheCall\",\"outputs\":[],\"payable\":false,\"stateMutability\":" + + "\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"testCallbackReturns_\",\"outputs\":" + + "[{\"name\":\"someBool\",\"type\":\"bool\"},{\"name\":\"someUint\",\"type\":\"uint256\"},{\"name\":\"someBytes32\",\"type\":" + + "\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_addr\",\"type\":" + + "\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + String code = + "608060405234801561001057600080fd5b5060405160208061029983398101806040528101908080519060200190929190505050806000806101" + + "000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506102168" + + "06100836000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff" + + "1680633855721a14610051578063dda810ec14610068575b600080fd5b34801561005d57600080fd5b506100666100ad565b005b34801561007457600080fd5" + + "b5061007d6101c5565b60405180841515151581526020018381526020018260001916600019168152602001935050505060405180910390f35b6000806000806" + + "0009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631a483b8c604051816" + + "3ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401606060405180830381600087803b158015610137576000" + + "80fd5b505af115801561014b573d6000803e3d6000fd5b505050506040513d606081101561016157600080fd5b810190808051906020019092919080519060200" + + "1909291908051906020019092919050505092509250925082600160000160006101000a81548160ff0219169083151502179055508160018001819055508060016" + + "002018160001916905550505050565b60018060000160009054906101000a900460ff169080600101549080600201549050835600a165627a7a72305820afe0957a" + + "5188a2329cea5d678a10b01436ab68941b47259fc16ae84985c1abce0029" + Hex + .toHexString(new DataWord(calledContractAddress).getData()); + long value = 0; + long feeLimit = 1000000000; + long consumeUserResourcePercent = 0; + + return TVMTestUtils + .deployContractWholeProcessReturnContractAddress(contractName, address, ABI, code, value, + feeLimit, consumeUserResourcePercent, null, + deposit, null); + } + + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + +} diff --git a/src/test/java/org/tron/common/runtime/RuntimeTransferComplexTest.java b/src/test/java/org/tron/common/runtime/RuntimeTransferComplexTest.java new file mode 100644 index 00000000000..580dc6c7dd2 --- /dev/null +++ b/src/test/java/org/tron/common/runtime/RuntimeTransferComplexTest.java @@ -0,0 +1,179 @@ +package org.tron.common.runtime; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.application.TronApplicationContext; +import org.testng.Assert; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.Transaction; + +@Slf4j +public class RuntimeTransferComplexTest { + private static Runtime runtime; + private static Manager dbManager; + private static TronApplicationContext context; + private static DepositImpl deposit; + private static final String dbPath = "output_RuntimeTransferComplexTest"; + private static final String OWNER_ADDRESS; + private static final String TRANSFER_TO; + + static { + Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + TRANSFER_TO = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + deposit = DepositImpl.createRoot(dbManager); + deposit.createAccount(Hex.decode(OWNER_ADDRESS),AccountType.Normal); + deposit.addBalance(Hex.decode(OWNER_ADDRESS),100000000); + deposit.createAccount(Hex.decode(TRANSFER_TO),AccountType.Normal); + deposit.addBalance(Hex.decode(TRANSFER_TO),10); + } + + + /** + * + * Test constructor Transfer + * pragma solidity ^0.4.16; + * contract transferWhenDeploy { + * constructor () payable{} + * } + */ + @Test + public void TransferTrxToContractAccountWhenDeployAContract() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + + String contractName = "TransferWhenDeployContract"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"inputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"constructor\"}]"; + String code = "608060405260358060116000396000f3006080604052600080fd00a165627a7a72305820d3b0de5bdc00ebe85619d50b72b29d30bd00dd233e8849402671979de0e9e73b0029"; + long value = 100; + long fee = 100000000; + long consumeUserResourcePercent = 0; + + + Transaction trx = TVMTestUtils.generateDeploySmartContractAndGetTransaction( + contractName,address,ABI,code,value,fee,consumeUserResourcePercent,null); + byte[] contractAddress = Wallet.generateContractAddress(trx); + runtime = TVMTestUtils.processTransactionAndReturnRuntime(trx, deposit, null); + Assert.assertNull(runtime.getRuntimeError()); + Assert.assertEquals(dbManager.getAccountStore().get(contractAddress).getBalance(),100); + } + + /** + * + * Test constructor Transfer + * pragma solidity ^0.4.16; + * contract transferWhenDeploy { + * constructor () {} + * } + */ + + @Test + public void TransferTrxToContractAccountFailIfNotPayable() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + + String contractName = "TransferWhenDeployContract"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + String code = "6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820f5dc348e1c7dc90f9996a05c69dc9d060b6d356a1ed570ce3cd89570dc4ce6440029"; + long value = 100; + long fee = 100000000; + long consumeUserResourcePercent = 0; + + + Transaction trx = TVMTestUtils.generateDeploySmartContractAndGetTransaction( + contractName,address,ABI,code,value,fee,consumeUserResourcePercent,null); + byte[] contractAddress = Wallet.generateContractAddress(trx); + runtime = TVMTestUtils.processTransactionAndReturnRuntime(trx, deposit, null); + Assert.assertNotNull(runtime.getRuntimeError().contains("REVERT")); + Assert.assertNull(dbManager.getAccountStore().get(contractAddress)); + } + + + /** + * pragma solidity ^0.4.16; + * contract transferWhenTriggerContract { + * constructor () {} + * function transferTo(address toAddress) public payable{ + * toAddress.transfer(5); + * } + * } + */ + @Test + public void TransferTrxToContractAccountWhenTriggerAContract() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + + String contractName = "TransferWhenDeployContract"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"toAddress\",\"type\":\"address\"}]," + + "\"name\":\"transferTo\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"}," + + "{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + String code = "608060405234801561001057600080fd5b5060ee8061001f6000396000f300608060405260043610603f576000357c01" + + "00000000000000000000000000000000000000000000000000000000900463ffffffff168063a03fa7e3146044575b600080fd5b607" + + "6600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506078565b005b8073" + + "ffffffffffffffffffffffffffffffffffffffff166108fc60059081150290604051600060405180830381858888f1935050505015801560be573d" + + "6000803e3d6000fd5b50505600a165627a7a723058209b248b5be19bae77660cdc92b0a141f279dc4746d858d9d7d270a22d014eb97a0029"; + long value = 0; + long feeLimit = 100000000; + long consumeUserResourcePercent = 0; + + byte[] contractAddress = TVMTestUtils.deployContractWholeProcessReturnContractAddress(contractName,address,ABI,code,value,feeLimit,consumeUserResourcePercent,null, + deposit,null); + + + + String selectorStr = "transferTo(address)"; + String params = "000000000000000000000000548794500882809695a8a687866e76d4271a1abc"; //TRANSFER_TO + byte[] triggerData = TVMTestUtils.parseABI(selectorStr,params); + + long triggerCallValue =100; + + Transaction transaction = TVMTestUtils.generateTriggerSmartContractAndGetTransaction(address,contractAddress,triggerData,triggerCallValue,feeLimit); + runtime = TVMTestUtils.processTransactionAndReturnRuntime(transaction, deposit, null); + Assert.assertNull(runtime.getRuntimeError()); + Assert.assertEquals(dbManager.getAccountStore().get(contractAddress).getBalance(),100 - 5); + Assert.assertEquals(dbManager.getAccountStore().get(Hex.decode(TRANSFER_TO)).getBalance(),10 + 5); + } + + + + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + +} diff --git a/src/test/java/org/tron/common/runtime/TVMTestResult.java b/src/test/java/org/tron/common/runtime/TVMTestResult.java new file mode 100644 index 00000000000..7b34114ce6e --- /dev/null +++ b/src/test/java/org/tron/common/runtime/TVMTestResult.java @@ -0,0 +1,46 @@ +package org.tron.common.runtime; + +import lombok.extern.slf4j.Slf4j; +import org.tron.core.capsule.ReceiptCapsule; + +@Slf4j +public class TVMTestResult { + + private Runtime runtime; + private ReceiptCapsule receipt; + private byte[] contractAddress; + + public byte[] getContractAddress() { + return contractAddress; + } + + public TVMTestResult setContractAddress(byte[] contractAddress) { + this.contractAddress = contractAddress; + return this; + } + + public Runtime getRuntime() { + return runtime; + } + + public TVMTestResult setRuntime(Runtime runtime) { + this.runtime = runtime; + return this; + } + + public ReceiptCapsule getReceipt() { + return receipt; + } + + public TVMTestResult setReceipt(ReceiptCapsule receipt) { + this.receipt = receipt; + return this; + } + + public TVMTestResult(Runtime runtime, ReceiptCapsule receipt, byte[] contractAddress) { + this.runtime = runtime; + this.receipt = receipt; + this.contractAddress = contractAddress; + } + +} diff --git a/src/test/java/org/tron/common/runtime/TVMTestUtils.java b/src/test/java/org/tron/common/runtime/TVMTestUtils.java new file mode 100644 index 00000000000..42acf9ee2fd --- /dev/null +++ b/src/test/java/org/tron/common/runtime/TVMTestUtils.java @@ -0,0 +1,394 @@ +package org.tron.common.runtime; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.protobuf.ByteString; +import java.io.UnsupportedEncodingException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import lombok.extern.slf4j.Slf4j; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.crypto.Hash; +import org.tron.common.runtime.vm.program.invoke.ProgramInvokeFactoryImpl; +import org.tron.common.storage.DepositImpl; +import org.tron.core.Wallet; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.db.TransactionTrace; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Contract; +import org.tron.protos.Contract.CreateSmartContract; +import org.tron.protos.Contract.TriggerSmartContract; +import org.tron.protos.Protocol.Block; +import org.tron.protos.Protocol.SmartContract; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; +import stest.tron.wallet.common.client.WalletClient; + + +/** + * Below functions mock the process to deploy, trigger a contract. Not consider of the transaction process on real chain(such as db revoke...). + * Just use them to execute runtime actions and vm commands. + */ +@Slf4j +public class TVMTestUtils { + + public static byte[] deployContractWholeProcessReturnContractAddress(String contractName, + byte[] callerAddress, + String ABI, String code, long value, long feeLimit, long consumeUserResourcePercent, + String libraryAddressPair,DepositImpl deposit, Block block) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + Transaction trx = generateDeploySmartContractAndGetTransaction(contractName,callerAddress,ABI,code,value,feeLimit,consumeUserResourcePercent,libraryAddressPair); + processTransactionAndReturnRuntime(trx,deposit,block); + return Wallet.generateContractAddress(trx); + } + + public static Runtime triggerContractWholeProcessReturnContractAddress(byte[] callerAddress, + byte[] contractAddress, byte[] data, long callValue, long feeLimit,DepositImpl deposit, Block block) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + Transaction trx = generateTriggerSmartContractAndGetTransaction(callerAddress,contractAddress,data,callValue,feeLimit); + return processTransactionAndReturnRuntime(trx, deposit, block); + } + + /** + * return generated smart contract Transaction, just before we use it to broadcast and push transaction + * @param contractName + * @param callerAddress + * @param ABI + * @param code + * @param value + * @param feeLimit + * @param consumeUserResourcePercent + * @param libraryAddressPair + * @return + */ + public static Transaction generateDeploySmartContractAndGetTransaction(String contractName, + byte[] callerAddress, + String ABI, String code, long value, long feeLimit, long consumeUserResourcePercent, + String libraryAddressPair) { + + CreateSmartContract contract = buildCreateSmartContract(contractName,callerAddress,ABI,code,value,consumeUserResourcePercent,libraryAddressPair); + TransactionCapsule trxCapWithoutFeeLimit = new TransactionCapsule(contract,ContractType.CreateSmartContract); + Transaction.Builder transactionBuilder = trxCapWithoutFeeLimit.getInstance().toBuilder(); + Transaction.raw.Builder rawBuilder = trxCapWithoutFeeLimit.getInstance().getRawData().toBuilder(); + rawBuilder.setFeeLimit(feeLimit); + transactionBuilder.setRawData(rawBuilder); + Transaction trx = transactionBuilder.build(); + return trx; + } + + /** + * use given input Transaction,deposit,block and execute TVM (for both Deploy and Trigger contracts) + * @param trx + * @param deposit + * @param block + * @return + * @throws TransactionTraceException + * @throws ContractExeException + * @throws ContractValidateException + * @throws OutOfSlotTimeException + */ + + public static Runtime processTransactionAndReturnRuntime(Transaction trx, + DepositImpl deposit, Block block) + throws TransactionTraceException, ContractExeException, ContractValidateException, OutOfSlotTimeException { + TransactionCapsule trxCap = new TransactionCapsule(trx); + TransactionTrace trace = new TransactionTrace(trxCap, deposit.getDbManager()); + Runtime runtime = new Runtime(trace, block,deposit, + new ProgramInvokeFactoryImpl()); + + // init + trace.init(); + //exec + trace.exec(runtime); + + return runtime; + } + + + public static TVMTestResult deployContractAndReturnTVMTestResult(String contractName, + byte[] callerAddress, + String ABI, String code, long value, long feeLimit, long consumeUserResourcePercent, + String libraryAddressPair, DepositImpl deposit, Block block) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + Transaction trx = generateDeploySmartContractAndGetTransaction(contractName, callerAddress, ABI, + code, value, feeLimit, consumeUserResourcePercent, libraryAddressPair); + + byte[] contractAddress = Wallet.generateContractAddress(trx); + + return processTransactionAndReturnTVMTestResult(trx, deposit, block) + .setContractAddress(Wallet.generateContractAddress(trx)); + } + + public static TVMTestResult triggerContractAndReturnTVMTestResult(byte[] callerAddress, + byte[] contractAddress, byte[] data, long callValue, long feeLimit, DepositImpl deposit, + Block block) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + Transaction trx = generateTriggerSmartContractAndGetTransaction(callerAddress, contractAddress, + data, callValue, feeLimit); + return processTransactionAndReturnTVMTestResult(trx, deposit, block) + .setContractAddress(contractAddress); + } + + + public static TVMTestResult processTransactionAndReturnTVMTestResult(Transaction trx, + DepositImpl deposit, Block block) + throws TransactionTraceException, ContractExeException, ContractValidateException, OutOfSlotTimeException { + TransactionCapsule trxCap = new TransactionCapsule(trx); + TransactionTrace trace = new TransactionTrace(trxCap, deposit.getDbManager()); + Runtime runtime = new Runtime(trace, block, deposit, + new ProgramInvokeFactoryImpl()); + + // init + trace.init(); + //exec + trace.exec(runtime); + + trace.pay(); + + return new TVMTestResult(runtime, trace.getReceipt(), null); + } + + + + /** + * create the Contract Instance for smart contract. + * + * @param contractName + * @param address + * @param ABI + * @param code + * @param value + * @param consumeUserResourcePercent + * @param libraryAddressPair + * @return + */ + public static CreateSmartContract buildCreateSmartContract(String contractName, + byte[] address, + String ABI, String code, long value, long consumeUserResourcePercent, + String libraryAddressPair){ + SmartContract.ABI abi = jsonStr2ABI(ABI); + if (abi == null) { + logger.error("abi is null"); + return null; + } + + SmartContract.Builder builder = SmartContract.newBuilder(); + builder.setName(contractName); + builder.setOriginAddress(ByteString.copyFrom(address)); + builder.setAbi(abi); + builder.setConsumeUserResourcePercent(consumeUserResourcePercent); + + if (value != 0) { + builder.setCallValue(value); + } + byte[] byteCode; + if (null != libraryAddressPair) { + byteCode = replaceLibraryAddress(code, libraryAddressPair); + } else { + byteCode = Hex.decode(code); + } + + builder.setBytecode(ByteString.copyFrom(byteCode)); + return CreateSmartContract.newBuilder().setOwnerAddress(ByteString.copyFrom(address)). + setNewContract(builder.build()).build(); + } + + + + + public static Transaction generateTriggerSmartContractAndGetTransaction( + byte[] callerAddress, byte[] contractAddress, byte[] data,long callValue, long feeLimit) { + + TriggerSmartContract contract = buildTriggerSmartContract(callerAddress,contractAddress,data,callValue); + TransactionCapsule trxCapWithoutFeeLimit = new TransactionCapsule(contract,ContractType.TriggerSmartContract); + Transaction.Builder transactionBuilder = trxCapWithoutFeeLimit.getInstance().toBuilder(); + Transaction.raw.Builder rawBuilder = trxCapWithoutFeeLimit.getInstance().getRawData().toBuilder(); + rawBuilder.setFeeLimit(feeLimit); + transactionBuilder.setRawData(rawBuilder); + Transaction trx = transactionBuilder.build(); + return trx; + } + + + public static TriggerSmartContract buildTriggerSmartContract(byte[] address,byte[] contractAddress, byte[] data, long callValue){ + Contract.TriggerSmartContract.Builder builder = Contract.TriggerSmartContract.newBuilder(); + builder.setOwnerAddress(ByteString.copyFrom(address)); + builder.setContractAddress(ByteString.copyFrom(contractAddress)); + builder.setData(ByteString.copyFrom(data)); + builder.setCallValue(callValue); + return builder.build(); + } + + private static byte[] replaceLibraryAddress(String code, String libraryAddressPair) { + + String[] libraryAddressList = libraryAddressPair.split("[,]"); + + for (int i = 0; i < libraryAddressList.length; i++) { + String cur = libraryAddressList[i]; + + int lastPosition = cur.lastIndexOf(":"); + if (-1 == lastPosition) { + throw new RuntimeException("libraryAddress delimit by ':'"); + } + String libraryName = cur.substring(0, lastPosition); + String addr = cur.substring(lastPosition + 1); + String libraryAddressHex; + try { + libraryAddressHex = (new String(Hex.encode(WalletClient.decodeFromBase58Check(addr)), + "US-ASCII")).substring(2); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // now ignore + } + String repeated = new String(new char[40 - libraryName.length() - 2]).replace("\0", "_"); + String beReplaced = "__" + libraryName + repeated; + Matcher m = Pattern.compile(beReplaced).matcher(code); + code = m.replaceAll(libraryAddressHex); + } + + return Hex.decode(code); + } + + private static SmartContract.ABI.Entry.EntryType getEntryType(String type) { + switch (type) { + case "constructor": + return SmartContract.ABI.Entry.EntryType.Constructor; + case "function": + return SmartContract.ABI.Entry.EntryType.Function; + case "event": + return SmartContract.ABI.Entry.EntryType.Event; + case "fallback": + return SmartContract.ABI.Entry.EntryType.Fallback; + default: + return SmartContract.ABI.Entry.EntryType.UNRECOGNIZED; + } + } + + private static SmartContract.ABI.Entry.StateMutabilityType getStateMutability( + String stateMutability) { + switch (stateMutability) { + case "pure": + return SmartContract.ABI.Entry.StateMutabilityType.Pure; + case "view": + return SmartContract.ABI.Entry.StateMutabilityType.View; + case "nonpayable": + return SmartContract.ABI.Entry.StateMutabilityType.Nonpayable; + case "payable": + return SmartContract.ABI.Entry.StateMutabilityType.Payable; + default: + return SmartContract.ABI.Entry.StateMutabilityType.UNRECOGNIZED; + } + } + + private static SmartContract.ABI jsonStr2ABI(String jsonStr) { + if (jsonStr == null) { + return null; + } + + JsonParser jsonParser = new JsonParser(); + JsonElement jsonElementRoot = jsonParser.parse(jsonStr); + JsonArray jsonRoot = jsonElementRoot.getAsJsonArray(); + SmartContract.ABI.Builder abiBuilder = SmartContract.ABI.newBuilder(); + for (int index = 0; index < jsonRoot.size(); index++) { + JsonElement abiItem = jsonRoot.get(index); + boolean anonymous = abiItem.getAsJsonObject().get("anonymous") != null && + abiItem.getAsJsonObject().get("anonymous").getAsBoolean(); + boolean constant = abiItem.getAsJsonObject().get("constant") != null && + abiItem.getAsJsonObject().get("constant").getAsBoolean(); + String name = abiItem.getAsJsonObject().get("name") != null ? + abiItem.getAsJsonObject().get("name").getAsString() : null; + JsonArray inputs = abiItem.getAsJsonObject().get("inputs") != null ? + abiItem.getAsJsonObject().get("inputs").getAsJsonArray() : null; + JsonArray outputs = abiItem.getAsJsonObject().get("outputs") != null ? + abiItem.getAsJsonObject().get("outputs").getAsJsonArray() : null; + String type = abiItem.getAsJsonObject().get("type") != null ? + abiItem.getAsJsonObject().get("type").getAsString() : null; + boolean payable = abiItem.getAsJsonObject().get("payable") != null && + abiItem.getAsJsonObject().get("payable").getAsBoolean(); + String stateMutability = abiItem.getAsJsonObject().get("stateMutability") != null ? + abiItem.getAsJsonObject().get("stateMutability").getAsString() : null; + if (type == null) { + logger.error("No type!"); + return null; + } + if (!type.equalsIgnoreCase("fallback") && null == inputs) { + logger.error("No inputs!"); + return null; + } + + SmartContract.ABI.Entry.Builder entryBuilder = SmartContract.ABI.Entry.newBuilder(); + entryBuilder.setAnonymous(anonymous); + entryBuilder.setConstant(constant); + if (name != null) { + entryBuilder.setName(name); + } + + /* { inputs : optional } since fallback function not requires inputs*/ + if (null != inputs) { + for (int j = 0; j < inputs.size(); j++) { + JsonElement inputItem = inputs.get(j); + if (inputItem.getAsJsonObject().get("name") == null || + inputItem.getAsJsonObject().get("type") == null) { + logger.error("Input argument invalid due to no name or no type!"); + return null; + } + String inputName = inputItem.getAsJsonObject().get("name").getAsString(); + String inputType = inputItem.getAsJsonObject().get("type").getAsString(); + SmartContract.ABI.Entry.Param.Builder paramBuilder = SmartContract.ABI.Entry.Param + .newBuilder(); + paramBuilder.setIndexed(false); + paramBuilder.setName(inputName); + paramBuilder.setType(inputType); + entryBuilder.addInputs(paramBuilder.build()); + } + } + + /* { outputs : optional } */ + if (outputs != null) { + for (int k = 0; k < outputs.size(); k++) { + JsonElement outputItem = outputs.get(k); + if (outputItem.getAsJsonObject().get("name") == null || + outputItem.getAsJsonObject().get("type") == null) { + logger.error("Output argument invalid due to no name or no type!"); + return null; + } + String outputName = outputItem.getAsJsonObject().get("name").getAsString(); + String outputType = outputItem.getAsJsonObject().get("type").getAsString(); + SmartContract.ABI.Entry.Param.Builder paramBuilder = SmartContract.ABI.Entry.Param + .newBuilder(); + paramBuilder.setIndexed(false); + paramBuilder.setName(outputName); + paramBuilder.setType(outputType); + entryBuilder.addOutputs(paramBuilder.build()); + } + } + + entryBuilder.setType(getEntryType(type)); + entryBuilder.setPayable(payable); + if (stateMutability != null) { + entryBuilder.setStateMutability(getStateMutability(stateMutability)); + } + + abiBuilder.addEntrys(entryBuilder.build()); + } + + return abiBuilder.build(); + } + + + + + public static byte[] parseABI(String selectorStr, String params){ + if(params == null){ + params = ""; + } + byte[] selector = new byte[4]; + System.arraycopy(Hash.sha3(selectorStr.getBytes()), 0, selector,0, 4); + byte[] triggerData = Hex.decode(Hex.toHexString(selector) + params); + return triggerData; + } + +} diff --git a/src/test/java/org/tron/common/runtime/vm/CPUEnergyTest.java b/src/test/java/org/tron/common/runtime/vm/CPUEnergyTest.java new file mode 100644 index 00000000000..ed69a47ba8a --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/CPUEnergyTest.java @@ -0,0 +1,244 @@ +package org.tron.common.runtime.vm; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.application.TronApplicationContext; +import org.testng.Assert; +import org.tron.common.runtime.TVMTestResult; +import org.tron.common.runtime.TVMTestUtils; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Protocol.AccountType; + +@Slf4j +public class CPUEnergyTest { + + private Manager dbManager; + private TronApplicationContext context; + private DepositImpl deposit; + private String dbPath = "output_CPUEnergyTest"; + private String OWNER_ADDRESS; + + + /** + * Init data. + */ + @Before + public void init() { + Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + dbManager = context.getBean(Manager.class); + deposit = DepositImpl.createRoot(dbManager); + deposit.createAccount(Hex.decode(OWNER_ADDRESS), AccountType.Normal); + deposit.addBalance(Hex.decode(OWNER_ADDRESS), 30000000000000L); + } + + // solidity for callValueTest + // pragma solidity ^0.4.0; + // + // contract SubContract { + // + // constructor () payable {} + // mapping(uint256=>uint256) map; + // + // function doSimple() public payable returns (uint ret) { + // return 42; + // } + // + // function doComplex() public payable returns (uint ret) { + // for (uint i = 0; i < 10; i++) { + // map[i] = i; + // } + // } + // + // } + // + // contract TestForValueGasFunction { + // + // SubContract subContract; + // + // constructor () payable { + // subContract = new SubContract(); + // } + // + // function simpleCall() public { subContract.doSimple.value(10).gas(3)(); } + // + // function complexCall() public { subContract.doComplex.value(10).gas(3)(); } + // + // } + + @Test + @Ignore + public void callValueTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + + long value = 10000000L; + long feeLimit = 20000000000000L; // sun + long consumeUserResourcePercent = 100; + TVMTestResult result = deployCallValueTestContract(value, feeLimit, + consumeUserResourcePercent); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 52439); + byte[] contractAddress = result.getContractAddress(); + + /* =================================== CALL simpleCall() =================================== */ + byte[] triggerData = TVMTestUtils.parseABI("simpleCall()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 7370); + + /* =================================== CALL complexCall() =================================== */ + triggerData = TVMTestUtils.parseABI("complexCall()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 9459); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), true); + } + + // solidity for sendTest and transferTest + // pragma solidity ^0.4.0; + // + // contract SubContract { + // + // constructor () payable {} + // mapping(uint256=>uint256) map; + // + // function () payable { + // map[1] = 1; + // } + // } + // + // contract TestForSendAndTransfer { + // + // SubContract subContract; + // + // constructor () payable { + // subContract = new SubContract(); + // } + // + // + // function doSend() public { address(subContract).send(10 ether); } + // + // function doTransfer() public { address(subContract).transfer(10 ether); } + // + // function getBalance() public view returns(uint256 balance){ + // balance = address(this).balance; + // } + // + // } + + + + @Test + public void sendTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + + long value = 10000000L; + long feeLimit = 20000000000000L; // sun + long consumeUserResourcePercent = 100; + TVMTestResult result = deploySendAndTransferTestContract(value, feeLimit, + consumeUserResourcePercent); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 52400); + byte[] contractAddress = result.getContractAddress(); + Assert.assertEquals(deposit.getAccount(contractAddress).getBalance(), 10000000L); + + /* =================================== CALL doSend() =================================== */ + byte[] triggerData = TVMTestUtils.parseABI("doSend()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 9325); + Assert.assertEquals(result.getRuntime().getResult().getException(), null); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertEquals(deposit.getAccount(contractAddress).getBalance(), 10000000L); + } + + @Test + public void transferTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + + long value = 10000000L; + long feeLimit = 20000000000000L; // sun + long consumeUserResourcePercent = 100; + TVMTestResult result = deploySendAndTransferTestContract(value, feeLimit, + consumeUserResourcePercent); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 52400); + byte[] contractAddress = result.getContractAddress(); + Assert.assertEquals(deposit.getAccount(contractAddress).getBalance(), 10000000L); + + /* =================================== CALL doSend() =================================== */ + byte[] triggerData = TVMTestUtils.parseABI("doTransfer()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 9330); + Assert.assertEquals(result.getRuntime().getResult().getException(), null); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), true); + Assert.assertEquals(deposit.getAccount(contractAddress).getBalance(), 10000000L); + } + + public TVMTestResult deployCallValueTestContract(long value, long feeLimit, + long consumeUserResourcePercent) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "TestForCallValue"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":false,\"inputs\":[],\"name\":\"complexCall\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"simpleCall\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"constructor\"}]"; + String code = "608060405261000c61004e565b604051809103906000f080158015610028573d6000803e3d6000fd5b5060008054600160a060020a031916600160a060020a039290921691909117905561005d565b60405160d68061020b83390190565b61019f8061006c6000396000f3006080604052600436106100325763ffffffff60e060020a60003504166306ce93af811461003757806340de221c1461004e575b600080fd5b34801561004357600080fd5b5061004c610063565b005b34801561005a57600080fd5b5061004c610103565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cd95478c600a6003906040518363ffffffff1660e060020a0281526004016020604051808303818589803b1580156100d357600080fd5b5088f11580156100e7573d6000803e3d6000fd5b5050505050506040513d60208110156100ff57600080fd5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b993e5e2600a6003906040518363ffffffff1660e060020a0281526004016020604051808303818589803b1580156100d357600080fd00a165627a7a72305820cb5f172ca9f81235a8b33ee1ddef9dd1b398644cf61228569356ff051bfaf3d10029608060405260c4806100126000396000f30060806040526004361060485763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663b993e5e28114604d578063cd95478c146065575b600080fd5b6053606b565b60408051918252519081900360200190f35b60536070565b602a90565b6000805b600a81101560945760008181526020819052604090208190556001016074565b50905600a165627a7a723058205ded543feb546472be4e116e713a2d46b8dafc823ca31256e67a1be92a6752730029"; + String libraryAddressPair = null; + + return TVMTestUtils + .deployContractAndReturnTVMTestResult(contractName, address, ABI, code, + value, + feeLimit, consumeUserResourcePercent, libraryAddressPair, + deposit, null); + } + + public TVMTestResult deploySendAndTransferTestContract(long value, long feeLimit, + long consumeUserResourcePercent) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "TestForSendAndTransfer"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"getBalance\",\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"doTransfer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"doSend\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"constructor\"}]"; + String code = "608060405261000c61004e565b604051809103906000f080158015610028573d6000803e3d6000fd5b5060008054600160a060020a031916600160a060020a039290921691909117905561005d565b604051606f806101d183390190565b6101658061006c6000396000f3006080604052600436106100565763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166312065fe0811461005b57806333182e8f14610082578063e3d237f914610099575b600080fd5b34801561006757600080fd5b506100706100ae565b60408051918252519081900360200190f35b34801561008e57600080fd5b506100976100b3565b005b3480156100a557600080fd5b506100976100ff565b303190565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169190678ac7230489e800009082818181858883f193505050501580156100fc573d6000803e3d6000fd5b50565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169190678ac7230489e800009082818181858883f150505050505600a165627a7a723058201c038c3f247a923f3cb38ac9d3e0f2804c483ae86e67e3578d8839b39a71d2f900296080604052605e8060116000396000f3006080604052600160008181526020527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d550000a165627a7a723058206850a348611e816bc7d1acd245e900cdde8ce98252ccc01d424d78bfd12eb6ed0029"; + String libraryAddressPair = null; + + return TVMTestUtils + .deployContractAndReturnTVMTestResult(contractName, address, ABI, code, + value, + feeLimit, consumeUserResourcePercent, libraryAddressPair, + deposit, null); + } + + /** + * Release resources. + */ + @After + public void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } +} diff --git a/src/test/java/org/tron/common/runtime/vm/CPUEnergyWhenAssertStyleTest.java b/src/test/java/org/tron/common/runtime/vm/CPUEnergyWhenAssertStyleTest.java new file mode 100644 index 00000000000..71de78262f9 --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/CPUEnergyWhenAssertStyleTest.java @@ -0,0 +1,225 @@ +package org.tron.common.runtime.vm; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.testng.Assert; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.runtime.TVMTestResult; +import org.tron.common.runtime.TVMTestUtils; +import org.tron.common.runtime.vm.program.Program.IllegalOperationException; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Protocol.AccountType; + + +@Slf4j +@Ignore +public class CPUEnergyWhenAssertStyleTest { + + private Manager dbManager; + private AnnotationConfigApplicationContext context; + private DepositImpl deposit; + private String dbPath = "output_CPUEnergyWhenAssertStyleTest"; + private String OWNER_ADDRESS; + + + /** + * Init data. + */ + @Before + public void init() { + Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + // context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + dbManager = context.getBean(Manager.class); + deposit = DepositImpl.createRoot(dbManager); + deposit.createAccount(Hex.decode(OWNER_ADDRESS), AccountType.Normal); + deposit.addBalance(Hex.decode(OWNER_ADDRESS), 30000000000000L); + } + + // solidity for CPUEnergyWhenAssertStyleTest + // pragma solidity ^0.4.0; + // + // An assert-style exception is generated in the following situations: + // + // If you access an array at a too large or negative index (i.e. x[i] where i >= x.length or i < 0). + // If you access a fixed-length bytesN at a too large or negative index. + // If you divide or modulo by zero (e.g. 5 / 0 or 23 % 0). + // If you shift by a negative amount. + // If you convert a value too big or negative into an enum type. + // If you call a zero-initialized variable of internal function type. + // If you call assert with an argument that evaluates to false. + + // contract TestAssertStyleContract{ + // + // enum fortest {one, second, third} + // + // function testOutOfIndex() public { + // uint256[] memory a = new uint256[](10); + // a[10] = 10; + // } + // + // function testbytesN() public { + // bytes16 a = 0x12345; + // uint c = 20; + // uint b = uint256(a[c]); + // } + // + // function testDivZero() public { + // uint256 a = 0; + // uint256 b = 10 / a; + // } + // + // function testShiftByNegative() public { + // int256 shift = -10; + // int256 a = 1024 >> shift; + // } + // + // function testEnumType() public { + // fortest a = fortest(10); + // + // } + // + // function testFunctionPointer() public { + // function (int) internal pure returns (int) funcPtr; + // funcPtr(1); + // } + // + // function testAssert(){ + // assert(1==2); + // } + // + // } + + @Test + public void whenAssertStyleTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + + long value = 0; + long feeLimit = 20000000000000L; // sun + long consumeUserResourcePercent = 100; + TVMTestResult result = deployWhenAssertStyleTestContract(value, feeLimit, + consumeUserResourcePercent); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 135); + byte[] contractAddress = result.getContractAddress(); + + /* =================================== CALL testOutOfIndex() =================================== */ + byte[] triggerData = TVMTestUtils.parseABI("testOutOfIndex()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testbytesN() =================================== */ + triggerData = TVMTestUtils.parseABI("testbytesN()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testDivZero() =================================== */ + triggerData = TVMTestUtils.parseABI("testDivZero()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testShiftByNegative() =================================== */ + triggerData = TVMTestUtils.parseABI("testShiftByNegative()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testEnumType() =================================== */ + triggerData = TVMTestUtils.parseABI("testEnumType()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testFunctionPointer() =================================== */ + triggerData = TVMTestUtils.parseABI("testFunctionPointer()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testAssert() =================================== */ + triggerData = TVMTestUtils.parseABI("testAssert()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + } + + public TVMTestResult deployWhenAssertStyleTestContract(long value, long feeLimit, + long consumeUserResourcePercent) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "test"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":false,\"inputs\":[],\"name\":\"testbytesN\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testAssert\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testEnumType\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testOutOfIndex\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testDivZero\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testShiftByNegative\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testFunctionPointer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + String code = "608060405234801561001057600080fd5b506101d7806100206000396000f3006080604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631e76e10781146100875780632b813bc01461009e5780635a43cddc146100b35780639a4e1fa0146100c8578063b87d948d146100dd578063e88e362a146100f2578063e9ad8ee714610107575b600080fd5b34801561009357600080fd5b5061009c61011c565b005b3480156100aa57600080fd5b5061009c610138565b3480156100bf57600080fd5b5061009c61013a565b3480156100d457600080fd5b5061009c610140565b3480156100e957600080fd5b5061009c610183565b3480156100fe57600080fd5b5061009c61018b565b34801561011357600080fd5b5061009c610196565b7201234500000000000000000000000000000000601460008282fe5bfe5b6000600afe5b60408051600a80825261016082019092526060916020820161014080388339019050509050600a81600a81518110151561017657fe5b6020908102909101015250565b60008080600afe5b600919600081610400fe5b6101386101a760018263ffffffff16565b50505600a165627a7a72305820155b43453889c7c579af81c62359ac291bb44abe0ab5c6772971f69745a4cfc20029"; + String libraryAddressPair = null; + + return TVMTestUtils + .deployContractAndReturnTVMTestResult(contractName, address, ABI, code, + value, + feeLimit, consumeUserResourcePercent, libraryAddressPair, + deposit, null); + } + + /** + * Release resources. + */ + @After + public void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } +} + diff --git a/src/test/java/org/tron/common/runtime/vm/CPUEnergyWhenRevertStyleTest.java b/src/test/java/org/tron/common/runtime/vm/CPUEnergyWhenRevertStyleTest.java new file mode 100644 index 00000000000..0db91cc83ad --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/CPUEnergyWhenRevertStyleTest.java @@ -0,0 +1,224 @@ +package org.tron.common.runtime.vm; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.testng.Assert; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.runtime.TVMTestResult; +import org.tron.common.runtime.TVMTestUtils; +import org.tron.common.runtime.vm.program.Program.IllegalOperationException; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Protocol.AccountType; + +@Slf4j +@Ignore +public class CPUEnergyWhenRevertStyleTest { + + private Manager dbManager; + private AnnotationConfigApplicationContext context; + private DepositImpl deposit; + private String dbPath = "output_CPUEnergyWhenAssertStyleTest"; + private String OWNER_ADDRESS; + + + /** + * Init data. + */ + @Before + public void init() { + Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + // context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + dbManager = context.getBean(Manager.class); + deposit = DepositImpl.createRoot(dbManager); + deposit.createAccount(Hex.decode(OWNER_ADDRESS), AccountType.Normal); + deposit.addBalance(Hex.decode(OWNER_ADDRESS), 30000000000000L); + } + + // solidity for CPUEnergyWhenAssertStyleTest + // pragma solidity ^0.4.0; + // + // An assert-style exception is generated in the following situations: + // + // If you access an array at a too large or negative index (i.e. x[i] where i >= x.length or i < 0). + // If you access a fixed-length bytesN at a too large or negative index. + // If you divide or modulo by zero (e.g. 5 / 0 or 23 % 0). + // If you shift by a negative amount. + // If you convert a value too big or negative into an enum type. + // If you call a zero-initialized variable of internal function type. + // If you call assert with an argument that evaluates to false. + + // contract TestAssertStyleContract{ + // + // enum fortest {one, second, third} + // + // function testOutOfIndex() public { + // uint256[] memory a = new uint256[](10); + // a[10] = 10; + // } + // + // function testbytesN() public { + // bytes16 a = 0x12345; + // uint c = 20; + // uint b = uint256(a[c]); + // } + // + // function testDivZero() public { + // uint256 a = 0; + // uint256 b = 10 / a; + // } + // + // function testShiftByNegative() public { + // int256 shift = -10; + // int256 a = 1024 >> shift; + // } + // + // function testEnumType() public { + // fortest a = fortest(10); + // + // } + // + // function testFunctionPointer() public { + // function (int) internal pure returns (int) funcPtr; + // funcPtr(1); + // } + // + // function testAssert(){ + // assert(1==2); + // } + // + // } + + @Test + public void whenAssertStyleTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + + long value = 0; + long feeLimit = 20000000000000L; // sun + long consumeUserResourcePercent = 100; + TVMTestResult result = deployWhenAssertStyleTestContract(value, feeLimit, + consumeUserResourcePercent); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 135); + byte[] contractAddress = result.getContractAddress(); + + /* =================================== CALL testOutOfIndex() =================================== */ + byte[] triggerData = TVMTestUtils.parseABI("testOutOfIndex()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testbytesN() =================================== */ + triggerData = TVMTestUtils.parseABI("testbytesN()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testDivZero() =================================== */ + triggerData = TVMTestUtils.parseABI("testDivZero()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testShiftByNegative() =================================== */ + triggerData = TVMTestUtils.parseABI("testShiftByNegative()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testEnumType() =================================== */ + triggerData = TVMTestUtils.parseABI("testEnumType()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testFunctionPointer() =================================== */ + triggerData = TVMTestUtils.parseABI("testFunctionPointer()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + /* =================================== CALL testAssert() =================================== */ + triggerData = TVMTestUtils.parseABI("testAssert()", null); + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, 0, feeLimit, deposit, null); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 200000000000L); + Assert.assertEquals(result.getRuntime().getResult().isRevert(), false); + Assert.assertTrue( + result.getRuntime().getResult().getException() instanceof IllegalOperationException); + + } + + public TVMTestResult deployWhenAssertStyleTestContract(long value, long feeLimit, + long consumeUserResourcePercent) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "test"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":false,\"inputs\":[],\"name\":\"testbytesN\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testAssert\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testEnumType\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testOutOfIndex\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testDivZero\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testShiftByNegative\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"testFunctionPointer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + String code = "608060405234801561001057600080fd5b506101d7806100206000396000f3006080604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631e76e10781146100875780632b813bc01461009e5780635a43cddc146100b35780639a4e1fa0146100c8578063b87d948d146100dd578063e88e362a146100f2578063e9ad8ee714610107575b600080fd5b34801561009357600080fd5b5061009c61011c565b005b3480156100aa57600080fd5b5061009c610138565b3480156100bf57600080fd5b5061009c61013a565b3480156100d457600080fd5b5061009c610140565b3480156100e957600080fd5b5061009c610183565b3480156100fe57600080fd5b5061009c61018b565b34801561011357600080fd5b5061009c610196565b7201234500000000000000000000000000000000601460008282fe5bfe5b6000600afe5b60408051600a80825261016082019092526060916020820161014080388339019050509050600a81600a81518110151561017657fe5b6020908102909101015250565b60008080600afe5b600919600081610400fe5b6101386101a760018263ffffffff16565b50505600a165627a7a72305820155b43453889c7c579af81c62359ac291bb44abe0ab5c6772971f69745a4cfc20029"; + String libraryAddressPair = null; + + return TVMTestUtils + .deployContractAndReturnTVMTestResult(contractName, address, ABI, code, + value, + feeLimit, consumeUserResourcePercent, libraryAddressPair, + deposit, null); + } + + /** + * Release resources. + */ + @After + public void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } +} + diff --git a/src/test/java/org/tron/common/runtime/vm/CPUTimeTest.java b/src/test/java/org/tron/common/runtime/vm/CPUTimeTest.java new file mode 100644 index 00000000000..c7e818ad978 --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/CPUTimeTest.java @@ -0,0 +1,138 @@ +package org.tron.common.runtime.vm; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.application.TronApplicationContext; +import org.testng.Assert; +import org.tron.common.runtime.TVMTestResult; +import org.tron.common.runtime.TVMTestUtils; +import org.tron.common.runtime.vm.program.Program.OutOfEnergyException; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Protocol.AccountType; + +@Slf4j +@Ignore +public class CPUTimeTest { + + private Manager dbManager; + private TronApplicationContext context; + private DepositImpl deposit; + private String dbPath = "output_CPUTimeTest"; + private String OWNER_ADDRESS; + + + /** + * Init data. + */ + @Before + public void init() { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + dbManager = context.getBean(Manager.class); + deposit = DepositImpl.createRoot(dbManager); + deposit.createAccount(Hex.decode(OWNER_ADDRESS), AccountType.Normal); + deposit.addBalance(Hex.decode(OWNER_ADDRESS), 30000000000000L); + } + + // solidity for endlessLoopTest + // pragma solidity ^0.4.0; + // + // contract TestForEndlessLoop { + // + // uint256 vote; + // constructor () public { + // vote = 0; + // } + // + // function getVote() public constant returns (uint256 _vote) { + // _vote = vote; + // } + // + // function setVote(uint256 _vote) public { + // vote = _vote; + // while(true) + // { + // vote += 1; + // } + // } + // } + + @Test + public void endlessLoopTest() + throws ContractExeException, TransactionTraceException, ContractValidateException, OutOfSlotTimeException { + + long value = 0; + long feeLimit = 20000000000000L; + long consumeUserResourcePercent = 0; + TVMTestResult result = deployEndlessLoopContract(value, feeLimit, + consumeUserResourcePercent); + Assert.assertEquals(result.getReceipt().getEnergyUsage(), 0); + Assert.assertEquals(result.getReceipt().getEnergyUsageTotal(), 5107); + Assert.assertEquals(result.getReceipt().getOriginEnergyUsage(), 0); + + byte[] contractAddress = result.getContractAddress(); + + /* =================================== CALL setVote(uint256) =================================== */ + String params = "0000000000000000000000000000000000000000000000000000000000000003"; + byte[] triggerData = TVMTestUtils.parseABI("setVote(uint256)", params); + boolean haveException = false; + try { + result = TVMTestUtils + .triggerContractAndReturnTVMTestResult(Hex.decode(OWNER_ADDRESS), + contractAddress, triggerData, value, feeLimit, deposit, null); + Exception exception = result.getRuntime().getResult().getException(); + Assert.assertTrue(exception instanceof OutOfEnergyException); + haveException = true; + } catch (Exception e) { + haveException = true; + Assert.assertTrue(e instanceof OutOfSlotTimeException); + } + Assert.assertTrue(haveException); + } + + public TVMTestResult deployEndlessLoopContract(long value, long feeLimit, + long consumeUserResourcePercent) + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "EndlessLoopContract"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"getVote\",\"outputs\":[{\"name\":\"_vote\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_vote\",\"type\":\"uint256\"}],\"name\":\"setVote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + String code = "608060405234801561001057600080fd5b506000808190555060fa806100266000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630242f35114604e578063230796ae146076575b600080fd5b348015605957600080fd5b50606060a0565b6040518082815260200191505060405180910390f35b348015608157600080fd5b50609e6004803603810190808035906020019092919050505060a9565b005b60008054905090565b806000819055505b60011560cb576001600080828254019250508190555060b1565b505600a165627a7a72305820290a38c9bbafccaf6c7f752ab56d229e354da767efb72715ee9fdb653b9f4b6c0029"; + String libraryAddressPair = null; + + return TVMTestUtils + .deployContractAndReturnTVMTestResult(contractName, address, ABI, code, + value, + feeLimit, consumeUserResourcePercent, libraryAddressPair, + deposit, null); + } + + /** + * Release resources. + */ + @After + public void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } +} diff --git a/src/test/java/org/tron/common/runtime/vm/DataWordTest.java b/src/test/java/org/tron/common/runtime/vm/DataWordTest.java new file mode 100644 index 00000000000..3388dfab36a --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/DataWordTest.java @@ -0,0 +1,433 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ +package org.tron.common.runtime.vm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; + +@Slf4j +public class DataWordTest { + + @Test + public void testAddPerformance() { + boolean enabled = false; + + if (enabled) { + byte[] one = new byte[]{0x01, 0x31, 0x54, 0x41, 0x01, 0x31, 0x54, + 0x41, 0x01, 0x31, 0x54, 0x41, 0x01, 0x31, 0x54, 0x41, 0x01, + 0x31, 0x54, 0x41, 0x01, 0x31, 0x54, 0x41, 0x01, 0x31, 0x54, + 0x41, 0x01, 0x31, 0x54, 0x41}; // Random value + + int ITERATIONS = 10000000; + + long now1 = System.currentTimeMillis(); + for (int i = 0; i < ITERATIONS; i++) { + DataWord x = new DataWord(one); + x.add(x); + } + System.out.println("Add1: " + (System.currentTimeMillis() - now1) + "ms"); + + long now2 = System.currentTimeMillis(); + for (int i = 0; i < ITERATIONS; i++) { + DataWord x = new DataWord(one); + x.add2(x); + } + System.out.println("Add2: " + (System.currentTimeMillis() - now2) + "ms"); + } else { + System.out.println("ADD performance test is disabled."); + } + } + + @Test + public void testAdd2() { + byte[] two = new byte[32]; + two[31] = (byte) 0xff; // 0x000000000000000000000000000000000000000000000000000000000000ff + + DataWord x = new DataWord(two); + x.add(new DataWord(two)); + System.out.println(Hex.toHexString(x.getData())); + + DataWord y = new DataWord(two); + y.add2(new DataWord(two)); + System.out.println(Hex.toHexString(y.getData())); + } + + @Test + public void testAdd3() { + byte[] three = new byte[32]; + for (int i = 0; i < three.length; i++) { + three[i] = (byte) 0xff; + } + + DataWord x = new DataWord(three); + x.add(new DataWord(three)); + assertEquals(32, x.getData().length); + System.out.println(Hex.toHexString(x.getData())); + + // FAIL +// DataWord y = new DataWord(three); +// y.add2(new DataWord(three)); +// System.out.println(Hex.toHexString(y.getData())); + } + + @Test + public void testMod() { + String expected = "000000000000000000000000000000000000000000000000000000000000001a"; + + byte[] one = new byte[32]; + one[31] = 0x1e; // 0x000000000000000000000000000000000000000000000000000000000000001e + + byte[] two = new byte[32]; + for (int i = 0; i < two.length; i++) { + two[i] = (byte) 0xff; + } + two[31] = 0x56; // 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff56 + + DataWord x = new DataWord(one);// System.out.println(x.value()); + DataWord y = new DataWord(two);// System.out.println(y.value()); + y.mod(x); + assertEquals(32, y.getData().length); + assertEquals(expected, Hex.toHexString(y.getData())); + } + + @Test + public void testMul() { + byte[] one = new byte[32]; + one[31] = 0x1; // 0x0000000000000000000000000000000000000000000000000000000000000001 + + byte[] two = new byte[32]; + two[11] = 0x1; // 0x0000000000000000000000010000000000000000000000000000000000000000 + + DataWord x = new DataWord(one);// System.out.println(x.value()); + DataWord y = new DataWord(two);// System.out.println(y.value()); + x.mul(y); + assertEquals(32, y.getData().length); + assertEquals("0000000000000000000000010000000000000000000000000000000000000000", Hex.toHexString(y.getData())); + } + + @Test + public void testMulOverflow() { + + byte[] one = new byte[32]; + one[30] = 0x1; // 0x0000000000000000000000000000000000000000000000000000000000000100 + + byte[] two = new byte[32]; + two[0] = 0x1; // 0x1000000000000000000000000000000000000000000000000000000000000000 + + DataWord x = new DataWord(one);// System.out.println(x.value()); + DataWord y = new DataWord(two);// System.out.println(y.value()); + x.mul(y); + assertEquals(32, y.getData().length); + assertEquals("0100000000000000000000000000000000000000000000000000000000000000", Hex.toHexString(y.getData())); + } + + @Test + public void testDiv() { + byte[] one = new byte[32]; + one[30] = 0x01; + one[31] = 0x2c; // 0x000000000000000000000000000000000000000000000000000000000000012c + + byte[] two = new byte[32]; + two[31] = 0x0f; // 0x000000000000000000000000000000000000000000000000000000000000000f + + DataWord x = new DataWord(one); + DataWord y = new DataWord(two); + x.div(y); + + assertEquals(32, x.getData().length); + assertEquals("0000000000000000000000000000000000000000000000000000000000000014", Hex.toHexString(x.getData())); + } + + @Test + public void testDivZero() { + byte[] one = new byte[32]; + one[30] = 0x05; // 0x0000000000000000000000000000000000000000000000000000000000000500 + + byte[] two = new byte[32]; + + DataWord x = new DataWord(one); + DataWord y = new DataWord(two); + x.div(y); + + assertEquals(32, x.getData().length); + assertTrue(x.isZero()); + } + + @Test + public void testSDivNegative() { + + // one is -300 as 256-bit signed integer: + byte[] one = Hex.decode("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed4"); + + byte[] two = new byte[32]; + two[31] = 0x0f; + + DataWord x = new DataWord(one); + DataWord y = new DataWord(two); + x.sDiv(y); + + assertEquals(32, x.getData().length); + assertEquals("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec", x.toString()); + } + + @Test + public void testPow() { + + BigInteger x = BigInteger.valueOf(Integer.MAX_VALUE); + BigInteger y = BigInteger.valueOf(1000); + + BigInteger result1 = x.modPow(x, y); + BigInteger result2 = pow(x, y); + System.out.println(result1); + System.out.println(result2); + } + + @Test + public void testSignExtend1() { + + DataWord x = new DataWord(Hex.decode("f2")); + byte k = 0; + String expected = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2"; + + x.signExtend(k); + System.out.println(x.toString()); + assertEquals(expected, x.toString()); + } + + @Test + public void testSignExtend2() { + DataWord x = new DataWord(Hex.decode("f2")); + byte k = 1; + String expected = "00000000000000000000000000000000000000000000000000000000000000f2"; + + x.signExtend(k); + System.out.println(x.toString()); + assertEquals(expected, x.toString()); + } + + @Test + public void testSignExtend3() { + + byte k = 1; + DataWord x = new DataWord(Hex.decode("0f00ab")); + String expected = "00000000000000000000000000000000000000000000000000000000000000ab"; + + x.signExtend(k); + System.out.println(x.toString()); + assertEquals(expected, x.toString()); + } + + @Test + public void testSignExtend4() { + + byte k = 1; + DataWord x = new DataWord(Hex.decode("ffff")); + String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + + x.signExtend(k); + System.out.println(x.toString()); + assertEquals(expected, x.toString()); + } + + @Test + public void testSignExtend5() { + + byte k = 3; + DataWord x = new DataWord(Hex.decode("ffffffff")); + String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + + x.signExtend(k); + System.out.println(x.toString()); + assertEquals(expected, x.toString()); + } + + @Test + public void testSignExtend6() { + + byte k = 3; + DataWord x = new DataWord(Hex.decode("ab02345678")); + String expected = "0000000000000000000000000000000000000000000000000000000002345678"; + + x.signExtend(k); + System.out.println(x.toString()); + assertEquals(expected, x.toString()); + } + + @Test + public void testSignExtend7() { + + byte k = 3; + DataWord x = new DataWord(Hex.decode("ab82345678")); + String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff82345678"; + + x.signExtend(k); + System.out.println(x.toString()); + assertEquals(expected, x.toString()); + } + + @Test + public void testSignExtend8() { + + byte k = 30; + DataWord x = new DataWord(Hex.decode("ff34567882345678823456788234567882345678823456788234567882345678")); + String expected = "0034567882345678823456788234567882345678823456788234567882345678"; + + x.signExtend(k); + System.out.println(x.toString()); + assertEquals(expected, x.toString()); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testSignExtendException1() { + + byte k = -1; + DataWord x = new DataWord(); + + x.signExtend(k); // should throw an exception + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testSignExtendException2() { + + byte k = 32; + DataWord x = new DataWord(); + + x.signExtend(k); // should throw an exception + } + + @Test + public void testAddModOverflow() { + testAddMod("9999999999999999999999999999999999999999999999999999999999999999", + "8888888888888888888888888888888888888888888888888888888888888888", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + testAddMod("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + } + + private void testAddMod(String v1, String v2, String v3) { + DataWord dv1 = new DataWord(Hex.decode(v1)); + DataWord dv2 = new DataWord(Hex.decode(v2)); + DataWord dv3 = new DataWord(Hex.decode(v3)); + BigInteger bv1 = new BigInteger(v1, 16); + BigInteger bv2 = new BigInteger(v2, 16); + BigInteger bv3 = new BigInteger(v3, 16); + + dv1.addmod(dv2, dv3); + BigInteger br = bv1.add(bv2).mod(bv3); + assertEquals(dv1.value(), br); + } + + @Test + public void testMulMod1() { + DataWord wr = new DataWord(Hex.decode("9999999999999999999999999999999999999999999999999999999999999999")); + DataWord w1 = new DataWord(Hex.decode("01")); + DataWord w2 = new DataWord(Hex.decode("9999999999999999999999999999999999999999999999999999999999999998")); + + wr.mulmod(w1, w2); + + assertEquals(32, wr.getData().length); + assertEquals("0000000000000000000000000000000000000000000000000000000000000001", Hex.toHexString(wr.getData())); + } + + @Test + public void testMulMod2() { + DataWord wr = new DataWord(Hex.decode("9999999999999999999999999999999999999999999999999999999999999999")); + DataWord w1 = new DataWord(Hex.decode("01")); + DataWord w2 = new DataWord(Hex.decode("9999999999999999999999999999999999999999999999999999999999999999")); + + wr.mulmod(w1, w2); + + assertEquals(32, wr.getData().length); + assertTrue(wr.isZero()); + } + + @Test + public void testMulModZero() { + DataWord wr = new DataWord(Hex.decode("00")); + DataWord w1 = new DataWord(Hex.decode("9999999999999999999999999999999999999999999999999999999999999999")); + DataWord w2 = new DataWord(Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + + wr.mulmod(w1, w2); + + assertEquals(32, wr.getData().length); + assertTrue(wr.isZero()); + } + + @Test + public void testMulModZeroWord1() { + DataWord wr = new DataWord(Hex.decode("9999999999999999999999999999999999999999999999999999999999999999")); + DataWord w1 = new DataWord(Hex.decode("00")); + DataWord w2 = new DataWord(Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + + wr.mulmod(w1, w2); + + assertEquals(32, wr.getData().length); + assertTrue(wr.isZero()); + } + + @Test + public void testMulModZeroWord2() { + DataWord wr = new DataWord(Hex.decode("9999999999999999999999999999999999999999999999999999999999999999")); + DataWord w1 = new DataWord(Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + DataWord w2 = new DataWord(Hex.decode("00")); + + wr.mulmod(w1, w2); + + assertEquals(32, wr.getData().length); + assertTrue(wr.isZero()); + } + + @Test + public void testMulModOverflow() { + DataWord wr = new DataWord(Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + DataWord w1 = new DataWord(Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + DataWord w2 = new DataWord(Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + + wr.mulmod(w1, w2); + + assertEquals(32, wr.getData().length); + assertTrue(wr.isZero()); + } + + private static BigInteger pow(BigInteger x, BigInteger y) { + if (y.compareTo(BigInteger.ZERO) < 0) + throw new IllegalArgumentException(); + BigInteger z = x; // z will successively become x^2, x^4, x^8, x^16, + // x^32... + BigInteger result = BigInteger.ONE; + byte[] bytes = y.toByteArray(); + for (int i = bytes.length - 1; i >= 0; i--) { + byte bits = bytes[i]; + for (int j = 0; j < 8; j++) { + if ((bits & 1) != 0) + result = result.multiply(z); + // short cut out if there are no more bits to handle: + if ((bits >>= 1) == 0 && i == 0) + return result; + z = z.multiply(z); + } + } + return result; + } +} diff --git a/src/test/java/org/tron/common/runtime/vm/InternalTransactionCallTest.java b/src/test/java/org/tron/common/runtime/vm/InternalTransactionCallTest.java new file mode 100644 index 00000000000..0c333ce4d56 --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/InternalTransactionCallTest.java @@ -0,0 +1,309 @@ +package org.tron.common.runtime.vm; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.application.TronApplicationContext; +import org.testng.Assert; +import org.tron.common.runtime.Runtime; +import org.tron.common.runtime.TVMTestUtils; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.TransactionTraceException; +import org.tron.protos.Protocol.AccountType; + +@Slf4j +public class InternalTransactionCallTest { + private Runtime runtime; + private Manager dbManager; + private TronApplicationContext context; + private DepositImpl deposit; + private String dbPath = "output_InternalTransactionCallTest"; + private String OWNER_ADDRESS; + + + /** + * Init data. + */ + @Before + public void init() { + Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + dbManager = context.getBean(Manager.class); + deposit = DepositImpl.createRoot(dbManager); + deposit.createAccount(Hex.decode(OWNER_ADDRESS),AccountType.Normal); + deposit.addBalance(Hex.decode(OWNER_ADDRESS),100000000); + } + + + /** + * contract A { + * uint256 public numberForB; + * address public senderForB; + * function callTest(address bAddress, uint256 _number) { + * bAddress.call(bytes4(sha3("setValue(uint256)")), _number); // B's storage is set, A is not modified + * } + * + * function callcodeTest(address bAddress, uint256 _number) { + * bAddress.callcode(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified + * } + * + * function delegatecallTest(address bAddress, uint256 _number) { + * bAddress.delegatecall(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified + * } + * } + * + * contract B { + * uint256 public numberForB; + * address public senderForB; + * + * function setValue(uint256 _number) { + * numberForB = _number; + * senderForB = msg.sender; + * // senderForB is A if invoked by A's callTest. B's storage will be updated + * // senderForB is A if invoked by A's callcodeTest. None of B's storage is updated + * // senderForB is OWNER if invoked by A's delegatecallTest. None of B's storage is updated + * } + * } + */ + + + /* + A call B, anything belongs to A should not be changed, B should be changed. + msg.sender for contractB should be A's address. + */ + + + @Test + public void callTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + byte[] contractBAddress = deployBContractAndGetItsAddress(); + byte[] contractAAddress =deployAContractandGetItsAddress(); + + /* =================================== CALL callTest() to change B storage =================================== */ + String params = Hex.toHexString(new DataWord(new DataWord(contractBAddress).getLast20Bytes()).getData()) + "0000000000000000000000000000000000000000000000000000000000000003"; + byte[] triggerData = TVMTestUtils.parseABI("callTest(address,uint256)",params); + TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData, + 0,1000000000,deposit,null); + + /* =================================== CALL numberForB() to check A's numberForB =================================== */ + byte[] triggerData2 = TVMTestUtils.parseABI("numberForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData2, + 0,1000000000,deposit,null); + // A should not be changed + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000000"); + + /* =================================== CALL senderForB() to check A's senderForB =================================== */ + byte[] triggerData3 = TVMTestUtils.parseABI("senderForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData3, + 0,1000000000,deposit,null); + // A should be changed + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000000"); + + /* =================================== CALL numberForB() to check B's numberForB =================================== */ + byte[] triggerData4 = TVMTestUtils.parseABI("numberForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractBAddress,triggerData4, + 0,1000000000,deposit,null); + // B's numberForB should be changed to 3 + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000003"); + + /* =================================== CALL senderForB() to check B's senderForB =================================== */ + byte[] triggerData5 = TVMTestUtils.parseABI("senderForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractBAddress,triggerData5, + 0,1000000000,deposit,null); + // B 's senderForB should be A + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),Hex.toHexString(new DataWord(new DataWord(contractAAddress).getLast20Bytes()).getData())); + } + + /* + A delegatecall B, A should be changed, anything belongs to B should not be changed. + msg.sender for contractB should be Caller(OWNER_ADDRESS), but this value will not be effected in B's senderForB since we use delegatecall. + We store it in A's senderForB. + */ + @Test + public void delegateCallTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + byte[] contractBAddress = deployBContractAndGetItsAddress(); + byte[] contractAAddress =deployAContractandGetItsAddress(); + /* =================================== CALL delegatecallTest() to change B storage =================================== */ + String params = Hex.toHexString(new DataWord(new DataWord(contractBAddress).getLast20Bytes()).getData()) + "0000000000000000000000000000000000000000000000000000000000000003"; + byte[] triggerData = TVMTestUtils.parseABI("delegatecallTest(address,uint256)",params); + TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData, + 0,1000000000,deposit,null); + + /* =================================== CALL numberForB() to check A's numberForB =================================== */ + byte[] triggerData2 = TVMTestUtils.parseABI("numberForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData2, + 0,1000000000,deposit,null); + // A should be changed to 3 + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000003"); + + /* =================================== CALL senderForB() to check A's senderForB =================================== */ + byte[] triggerData3 = TVMTestUtils.parseABI("senderForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData3, + 0,1000000000,deposit,null); + // A's senderForB should be changed to caller's contract Address (OWNER_ADDRESS) + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),Hex.toHexString(new DataWord(new DataWord(OWNER_ADDRESS).getLast20Bytes()).getData())); + + /* =================================== CALL numberForB() to check B's numberForB =================================== */ + byte[] triggerData4 = TVMTestUtils.parseABI("numberForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractBAddress,triggerData4, + 0,1000000000,deposit,null); + // B's numberForB should not be changed + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000000"); + + /* =================================== CALL senderForB() to check B's senderForB =================================== */ + byte[] triggerData5 = TVMTestUtils.parseABI("senderForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractBAddress,triggerData5, + 0,1000000000,deposit,null); + // B 's senderForB should not be changed + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000000"); + + } + + /* + A callcode B, A should be changed, anything belongs to B should not be changed. + msg.sender for contractB should be A, but this value will not be effected in B's senderForB since we use callcode. + We store it in A's senderForB. + */ + @Test + public void callCodeTest() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + byte[] contractBAddress = deployBContractAndGetItsAddress(); + byte[] contractAAddress =deployAContractandGetItsAddress(); + /* =================================== CALL callcodeTest() to change B storage =================================== */ + String params = Hex.toHexString(new DataWord(new DataWord(contractBAddress).getLast20Bytes()).getData()) + "0000000000000000000000000000000000000000000000000000000000000003"; + byte[] triggerData = TVMTestUtils.parseABI("callcodeTest(address,uint256)",params); + TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData, + 0,1000000000,deposit,null); + + /* =================================== CALL numberForB() to check A's numberForB =================================== */ + byte[] triggerData2 = TVMTestUtils.parseABI("numberForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData2, + 0,1000000000,deposit,null); + // A should be changed to 3 + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000003"); + + /* =================================== CALL senderForB() to check A's senderForB =================================== */ + byte[] triggerData3 = TVMTestUtils.parseABI("senderForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractAAddress,triggerData3, + 0,1000000000,deposit,null); + // A's senderForB should be changed to A's contract Address + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),Hex.toHexString(new DataWord(new DataWord(contractAAddress).getLast20Bytes()).getData())); + + /* =================================== CALL numberForB() to check B's numberForB =================================== */ + byte[] triggerData4 = TVMTestUtils.parseABI("numberForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractBAddress,triggerData4, + 0,1000000000,deposit,null); + // B's numberForB should not be changed + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000000"); + + /* =================================== CALL senderForB() to check B's senderForB =================================== */ + byte[] triggerData5 = TVMTestUtils.parseABI("senderForB()",""); + runtime = TVMTestUtils.triggerContractWholeProcessReturnContractAddress(Hex.decode(OWNER_ADDRESS),contractBAddress,triggerData5, + 0,1000000000,deposit,null); + // B 's senderForB should not be changed + Assert.assertEquals(Hex.toHexString(runtime.getResult().getHReturn()),"0000000000000000000000000000000000000000000000000000000000000000"); + } + + @Test + public void staticCallTest(){ + //TODO: need to implement this + } + + + // Just for the AB example above + public byte[] deployAContractandGetItsAddress() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "AContract"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"bAddress\",\"type\":\"address\"},{\"name\":\"_number\",\"type\":\"uint256\"}]," + + "\"name\":\"delegatecallTest\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant" + + "\":false,\"inputs\":[{\"name\":\"bAddress\",\"type\":\"address\"},{\"name\":\"_number\",\"type\":\"uint256\"}],\"name\":\"callTest\"," + + "\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":" + + "\"senderForB\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":" + + "\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"bAddress\",\"type\":\"address\"},{\"name\":\"_number\",\"type\":\"uint256\"}]," + + "\"name\":\"callcodeTest\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true," + + "\"inputs\":[],\"name\":\"numberForB\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\"," + + "\"type\":\"function\"}]"; + String code = "608060405234801561001057600080fd5b506102d4806100206000396000f3006080604052600436106100535763ffffffff60e060020a6000350" + + "416633da5d187811461005857806343c3a43a1461007e578063b053ebd4146100a2578063d7d21f5b146100d3578063dd92afef146100f7575b600080fd5b" + + "34801561006457600080fd5b5061007c600160a060020a036004351660243561011e565b005b34801561008a57600080fd5b5061007c600160a060020a036" + + "0043516602435610199565b3480156100ae57600080fd5b506100b7610216565b60408051600160a060020a039092168252519081900360200190f35b3480" + + "156100df57600080fd5b5061007c600160a060020a0360043516602435610225565b34801561010357600080fd5b5061010c6102a2565b604080519182525" + + "19081900360200190f35b81600160a060020a031660405180807f73657456616c75652875696e743235362900000000000000000000000000000081525060" + + "11019050604051809103902060e060020a9004826040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381865af4" + + "505050505050565b81600160a060020a031660405180807f73657456616c75652875696e743235362900000000000000000000000000000081525060110190" + + "50604051809103902060e060020a9004826040518263ffffffff1660e060020a028152600401808281526020019150506000604051808303816000875af150" + + "5050505050565b600154600160a060020a031681565b81600160a060020a031660405180807f73657456616c75652875696e74323536290000000000000000" + + "000000000000008152506011019050604051809103902060e060020a9004826040518263ffffffff1660e060020a0281526004018082815260200191505060" + + "00604051808303816000875af2505050505050565b600054815600a165627a7a723058206d36ef7c6f6d387ad915f299e715c9b360f3719843a1113badb28b" + + "6595e66c1e0029"; + long value = 0; + long feeLimit = 1000000000; + long consumeUserResourcePercent = 0; + String libraryAddressPair=null; + + byte[] contractAddress = TVMTestUtils + .deployContractWholeProcessReturnContractAddress(contractName,address,ABI,code,value,feeLimit,consumeUserResourcePercent,libraryAddressPair, + deposit,null); + return contractAddress; + } + + // Just for the AB example above + public byte[] deployBContractAndGetItsAddress() + throws ContractExeException, OutOfSlotTimeException, TransactionTraceException, ContractValidateException { + String contractName = "BContract"; + byte[] address = Hex.decode(OWNER_ADDRESS); + String ABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_number\",\"type\":\"uint256\"}],\"name\":\"setValue\"," + + "\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true," + + "\"inputs\":[],\"name\":\"senderForB\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false," + + "\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"numberForB\"," + + "\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":" + + "\"function\"}]"; + String code = "608060405234801561001057600080fd5b5061014c806100206000396000f3006080604052600436106100565763ffffffff7" + + "c010000000000000000000000000000000000000000000000000000000060003504166355241077811461005b578063b053ebd4146100" + + "75578063dd92afef146100b3575b600080fd5b34801561006757600080fd5b506100736004356100da565b005b34801561008157600080" + + "fd5b5061008a6100fe565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b348015" + + "6100bf57600080fd5b506100c861011a565b60408051918252519081900360200190f35b6000556001805473ffffffffffffffffffffff" + + "ffffffffffffffffff191633179055565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b600054815600a165627a7" + + "a72305820e2c513cf46bb32018879ec48f8fe264c985b6d2c7a853a578f4f56583fe1ffb80029"; + long value = 0; + long feeLimit = 1000000000; + long consumeUserResourcePercent = 0; + String libraryAddressPair=null; + + byte[] contractAddress = TVMTestUtils.deployContractWholeProcessReturnContractAddress(contractName,address,ABI,code,value,feeLimit,consumeUserResourcePercent,libraryAddressPair, + deposit,null); + return contractAddress; + } + + + /** + * Release resources. + */ + @After + public void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } +} diff --git a/src/test/java/org/tron/common/runtime/vm/InterpreterTest.java b/src/test/java/org/tron/common/runtime/vm/InterpreterTest.java new file mode 100644 index 00000000000..67b5419276c --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/InterpreterTest.java @@ -0,0 +1,59 @@ +/* + * 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.runtime.vm; + +import static org.junit.Assert.assertTrue; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import java.io.*; +import org.tron.protos.Protocol.Transaction; +import org.tron.common.runtime.vm.program.InternalTransaction; +import org.tron.common.runtime.vm.VM; +import org.tron.common.runtime.vm.program.Program; +import org.tron.common.runtime.vm.program.invoke.ProgramInvokeMockImpl; + +@Slf4j +public class InterpreterTest { + + private ProgramInvokeMockImpl invoke; + private Program program; + + @Test + public void testVMException() { + VM vm = new VM(); + invoke = new ProgramInvokeMockImpl(); + byte[] op = { 0x5b, 0x60, 0x00, 0x56 }; + // 0x5b - JUMPTEST + // 0x60 0x00 - PUSH 0x00 + // 0x56 - JUMP to 0 + Transaction trx = Transaction.getDefaultInstance(); + InternalTransaction interTrx = new InternalTransaction(trx); + program = new Program(op, invoke, interTrx); + + boolean result = false; + + try { + while (!program.isStopped()) { + vm.step(program); + } + } catch (Exception e) { + result = true; + } + + assertTrue(result); + } +} diff --git a/src/test/java/org/tron/common/runtime/vm/MemoryTest.java b/src/test/java/org/tron/common/runtime/vm/MemoryTest.java new file mode 100644 index 00000000000..a161515e86a --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/MemoryTest.java @@ -0,0 +1,534 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ +package org.tron.common.runtime.vm; + +import static java.lang.Math.ceil; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; +import org.testng.Assert; +import org.tron.common.runtime.vm.program.Memory; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; + +@Slf4j +public class MemoryTest { + + private static final int WORD_SIZE = 32; + private static final int CHUNK_SIZE = 1024; + + @Test + public void testExtend() { + checkMemoryExtend(0); + checkMemoryExtend(1); + checkMemoryExtend(WORD_SIZE); + checkMemoryExtend(WORD_SIZE * 2); + checkMemoryExtend(CHUNK_SIZE - 1); + checkMemoryExtend(CHUNK_SIZE); + checkMemoryExtend(CHUNK_SIZE + 1); + checkMemoryExtend(2000); + } + + private static void checkMemoryExtend(int dataSize) { + Memory memory = new Memory(); + memory.extend(0, dataSize); + Assert.assertEquals(calcSize(dataSize, CHUNK_SIZE), memory.internalSize()); + Assert.assertEquals(calcSize(dataSize, WORD_SIZE), memory.size()); + } + + private static int calcSize(int dataSize, int chunkSize) { + return (int) ceil((double) dataSize / chunkSize) * chunkSize; + } + + @Test + public void memorySave_1() { + + Memory memoryBuffer = new Memory(); + byte[] data = {1, 1, 1, 1}; + + memoryBuffer.write(0, data, data.length, false); + + assertTrue(1 == memoryBuffer.getChunks().size()); + + byte[] chunk = memoryBuffer.getChunks().get(0); + assertTrue(chunk[0] == 1); + assertTrue(chunk[1] == 1); + assertTrue(chunk[2] == 1); + assertTrue(chunk[3] == 1); + assertTrue(chunk[4] == 0); + + assertTrue(memoryBuffer.size() == 32); + } + + @Test + public void memorySave_2() { + + Memory memoryBuffer = new Memory(); + byte[] data = Hex.decode("0101010101010101010101010101010101010101010101010101010101010101"); + + memoryBuffer.write(0, data, data.length, false); + + assertTrue(1 == memoryBuffer.getChunks().size()); + + byte[] chunk = memoryBuffer.getChunks().get(0); + assertTrue(chunk[0] == 1); + assertTrue(chunk[1] == 1); + + assertTrue(chunk[30] == 1); + assertTrue(chunk[31] == 1); + assertTrue(chunk[32] == 0); + + assertTrue(memoryBuffer.size() == 32); + } + + @Test + public void memorySave_3() { + + Memory memoryBuffer = new Memory(); + byte[] data = Hex.decode("010101010101010101010101010101010101010101010101010101010101010101"); + + memoryBuffer.write(0, data, data.length, false); + + assertTrue(1 == memoryBuffer.getChunks().size()); + + byte[] chunk = memoryBuffer.getChunks().get(0); + assertTrue(chunk[0] == 1); + assertTrue(chunk[1] == 1); + + assertTrue(chunk[30] == 1); + assertTrue(chunk[31] == 1); + assertTrue(chunk[32] == 1); + assertTrue(chunk[33] == 0); + + assertTrue(memoryBuffer.size() == 64); + } + + @Test + public void memorySave_4() { + + Memory memoryBuffer = new Memory(); + byte[] data = new byte[1024]; + Arrays.fill(data, (byte) 1); + + memoryBuffer.write(0, data, data.length, false); + + assertTrue(1 == memoryBuffer.getChunks().size()); + + byte[] chunk = memoryBuffer.getChunks().get(0); + assertTrue(chunk[0] == 1); + assertTrue(chunk[1] == 1); + + assertTrue(chunk[1022] == 1); + assertTrue(chunk[1023] == 1); + + assertTrue(memoryBuffer.size() == 1024); + } + + @Test + public void memorySave_5() { + + Memory memoryBuffer = new Memory(); + + byte[] data = new byte[1025]; + Arrays.fill(data, (byte) 1); + + memoryBuffer.write(0, data, data.length, false); + + assertTrue(2 == memoryBuffer.getChunks().size()); + + byte[] chunk1 = memoryBuffer.getChunks().get(0); + assertTrue(chunk1[0] == 1); + assertTrue(chunk1[1] == 1); + + assertTrue(chunk1[1022] == 1); + assertTrue(chunk1[1023] == 1); + + byte[] chunk2 = memoryBuffer.getChunks().get(1); + assertTrue(chunk2[0] == 1); + assertTrue(chunk2[1] == 0); + + assertTrue(memoryBuffer.size() == 1056); + } + + @Test + public void memorySave_6() { + + Memory memoryBuffer = new Memory(); + + byte[] data1 = new byte[1024]; + Arrays.fill(data1, (byte) 1); + + byte[] data2 = new byte[1024]; + Arrays.fill(data2, (byte) 2); + + memoryBuffer.write(0, data1, data1.length, false); + memoryBuffer.write(1024, data2, data2.length, false); + + assertTrue(2 == memoryBuffer.getChunks().size()); + + byte[] chunk1 = memoryBuffer.getChunks().get(0); + assertTrue(chunk1[0] == 1); + assertTrue(chunk1[1] == 1); + + assertTrue(chunk1[1022] == 1); + assertTrue(chunk1[1023] == 1); + + byte[] chunk2 = memoryBuffer.getChunks().get(1); + assertTrue(chunk2[0] == 2); + assertTrue(chunk2[1] == 2); + + assertTrue(chunk2[1022] == 2); + assertTrue(chunk2[1023] == 2); + + assertTrue(memoryBuffer.size() == 2048); + } + + @Test + public void memorySave_7() { + + Memory memoryBuffer = new Memory(); + + byte[] data1 = new byte[1024]; + Arrays.fill(data1, (byte) 1); + + byte[] data2 = new byte[1024]; + Arrays.fill(data2, (byte) 2); + + byte[] data3 = new byte[1]; + Arrays.fill(data3, (byte) 3); + + memoryBuffer.write(0, data1, data1.length, false); + memoryBuffer.write(1024, data2, data2.length, false); + memoryBuffer.write(2048, data3, data3.length, false); + + assertTrue(3 == memoryBuffer.getChunks().size()); + + byte[] chunk1 = memoryBuffer.getChunks().get(0); + assertTrue(chunk1[0] == 1); + assertTrue(chunk1[1] == 1); + + assertTrue(chunk1[1022] == 1); + assertTrue(chunk1[1023] == 1); + + byte[] chunk2 = memoryBuffer.getChunks().get(1); + assertTrue(chunk2[0] == 2); + assertTrue(chunk2[1] == 2); + + assertTrue(chunk2[1022] == 2); + assertTrue(chunk2[1023] == 2); + + byte[] chunk3 = memoryBuffer.getChunks().get(2); + assertTrue(chunk3[0] == 3); + + assertTrue(memoryBuffer.size() == 2080); + } + + @Test + public void memorySave_8() { + + Memory memoryBuffer = new Memory(); + + byte[] data1 = new byte[128]; + Arrays.fill(data1, (byte) 1); + + memoryBuffer.extendAndWrite(0, 256, data1); + + int ones = 0; int zeroes = 0; + for (int i = 0; i < memoryBuffer.size(); ++i){ + if (memoryBuffer.readByte(i) == 1) ++ones; + if (memoryBuffer.readByte(i) == 0) ++zeroes; + } + + assertTrue(ones == zeroes); + assertTrue(256 == memoryBuffer.size()); + } + + + + @Test + public void memoryLoad_1() { + + Memory memoryBuffer = new Memory(); + DataWord value = memoryBuffer.readWord(100); + assertTrue(value.intValue() == 0); + assertTrue(memoryBuffer.getChunks().size() == 1); + assertTrue(memoryBuffer.size() == 32 * 5); + } + + @Test + public void memoryLoad_2() { + + Memory memoryBuffer = new Memory(); + DataWord value = memoryBuffer.readWord(2015); + assertTrue(value.intValue() == 0); + assertTrue(memoryBuffer.getChunks().size() == 2); + assertTrue(memoryBuffer.size() == 2048); + } + + @Test + public void memoryLoad_3() { + + Memory memoryBuffer = new Memory(); + DataWord value = memoryBuffer.readWord(2016); + assertTrue(value.intValue() == 0); + assertTrue(memoryBuffer.getChunks().size() == 2); + assertTrue(memoryBuffer.size() == 2048); + } + + @Test + public void memoryLoad_4() { + + Memory memoryBuffer = new Memory(); + DataWord value = memoryBuffer.readWord(2017); + assertTrue(value.intValue() == 0); + assertTrue(memoryBuffer.getChunks().size() == 3); + assertTrue(memoryBuffer.size() == 2080); + } + + @Test + public void memoryLoad_5() { + + Memory memoryBuffer = new Memory(); + + byte[] data1 = new byte[1024]; + Arrays.fill(data1, (byte) 1); + + byte[] data2 = new byte[1024]; + Arrays.fill(data2, (byte) 2); + + memoryBuffer.write(0, data1, data1.length, false); + memoryBuffer.write(1024, data2, data2.length, false); + + assertTrue(memoryBuffer.getChunks().size() == 2); + assertTrue(memoryBuffer.size() == 2048); + + DataWord val1 = memoryBuffer.readWord(0x3df); + DataWord val2 = memoryBuffer.readWord(0x3e0); + DataWord val3 = memoryBuffer.readWord(0x3e1); + + assertArrayEquals( + Hex.decode("0101010101010101010101010101010101010101010101010101010101010101"), + val1.getData()); + + assertArrayEquals( + Hex.decode("0101010101010101010101010101010101010101010101010101010101010101"), + val2.getData()); + + assertArrayEquals( + Hex.decode("0101010101010101010101010101010101010101010101010101010101010102"), + val3.getData()); + assertTrue(memoryBuffer.size() == 2048); + } + + + @Test + public void memoryChunk_1(){ + Memory memoryBuffer = new Memory(); + + byte[] data1 = new byte[32]; + Arrays.fill(data1, (byte) 1); + + byte[] data2 = new byte[32]; + Arrays.fill(data2, (byte) 2); + + memoryBuffer.write(0, data1, data1.length, false); + memoryBuffer.write(32, data2, data2.length, false); + + byte[] data = memoryBuffer.read(0, 64); + + assertArrayEquals( + Hex.decode("0101010101010101010101010101010101010101010101010101010101010101" + + "0202020202020202020202020202020202020202020202020202020202020202"), + data + ); + + Assert.assertEquals(64, memoryBuffer.size()); + } + + + @Test + public void memoryChunk_2(){ + Memory memoryBuffer = new Memory(); + + byte[] data1 = new byte[32]; + Arrays.fill(data1, (byte) 1); + + memoryBuffer.write(0, data1, data1.length, false); + assertTrue(32 == memoryBuffer.size()); + + byte[] data = memoryBuffer.read(0, 64); + + assertArrayEquals( + Hex.decode("0101010101010101010101010101010101010101010101010101010101010101" + + "0000000000000000000000000000000000000000000000000000000000000000"), + data + ); + + Assert.assertEquals(64, memoryBuffer.size()); + } + + @Test + public void memoryChunk_3(){ + + Memory memoryBuffer = new Memory(); + + byte[] data1 = new byte[1024]; + Arrays.fill(data1, (byte) 1); + + byte[] data2 = new byte[1024]; + Arrays.fill(data2, (byte) 2); + + memoryBuffer.write(0, data1, data1.length, false); + memoryBuffer.write(1024, data2, data2.length, false); + + byte[] data = memoryBuffer.read(0, 2048); + + int ones = 0; int twos = 0; + for (int i = 0; i < data.length; ++i){ + if (data[i] == 1) ++ones; + if (data[i] == 2) ++twos; + } + + assertTrue(ones == twos); + assertTrue(2048 == memoryBuffer.size()); + } + + @Test + public void memoryChunk_4(){ + + Memory memoryBuffer = new Memory(); + + byte[] data1 = new byte[1024]; + Arrays.fill(data1, (byte) 1); + + byte[] data2 = new byte[1024]; + Arrays.fill(data2, (byte) 2); + + memoryBuffer.write(0, data1, data1.length, false); + memoryBuffer.write(1024, data2, data2.length, false); + + byte[] data = memoryBuffer.read(0, 2049); + + int ones = 0; int twos = 0; int zero = 0; + for (int i = 0; i < data.length; ++i){ + if (data[i] == 1) ++ones; + if (data[i] == 2) ++twos; + if (data[i] == 0) ++zero; + } + + assertTrue(zero == 1); + assertTrue(ones == twos); + assertTrue(2080 == memoryBuffer.size()); + } + + + @Test + public void memoryWriteLimited_1(){ + + Memory memoryBuffer = new Memory(); + memoryBuffer.extend(0, 3072); + + byte[] data1 = new byte[6272]; + Arrays.fill(data1, (byte) 1); + + memoryBuffer.write(2720, data1, data1.length, true); + + byte lastZero = memoryBuffer.readByte(2719); + byte firstOne = memoryBuffer.readByte(2721); + + assertTrue(memoryBuffer.size() == 3072); + assertTrue(lastZero == 0); + assertTrue(firstOne == 1); + + byte[] data = memoryBuffer.read(2720, 352); + + int ones = 0; int zero = 0; + for (int i = 0; i < data.length; ++i){ + if (data[i] == 1) ++ones; + if (data[i] == 0) ++zero; + } + + assertTrue(ones == data.length); + assertTrue(zero == 0); + } + + @Test + public void memoryWriteLimited_2(){ + + Memory memoryBuffer = new Memory(); + memoryBuffer.extend(0, 3072); + + byte[] data1 = new byte[6272]; + Arrays.fill(data1, (byte) 1); + + memoryBuffer.write(2720, data1, 300, true); + + byte lastZero = memoryBuffer.readByte(2719); + byte firstOne = memoryBuffer.readByte(2721); + + assertTrue(memoryBuffer.size() == 3072); + assertTrue(lastZero == 0); + assertTrue(firstOne == 1); + + byte[] data = memoryBuffer.read(2720, 352); + + int ones = 0; int zero = 0; + for (int i = 0; i < data.length; ++i){ + if (data[i] == 1) ++ones; + if (data[i] == 0) ++zero; + } + + assertTrue(ones == 300); + assertTrue(zero == 52); + } + + @Test + public void memoryWriteLimited_3(){ + + Memory memoryBuffer = new Memory(); + memoryBuffer.extend(0, 128); + + byte[] data1 = new byte[20]; + Arrays.fill(data1, (byte) 1); + + memoryBuffer.write(10, data1, 40, true); + + byte lastZero = memoryBuffer.readByte(9); + byte firstOne = memoryBuffer.readByte(10); + + assertTrue(memoryBuffer.size() == 128); + assertTrue(lastZero == 0); + assertTrue(firstOne == 1); + + byte[] data = memoryBuffer.read(10, 30); + + int ones = 0; int zero = 0; + for (int i = 0; i < data.length; ++i){ + if (data[i] == 1) ++ones; + if (data[i] == 0) ++zero; + } + + assertTrue(ones == 20); + assertTrue(zero == 10); + } + + + +} \ No newline at end of file diff --git a/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java b/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java new file mode 100644 index 00000000000..8431097be09 --- /dev/null +++ b/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java @@ -0,0 +1,322 @@ +package org.tron.common.runtime.vm; + + +import static junit.framework.TestCase.fail; +import static org.tron.common.runtime.utils.MUtil.convertToTronAddress; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.spongycastle.util.Arrays; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.runtime.vm.PrecompiledContracts.PrecompiledContract; +import org.tron.common.runtime.vm.program.ProgramResult; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.ByteUtil; +import org.tron.common.utils.FileUtil; +import org.tron.common.utils.StringUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.actuator.FreezeBalanceActuator; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ProposalCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.capsule.WitnessCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.BalanceInsufficientException; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.protos.Contract; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.Proposal.State; + +@Slf4j +public class PrecompiledContractsTest { + + // common + private static final DataWord voteContractAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000010001"); +// private static final DataWord freezeBalanceAddr = new DataWord( +// "0000000000000000000000000000000000000000000000000000000000010002"); +// private static final DataWord unFreezeBalanceAddr = new DataWord( +// "0000000000000000000000000000000000000000000000000000000000010003"); + private static final DataWord withdrawBalanceAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000010004"); + private static final DataWord proposalApproveAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000010005"); + private static final DataWord proposalCreateAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000010006"); + private static final DataWord proposalDeleteAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000010007"); + private static final DataWord convertFromTronBytesAddressAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000010008"); + private static final DataWord convertFromTronBase58AddressAddr = new DataWord( + "0000000000000000000000000000000000000000000000000000000000010009"); + + private static TronApplicationContext context; + private static Manager dbManager; + private static final String dbPath = "output_PrecompiledContracts_test"; + private static final String ACCOUNT_NAME = "account"; + private static final String OWNER_ADDRESS; + private static final String WITNESS_NAME = "witness"; + private static final String WITNESS_ADDRESS; + private static final String WITNESS_ADDRESS_BASE = "548794500882809695a8a687866e76d4271a1abc" ; + private static final String URL = "https://tron.network"; + + // withdraw + private static final long initBalance = 10_000_000_000L; + private static final long allowance = 32_000_000L; + + static { + Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + WITNESS_ADDRESS = Wallet.getAddressPreFixString() + WITNESS_ADDRESS_BASE; + + } + + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + } + + /** + * create temp Capsule test need. + */ + @Before + public void createCapsule() { + // witness: witnessCapsule + WitnessCapsule witnessCapsule = + new WitnessCapsule( + StringUtil.hexString2ByteString(WITNESS_ADDRESS), + 10L, + URL); + // witness: AccountCapsule + AccountCapsule witnessAccountCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(WITNESS_NAME), + StringUtil.hexString2ByteString(WITNESS_ADDRESS), + AccountType.Normal, + initBalance); + // some normal account + AccountCapsule ownerAccountFirstCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME), + StringUtil.hexString2ByteString(OWNER_ADDRESS), + AccountType.Normal, + 10_000_000_000_000L); + + dbManager.getAccountStore() + .put(witnessAccountCapsule.getAddress().toByteArray(), witnessAccountCapsule); + dbManager.getAccountStore() + .put(ownerAccountFirstCapsule.getAddress().toByteArray(), ownerAccountFirstCapsule); + dbManager.getWitnessStore().put(witnessCapsule.getAddress().toByteArray(), witnessCapsule); + + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); + dbManager.getDynamicPropertiesStore().saveNextMaintenanceTime(2000000); + } + + + private Any getFreezeContract(String ownerAddress, long frozenBalance, long duration) { + return Any.pack( + Contract.FreezeBalanceContract.newBuilder() + .setOwnerAddress(StringUtil.hexString2ByteString(ownerAddress)) + .setFrozenBalance(frozenBalance) + .setFrozenDuration(duration) + .build()); + } + + private PrecompiledContract createPrecompiledContract(DataWord addr, String ownerAddress) { + PrecompiledContract contract = PrecompiledContracts.getContractForAddress(addr); + contract.setCallerAddress(convertToTronAddress(Hex.decode(ownerAddress))); + contract.setDeposit(DepositImpl.createRoot(dbManager)); + ProgramResult programResult = new ProgramResult(); + contract.setResult(programResult); + return contract; + } + + @Test + public void voteWitnessNativeTest() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, ContractValidateException, ContractExeException { + PrecompiledContract contract = createPrecompiledContract(voteContractAddr, OWNER_ADDRESS); + byte[] witnessAddressBytes = new byte[32]; + byte[] witnessAddressBytes21 = Hex.decode(WITNESS_ADDRESS); + System.arraycopy(witnessAddressBytes21, 0, witnessAddressBytes, + witnessAddressBytes.length - witnessAddressBytes21.length, witnessAddressBytes21.length); + + DataWord voteCount = new DataWord( + "0000000000000000000000000000000000000000000000000000000000000001"); + byte[] voteCountBytes = voteCount.getData(); + byte[] data = new byte[witnessAddressBytes.length + voteCountBytes.length]; + System.arraycopy(witnessAddressBytes, 0, data, 0, witnessAddressBytes.length); + System.arraycopy(voteCountBytes, 0, data, witnessAddressBytes.length, voteCountBytes.length); + + long frozenBalance = 1_000_000_000_000L; + long duration = 3; + Any freezeContract = getFreezeContract(OWNER_ADDRESS, frozenBalance, duration); + Constructor constructor = + FreezeBalanceActuator.class + .getDeclaredConstructor(Any.class, dbManager.getClass()); + constructor.setAccessible(true); + FreezeBalanceActuator freezeBalanceActuator = constructor + .newInstance(freezeContract, dbManager); + + TransactionResultCapsule ret = new TransactionResultCapsule(); + freezeBalanceActuator.validate(); + freezeBalanceActuator.execute(ret); + + Boolean result = contract.execute(data).getLeft(); + Assert.assertEquals(1, + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)).getVotesList() + .get(0).getVoteCount()); + Assert.assertArrayEquals(ByteArray.fromHexString(WITNESS_ADDRESS), + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)).getVotesList() + .get(0).getVoteAddress().toByteArray()); + Assert.assertEquals(true, result); + } + + @Test + public void withdrawBalanceNativeTest() { + PrecompiledContract contract = createPrecompiledContract(withdrawBalanceAddr, WITNESS_ADDRESS); + + long now = System.currentTimeMillis(); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(now); + byte[] address = ByteArray.fromHexString(WITNESS_ADDRESS); + try { + dbManager.adjustAllowance(address, allowance); + } catch (BalanceInsufficientException e) { + fail("BalanceInsufficientException"); + } + AccountCapsule accountCapsule = dbManager.getAccountStore().get(address); + Assert.assertEquals(allowance, accountCapsule.getAllowance()); + Assert.assertEquals(0, accountCapsule.getLatestWithdrawTime()); + + WitnessCapsule witnessCapsule = new WitnessCapsule(ByteString.copyFrom(address), + 100, "http://baidu.com"); + dbManager.getWitnessStore().put(address, witnessCapsule); + + contract.execute(new byte[0]); + AccountCapsule witnessAccount = + dbManager.getAccountStore().get(ByteArray.fromHexString(WITNESS_ADDRESS)); + Assert.assertEquals(initBalance + allowance, witnessAccount.getBalance()); + Assert.assertEquals(0, witnessAccount.getAllowance()); + Assert.assertNotEquals(0, witnessAccount.getLatestWithdrawTime()); + } + + + @Test + public void proposalTest() { + + try { + /* + * create proposal Test + */ + DataWord key = new DataWord( + "0000000000000000000000000000000000000000000000000000000000000000"); + // 1000000 == 0xF4240 + DataWord value = new DataWord( + "00000000000000000000000000000000000000000000000000000000000F4240"); + byte[] data4Create = new byte[64]; + System.arraycopy(key.getData(),0,data4Create,0,key.getData().length); + System.arraycopy(value.getData(),0,data4Create,key.getData().length,value.getData().length); + + PrecompiledContract createContract = createPrecompiledContract(proposalCreateAddr,WITNESS_ADDRESS); + + Assert.assertEquals(0, dbManager.getDynamicPropertiesStore().getLatestProposalNum()); + ProposalCapsule proposalCapsule; + byte[] idBytes = createContract.execute(data4Create).getRight(); + long id = ByteUtil.byteArrayToLong(idBytes); + proposalCapsule = dbManager.getProposalStore().get(ByteArray.fromLong(id)); + Assert.assertNotNull(proposalCapsule); + Assert.assertEquals(1, dbManager.getDynamicPropertiesStore().getLatestProposalNum()); + Assert.assertEquals(0, proposalCapsule.getApprovals().size()); + Assert.assertEquals(1000000, proposalCapsule.getCreateTime()); + Assert.assertEquals(261200000, proposalCapsule.getExpirationTime() + ); // 2000000 + 3 * 4 * 21600000 + + + + /* + * approve proposal Test + */ + + byte[] data4Approve = new byte[64]; + DataWord isApprove = new DataWord("0000000000000000000000000000000000000000000000000000000000000001"); + System.arraycopy(idBytes,0,data4Approve,0,idBytes.length); + System.arraycopy(isApprove.getData(),0,data4Approve,idBytes.length,isApprove.getData().length); + PrecompiledContract approveContract = createPrecompiledContract(proposalApproveAddr,WITNESS_ADDRESS); + approveContract.execute(data4Approve); + proposalCapsule = dbManager.getProposalStore().get(ByteArray.fromLong(id)); + Assert.assertEquals(1,proposalCapsule.getApprovals().size()); + Assert.assertEquals(ByteString.copyFrom(ByteArray.fromHexString(WITNESS_ADDRESS)), + proposalCapsule.getApprovals().get(0)); + + /* + * delete proposal Test + */ + PrecompiledContract deleteContract = createPrecompiledContract(proposalDeleteAddr,WITNESS_ADDRESS); + deleteContract.execute(idBytes); + proposalCapsule = dbManager.getProposalStore().get(ByteArray.fromLong(id)); + Assert.assertEquals(State.CANCELED, proposalCapsule.getState()); + + } catch (ItemNotFoundException e) { + Assert.fail(); + } + } + + + @Test + public void convertFromTronBytesAddressNativeTest() { + PrecompiledContract contract = createPrecompiledContract(convertFromTronBytesAddressAddr, WITNESS_ADDRESS); + byte[] solidityAddress = contract.execute(Hex.decode(WITNESS_ADDRESS)).getRight(); + Assert.assertArrayEquals(solidityAddress,new DataWord(Hex.decode(WITNESS_ADDRESS_BASE)).getData()); + } + + @Test + public void convertFromTronBase58AddressNative() { + // 27WnTihwXsqCqpiNedWvtKCZHsLjDt4Hfmf TestNet address + DataWord word1 = new DataWord("3237576e54696877587371437170694e65645776744b435a48734c6a44743448"); + DataWord word2 = new DataWord("666d660000000000000000000000000000000000000000000000000000000000"); + + byte[] data = new byte[35]; + System.arraycopy(word1.getData(),0,data,0, word1.getData().length); + System.arraycopy(Arrays.copyOfRange(word2.getData(), 0, 3),0,data,word1.getData().length,3); + PrecompiledContract contract = createPrecompiledContract(convertFromTronBase58AddressAddr, WITNESS_ADDRESS); + + byte[] solidityAddress = contract.execute(data).getRight(); + Assert.assertArrayEquals(solidityAddress,new DataWord(Hex.decode(WITNESS_ADDRESS_BASE)).getData()); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + +} diff --git a/src/test/java/org/tron/core/BandwidthProcessorTest.java b/src/test/java/org/tron/core/BandwidthProcessorTest.java index bdf9f60eac5..611af7d88cf 100755 --- a/src/test/java/org/tron/core/BandwidthProcessorTest.java +++ b/src/test/java/org/tron/core/BandwidthProcessorTest.java @@ -9,7 +9,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.capsule.AccountCapsule; @@ -20,6 +20,7 @@ import org.tron.core.config.args.Args; import org.tron.core.db.BandwidthProcessor; import org.tron.core.db.Manager; +import org.tron.core.db.TransactionTrace; import org.tron.protos.Contract; import org.tron.protos.Contract.AssetIssueContract; import org.tron.protos.Contract.TransferAssetContract; @@ -31,7 +32,7 @@ public class BandwidthProcessorTest { private static Manager dbManager; private static final String dbPath = "bandwidth_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String ASSET_NAME; private static final String OWNER_ADDRESS; private static final String ASSET_ADDRESS; @@ -39,7 +40,7 @@ public class BandwidthProcessorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); ASSET_NAME = "test_token"; OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; TO_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; @@ -174,7 +175,9 @@ public void testFree() throws Exception { dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); TransactionResultCapsule ret = new TransactionResultCapsule(); - dbManager.consumeBandwidth(trx, ret); + TransactionTrace trace = new TransactionTrace(trx, dbManager); + + dbManager.consumeBandwidth(trx, ret, trace); AccountCapsule ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -188,11 +191,11 @@ public void testFree() throws Exception { dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1526691038000L); // + 12h - dbManager.consumeBandwidth(trx, ret); + dbManager.consumeBandwidth(trx, ret, trace); ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(61L + 122L, ownerCapsuleNew.getFreeNetUsage()); + Assert.assertEquals(61L + 122, ownerCapsuleNew.getFreeNetUsage()); Assert.assertEquals(508897012L, ownerCapsuleNew.getLatestConsumeFreeTime()); // 508882612L + 28800L/2 Assert.assertEquals(1526691038000L, ownerCapsuleNew.getLatestOperationTime()); @@ -220,7 +223,8 @@ public void testConsumeAssetAccount() throws Exception { dbManager.getAccountStore().put(assetCapsule.getAddress().toByteArray(), assetCapsule); TransactionResultCapsule ret = new TransactionResultCapsule(); - dbManager.consumeBandwidth(trx, ret); + TransactionTrace trace = new TransactionTrace(trx, dbManager); + dbManager.consumeBandwidth(trx, ret, trace); AccountCapsule ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -236,7 +240,7 @@ public void testConsumeAssetAccount() throws Exception { dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1526691038000L); // + 12h - dbManager.consumeBandwidth(trx, ret); + dbManager.consumeBandwidth(trx, ret, trace); ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -268,7 +272,8 @@ public void testConsumeOwner() throws Exception { dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); TransactionResultCapsule ret = new TransactionResultCapsule(); - dbManager.consumeBandwidth(trx, ret); + TransactionTrace trace = new TransactionTrace(trx, dbManager); + dbManager.consumeBandwidth(trx, ret, trace); AccountCapsule ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -283,7 +288,7 @@ public void testConsumeOwner() throws Exception { dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1526691038000L); // + 12h - dbManager.consumeBandwidth(trx, ret); + dbManager.consumeBandwidth(trx, ret, trace); ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -322,12 +327,13 @@ public void testUsingFee() throws Exception { dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); TransactionResultCapsule ret = new TransactionResultCapsule(); - dbManager.consumeBandwidth(trx, ret); + TransactionTrace trace = new TransactionTrace(trx, dbManager); + dbManager.consumeBandwidth(trx, ret, trace); AccountCapsule ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - long transactionFee = 122L * dbManager.getDynamicPropertiesStore().getTransactionFee(); + long transactionFee = (122L) * dbManager.getDynamicPropertiesStore().getTransactionFee(); Assert.assertEquals(transactionFee, dbManager.getDynamicPropertiesStore().getTotalTransactionCost()); Assert.assertEquals( @@ -336,7 +342,7 @@ public void testUsingFee() throws Exception { Assert.assertEquals(transactionFee, ret.getFee()); dbManager.getAccountStore().delete(ByteArray.fromHexString(TO_ADDRESS)); - dbManager.consumeBandwidth(trx, ret); + dbManager.consumeBandwidth(trx, ret, trace); // long createAccountFee = dbManager.getDynamicPropertiesStore().getCreateAccountFee(); // ownerCapsuleNew = dbManager.getAccountStore() diff --git a/src/test/java/org/tron/core/CpuProcessorTest.java b/src/test/java/org/tron/core/EnergyProcessorTest.java similarity index 77% rename from src/test/java/org/tron/core/CpuProcessorTest.java rename to src/test/java/org/tron/core/EnergyProcessorTest.java index 341d09ae5c3..89c72927985 100755 --- a/src/test/java/org/tron/core/CpuProcessorTest.java +++ b/src/test/java/org/tron/core/EnergyProcessorTest.java @@ -8,34 +8,31 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.capsule.AccountCapsule; -import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.capsule.TransactionResultCapsule; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; -import org.tron.core.db.CpuProcessor; +import org.tron.core.db.EnergyProcessor; import org.tron.core.db.Manager; import org.tron.protos.Contract; import org.tron.protos.Contract.AssetIssueContract; -import org.tron.protos.Contract.TransferAssetContract; import org.tron.protos.Protocol.AccountType; @Slf4j -public class CpuProcessorTest { +public class EnergyProcessorTest { private static Manager dbManager; - private static final String dbPath = "CpuProcessorTest"; - private static AnnotationConfigApplicationContext context; + private static final String dbPath = "EnergyProcessorTest"; + private static TronApplicationContext context; private static final String ASSET_NAME; private static final String CONTRACT_PROVIDER_ADDRESS; private static final String USER_ADDRESS; static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); ASSET_NAME = "test_token"; CONTRACT_PROVIDER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; @@ -103,31 +100,32 @@ private AssetIssueContract getAssetIssueContract() { } @Test - public void testUseContractCreatorCpu() throws Exception { + public void testUseContractCreatorEnergy() throws Exception { dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1526647838000L); - dbManager.getDynamicPropertiesStore().saveTotalCpuWeight(10_000_000L); + dbManager.getDynamicPropertiesStore().saveTotalEnergyWeight(10_000_000L); AccountCapsule ownerCapsule = dbManager.getAccountStore() .get(ByteArray.fromHexString(CONTRACT_PROVIDER_ADDRESS)); dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); - CpuProcessor processor = new CpuProcessor(dbManager); - long cpuTime = 10000; + EnergyProcessor processor = new EnergyProcessor(dbManager); + long energy = 10000; long now = 1526647838000L; - boolean result = processor.useCpu(ownerCapsule, cpuTime, now); + boolean result = processor.useEnergy(ownerCapsule, energy, now); Assert.assertEquals(false, result); - ownerCapsule.setFrozenForCpu(10_000_000L, 0L); - result = processor.useCpu(ownerCapsule, cpuTime, now); + ownerCapsule.setFrozenForEnergy(10_000_000L, 0L); + result = processor.useEnergy(ownerCapsule, energy, now); Assert.assertEquals(true, result); AccountCapsule ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(CONTRACT_PROVIDER_ADDRESS)); Assert.assertEquals(1526647838000L, ownerCapsuleNew.getLatestOperationTime()); - Assert.assertEquals(1526647838000L, ownerCapsuleNew.getAccountResource().getLatestConsumeTimeForCpu()); - Assert.assertEquals(10000L, ownerCapsuleNew.getAccountResource().getCpuUsage()); + Assert.assertEquals(1526647838000L, + ownerCapsuleNew.getAccountResource().getLatestConsumeTimeForEnergy()); + Assert.assertEquals(10000L, ownerCapsuleNew.getAccountResource().getEnergyUsage()); } diff --git a/src/test/java/org/tron/core/StorageMarketTest.java b/src/test/java/org/tron/core/StorageMarketTest.java new file mode 100644 index 00000000000..710ba5876f3 --- /dev/null +++ b/src/test/java/org/tron/core/StorageMarketTest.java @@ -0,0 +1,293 @@ +package org.tron.core; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.Parameter.ChainConstant; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.db.StorageMarket; +import org.tron.protos.Contract; +import org.tron.protos.Protocol.AccountType; + +@Slf4j +public class StorageMarketTest { + + private static Manager dbManager; + private static StorageMarket storageMarket; + private static final String dbPath = "output_buy_storage_test"; + private static TronApplicationContext context; + private static final String OWNER_ADDRESS; + private static final String OWNER_ADDRESS_INVALID = "aaaa"; + private static final String OWNER_ACCOUNT_INVALID; + private static final long initBalance = 10_000_000_000_000_000L; + + static { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + OWNER_ACCOUNT_INVALID = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + storageMarket = new StorageMarket(dbManager); + // Args.setParam(new String[]{"--output-directory", dbPath}, + // "config-junit.conf"); + // dbManager = new Manager(); + // dbManager.init(); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + /** + * create temp Capsule test need. + */ + @Before + public void createAccountCapsule() { + AccountCapsule ownerCapsule = + new AccountCapsule( + ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), + AccountType.Normal, + initBalance); + dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); + + dbManager.getDynamicPropertiesStore().saveTotalStorageReserved( + 128L * 1024 * 1024 * 1024); + dbManager.getDynamicPropertiesStore().saveTotalStoragePool(100_000_000_000000L); + dbManager.getDynamicPropertiesStore().saveTotalStorageTax(0); + + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(0); + } + + private Any getContract(String ownerAddress, long quant) { + return Any.pack( + Contract.BuyStorageContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(ownerAddress))) + .setQuant(quant) + .build()); + } + + @Test + public void testBuyStorage() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + AccountCapsule owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + + long quant = 2_000_000_000_000L; // 2 million trx + storageMarket.buyStorage(owner, quant); + + Assert.assertEquals(owner.getBalance(), initBalance - quant + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(2694881440L, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - 2694881440L, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + quant, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + } + + @Test + public void testBuyStorage2() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + AccountCapsule owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + + long quant = 1_000_000_000_000L; // 1 million trx + + storageMarket.buyStorage(owner, quant); + + Assert.assertEquals(owner.getBalance(), initBalance - quant + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(1360781717L, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - 1360781717L, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + quant, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + storageMarket.buyStorage(owner, quant); + + Assert.assertEquals(owner.getBalance(), initBalance - 2 * quant + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(2694881439L, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - 2694881439L, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + 2 * quant, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + } + + + @Test + public void testBuyStorageBytes() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + AccountCapsule owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + + long bytes = 2694881440L; // 2 million trx + storageMarket.buyStorageBytes(owner, bytes); + + Assert.assertEquals(owner.getBalance(), initBalance - 2_000_000_000_000L + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(bytes, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - bytes, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + 2_000_000_000_000L, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + } + + @Test + public void testBuyStorageBytes2() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + AccountCapsule owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + + long bytes1 = 1360781717L; + + storageMarket.buyStorageBytes(owner, bytes1); + + Assert.assertEquals(owner.getBalance(), initBalance - 1_000_000_000_000L + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(bytes1, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - bytes1, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + 1_000_000_000_000L, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + long bytes2 = 1334099723L; + storageMarket.buyStorageBytes(owner, bytes2); + Assert.assertEquals(owner.getBalance(), initBalance - 2 * 1_000_000_000_000L + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(bytes1 + bytes2, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - (bytes1 + bytes2), + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + 2 * 1_000_000_000_000L, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + } + + @Test + public void testSellStorage() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + AccountCapsule owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + + long quant = 2_000_000_000_000L; // 2 million trx + storageMarket.buyStorage(owner, quant); + + Assert.assertEquals(owner.getBalance(), initBalance - quant + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(2694881440L, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - 2694881440L, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + quant, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + long bytes = 2694881440L; + storageMarket.sellStorage(owner, bytes); + + Assert.assertEquals(owner.getBalance(), initBalance); + Assert.assertEquals(0, owner.getStorageLimit()); + Assert.assertEquals(currentReserved, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(100_000_000_000_000L, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + } + + @Test + public void testSellStorage2() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + AccountCapsule owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + + long quant = 2_000_000_000_000L; // 2 million trx + storageMarket.buyStorage(owner, quant); + + Assert.assertEquals(owner.getBalance(), initBalance - quant + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(2694881440L, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - 2694881440L, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + quant, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + long bytes1 = 2694881440L - 1360781717L; // 1 million trx + long bytes2 = 1360781717L; // 1 million trx + + storageMarket.sellStorage(owner, bytes1); + + Assert.assertEquals(owner.getBalance(), initBalance - 1_000_000_000_000L); + Assert.assertEquals(1360781717L, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - 1360781717L, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + 1_000_000_000_000L, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + storageMarket.sellStorage(owner, bytes2); + + Assert.assertEquals(owner.getBalance(), initBalance); + Assert.assertEquals(0, owner.getStorageLimit()); + Assert.assertEquals(currentReserved, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + } + + +} diff --git a/src/test/java/org/tron/core/WalletTest.java b/src/test/java/org/tron/core/WalletTest.java index 18ccd0d057d..f5bd1476cf1 100644 --- a/src/test/java/org/tron/core/WalletTest.java +++ b/src/test/java/org/tron/core/WalletTest.java @@ -32,7 +32,7 @@ import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.api.GrpcAPI.AssetIssueList; import org.tron.api.GrpcAPI.BlockList; import org.tron.common.crypto.ECKey; @@ -57,7 +57,7 @@ @Slf4j public class WalletTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Wallet wallet; private static Manager manager; private static String dbPath = "output_wallet_test"; @@ -100,7 +100,7 @@ public class WalletTest { static { Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @BeforeClass diff --git a/src/test/java/org/tron/core/actuator/AssetIssueActuatorTest.java b/src/test/java/org/tron/core/actuator/AssetIssueActuatorTest.java index 39c39e519b7..bb2e07e464f 100755 --- a/src/test/java/org/tron/core/actuator/AssetIssueActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/AssetIssueActuatorTest.java @@ -14,7 +14,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -35,7 +35,7 @@ @Slf4j public class AssetIssueActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_assetIssue_test"; private static final String OWNER_ADDRESS; @@ -53,7 +53,7 @@ public class AssetIssueActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ADDRESS_SECOND = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; @@ -922,7 +922,7 @@ public void descriptionTest() { .setTrxNum(TRX_NUM).setNum(NUM) .setStartTime(nowTime) .setEndTime(nowTime + 24 * 3600 * 1000) - .setDescription(ByteString.copyFromUtf8(description200Bytes+"0")) + .setDescription(ByteString.copyFromUtf8(description200Bytes + "0")) .setUrl(ByteString.copyFromUtf8(URL)) .build()); @@ -1329,24 +1329,21 @@ public void frozenTest() { } /** - * 1. start time should not be null - * 2. end time should not be null - * 3. start time >= getHeadBlockTimeStamp - * 4. start time < end time - * + * 1. start time should not be null 2. end time should not be null 3. start time >= + * getHeadBlockTimeStamp 4. start time < end time */ @Test public void issueTimeTest() { //empty start time will throw exception Any contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setEndTime(endTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setEndTime(endTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); AssetIssueActuator actuator = new AssetIssueActuator(contract, dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); try { @@ -1364,14 +1361,14 @@ public void issueTimeTest() { //empty end time will throw exception contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(startTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(startTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); actuator = new AssetIssueActuator(contract, dbManager); ret = new TransactionResultCapsule(); try { @@ -1389,15 +1386,15 @@ public void issueTimeTest() { //startTime == now, throw exception contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(now) - .setEndTime(endTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(now) + .setEndTime(endTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); actuator = new AssetIssueActuator(contract, dbManager); ret = new TransactionResultCapsule(); try { @@ -1415,15 +1412,15 @@ public void issueTimeTest() { //startTime < now, throw exception contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(now - 1) - .setEndTime(endTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(now - 1) + .setEndTime(endTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); actuator = new AssetIssueActuator(contract, dbManager); ret = new TransactionResultCapsule(); try { @@ -1441,15 +1438,15 @@ public void issueTimeTest() { //endTime == startTime, throw exception contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(startTime) - .setEndTime(startTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(startTime) + .setEndTime(startTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); actuator = new AssetIssueActuator(contract, dbManager); ret = new TransactionResultCapsule(); try { @@ -1467,15 +1464,15 @@ public void issueTimeTest() { //endTime < startTime, throw exception contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(endTime) - .setEndTime(startTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(endTime) + .setEndTime(startTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); actuator = new AssetIssueActuator(contract, dbManager); ret = new TransactionResultCapsule(); try { @@ -1493,21 +1490,22 @@ public void issueTimeTest() { //right issue, will not throw exception contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(startTime) - .setEndTime(endTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(startTime) + .setEndTime(endTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); actuator = new AssetIssueActuator(contract, dbManager); ret = new TransactionResultCapsule(); try { actuator.validate(); actuator.execute(ret); - AccountCapsule account = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + AccountCapsule account = dbManager.getAccountStore() + .get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); Assert.assertEquals(account.getAssetIssuedName().toStringUtf8(), NAME); Assert.assertEquals(account.getAssetMap().size(), 1); @@ -1526,50 +1524,50 @@ public void issueTimeTest() { @Test public void assetIssueNameTest() { Any contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(startTime) - .setEndTime(endTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(startTime) + .setEndTime(endTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); AssetIssueActuator actuator = new AssetIssueActuator(contract, dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); try { - actuator.validate(); - actuator.execute(ret); + actuator.validate(); + actuator.execute(ret); } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); + Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.assertFalse(e instanceof ContractExeException); } contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(ASSET_NAME_SECOND)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(startTime) - .setEndTime(endTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(ASSET_NAME_SECOND)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(startTime) + .setEndTime(endTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .build()); actuator = new AssetIssueActuator(contract, dbManager); ret = new TransactionResultCapsule(); try { - actuator.validate(); - actuator.execute(ret); - Assert.assertTrue(false); + actuator.validate(); + actuator.execute(ret); + Assert.assertTrue(false); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("An account can only issue one asset", e.getMessage()); + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("An account can only issue one asset", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.assertFalse(e instanceof ContractExeException); } finally { - dbManager.getAssetIssueStore().delete(ByteArray.fromString(NAME)); - dbManager.getAssetIssueStore().delete(ByteArray.fromString(ASSET_NAME_SECOND)); + dbManager.getAssetIssueStore().delete(ByteArray.fromString(NAME)); + dbManager.getAssetIssueStore().delete(ByteArray.fromString(ASSET_NAME_SECOND)); } } @@ -1577,24 +1575,25 @@ public void assetIssueNameTest() { public void frozenListSizeTest() { this.dbManager.getDynamicPropertiesStore().saveMaxFrozenSupplyNumber(3); List frozenList = new ArrayList(); - for (int i = 0; i < this.dbManager.getDynamicPropertiesStore().getMaxFrozenSupplyNumber() + 2; i++) { + for (int i = 0; i < this.dbManager.getDynamicPropertiesStore().getMaxFrozenSupplyNumber() + 2; + i++) { frozenList.add(FrozenSupply.newBuilder() - .setFrozenAmount(10) - .setFrozenDays(3) - .build()); + .setFrozenAmount(10) + .setFrozenDays(3) + .build()); } Any contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(startTime) - .setEndTime(endTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .addAllFrozenSupply(frozenList) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(startTime) + .setEndTime(endTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .addAllFrozenSupply(frozenList) + .build()); AssetIssueActuator actuator = new AssetIssueActuator(contract, dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); try { @@ -1616,20 +1615,20 @@ public void frozenSupplyMoreThanTotalSupplyTest() { this.dbManager.getDynamicPropertiesStore().saveMaxFrozenSupplyNumber(3); List frozenList = new ArrayList(); frozenList.add(FrozenSupply.newBuilder() - .setFrozenAmount(TOTAL_SUPPLY + 1) - .setFrozenDays(3) - .build()); + .setFrozenAmount(TOTAL_SUPPLY + 1) + .setFrozenDays(3) + .build()); Any contract = Any.pack(Contract.AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) - .setName(ByteString.copyFromUtf8(NAME)) - .setTotalSupply(TOTAL_SUPPLY) - .setTrxNum(TRX_NUM).setNum(NUM) - .setStartTime(startTime) - .setEndTime(endTime) - .setDescription(ByteString.copyFromUtf8("description")) - .setUrl(ByteString.copyFromUtf8(URL)) - .addAllFrozenSupply(frozenList) - .build()); + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFromUtf8(NAME)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM) + .setStartTime(startTime) + .setEndTime(endTime) + .setDescription(ByteString.copyFromUtf8("description")) + .setUrl(ByteString.copyFromUtf8(URL)) + .addAllFrozenSupply(frozenList) + .build()); AssetIssueActuator actuator = new AssetIssueActuator(contract, dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); try { diff --git a/src/test/java/org/tron/core/actuator/BuyStorageActuatorTest.java b/src/test/java/org/tron/core/actuator/BuyStorageActuatorTest.java index bbb478555aa..5ccb6ef85eb 100644 --- a/src/test/java/org/tron/core/actuator/BuyStorageActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/BuyStorageActuatorTest.java @@ -9,7 +9,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -31,7 +31,7 @@ public class BuyStorageActuatorTest { private static Manager dbManager; private static final String dbPath = "output_buy_storage_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String OWNER_ADDRESS; private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; @@ -39,7 +39,7 @@ public class BuyStorageActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; @@ -139,7 +139,7 @@ public void testBuyStorage2() { Assert.assertEquals(currentPool, 100_000_000_000000L); Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); - long quant = 1_000_000_000_000L; // 2 million trx + long quant = 1_000_000_000_000L; // 1 million trx BuyStorageActuator actuator = new BuyStorageActuator( getContract(OWNER_ADDRESS, quant), dbManager); @@ -164,19 +164,17 @@ public void testBuyStorage2() { dbManager.getDynamicPropertiesStore().getTotalStoragePool()); actuator2.validate(); - actuator2.execute(ret); + actuator2.execute(ret2); Assert.assertEquals(ret2.getInstance().getRet(), code.SUCESS); + owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(owner.getBalance(), initBalance - 2 * quant - ChainConstant.TRANSFER_FEE); Assert.assertEquals(2694881439L, owner.getStorageLimit()); - long tax = 0L; - Assert.assertEquals(tax, - dbManager.getDynamicPropertiesStore().getTotalStorageTax()); Assert.assertEquals(currentReserved - 2694881439L, dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); - Assert.assertEquals(currentPool + 2 * quant - tax, + Assert.assertEquals(currentPool + 2 * quant, dbManager.getDynamicPropertiesStore().getTotalStoragePool()); } catch (ContractValidateException e) { @@ -186,21 +184,115 @@ public void testBuyStorage2() { } } +// @Test +// public void testBuyStorageTax() { +// long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); +// long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); +// Assert.assertEquals(currentPool, 100_000_000_000000L); +// Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); +// +// long quant = 1_000_000_000_000L; // 2 million trx +// +// BuyStorageActuator actuator = new BuyStorageActuator( +// getContract(OWNER_ADDRESS, quant), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// +// BuyStorageActuator actuator2 = new BuyStorageActuator( +// getContract(OWNER_ADDRESS, quant), dbManager); +// TransactionResultCapsule ret2 = new TransactionResultCapsule(); +// +// try { +// actuator.validate(); +// actuator.execute(ret); +// Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); +// AccountCapsule owner = +// dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); +// Assert.assertEquals(owner.getBalance(), initBalance - quant +// - ChainConstant.TRANSFER_FEE); +// Assert.assertEquals(1360781717L, owner.getStorageLimit()); +// Assert.assertEquals(currentReserved - 1360781717L, +// dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); +// Assert.assertEquals(currentPool + quant, +// dbManager.getDynamicPropertiesStore().getTotalStoragePool()); +// +// dbManager.getDynamicPropertiesStore() +// .saveLatestBlockHeaderTimestamp(365 * 24 * 3600 * 1000L); +// actuator2.validate(); +// actuator2.execute(ret); +// Assert.assertEquals(ret2.getInstance().getRet(), code.SUCESS); +// owner = +// dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); +// Assert.assertEquals(owner.getBalance(), initBalance - 2 * quant +// - ChainConstant.TRANSFER_FEE); +// Assert.assertEquals(2561459696L, owner.getStorageLimit()); +// long tax = 100899100225L; +// Assert.assertEquals(tax, +// dbManager.getDynamicPropertiesStore().getTotalStorageTax()); +// Assert.assertEquals(currentReserved - 2561459696L, +// dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); +// Assert.assertEquals(currentPool + 2 * quant - tax, +// dbManager.getDynamicPropertiesStore().getTotalStoragePool()); +// +// } catch (ContractValidateException e) { +// Assert.assertFalse(e instanceof ContractValidateException); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } + + @Test + public void buyLessThanZero() { + long quant = -1_000_000_000L; + BuyStorageActuator actuator = new BuyStorageActuator( + getContract(OWNER_ADDRESS, quant), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("quantity must be positive", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + @Test - public void testBuyStorageTax() { + public void buyLessThan1Trx() { + long quant = 200_000L; + BuyStorageActuator actuator = new BuyStorageActuator( + getContract(OWNER_ADDRESS, quant), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("quantity must be larger than 1TRX", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + @Test + public void buyLessThan1Byte() { long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); Assert.assertEquals(currentPool, 100_000_000_000000L); Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); - long quant = 1_000_000_000_000L; // 2 million trx + long quant = 9_000_000_000_000_000L; // 9 billion trx BuyStorageActuator actuator = new BuyStorageActuator( getContract(OWNER_ADDRESS, quant), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); BuyStorageActuator actuator2 = new BuyStorageActuator( - getContract(OWNER_ADDRESS, quant), dbManager); + getContract(OWNER_ADDRESS, 1_000_000), dbManager); TransactionResultCapsule ret2 = new TransactionResultCapsule(); try { @@ -211,54 +303,24 @@ public void testBuyStorageTax() { dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(owner.getBalance(), initBalance - quant - ChainConstant.TRANSFER_FEE); - Assert.assertEquals(1360781717L, owner.getStorageLimit()); - Assert.assertEquals(currentReserved - 1360781717L, + Assert.assertEquals(135928635301L, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - 135928635301L, dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); Assert.assertEquals(currentPool + quant, dbManager.getDynamicPropertiesStore().getTotalStoragePool()); - dbManager.getDynamicPropertiesStore() - .saveLatestBlockHeaderTimestamp(365 * 24 * 3600 * 1000L); actuator2.validate(); - actuator2.execute(ret); - Assert.assertEquals(ret2.getInstance().getRet(), code.SUCESS); - owner = - dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(owner.getBalance(), initBalance - 2 * quant - - ChainConstant.TRANSFER_FEE); - Assert.assertEquals(2561459696L, owner.getStorageLimit()); - long tax = 100899100225L; - Assert.assertEquals(tax, - dbManager.getDynamicPropertiesStore().getTotalStorageTax()); - Assert.assertEquals(currentReserved - 2561459696L, - dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); - Assert.assertEquals(currentPool + 2 * quant - tax, - dbManager.getDynamicPropertiesStore().getTotalStoragePool()); - - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); - } - } - - @Test - public void buyLessThanZero() { - long quant = -1_000_000_000L; - BuyStorageActuator actuator = new BuyStorageActuator( - getContract(OWNER_ADDRESS, quant), dbManager); - TransactionResultCapsule ret = new TransactionResultCapsule(); - try { - actuator.validate(); - actuator.execute(ret); + actuator2.execute(ret2); Assert.fail("cannot run here."); } catch (ContractValidateException e) { Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("quantity must be positive", e.getMessage()); + Assert.assertEquals("storage_bytes must be larger than 1,current storage_bytes[0]", + e.getMessage()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); } + } @Test diff --git a/src/test/java/org/tron/core/actuator/BuyStorageBytesActuatorTest.java b/src/test/java/org/tron/core/actuator/BuyStorageBytesActuatorTest.java new file mode 100644 index 00000000000..a479439e7a7 --- /dev/null +++ b/src/test/java/org/tron/core/actuator/BuyStorageBytesActuatorTest.java @@ -0,0 +1,369 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.Parameter.ChainConstant; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.protos.Contract; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j +public class BuyStorageBytesActuatorTest { + + private static Manager dbManager; + private static final String dbPath = "output_buy_storage_bytes_test"; + private static TronApplicationContext context; + private static final String OWNER_ADDRESS; + private static final String OWNER_ADDRESS_INVALID = "aaaa"; + private static final String OWNER_ACCOUNT_INVALID; + private static final long initBalance = 10_000_000_000_000_000L; + + static { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + OWNER_ACCOUNT_INVALID = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + // Args.setParam(new String[]{"--output-directory", dbPath}, + // "config-junit.conf"); + // dbManager = new Manager(); + // dbManager.init(); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + /** + * create temp Capsule test need. + */ + @Before + public void createAccountCapsule() { + AccountCapsule ownerCapsule = + new AccountCapsule( + ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), + AccountType.Normal, + initBalance); + dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); + + dbManager.getDynamicPropertiesStore().saveTotalStorageReserved( + 128L * 1024 * 1024 * 1024); + dbManager.getDynamicPropertiesStore().saveTotalStoragePool(100_000_000_000000L); + dbManager.getDynamicPropertiesStore().saveTotalStorageTax(0); + + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(0); + } + + private Any getContract(String ownerAddress, long bytes) { + return Any.pack( + Contract.BuyStorageBytesContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(ownerAddress))) + .setBytes(bytes) + .build()); + } + + @Test + public void testBuyStorageBytes() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + long bytes = 2694881440L; // 2 million trx + long quant = 2_000_000_000_000L; + BuyStorageBytesActuator actuator = new BuyStorageBytesActuator( + getContract(OWNER_ADDRESS, bytes), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + AccountCapsule owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + + Assert.assertEquals(owner.getBalance(), initBalance - quant + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(2694881440L, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - 2694881440L, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + quant, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + } catch (ContractValidateException e) { + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + @Test + public void testBuyStorageBytes2() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + long quant = 1_000_000_000_000L; // 1 million trx + long bytes1 = 1360781717L; + long bytes2 = 2694881439L - bytes1; + + BuyStorageBytesActuator actuator = new BuyStorageBytesActuator( + getContract(OWNER_ADDRESS, bytes1), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + BuyStorageBytesActuator actuator2 = new BuyStorageBytesActuator( + getContract(OWNER_ADDRESS, bytes2), dbManager); + TransactionResultCapsule ret2 = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + AccountCapsule owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getBalance(), initBalance - quant + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(bytes1, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - bytes1, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + quant, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + actuator2.validate(); + actuator2.execute(ret2); + Assert.assertEquals(ret2.getInstance().getRet(), code.SUCESS); + owner = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getBalance(), initBalance - 2 * quant + - ChainConstant.TRANSFER_FEE); + Assert.assertEquals(bytes1 + bytes2, owner.getStorageLimit()); + Assert.assertEquals(currentReserved - bytes1 - bytes2, + dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); + Assert.assertEquals(currentPool + 2 * quant, + dbManager.getDynamicPropertiesStore().getTotalStoragePool()); + + } catch (ContractValidateException e) { + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + +// @Test +// public void testBuyStorageTax() { +// long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); +// long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); +// Assert.assertEquals(currentPool, 100_000_000_000000L); +// Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); +// +// long quant = 1_000_000_000_000L; // 2 million trx +// +// BuyStorageActuator actuator = new BuyStorageActuator( +// getContract(OWNER_ADDRESS, quant), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// +// BuyStorageActuator actuator2 = new BuyStorageActuator( +// getContract(OWNER_ADDRESS, quant), dbManager); +// TransactionResultCapsule ret2 = new TransactionResultCapsule(); +// +// try { +// actuator.validate(); +// actuator.execute(ret); +// Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); +// AccountCapsule owner = +// dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); +// Assert.assertEquals(owner.getBalance(), initBalance - quant +// - ChainConstant.TRANSFER_FEE); +// Assert.assertEquals(1360781717L, owner.getStorageLimit()); +// Assert.assertEquals(currentReserved - 1360781717L, +// dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); +// Assert.assertEquals(currentPool + quant, +// dbManager.getDynamicPropertiesStore().getTotalStoragePool()); +// +// dbManager.getDynamicPropertiesStore() +// .saveLatestBlockHeaderTimestamp(365 * 24 * 3600 * 1000L); +// actuator2.validate(); +// actuator2.execute(ret); +// Assert.assertEquals(ret2.getInstance().getRet(), code.SUCESS); +// owner = +// dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); +// Assert.assertEquals(owner.getBalance(), initBalance - 2 * quant +// - ChainConstant.TRANSFER_FEE); +// Assert.assertEquals(2561459696L, owner.getStorageLimit()); +// long tax = 100899100225L; +// Assert.assertEquals(tax, +// dbManager.getDynamicPropertiesStore().getTotalStorageTax()); +// Assert.assertEquals(currentReserved - 2561459696L, +// dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); +// Assert.assertEquals(currentPool + 2 * quant - tax, +// dbManager.getDynamicPropertiesStore().getTotalStoragePool()); +// +// } catch (ContractValidateException e) { +// Assert.assertFalse(e instanceof ContractValidateException); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } + + @Test + public void buyLessThanZero() { + long bytes = -1_000_000_000L; + BuyStorageBytesActuator actuator = new BuyStorageBytesActuator( + getContract(OWNER_ADDRESS, bytes), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("bytes must be positive", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + @Test + public void buyLessThan1Byte() { + long bytes = 0L; + BuyStorageBytesActuator actuator = new BuyStorageBytesActuator( + getContract(OWNER_ADDRESS, bytes), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("bytes must be larger than 1, current storage_bytes[0]", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + @Test + public void buyLessThan1Trx() { + long bytes = 1L; + BuyStorageBytesActuator actuator = new BuyStorageBytesActuator( + getContract(OWNER_ADDRESS, bytes), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("quantity must be larger than 1TRX", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + + } + + @Test + public void buyMoreThanBalance() { + long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); + long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); + Assert.assertEquals(currentPool, 100_000_000_000000L); + Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); + + long bytes = 136178171754L; + + BuyStorageBytesActuator actuator = new BuyStorageBytesActuator( + getContract(OWNER_ADDRESS, bytes), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("quantity must be less than accountBalance", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + @Test + public void invalidOwnerAddress() { + long bytes = 1_000_000_000L; + BuyStorageBytesActuator actuator = new BuyStorageBytesActuator( + getContract(OWNER_ADDRESS_INVALID, bytes), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + + Assert.assertEquals("Invalid address", e.getMessage()); + + } catch (ContractExeException e) { + Assert.assertTrue(e instanceof ContractExeException); + } + + } + + @Test + public void invalidOwnerAccount() { + long bytes = 1_000_000_000L; + BuyStorageBytesActuator actuator = new BuyStorageBytesActuator( + getContract(OWNER_ACCOUNT_INVALID, bytes), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Account[" + OWNER_ACCOUNT_INVALID + "] not exists", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + +} diff --git a/src/test/java/org/tron/core/actuator/CreateAccountActuatorTest.java b/src/test/java/org/tron/core/actuator/CreateAccountActuatorTest.java index 29d4e1ecb0b..6477d417a68 100755 --- a/src/test/java/org/tron/core/actuator/CreateAccountActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/CreateAccountActuatorTest.java @@ -9,7 +9,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; @@ -29,7 +29,7 @@ @Slf4j public class CreateAccountActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_CreateAccount_test"; private static final String OWNER_ADDRESS_FIRST; @@ -38,7 +38,7 @@ public class CreateAccountActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java b/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java index 3bbca885a4f..1bcd76e53e1 100644 --- a/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java @@ -11,7 +11,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -33,7 +33,7 @@ public class FreezeBalanceActuatorTest { private static Manager dbManager; private static final String dbPath = "output_freeze_balance_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String OWNER_ADDRESS; private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; @@ -41,7 +41,7 @@ public class FreezeBalanceActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; diff --git a/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java b/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java index e648e8417cb..effb63cb437 100755 --- a/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java @@ -11,7 +11,7 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -34,7 +34,7 @@ public class ParticipateAssetIssueActuatorTest { private static final Logger logger = LoggerFactory.getLogger("Test"); private static Manager dbManager; private static final String dbPath = "output_participateAsset_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String OWNER_ADDRESS; private static final String TO_ADDRESS; private static final String THIRD_ADDRESS; @@ -51,7 +51,7 @@ public class ParticipateAssetIssueActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; TO_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; THIRD_ADDRESS = Wallet.getAddressPreFixString() + "4948c2e8a756d9437037dcd8c7e0c73d560ca38d"; diff --git a/src/test/java/org/tron/core/actuator/ProposalApproveActuatorTest.java b/src/test/java/org/tron/core/actuator/ProposalApproveActuatorTest.java index 6f228dec09d..3e73073381e 100644 --- a/src/test/java/org/tron/core/actuator/ProposalApproveActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ProposalApproveActuatorTest.java @@ -12,7 +12,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; @@ -37,7 +37,7 @@ public class ProposalApproveActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_ProposalApprove_test"; private static final String ACCOUNT_NAME_FIRST = "ownerF"; @@ -50,7 +50,7 @@ public class ProposalApproveActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java b/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java index 164d100e967..e0d26253fde 100644 --- a/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java @@ -12,7 +12,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -35,7 +35,7 @@ public class ProposalCreateActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_ProposalCreate_test"; private static final String ACCOUNT_NAME_FIRST = "ownerF"; @@ -49,7 +49,7 @@ public class ProposalCreateActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = @@ -263,6 +263,34 @@ public void invalidPara() { } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); } + + paras = new HashMap<>(); + paras.put(10L, -1L); + actuator = + new ProposalCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); + dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); + try { + actuator.validate(); + fail("This proposal has been executed before and is only allowed to be executed once"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("This proposal has been executed before and is only allowed to be executed once", + e.getMessage()); + } + + paras.put(10L, -1L); + dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); + actuator = + new ProposalCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); + dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); + try { + actuator.validate(); + fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", + e.getMessage()); + } } } \ No newline at end of file diff --git a/src/test/java/org/tron/core/actuator/ProposalDeleteActuatorTest.java b/src/test/java/org/tron/core/actuator/ProposalDeleteActuatorTest.java index 74aa9dfeec1..49db73576b8 100644 --- a/src/test/java/org/tron/core/actuator/ProposalDeleteActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ProposalDeleteActuatorTest.java @@ -12,7 +12,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; @@ -37,7 +37,7 @@ public class ProposalDeleteActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_ProposalApprove_test"; private static final String ACCOUNT_NAME_FIRST = "ownerF"; @@ -50,7 +50,7 @@ public class ProposalDeleteActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/src/test/java/org/tron/core/actuator/SellStorageActuatorTest.java b/src/test/java/org/tron/core/actuator/SellStorageActuatorTest.java index 4e4be4f7ec8..076a7db89dd 100644 --- a/src/test/java/org/tron/core/actuator/SellStorageActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/SellStorageActuatorTest.java @@ -9,7 +9,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -31,7 +31,7 @@ public class SellStorageActuatorTest { private static Manager dbManager; private static final String dbPath = "output_sell_storage_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String OWNER_ADDRESS; private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; @@ -39,7 +39,7 @@ public class SellStorageActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; @@ -151,11 +151,11 @@ public void testSellStorage() { dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); // TODO: more precise - Assert.assertEquals(owner.getBalance(), 9999999999999496L); + Assert.assertEquals(owner.getBalance(), initBalance); Assert.assertEquals(0, owner.getStorageLimit()); Assert.assertEquals(currentReserved, dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); - Assert.assertEquals(100000000000504L, + Assert.assertEquals(100000000000000L, dbManager.getDynamicPropertiesStore().getTotalStoragePool()); } catch (ContractValidateException e) { logger.info(e.getMessage()); @@ -213,11 +213,11 @@ public void testSellStorage2() { Assert.assertEquals(ret1.getInstance().getRet(), code.SUCESS); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(owner.getBalance(), 9998999999999882L); + Assert.assertEquals(owner.getBalance(), initBalance - 1_000_000_000_000L); Assert.assertEquals(1360781717L, owner.getStorageLimit()); Assert.assertEquals(currentReserved - 1360781717L, dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); - Assert.assertEquals(101000000000118L, + Assert.assertEquals(101000000000000L, dbManager.getDynamicPropertiesStore().getTotalStoragePool()); sellStorageActuator2.validate(); @@ -225,14 +225,14 @@ public void testSellStorage2() { Assert.assertEquals(ret2.getInstance().getRet(), code.SUCESS); owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(owner.getBalance(), 9999999999999288L); + Assert.assertEquals(owner.getBalance(), initBalance); Assert.assertEquals(0, owner.getStorageLimit()); long tax = 0L; Assert.assertEquals(tax, dbManager.getDynamicPropertiesStore().getTotalStorageTax()); Assert.assertEquals(currentReserved, dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); - Assert.assertEquals(100000000000712L, + Assert.assertEquals(100000000000000L, dbManager.getDynamicPropertiesStore().getTotalStoragePool()); } catch (ContractValidateException e) { @@ -242,8 +242,88 @@ public void testSellStorage2() { } } +// @Test +// public void testSellStorageTax() { +// long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); +// long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); +// Assert.assertEquals(currentPool, 100_000_000_000000L); +// Assert.assertEquals(currentReserved, 128L * 1024 * 1024 * 1024); +// +// long quant = 2_000_000_000_000L; // 2 million trx +// BuyStorageActuator buyStorageactuator = new BuyStorageActuator( +// getBuyContract(OWNER_ADDRESS, quant), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// buyStorageactuator.validate(); +// buyStorageactuator.execute(ret); +// Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); +// AccountCapsule owner = +// dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); +// +// Assert.assertEquals(owner.getBalance(), initBalance - quant +// - ChainConstant.TRANSFER_FEE); +// Assert.assertEquals(2694881440L, owner.getStorageLimit()); +// Assert.assertEquals(currentReserved - 2694881440L, +// dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); +// Assert.assertEquals(currentPool + quant, +// dbManager.getDynamicPropertiesStore().getTotalStoragePool()); +// } catch (ContractValidateException e) { +// Assert.assertFalse(e instanceof ContractValidateException); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// dbManager.getDynamicPropertiesStore() +// .saveLatestBlockHeaderTimestamp(365 * 24 * 3600 * 1000L); +// long bytes = 2694881440L - 269488144L; +// SellStorageActuator sellStorageActuator = new SellStorageActuator( +// getContract(OWNER_ADDRESS, bytes), dbManager); +// TransactionResultCapsule ret2 = new TransactionResultCapsule(); +// try { +// sellStorageActuator.validate(); +// sellStorageActuator.execute(ret); +// Assert.assertEquals(ret2.getInstance().getRet(), code.SUCESS); +// AccountCapsule owner = +// dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); +// +// Assert.assertEquals(owner.getBalance(), 9999796407185160L); +// Assert.assertEquals(0, owner.getStorageLimit()); +// long tax = 10_000_000_000_000_000L + 100_000_000_000_000L +// - 9999796407185160L - 100000000000550L; // == 203592814290L +// Assert.assertEquals(currentReserved, +// dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); +// Assert.assertEquals(100000000000550L, +// dbManager.getDynamicPropertiesStore().getTotalStoragePool()); +// Assert.assertEquals(tax, +// dbManager.getDynamicPropertiesStore().getTotalStorageTax()); +// } catch (ContractValidateException e) { +// Assert.assertFalse(e instanceof ContractValidateException); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } + + @Test + public void sellLessThanZero() { + long bytes = -1_000_000_000L; + SellStorageActuator actuator = new SellStorageActuator( + getContract(OWNER_ADDRESS, bytes), dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + Assert.fail("cannot run here."); + + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("bytes must be positive", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + @Test - public void testSellStorageTax() { + public void sellLessThan1Trx() { long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); Assert.assertEquals(currentPool, 100_000_000_000000L); @@ -273,57 +353,25 @@ public void testSellStorageTax() { Assert.assertFalse(e instanceof ContractExeException); } - dbManager.getDynamicPropertiesStore() - .saveLatestBlockHeaderTimestamp(365 * 24 * 3600 * 1000L); - long bytes = 2694881440L - 269488144L; + long bytes = 1200L; SellStorageActuator sellStorageActuator = new SellStorageActuator( getContract(OWNER_ADDRESS, bytes), dbManager); TransactionResultCapsule ret2 = new TransactionResultCapsule(); try { sellStorageActuator.validate(); - sellStorageActuator.execute(ret); - Assert.assertEquals(ret2.getInstance().getRet(), code.SUCESS); - AccountCapsule owner = - dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); - - Assert.assertEquals(owner.getBalance(), 9999796407185160L); - Assert.assertEquals(0, owner.getStorageLimit()); - long tax = 10_000_000_000_000_000L + 100_000_000_000_000L - - 9999796407185160L - 100000000000550L; // == 203592814290L - Assert.assertEquals(currentReserved, - dbManager.getDynamicPropertiesStore().getTotalStorageReserved()); - Assert.assertEquals(100000000000550L, - dbManager.getDynamicPropertiesStore().getTotalStoragePool()); - Assert.assertEquals(tax, - dbManager.getDynamicPropertiesStore().getTotalStorageTax()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); - } - } - - @Test - public void sellLessThanZero() { - long bytes = -1_000_000_000L; - SellStorageActuator actuator = new SellStorageActuator( - getContract(OWNER_ADDRESS, bytes), dbManager); - TransactionResultCapsule ret = new TransactionResultCapsule(); - try { - actuator.validate(); - actuator.execute(ret); + sellStorageActuator.execute(ret2); Assert.fail("cannot run here."); - } catch (ContractValidateException e) { Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("bytes must be positive", e.getMessage()); + Assert.assertEquals("quantity must be larger than 1TRX,current quantity[900000]", + e.getMessage()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); } } @Test - public void buyMoreThanLimit() { + public void sellMoreThanLimit() { long currentPool = dbManager.getDynamicPropertiesStore().getTotalStoragePool(); long currentReserved = dbManager.getDynamicPropertiesStore().getTotalStorageReserved(); Assert.assertEquals(currentPool, 100_000_000_000000L); @@ -353,19 +401,17 @@ public void buyMoreThanLimit() { Assert.assertFalse(e instanceof ContractExeException); } - dbManager.getDynamicPropertiesStore() - .saveLatestBlockHeaderTimestamp(365 * 24 * 3600 * 1000L); - long bytes = 2694881440L - 269488143L; + long bytes = 2694881441L; SellStorageActuator sellStorageActuator = new SellStorageActuator( getContract(OWNER_ADDRESS, bytes), dbManager); TransactionResultCapsule ret2 = new TransactionResultCapsule(); try { sellStorageActuator.validate(); - sellStorageActuator.execute(ret); + sellStorageActuator.execute(ret2); Assert.fail("cannot run here."); } catch (ContractValidateException e) { Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("bytes must be less than currentUnusedStorage minus tax", + Assert.assertEquals("bytes must be less than currentUnusedStorage[2694881440]", e.getMessage()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); diff --git a/src/test/java/org/tron/core/actuator/SetAccountIdActuatorTest.java b/src/test/java/org/tron/core/actuator/SetAccountIdActuatorTest.java index 511435b0ddf..f129f1bd265 100644 --- a/src/test/java/org/tron/core/actuator/SetAccountIdActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/SetAccountIdActuatorTest.java @@ -9,7 +9,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -28,7 +28,7 @@ @Slf4j public class SetAccountIdActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_setaccountid_test"; private static final String ACCOUNT_NAME = "ownertest"; @@ -39,7 +39,7 @@ public class SetAccountIdActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ADDRESS_1 = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/src/test/java/org/tron/core/actuator/TransferActuatorTest.java b/src/test/java/org/tron/core/actuator/TransferActuatorTest.java index 32d4420be6f..b55309b5650 100755 --- a/src/test/java/org/tron/core/actuator/TransferActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/TransferActuatorTest.java @@ -12,7 +12,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -34,7 +34,7 @@ public class TransferActuatorTest { private static Manager dbManager; private static final String dbPath = "output_transfer_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String OWNER_ADDRESS; private static final String TO_ADDRESS; private static final long AMOUNT = 100; @@ -48,7 +48,7 @@ public class TransferActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; TO_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ACCOUNT_INVALID = diff --git a/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java b/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java index 4a99435b474..94b445ec1b2 100755 --- a/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java @@ -26,7 +26,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -47,7 +47,7 @@ @Slf4j public class TransferAssetActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static Any contract; private static final String dbPath = "output_transferasset_test"; @@ -72,7 +72,7 @@ public class TransferAssetActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; TO_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a146a"; NOT_EXIT_ADDRESS = Wallet.getAddressPreFixString() + "B56446E617E924805E4D6CA021D341FEF6E2013B"; @@ -583,7 +583,6 @@ public void assetNameTest() { Assert.assertFalse(e instanceof ContractExeException); } - //Too long name, throw exception. Max long is 32. String assetName = "testname0123456789abcdefghijgklmo"; // actuator = new TransferAssetActuator(getContract(100L, assetName), diff --git a/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java b/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java index dff94f464d7..dda5e00fce9 100644 --- a/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java @@ -9,7 +9,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; @@ -33,7 +33,7 @@ public class UnfreezeAssetActuatorTest { private static Manager dbManager; private static final String dbPath = "output_unfreeze_asset_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String OWNER_ADDRESS; private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; @@ -43,7 +43,7 @@ public class UnfreezeAssetActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; @@ -105,8 +105,8 @@ public void testUnfreezeAsset() { .setExpireTime(now) .build(); Frozen newFrozen1 = Frozen.newBuilder() - .setFrozenBalance(frozenBalance+1) - .setExpireTime(now+600000) + .setFrozenBalance(frozenBalance + 1) + .setExpireTime(now + 600000) .build(); account = account.toBuilder().addFrozenSupply(newFrozen0).addFrozenSupply(newFrozen1).build(); AccountCapsule accountCapsule = new AccountCapsule(account); diff --git a/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java b/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java index 364971b49f7..970d049b386 100644 --- a/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java @@ -13,7 +13,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -36,7 +36,7 @@ public class UnfreezeBalanceActuatorTest { private static Manager dbManager; private static final String dbPath = "output_unfreeze_balance_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String OWNER_ADDRESS; private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; @@ -45,7 +45,7 @@ public class UnfreezeBalanceActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; diff --git a/src/test/java/org/tron/core/actuator/UpdateAccountActuatorTest.java b/src/test/java/org/tron/core/actuator/UpdateAccountActuatorTest.java index dad76eabe2a..a2749787171 100755 --- a/src/test/java/org/tron/core/actuator/UpdateAccountActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/UpdateAccountActuatorTest.java @@ -9,7 +9,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -28,7 +28,7 @@ @Slf4j public class UpdateAccountActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_updateaccount_test"; private static final String ACCOUNT_NAME = "ownerTest"; @@ -39,7 +39,7 @@ public class UpdateAccountActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ADDRESS_1 = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/src/test/java/org/tron/core/actuator/VoteWitnessActuatorTest.java b/src/test/java/org/tron/core/actuator/VoteWitnessActuatorTest.java index d836136f462..5da02787d3b 100644 --- a/src/test/java/org/tron/core/actuator/VoteWitnessActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/VoteWitnessActuatorTest.java @@ -11,7 +11,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; @@ -35,7 +35,7 @@ @Slf4j public class VoteWitnessActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static WitnessController witnessController; private static final String dbPath = "output_VoteWitness_test"; @@ -51,7 +51,7 @@ public class VoteWitnessActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; WITNESS_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; WITNESS_ADDRESS_NOACCOUNT = @@ -156,8 +156,9 @@ public void voteWitness() { .get(0).getVoteAddress().toByteArray()); Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); - Assert.assertEquals(10+1, witnessCapsule.getVoteCount()); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + Assert.assertEquals(10 + 1, witnessCapsule.getVoteCount()); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -182,7 +183,8 @@ public void InvalidAddress() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("Invalid address", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -210,7 +212,8 @@ public void noAccount() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("Account[" + WITNESS_ADDRESS_NOACCOUNT + "] not exists", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -246,7 +249,8 @@ public void noWitness() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("Witness[" + WITNESS_ADDRESS_NOACCOUNT + "] not exists", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -280,7 +284,8 @@ public void invalideVoteAddress() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("Invalid vote address!", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -310,7 +315,8 @@ public void voteCountTest() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("vote count must be greater than 0", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -328,7 +334,8 @@ public void voteCountTest() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("vote count must be greater than 0", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -358,7 +365,8 @@ public void voteCountsTest() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("VoteNumber must more than 0", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -374,7 +382,8 @@ public void voteCountsTest() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("VoteNumber more than maxVoteNumber 30", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -401,8 +410,9 @@ public void vote1WitnssOneMoreTiems() { actuator.execute(ret); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); - Assert.assertEquals(10+30, witnessCapsule.getVoteCount()); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + Assert.assertEquals(10 + 30, witnessCapsule.getVoteCount()); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -428,7 +438,8 @@ public void noOwnerAccount() { Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("Account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -450,7 +461,8 @@ public void balanceNotSufficient() { dbManager.getAccountStore() .put(balanceNotSufficientCapsule.getAddress().toByteArray(), balanceNotSufficientCapsule); VoteWitnessActuator actuator = - new VoteWitnessActuator(getContract(OWNER_ADDRESS_BALANCENOTSUFFICIENT, WITNESS_ADDRESS, 1L), + new VoteWitnessActuator( + getContract(OWNER_ADDRESS_BALANCENOTSUFFICIENT, WITNESS_ADDRESS, 1L), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); try { @@ -466,7 +478,8 @@ public void balanceNotSufficient() { .assertEquals("The total number of votes[" + 1000000 + "] is greater than the tronPower[" + balanceNotSufficientCapsule.getTronPower() + "]", e.getMessage()); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(10, witnessCapsule.getVoteCount()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -503,7 +516,8 @@ public void voteWitnessTwice() { Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); witnessController.updateWitness(); - WitnessCapsule witnessCapsule = witnessController.getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); + WitnessCapsule witnessCapsule = witnessController + .getWitnesseByAddress(StringUtil.hexString2ByteString(WITNESS_ADDRESS)); Assert.assertEquals(13, witnessCapsule.getVoteCount()); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); diff --git a/src/test/java/org/tron/core/actuator/WithdrawBalanceActuatorTest.java b/src/test/java/org/tron/core/actuator/WithdrawBalanceActuatorTest.java index fc7fea5e8aa..cbc9cd13c58 100644 --- a/src/test/java/org/tron/core/actuator/WithdrawBalanceActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/WithdrawBalanceActuatorTest.java @@ -11,7 +11,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; @@ -36,7 +36,7 @@ public class WithdrawBalanceActuatorTest { private static Manager dbManager; private static final String dbPath = "output_withdraw_balance_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final String OWNER_ADDRESS; private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; @@ -45,7 +45,7 @@ public class WithdrawBalanceActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; diff --git a/src/test/java/org/tron/core/actuator/WitnessCreateActuatorTest.java b/src/test/java/org/tron/core/actuator/WitnessCreateActuatorTest.java index ff4360936b7..991ee9dd167 100644 --- a/src/test/java/org/tron/core/actuator/WitnessCreateActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/WitnessCreateActuatorTest.java @@ -11,7 +11,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -32,7 +32,7 @@ public class WitnessCreateActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_WitnessCreate_test"; private static final String ACCOUNT_NAME_FIRST = "ownerF"; @@ -46,7 +46,7 @@ public class WitnessCreateActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/src/test/java/org/tron/core/actuator/WitnessUpdateActuatorTest.java b/src/test/java/org/tron/core/actuator/WitnessUpdateActuatorTest.java index 033dcbe85ad..b0b5c2dbe36 100644 --- a/src/test/java/org/tron/core/actuator/WitnessUpdateActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/WitnessUpdateActuatorTest.java @@ -11,7 +11,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -31,7 +31,7 @@ @Slf4j public class WitnessUpdateActuatorTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static final String dbPath = "output_WitnessUpdate_test"; private static final String OWNER_ADDRESS; @@ -45,7 +45,7 @@ public class WitnessUpdateActuatorTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_NOTEXIST = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; @@ -68,10 +68,10 @@ public static void init() { public void createCapsule() { // address in accountStore and witnessStore AccountCapsule accountCapsule = - new AccountCapsule( - ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), - ByteString.copyFromUtf8(OWNER_ADDRESS_ACCOUNT_NAME), - Protocol.AccountType.Normal); + new AccountCapsule( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), + ByteString.copyFromUtf8(OWNER_ADDRESS_ACCOUNT_NAME), + Protocol.AccountType.Normal); dbManager.getAccountStore().put(ByteArray.fromHexString(OWNER_ADDRESS), accountCapsule); WitnessCapsule ownerCapsule = new WitnessCapsule( ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), 10_000_000L, URL); @@ -79,11 +79,12 @@ public void createCapsule() { // address exist in accountStore, but is not witness AccountCapsule accountNotWitnessCapsule = - new AccountCapsule( - ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_NOT_WITNESS)), - ByteString.copyFromUtf8(OWNER_ADDRESS_NOT_WITNESS_ACCOUNT_NAME), - Protocol.AccountType.Normal); - dbManager.getAccountStore().put(ByteArray.fromHexString(OWNER_ADDRESS_NOT_WITNESS), accountNotWitnessCapsule); + new AccountCapsule( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_NOT_WITNESS)), + ByteString.copyFromUtf8(OWNER_ADDRESS_NOT_WITNESS_ACCOUNT_NAME), + Protocol.AccountType.Normal); + dbManager.getAccountStore() + .put(ByteArray.fromHexString(OWNER_ADDRESS_NOT_WITNESS), accountNotWitnessCapsule); dbManager.getWitnessStore().delete(ByteArray.fromHexString(OWNER_ADDRESS_NOT_WITNESS)); // address does not exist in accountStore @@ -221,8 +222,8 @@ public void InvalidUrlTest() { } /** - * use AccountStore not exists Address createWitness,result is failed,exception is - * "Witness does not exist" + * use AccountStore not exists Address createWitness,result is failed,exception is "Witness does + * not exist" */ @Test public void notExistWitness() { @@ -247,7 +248,7 @@ public void notExistWitness() { @Test public void notExistAccount() { WitnessUpdateActuator actuator = new WitnessUpdateActuator( - getContract(OWNER_ADDRESS_NOTEXIST, URL), dbManager); + getContract(OWNER_ADDRESS_NOTEXIST, URL), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); try { actuator.validate(); diff --git a/src/test/java/org/tron/core/capsule/ExchangeCapsuleTest.java b/src/test/java/org/tron/core/capsule/ExchangeCapsuleTest.java new file mode 100644 index 00000000000..11ed3007745 --- /dev/null +++ b/src/test/java/org/tron/core/capsule/ExchangeCapsuleTest.java @@ -0,0 +1,125 @@ +package org.tron.core.capsule; + +import com.google.protobuf.ByteString; +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.db.StorageMarket; +import org.tron.core.exception.ItemNotFoundException; + +@Slf4j +public class ExchangeCapsuleTest { + + private static Manager dbManager; + private static StorageMarket storageMarket; + private static final String dbPath = "output_buy_storage_test"; + private static AnnotationConfigApplicationContext context; + private static final String OWNER_ADDRESS; + private static final String OWNER_ADDRESS_INVALID = "aaaa"; + private static final String OWNER_ACCOUNT_INVALID; + private static final long initBalance = 10_000_000_000_000_000L; + + static { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new AnnotationConfigApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + OWNER_ACCOUNT_INVALID = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + storageMarket = new StorageMarket(dbManager); + // Args.setParam(new String[]{"--output-directory", dbPath}, + // "config-junit.conf"); + // dbManager = new Manager(); + // dbManager.init(); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + /** + * create temp Capsule test need. + */ + @Before + public void createExchangeCapsule() { + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(0); + + long now = dbManager.getHeadBlockTimeStamp(); + ExchangeCapsule exchangeCapsulee = + new ExchangeCapsule( + ByteString.copyFromUtf8("owner"), + 1, + now, + "abc".getBytes(), + "def".getBytes()); + + dbManager.getExchangeStore().put(exchangeCapsulee.createDbKey(), exchangeCapsulee); + + } + + @Test + public void testExchange() { + long sellBalance = 100000000L; + long buyBalance = 100000000L; + + byte[] key = ByteArray.fromLong(1); + + ExchangeCapsule exchangeCapsule; + try { + exchangeCapsule = dbManager.getExchangeStore().get(key); + exchangeCapsule.setBalance(sellBalance, buyBalance); + + long sellQuant = 1_000_000L; + byte[] sellID = "abc".getBytes(); + + long result = exchangeCapsule.transaction(sellID, sellQuant); + Assert.assertEquals(990_099L, result); + sellBalance += sellQuant; + Assert.assertEquals(sellBalance, exchangeCapsule.getFirstTokenBalance()); + buyBalance -= result; + Assert.assertEquals(buyBalance, exchangeCapsule.getSecondTokenBalance()); + + sellQuant = 9_000_000L; + long result2 = exchangeCapsule.transaction(sellID, sellQuant); + Assert.assertEquals(9090909L, result + result2); + sellBalance += sellQuant; + Assert.assertEquals(sellBalance, exchangeCapsule.getFirstTokenBalance()); + buyBalance -= result2; + Assert.assertEquals(buyBalance, exchangeCapsule.getSecondTokenBalance()); + + } catch (ItemNotFoundException e) { + Assert.fail(); + } + + } + +} diff --git a/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java b/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java new file mode 100644 index 00000000000..c9839b8dc1a --- /dev/null +++ b/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java @@ -0,0 +1,135 @@ +package org.tron.core.capsule.utils; + +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; + +@Slf4j +public class ExchangeProcessorTest { + + private static ExchangeProcessor processor; + private static final String dbPath = "output_buy_exchange_processor_test"; + private static AnnotationConfigApplicationContext context; + private static final String OWNER_ADDRESS; + private static final String OWNER_ADDRESS_INVALID = "aaaa"; + private static final String OWNER_ACCOUNT_INVALID; + private static final long initBalance = 10_000_000_000_000_000L; + + static { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new AnnotationConfigApplicationContext(DefaultConfig.class); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + OWNER_ACCOUNT_INVALID = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + long supply = 1_000_000_000_000_000_000L; + processor = new ExchangeProcessor(supply); + // Args.setParam(new String[]{"--output-directory", dbPath}, + // "config-junit.conf"); + // dbManager = new Manager(); + // dbManager.init(); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + @Test + public void testExchange() { + long sellBalance = 100_000_000_000000L; + long buyBalance = 128L * 1024 * 1024 * 1024; + long sellQuant = 2_000_000_000_000L; // 2 million trx + + long result = processor.exchange(sellBalance, buyBalance, sellQuant); + + Assert.assertEquals(2694881440L, result); + } + + @Test + public void testExchange2() { + long sellBalance = 100_000_000_000000L; + long buyBalance = 128L * 1024 * 1024 * 1024; + long sellQuant = 1_000_000_000_000L; // 2 million trx + + long result = processor.exchange(sellBalance, buyBalance, sellQuant); + Assert.assertEquals(1360781717L, result); + + sellBalance += sellQuant; + buyBalance -= result; + + long result2 = processor.exchange(sellBalance, buyBalance, sellQuant); + Assert.assertEquals(2694881440L - 1360781717L, result2); + + } + + + @Test + public void testSellAndBuy() { + long sellBalance = 100_000_000_000000L; + long buyBalance = 128L * 1024 * 1024 * 1024; + long sellQuant = 2_000_000_000_000L; // 2 million trx + + long result = processor.exchange(sellBalance, buyBalance, sellQuant); + Assert.assertEquals(2694881440L, result); + + sellBalance += sellQuant; + buyBalance -= result; + + long result2 = processor.exchange(buyBalance, sellBalance, result); + Assert.assertEquals(1999999999542L, result2); + + } + + @Test + public void testSellAndBuy2() { + long sellBalance = 100_000_000_000000L; + long buyBalance = 128L * 1024 * 1024 * 1024; + long sellQuant = 2_000_000_000_000L; // 2 million trx + + long result = processor.exchange(sellBalance, buyBalance, sellQuant); + Assert.assertEquals(2694881440L, result); + + sellBalance += sellQuant; + buyBalance -= result; + + long quant1 = 2694881440L - 1360781717L; + long quant2 = 1360781717L; + + long result1 = processor.exchange(buyBalance, sellBalance, quant1); + Assert.assertEquals(999999999927L, result1); + + buyBalance += quant1; + sellBalance -= result1; + + long result2 = processor.exchange(buyBalance, sellBalance, quant2); + Assert.assertEquals(999999999587L, result2); + + } + + +} diff --git a/src/test/java/org/tron/core/db/AccountIdIndexStoreTest.java b/src/test/java/org/tron/core/db/AccountIdIndexStoreTest.java index d338597b977..9c1996b85a3 100644 --- a/src/test/java/org/tron/core/db/AccountIdIndexStoreTest.java +++ b/src/test/java/org/tron/core/db/AccountIdIndexStoreTest.java @@ -7,7 +7,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.Wallet; @@ -19,7 +19,7 @@ public class AccountIdIndexStoreTest { private static String dbPath = "output_AccountIndexStore_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static AccountIdIndexStore accountIdIndexStore; private static final byte[] ACCOUNT_ADDRESS_ONE = randomBytes(16); private static final byte[] ACCOUNT_ADDRESS_TWO = randomBytes(16); @@ -38,7 +38,7 @@ public class AccountIdIndexStoreTest { static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @AfterClass diff --git a/src/test/java/org/tron/core/db/AccountStoreTest.java b/src/test/java/org/tron/core/db/AccountStoreTest.java index abbf8d40f53..d58fa06d8c4 100755 --- a/src/test/java/org/tron/core/db/AccountStoreTest.java +++ b/src/test/java/org/tron/core/db/AccountStoreTest.java @@ -8,7 +8,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -22,7 +22,7 @@ public class AccountStoreTest { private static String dbPath = "output_AccountStore_test"; private static String dbDirectory = "db_AccountStore_test"; private static String indexDirectory = "index_AccountStore_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static AccountStore accountStore; private static final byte[] data = TransactionStoreTest.randomBytes(32); private static byte[] address = TransactionStoreTest.randomBytes(32); @@ -37,7 +37,7 @@ public class AccountStoreTest { }, Constant.TEST_CONF ); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @AfterClass diff --git a/src/test/java/org/tron/core/db/BlockStoreTest.java b/src/test/java/org/tron/core/db/BlockStoreTest.java index bd9199e3211..68408809063 100644 --- a/src/test/java/org/tron/core/db/BlockStoreTest.java +++ b/src/test/java/org/tron/core/db/BlockStoreTest.java @@ -5,7 +5,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.config.DefaultConfig; @@ -16,12 +16,12 @@ public class BlockStoreTest { private static final String dbPath = "output-blockStore-test"; BlockStore blockStore; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @Before diff --git a/src/test/java/org/tron/core/db/KhaosDatabaseTest.java b/src/test/java/org/tron/core/db/KhaosDatabaseTest.java index 9f371e704ac..abec8fd355a 100644 --- a/src/test/java/org/tron/core/db/KhaosDatabaseTest.java +++ b/src/test/java/org/tron/core/db/KhaosDatabaseTest.java @@ -9,7 +9,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -27,12 +27,12 @@ public class KhaosDatabaseTest { private static final String dbPath = "output-khaosDatabase-test"; private static KhaosDatabase khaosDatabase; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; static { Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @BeforeClass diff --git a/src/test/java/org/tron/core/db/ManagerTest.java b/src/test/java/org/tron/core/db/ManagerTest.java index b655b5ee7d7..35e2d70ee33 100755 --- a/src/test/java/org/tron/core/db/ManagerTest.java +++ b/src/test/java/org/tron/core/db/ManagerTest.java @@ -8,12 +8,10 @@ import java.util.stream.IntStream; import lombok.extern.slf4j.Slf4j; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.crypto.ECKey; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; @@ -36,10 +34,14 @@ import org.tron.core.exception.HeaderNotFound; import org.tron.core.exception.ItemNotFoundException; import org.tron.core.exception.NonCommonBlockException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.core.exception.ReceiptException; import org.tron.core.exception.TaposException; import org.tron.core.exception.TooBigTransactionException; import org.tron.core.exception.TransactionExpirationException; +import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.UnLinkedBlockException; +import org.tron.core.exception.UnsupportVMException; import org.tron.core.exception.ValidateScheduleException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.witness.WitnessController; @@ -51,14 +53,14 @@ public class ManagerTest { private static Manager dbManager; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static BlockCapsule blockCapsule2; private static String dbPath = "output_manager_test"; @Before public void init() { Args.setParam(new String[]{"-d", dbPath, "-w"}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); dbManager = context.getBean(Manager.class); @@ -89,7 +91,7 @@ public void removeDb() { @Test public void setBlockReference() throws ContractExeException, UnLinkedBlockException, ValidateScheduleException, BadBlockException, - ContractValidateException, ValidateSignatureException, BadItemException, ItemNotFoundException, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, DupTransactionException, TaposException, BadNumberBlockException, NonCommonBlockException { + ContractValidateException, ValidateSignatureException, BadItemException, ItemNotFoundException, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, DupTransactionException, TaposException, BadNumberBlockException, NonCommonBlockException, ReceiptException, TransactionTraceException, OutOfSlotTimeException, UnsupportVMException { BlockCapsule blockCapsule = new BlockCapsule( @@ -213,11 +215,11 @@ public void updateWits() { @Test public void fork() throws ValidateSignatureException, ContractValidateException, ContractExeException, - UnLinkedBlockException, ValidateScheduleException, BadItemException, + UnLinkedBlockException, ValidateScheduleException, BadItemException, ReceiptException, ItemNotFoundException, HeaderNotFound, AccountResourceInsufficientException, - TransactionExpirationException, TooBigTransactionException, - DupTransactionException, BadBlockException, - TaposException, BadNumberBlockException, NonCommonBlockException { + TransactionExpirationException, TooBigTransactionException, DupTransactionException, + BadBlockException, TaposException, BadNumberBlockException, NonCommonBlockException, + TransactionTraceException, OutOfSlotTimeException, UnsupportVMException { Args.setParam(new String[]{"--witness"}, Constant.TEST_CONF); long size = dbManager.getBlockStore().size(); System.out.print("block store size:" + size + "\n"); @@ -227,29 +229,34 @@ public void fork() byte[] address = ecKey.getAddress(); WitnessCapsule witnessCapsule = new WitnessCapsule(ByteString.copyFrom(address)); dbManager.addWitness(ByteString.copyFrom(address)); - dbManager.generateBlock(witnessCapsule, System.currentTimeMillis(), privateKey); + dbManager.generateBlock(witnessCapsule, 1533529947843L, privateKey); Map addressToProvateKeys = addTestWitnessAndAccount(); + long num = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber(); BlockCapsule blockCapsule0 = createTestBlockCapsule( + 1533529947843L+3000, num + 1, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); BlockCapsule blockCapsule1 = createTestBlockCapsule( + 1533529947843L+3000, num + 1, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); + dbManager.pushBlock(blockCapsule0); + dbManager.pushBlock(blockCapsule1); + BlockCapsule blockCapsule2 = createTestBlockCapsule( + 1533529947843L +6000, num + 2, blockCapsule1.getBlockId().getByteString(), addressToProvateKeys); - dbManager.pushBlock(blockCapsule0); - dbManager.pushBlock(blockCapsule1); dbManager.pushBlock(blockCapsule2); Assert.assertNotNull(dbManager.getBlockStore().get(blockCapsule1.getBlockId().getBytes())); @@ -277,11 +284,12 @@ public void fork() @Test public void doNotSwitch() throws ValidateSignatureException, ContractValidateException, ContractExeException, - UnLinkedBlockException, ValidateScheduleException, BadItemException, + UnLinkedBlockException, ValidateScheduleException, BadItemException, ReceiptException, ItemNotFoundException, HeaderNotFound, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, DupTransactionException, BadBlockException, - TaposException, BadNumberBlockException, NonCommonBlockException { + TaposException, BadNumberBlockException, NonCommonBlockException, TransactionTraceException, + OutOfSlotTimeException, UnsupportVMException { Args.setParam(new String[]{"--witness"}, Constant.TEST_CONF); long size = dbManager.getBlockStore().size(); System.out.print("block store size:" + size + "\n"); @@ -291,35 +299,40 @@ public void doNotSwitch() byte[] address = ecKey.getAddress(); WitnessCapsule witnessCapsule = new WitnessCapsule(ByteString.copyFrom(address)); dbManager.addWitness(ByteString.copyFrom(address)); - dbManager.generateBlock(witnessCapsule, System.currentTimeMillis(), privateKey); + dbManager.generateBlock(witnessCapsule, 1533529947843L, privateKey); Map addressToProvateKeys = addTestWitnessAndAccount(); long num = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber(); BlockCapsule blockCapsule0 = createTestBlockCapsule( + 1533529947843L + 3000, num + 1, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); BlockCapsule blockCapsule1 = createTestBlockCapsule( + 1533529947843L + 3001, num + 1, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); - BlockCapsule blockCapsule2 = - createTestBlockCapsule( - num + 2, blockCapsule1.getBlockId().getByteString(), addressToProvateKeys); + logger.info("******block0:" + blockCapsule0); logger.info("******block1:" + blockCapsule1); - logger.info("******block2:" + blockCapsule2); dbManager.pushBlock(blockCapsule0); dbManager.pushBlock(blockCapsule1); context.getBean(KhaosDatabase.class).removeBlk(dbManager.getBlockIdByNum(num)); Exception exception = null; + + BlockCapsule blockCapsule2 = + createTestBlockCapsule( + 1533529947843L + 6000, + num + 2, blockCapsule1.getBlockId().getByteString(), addressToProvateKeys); + logger.info("******block2:" + blockCapsule2); try { dbManager.pushBlock(blockCapsule2); } catch (NonCommonBlockException e) { @@ -337,19 +350,22 @@ public void doNotSwitch() } BlockCapsule blockCapsule3 = - createTestBlockCapsule( + createTestBlockCapsule(1533529947843L + 9000, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1, - dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); + dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), + addressToProvateKeys); logger.info("******block3:" + blockCapsule3); dbManager.pushBlock(blockCapsule3); Assert.assertEquals(blockCapsule3.getBlockId(), dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash()); Assert.assertEquals(blockCapsule3.getBlockId(), - dbManager.getBlockStore().get(dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getBytes()).getBlockId()); + dbManager.getBlockStore() + .get(dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getBytes()) + .getBlockId()); BlockCapsule blockCapsule4 = - createTestBlockCapsule( + createTestBlockCapsule(1533529947843L + 12000, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1, blockCapsule3.getBlockId().getByteString(), addressToProvateKeys); logger.info("******block4:" + blockCapsule4); @@ -358,17 +374,19 @@ public void doNotSwitch() Assert.assertEquals(blockCapsule4.getBlockId(), dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash()); Assert.assertEquals(blockCapsule4.getBlockId(), - dbManager.getBlockStore().get(dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getBytes()).getBlockId()); + dbManager.getBlockStore() + .get(dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getBytes()) + .getBlockId()); } @Test public void switchBack() throws ValidateSignatureException, ContractValidateException, ContractExeException, - UnLinkedBlockException, ValidateScheduleException, BadItemException, + UnLinkedBlockException, ValidateScheduleException, BadItemException, ReceiptException, ItemNotFoundException, HeaderNotFound, AccountResourceInsufficientException, - TransactionExpirationException, TooBigTransactionException, - DupTransactionException, BadBlockException, - TaposException, BadNumberBlockException, NonCommonBlockException { + TransactionExpirationException, TooBigTransactionException, DupTransactionException, + BadBlockException, TaposException, BadNumberBlockException, NonCommonBlockException, + TransactionTraceException, OutOfSlotTimeException, UnsupportVMException { Args.setParam(new String[]{"--witness"}, Constant.TEST_CONF); long size = dbManager.getBlockStore().size(); System.out.print("block store size:" + size + "\n"); @@ -378,30 +396,34 @@ public void switchBack() byte[] address = ecKey.getAddress(); WitnessCapsule witnessCapsule = new WitnessCapsule(ByteString.copyFrom(address)); dbManager.addWitness(ByteString.copyFrom(address)); - dbManager.generateBlock(witnessCapsule, System.currentTimeMillis(), privateKey); + dbManager.generateBlock(witnessCapsule, 1533529947843L, privateKey); Map addressToProvateKeys = addTestWitnessAndAccount(); long num = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber(); BlockCapsule blockCapsule0 = createTestBlockCapsule( + 1533529947843L +3000, num + 1, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); BlockCapsule blockCapsule1 = createTestBlockCapsule( + 1533529947843L +3000, num + 1, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); - BlockCapsule blockCapsule2 = - createTestBlockCapsuleError( - num + 2, blockCapsule1.getBlockId().getByteString(), addressToProvateKeys); dbManager.pushBlock(blockCapsule0); dbManager.pushBlock(blockCapsule1); try { + BlockCapsule blockCapsule2 = + createTestBlockCapsuleError( + 1533529947843L +6000, + num + 2, blockCapsule1.getBlockId().getByteString(), addressToProvateKeys); + dbManager.pushBlock(blockCapsule2); } catch (ValidateScheduleException e) { logger.info("the fork chain has error block"); @@ -413,6 +435,7 @@ public void switchBack() BlockCapsule blockCapsule3 = createTestBlockCapsule( + 1533529947843L +9000, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1, blockCapsule0.getBlockId().getByteString(), addressToProvateKeys); dbManager.pushBlock(blockCapsule3); @@ -420,10 +443,13 @@ public void switchBack() Assert.assertEquals(blockCapsule3.getBlockId(), dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash()); Assert.assertEquals(blockCapsule3.getBlockId(), - dbManager.getBlockStore().get(dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getBytes()).getBlockId()); + dbManager.getBlockStore() + .get(dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getBytes()) + .getBlockId()); BlockCapsule blockCapsule4 = createTestBlockCapsule( + 1533529947843L +12000, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1, blockCapsule3.getBlockId().getByteString(), addressToProvateKeys); dbManager.pushBlock(blockCapsule4); @@ -431,7 +457,9 @@ public void switchBack() Assert.assertEquals(blockCapsule4.getBlockId(), dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash()); Assert.assertEquals(blockCapsule4.getBlockId(), - dbManager.getBlockStore().get(dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getBytes()).getBlockId()); + dbManager.getBlockStore() + .get(dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getBytes()) + .getBlockId()); } private Map addTestWitnessAndAccount() { @@ -455,14 +483,18 @@ private Map addTestWitnessAndAccount() { }) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } - private BlockCapsule createTestBlockCapsule( long number, ByteString hash, Map addressToProvateKeys) { long time = System.currentTimeMillis(); + return createTestBlockCapsule(time,number,hash,addressToProvateKeys); + } + private BlockCapsule createTestBlockCapsule(long time , + long number, ByteString hash, Map addressToProvateKeys) { WitnessController witnessController = dbManager.getWitnessController(); ByteString witnessAddress = witnessController.getScheduledWitness(witnessController.getSlotAtTime(time)); - BlockCapsule blockCapsule = new BlockCapsule(number, Sha256Hash.wrap(hash), time, witnessAddress); + BlockCapsule blockCapsule = new BlockCapsule(number, Sha256Hash.wrap(hash), time, + witnessAddress); blockCapsule.generatedByMyself = true; blockCapsule.setMerkleRoot(); blockCapsule.sign(ByteArray.fromHexString(addressToProvateKeys.get(witnessAddress))); @@ -472,10 +504,15 @@ private BlockCapsule createTestBlockCapsule( private BlockCapsule createTestBlockCapsuleError( long number, ByteString hash, Map addressToProvateKeys) { long time = System.currentTimeMillis(); + return createTestBlockCapsuleError(time,number,hash,addressToProvateKeys); + } + private BlockCapsule createTestBlockCapsuleError(long time , + long number, ByteString hash, Map addressToProvateKeys) { WitnessController witnessController = dbManager.getWitnessController(); ByteString witnessAddress = witnessController.getScheduledWitness(witnessController.getSlotAtTime(time)); - BlockCapsule blockCapsule = new BlockCapsule(number, Sha256Hash.wrap(hash), time, ByteString.copyFromUtf8("onlyTest")); + BlockCapsule blockCapsule = new BlockCapsule(number, Sha256Hash.wrap(hash), time, + ByteString.copyFromUtf8("onlyTest")); blockCapsule.generatedByMyself = true; blockCapsule.setMerkleRoot(); blockCapsule.sign(ByteArray.fromHexString(addressToProvateKeys.get(witnessAddress))); diff --git a/src/test/java/org/tron/core/db/TransactionHistoryTest.java b/src/test/java/org/tron/core/db/TransactionHistoryTest.java index 26a040c5ac5..49e683cee41 100644 --- a/src/test/java/org/tron/core/db/TransactionHistoryTest.java +++ b/src/test/java/org/tron/core/db/TransactionHistoryTest.java @@ -5,7 +5,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -19,7 +19,7 @@ public class TransactionHistoryTest { private static String dbPath = "output_TransactionHistoryStore_test"; private static String dbDirectory = "db_TransactionHistoryStore_test"; private static String indexDirectory = "index_TransactionHistoryStore_test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static TransactionHistoryStore transactionHistoryStore; private static final byte[] transactionId = TransactionStoreTest.randomBytes(32); @@ -32,7 +32,7 @@ public class TransactionHistoryTest { }, Constant.TEST_CONF ); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @AfterClass diff --git a/src/test/java/org/tron/core/db/TransactionStoreTest.java b/src/test/java/org/tron/core/db/TransactionStoreTest.java index 2800b5b4a71..c444cfba5d5 100644 --- a/src/test/java/org/tron/core/db/TransactionStoreTest.java +++ b/src/test/java/org/tron/core/db/TransactionStoreTest.java @@ -7,7 +7,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; @@ -30,7 +30,7 @@ public class TransactionStoreTest { private static String dbDirectory = "db_TransactionStore_test"; private static String indexDirectory = "index_TransactionStore_test"; private static TransactionStore transactionStore; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static final byte[] key1 = TransactionStoreTest.randomBytes(21); private static Manager dbManager; private static final byte[] key2 = TransactionStoreTest.randomBytes(21); @@ -57,7 +57,7 @@ public class TransactionStoreTest { }, Constant.TEST_CONF ); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } /** diff --git a/src/test/java/org/tron/core/db/TransactionTraceTest.java b/src/test/java/org/tron/core/db/TransactionTraceTest.java new file mode 100644 index 00000000000..105a380161e --- /dev/null +++ b/src/test/java/org/tron/core/db/TransactionTraceTest.java @@ -0,0 +1,272 @@ +/* + * 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.core.db; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.runtime.Runtime; +import org.tron.common.runtime.vm.program.invoke.ProgramInvokeFactoryImpl; +import org.tron.common.storage.DepositImpl; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ContractCapsule; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.OutOfSlotTimeException; +import org.tron.protos.Contract.CreateSmartContract; +import org.tron.protos.Contract.TriggerSmartContract; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.Account.AccountResource; +import org.tron.protos.Protocol.Account.Frozen; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.SmartContract; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; +import org.tron.protos.Protocol.Transaction.raw; + +@RunWith(Parameterized.class) +public class TransactionTraceTest { + + public static final long totalBalance = 1000_0000_000_000L; + public static final int deployStorageDelta = 680000; + private static String dbPath = "output_TransactionTrace_test"; + private static String dbDirectory = "db_TransactionTrace_test"; + private static String indexDirectory = "index_TransactionTrace_test"; + private static TronApplicationContext context; + private static Manager dbManager; + private static StorageMarket storageMarket; + private static ByteString ownerAddress = ByteString.copyFrom(ByteArray.fromInt(1)); + private static ByteString contractAddress = ByteString.copyFrom(ByteArray.fromInt(2)); + + private long energyUsage; + private long storageUsage; + /* + * DeployContract tracetestContract [{"constant":false,"inputs":[{"name":"accountId","type":"uint256"}],"name":"getVoters","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"voters","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"uint256"}],"name":"addVoters","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}] 608060405234801561001057600080fd5b5060015b620186a0811015610038576000818152602081905260409020819055600a01610014565b5061010b806100486000396000f30060806040526004361060525763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166386b646f281146057578063da58c7d914607e578063eb91a5ff146093575b600080fd5b348015606257600080fd5b50606c60043560aa565b60408051918252519081900360200190f35b348015608957600080fd5b50606c60043560bc565b348015609e57600080fd5b5060a860043560ce565b005b60009081526020819052604090205490565b60006020819052908152604090205481565b6000818152602081905260409020555600a165627a7a72305820f9935f89890e51bcf3ea98fa4841c91ac5957a197d99eeb7879a775b30ee9a2d0029 1000000000000 100 + * */ + private String trxByte = "0a80050a0231ca220844c8b91d4d5d7e5f40e0f19aecd32c5ad904081e12d4040a30747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e437265617465536d617274436f6e7472616374129f040a15411bd09e9a1bf949b3d08b56f85ad3e3e3905763c81285040a15411bd09e9a1bf949b3d08b56f85ad3e3e3905763c81a80010a301a09676574566f74657273221412096163636f756e7449641a0775696e743235362a091a0775696e74323536300240030a2410011a06766f7465727322091a0775696e743235362a091a0775696e74323536300240020a201a09616464566f74657273220f1204766f74651a0775696e74323536300240030a043001400322d302608060405234801561001057600080fd5b5060015b620186a0811015610038576000818152602081905260409020819055600a01610014565b5061010b806100486000396000f30060806040526004361060525763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166386b646f281146057578063da58c7d914607e578063eb91a5ff146093575b600080fd5b348015606257600080fd5b50606c60043560aa565b60408051918252519081900360200190f35b348015608957600080fd5b50606c60043560bc565b348015609e57600080fd5b5060a860043560ce565b005b60009081526020819052604090205490565b60006020819052908152604090205481565b6000818152602081905260409020555600a165627a7a72305820f9935f89890e51bcf3ea98fa4841c91ac5957a197d99eeb7879a775b30ee9a2d002930643a11747261636574657374436f6e747261637470d7b297ecd32c900180a094a58d1d124165e6fe033d9ee0369c298f7ef263eab2ebf33a63e20c6fad38cf64e0f0a4f8fa0c562e6beafbd43a841ff9058e7a09c88381636db68a9ce17f4529d66f00111e00"; + private static String OwnerAddress = "TCWHANtDDdkZCTo2T2peyEq3Eg9c2XB7ut"; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath, + "--storage-db-directory", dbDirectory, + "--storage-index-directory", indexDirectory, + "-w", + "--debug" + }, + "config-test-mainnet.conf" + ); + context = new TronApplicationContext(DefaultConfig.class); + } + + public TransactionTraceTest(long energyUsage, long storageUsage) { + this.energyUsage = energyUsage; + this.storageUsage = storageUsage; + } + + /** + * resourceUsage prepare data for testing. + */ + @Parameters + public static Collection resourceUsage() { + return Arrays.asList(new Object[][]{ + + {0, 0}, + // {6, 1000}, + // {7, 1000}, + // {10, 999}, + // {13, 1000}, + // {14, 1000}, + // {20, 1000}, + // {10, 1000}, + // {10, 1001} + + }); + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + storageMarket = new StorageMarket(dbManager); + //init energy + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1526647838000L); + dbManager.getDynamicPropertiesStore().saveTotalEnergyWeight(10_000_000L); + //init storage + dbManager.getDynamicPropertiesStore().saveTotalStorageReserved( + 128L * 1024 * 1024 * 1024); + dbManager.getDynamicPropertiesStore().saveTotalStoragePool(100_000_000_000000L); + dbManager.getDynamicPropertiesStore().saveTotalStorageTax(0); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(0); + + } + + @Test + public void testUseFee() throws InvalidProtocolBufferException { + AccountCapsule accountCapsule = new AccountCapsule(ByteString.copyFrom("owner".getBytes()), + ByteString.copyFrom(Wallet.decodeFromBase58Check(OwnerAddress)), AccountType.Normal, + totalBalance); + dbManager.getAccountStore() + .put(Wallet.decodeFromBase58Check(OwnerAddress), accountCapsule); + Transaction transaction = Transaction.parseFrom(ByteArray.fromHexString(trxByte)); + TransactionCapsule transactionCapsule = new TransactionCapsule(transaction); + TransactionTrace trace = new TransactionTrace(transactionCapsule, dbManager); + DepositImpl deposit = DepositImpl.createRoot(dbManager); + Runtime runtime = new Runtime(trace, null, deposit, + new ProgramInvokeFactoryImpl()); + try { + trace.exec(runtime); + trace.pay(); + Assert.assertEquals(0, trace.getReceipt().getEnergyUsage()); + Assert.assertEquals(49503930, trace.getReceipt().getEnergyFee()); + // Assert.assertEquals(deployStorageDelta, trace.getReceipt().getStorageDelta()); + // Assert.assertEquals(494800000, trace.getReceipt().getStorageFee()); + accountCapsule = dbManager.getAccountStore().get(accountCapsule.getAddress().toByteArray()); + // Assert.assertEquals(totalBalance, + // trace.getReceipt().getStorageFee() + trace.getReceipt().getEnergyFee() + accountCapsule + // .getBalance()); + } catch (ContractExeException e) { + e.printStackTrace(); + } catch (ContractValidateException e) { + e.printStackTrace(); + } catch (OutOfSlotTimeException e) { + e.printStackTrace(); + } + } + + @Test + public void testUseUsage() throws InvalidProtocolBufferException { + + AccountCapsule accountCapsule = new AccountCapsule(ByteString.copyFrom("owner".getBytes()), + ByteString.copyFrom(Wallet.decodeFromBase58Check(OwnerAddress)), AccountType.Normal, + totalBalance); + + accountCapsule.setFrozenForEnergy(10_000_000L, 0L); + dbManager.getAccountStore() + .put(Wallet.decodeFromBase58Check(OwnerAddress), accountCapsule); + storageMarket.buyStorage(accountCapsule, 1000_000L); + Transaction transaction = Transaction.parseFrom(ByteArray.fromHexString(trxByte)); + TransactionCapsule transactionCapsule = new TransactionCapsule(transaction); + TransactionTrace trace = new TransactionTrace(transactionCapsule, dbManager); + DepositImpl deposit = DepositImpl.createRoot(dbManager); + Runtime runtime = new Runtime(trace, null, deposit, + new ProgramInvokeFactoryImpl()); + try { + trace.exec(runtime); + trace.pay(); + Assert.assertEquals(50000, trace.getReceipt().getEnergyUsage()); + Assert.assertEquals(20110013100L, trace.getReceipt().getEnergyFee()); + Assert.assertEquals(201150131L, trace.getReceipt().getEnergyUsageTotal()); + // Assert.assertEquals(deployStorageDelta, trace.getReceipt().getStorageDelta()); + // Assert.assertEquals(493800000, trace.getReceipt().getStorageFee()); + accountCapsule = dbManager.getAccountStore().get(accountCapsule.getAddress().toByteArray()); + } catch (ContractExeException e) { + e.printStackTrace(); + } catch (ContractValidateException e) { + e.printStackTrace(); + } catch (OutOfSlotTimeException e) { + e.printStackTrace(); + } + } + + @Test + public void testPay() { + Account account = Account.newBuilder() + .setAddress(ownerAddress) + .setBalance(1000000) + .setAccountResource( + AccountResource.newBuilder() + .setEnergyUsage(this.energyUsage) + .setFrozenBalanceForEnergy( + Frozen.newBuilder() + .setExpireTime(100000) + .setFrozenBalance(100000) + .build()) + .setStorageUsage(this.storageUsage) + .setStorageLimit(3000) + .build()).build(); + + AccountCapsule accountCapsule = new AccountCapsule(account); + dbManager.getAccountStore().put(accountCapsule.getAddress().toByteArray(), accountCapsule); + TriggerSmartContract contract = TriggerSmartContract.newBuilder() + .setContractAddress(contractAddress) + .setOwnerAddress(ownerAddress) + .build(); + + SmartContract smartContract = SmartContract.newBuilder() + .setOriginAddress(ownerAddress) + .setContractAddress(contractAddress) + .build(); + + CreateSmartContract createSmartContract = CreateSmartContract.newBuilder() + .setOwnerAddress(ownerAddress) + .setNewContract(smartContract) + .build(); + + Transaction transaction = Transaction.newBuilder() + .setRawData( + raw.newBuilder() + .addContract( + Contract.newBuilder() + .setParameter(Any.pack(contract)) + .setType(ContractType.TriggerSmartContract) + .build()) + .build() + ) + .build(); + + dbManager.getContractStore().put( + contractAddress.toByteArray(), + new ContractCapsule(smartContract)); + + TransactionCapsule transactionCapsule = new TransactionCapsule(transaction); + TransactionTrace transactionTrace = new TransactionTrace(transactionCapsule, dbManager); + // transactionTrace.setBill(this.energyUsage, this.storageUsage); + transactionTrace.pay(); + AccountCapsule accountCapsule1 = dbManager.getAccountStore().get(ownerAddress.toByteArray()); + } + + /** + * destroy clear data of testing. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + FileUtil.deleteDir(new File(dbPath)); + context.destroy(); + } +} diff --git a/src/test/java/org/tron/core/db/VotesStoreTest.java b/src/test/java/org/tron/core/db/VotesStoreTest.java index af1eb8e17d6..2ff2dd26bc6 100755 --- a/src/test/java/org/tron/core/db/VotesStoreTest.java +++ b/src/test/java/org/tron/core/db/VotesStoreTest.java @@ -9,7 +9,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.capsule.VotesCapsule; @@ -21,12 +21,12 @@ public class VotesStoreTest { private static final String dbPath = "output-votesStore-test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; VotesStore votesStore; static { Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @Before diff --git a/src/test/java/org/tron/core/db/WitnessStoreTest.java b/src/test/java/org/tron/core/db/WitnessStoreTest.java index 6f88132c63f..4dd0dd7e53f 100755 --- a/src/test/java/org/tron/core/db/WitnessStoreTest.java +++ b/src/test/java/org/tron/core/db/WitnessStoreTest.java @@ -7,7 +7,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.capsule.WitnessCapsule; @@ -18,12 +18,12 @@ public class WitnessStoreTest { private static final String dbPath = "output-witnessStore-test"; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; WitnessStore witnessStore; static { Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @Before diff --git a/src/test/java/org/tron/core/db/api/IndexHelperTest.java b/src/test/java/org/tron/core/db/api/IndexHelperTest.java index effa60c836d..b3eee71ef68 100644 --- a/src/test/java/org/tron/core/db/api/IndexHelperTest.java +++ b/src/test/java/org/tron/core/db/api/IndexHelperTest.java @@ -12,7 +12,7 @@ import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.capsule.AccountCapsule; @@ -38,13 +38,13 @@ public class IndexHelperTest { private static Manager dbManager; private static IndexHelper indexHelper; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static String dbPath = "output_IndexHelper_test"; static { Args.setParam(new String[]{"-d", dbPath, "-w"}, "config-test-index.conf"); Args.getInstance().setSolidityNode(true); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @BeforeClass diff --git a/src/test/java/org/tron/core/db/api/StoreAPITest.java b/src/test/java/org/tron/core/db/api/StoreAPITest.java index 534cdc3dbc0..dbc2c6d41b8 100644 --- a/src/test/java/org/tron/core/db/api/StoreAPITest.java +++ b/src/test/java/org/tron/core/db/api/StoreAPITest.java @@ -9,7 +9,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.core.capsule.AccountCapsule; @@ -98,13 +98,13 @@ public class StoreAPITest { public static AssetIssueContract assetIssue4; private static Manager dbManager; private static StoreAPI storeAPI; - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static String dbPath = "output_StoreAPI_test"; static { Args.setParam(new String[]{"-d", dbPath, "-w"}, "config-test-index.conf"); Args.getInstance().setSolidityNode(true); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @BeforeClass diff --git a/src/test/java/org/tron/core/net/UdpTest.java b/src/test/java/org/tron/core/net/UdpTest.java index d3d148177ca..35fdf75b080 100644 --- a/src/test/java/org/tron/core/net/UdpTest.java +++ b/src/test/java/org/tron/core/net/UdpTest.java @@ -7,7 +7,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.testng.collections.Lists; import org.tron.common.net.udp.message.discover.FindNodeMessage; import org.tron.common.net.udp.message.Message; @@ -45,7 +45,7 @@ public void before(){ cfgArgs.getSeedNode().setIpList(Lists.newArrayList()); cfgArgs.setNodeP2pVersion(100); cfgArgs.setNodeListenPort(10001); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); }).start(); } diff --git a/src/test/java/org/tron/core/net/node/BaseNetTest.java b/src/test/java/org/tron/core/net/node/BaseNetTest.java index 72348c59bad..84c353f891a 100644 --- a/src/test/java/org/tron/core/net/node/BaseNetTest.java +++ b/src/test/java/org/tron/core/net/node/BaseNetTest.java @@ -21,7 +21,7 @@ import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Before; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.overlay.client.PeerClient; @@ -39,7 +39,7 @@ @Slf4j public abstract class BaseNetTest { - protected static AnnotationConfigApplicationContext context; + protected static TronApplicationContext context; protected NodeImpl node; protected RpcApiService rpcApiService; protected PeerClient peerClient; @@ -84,7 +84,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/BroadTest.java b/src/test/java/org/tron/core/net/node/BroadTest.java index 4d7ce73e586..475b46fad61 100644 --- a/src/test/java/org/tron/core/net/node/BroadTest.java +++ b/src/test/java/org/tron/core/net/node/BroadTest.java @@ -13,7 +13,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.overlay.client.PeerClient; @@ -45,7 +45,7 @@ @Slf4j public class BroadTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private NodeImpl node; RpcApiService rpcApiService; PeerClient peerClient; @@ -196,7 +196,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/FinishProcessSyncBlockTest.java b/src/test/java/org/tron/core/net/node/FinishProcessSyncBlockTest.java index d490a8702b7..1bf4e172c15 100644 --- a/src/test/java/org/tron/core/net/node/FinishProcessSyncBlockTest.java +++ b/src/test/java/org/tron/core/net/node/FinishProcessSyncBlockTest.java @@ -7,7 +7,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.crypto.ECKey; @@ -39,7 +39,7 @@ @Slf4j public class FinishProcessSyncBlockTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private NodeImpl node; RpcApiService rpcApiService; PeerClient peerClient; @@ -131,7 +131,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/GetBlockChainSummaryTest.java b/src/test/java/org/tron/core/net/node/GetBlockChainSummaryTest.java index df77d3b77c9..13e6ebc3c9b 100644 --- a/src/test/java/org/tron/core/net/node/GetBlockChainSummaryTest.java +++ b/src/test/java/org/tron/core/net/node/GetBlockChainSummaryTest.java @@ -8,7 +8,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.crypto.ECKey; @@ -43,7 +43,7 @@ @Slf4j public class GetBlockChainSummaryTest{ - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private NodeImpl node; RpcApiService rpcApiService; PeerClient peerClient; @@ -73,8 +73,8 @@ public void testGetBlockChainSummary() { long number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; Map addressToProvateKeys = addTestWitnessAndAccount(); - BlockCapsule capsule = createTestBlockCapsule(number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), - addressToProvateKeys); + BlockCapsule capsule = createTestBlockCapsule(1533529947843L,number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), + addressToProvateKeys); try { dbManager.pushBlock(capsule); } catch (Exception e) { @@ -82,7 +82,7 @@ public void testGetBlockChainSummary() { } for (int i = 1; i < 5; i++) { number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - capsule = createTestBlockCapsule(number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); + capsule = createTestBlockCapsule(1533529947843L + 3000L * i,number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); try { dbManager.pushBlock(capsule); } catch (Exception e) { @@ -111,7 +111,7 @@ public void testGetBlockChainSummary() { peer_he.getSyncBlockToFetch().clear(); for(int i=0; i<4 ;i++){ number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - capsule = createTestBlockCapsule(number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), + capsule = createTestBlockCapsule(1533529947843L + 3000L * i, number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); toFetch.add(capsule.getBlockId()); } @@ -131,18 +131,18 @@ public void testGetBlockChainSummary() { toFetch.clear(); peer_he.getSyncBlockToFetch().clear(); number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - BlockCapsule capsule1 = createTestBlockCapsule(number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), + BlockCapsule capsule1 = createTestBlockCapsule(1533529947843L + 3000L * 6, number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); dbManager.pushBlock(capsule1); number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - BlockCapsule capsule2 = createTestBlockCapsule(number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), + BlockCapsule capsule2 = createTestBlockCapsule(1533529947843L + 3000L * 7, number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); dbManager.pushBlock(capsule2); for(int i=0; i<2; i++){ number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - capsule = createTestBlockCapsule(number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), + capsule = createTestBlockCapsule(1533529947843L + 3000L * 8 + 3000L * i, number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); toFetch.add(capsule.getBlockId()); } @@ -185,6 +185,11 @@ private Map addTestWitnessAndAccount() { private BlockCapsule createTestBlockCapsule( long number, ByteString hash, Map addressToProvateKeys) { long time = System.currentTimeMillis(); + return createTestBlockCapsule(time,number,hash,addressToProvateKeys); + } + + private BlockCapsule createTestBlockCapsule(long time , + long number, ByteString hash, Map addressToProvateKeys) { WitnessController witnessController = dbManager.getWitnessController(); ByteString witnessAddress = witnessController.getScheduledWitness(witnessController.getSlotAtTime(time)); @@ -216,7 +221,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/GetLostBlockIdsTest.java b/src/test/java/org/tron/core/net/node/GetLostBlockIdsTest.java index c22c7500e2b..fc46abe04ab 100644 --- a/src/test/java/org/tron/core/net/node/GetLostBlockIdsTest.java +++ b/src/test/java/org/tron/core/net/node/GetLostBlockIdsTest.java @@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.MapUtils; import org.junit.*; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.crypto.ECKey; @@ -37,7 +37,7 @@ @Slf4j public class GetLostBlockIdsTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private NodeImpl node; RpcApiService rpcApiService; PeerClient peerClient; @@ -64,7 +64,7 @@ public void testGetLostBlockIds(){ BlockCapsule capsule = null; for (int i = 0; i<5; i++) { number = dbManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() + 1; - capsule = createTestBlockCapsule(number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); + capsule = createTestBlockCapsule(1533529947843L + 3000L * i ,number, dbManager.getDynamicPropertiesStore().getLatestBlockHeaderHash().getByteString(), addressToProvateKeys); try { dbManager.pushBlock(capsule); } catch (Exception e) { @@ -167,6 +167,10 @@ private Map addTestWitnessAndAccount() { private BlockCapsule createTestBlockCapsule( long number, ByteString hash, Map addressToProvateKeys) { long time = System.currentTimeMillis(); + return createTestBlockCapsule(time,number,hash,addressToProvateKeys); + } + private BlockCapsule createTestBlockCapsule(long time , + long number, ByteString hash, Map addressToProvateKeys) { WitnessController witnessController = dbManager.getWitnessController(); ByteString witnessAddress = witnessController.getScheduledWitness(witnessController.getSlotAtTime(time)); @@ -198,7 +202,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java b/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java index 484ce1870fc..564810b83ca 100644 --- a/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java +++ b/src/test/java/org/tron/core/net/node/HandleBlockMessageTest.java @@ -1,13 +1,17 @@ package org.tron.core.net.node; import com.google.protobuf.ByteString; +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.MapUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.crypto.ECKey; @@ -32,15 +36,11 @@ import org.tron.protos.Protocol.BlockHeader; import org.tron.protos.Protocol.Inventory.InventoryType; -import java.io.File; -import java.util.Map; -import java.util.concurrent.ExecutorService; - @Slf4j public class HandleBlockMessageTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private NodeImpl node; RpcApiService rpcApiService; PeerClient peerClient; @@ -67,7 +67,8 @@ private static Boolean deleteFolder(File index) { @Test public void testHandleBlockMessage() throws Exception { - PeerConnection peer = new PeerConnection(); + List activePeers = ReflectUtils.getFieldValue(pool, "activePeers"); + PeerConnection peer = activePeers.get(0); //收到同步请求块 BlockCapsule headBlockCapsule = dbManager.getHead(); @@ -148,7 +149,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/HandleSyncBlockTest.java b/src/test/java/org/tron/core/net/node/HandleSyncBlockTest.java index 01ce0263140..1c9312ecf62 100644 --- a/src/test/java/org/tron/core/net/node/HandleSyncBlockTest.java +++ b/src/test/java/org/tron/core/net/node/HandleSyncBlockTest.java @@ -13,7 +13,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.crypto.ECKey; @@ -42,7 +42,7 @@ @Slf4j public class HandleSyncBlockTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private NodeImpl node; RpcApiService rpcApiService; PeerClient peerClient; @@ -169,7 +169,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/HandleTransactionTest.java b/src/test/java/org/tron/core/net/node/HandleTransactionTest.java index 2632081dc19..f81485c65db 100644 --- a/src/test/java/org/tron/core/net/node/HandleTransactionTest.java +++ b/src/test/java/org/tron/core/net/node/HandleTransactionTest.java @@ -6,7 +6,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.overlay.client.PeerClient; @@ -36,7 +36,7 @@ @Slf4j public class HandleTransactionTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private NodeImpl node; RpcApiService rpcApiService; PeerClient peerClient; @@ -105,7 +105,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/NodeImplTest.java b/src/test/java/org/tron/core/net/node/NodeImplTest.java index e9864d851db..16dc288d4ce 100644 --- a/src/test/java/org/tron/core/net/node/NodeImplTest.java +++ b/src/test/java/org/tron/core/net/node/NodeImplTest.java @@ -11,7 +11,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.crypto.ECKey; @@ -36,7 +36,7 @@ @Slf4j public class NodeImplTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Application appT; private static String dbPath = "output_nodeimpl_test"; @@ -46,7 +46,7 @@ public class NodeImplTest { static { Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); Args.getInstance().setSolidityNode(true); appT = ApplicationFactory.create(context); } diff --git a/src/test/java/org/tron/core/net/node/StartFetchSyncBlockTest.java b/src/test/java/org/tron/core/net/node/StartFetchSyncBlockTest.java index b0ff27acd11..e3c31187106 100644 --- a/src/test/java/org/tron/core/net/node/StartFetchSyncBlockTest.java +++ b/src/test/java/org/tron/core/net/node/StartFetchSyncBlockTest.java @@ -12,7 +12,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.overlay.client.PeerClient; @@ -37,7 +37,7 @@ @Slf4j public class StartFetchSyncBlockTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private NodeImpl node; RpcApiService rpcApiService; PeerClient peerClient; @@ -150,7 +150,7 @@ public void run() { cfgArgs.setNeedSyncCheck(false); cfgArgs.setNodeExternalIp("127.0.0.1"); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); if (cfgArgs.isHelp()) { logger.info("Here is the help message."); diff --git a/src/test/java/org/tron/core/net/node/TcpNetTest.java b/src/test/java/org/tron/core/net/node/TcpNetTest.java index 0ac2f8cf137..3390cf18f02 100644 --- a/src/test/java/org/tron/core/net/node/TcpNetTest.java +++ b/src/test/java/org/tron/core/net/node/TcpNetTest.java @@ -5,7 +5,7 @@ import static org.tron.protos.Protocol.ReasonCode.DUPLICATE_PEER; import static org.tron.protos.Protocol.ReasonCode.FORKED; import static org.tron.protos.Protocol.ReasonCode.INCOMPATIBLE_CHAIN; -import static org.tron.protos.Protocol.ReasonCode.INCOMPATIBLE_PROTOCOL; +import static org.tron.protos.Protocol.ReasonCode.INCOMPATIBLE_VERSION; import com.google.common.cache.CacheBuilder; import io.netty.buffer.ByteBuf; @@ -99,7 +99,7 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List ou break; case errorVersion: Assert.assertEquals(msg.getType(), P2P_DISCONNECT); - Assert.assertEquals(((DisconnectMessage) msg).getReasonCode(), INCOMPATIBLE_PROTOCOL); + Assert.assertEquals(((DisconnectMessage) msg).getReasonCode(), INCOMPATIBLE_VERSION); break; case errorSolid: Assert.assertEquals(msg.getType(), P2P_DISCONNECT); diff --git a/src/test/java/org/tron/core/witness/ProposalControllerTest.java b/src/test/java/org/tron/core/witness/ProposalControllerTest.java index f85bc69f4f7..c779995569f 100644 --- a/src/test/java/org/tron/core/witness/ProposalControllerTest.java +++ b/src/test/java/org/tron/core/witness/ProposalControllerTest.java @@ -9,7 +9,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.testng.collections.Lists; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; @@ -26,13 +26,13 @@ public class ProposalControllerTest { private static Manager dbManager = new Manager(); - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static String dbPath = "output_proposal_controller_test"; private static ProposalController proposalController; static { Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } @BeforeClass diff --git a/src/test/java/org/tron/core/witness/WitnessControllerTest.java b/src/test/java/org/tron/core/witness/WitnessControllerTest.java index 8a5ffeabed1..8270778a2ff 100644 --- a/src/test/java/org/tron/core/witness/WitnessControllerTest.java +++ b/src/test/java/org/tron/core/witness/WitnessControllerTest.java @@ -9,22 +9,24 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.utils.ByteArray; 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.config.args.Witness; import org.tron.core.db.Manager; public class WitnessControllerTest { + private static Manager dbManager = new Manager(); - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static String dbPath = "output_witness_controller_test"; static { - Args.setParam(new String[] {"-d", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); } @BeforeClass @@ -51,10 +53,9 @@ public void testSlot() { // assertEquals(2, dbManager.getWitnessController().getSlotAtTime(21500)); // assertEquals(19, dbManager.getWitnessController().getHeadSlot()); - } -// @Test + // @Test public void testWitnessSchedule() { // no witness produce block @@ -106,4 +107,26 @@ public void testWitnessSchedule() { assertEquals(a, dbManager.getWitnessController().getScheduledWitness(3)); assertEquals(b, dbManager.getWitnessController().getScheduledWitness(4)); } + + @Test + public void testTryRemoveThePowerOfTheGr() { + + Witness witness = Args.getInstance().getGenesisBlock().getWitnesses().get(0); + assertEquals(105, witness.getVoteCount()); + + dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); + dbManager.getWitnessController().tryRemoveThePowerOfTheGr(); + assertEquals(105, dbManager.getWitnessStore().get(witness.getAddress()).getVoteCount()); + + dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(1); + dbManager.getWitnessController().tryRemoveThePowerOfTheGr(); + assertEquals(0, dbManager.getWitnessStore().get(witness.getAddress()).getVoteCount()); + + dbManager.getWitnessController().tryRemoveThePowerOfTheGr(); + assertEquals(0, dbManager.getWitnessStore().get(witness.getAddress()).getVoteCount()); + + + } + + } diff --git a/src/test/java/org/tron/program/AccountVoteWitnessTest.java b/src/test/java/org/tron/program/AccountVoteWitnessTest.java index 3a433a71bf1..5726ca85a47 100755 --- a/src/test/java/org/tron/program/AccountVoteWitnessTest.java +++ b/src/test/java/org/tron/program/AccountVoteWitnessTest.java @@ -8,7 +8,7 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.core.Constant; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.WitnessCapsule; @@ -20,14 +20,14 @@ @Slf4j public class AccountVoteWitnessTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static Manager dbManager; private static String dbPath = "output_witness_test"; static { Args.setParam(new String[] {"-d", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); } /** init db. */ diff --git a/src/test/java/org/tron/program/SolidityNodeTest.java b/src/test/java/org/tron/program/SolidityNodeTest.java index 8d8df4a4cfd..e2e68677e65 100755 --- a/src/test/java/org/tron/program/SolidityNodeTest.java +++ b/src/test/java/org/tron/program/SolidityNodeTest.java @@ -6,7 +6,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.overlay.client.DatabaseGrpcClient; @@ -20,7 +20,7 @@ @Slf4j public class SolidityNodeTest { - private static AnnotationConfigApplicationContext context; + private static TronApplicationContext context; private static RpcApiService rpcApiService; private static Application appT; @@ -28,7 +28,7 @@ public class SolidityNodeTest { static { Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - context = new AnnotationConfigApplicationContext(DefaultConfig.class); + context = new TronApplicationContext(DefaultConfig.class); Args.getInstance().setSolidityNode(true); appT = ApplicationFactory.create(context); rpcApiService = context.getBean(RpcApiService.class); diff --git a/src/test/java/stest/tron/wallet/account/WalletTestAccount001.java b/src/test/java/stest/tron/wallet/account/WalletTestAccount001.java index 5aa7686ae95..ef576012ee1 100644 --- a/src/test/java/stest/tron/wallet/account/WalletTestAccount001.java +++ b/src/test/java/stest/tron/wallet/account/WalletTestAccount001.java @@ -5,6 +5,7 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import java.math.BigInteger; +import java.util.Random; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -19,14 +20,13 @@ import org.tron.api.WalletSolidityGrpc; import org.tron.common.crypto.ECKey; import org.tron.common.utils.ByteArray; +import org.tron.core.Wallet; import org.tron.protos.Protocol.Account; import org.tron.protos.Protocol.Block; import stest.tron.wallet.common.client.Configuration; import stest.tron.wallet.common.client.Parameter.CommonConstant; -import stest.tron.wallet.common.client.WalletClient; -import stest.tron.wallet.common.client.utils.Base58; import stest.tron.wallet.common.client.utils.PublicMethed; -import org.tron.core.Wallet; + @Slf4j @@ -109,6 +109,7 @@ public void testqueryaccountfromsoliditynode() { Assert.assertTrue(invalidQueryResult.getAccountName().isEmpty()); Assert.assertTrue(invalidQueryResult.getAddress().isEmpty()); + } @AfterClass diff --git a/src/test/java/stest/tron/wallet/account/WalletTestAccount003.java b/src/test/java/stest/tron/wallet/account/WalletTestAccount003.java index 362a896685d..1fa5641127a 100644 --- a/src/test/java/stest/tron/wallet/account/WalletTestAccount003.java +++ b/src/test/java/stest/tron/wallet/account/WalletTestAccount003.java @@ -126,7 +126,7 @@ public void testCreateAccount() { } } - @Test(enabled = false) + @Test(enabled = true) public void testUpdateAccount() { Account tryToUpdateAccount = queryAccount(lowBalTest, blockingStubFull); if (tryToUpdateAccount.getAccountName().isEmpty()) { @@ -139,11 +139,11 @@ public void testUpdateAccount() { Assert.assertTrue(updateAccount(lowBalAddress, mostLongName.getBytes(), lowBalTest)); tryToUpdateAccount = queryAccount(lowBalTest, blockingStubFull); Assert.assertFalse(tryToUpdateAccount.getAccountName().isEmpty()); - Assert.assertFalse(updateAccount(lowBalAddress, "secondUpdateName".getBytes(), lowBalTest)); + Assert.assertTrue(updateAccount(lowBalAddress, "secondUpdateName".getBytes(), lowBalTest)); } } - @Test(enabled = false) + @Test(enabled = true) public void testNoBalanceCreateAssetIssue() { Account lowaccount = queryAccount(lowBalTest, blockingStubFull); if (lowaccount.getBalance() > 0) { @@ -161,19 +161,19 @@ public void testNoBalanceCreateAssetIssue() { logger.info("nobalancecreateassetissue"); } - @Test(enabled = false) + @Test(enabled = true) public void testNoBalanceTransferTrx() { //Send Coin failed when there is no enough balance. Assert.assertFalse(sendCoin(toAddress, 100000000000000000L, lowBalAddress, lowBalTest)); } - @Test(enabled = false) + @Test(enabled = true) public void testNoBalanceCreateWitness() { //Apply to be super witness failed when no enough balance. Assert.assertFalse(createWitness(lowBalAddress, fromAddress, lowBalTest)); } - @Test(enabled = false) + @Test(enabled = true) public void testNoFreezeBalanceToUnfreezeBalance() { //Unfreeze account failed when no freeze balance Account noFreezeAccount = queryAccount(lowBalTest, blockingStubFull); diff --git a/src/test/java/stest/tron/wallet/account/WalletTestAccount008.java b/src/test/java/stest/tron/wallet/account/WalletTestAccount008.java new file mode 100644 index 00000000000..95da20f4a8b --- /dev/null +++ b/src/test/java/stest/tron/wallet/account/WalletTestAccount008.java @@ -0,0 +1,156 @@ +package stest.tron.wallet.account; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountNetMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class WalletTestAccount008 { + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private static final long now = System.currentTimeMillis(); + private static String name = "AssetIssue012_" + Long.toString(now); + private static final long totalSupply = now; + private static final long sendAmount = 10000000000L; + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") + .get(0); + + private static final long FREENETLIMIT = 5000L; + private static final long BASELINE = 4800L; + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] account008Address = ecKey1.getAddress(); + String account008Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + ECKey ecKey2 = new ECKey(Utils.getRandom()); + byte[] account008SecondAddress = ecKey2.getAddress(); + String account008SecondKey = ByteArray.toHexString(ecKey2.getPrivKeyBytes()); + + ECKey ecKey3 = new ECKey(Utils.getRandom()); + byte[] account008InvalidAddress = ecKey3.getAddress(); + String account008InvalidKey = ByteArray.toHexString(ecKey3.getPrivKeyBytes()); + + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(account008Key); + PublicMethed.printAddress(account008SecondKey); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + + Assert.assertTrue(PublicMethed.sendcoin(account008Address,10000000, + fromAddress,testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(account008SecondAddress,10000000, + fromAddress,testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(account008InvalidAddress,10000000, + fromAddress,testKey002,blockingStubFull)); + + } + + @Test(enabled = true) + public void testSetAccountId() { + String lessThan7Char = getRandomStr(7); + String moreThan32Char = getRandomStr(33); + String shortAccountId = getRandomStr(8); + String longAccountId = getRandomStr(32); + //Less than 7 char can't set success. + Assert.assertFalse(PublicMethed.setAccountId(lessThan7Char.getBytes(),account008Address, + account008Key,blockingStubFull)); + //More than 33 char can't set success. + Assert.assertFalse(PublicMethed.setAccountId(moreThan32Char.getBytes(),account008Address, + account008Key,blockingStubFull)); + //The shortest char is 8,it can success. + Assert.assertTrue(PublicMethed.setAccountId(shortAccountId.getBytes(),account008Address, + + account008Key,blockingStubFull)); + //One account only can set account id 1 time. + Assert.assertFalse(PublicMethed.setAccountId(longAccountId.getBytes(),account008Address, + account008Key,blockingStubFull)); + //One account id only can set by one account, when another account try to set, is will failed. + Assert.assertFalse(PublicMethed.setAccountId(shortAccountId.getBytes(),account008SecondAddress, + account008SecondKey,blockingStubFull)); + //The longest char is 32, it can success. + Assert.assertTrue(PublicMethed.setAccountId(longAccountId.getBytes(),account008SecondAddress, + account008SecondKey,blockingStubFull)); + + Account account008Info = PublicMethed.queryAccount(account008Key,blockingStubFull); + Assert.assertTrue(ByteArray.toStr(account008Info.getAccountId().toByteArray()).length() == 8); + Account account008SecondInfo = PublicMethed.queryAccount(account008SecondKey,blockingStubFull); + Assert.assertTrue(ByteArray.toStr(account008SecondInfo.getAccountId() + .toByteArray()).length() == 32); + + } + + @Test(enabled = true) + public void testSetInvalidAccountId() { + String hasSpaceAccountId = getRandomStr(4) + " " + getRandomStr(10); + String hasChineseAccountId = getRandomStr(4) + "中文账户名称"; + Assert.assertFalse(PublicMethed.setAccountId(hasSpaceAccountId.getBytes(), + account008InvalidAddress, account008InvalidKey,blockingStubFull)); + Assert.assertFalse(PublicMethed.setAccountId(hasChineseAccountId.getBytes(), + account008InvalidAddress, account008InvalidKey,blockingStubFull)); + + + } + + @AfterClass(enabled = true) + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } + + + public static String getRandomStr(int length) { + String base = "abcdefghijklmnopqrstuvwxyz0123456789"; + int randomNum; + char randomChar; + Random random = new Random(); + // StringBuffer类型的可以append增加字符 + StringBuffer str = new StringBuffer(); + + for (int i = 0; i < length; i++) { + // 可生成[0,n)之间的整数,获得随机位置 + randomNum = random.nextInt(base.length()); + // 获得随机位置对应的字符 + randomChar = base.charAt(randomNum); + // 组成一个随机字符串 + str.append(randomChar); + } + return str.toString(); + } + +} + + diff --git a/src/test/java/stest/tron/wallet/account/WalletTestAccount009.java b/src/test/java/stest/tron/wallet/account/WalletTestAccount009.java new file mode 100644 index 00000000000..04f79af4d11 --- /dev/null +++ b/src/test/java/stest/tron/wallet/account/WalletTestAccount009.java @@ -0,0 +1,122 @@ +package stest.tron.wallet.account; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class WalletTestAccount009 { + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private static final long now = System.currentTimeMillis(); + private static String name = "AssetIssue012_" + Long.toString(now); + private static final long totalSupply = now; + private static final long sendAmount = 10000000000L; + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") + .get(0); + + private static final long FREENETLIMIT = 5000L; + private static final long BASELINE = 4800L; + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] account009Address = ecKey1.getAddress(); + String account009Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + ECKey ecKey2 = new ECKey(Utils.getRandom()); + byte[] account009SecondAddress = ecKey2.getAddress(); + String account009SecondKey = ByteArray.toHexString(ecKey2.getPrivKeyBytes()); + + ECKey ecKey3 = new ECKey(Utils.getRandom()); + byte[] account009InvalidAddress = ecKey3.getAddress(); + String account009InvalidKey = ByteArray.toHexString(ecKey3.getPrivKeyBytes()); + + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(account009Key); + PublicMethed.printAddress(account009SecondKey); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + + Assert.assertTrue(PublicMethed.sendcoin(account009Address,10000000, + fromAddress,testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(account009SecondAddress,10000000, + fromAddress,testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(account009InvalidAddress,10000000, + fromAddress,testKey002,blockingStubFull)); + + } + + @Test(enabled = true) + public void testGetEnergy() { + Account account009Info = PublicMethed.queryAccount(account009Key,blockingStubFull); + Assert.assertTrue(account009Info.getAccountResource().getEnergyUsage() == 0); + Assert.assertTrue(account009Info.getAccountResource().getFrozenBalanceForEnergy() + .getExpireTime() == 0); + + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(account009Address, 1000000L, + 3,1,account009Key,blockingStubFull)); + account009Info = PublicMethed.queryAccount(account009Key,blockingStubFull); + Assert.assertTrue(account009Info.getAccountResource().getEnergyUsage() == 0); + Assert.assertTrue(account009Info.getAccountResource().getFrozenBalanceForEnergy() + .getFrozenBalance() == 1000000L); + + AccountResourceMessage account009Resource = PublicMethed.getAccountResource(account009Address, + blockingStubFull); + Assert.assertTrue(account009Resource.getTotalEnergyLimit() == 50000000000L); + Assert.assertTrue(account009Resource.getEnergyLimit() > 0); + Assert.assertTrue(account009Resource.getTotalEnergyWeight() >= 1); + } + + @Test(enabled = true) + public void testGetEnergyInvalid() { + //The resourceCode can only be 0 or 1 + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(account009InvalidAddress, + 1000000L, 3,0,account009InvalidKey,blockingStubFull)); + Assert.assertFalse(PublicMethed.freezeBalanceGetEnergy(account009InvalidAddress, 1000000L, + 3,-1,account009InvalidKey,blockingStubFull)); + Assert.assertFalse(PublicMethed.freezeBalanceGetEnergy(account009InvalidAddress, 1000000L, + 3,2,account009InvalidKey,blockingStubFull)); + + } + + + @AfterClass(enabled = true) + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/account/WalletTestAccount010.java b/src/test/java/stest/tron/wallet/account/WalletTestAccount010.java new file mode 100644 index 00000000000..3ef53ab174c --- /dev/null +++ b/src/test/java/stest/tron/wallet/account/WalletTestAccount010.java @@ -0,0 +1,129 @@ +package stest.tron.wallet.account; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class WalletTestAccount010 { + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private static final long now = System.currentTimeMillis(); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") + .get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] account010Address = ecKey1.getAddress(); + String account010Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + ECKey ecKey2 = new ECKey(Utils.getRandom()); + byte[] account010SecondAddress = ecKey2.getAddress(); + String account010SecondKey = ByteArray.toHexString(ecKey2.getPrivKeyBytes()); + + ECKey ecKey3 = new ECKey(Utils.getRandom()); + byte[] account010InvalidAddress = ecKey3.getAddress(); + String account010InvalidKey = ByteArray.toHexString(ecKey3.getPrivKeyBytes()); + + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = false) + public void beforeClass() { + PublicMethed.printAddress(account010Key); + PublicMethed.printAddress(account010SecondKey); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + + Assert.assertTrue(PublicMethed.sendcoin(account010Address,100000000, + fromAddress,testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(account010SecondAddress,100000000, + fromAddress,testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(account010InvalidAddress,100000000, + fromAddress,testKey002,blockingStubFull)); + + } + + @Test(enabled = false) + public void testGetStorage() { + Account account010Info = PublicMethed.queryAccount(account010Key,blockingStubFull); + Assert.assertTrue(account010Info.getAccountResource().getStorageLimit() == 0); + Assert.assertTrue(account010Info.getAccountResource().getLatestExchangeStorageTime() == 0); + + Assert.assertTrue(PublicMethed.buyStorage(100000000L,account010Address,account010Key, + blockingStubFull)); + + account010Info = PublicMethed.queryAccount(account010Key,blockingStubFull); + Assert.assertTrue(account010Info.getAccountResource().getStorageLimit() > 0); + Assert.assertTrue(account010Info.getAccountResource().getLatestExchangeStorageTime() > 0); + + AccountResourceMessage account010Resource = PublicMethed.getAccountResource(account010Address, + blockingStubFull); + Assert.assertTrue(account010Resource.getStorageLimit() > 0); + } + + @Test(enabled = false) + public void testSellStorage() { + AccountResourceMessage account010Resource = PublicMethed.getAccountResource(account010Address, + blockingStubFull); + Long storageLimit = account010Resource.getStorageLimit(); + Account account001Info = PublicMethed.queryAccount(account010Key,blockingStubFull); + Assert.assertTrue(account001Info.getBalance() == 0); + //When there is no enough storage,sell failed. + Assert.assertFalse(PublicMethed.sellStorage(storageLimit + 1,account010Address,account010Key, + blockingStubFull)); + //Can not sell 0 storage + Assert.assertFalse(PublicMethed.sellStorage(0,account010Address,account010Key, + blockingStubFull)); + //Sell all storage. + Assert.assertTrue(PublicMethed.sellStorage(storageLimit,account010Address,account010Key, + blockingStubFull)); + account010Resource = PublicMethed.getAccountResource(account010Address, + blockingStubFull); + storageLimit = account010Resource.getStorageLimit(); + Assert.assertTrue(storageLimit == 0); + account001Info = PublicMethed.queryAccount(account010Key,blockingStubFull); + Assert.assertTrue(account001Info.getBalance() > 0); + + + + } + + + + @AfterClass(enabled = false) + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue002.java b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue002.java index b41e09ff7a1..8ef7c66a8a7 100644 --- a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue002.java +++ b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue002.java @@ -97,7 +97,8 @@ public void beforeClass() { testKey002,blockingStubFull)); //Create a new Asset Issue Assert.assertTrue(PublicMethed.createAssetIssue(participateAccountAddress, - name, totalSupply, 1, 1, start, end, 1, description, url, + name, totalSupply, 1, 1, System.currentTimeMillis() + 2000, + System.currentTimeMillis() + 1000000000, 1, description, url, 2000L,2000L, 1L, 1L, participateAccountKey,blockingStubFull)); } else { diff --git a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue003.java b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue003.java index 0c4b9dcb0f4..089f01dbb2f 100644 --- a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue003.java +++ b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue003.java @@ -185,11 +185,6 @@ public void beforeClass() { //Test not in the duration time, participate failed. Assert.assertFalse(PublicMethed.participateAssetIssue(fromAddress, name.getBytes(), 1L, toAddress, testKey003,blockingStubFull)); - //Test another address try to create the same name asset issue, create failed. - Assert.assertFalse(PublicMethed.createAssetIssue(toAddress, name, totalSupply, 1, 10, - start, end, 2, description, url, 10000L,10000L, - 1L, 3652L, testKey003,blockingStubFull)); - try { Thread.sleep(4000); } catch (InterruptedException e) { diff --git a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue007.java b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue007.java index 3244e36bc7a..8f02bff4870 100644 --- a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue007.java +++ b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue007.java @@ -51,7 +51,7 @@ public class WalletTestAssetIssue007 { private static final long totalSupply = now; private static final long sendAmount = 10000000000L; private static final long netCostMeasure = 200L; - private static final Integer trxNum = 2; + private static final Integer trxNum = 1; private static final Integer icoNum = 1; Long freeAssetNetLimit = 10000L; @@ -117,9 +117,11 @@ public void beforeClass() { } } - @Test(enabled = false) + @Test(enabled = true) public void testParticipateAssetIssueUseParticipaterBandwidth() { logger.info(name); + Assert.assertTrue(PublicMethed.waitProduceNextBlock(blockingStubFull)); + Assert.assertTrue(PublicMethed.waitProduceNextBlock(blockingStubFull)); //When no balance, participate an asset issue Assert.assertFalse(PublicMethed.participateAssetIssue(asset007Address, name.getBytes(), 1L, participateAssetAddress, participateAssetCreateKey,blockingStubFull)); @@ -139,7 +141,6 @@ public void testParticipateAssetIssueUseParticipaterBandwidth() { Assert.assertTrue(participateAccountBeforeNetUsed == 0); //Participate an assetIssue, then query the net information. - //Assert.assertTrue(PublicMethed.waitProduceNextBlock(blockingStubFull)); ByteString assetNameBs = ByteString.copyFrom(name.getBytes()); GrpcAPI.BytesMessage request1 = GrpcAPI.BytesMessage.newBuilder().setValue(assetNameBs).build(); Contract.AssetIssueContract assetIssueByName = blockingStubFull.getAssetIssueByName(request1); @@ -180,7 +181,7 @@ public void testParticipateAssetIssueUseParticipaterBandwidth() { participateInfo = PublicMethed.queryAccount(participateAssetCreateKey,blockingStubFull); final Long afterBalance = participateInfo.getBalance(); - Assert.assertTrue(beforeBalance - trxNum*1*icoNum > afterBalance); + Assert.assertTrue(beforeBalance - trxNum*1*icoNum >= afterBalance); diff --git a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue011.java b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue011.java index f97bcea13cd..67a5265fafa 100644 --- a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue011.java +++ b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue011.java @@ -73,8 +73,8 @@ public void beforeSuite() { @BeforeClass(enabled = true) public void beforeClass() { - logger.info(testKeyForAssetIssue011); - logger.info(transferAssetCreateKey); + PublicMethed.printAddress(testKeyForAssetIssue011); + PublicMethed.printAddress(transferAssetCreateKey); channelFull = ManagedChannelBuilder.forTarget(fullnode) .usePlaintext(true) diff --git a/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue018.java b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue018.java new file mode 100644 index 00000000000..53ef65ac485 --- /dev/null +++ b/src/test/java/stest/tron/wallet/assetissue/WalletTestAssetIssue018.java @@ -0,0 +1,355 @@ +package stest.tron.wallet.assetissue; + +import com.google.protobuf.ByteString; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.math.BigInteger; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.spongycastle.util.encoders.Hex; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI; +import org.tron.api.GrpcAPI.NumberMessage; +import org.tron.api.GrpcAPI.Return; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Contract; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.Block; +import org.tron.protos.Protocol.Transaction; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; +import stest.tron.wallet.common.client.utils.TransactionUtils; + +@Slf4j +public class WalletTestAssetIssue018 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final String testKey003 = + "6815B367FDDE637E53E9ADC8E69424E07724333C9A2B973CFA469975E20753FC"; + + /* //testng001、testng002、testng003、testng004 + private static final byte[] fromAddress = Base58 + .decodeFromBase58Check("THph9K2M2nLvkianrMGswRhz5hjSA9fuH7"); + private static final byte[] toAddress = Base58 + .decodeFromBase58Check("TV75jZpdmP2juMe1dRwGrwpV6AMU6mr1EU");*/ + + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + private final byte[] toAddress = PublicMethed.getFinalAddress(testKey003); + + private static final long now = System.currentTimeMillis(); + private static final String name = "testAssetIssue018_" + Long.toString(now); + private static final long totalSupply = now; + String description = "just-test"; + String url = "https://github.com/tronprotocol/wallet-cli/"; + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") + .get(0); + + //get account + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] assetAccount1Address = ecKey1.getAddress(); + String assetAccount1Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + ECKey ecKey2 = new ECKey(Utils.getRandom()); + byte[] assetAccount2Address = ecKey2.getAddress(); + String assetAccount2Key = ByteArray.toHexString(ecKey2.getPrivKeyBytes()); + + ECKey ecKey3 = new ECKey(Utils.getRandom()); + byte[] assetAccount3Address = ecKey3.getAddress(); + String assetAccount3Key = ByteArray.toHexString(ecKey3.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + PublicMethed.printAddress(assetAccount1Key); + PublicMethed.printAddress(assetAccount2Key); + PublicMethed.printAddress(assetAccount3Key); + } + + @Test(enabled = true) + public void testSameAssetissueName() { + logger.info(name); + logger.info("total supply is " + Long.toString(totalSupply)); + //send coin to the new account + Assert.assertTrue(PublicMethed.sendcoin(assetAccount1Address,2048000000,fromAddress, + testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(assetAccount2Address,2048000000,fromAddress, + testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(assetAccount3Address,2048000000,fromAddress, + testKey002,blockingStubFull)); + + //Create 3 the same name token. + Long start = System.currentTimeMillis() + 3000; + Long end = System.currentTimeMillis() + 1000000000; + Assert.assertTrue(PublicMethed.createAssetIssue(assetAccount1Address, + name, totalSupply, 1, 1, start, end, 1, description, url, + 2000L,2000L, 1L,1L,assetAccount1Key,blockingStubFull)); + start = System.currentTimeMillis() + 3000; + end = System.currentTimeMillis() + 1000000000; + Assert.assertTrue(PublicMethed.createAssetIssue(assetAccount2Address, + name, totalSupply + 1, 2, 2, start, end, 2, description, url, + 3000L,3000L, 2L,2L,assetAccount2Key,blockingStubFull)); + start = System.currentTimeMillis() + 3000; + end = System.currentTimeMillis() + 1000000000; + Assert.assertTrue(PublicMethed.createAssetIssue(assetAccount3Address, + name, totalSupply + 2, 3, 3, start, end, 3, description, url, + 4000L,4000L, 3L,2L,assetAccount3Key,blockingStubFull)); + + + //Get asset issue by name + String asset1Name = name; + String asset2Name = name + "_1"; + String asset3Name = name + "_2"; + ByteString assetNameBs = ByteString.copyFrom(asset1Name.getBytes()); + GrpcAPI.BytesMessage request = GrpcAPI.BytesMessage.newBuilder().setValue(assetNameBs).build(); + Contract.AssetIssueContract assetIssueByName = blockingStubFull.getAssetIssueByName(request); + Assert.assertTrue(assetIssueByName.getVoteScore() == 1); + + assetNameBs = ByteString.copyFrom(asset2Name.getBytes()); + request = GrpcAPI.BytesMessage.newBuilder().setValue(assetNameBs).build(); + assetIssueByName = blockingStubFull.getAssetIssueByName(request); + Assert.assertTrue(assetIssueByName.getVoteScore() == 2); + + assetNameBs = ByteString.copyFrom(asset3Name.getBytes()); + request = GrpcAPI.BytesMessage.newBuilder().setValue(assetNameBs).build(); + assetIssueByName = blockingStubFull.getAssetIssueByName(request); + Assert.assertTrue(assetIssueByName.getVoteScore() == 3); + + //Transfer asset issue. + Assert.assertTrue(PublicMethed.transferAsset(assetAccount2Address, + asset1Name.getBytes(),1L,assetAccount1Address,assetAccount1Key,blockingStubFull)); + + Assert.assertTrue(PublicMethed.transferAsset(assetAccount3Address, + asset2Name.getBytes(),2L,assetAccount2Address,assetAccount2Key,blockingStubFull)); + + Assert.assertTrue(PublicMethed.transferAsset(assetAccount1Address, + asset3Name.getBytes(),3L,assetAccount3Address,assetAccount3Key,blockingStubFull)); + + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //Participate asset issue. + Assert.assertTrue(PublicMethed.participateAssetIssue(assetAccount3Address,asset3Name.getBytes(), + 1L,assetAccount2Address,assetAccount2Key,blockingStubFull)); + + Assert.assertTrue(PublicMethed.participateAssetIssue(assetAccount1Address,asset1Name.getBytes(), + 2L,assetAccount3Address,assetAccount3Key,blockingStubFull)); + + Assert.assertTrue(PublicMethed.participateAssetIssue(assetAccount2Address,asset2Name.getBytes(), + 3L,assetAccount1Address,assetAccount1Key,blockingStubFull)); + + + } + + @AfterClass(enabled = true) + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } + + public boolean participateAssetIssue(byte[] to, byte[] assertName, long amount, byte[] from, + String priKey) { + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + Contract.ParticipateAssetIssueContract.Builder builder = Contract.ParticipateAssetIssueContract + .newBuilder(); + ByteString bsTo = ByteString.copyFrom(to); + ByteString bsName = ByteString.copyFrom(assertName); + ByteString bsOwner = ByteString.copyFrom(from); + builder.setToAddress(bsTo); + builder.setAssetName(bsName); + builder.setOwnerAddress(bsOwner); + builder.setAmount(amount); + Contract.ParticipateAssetIssueContract contract = builder.build(); + + Transaction transaction = blockingStubFull.participateAssetIssue(contract); + transaction = signTransaction(ecKey, transaction); + Return response = blockingStubFull.broadcastTransaction(transaction); + if (response.getResult() == false) { + logger.info(ByteArray.toStr(response.getMessage().toByteArray())); + return false; + } else { + logger.info(name); + return true; + } + } + + public Boolean createAssetIssue(byte[] address, String name, Long totalSupply, Integer trxNum, + Integer icoNum, Long startTime, Long endTime, + Integer voteScore, String description, String url, Long fronzenAmount, Long frozenDay, + String priKey,Long order) { + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + ECKey ecKey = temKey; + + try { + Contract.AssetIssueContract.Builder builder = Contract.AssetIssueContract.newBuilder(); + builder.setOwnerAddress(ByteString.copyFrom(address)); + builder.setName(ByteString.copyFrom(name.getBytes())); + builder.setTotalSupply(totalSupply); + builder.setTrxNum(trxNum); + builder.setNum(icoNum); + builder.setStartTime(startTime); + builder.setEndTime(endTime); + builder.setVoteScore(voteScore); + builder.setDescription(ByteString.copyFrom(description.getBytes())); + builder.setUrl(ByteString.copyFrom(url.getBytes())); + builder.setFreeAssetNetLimit(20000); + builder.setPublicFreeAssetNetLimit(20000); + Contract.AssetIssueContract.FrozenSupply.Builder frozenBuilder = + Contract.AssetIssueContract.FrozenSupply.newBuilder(); + frozenBuilder.setFrozenAmount(fronzenAmount); + frozenBuilder.setFrozenDays(frozenDay); + builder.addFrozenSupply(0, frozenBuilder); + + Transaction transaction = blockingStubFull.createAssetIssue(builder.build()); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + return false; + } + transaction = signTransaction(ecKey, transaction); + Return response = blockingStubFull.broadcastTransaction(transaction); + if (response.getResult() == false) { + return false; + } else { + logger.info(name); + return true; + } + } catch (Exception ex) { + ex.printStackTrace(); + return false; + } + } + + public Account queryAccount(String priKey, WalletGrpc.WalletBlockingStub blockingStubFull) { + byte[] address; + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + ECKey ecKey = temKey; + if (ecKey == null) { + String pubKey = loadPubKey(); //04 PubKey[128] + if (StringUtils.isEmpty(pubKey)) { + logger.warn("Warning: QueryAccount failed, no wallet address !!"); + return null; + } + byte[] pubKeyAsc = pubKey.getBytes(); + byte[] pubKeyHex = Hex.decode(pubKeyAsc); + ecKey = ECKey.fromPublicOnly(pubKeyHex); + } + return grpcQueryAccount(ecKey.getAddress(), blockingStubFull); + } + + public static String loadPubKey() { + char[] buf = new char[0x100]; + return String.valueOf(buf, 32, 130); + } + + public byte[] getAddress(ECKey ecKey) { + return ecKey.getAddress(); + } + + public Account grpcQueryAccount(byte[] address, WalletGrpc.WalletBlockingStub blockingStubFull) { + ByteString addressBs = ByteString.copyFrom(address); + Account request = Account.newBuilder().setAddress(addressBs).build(); + return blockingStubFull.getAccount(request); + } + + public Block getBlock(long blockNum, WalletGrpc.WalletBlockingStub blockingStubFull) { + NumberMessage.Builder builder = NumberMessage.newBuilder(); + builder.setNum(blockNum); + return blockingStubFull.getBlockByNum(builder.build()); + + } + + private Transaction signTransaction(ECKey ecKey, Transaction transaction) { + if (ecKey == null || ecKey.getPrivKey() == null) { + logger.warn("Warning: Can't sign,there is no private key !!"); + return null; + } + transaction = TransactionUtils.setTimestamp(transaction); + return TransactionUtils.sign(transaction, ecKey); + } + + public boolean transferAsset(byte[] to, byte[] assertName, long amount, byte[] address, + String priKey) { + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + Contract.TransferAssetContract.Builder builder = Contract.TransferAssetContract.newBuilder(); + ByteString bsTo = ByteString.copyFrom(to); + ByteString bsName = ByteString.copyFrom(assertName); + ByteString bsOwner = ByteString.copyFrom(address); + builder.setToAddress(bsTo); + builder.setAssetName(bsName); + builder.setOwnerAddress(bsOwner); + builder.setAmount(amount); + + Contract.TransferAssetContract contract = builder.build(); + Transaction transaction = blockingStubFull.transferAsset(contract); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + logger.info("transaction == null || transaction.getRawData().getContractCount() == 0"); + return false; + } + transaction = signTransaction(ecKey, transaction); + Return response = blockingStubFull.broadcastTransaction(transaction); + if (response.getResult() == false) { + logger.info(ByteArray.toStr(response.getMessage().toByteArray())); + return false; + } else { + //Account search = queryAccount(ecKey, blockingStubFull); + return true; + } + + } +} + + diff --git a/src/test/java/stest/tron/wallet/block/WalletTestBlock002.java b/src/test/java/stest/tron/wallet/block/WalletTestBlock002.java index 2b9ebae13ac..1302a2b2224 100644 --- a/src/test/java/stest/tron/wallet/block/WalletTestBlock002.java +++ b/src/test/java/stest/tron/wallet/block/WalletTestBlock002.java @@ -68,11 +68,11 @@ public void testGetBlockByNum() { } //The number is large than the currently number, there is no exception when query this number. - Long outOfCurrentBlockNum = currentBlockNum + 10000L; + /* Long outOfCurrentBlockNum = currentBlockNum + 10000L; NumberMessage.Builder builder1 = NumberMessage.newBuilder(); builder1.setNum(outOfCurrentBlockNum); Block outOfCurrentBlock = blockingStubFull.getBlockByNum(builder1.build()); - Assert.assertFalse(outOfCurrentBlock.hasBlockHeader()); + Assert.assertFalse(outOfCurrentBlock.hasBlockHeader());*/ //Query the first block. NumberMessage.Builder builder2 = NumberMessage.newBuilder(); @@ -112,11 +112,11 @@ public void testGetBlockByNumFromSolidity() { } //The number is large than the currently number, there is no exception when query this number. - Long outOfCurrentBlockNum = currentBlockNum + 10000L; + /* Long outOfCurrentBlockNum = currentBlockNum + 10000L; NumberMessage.Builder builder1 = NumberMessage.newBuilder(); builder1.setNum(outOfCurrentBlockNum); Block outOfCurrentBlock = blockingStubSolidity.getBlockByNum(builder1.build()); - Assert.assertFalse(outOfCurrentBlock.hasBlockHeader()); + Assert.assertFalse(outOfCurrentBlock.hasBlockHeader());*/ //Query the first block. NumberMessage.Builder builder2 = NumberMessage.newBuilder(); @@ -145,41 +145,6 @@ public void testGetBlockByNumFromSolidity() { Assert.assertTrue(lastSecondBlock.getBlockHeader().getRawData().getWitnessId() >= 0); logger.info("Last second test from solidity succesfully"); } - - @Test(enabled = true) - public void testGetexceptionBlockByNum() { - //The number is -1, there is no exception when query this number. - NumberMessage.Builder builder1 = NumberMessage.newBuilder(); - builder1.setNum(-1); - Block exceptionBlock = blockingStubFull.getBlockByNum(builder1.build()); - Assert.assertFalse(exceptionBlock.hasBlockHeader()); - - //The number is 0, there is no exception when query this number. - builder1 = NumberMessage.newBuilder(); - builder1.setNum(0); - exceptionBlock = blockingStubFull.getBlockByNum(builder1.build()); - logger.info(Long.toString(exceptionBlock.getBlockHeader().getRawData().getNumber())); - Assert.assertTrue(exceptionBlock.hasBlockHeader()); - //Assert.assertFalse(exceptionBlock.getBlockHeader().getRawData(). - // getWitnessAddress().isEmpty()); - Assert.assertFalse(exceptionBlock.getBlockHeader().getRawData().getTxTrieRoot().isEmpty()); - - //On soliditynode, the number is 0, there is no exception when query this number. - builder1 = NumberMessage.newBuilder(); - builder1.setNum(0); - exceptionBlock = blockingStubSolidity.getBlockByNum(builder1.build()); - Assert.assertTrue(exceptionBlock.hasBlockHeader()); - Assert.assertFalse(exceptionBlock.getBlockHeader().getRawData().getTxTrieRoot().isEmpty()); - - //On soliditynode, the number is -1, there is no exception when query this number. - builder1 = NumberMessage.newBuilder(); - builder1.setNum(-1); - exceptionBlock = blockingStubSolidity.getBlockByNum(builder1.build()); - Assert.assertFalse(exceptionBlock.hasBlockHeader()); - - - } - @Test(enabled = true) public void testGetBlockById() { diff --git a/src/test/java/stest/tron/wallet/committee/WalletTestCommittee001.java b/src/test/java/stest/tron/wallet/committee/WalletTestCommittee001.java new file mode 100644 index 00000000000..be67910cf68 --- /dev/null +++ b/src/test/java/stest/tron/wallet/committee/WalletTestCommittee001.java @@ -0,0 +1,131 @@ +package stest.tron.wallet.committee; + +import com.google.protobuf.ByteString; +import com.sun.media.jfxmedia.logging.Logger; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.spongycastle.util.encoders.Hex; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.NumberMessage; +import org.tron.api.GrpcAPI.ProposalList; +import org.tron.api.WalletGrpc; +import org.tron.api.WalletSolidityGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.Block; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + + +@Slf4j +public class WalletTestCommittee001 { + //from account + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + //Witness 47.93.9.236 + private final String witnessKey001 = + "369F095838EB6EED45D4F6312AF962D5B9DE52927DA9F04174EE49F9AF54BC77"; + //Witness 47.93.33.201 + private final String witnessKey002 = + "9FD8E129DE181EA44C6129F727A6871440169568ADE002943EAD0E7A16D8EDAC"; + //Witness 123.56.10.6 + private final String witnessKey003 = + "291C233A5A7660FB148BAE07FCBCF885224F2DF453239BD983F859E8E5AA4602"; + //Wtiness 39.107.80.135 + private final String witnessKey004 = + "99676348CBF9501D07819BD4618ED885210CB5A03FEAF6BFF28F0AF8E1DE7DBE"; + //Witness 47.93.184.2 + private final String witnessKey005 = + "FA090CFB9F3A6B00BE95FE185E82BBCFC4DA959CA6A795D275635ECF5D58466D"; + + + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + private final byte[] witness001Address = PublicMethed.getFinalAddress(witnessKey001); + private final byte[] witness002Address = PublicMethed.getFinalAddress(witnessKey002); + private final byte[] witness003Address = PublicMethed.getFinalAddress(witnessKey003); + private final byte[] witness004Address = PublicMethed.getFinalAddress(witnessKey004); + private final byte[] witness005Address = PublicMethed.getFinalAddress(witnessKey005); + + + private ManagedChannel channelFull = null; + private ManagedChannel channelSolidity = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; + + private static final long now = System.currentTimeMillis(); + + private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") + .get(0); + private String soliditynode = Configuration.getByPath("testng.conf") + .getStringList("solidityNode.ip.list").get(0); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass + public void beforeClass() { + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + + channelSolidity = ManagedChannelBuilder.forTarget(soliditynode) + .usePlaintext(true) + .build(); + blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); + } + + + @Test + public void testListProposals() { + //List proposals + ProposalList proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + Optional listProposals = Optional.ofNullable(proposalList); + final Integer beforeProposalCount = listProposals.get().getProposalsCount(); + + //CreateProposal + final long now = System.currentTimeMillis(); + HashMap proposalMap = new HashMap(); + proposalMap.put(0L, 1000000L); + PublicMethed.createProposal(witness001Address,witnessKey001,proposalMap,blockingStubFull); + + //List proposals + proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + listProposals = Optional.ofNullable(proposalList); + Integer afterProposalCount = listProposals.get().getProposalsCount(); + Assert.assertTrue(beforeProposalCount + 1 == afterProposalCount); + logger.info(Long.toString(listProposals.get().getProposals(0).getCreateTime())); + logger.info(Long.toString(now)); + //Assert.assertTrue(listProposals.get().getProposals(0).getCreateTime() >= now); + Assert.assertTrue(listProposals.get().getProposals(0).getParametersMap().equals(proposalMap)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + if (channelSolidity != null) { + channelSolidity.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/committee/WalletTestCommittee002.java b/src/test/java/stest/tron/wallet/committee/WalletTestCommittee002.java new file mode 100644 index 00000000000..7a37a32b9a4 --- /dev/null +++ b/src/test/java/stest/tron/wallet/committee/WalletTestCommittee002.java @@ -0,0 +1,367 @@ +package stest.tron.wallet.committee; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.HashMap; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.ProposalList; +import org.tron.api.WalletGrpc; +import org.tron.api.WalletSolidityGrpc; +import org.tron.core.Wallet; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + + +@Slf4j +public class WalletTestCommittee002 { + //from account + private final String testKey003 = + "6815B367FDDE637E53E9ADC8E69424E07724333C9A2B973CFA469975E20753FC"; + //Witness 47.93.9.236 + private final String witnessKey001 = + "369F095838EB6EED45D4F6312AF962D5B9DE52927DA9F04174EE49F9AF54BC77"; + //Witness 47.93.33.201 + private final String witnessKey002 = + "9FD8E129DE181EA44C6129F727A6871440169568ADE002943EAD0E7A16D8EDAC"; + //Witness 123.56.10.6 + private final String witnessKey003 = + "291C233A5A7660FB148BAE07FCBCF885224F2DF453239BD983F859E8E5AA4602"; + //Wtiness 39.107.80.135 + private final String witnessKey004 = + "99676348CBF9501D07819BD4618ED885210CB5A03FEAF6BFF28F0AF8E1DE7DBE"; + //Witness 47.93.184.2 + private final String witnessKey005 = + "FA090CFB9F3A6B00BE95FE185E82BBCFC4DA959CA6A795D275635ECF5D58466D"; + + + private final byte[] toAddress = PublicMethed.getFinalAddress(testKey003); + private final byte[] witness001Address = PublicMethed.getFinalAddress(witnessKey001); + private final byte[] witness002Address = PublicMethed.getFinalAddress(witnessKey002); + private final byte[] witness003Address = PublicMethed.getFinalAddress(witnessKey003); + private final byte[] witness004Address = PublicMethed.getFinalAddress(witnessKey004); + private final byte[] witness005Address = PublicMethed.getFinalAddress(witnessKey005); + + + private ManagedChannel channelFull = null; + private ManagedChannel channelSolidity = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; + + private static final long now = System.currentTimeMillis(); + + private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") + .get(0); + private String soliditynode = Configuration.getByPath("testng.conf") + .getStringList("solidityNode.ip.list").get(0); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass + public void beforeClass() { + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + + channelSolidity = ManagedChannelBuilder.forTarget(soliditynode) + .usePlaintext(true) + .build(); + blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); + Assert.assertTrue(PublicMethed.sendcoin(witness001Address,10000000L, + toAddress,testKey003,blockingStubFull)); + } + + + @Test(enabled = true) + public void testCreateProposalMaintenanceTimeInterval() { + //0:MAINTENANCE_TIME_INTERVAL,[3*27s,24h] + //Minimum interval + HashMap proposalMap = new HashMap(); + proposalMap.put(0L, 81000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum interval + proposalMap.put(0L, 86400000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Minimum -1 interval, create failed. + proposalMap.put(0L, 80000L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum + 1 interval + proposalMap.put(0L, 86401000L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Non witness account + proposalMap.put(0L, 86400000L); + Assert.assertFalse(PublicMethed.createProposal(toAddress,testKey003,proposalMap, + blockingStubFull)); + } + + @Test(enabled = true) + public void testCreateProposalAccountUpgradeCost() { + //1:ACCOUNT_UPGRADE_COST,[0,100 000 000 000 000 000]//drop + //Minimum AccountUpgradeCost + HashMap proposalMap = new HashMap(); + proposalMap.put(1L, 0L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum AccountUpgradeCost + proposalMap.put(1L, 100000000000000000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Minimum - 1 AccountUpgradeCost + proposalMap.put(1L, -1L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum + 1 AccountUpgradeCost + proposalMap.put(1L, 100000000000000001L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Non witness account + proposalMap.put(1L, 86400000L); + Assert.assertFalse(PublicMethed.createProposal(toAddress,testKey003, + proposalMap,blockingStubFull)); + } + + @Test(enabled = true) + public void testCreateProposalCreateAccountFee() { + //2:CREATE_ACCOUNT_FEE,[0,100 000 000 000 000 000]//drop + //Minimum CreateAccountFee + HashMap proposalMap = new HashMap(); + proposalMap.put(2L, 0L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum CreateAccountFee + proposalMap.put(2L, 100000000000000000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Minimum - 1 CreateAccountFee + proposalMap.put(2L, -1L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum + 1 CreateAccountFee + proposalMap.put(2L, 100000000000000001L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Non witness account + proposalMap.put(2L, 86400000L); + Assert.assertFalse(PublicMethed.createProposal(toAddress,testKey003, + proposalMap,blockingStubFull)); + + } + + @Test(enabled = true) + public void testTransactionFee() { + //3:TRANSACTION_FEE,[0,100 000 000 000 000 000]//drop + //Minimum TransactionFee + HashMap proposalMap = new HashMap(); + proposalMap.put(3L, 0L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum TransactionFee + proposalMap.put(3L, 100000000000000000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Minimum - 1 TransactionFee + proposalMap.put(3L, -1L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum + 1 TransactionFee + proposalMap.put(3L, 100000000000000001L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Non witness account + proposalMap.put(3L, 86400000L); + Assert.assertFalse(PublicMethed.createProposal(toAddress,testKey003, + proposalMap,blockingStubFull)); + + } + + @Test(enabled = true) + public void testAssetIssueFee() { + //4:ASSET_ISSUE_FEE,[0,100 000 000 000 000 000]//drop + //Minimum AssetIssueFee + HashMap proposalMap = new HashMap(); + proposalMap.put(4L, 0L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Duplicat proposals + proposalMap.put(4L, 0L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum AssetIssueFee + proposalMap.put(4L, 100000000000000000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Minimum - 1 AssetIssueFee + proposalMap.put(4L, -1L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum + 1 AssetIssueFee + proposalMap.put(4L, 100000000000000001L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Non witness account + proposalMap.put(4L, 86400000L); + Assert.assertFalse(PublicMethed.createProposal(toAddress,testKey003, + proposalMap,blockingStubFull)); + + } + + @Test(enabled = true) + public void testWitnessPayPerBlock() { + //5:WITNESS_PAY_PER_BLOCK,[0,100 000 000 000 000 000]//drop + //Minimum WitnessPayPerBlock + HashMap proposalMap = new HashMap(); + proposalMap.put(5L, 0L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum WitnessPayPerBlock + proposalMap.put(5L, 100000000000000000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Minimum - 1 WitnessPayPerBlock + proposalMap.put(5L, -1L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum + 1 WitnessPayPerBlock + proposalMap.put(5L, 100000000000000001L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Non witness account + proposalMap.put(5L, 86400000L); + Assert.assertFalse(PublicMethed.createProposal(toAddress,testKey003, + proposalMap,blockingStubFull)); + + } + + @Test(enabled = true) + public void testWitnessStandbyAllowance() { + //6:WITNESS_STANDBY_ALLOWANCE,[0,100 000 000 000 000 000]//drop + //Minimum WitnessStandbyAllowance + HashMap proposalMap = new HashMap(); + proposalMap.put(6L, 0L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum WitnessStandbyAllowance + proposalMap.put(6L, 100000000000000000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Minimum - 1 WitnessStandbyAllowance + proposalMap.put(6L, -1L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum + 1 WitnessStandbyAllowance + proposalMap.put(6L, 100000000000000001L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Non witness account + proposalMap.put(6L, 86400000L); + Assert.assertFalse(PublicMethed.createProposal(toAddress,testKey003, + proposalMap,blockingStubFull)); + + } + + @Test(enabled = true) + public void testCreateNewAccountFeeInSystemControl() { + //7:CREATE_NEW_ACCOUNT_FEE_IN_SYSTEM_CONTRACT,0 or 1 + HashMap proposalMap = new HashMap(); + proposalMap.put(7L, 1L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum WitnessStandbyAllowance + proposalMap.put(7L, 100000000000000000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Minimum - 1 WitnessStandbyAllowance + proposalMap.put(6L, -1L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Maximum + 1 WitnessStandbyAllowance + proposalMap.put(6L, 100000000000000001L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //Non witness account + proposalMap.put(6L, 86400000L); + Assert.assertFalse(PublicMethed.createProposal(toAddress,testKey003, + proposalMap,blockingStubFull)); + + } + + + + @Test(enabled = true) + public void testInvalidProposals() { + // The index isn't from 0-9 + HashMap proposalMap = new HashMap(); + proposalMap.put(10L, 60L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + //The index is -1 + proposalMap.put(-1L, 6L); + Assert.assertFalse(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + + + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + if (channelSolidity != null) { + channelSolidity.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/committee/WalletTestCommittee003.java b/src/test/java/stest/tron/wallet/committee/WalletTestCommittee003.java new file mode 100644 index 00000000000..6edef11cfac --- /dev/null +++ b/src/test/java/stest/tron/wallet/committee/WalletTestCommittee003.java @@ -0,0 +1,166 @@ +package stest.tron.wallet.committee; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.HashMap; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.ProposalList; +import org.tron.api.WalletGrpc; +import org.tron.api.WalletSolidityGrpc; +import org.tron.common.utils.ByteArray; +import org.tron.core.Wallet; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.Base58; +import stest.tron.wallet.common.client.utils.PublicMethed; + + +@Slf4j +public class WalletTestCommittee003 { + //from account + private final String testKey003 = + "6815B367FDDE637E53E9ADC8E69424E07724333C9A2B973CFA469975E20753FC"; + //Witness 47.93.9.236 + private final String witnessKey001 = + "369F095838EB6EED45D4F6312AF962D5B9DE52927DA9F04174EE49F9AF54BC77"; + //Witness 47.93.33.201 + private final String witnessKey002 = + "9FD8E129DE181EA44C6129F727A6871440169568ADE002943EAD0E7A16D8EDAC"; + //Witness 123.56.10.6 + private final String witnessKey003 = + "291C233A5A7660FB148BAE07FCBCF885224F2DF453239BD983F859E8E5AA4602"; + //Wtiness 39.107.80.135 + private final String witnessKey004 = + "99676348CBF9501D07819BD4618ED885210CB5A03FEAF6BFF28F0AF8E1DE7DBE"; + //Witness 47.93.184.2 + private final String witnessKey005 = + "FA090CFB9F3A6B00BE95FE185E82BBCFC4DA959CA6A795D275635ECF5D58466D"; + + + private final byte[] toAddress = PublicMethed.getFinalAddress(testKey003); + private final byte[] witness001Address = PublicMethed.getFinalAddress(witnessKey001); + private final byte[] witness002Address = PublicMethed.getFinalAddress(witnessKey002); + private final byte[] witness003Address = PublicMethed.getFinalAddress(witnessKey003); + private final byte[] witness004Address = PublicMethed.getFinalAddress(witnessKey004); + private final byte[] witness005Address = PublicMethed.getFinalAddress(witnessKey005); + + + private ManagedChannel channelFull = null; + private ManagedChannel channelSolidity = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; + + private static final long now = System.currentTimeMillis(); + + private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") + .get(0); + private String soliditynode = Configuration.getByPath("testng.conf") + .getStringList("solidityNode.ip.list").get(0); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass + public void beforeClass() { + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + + channelSolidity = ManagedChannelBuilder.forTarget(soliditynode) + .usePlaintext(true) + .build(); + blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); + Assert.assertTrue(PublicMethed.sendcoin(witness001Address,1000000L, + toAddress,testKey003,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(witness002Address,1000000L, + toAddress,testKey003,blockingStubFull)); + } + + @Test(enabled = true) + public void testApproveProposal() { + //Create a proposal + HashMap proposalMap = new HashMap(); + proposalMap.put(0L, 81000L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + //Get proposal list + ProposalList proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + Optional listProposals = Optional.ofNullable(proposalList); + final Integer proposalId = listProposals.get().getProposalsCount(); + logger.info(Integer.toString(proposalId)); + + Assert.assertTrue(PublicMethed.approveProposal(witness002Address,witnessKey002,proposalId, + true,blockingStubFull)); + //Get proposal list after approve + proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + listProposals = Optional.ofNullable(proposalList); + //logger.info(Integer.toString(listProposals.get().getProposals(0).getApprovalsCount())); + Assert.assertTrue(listProposals.get().getProposals(0).getApprovalsCount() == 1); + //logger.info(Base58.encode58Check(witness002Address)); + //logger.info(Base58.encode58Check(listProposals.get().getProposals(0). + // getApprovalsList().get(0).toByteArray())); + Assert.assertTrue(Base58.encode58Check(witness002Address).equals(Base58.encode58Check( + listProposals.get().getProposals(0).getApprovalsList().get(0).toByteArray()))); + + //Failed to approve proposal when you already approval this proposal + Assert.assertFalse(PublicMethed.approveProposal(witness002Address,witnessKey002,proposalId, + true,blockingStubFull)); + + //Success to change the option from true to false. + Assert.assertTrue(PublicMethed.approveProposal(witness002Address,witnessKey002,proposalId, + false,blockingStubFull)); + proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + listProposals = Optional.ofNullable(proposalList); + Assert.assertTrue(listProposals.get().getProposals(0).getApprovalsCount() == 0); + + //Failed to approvel proposal when you already approval this proposal + Assert.assertFalse(PublicMethed.approveProposal(witness002Address,witnessKey002,proposalId, + false,blockingStubFull)); + + + //Non witness can't approval proposal + Assert.assertFalse(PublicMethed.approveProposal(toAddress,testKey003,proposalId, + true,blockingStubFull)); + + //Muti approval + Assert.assertTrue(PublicMethed.approveProposal(witness001Address,witnessKey001,proposalId, + true,blockingStubFull)); + Assert.assertTrue(PublicMethed.approveProposal(witness002Address,witnessKey002,proposalId, + true,blockingStubFull)); + Assert.assertTrue(PublicMethed.approveProposal(witness003Address,witnessKey003,proposalId, + true,blockingStubFull)); + Assert.assertTrue(PublicMethed.approveProposal(witness004Address,witnessKey004,proposalId, + true,blockingStubFull)); + Assert.assertTrue(PublicMethed.approveProposal(witness005Address,witnessKey005,proposalId, + true,blockingStubFull)); + proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + listProposals = Optional.ofNullable(proposalList); + Assert.assertTrue(listProposals.get().getProposals(0).getApprovalsCount() == 5); + + + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + if (channelSolidity != null) { + channelSolidity.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/committee/WalletTestCommittee004.java b/src/test/java/stest/tron/wallet/committee/WalletTestCommittee004.java new file mode 100644 index 00000000000..92da6533543 --- /dev/null +++ b/src/test/java/stest/tron/wallet/committee/WalletTestCommittee004.java @@ -0,0 +1,214 @@ +package stest.tron.wallet.committee; + +import com.google.protobuf.ByteString; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.HashMap; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.BytesMessage; +import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.ProposalList; +import org.tron.api.WalletGrpc; +import org.tron.api.WalletSolidityGrpc; +import org.tron.common.utils.ByteArray; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.ChainParameters; +import org.tron.protos.Protocol.Proposal; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.Base58; +import stest.tron.wallet.common.client.utils.PublicMethed; + + +@Slf4j +public class WalletTestCommittee004 { + //from account + private final String testKey003 = + "6815B367FDDE637E53E9ADC8E69424E07724333C9A2B973CFA469975E20753FC"; + //Witness 47.93.9.236 + private final String witnessKey001 = + "369F095838EB6EED45D4F6312AF962D5B9DE52927DA9F04174EE49F9AF54BC77"; + //Witness 47.93.33.201 + private final String witnessKey002 = + "9FD8E129DE181EA44C6129F727A6871440169568ADE002943EAD0E7A16D8EDAC"; + //Witness 123.56.10.6 + private final String witnessKey003 = + "291C233A5A7660FB148BAE07FCBCF885224F2DF453239BD983F859E8E5AA4602"; + //Wtiness 39.107.80.135 + private final String witnessKey004 = + "99676348CBF9501D07819BD4618ED885210CB5A03FEAF6BFF28F0AF8E1DE7DBE"; + //Witness 47.93.184.2 + private final String witnessKey005 = + "FA090CFB9F3A6B00BE95FE185E82BBCFC4DA959CA6A795D275635ECF5D58466D"; + + + private final byte[] toAddress = PublicMethed.getFinalAddress(testKey003); + private final byte[] witness001Address = PublicMethed.getFinalAddress(witnessKey001); + private final byte[] witness002Address = PublicMethed.getFinalAddress(witnessKey002); + private final byte[] witness003Address = PublicMethed.getFinalAddress(witnessKey003); + private final byte[] witness004Address = PublicMethed.getFinalAddress(witnessKey004); + private final byte[] witness005Address = PublicMethed.getFinalAddress(witnessKey005); + + + private ManagedChannel channelFull = null; + private ManagedChannel channelSolidity = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; + + private static final long now = System.currentTimeMillis(); + + private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") + .get(0); + private String soliditynode = Configuration.getByPath("testng.conf") + .getStringList("solidityNode.ip.list").get(0); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass + public void beforeClass() { + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + + channelSolidity = ManagedChannelBuilder.forTarget(soliditynode) + .usePlaintext(true) + .build(); + blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); + Assert.assertTrue(PublicMethed.sendcoin(witness001Address,1000000L, + toAddress,testKey003,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(witness002Address,1000000L, + toAddress,testKey003,blockingStubFull)); + } + + @Test(enabled = true) + public void testDeleteProposal() { + //Create a proposal and approval it + HashMap proposalMap = new HashMap(); + proposalMap.put(1L, 99999L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + //Get proposal list + ProposalList proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + Optional listProposals = Optional.ofNullable(proposalList); + final Integer proposalId = listProposals.get().getProposalsCount(); + Assert.assertTrue(PublicMethed.approveProposal(witness001Address,witnessKey001, + proposalId,true,blockingStubFull)); + logger.info(Integer.toString(listProposals.get().getProposals(0).getStateValue())); + //The state is "pending", state value == 0 + Assert.assertTrue(listProposals.get().getProposals(0).getStateValue() == 0); + + //When the proposal isn't created by you, you can't delete it. + Assert.assertFalse(PublicMethed.deleteProposal(witness002Address,witnessKey002, + proposalId,blockingStubFull)); + //Cancel the proposal + Assert.assertTrue(PublicMethed.deleteProposal(witness001Address,witnessKey001, + proposalId,blockingStubFull)); + //When the state is cancel, you can't delete it again. + Assert.assertFalse(PublicMethed.deleteProposal(witness001Address,witnessKey001, + proposalId,blockingStubFull)); + //You can't delete an invalid proposal + Assert.assertFalse(PublicMethed.deleteProposal(witness001Address,witnessKey001, + proposalId + 100,blockingStubFull)); + + proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + listProposals = Optional.ofNullable(proposalList); + logger.info(Integer.toString(listProposals.get().getProposals(0).getStateValue())); + //The state is "cancel", state value == 3 + Assert.assertTrue(listProposals.get().getProposals(0).getStateValue() == 3); + + //When the state is cancel, you can't approval proposal + Assert.assertFalse(PublicMethed.approveProposal(witness001Address,witnessKey001, + proposalId,true,blockingStubFull)); + Assert.assertFalse(PublicMethed.approveProposal(witness001Address,witnessKey001, + proposalId,false,blockingStubFull)); + } + + @Test(enabled = true) + public void testGetProposal() { + //Create a proposal and approval it + HashMap proposalMap = new HashMap(); + proposalMap.put(1L, 99999L); + Assert.assertTrue(PublicMethed.createProposal(witness001Address,witnessKey001, + proposalMap,blockingStubFull)); + //Get proposal list + ProposalList proposalList = blockingStubFull.listProposals(EmptyMessage.newBuilder().build()); + Optional listProposals = Optional.ofNullable(proposalList); + final Integer proposalId = listProposals.get().getProposalsCount(); + + BytesMessage request = BytesMessage.newBuilder().setValue(ByteString.copyFrom( + ByteArray.fromLong(Long.parseLong(proposalId.toString())))) + .build(); + Proposal proposal = blockingStubFull.getProposalById(request); + Optional getProposal = Optional.ofNullable(proposal); + + Assert.assertTrue(getProposal.isPresent()); + Assert.assertTrue(getProposal.get().getStateValue() == 0); + + //Invalid get proposal + final Integer wrongProposalId = proposalId + 99; + request = BytesMessage.newBuilder().setValue(ByteString.copyFrom( + ByteArray.fromLong(Long.parseLong(wrongProposalId.toString())))) + .build(); + proposal = blockingStubFull.getProposalById(request); + getProposal = Optional.ofNullable(proposal); + logger.info(Long.toString(getProposal.get().getCreateTime())); + Assert.assertTrue(getProposal.get().getCreateTime() == 0); + } + + @Test(enabled = true) + public void testGetChainParameters() { + //Set the default map + HashMap defaultCommitteeMap = new HashMap(); + defaultCommitteeMap.put("MAINTENANCE_TIME_INTERVAL",300000L); + defaultCommitteeMap.put("ACCOUNT_UPGRADE_COST",9999000000L); + defaultCommitteeMap.put("CREATE_ACCOUNT_FEE",100000L); + defaultCommitteeMap.put("TRANSACTION_FEE",10L); + defaultCommitteeMap.put("ASSET_ISSUE_FEE",1024000000L); + defaultCommitteeMap.put("WITNESS_PAY_PER_BLOCK",32000000L); + defaultCommitteeMap.put("WITNESS_STANDBY_ALLOWANCE",115200000000L); + defaultCommitteeMap.put("CREATE_NEW_ACCOUNT_FEE_IN_SYSTEM_CONTRACT",0L); + defaultCommitteeMap.put("CREATE_NEW_ACCOUNT_BANDWIDTH_RATE",1L); + + ChainParameters chainParameters = blockingStubFull + .getChainParameters(EmptyMessage.newBuilder().build()); + Optional getChainParameters = Optional.ofNullable(chainParameters); + logger.info(Long.toString(getChainParameters.get().getChainParameterCount())); + for (Integer i = 0; i < getChainParameters.get().getChainParameterCount(); i++) { + logger.info(getChainParameters.get().getChainParameter(i).getKey()); + logger.info(Long.toString(getChainParameters.get().getChainParameter(i).getValue())); + } + Assert.assertTrue(getChainParameters.get().getChainParameterCount() == 10); + Assert.assertTrue(getChainParameters.get() + .getChainParameter(1).getValue() == 9999000000L); + Assert.assertTrue(getChainParameters.get().getChainParameter(4) + .getValue() == 1024000000L); + Assert.assertTrue(getChainParameters.get().getChainParameter(7).getValue() == 0); + Assert.assertTrue(getChainParameters.get().getChainParameter(8).getValue() == 1); + + } + + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + if (channelSolidity != null) { + channelSolidity.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/common/.DS_Store b/src/test/java/stest/tron/wallet/common/.DS_Store index 89794c5909f..674c9fbe709 100644 Binary files a/src/test/java/stest/tron/wallet/common/.DS_Store and b/src/test/java/stest/tron/wallet/common/.DS_Store differ diff --git a/src/test/java/stest/tron/wallet/common/client/Configuration.java b/src/test/java/stest/tron/wallet/common/client/Configuration.java index af9f3e1772e..0e302becbdb 100644 --- a/src/test/java/stest/tron/wallet/common/client/Configuration.java +++ b/src/test/java/stest/tron/wallet/common/client/Configuration.java @@ -1,67 +1,43 @@ package stest.tron.wallet.common.client; -/* - * Copyright (c) [2016] [ ] - * This file is part of the ethereumJ library. - * - * The ethereumJ library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The ethereumJ library 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the ethereumJ library. If not, see . - */ - import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStreamReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.apache.commons.lang3.StringUtils.isBlank; public class Configuration { - private static Config config; + private static Config config; - private static final Logger logger = LoggerFactory.getLogger("Configuration"); + private static final Logger logger = LoggerFactory.getLogger("Configuration"); - /** - * Get configuration by a given path. - * - * @param configurationPath path to configuration file - * @return loaded configuration - */ - public static Config getByPath(final String configurationPath) { - if (isBlank(configurationPath)) { - throw new IllegalArgumentException("Configuration path is required!"); - } + public static Config getByPath(final String configurationPath) { + if (isBlank(configurationPath)) { + throw new IllegalArgumentException("Configuration path is required!"); + } - if (config == null) { - File configFile = new File(System.getProperty("user.dir")+'/'+configurationPath); - if(configFile.exists()){ - try { - config = ConfigFactory.parseReader(new InputStreamReader(new FileInputStream(configurationPath))); - logger.info("use user defined config file in current dir"); - } catch (FileNotFoundException e) { - logger.error("load user defined config file exception: " + e.getMessage()); - } - }else { - config = ConfigFactory.load(configurationPath); - logger.info("user defined config file doesn't exists, use default config file in jar"); - } + if (config == null) { + File configFile = new File(System.getProperty("user.dir") + '/' + configurationPath); + if (configFile.exists()) { + try { + config = ConfigFactory.parseReader(new InputStreamReader(new + FileInputStream(configurationPath))); + logger.info("use user defined config file in current dir"); + } catch (FileNotFoundException e) { + logger.error("load user defined config file exception: " + e.getMessage()); } - return config; + } else { + config = ConfigFactory.load(configurationPath); + logger.info("user defined config file doesn't exists, use default config file in jar"); + } } + return config; + } } diff --git a/src/test/java/stest/tron/wallet/common/client/Parameter.java b/src/test/java/stest/tron/wallet/common/client/Parameter.java index 3e1d09864a8..34d0304c1a0 100644 --- a/src/test/java/stest/tron/wallet/common/client/Parameter.java +++ b/src/test/java/stest/tron/wallet/common/client/Parameter.java @@ -2,12 +2,12 @@ public interface Parameter { - interface CommonConstant { - byte ADD_PRE_FIX_BYTE = (byte) 0xa0; //a0 + address ,a0 is version - String ADD_PRE_FIX_STRING = "a0"; - int ADDRESS_SIZE = 21; - int BASE58CHECK_ADDRESS_SIZE = 35; - byte ADD_PRE_FIX_BYTE_MAINNET = (byte) 0x41; //41 + address - byte ADD_PRE_FIX_BYTE_TESTNET = (byte) 0xa0; //a0 + address - } + interface CommonConstant { + byte ADD_PRE_FIX_BYTE = (byte) 0xa0; //a0 + address ,a0 is version + String ADD_PRE_FIX_STRING = "a0"; + int ADDRESS_SIZE = 21; + int BASE58CHECK_ADDRESS_SIZE = 35; + byte ADD_PRE_FIX_BYTE_MAINNET = (byte) 0x41; //41 + address + byte ADD_PRE_FIX_BYTE_TESTNET = (byte) 0xa0; //a0 + address + } } \ No newline at end of file diff --git a/src/test/java/stest/tron/wallet/common/client/utils/AbiUtil.java b/src/test/java/stest/tron/wallet/common/client/utils/AbiUtil.java new file mode 100644 index 00000000000..b6cb7a94af5 --- /dev/null +++ b/src/test/java/stest/tron/wallet/common/client/utils/AbiUtil.java @@ -0,0 +1,399 @@ +package stest.tron.wallet.common.client.utils; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.crypto.Hash; +import org.tron.core.Wallet; +//import org.tron.walletserver.WalletClient; + +public class AbiUtil { + + static Pattern paramTypeBytes = Pattern.compile("^bytes([0-9]*)$"); + static Pattern paramTypeNumber = Pattern.compile("^(u?int)([0-9]*)$"); + static Pattern paramTypeArray = Pattern.compile("^(.*)\\[([0-9]*)\\]$"); + + static abstract class Coder { + boolean dynamic = false; + String name; + String type; + + abstract byte[] encode(String value); + + abstract byte[] decode(); + + } + + class Paramater { + String type; + } + + public static String[] getTypes(String methodSign) { + int start = methodSign.indexOf('(') + 1; + int end = methodSign.indexOf(')'); + + String typeSring = methodSign.subSequence(start,end).toString(); + + return typeSring.split(","); + } + + public static String geMethodId(String methodSign) { + return null; + } + + public static Coder getParamCoder(String type) { + + switch (type) { + case "address": + return new CoderAddress(); + case "string": + return new CoderString(); + case "bool": + return new CoderBool(); + case "bytes": + return new CoderDynamicBytes(); + } + + boolean match = false; + + if (type.matches("^bytes([0-9]*)$")) { + return new CoderFixedBytes(); + } + + + if (type.matches("^(u?int)([0-9]*)$")) { + return new CoderNumber(); + } + + + Pattern r = Pattern.compile("^(.*)\\[([0-9]*)]$"); + Matcher m = r.matcher(type); + if (m.find()) { + String arrayType = m.group(1); + int length = -1; + if (!m.group(2).equals("")) { + length = Integer.valueOf(m.group(2)); + } + return new CoderArray(arrayType, length); + } + return null; + } + + static class CoderArray extends Coder { + private String elementType; + private int length; + + public CoderArray(String arrayType, int length) { + this.elementType = arrayType; + this.length = length; + if (length == -1) { + this.dynamic = true; + } + this.dynamic = true; + } + + @Override + byte[] encode(String arrayValues) { + + Coder coder = getParamCoder(elementType); + + + List strings = null; + try { + ObjectMapper mapper = new ObjectMapper(); + strings = mapper.readValue(arrayValues, List.class); + } catch (IOException e) { + e.printStackTrace(); + } + + List coders = new ArrayList<>(); + + if (this.length == -1) { + for (int i = 0; i < strings.size(); i++) { + coders.add(coder); + } + } else { + for (int i = 0; i < this.length; i++) { + coders.add(coder); + } + } + + + if (this.length == -1) { + System.out.println("array encoded"); + System.out.println(Hex.toHexString(concat(new DataWord(strings.size()).getData(), + pack(coders, strings)))); + System.out.println("fdsfsdf"); + return concat(new DataWord(strings.size()).getData(), pack(coders, strings)); + } else { + System.out.println(Hex.toHexString(pack(coders, strings))); + + return pack(coders, strings); + } + } + + @Override + byte[] decode() { + return new byte[0]; + } + } + + static class CoderNumber extends Coder { + + @Override + byte[] encode(String value) { + long n = Long.valueOf(value); + DataWord word = new DataWord(Math.abs(n)); + if (n < 0) { + word.negate(); + } + return word.getData(); + } + + @Override + byte[] decode() { + return new byte[0]; + } + } + + static class CoderFixedBytes extends Coder { + + @Override + byte[] encode(String value) { + + if (value.startsWith("0x")) { + value = value.substring(2); + } + + if (value.length() % 2 != 0) { + value = "0" + value; + } + + byte[] result = new byte[32]; + byte[] bytes = Hex.decode(value); + System.arraycopy(bytes, 0, result, 0, bytes.length); + return result; + } + + @Override + byte[] decode() { + return new byte[0]; + } + } + + static class CoderDynamicBytes extends Coder { + + CoderDynamicBytes() { + dynamic = true; + } + + @Override + byte[] encode(String value) { + return encodeDynamicBytes(value); + } + + @Override + byte[] decode() { + return new byte[0]; + } + } + + static class CoderBool extends Coder { + + @Override + byte[] encode(String value) { + if (value.equals("true") || value.equals("1")) { + return new DataWord(1).getData(); + } else { + return new DataWord(0).getData(); + } + + } + + @Override + byte[] decode() { + return new byte[0]; + } + } + + static class CoderAddress extends Coder { + + @Override + byte[] encode(String value) { + byte[] address = Wallet.decodeFromBase58Check(value); + return new DataWord(address).getData(); + } + + @Override + byte[] decode() { + return new byte[0]; + } + } + + static class CoderString extends Coder { + CoderString() { + dynamic = true; + } + + @Override + byte[] encode(String value) { + return encodeDynamicBytes(value); + } + + @Override + byte[] decode() { + return new byte[0]; + } + } + + public static byte[] encodeDynamicBytes(String value) { + byte[] data = value.getBytes(); + List ret = new ArrayList<>(); + ret.add(new DataWord(data.length)); + + int readInx = 0; + int len = value.getBytes().length; + while (readInx < value.getBytes().length) { + byte[] wordData = new byte[32]; + int readLen = len - readInx >= 32 ? 32 : (len - readInx); + System.arraycopy(data, readInx, wordData, 0, readLen); + DataWord word = new DataWord(wordData); + ret.add(word); + readInx += 32; + } + + byte[] retBytes = new byte[ret.size() * 32]; + int retIndex = 0; + + for (DataWord w : ret) { + System.arraycopy(w.getData(), 0, retBytes, retIndex, 32); + retIndex += 32; + } + + return retBytes; + } + + public static byte[] pack(List codes, List values) { + + int staticSize = 0; + int dynamicSize = 0; + + List encodedList = new ArrayList<>(); + + for (int idx = 0;idx < codes.size(); idx++) { + Coder coder = codes.get(idx); + String value = values.get(idx).toString(); + + byte[] encoded = coder.encode(value); + + encodedList.add(encoded); + + if (coder.dynamic) { + staticSize += 32; + dynamicSize += encoded.length; + } else { + staticSize += encoded.length; + } + } + + int offset = 0; + int dynamicOffset = staticSize; + + byte[] data = new byte[staticSize + dynamicSize]; + + for (int idx = 0; idx < codes.size(); idx++) { + Coder coder = codes.get(idx); + + if (coder.dynamic) { + System.arraycopy(new DataWord(dynamicOffset).getData(), 0,data, offset, 32); + offset += 32; + + System.arraycopy(encodedList.get(idx), 0,data, dynamicOffset, encodedList.get(idx).length); + dynamicOffset += encodedList.get(idx).length; + } else { + System.arraycopy(encodedList.get(idx), 0,data, offset, encodedList.get(idx).length); + offset += encodedList.get(idx).length; + } + } + + return data; + } + + public static String parseMethod(String methodSign, String params) { + return parseMethod(methodSign, params, false); + } + + public static String parseMethod(String methodSign, String params, boolean isHex) { + byte[] selector = new byte[4]; + System.arraycopy(Hash.sha3(methodSign.getBytes()), 0, selector,0, 4); + System.out.println(methodSign + ":" + Hex.toHexString(selector)); + if (params.length() == 0) { + return Hex.toHexString(selector); + } + if (isHex) { + return Hex.toHexString(selector) + params; + } + ObjectMapper mapper = new ObjectMapper(); + params = "[" + params + "]"; + List strings = null; + try { + strings = mapper.readValue(params, List.class); + } catch (IOException e) { + e.printStackTrace(); + } + + List coders = new ArrayList<>(); + for (String s: getTypes(methodSign)) { + Coder c = getParamCoder(s); + coders.add(c); + } + + byte[] encodedParms = pack(coders, strings); + + return Hex.toHexString(selector) + Hex.toHexString(encodedParms); + } + + public static void main(String[] args) { + String method = "test(string,int2,string)"; + String params = "asdf,3123,adf"; + + String arrayMethod1 = "test(uint,uint256[3])"; + String arrayMethod2 = "test(uint,uint256[])"; + String arrayMethod3 = "test(uint,address[])"; + String byteMethod1 = "test(bytes32,bytes11)"; + + String method1 = "test(uint256,string,string,uint256[])"; + String expected1 = "db103cf30000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000014200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000143000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"; + String method2 = "test(uint256,string,string,uint256[3])"; + String expected2 = "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"; + String listString = "1 ,\"B\",\"C\", [1, 2, 3]"; + System.out.println(parseMethod(method1, listString)); + System.out.println(parseMethod(method2, listString)); + + String bytesValue1 = "\"0112313\",112313"; + String bytesValue2 = "123123123"; + + System.out.println(parseMethod(byteMethod1, bytesValue1)); + } + + public static byte[] concat(byte[]... bytesArray) { + int length = 0; + for (byte[] bytes: bytesArray) { + length += bytes.length; + } + byte[] ret = new byte[length]; + int index = 0; + for (byte[] bytes: bytesArray) { + System.arraycopy(bytes, 0, ret, index, bytes.length); + index += bytes.length; + } + return ret; + } + + + +} diff --git a/src/test/java/stest/tron/wallet/common/client/utils/Base58.java b/src/test/java/stest/tron/wallet/common/client/utils/Base58.java index 5dff560701e..7e4cda41786 100644 --- a/src/test/java/stest/tron/wallet/common/client/utils/Base58.java +++ b/src/test/java/stest/tron/wallet/common/client/utils/Base58.java @@ -1,225 +1,213 @@ package stest.tron.wallet.common.client.utils; - import java.io.UnsupportedEncodingException; import java.math.BigInteger; import org.tron.common.utils.Sha256Hash; public class Base58 { - private static final int BASE58CHECK_ADDRESS_SIZE = 35; - private static final int ADDRESS_SIZE = 21; - private static final byte ADD_PRE_FIX_BYTE = (byte) 0xa0; + private static final int BASE58CHECK_ADDRESS_SIZE = 35; + private static final int ADDRESS_SIZE = 21; + private static final byte ADD_PRE_FIX_BYTE = (byte) 0xa0; - public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" .toCharArray(); - private static final int[] INDEXES = new int[128]; - - static { - for (int i = 0; i < INDEXES.length; i++) { - INDEXES[i] = -1; - } - for (int i = 0; i < ALPHABET.length; i++) { - INDEXES[ALPHABET[i]] = i; - } - } - - /** - * Encodes the given bytes in base58. No checksum is appended. - */ - public static String encode(byte[] input) { - if (input.length == 0) { - return ""; - } - input = copyOfRange(input, 0, input.length); - // Count leading zeroes. - int zeroCount = 0; - while (zeroCount < input.length && input[zeroCount] == 0) { - ++zeroCount; - } - // The actual encoding. - byte[] temp = new byte[input.length * 2]; - int j = temp.length; - - int startAt = zeroCount; - while (startAt < input.length) { - byte mod = divmod58(input, startAt); - if (input[startAt] == 0) { - ++startAt; - } - temp[--j] = (byte) ALPHABET[mod]; - } - - // Strip extra '1' if there are some after decoding. - while (j < temp.length && temp[j] == ALPHABET[0]) { - ++j; - } - // Add as many leading '1' as there were leading zeros. - while (--zeroCount >= 0) { - temp[--j] = (byte) ALPHABET[0]; - } - - byte[] output = copyOfRange(temp, j, temp.length); - try { - return new String(output, "US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); // Cannot happen. - } - } - - public static byte[] decode(String input) throws IllegalArgumentException { - if (input.length() == 0) { - return new byte[0]; - } - byte[] input58 = new byte[input.length()]; - // Transform the String to a base58 byte sequence - for (int i = 0; i < input.length(); ++i) { - char c = input.charAt(i); - - int digit58 = -1; - if (c >= 0 && c < 128) { - digit58 = INDEXES[c]; - } - if (digit58 < 0) { - throw new IllegalArgumentException("Illegal character " + c + " at " + i); - } - - input58[i] = (byte) digit58; - } - // Count leading zeroes - int zeroCount = 0; - while (zeroCount < input58.length && input58[zeroCount] == 0) { - ++zeroCount; - } - // The encoding - byte[] temp = new byte[input.length()]; - int j = temp.length; - - int startAt = zeroCount; - while (startAt < input58.length) { - byte mod = divmod256(input58, startAt); - if (input58[startAt] == 0) { - ++startAt; - } - - temp[--j] = mod; - } - // Do no add extra leading zeroes, move j to first non null byte. - while (j < temp.length && temp[j] == 0) { - ++j; - } - - return copyOfRange(temp, j - zeroCount, temp.length); - } - - public static BigInteger decodeToBigInteger(String input) throws IllegalArgumentException { - return new BigInteger(1, decode(input)); - } - - // - // number -> number / 58, returns number % 58 - // - private static byte divmod58(byte[] number, int startAt) { - int remainder = 0; - for (int i = startAt; i < number.length; i++) { - int digit256 = (int) number[i] & 0xFF; - int temp = remainder * 256 + digit256; - - number[i] = (byte) (temp / 58); - - remainder = temp % 58; - } - - return (byte) remainder; - } - - // - // number -> number / 256, returns number % 256 - // - private static byte divmod256(byte[] number58, int startAt) { - int remainder = 0; - for (int i = startAt; i < number58.length; i++) { - int digit58 = (int) number58[i] & 0xFF; - int temp = remainder * 58 + digit58; - - number58[i] = (byte) (temp / 256); - - remainder = temp % 256; - } - - return (byte) remainder; - } - - private static byte[] copyOfRange(byte[] source, int from, int to) { - byte[] range = new byte[to - from]; - System.arraycopy(source, from, range, 0, range.length); - - return range; - } - - public static byte[] decodeFromBase58Check(String addressBase58) { - if (addressBase58 == null || addressBase58.length() == 0) { - System.out.println("Warning: Address is empty !!"); - return null; - } - if (addressBase58.length() != BASE58CHECK_ADDRESS_SIZE) { - System.out.println( + private static final int[] INDEXES = new int[128]; + + static { + for (int i = 0; i < INDEXES.length; i++) { + INDEXES[i] = -1; + } + for (int i = 0; i < ALPHABET.length; i++) { + INDEXES[ALPHABET[i]] = i; + } + } + + public static String encode(byte[] input) { + if (input.length == 0) { + return ""; + } + input = copyOfRange(input, 0, input.length); + int zeroCount = 0; + while (zeroCount < input.length && input[zeroCount] == 0) { + ++zeroCount; + } + byte[] temp = new byte[input.length * 2]; + int j = temp.length; + + int startAt = zeroCount; + while (startAt < input.length) { + byte mod = divmod58(input, startAt); + if (input[startAt] == 0) { + ++startAt; + } + temp[--j] = (byte) ALPHABET[mod]; + } + + // Strip extra '1' if there are some after decoding. + while (j < temp.length && temp[j] == ALPHABET[0]) { + ++j; + } + // Add as many leading '1' as there were leading zeros. + while (--zeroCount >= 0) { + temp[--j] = (byte) ALPHABET[0]; + } + + byte[] output = copyOfRange(temp, j, temp.length); + try { + return new String(output, "US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // Cannot happen. + } + } + + public static byte[] decode(String input) throws IllegalArgumentException { + if (input.length() == 0) { + return new byte[0]; + } + byte[] input58 = new byte[input.length()]; + // Transform the String to a base58 byte sequence + for (int i = 0; i < input.length(); ++i) { + char c = input.charAt(i); + + int digit58 = -1; + if (c >= 0 && c < 128) { + digit58 = INDEXES[c]; + } + if (digit58 < 0) { + throw new IllegalArgumentException("Illegal character " + c + " at " + i); + } + + input58[i] = (byte) digit58; + } + // Count leading zeroes + int zeroCount = 0; + while (zeroCount < input58.length && input58[zeroCount] == 0) { + ++zeroCount; + } + byte[] temp = new byte[input.length()]; + int j = temp.length; + + int startAt = zeroCount; + while (startAt < input58.length) { + byte mod = divmod256(input58, startAt); + if (input58[startAt] == 0) { + ++startAt; + } + + temp[--j] = mod; + } + // Do no add extra leading zeroes, move j to first non null byte. + while (j < temp.length && temp[j] == 0) { + ++j; + } + + return copyOfRange(temp, j - zeroCount, temp.length); + } + + public static BigInteger decodeToBigInteger(String input) throws IllegalArgumentException { + return new BigInteger(1, decode(input)); + } + + private static byte divmod58(byte[] number, int startAt) { + int remainder = 0; + for (int i = startAt; i < number.length; i++) { + int digit256 = (int) number[i] & 0xFF; + int temp = remainder * 256 + digit256; + + number[i] = (byte) (temp / 58); + + remainder = temp % 58; + } + + return (byte) remainder; + } + + + private static byte divmod256(byte[] number58, int startAt) { + int remainder = 0; + for (int i = startAt; i < number58.length; i++) { + int digit58 = (int) number58[i] & 0xFF; + int temp = remainder * 58 + digit58; + + number58[i] = (byte) (temp / 256); + + remainder = temp % 256; + } + + return (byte) remainder; + } + + private static byte[] copyOfRange(byte[] source, int from, int to) { + byte[] range = new byte[to - from]; + System.arraycopy(source, from, range, 0, range.length); + + return range; + } + + public static byte[] decodeFromBase58Check(String addressBase58) { + if (addressBase58 == null || addressBase58.length() == 0) { + System.out.println("Warning: Address is empty !!"); + return null; + } + if (addressBase58.length() != BASE58CHECK_ADDRESS_SIZE) { + System.out.println( "Warning: Base58 address length need " + BASE58CHECK_ADDRESS_SIZE + " but " + addressBase58.length() + " !!"); - return null; - } - byte[] address = decode58Check(addressBase58); - if (!addressValid(address)) { - return null; - } - return address; - } - - private static byte[] decode58Check(String input) { - byte[] decodeCheck = Base58.decode(input); - if (decodeCheck.length <= 4) { - return null; - } - byte[] decodeData = new byte[decodeCheck.length - 4]; - System.arraycopy(decodeCheck, 0, decodeData, 0, decodeData.length); - byte[] hash0 = Sha256Hash.hash(decodeData); - byte[] hash1 = Sha256Hash.hash(hash0); - if (hash1[0] == decodeCheck[decodeData.length] && - hash1[1] == decodeCheck[decodeData.length + 1] && - hash1[2] == decodeCheck[decodeData.length + 2] && - hash1[3] == decodeCheck[decodeData.length + 3]) { - return decodeData; - } - return null; - } - - public static boolean addressValid(byte[] address) { - if (address == null || address.length == 0) { - System.out.println("Warning: Address is empty !!"); - return false; - } - if (address.length != ADDRESS_SIZE) { - System.out.println( + return null; + } + byte[] address = decode58Check(addressBase58); + if (!addressValid(address)) { + return null; + } + return address; + } + + private static byte[] decode58Check(String input) { + byte[] decodeCheck = Base58.decode(input); + if (decodeCheck.length <= 4) { + return null; + } + byte[] decodeData = new byte[decodeCheck.length - 4]; + System.arraycopy(decodeCheck, 0, decodeData, 0, decodeData.length); + byte[] hash0 = Sha256Hash.hash(decodeData); + byte[] hash1 = Sha256Hash.hash(hash0); + if (hash1[0] == decodeCheck[decodeData.length] + && hash1[1] == decodeCheck[decodeData.length + 1] + && hash1[2] == decodeCheck[decodeData.length + 2] + && hash1[3] == decodeCheck[decodeData.length + 3]) { + return decodeData; + } + return null; + } + + public static boolean addressValid(byte[] address) { + if (address == null || address.length == 0) { + System.out.println("Warning: Address is empty !!"); + return false; + } + if (address.length != ADDRESS_SIZE) { + System.out.println( "Warning: Address length need " + ADDRESS_SIZE + " but " + address.length + " !!"); - return false; - } - byte preFixbyte = address[0]; - if (preFixbyte != ADD_PRE_FIX_BYTE) { - System.out.println("Warning: Address need prefix with " + ADD_PRE_FIX_BYTE + " but " - + preFixbyte + " !!"); - return false; - } - //Other rule; - return true; + return false; } - - public static String encode58Check(byte[] input) { - byte[] hash0 = Sha256Hash.hash(input); - byte[] hash1 = Sha256Hash.hash(hash0); - byte[] inputCheck = new byte[input.length + 4]; - System.arraycopy(input, 0, inputCheck, 0, input.length); - System.arraycopy(hash1, 0, inputCheck, input.length, 4); - return Base58.encode(inputCheck); + byte preFixbyte = address[0]; + if (preFixbyte != ADD_PRE_FIX_BYTE) { + System.out.println("Warning: Address need prefix with " + ADD_PRE_FIX_BYTE + " but " + + preFixbyte + " !!"); + return false; } + //Other rule; + return true; + } + + public static String encode58Check(byte[] input) { + byte[] hash0 = Sha256Hash.hash(input); + byte[] hash1 = Sha256Hash.hash(hash0); + byte[] inputCheck = new byte[input.length + 4]; + System.arraycopy(input, 0, inputCheck, 0, input.length); + System.arraycopy(hash1, 0, inputCheck, input.length, 4); + return Base58.encode(inputCheck); + } } \ No newline at end of file diff --git a/src/test/java/stest/tron/wallet/common/client/utils/ByteArrayWrapper.java b/src/test/java/stest/tron/wallet/common/client/utils/ByteArrayWrapper.java new file mode 100644 index 00000000000..c9d38ffa103 --- /dev/null +++ b/src/test/java/stest/tron/wallet/common/client/utils/ByteArrayWrapper.java @@ -0,0 +1,75 @@ +package stest.tron.wallet.common.client.utils; +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ + +import java.io.Serializable; +import java.util.Arrays; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.utils.FastByteComparisons; + +public class ByteArrayWrapper implements Comparable, Serializable { + + private final byte[] data; + private int hashCode = 0; + + /** + * constructor. + */ + public ByteArrayWrapper(byte[] data) { + if (data == null) { + throw new NullPointerException("Data must not be null"); + } + this.data = data; + this.hashCode = Arrays.hashCode(data); + } + + + /** + * equals Objects. + */ + public boolean equals(Object other) { + if (other == null || this.getClass() != other.getClass()) { + return false; + } + byte[] otherData = ((ByteArrayWrapper) other).getData(); + return FastByteComparisons.compareTo( + data, 0, data.length, + otherData, 0, otherData.length) == 0; + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public int compareTo(ByteArrayWrapper o) { + return FastByteComparisons.compareTo( + data, 0, data.length, + o.getData(), 0, o.getData().length); + } + + public byte[] getData() { + return data; + } + + @Override + public String toString() { + return Hex.toHexString(data); + } +} diff --git a/src/test/java/stest/tron/wallet/common/client/utils/DataWord.java b/src/test/java/stest/tron/wallet/common/client/utils/DataWord.java new file mode 100644 index 00000000000..cc8ef3dddf2 --- /dev/null +++ b/src/test/java/stest/tron/wallet/common/client/utils/DataWord.java @@ -0,0 +1,432 @@ +package stest.tron.wallet.common.client.utils; + +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import org.spongycastle.util.Arrays; +import org.spongycastle.util.encoders.Hex; +import org.tron.common.utils.ByteUtil; +import org.tron.common.utils.FastByteComparisons; + +public class DataWord implements Comparable { + + /* Maximum value of the DataWord */ + public static final BigInteger _2_256 = BigInteger.valueOf(2).pow(256); + public static final BigInteger MAX_VALUE = _2_256.subtract(BigInteger.ONE); + public static final DataWord ZERO = new DataWord(new byte[32]); + public static final DataWord ZERO_EMPTY_ARRAY = new DataWord(new byte[0]); + + private byte[] data = new byte[32]; + + public DataWord() { + } + + public DataWord(int num) { + this(ByteBuffer.allocate(4).putInt(num)); + } + + public DataWord(long num) { + this(ByteBuffer.allocate(8).putLong(num)); + } + + private DataWord(ByteBuffer buffer) { + final ByteBuffer data = ByteBuffer.allocate(32); + final byte[] array = buffer.array(); + System.arraycopy(array, 0, data.array(), 32 - array.length, array.length); + this.data = data.array(); + } + + @JsonCreator + public DataWord(String data) { + this(Hex.decode(data)); + } + + public DataWord(ByteArrayWrapper wrappedData) { + this(wrappedData.getData()); + } + + public DataWord(byte[] data) { + if (data == null) { + this.data = ByteUtil.EMPTY_BYTE_ARRAY; + } else if (data.length == 32) { + this.data = data; + } else if (data.length <= 32) { + System.arraycopy(data, 0, this.data, 32 - data.length, data.length); + } else { + throw new RuntimeException("Data word can't exceed 32 bytes: " + data); + } + + } + + public byte[] getData() { + return data; + } + + public byte[] getNoLeadZeroesData() { + return ByteUtil.stripLeadingZeroes(data); + } + + public byte[] getLast20Bytes() { + return Arrays.copyOfRange(data, 12, data.length); + } + + public BigInteger value() { + return new BigInteger(1, data); + } + + /** + * Converts this DataWord to an int, checking for lost information. + * If this DataWord is out of the possible range for an int result + * then an ArithmeticException is thrown. + * + * @return this DataWord converted to an int. + * @throws ArithmeticException - if this will not fit in an int. + */ + public int intValue() { + int intVal = 0; + + for (byte aaData : data) { + intVal = (intVal << 8) + (aaData & 0xff); + } + + return intVal; + } + + /** + * In case of int overflow returns Integer.MAX_VALUE + * otherwise works as #intValue() + */ + public int intValueSafe() { + int bytesOccupied = bytesOccupied(); + int intValue = intValue(); + if (bytesOccupied > 4 || intValue < 0) { + return Integer.MAX_VALUE; + } + return intValue; + } + + /** + * Converts this DataWord to a long, checking for lost information. + * If this DataWord is out of the possible range for a long result + * then an ArithmeticException is thrown. + * + * @return this DataWord converted to a long. + * @throws ArithmeticException - if this will not fit in a long. + */ + public long longValue() { + + long longVal = 0; + for (byte aaData : data) { + longVal = (longVal << 8) + (aaData & 0xff); + } + + return longVal; + } + + /** + * In case of long overflow returns Long.MAX_VALUE + * otherwise works as #longValue() + */ + public long longValueSafe() { + int bytesOccupied = bytesOccupied(); + long longValue = longValue(); + if (bytesOccupied > 8 || longValue < 0) { + return Long.MAX_VALUE; + } + return longValue; + } + + public BigInteger sValue() { + return new BigInteger(data); + } + + public String bigIntValue() { + return new BigInteger(data).toString(); + } + + public boolean isZero() { + for (byte tmp : data) { + if (tmp != 0) { + return false; + } + } + return true; + } + + // only in case of signed operation + // when the number is explicit defined + // as negative + public boolean isNegative() { + int result = data[0] & 0x80; + return result == 0x80; + } + + public DataWord and(DataWord w2) { + + for (int i = 0; i < this.data.length; ++i) { + this.data[i] &= w2.data[i]; + } + return this; + } + + public DataWord or(DataWord w2) { + + for (int i = 0; i < this.data.length; ++i) { + this.data[i] |= w2.data[i]; + } + return this; + } + + public DataWord xor(DataWord w2) { + + for (int i = 0; i < this.data.length; ++i) { + this.data[i] ^= w2.data[i]; + } + return this; + } + + public void negate() { + + if (this.isZero()) { + return; + } + + for (int i = 0; i < this.data.length; ++i) { + this.data[i] = (byte) ~this.data[i]; + } + + for (int i = this.data.length - 1; i >= 0; --i) { + this.data[i] = (byte) (1 + this.data[i] & 0xFF); + if (this.data[i] != 0) { + break; + } + } + } + + public void bnot() { + if (this.isZero()) { + this.data = ByteUtil.copyToArray(MAX_VALUE); + return; + } + this.data = ByteUtil.copyToArray(MAX_VALUE.subtract(this.value())); + } + + // By : Holger + // From : http://stackoverflow.com/a/24023466/459349 + public void add(DataWord word) { + byte[] result = new byte[32]; + for (int i = 31, overflow = 0; i >= 0; i--) { + int v = (this.data[i] & 0xff) + (word.data[i] & 0xff) + overflow; + result[i] = (byte) v; + overflow = v >>> 8; + } + this.data = result; + } + + // old add-method with BigInteger quick hack + public void add2(DataWord word) { + BigInteger result = value().add(word.value()); + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + // TODO: mul can be done in more efficient way + // TODO: with shift left shift right trick + // TODO without BigInteger quick hack + public void mul(DataWord word) { + BigInteger result = value().multiply(word.value()); + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + // TODO: improve with no BigInteger + public void div(DataWord word) { + + if (word.isZero()) { + this.and(ZERO); + return; + } + + BigInteger result = value().divide(word.value()); + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + // TODO: improve with no BigInteger + public void sDiv(DataWord word) { + + if (word.isZero()) { + this.and(ZERO); + return; + } + + BigInteger result = sValue().divide(word.sValue()); + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + // TODO: improve with no BigInteger + public void sub(DataWord word) { + BigInteger result = value().subtract(word.value()); + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + // TODO: improve with no BigInteger + public void exp(DataWord word) { + BigInteger result = value().modPow(word.value(), _2_256); + this.data = ByteUtil.copyToArray(result); + } + + // TODO: improve with no BigInteger + public void mod(DataWord word) { + + if (word.isZero()) { + this.and(ZERO); + return; + } + + BigInteger result = value().mod(word.value()); + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + public void sMod(DataWord word) { + + if (word.isZero()) { + this.and(ZERO); + return; + } + + BigInteger result = sValue().abs().mod(word.sValue().abs()); + result = (sValue().signum() == -1) ? result.negate() : result; + + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + public void addmod(DataWord word1, DataWord word2) { + if (word2.isZero()) { + this.data = new byte[32]; + return; + } + + BigInteger result = value().add(word1.value()).mod(word2.value()); + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + public void mulmod(DataWord word1, DataWord word2) { + + if (this.isZero() || word1.isZero() || word2.isZero()) { + this.data = new byte[32]; + return; + } + + BigInteger result = value().multiply(word1.value()).mod(word2.value()); + this.data = ByteUtil.copyToArray(result.and(MAX_VALUE)); + } + + @JsonValue + @Override + public String toString() { + return Hex.toHexString(data); + } + + public String toPrefixString() { + + byte[] pref = getNoLeadZeroesData(); + if (pref.length == 0) { + return ""; + } + + if (pref.length < 7) { + return Hex.toHexString(pref); + } + + + return Hex.toHexString(pref).substring(0, 6); + } + + public String shortHex() { + String hexValue = Hex.toHexString(getNoLeadZeroesData()).toUpperCase(); + return "0x" + hexValue.replaceFirst("^0+(?!$)", ""); + } + + public DataWord clone() { + return new DataWord(Arrays.clone(data)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + DataWord dataWord = (DataWord) o; + + return java.util.Arrays.equals(data, dataWord.data); + + } + + @Override + public int hashCode() { + return java.util.Arrays.hashCode(data); + } + + @Override + public int compareTo(DataWord o) { + if (o == null || o.getData() == null) { + return -1; + } + int result = FastByteComparisons.compareTo( + data, 0, data.length, + o.getData(), 0, o.getData().length); + // Convert result into -1, 0 or 1 as is the convention + return (int) Math.signum(result); + } + + public void signExtend(byte k) { + if (0 > k || k > 31) { + throw new IndexOutOfBoundsException(); + } + byte mask = this.sValue().testBit((k * 8) + 7) ? (byte) 0xff : 0; + for (int i = 31; i > k; i--) { + this.data[31 - i] = mask; + } + } + + public int bytesOccupied() { + int firstNonZero = ByteUtil.firstNonZeroByte(data); + if (firstNonZero == -1) { + return 0; + } + return 31 - firstNonZero + 1; + } + + public boolean isHex(String hex) { + return Hex.toHexString(data).equals(hex); + } + + public String asString() { + return new String(getNoLeadZeroesData()); + } + + public String toHexString() { + return Hex.toHexString(data); + } +} diff --git a/src/test/java/stest/tron/wallet/common/client/utils/FileUtil.java b/src/test/java/stest/tron/wallet/common/client/utils/FileUtil.java index b5af70d21d9..13c5a6dac1f 100644 --- a/src/test/java/stest/tron/wallet/common/client/utils/FileUtil.java +++ b/src/test/java/stest/tron/wallet/common/client/utils/FileUtil.java @@ -21,111 +21,111 @@ public class FileUtil { - public static List recursiveList(String path) throws IOException { + public static List recursiveList(String path) throws IOException { - final List files = new ArrayList<>(); + final List files = new ArrayList<>(); - Files.walkFileTree(Paths.get(path), new FileVisitor() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { - return FileVisitResult.CONTINUE; - } + Files.walkFileTree(Paths.get(path), new FileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + return FileVisitResult.CONTINUE; + } - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - files.add(file.toString()); - return FileVisitResult.CONTINUE; - } + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + files.add(file.toString()); + return FileVisitResult.CONTINUE; + } - @Override - public FileVisitResult visitFileFailed(Path file, IOException exc) { - return FileVisitResult.CONTINUE; - } + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + return FileVisitResult.CONTINUE; + } - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) { - return FileVisitResult.CONTINUE; - } - }); + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + return FileVisitResult.CONTINUE; + } + }); - return files; - } - - public static boolean recursiveDelete(String fileName) { - File file = new File(fileName); - if (file.exists()) { - //check if the file is a directory - if (file.isDirectory()) { - if ((file.list()).length > 0) { - for (String s : file.list()) { - //call deletion of file individually - recursiveDelete(fileName + System.getProperty("file.separator") + s); - } - } - } + return files; + } - file.setWritable(true); - boolean result = file.delete(); - return result; - } else { - return false; + public static boolean recursiveDelete(String fileName) { + File file = new File(fileName); + if (file.exists()) { + //check if the file is a directory + if (file.isDirectory()) { + if ((file.list()).length > 0) { + for (String s : file.list()) { + //call deletion of file individually + recursiveDelete(fileName + System.getProperty("file.separator") + s); + } } + } + + file.setWritable(true); + boolean result = file.delete(); + return result; + } else { + return false; } + } - public static void saveData(String filePath, byte[] data) { - FileOutputStream fos = null; + public static void saveData(String filePath, byte[] data) { + FileOutputStream fos = null; + try { + File file = new File(filePath); + file.createNewFile(); + fos = new FileOutputStream(file); + fos.write(data); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (fos != null) { try { - File file = new File(filePath); - file.createNewFile(); - fos = new FileOutputStream(file); - fos.write(data); + fos.close(); } catch (IOException e) { - e.printStackTrace(); - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } + e.printStackTrace(); } + } } + } - public static byte[] readData(String filePath) { - FileInputStream fi = null; + public static byte[] readData(String filePath) { + FileInputStream fi = null; + try { + File file = new File(filePath); + long fileSize = file.length(); + if (fileSize > Integer.MAX_VALUE) { + System.out.println("file too big..."); + return null; + } + fi = new FileInputStream(file); + byte[] buffer = new byte[(int) fileSize]; + int offset = 0; + int numRead; + while (offset < buffer.length + && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) { + offset += numRead; + } + if (offset != buffer.length) { + return null; + } + return buffer; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (fi != null) { try { - File file = new File(filePath); - long fileSize = file.length(); - if (fileSize > Integer.MAX_VALUE) { - System.out.println("file too big..."); - return null; - } - fi = new FileInputStream(file); - byte[] buffer = new byte[(int) fileSize]; - int offset = 0; - int numRead; - while (offset < buffer.length - && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) { - offset += numRead; - } - if (offset != buffer.length) { - return null; - } - return buffer; - } catch (FileNotFoundException e) { - e.printStackTrace(); + fi.close(); } catch (IOException e) { - e.printStackTrace(); - } finally { - if (fi != null) { - try { - fi.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } + e.printStackTrace(); } - return null; + } } + return null; + } } diff --git a/src/test/java/stest/tron/wallet/common/client/utils/PublicMethed.java b/src/test/java/stest/tron/wallet/common/client/utils/PublicMethed.java index 17bc6cd9552..7179861071b 100644 --- a/src/test/java/stest/tron/wallet/common/client/utils/PublicMethed.java +++ b/src/test/java/stest/tron/wallet/common/client/utils/PublicMethed.java @@ -1,9 +1,15 @@ package stest.tron.wallet.common.client.utils; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; import com.google.protobuf.ByteString; -import com.typesafe.config.Config; +import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.util.HashMap; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,25 +17,35 @@ import org.testng.Assert; import org.tron.api.GrpcAPI; import org.tron.api.GrpcAPI.AccountNetMessage; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.GrpcAPI.BytesMessage; import org.tron.api.GrpcAPI.Return; +import org.tron.api.GrpcAPI.Return.response_code; import org.tron.api.GrpcAPI.TransactionExtention; import org.tron.api.WalletGrpc; import org.tron.api.WalletSolidityGrpc; import org.tron.common.crypto.ECKey; +import org.tron.common.crypto.Hash; import org.tron.common.utils.ByteArray; import org.tron.core.Wallet; import org.tron.protos.Contract; +import org.tron.protos.Contract.CreateSmartContract; +import org.tron.protos.Contract.UpdateSettingContract; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Account; import org.tron.protos.Protocol.Block; +import org.tron.protos.Protocol.SmartContract; import org.tron.protos.Protocol.Transaction; -import stest.tron.wallet.common.client.Configuration; +import org.tron.protos.Protocol.Transaction.Result; +import org.tron.protos.Protocol.TransactionInfo; import stest.tron.wallet.common.client.Parameter.CommonConstant; import stest.tron.wallet.common.client.WalletClient; +import stest.tron.wallet.common.client.utils.AbiUtil; public class PublicMethed { + Wallet wallet = new Wallet(); //Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); @@ -107,6 +123,14 @@ public static Account queryAccountByAddress(byte[] address, return blockingStubFull.getAccount(request); } + public static Account queryAccount(byte[] address,WalletGrpc + .WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ByteString addressBs = ByteString.copyFrom(address); + Account request = Account.newBuilder().setAddress(addressBs).build(); + return blockingStubFull.getAccount(request); + } + public static Protocol.Account queryAccount(String priKey, WalletGrpc.WalletBlockingStub blockingStubFull) { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); @@ -303,6 +327,15 @@ public static Boolean sendcoin(byte[] to, long amount, byte[] owner, String priK logger.info("transaction ==null"); return false; } + //Test raw data + /* Protocol.Transaction.raw.Builder builder1 = transaction.getRawData().toBuilder(); + builder1.setData(ByteString.copyFromUtf8("12345678")); + Transaction.Builder builder2 = transaction.toBuilder(); + builder2.setRawData(builder1); + transaction = builder2.build();*/ + + + transaction = signTransaction(ecKey, transaction); GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); if (response.getResult() == false) { @@ -372,8 +405,10 @@ public static boolean transferAsset(byte[] to, byte[] assertName, long amount, b builder.setOwnerAddress(bsOwner); builder.setAmount(amount); + Contract.TransferAssetContract contract = builder.build(); Protocol.Transaction transaction = blockingStubFull.transferAsset(contract); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { if (transaction == null) { logger.info("transaction == null"); @@ -383,12 +418,12 @@ public static boolean transferAsset(byte[] to, byte[] assertName, long amount, b return false; } transaction = signTransaction(ecKey, transaction); + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); if (response.getResult() == false) { logger.info(ByteArray.toStr(response.getMessage().toByteArray())); return false; } else { - //Protocol.Account search = queryAccount(ecKey, blockingStubFull); return true; } } @@ -490,7 +525,7 @@ public static boolean waitProduceNextBlock(WalletGrpc.WalletBlockingStub return true; } - public static AccountNetMessage getAccountNet(byte[] address,WalletGrpc.WalletBlockingStub + public static AccountNetMessage getAccountNet(byte[] address, WalletGrpc.WalletBlockingStub blockingStubFull) { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); ByteString addressBs = ByteString.copyFrom(address); @@ -522,11 +557,11 @@ public static byte[] getFinalAddress(String priKey) { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); WalletClient walletClient; walletClient = new WalletClient(priKey); - walletClient.init(0); + //walletClient.init(0); return walletClient.getAddress(); } - public static boolean createAccount(byte[] ownerAddress,byte[] newAddress,String priKey, + public static boolean createAccount(byte[] ownerAddress, byte[] newAddress, String priKey, WalletGrpc.WalletBlockingStub blockingStubFull) { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); ECKey temKey = null; @@ -603,8 +638,8 @@ public static boolean createProposal(byte[] ownerAddress, String priKey, } } - public static boolean approveProposal(byte[] ownerAddress, String priKey,long id, boolean is_add_approval, - WalletGrpc.WalletBlockingStub blockingStubFull) { + public static boolean approveProposal(byte[] ownerAddress, String priKey, long id, + boolean isAddApproval, WalletGrpc.WalletBlockingStub blockingStubFull) { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); ECKey temKey = null; try { @@ -616,10 +651,11 @@ public static boolean approveProposal(byte[] ownerAddress, String priKey,long id final ECKey ecKey = temKey; byte[] owner = ownerAddress; - Contract.ProposalApproveContract.Builder builder = Contract.ProposalApproveContract.newBuilder(); + Contract.ProposalApproveContract.Builder builder = Contract.ProposalApproveContract + .newBuilder(); builder.setOwnerAddress(ByteString.copyFrom(owner)); builder.setProposalId(id); - builder.setIsAddApproval(is_add_approval); + builder.setIsAddApproval(isAddApproval); Contract.ProposalApproveContract contract = builder.build(); TransactionExtention transactionExtention = blockingStubFull.proposalApprove(contract); if (transactionExtention == null) { @@ -648,7 +684,7 @@ public static boolean approveProposal(byte[] ownerAddress, String priKey,long id } } - public static boolean deleteProposal(byte[] ownerAddress, String priKey,long id, + public static boolean deleteProposal(byte[] ownerAddress, String priKey, long id, WalletGrpc.WalletBlockingStub blockingStubFull) { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); ECKey temKey = null; @@ -701,4 +737,783 @@ public static boolean printAddress(String key) { return true; } + + public static boolean setAccountId(byte[] accountIdBytes, byte[] ownerAddress, String priKey, + WalletGrpc.WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + byte[] owner = ownerAddress; + Contract.SetAccountIdContract.Builder builder = Contract.SetAccountIdContract.newBuilder(); + ByteString bsAddress = ByteString.copyFrom(owner); + ByteString bsAccountId = ByteString.copyFrom(accountIdBytes); + builder.setAccountId(bsAccountId); + builder.setOwnerAddress(bsAddress); + Contract.SetAccountIdContract contract = builder.build(); + Transaction transaction = blockingStubFull.setAccountId(contract); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + logger.info("transaction == null"); + } + transaction = signTransaction(ecKey, transaction); + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); + if (response.getResult() == false) { + logger.info(ByteArray.toStr(response.getMessage().toByteArray())); + return false; + } else { + return true; + } + } + + + public static Boolean freezeBalanceGetEnergy(byte[] addRess, long freezeBalance, + long freezeDuration, + int resourceCode, String priKey, WalletGrpc.WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + byte[] address = addRess; + long frozenBalance = freezeBalance; + long frozenDuration = freezeDuration; + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + Contract.FreezeBalanceContract.Builder builder = Contract.FreezeBalanceContract.newBuilder(); + ByteString byteAddreess = ByteString.copyFrom(address); + + builder.setOwnerAddress(byteAddreess).setFrozenBalance(frozenBalance) + .setFrozenDuration(frozenDuration).setResourceValue(resourceCode); + + Contract.FreezeBalanceContract contract = builder.build(); + Protocol.Transaction transaction = blockingStubFull.freezeBalance(contract); + + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + logger.info("transaction = null"); + return false; + } + transaction = TransactionUtils.setTimestamp(transaction); + transaction = TransactionUtils.sign(transaction, ecKey); + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); + + if (response.getResult() == false) { + logger.info(ByteArray.toStr(response.getMessage().toByteArray())); + return false; + } + return true; + } + + public static AccountResourceMessage getAccountResource(byte[] address, + WalletGrpc.WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ByteString addressBs = ByteString.copyFrom(address); + Account request = Account.newBuilder().setAddress(addressBs).build(); + return blockingStubFull.getAccountResource(request); + } + + public static boolean buyStorage(long quantity, byte[] address, + String priKey, WalletGrpc.WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + Contract.BuyStorageContract.Builder builder = Contract.BuyStorageContract.newBuilder(); + ByteString byteAddress = ByteString.copyFrom(address); + builder.setOwnerAddress(byteAddress).setQuant(quantity); + Contract.BuyStorageContract contract = builder.build(); + TransactionExtention transactionExtention = blockingStubFull.buyStorage(contract); + if (transactionExtention == null) { + return false; + } + Return ret = transactionExtention.getResult(); + if (!ret.getResult()) { + System.out.println("Code = " + ret.getCode()); + System.out.println("Message = " + ret.getMessage().toStringUtf8()); + return false; + } + Transaction transaction = transactionExtention.getTransaction(); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + System.out.println("Transaction is empty"); + return false; + } + System.out.println( + "Receive txid = " + ByteArray.toHexString(transactionExtention.getTxid().toByteArray())); + transaction = signTransaction(ecKey, transaction); + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); + if (response.getResult() == false) { + logger.info(ByteArray.toStr(response.getMessage().toByteArray())); + return false; + } else { + return true; + } + } + + public static boolean sellStorage(long quantity, byte[] address, + String priKey, WalletGrpc.WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + Contract.SellStorageContract.Builder builder = Contract.SellStorageContract.newBuilder(); + ByteString byteAddress = ByteString.copyFrom(address); + builder.setOwnerAddress(byteAddress).setStorageBytes(quantity); + Contract.SellStorageContract contract = builder.build(); + TransactionExtention transactionExtention = blockingStubFull.sellStorage(contract); + if (transactionExtention == null) { + return false; + } + Return ret = transactionExtention.getResult(); + if (!ret.getResult()) { + System.out.println("Code = " + ret.getCode()); + System.out.println("Message = " + ret.getMessage().toStringUtf8()); + return false; + } + Transaction transaction = transactionExtention.getTransaction(); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + System.out.println("Transaction is empty"); + return false; + } + System.out.println( + "Receive txid = " + ByteArray.toHexString(transactionExtention.getTxid().toByteArray())); + transaction = signTransaction(ecKey, transaction); + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); + if (response.getResult() == false) { + logger.info(ByteArray.toStr(response.getMessage().toByteArray())); + return false; + } else { + return true; + } + } + + public static byte[] deployContract(String contractName, String abiString, String code, + String data, Long feeLimit, long value, + long consumeUserResourcePercent, byte[] libraryAddress,String priKey, byte[] ownerAddress, + WalletGrpc.WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + byte[] owner = ownerAddress; + SmartContract.ABI abi = jsonStr2Abi(abiString); + if (abi == null) { + logger.error("abi is null"); + return null; + } + //byte[] codeBytes = Hex.decode(code); + SmartContract.Builder builder = SmartContract.newBuilder(); + builder.setName(contractName); + builder.setOriginAddress(ByteString.copyFrom(owner)); + builder.setAbi(abi); + builder.setConsumeUserResourcePercent(consumeUserResourcePercent); + + if (value != 0) { + + builder.setCallValue(value); + } + + byte[] byteCode; + if (null != libraryAddress) { + byteCode = replaceLibraryAddress(code, libraryAddress); + } else { + byteCode = Hex.decode(code); + } + builder.setBytecode(ByteString.copyFrom(byteCode)); + + CreateSmartContract contractDeployContract = CreateSmartContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(owner)).setNewContract(builder.build()).build(); + + TransactionExtention transactionExtention = blockingStubFull + .deployContract(contractDeployContract); + if (transactionExtention == null || !transactionExtention.getResult().getResult()) { + System.out.println("RPC create trx failed!"); + if (transactionExtention != null) { + System.out.println("Code = " + transactionExtention.getResult().getCode()); + System.out + .println("Message = " + transactionExtention.getResult().getMessage().toStringUtf8()); + } + return null; + } + + final TransactionExtention.Builder texBuilder = TransactionExtention.newBuilder(); + Transaction.Builder transBuilder = Transaction.newBuilder(); + Transaction.raw.Builder rawBuilder = transactionExtention.getTransaction().getRawData() + .toBuilder(); + rawBuilder.setFeeLimit(feeLimit); + transBuilder.setRawData(rawBuilder); + for (int i = 0; i < transactionExtention.getTransaction().getSignatureCount(); i++) { + ByteString s = transactionExtention.getTransaction().getSignature(i); + transBuilder.setSignature(i, s); + } + for (int i = 0; i < transactionExtention.getTransaction().getRetCount(); i++) { + Result r = transactionExtention.getTransaction().getRet(i); + transBuilder.setRet(i, r); + } + texBuilder.setTransaction(transBuilder); + texBuilder.setResult(transactionExtention.getResult()); + texBuilder.setTxid(transactionExtention.getTxid()); + transactionExtention = texBuilder.build(); + + + + byte[] contractAddress = generateContractAddress(transactionExtention.getTransaction(), owner); + System.out.println( + "Your smart contract address will be: " + WalletClient.encode58Check(contractAddress)); + if (transactionExtention == null) { + return null; + } + Return ret = transactionExtention.getResult(); + if (!ret.getResult()) { + System.out.println("Code = " + ret.getCode()); + System.out.println("Message = " + ret.getMessage().toStringUtf8()); + return null; + } + Transaction transaction = transactionExtention.getTransaction(); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + System.out.println("Transaction is empty"); + return null; + } + transaction = signTransaction(ecKey, transaction); + System.out.println( + "txid = " + ByteArray.toHexString(Sha256Hash.hash(transaction.getRawData().toByteArray()))); + contractAddress = generateContractAddress(transaction, owner); + System.out.println( + "Your smart contract address will be: " + WalletClient.encode58Check(contractAddress)); + + int i = 10; + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); + while (response.getResult() == false && response.getCode() == response_code.SERVER_BUSY + && i > 0) { + i--; + response = blockingStubFull.broadcastTransaction(transaction); + logger.info("repeate times = " + (11 - i)); + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (response.getResult() == false) { + logger.info("Code = " + response.getCode()); + logger.info("Message = " + response.getMessage().toStringUtf8()); + return null; + } else { + logger.info("brodacast succesfully"); + return contractAddress; + } + } + + public static String deployContractAndGetTransactionInfoById(String contractName, + String abiString, String code, String data, Long feeLimit, long value, + long consumeUserResourcePercent, byte[] libraryAddress,String priKey, byte[] ownerAddress, + WalletGrpc.WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + byte[] owner = ownerAddress; + SmartContract.ABI abi = jsonStr2Abi(abiString); + if (abi == null) { + logger.error("abi is null"); + return null; + } + //byte[] codeBytes = Hex.decode(code); + SmartContract.Builder builder = SmartContract.newBuilder(); + builder.setName(contractName); + builder.setOriginAddress(ByteString.copyFrom(owner)); + builder.setAbi(abi); + builder.setConsumeUserResourcePercent(consumeUserResourcePercent); + + if (value != 0) { + + builder.setCallValue(value); + } + + byte[] byteCode; + if (null != libraryAddress) { + byteCode = replaceLibraryAddress(code, libraryAddress); + } else { + byteCode = Hex.decode(code); + } + builder.setBytecode(ByteString.copyFrom(byteCode)); + + CreateSmartContract contractDeployContract = CreateSmartContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(owner)).setNewContract(builder.build()).build(); + + TransactionExtention transactionExtention = blockingStubFull + .deployContract(contractDeployContract); + if (transactionExtention == null || !transactionExtention.getResult().getResult()) { + System.out.println("RPC create trx failed!"); + if (transactionExtention != null) { + System.out.println("Code = " + transactionExtention.getResult().getCode()); + System.out + .println("Message = " + transactionExtention.getResult().getMessage().toStringUtf8()); + } + return null; + } + + final TransactionExtention.Builder texBuilder = TransactionExtention.newBuilder(); + Transaction.Builder transBuilder = Transaction.newBuilder(); + Transaction.raw.Builder rawBuilder = transactionExtention.getTransaction().getRawData() + .toBuilder(); + rawBuilder.setFeeLimit(feeLimit); + transBuilder.setRawData(rawBuilder); + for (int i = 0; i < transactionExtention.getTransaction().getSignatureCount(); i++) { + ByteString s = transactionExtention.getTransaction().getSignature(i); + transBuilder.setSignature(i, s); + } + for (int i = 0; i < transactionExtention.getTransaction().getRetCount(); i++) { + Result r = transactionExtention.getTransaction().getRet(i); + transBuilder.setRet(i, r); + } + texBuilder.setTransaction(transBuilder); + texBuilder.setResult(transactionExtention.getResult()); + texBuilder.setTxid(transactionExtention.getTxid()); + transactionExtention = texBuilder.build(); + + + + byte[] contractAddress = generateContractAddress(transactionExtention.getTransaction(), owner); + System.out.println( + "Your smart contract address will be: " + WalletClient.encode58Check(contractAddress)); + if (transactionExtention == null) { + return null; + } + Return ret = transactionExtention.getResult(); + if (!ret.getResult()) { + System.out.println("Code = " + ret.getCode()); + System.out.println("Message = " + ret.getMessage().toStringUtf8()); + return null; + } + Transaction transaction = transactionExtention.getTransaction(); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + System.out.println("Transaction is empty"); + return null; + } + transaction = signTransaction(ecKey, transaction); + System.out.println( + "txid = " + ByteArray.toHexString(Sha256Hash.hash(transaction.getRawData().toByteArray()))); + contractAddress = generateContractAddress(transaction, owner); + System.out.println( + "Your smart contract address will be: " + WalletClient.encode58Check(contractAddress)); + int i = 10; + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); + while (response.getResult() == false && response.getCode() == response_code.SERVER_BUSY + && i > 0) { + i--; + response = blockingStubFull.broadcastTransaction(transaction); + logger.info("repeate times = " + (11 - i)); + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (response.getResult() == false) { + logger.info("Code = " + response.getCode()); + logger.info("Message = " + response.getMessage().toStringUtf8()); + return null; + } else { + logger.info("brodacast succesfully"); + return ByteArray.toHexString(Sha256Hash.hash(transaction.getRawData().toByteArray())); + } + } + + + public static SmartContract.ABI jsonStr2Abi(String jsonStr) { + if (jsonStr == null) { + return null; + } + + JsonParser jsonParser = new JsonParser(); + JsonElement jsonElementRoot = jsonParser.parse(jsonStr); + JsonArray jsonRoot = jsonElementRoot.getAsJsonArray(); + SmartContract.ABI.Builder abiBuilder = SmartContract.ABI.newBuilder(); + for (int index = 0; index < jsonRoot.size(); index++) { + JsonElement abiItem = jsonRoot.get(index); + boolean anonymous = abiItem.getAsJsonObject().get("anonymous") != null + ? abiItem.getAsJsonObject().get("anonymous").getAsBoolean() : false; + final boolean constant = abiItem.getAsJsonObject().get("constant") != null + ? abiItem.getAsJsonObject().get("constant").getAsBoolean() : false; + final String name = abiItem.getAsJsonObject().get("name") != null + ? abiItem.getAsJsonObject().get("name").getAsString() : null; + JsonArray inputs = abiItem.getAsJsonObject().get("inputs") != null + ? abiItem.getAsJsonObject().get("inputs").getAsJsonArray() : null; + final JsonArray outputs = abiItem.getAsJsonObject().get("outputs") != null + ? abiItem.getAsJsonObject().get("outputs").getAsJsonArray() : null; + String type = abiItem.getAsJsonObject().get("type") != null + ? abiItem.getAsJsonObject().get("type").getAsString() : null; + final boolean payable = abiItem.getAsJsonObject().get("payable") != null + ? abiItem.getAsJsonObject().get("payable").getAsBoolean() : false; + final String stateMutability = abiItem.getAsJsonObject().get("stateMutability") != null + ? abiItem.getAsJsonObject().get("stateMutability").getAsString() : null; + if (type == null) { + logger.error("No type!"); + return null; + } + if (!type.equalsIgnoreCase("fallback") && null == inputs) { + logger.error("No inputs!"); + return null; + } + + SmartContract.ABI.Entry.Builder entryBuilder = SmartContract.ABI.Entry.newBuilder(); + entryBuilder.setAnonymous(anonymous); + entryBuilder.setConstant(constant); + if (name != null) { + entryBuilder.setName(name); + } + + /* { inputs : optional } since fallback function not requires inputs*/ + if (inputs != null) { + for (int j = 0; j < inputs.size(); j++) { + JsonElement inputItem = inputs.get(j); + if (inputItem.getAsJsonObject().get("name") == null + || inputItem.getAsJsonObject().get("type") == null) { + logger.error("Input argument invalid due to no name or no type!"); + return null; + } + String inputName = inputItem.getAsJsonObject().get("name").getAsString(); + String inputType = inputItem.getAsJsonObject().get("type").getAsString(); + SmartContract.ABI.Entry.Param.Builder paramBuilder = SmartContract.ABI.Entry.Param + .newBuilder(); + paramBuilder.setIndexed(false); + paramBuilder.setName(inputName); + paramBuilder.setType(inputType); + entryBuilder.addInputs(paramBuilder.build()); + } + } + + /* { outputs : optional } */ + if (outputs != null) { + for (int k = 0; k < outputs.size(); k++) { + JsonElement outputItem = outputs.get(k); + if (outputItem.getAsJsonObject().get("name") == null + || outputItem.getAsJsonObject().get("type") == null) { + logger.error("Output argument invalid due to no name or no type!"); + return null; + } + String outputName = outputItem.getAsJsonObject().get("name").getAsString(); + String outputType = outputItem.getAsJsonObject().get("type").getAsString(); + SmartContract.ABI.Entry.Param.Builder paramBuilder = SmartContract.ABI.Entry.Param + .newBuilder(); + paramBuilder.setIndexed(false); + paramBuilder.setName(outputName); + paramBuilder.setType(outputType); + entryBuilder.addOutputs(paramBuilder.build()); + } + } + + entryBuilder.setType(getEntryType(type)); + entryBuilder.setPayable(payable); + if (stateMutability != null) { + entryBuilder.setStateMutability(getStateMutability(stateMutability)); + } + + abiBuilder.addEntrys(entryBuilder.build()); + } + + return abiBuilder.build(); + } + + public static SmartContract.ABI.Entry.EntryType getEntryType(String type) { + switch (type) { + case "constructor": + return SmartContract.ABI.Entry.EntryType.Constructor; + case "function": + return SmartContract.ABI.Entry.EntryType.Function; + case "event": + return SmartContract.ABI.Entry.EntryType.Event; + case "fallback": + return SmartContract.ABI.Entry.EntryType.Fallback; + default: + return SmartContract.ABI.Entry.EntryType.UNRECOGNIZED; + } + } + + public static SmartContract.ABI.Entry.StateMutabilityType getStateMutability( + String stateMutability) { + switch (stateMutability) { + case "pure": + return SmartContract.ABI.Entry.StateMutabilityType.Pure; + case "view": + return SmartContract.ABI.Entry.StateMutabilityType.View; + case "nonpayable": + return SmartContract.ABI.Entry.StateMutabilityType.Nonpayable; + case "payable": + return SmartContract.ABI.Entry.StateMutabilityType.Payable; + default: + return SmartContract.ABI.Entry.StateMutabilityType.UNRECOGNIZED; + } + } + + public static byte[] generateContractAddress(Transaction trx, byte[] owneraddress) { + + // get owner address + // this address should be as same as the onweraddress in trx, DONNOT modify it + byte[] ownerAddress = owneraddress; + + // get tx hash + byte[] txRawDataHash = Sha256Hash.of(trx.getRawData().toByteArray()).getBytes(); + + // combine + byte[] combined = new byte[txRawDataHash.length + ownerAddress.length]; + System.arraycopy(txRawDataHash, 0, combined, 0, txRawDataHash.length); + System.arraycopy(ownerAddress, 0, combined, txRawDataHash.length, ownerAddress.length); + + return Hash.sha3omit12(combined); + + } + + public static SmartContract getContract(byte[] address, WalletGrpc + .WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ByteString byteString = ByteString.copyFrom(address); + BytesMessage bytesMessage = BytesMessage.newBuilder().setValue(byteString).build(); + Integer i = 0; + while (blockingStubFull.getContract(bytesMessage).getName().isEmpty() && i++ < 7) { + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + logger.info("contract name is " + blockingStubFull.getContract(bytesMessage).getName()); + logger.info("contract address is " + WalletClient.encode58Check(address)); + return blockingStubFull.getContract(bytesMessage); + } + + private static byte[] replaceLibraryAddress(String code, byte[] libraryAddress) { + + String libraryAddressHex; + try { + libraryAddressHex = (new String(Hex.encode(libraryAddress), "US-ASCII")).substring(2); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // now ignore + } + + Matcher m = Pattern.compile("__.{36}__").matcher(code); + code = m.replaceAll(libraryAddressHex); + return Hex.decode(code); + } + + public static boolean updateSetting(byte[] contractAddress, long consumeUserResourcePercent, + String priKey, byte[] ownerAddress, WalletGrpc + .WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + + byte[] owner = ownerAddress; + Contract.UpdateSettingContract.Builder builder = Contract.UpdateSettingContract.newBuilder(); + builder.setOwnerAddress(ByteString.copyFrom(owner)); + builder.setContractAddress(ByteString.copyFrom(contractAddress)); + builder.setConsumeUserResourcePercent(consumeUserResourcePercent); + + + UpdateSettingContract updateSettingContract = builder.build(); + TransactionExtention transactionExtention = blockingStubFull + .updateSetting(updateSettingContract); + if (transactionExtention == null || !transactionExtention.getResult().getResult()) { + System.out.println("RPC create trx failed!"); + if (transactionExtention != null) { + System.out.println("Code = " + transactionExtention.getResult().getCode()); + System.out + .println("Message = " + transactionExtention.getResult().getMessage().toStringUtf8()); + } + return false; + } + if (transactionExtention == null) { + return false; + } + Return ret = transactionExtention.getResult(); + if (!ret.getResult()) { + System.out.println("Code = " + ret.getCode()); + System.out.println("Message = " + ret.getMessage().toStringUtf8()); + return false; + } + Transaction transaction = transactionExtention.getTransaction(); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + System.out.println("Transaction is empty"); + return false; + } + System.out.println( + "Receive txid = " + ByteArray.toHexString(transactionExtention.getTxid().toByteArray())); + transaction = signTransaction(ecKey, transaction); + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); + if (response.getResult() == false) { + logger.info(ByteArray.toStr(response.getMessage().toByteArray())); + return false; + } else { + return true; + } + } + + public static Optional getTransactionInfoById(String txId,WalletGrpc + .WalletBlockingStub blockingStubFull) { + ByteString bsTxid = ByteString.copyFrom(ByteArray.fromHexString(txId)); + BytesMessage request = BytesMessage.newBuilder().setValue(bsTxid).build(); + TransactionInfo transactionInfo; + transactionInfo = blockingStubFull.getTransactionInfoById(request); + return Optional.ofNullable(transactionInfo); + } + + public static String triggerContract(byte[] contractAddress, String method,String argsStr, + Boolean isHex, long callValue, long feeLimit,byte[] ownerAddress, + String priKey,WalletGrpc.WalletBlockingStub blockingStubFull) { + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + ECKey temKey = null; + try { + BigInteger priK = new BigInteger(priKey, 16); + temKey = ECKey.fromPrivate(priK); + } catch (Exception ex) { + ex.printStackTrace(); + } + final ECKey ecKey = temKey; + if (argsStr.equalsIgnoreCase("#")) { + logger.info("argsstr is #"); + argsStr = ""; + } + + byte[] owner = ownerAddress; + byte[] input = Hex.decode(AbiUtil.parseMethod(method, argsStr, isHex)); + + + Contract.TriggerSmartContract.Builder builder = Contract.TriggerSmartContract.newBuilder(); + builder.setOwnerAddress(ByteString.copyFrom(owner)); + builder.setContractAddress(ByteString.copyFrom(contractAddress)); + builder.setData(ByteString.copyFrom(input)); + builder.setCallValue(callValue); + Contract.TriggerSmartContract triggerContract = builder.build(); + TransactionExtention transactionExtention = blockingStubFull.triggerContract(triggerContract); + if (transactionExtention == null || !transactionExtention.getResult().getResult()) { + System.out.println("RPC create call trx failed!"); + System.out.println("Code = " + transactionExtention.getResult().getCode()); + System.out + .println("Message = " + transactionExtention.getResult().getMessage().toStringUtf8()); + return null; + } + Transaction transaction = transactionExtention.getTransaction(); + if (transaction.getRetCount() != 0 + && transactionExtention.getConstantResult(0) != null + && transactionExtention.getResult() != null) { + byte[] result = transactionExtention.getConstantResult(0).toByteArray(); + System.out.println("message:" + transaction.getRet(0).getRet()); + System.out.println(":" + ByteArray + .toStr(transactionExtention.getResult().getMessage().toByteArray())); + System.out.println("Result:" + Hex.toHexString(result)); + return null; + } + + final TransactionExtention.Builder texBuilder = TransactionExtention.newBuilder(); + Transaction.Builder transBuilder = Transaction.newBuilder(); + Transaction.raw.Builder rawBuilder = transactionExtention.getTransaction().getRawData() + .toBuilder(); + rawBuilder.setFeeLimit(feeLimit); + transBuilder.setRawData(rawBuilder); + for (int i = 0; i < transactionExtention.getTransaction().getSignatureCount(); i++) { + ByteString s = transactionExtention.getTransaction().getSignature(i); + transBuilder.setSignature(i, s); + } + for (int i = 0; i < transactionExtention.getTransaction().getRetCount(); i++) { + Result r = transactionExtention.getTransaction().getRet(i); + transBuilder.setRet(i, r); + } + texBuilder.setTransaction(transBuilder); + texBuilder.setResult(transactionExtention.getResult()); + texBuilder.setTxid(transactionExtention.getTxid()); + transactionExtention = texBuilder.build(); + if (transactionExtention == null) { + return null; + } + Return ret = transactionExtention.getResult(); + if (!ret.getResult()) { + System.out.println("Code = " + ret.getCode()); + System.out.println("Message = " + ret.getMessage().toStringUtf8()); + return null; + } + transaction = transactionExtention.getTransaction(); + if (transaction == null || transaction.getRawData().getContractCount() == 0) { + System.out.println("Transaction is empty"); + return null; + } + transaction = signTransaction(ecKey, transaction); + System.out.println( + "trigger txid = " + ByteArray.toHexString(Sha256Hash.hash(transaction.getRawData() + .toByteArray()))); + int i = 10; + GrpcAPI.Return response = blockingStubFull.broadcastTransaction(transaction); + while (response.getResult() == false && response.getCode() == response_code.SERVER_BUSY + && i > 0) { + i--; + response = blockingStubFull.broadcastTransaction(transaction); + logger.info("repeate times = " + (11 - i)); + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (response.getResult() == false) { + logger.info("Code = " + response.getCode()); + logger.info("Message = " + response.getMessage().toStringUtf8()); + return null; + } else { + logger.info("brodacast succesfully"); + return ByteArray.toHexString(Sha256Hash.hash(transaction.getRawData().toByteArray())); + } + + + + + + + + + + + + + + } + + + } diff --git a/src/test/java/stest/tron/wallet/common/client/utils/Retry.java b/src/test/java/stest/tron/wallet/common/client/utils/Retry.java new file mode 100644 index 00000000000..6ba976400c7 --- /dev/null +++ b/src/test/java/stest/tron/wallet/common/client/utils/Retry.java @@ -0,0 +1,35 @@ +package stest.tron.wallet.common.client.utils; + +import org.testng.IRetryAnalyzer; +import org.testng.ITestResult; + +public class Retry implements IRetryAnalyzer { + private int retryCount = 0; + private int maxRetryCount = 3; + + // Below method returns 'true' if the test method has to be retried else 'false' + //and it takes the 'Result' as parameter of the test method that just ran + public boolean retry(ITestResult result) { + if (retryCount < maxRetryCount) { + System.out.println("Retrying test " + result.getName() + " with status " + + getResultStatusName(result.getStatus()) + " for the " + (retryCount + 1) + " time(s)."); + retryCount++; + return true; + } + return false; + } + + public String getResultStatusName(int status) { + String resultName = null; + if (status == 1) { + resultName = "SUCCESS"; + } + if (status == 2) { + resultName = "FAILURE"; + } + if (status == 3) { + resultName = "SKIP"; + } + return resultName; + } +} \ No newline at end of file diff --git a/src/test/java/stest/tron/wallet/common/client/utils/RetryListener.java b/src/test/java/stest/tron/wallet/common/client/utils/RetryListener.java new file mode 100644 index 00000000000..1fb49d3ec68 --- /dev/null +++ b/src/test/java/stest/tron/wallet/common/client/utils/RetryListener.java @@ -0,0 +1,21 @@ +package stest.tron.wallet.common.client.utils; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import org.testng.IAnnotationTransformer; +import org.testng.IRetryAnalyzer; +import org.testng.annotations.ITestAnnotation; + +public class RetryListener implements IAnnotationTransformer { + + @Override + public void transform(ITestAnnotation testannotation, Class testClass, + Constructor testConstructor, Method testMethod) { + IRetryAnalyzer retry = testannotation.getRetryAnalyzer(); + + if (retry == null) { + testannotation.setRetryAnalyzer(Retry.class); + } + } +} diff --git a/src/test/java/stest/tron/wallet/common/client/utils/Sha256Hash.java b/src/test/java/stest/tron/wallet/common/client/utils/Sha256Hash.java index b12829d15bd..0e4c9afe1c5 100644 --- a/src/test/java/stest/tron/wallet/common/client/utils/Sha256Hash.java +++ b/src/test/java/stest/tron/wallet/common/client/utils/Sha256Hash.java @@ -63,7 +63,7 @@ private byte[] generateBlockId(long blockNum, byte[] blockHash) { return hash; } - public long getBlockNum(){ + public long getBlockNum() { return blockNum; } diff --git a/src/test/java/stest/tron/wallet/common/client/utils/TransactionUtils.java b/src/test/java/stest/tron/wallet/common/client/utils/TransactionUtils.java index 256bb70b3d8..0a64106071a 100644 --- a/src/test/java/stest/tron/wallet/common/client/utils/TransactionUtils.java +++ b/src/test/java/stest/tron/wallet/common/client/utils/TransactionUtils.java @@ -32,12 +32,6 @@ public class TransactionUtils { private static final Logger logger = LoggerFactory.getLogger("Transaction"); private final static int RESERVE_BALANCE = 10; - /** - * Obtain a data bytes after removing the id and SHA-256(data) - * - * @param transaction {@link Transaction} transaction - * @return byte[] the hash of the transaction's data bytes which have no id - */ public static byte[] getHash(Transaction transaction) { Transaction.Builder tmp = transaction.toBuilder(); //tmp.clearId(); @@ -114,8 +108,8 @@ public static String getBase64FromByteString(ByteString sign) { * 4. check balance */ public static boolean validTransaction(Transaction signedTransaction) { - assert (signedTransaction.getSignatureCount() == - signedTransaction.getRawData().getContractCount()); + assert (signedTransaction.getSignatureCount() + == signedTransaction.getRawData().getContractCount()); List listContract = signedTransaction.getRawData().getContractList(); byte[] hash = Sha256Hash.hash(signedTransaction.getRawData().toByteArray()); int count = signedTransaction.getSignatureCount(); diff --git a/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage001.java b/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage001.java new file mode 100644 index 00000000000..b43d3615c87 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage001.java @@ -0,0 +1,144 @@ +package stest.tron.wallet.contract.linkage; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractLinkage001 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] linkage001Address = ecKey1.getAddress(); + String linkage001Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(linkage001Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(linkage001Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(linkage001Address, 5000000L, + 3,1,linkage001Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,linkage001Address,linkage001Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployContentValue() { + String contractName = "tronNative"; + String noPayableCode = "608060405260008054600160a060020a031990811662010001179091556001805482166201000217905560028054821662010003179055600380548216620100041790556004805482166201000517905560058054821662010006179055600680549091166201000717905534801561007757600080fd5b506104ce806100876000396000f3006080604052600436106100da5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630a90265081146100df5780630dfb51ac146100fc57806345bd20101461012d5780634efaaa1b1461014257806352ae1b811461016657806353c4263f1461017b5780635fd8c710146101905780637c369c90146101a55780637f2b7f93146101ba5780638259d5531461020f578063906fbec914610227578063961a8be71461023c578063cee14bb414610251578063ec9928bd14610275578063fb4f32aa14610292575b600080fd5b3480156100eb57600080fd5b506100fa6004356024356102a7565b005b34801561010857600080fd5b506101116102dc565b60408051600160a060020a039092168252519081900360200190f35b34801561013957600080fd5b506101116102eb565b34801561014e57600080fd5b506100fa600160a060020a03600435166024356102fa565b34801561017257600080fd5b50610111610320565b34801561018757600080fd5b5061011161032f565b34801561019c57600080fd5b506100fa61033e565b3480156101b157600080fd5b5061011161035d565b3480156101c657600080fd5b50604080516020600480358082013583810280860185019096528085526100fa9536959394602494938501929182918501908490808284375094975061036c9650505050505050565b34801561021b57600080fd5b506100fa6004356103c6565b34801561023357600080fd5b506101116103f7565b34801561024857600080fd5b50610111610406565b34801561025d57600080fd5b506100fa600160a060020a0360043516602435610415565b34801561028157600080fd5b506100fa600435602435151561044d565b34801561029e57600080fd5b506100fa610483565b60015460408051848152602081018490528151600160a060020a0390931692818301926000928290030181855af45050505050565b600654600160a060020a031681565b600354600160a060020a031681565b816080528060a0526000608060406080620100016000f4151561031c57600080fd5b5050565b600254600160a060020a031681565b600454600160a060020a031681565b600354604051600160a060020a03909116906000818181855af4505050565b600554600160a060020a031681565b6005546040518251600160a060020a039092169183919081906020808501910280838360005b838110156103aa578181015183820152602001610392565b50505050905001915050600060405180830381855af450505050565b600654604080518381529051600160a060020a039092169160208083019260009291908290030181855af450505050565b600054600160a060020a031681565b600154600160a060020a031681565b6000805460408051600160a060020a03868116825260208201869052825193169381830193909290918290030181855af45050505050565b6004546040805184815283151560208201528151600160a060020a0390931692818301926000928290030181855af45050505050565b600254604051600160a060020a03909116906000818181855af45050505600a165627a7a7230582076efe233a097282a46d3aefb879b720ed02a4ad3c6cf053cc5936a01e366c7dc0029"; + String noPayableAbi = "[{\"constant\":false,\"inputs\":[{\"name\":\"frozen_Balance\",\"type\":\"uint256\"},{\"name\":\"frozen_Duration\",\"type\":\"uint256\"}],\"name\":\"freezeBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"deleteProposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"withdrawBalanceAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\",\"type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteUsingAssembly\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"unFreezeBalanceAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"approveProposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"createProposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"data\",\"type\":\"bytes32[]\"}],\"name\":\"createProposal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"deleteProposal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"voteContractAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"freezeBalanceAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\",\"type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteForSingleWitness\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"},{\"name\":\"isApprove\",\"type\":\"bool\"}],\"name\":\"approveProposal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unFreezeBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + + String payableCode = "608060405260008054600160a060020a03199081166201000117909155600180548216620100021790556002805482166201000317905560038054821662010004179055600480548216620100051790556005805482166201000617905560068054909116620100071790556104ce8061007a6000396000f3006080604052600436106100da5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630a90265081146100df5780630dfb51ac146100fc57806345bd20101461012d5780634efaaa1b1461014257806352ae1b811461016657806353c4263f1461017b5780635fd8c710146101905780637c369c90146101a55780637f2b7f93146101ba5780638259d5531461020f578063906fbec914610227578063961a8be71461023c578063cee14bb414610251578063ec9928bd14610275578063fb4f32aa14610292575b600080fd5b3480156100eb57600080fd5b506100fa6004356024356102a7565b005b34801561010857600080fd5b506101116102dc565b60408051600160a060020a039092168252519081900360200190f35b34801561013957600080fd5b506101116102eb565b34801561014e57600080fd5b506100fa600160a060020a03600435166024356102fa565b34801561017257600080fd5b50610111610320565b34801561018757600080fd5b5061011161032f565b34801561019c57600080fd5b506100fa61033e565b3480156101b157600080fd5b5061011161035d565b3480156101c657600080fd5b50604080516020600480358082013583810280860185019096528085526100fa9536959394602494938501929182918501908490808284375094975061036c9650505050505050565b34801561021b57600080fd5b506100fa6004356103c6565b34801561023357600080fd5b506101116103f7565b34801561024857600080fd5b50610111610406565b34801561025d57600080fd5b506100fa600160a060020a0360043516602435610415565b34801561028157600080fd5b506100fa600435602435151561044d565b34801561029e57600080fd5b506100fa610483565b60015460408051848152602081018490528151600160a060020a0390931692818301926000928290030181855af45050505050565b600654600160a060020a031681565b600354600160a060020a031681565b816080528060a0526000608060406080620100016000f4151561031c57600080fd5b5050565b600254600160a060020a031681565b600454600160a060020a031681565b600354604051600160a060020a03909116906000818181855af4505050565b600554600160a060020a031681565b6005546040518251600160a060020a039092169183919081906020808501910280838360005b838110156103aa578181015183820152602001610392565b50505050905001915050600060405180830381855af450505050565b600654604080518381529051600160a060020a039092169160208083019260009291908290030181855af450505050565b600054600160a060020a031681565b600154600160a060020a031681565b6000805460408051600160a060020a03868116825260208201869052825193169381830193909290918290030181855af45050505050565b6004546040805184815283151560208201528151600160a060020a0390931692818301926000928290030181855af45050505050565b600254604051600160a060020a03909116906000818181855af45050505600a165627a7a72305820bf65c4013bea4495f2cbccf685ee1442e2585d226cf4bd8184c636cdd1d485dc0029"; + String payableAbi = "[{\"constant\":false,\"inputs\":[{\"name\":\"frozen_Balance\",\"type\":\"uint256\"},{\"name\":\"frozen_Duration\",\"type\":\"uint256\"}],\"name\":\"freezeBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"deleteProposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"withdrawBalanceAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\",\"type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteUsingAssembly\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"unFreezeBalanceAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"approveProposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"createProposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"data\",\"type\":\"bytes32[]\"}],\"name\":\"createProposal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"deleteProposal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"voteContractAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"freezeBalanceAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\",\"type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteForSingleWitness\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"},{\"name\":\"isApprove\",\"type\":\"bool\"}],\"name\":\"approveProposal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unFreezeBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"constructor\"}]"; + AccountResourceMessage accountResource = PublicMethed.getAccountResource(linkage001Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + + Account account = PublicMethed.queryAccount(linkage001Key,blockingStubFull); + Long beforeAccountBalance = account.getBalance(); + logger.info("before balance is " + Long.toString(account.getBalance())); + + //Value is 1 drop. + byte [] contractAddress = PublicMethed.deployContract(contractName,payableAbi,payableCode,"",maxFeeLimit, + 1L, 100,null,linkage001Key,linkage001Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + + accountResource = PublicMethed.getAccountResource(linkage001Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + + account = PublicMethed.queryAccount(linkage001Key,blockingStubFull); + Long afterAccountBalance = account.getBalance(); + logger.info(Long.toString(beforeAccountBalance)); + logger.info(Long.toString(afterAccountBalance)); + Assert.assertTrue(beforeAccountBalance - 1L == afterAccountBalance); + account = PublicMethed.queryAccount(contractAddress,blockingStubFull); + Assert.assertTrue(account.getBalance() == 1L); + + //Value is account all balance plus 1. + account = PublicMethed.queryAccount(linkage001Key,blockingStubFull); + Long valueBalance = account.getBalance(); + contractAddress = PublicMethed.deployContract(contractName,payableAbi,payableCode,"",maxFeeLimit, + valueBalance + 1, 100,null,linkage001Key,linkage001Address,blockingStubFull); + Assert.assertTrue(contractAddress == null); + + //Value is account all balance. + account = PublicMethed.queryAccount(linkage001Key,blockingStubFull); + valueBalance = account.getBalance(); + contractAddress = PublicMethed.deployContract(contractName,payableAbi,payableCode,"",maxFeeLimit, + valueBalance, 100,null,linkage001Key,linkage001Address,blockingStubFull); + smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + Assert.assertTrue(PublicMethed.queryAccount(linkage001Key,blockingStubFull).getBalance() == 0); + Assert.assertTrue(PublicMethed.queryAccount(contractAddress,blockingStubFull).getBalance() == valueBalance); + + + + + + } + + + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage002.java b/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage002.java new file mode 100644 index 00000000000..36a66bac919 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage002.java @@ -0,0 +1,193 @@ +package stest.tron.wallet.contract.linkage; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractLinkage002 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] linkage002Address = ecKey1.getAddress(); + String linkage002Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(linkage002Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(linkage002Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(linkage002Address, 5000000L, + 3,1,linkage002Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,linkage002Address,linkage002Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void updateSetting() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(linkage002Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "tronNative"; + String code = "608060405260008054600160a060020a03199081166201000117909155600180548216620100021" + + "790556002805482166201000317905560038054821662010004179055600480548216620100051790556005" + + "8054821662010006179055600680549091166201000717905534801561007757600080fd5b506104ce80610" + + "0876000396000f3006080604052600436106100da5763ffffffff7c01000000000000000000000000000000" + + "000000000000000000000000006000350416630a90265081146100df5780630dfb51ac146100fc57806345b" + + "d20101461012d5780634efaaa1b1461014257806352ae1b811461016657806353c4263f1461017b5780635f" + + "d8c710146101905780637c369c90146101a55780637f2b7f93146101ba5780638259d5531461020f5780639" + + "06fbec914610227578063961a8be71461023c578063cee14bb414610251578063ec9928bd14610275578063" + + "fb4f32aa14610292575b600080fd5b3480156100eb57600080fd5b506100fa6004356024356102a7565b005" + + "b34801561010857600080fd5b506101116102dc565b60408051600160a060020a0390921682525190819003" + + "60200190f35b34801561013957600080fd5b506101116102eb565b34801561014e57600080fd5b506100fa6" + + "00160a060020a03600435166024356102fa565b34801561017257600080fd5b50610111610320565b348015" + + "61018757600080fd5b5061011161032f565b34801561019c57600080fd5b506100fa61033e565b348015610" + + "1b157600080fd5b5061011161035d565b3480156101c657600080fd5b506040805160206004803580820135" + + "83810280860185019096528085526100fa95369593946024949385019291829185019084908082843750949" + + "75061036c9650505050505050565b34801561021b57600080fd5b506100fa6004356103c6565b3480156102" + + "3357600080fd5b506101116103f7565b34801561024857600080fd5b50610111610406565b34801561025d5" + + "7600080fd5b506100fa600160a060020a0360043516602435610415565b34801561028157600080fd5b5061" + + "00fa600435602435151561044d565b34801561029e57600080fd5b506100fa610483565b600154604080518" + + "48152602081018490528151600160a060020a0390931692818301926000928290030181855af45050505050" + + "565b600654600160a060020a031681565b600354600160a060020a031681565b816080528060a0526000608" + + "060406080620100016000f4151561031c57600080fd5b5050565b600254600160a060020a031681565b6004" + + "54600160a060020a031681565b600354604051600160a060020a03909116906000818181855af4505050565" + + "b600554600160a060020a031681565b6005546040518251600160a060020a03909216918391908190602080" + + "8501910280838360005b838110156103aa578181015183820152602001610392565b5050505090500191505" + + "0600060405180830381855af450505050565b600654604080518381529051600160a060020a039092169160" + + "208083019260009291908290030181855af450505050565b600054600160a060020a031681565b600154600" + + "160a060020a031681565b6000805460408051600160a060020a038681168252602082018690528251931693" + + "81830193909290918290030181855af45050505050565b60045460408051848152831515602082015281516" + + "00160a060020a0390931692818301926000928290030181855af45050505050565b600254604051600160a0" + + "60020a03909116906000818181855af45050505600a165627a7a7230582076efe233a097282a46d3aefb879" + + "b720ed02a4ad3c6cf053cc5936a01e366c7dc0029"; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"frozen_Balance\",\"type\":\"uint256" + + "\"},{\"name\":\"frozen_Duration\",\"type\":\"uint256\"}],\"name\":\"freezeBalance\",\"o" + + "utputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}" + + ",{\"constant\":true,\"inputs\":[],\"name\":\"deleteProposalAddress\",\"outputs\":[{\"na" + + "me\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type" + + "\"" + + ":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"withdrawBalanceAddress\",\"o" + + "utputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\"" + + ":\"" + + "view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\"" + + ",\"type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteUs" + + "ingAssembly\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"typ" + + "e\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"unFreezeBalanceAddress\"" + + ",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability" + + "\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"approveP" + + "roposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false," + + "\"" + + "stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"n" + + "ame\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpay" + + "able\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"createProposa" + + "lAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"state" + + "Mutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":" + + "\"data\",\"type\":\"bytes32[]\"}],\"name\":\"createProposal\",\"outputs\":[],\"payable" + + "\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false," + + "\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"deleteProposal\",\"outpu" + + "ts\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"" + + "constant\":true,\"inputs\":[],\"name\":\"voteContractAddress\",\"outputs\":[{\"name\":" + + "\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"" + + "function\"},{\"constant\":true,\"inputs\":[],\"name\":\"freezeBalanceAddress\",\"output" + + "s\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view" + + "\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\",\"" + + "type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteForS" + + "ingleWitness\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t" + + "ype\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint25" + + "6\"},{\"name\":\"isApprove\",\"type\":\"bool\"}],\"name\":\"approveProposal\",\"output" + + "s\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"" + + "constant\":false,\"inputs\":[],\"name\":\"unFreezeBalance\",\"outputs\":[],\"payable\"" + + ":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + + + //Set the consumeUserResourcePercent is -1 + byte [] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, -1,null,linkage002Key,linkage002Address,blockingStubFull); + + //Set the consumeUserResourcePercent is 101 + contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 101,null,linkage002Key,linkage002Address,blockingStubFull); + //Set the consumeUserResourcePercent is 100 + contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,linkage002Key,linkage002Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + Assert.assertTrue(smartContract.getConsumeUserResourcePercent() == 100); + + //Set the consumeUserResourcePercent is 0 + contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 0,null,linkage002Key,linkage002Address,blockingStubFull); + smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + Assert.assertTrue(smartContract.getConsumeUserResourcePercent() == 0); + + + //Update the consumeUserResourcePercent setting. + Assert.assertTrue(PublicMethed.updateSetting(contractAddress,66L, + linkage002Key,linkage002Address,blockingStubFull)); + smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + Assert.assertTrue(smartContract.getConsumeUserResourcePercent() == 66); + + //Updaate the consumeUserResourcePercent setting with -1 and 101 + Assert.assertFalse(PublicMethed.updateSetting(contractAddress,-1L, + linkage002Key,linkage002Address,blockingStubFull)); + Assert.assertFalse(PublicMethed.updateSetting(contractAddress,101L, + linkage002Key,linkage002Address,blockingStubFull)); + + } + + + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage003.java b/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage003.java new file mode 100644 index 00000000000..d9a5508e3dc --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage003.java @@ -0,0 +1,171 @@ +package stest.tron.wallet.contract.linkage; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractLinkage003 { + + //testng001、testng002、testng003、testng004 + private final String testKey003 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey003); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] linkage003Address = ecKey1.getAddress(); + String linkage002Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(linkage002Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(linkage003Address,20000000L,fromAddress, + testKey003,blockingStubFull)); + } + + @Test(enabled = false) + public void deployWhenNoEnergyAndNoStorage() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(linkage003Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "tronNative"; + String code = "608060405260008054600160a060020a03199081166201000117909155600180548216620100021" + + "790556002805482166201000317905560038054821662010004179055600480548216620100051790556005" + + "8054821662010006179055600680549091166201000717905534801561007757600080fd5b506104ce80610" + + "0876000396000f3006080604052600436106100da5763ffffffff7c01000000000000000000000000000000" + + "000000000000000000000000006000350416630a90265081146100df5780630dfb51ac146100fc57806345b" + + "d20101461012d5780634efaaa1b1461014257806352ae1b811461016657806353c4263f1461017b5780635f" + + "d8c710146101905780637c369c90146101a55780637f2b7f93146101ba5780638259d5531461020f5780639" + + "06fbec914610227578063961a8be71461023c578063cee14bb414610251578063ec9928bd14610275578063" + + "fb4f32aa14610292575b600080fd5b3480156100eb57600080fd5b506100fa6004356024356102a7565b005" + + "b34801561010857600080fd5b506101116102dc565b60408051600160a060020a0390921682525190819003" + + "60200190f35b34801561013957600080fd5b506101116102eb565b34801561014e57600080fd5b506100fa6" + + "00160a060020a03600435166024356102fa565b34801561017257600080fd5b50610111610320565b348015" + + "61018757600080fd5b5061011161032f565b34801561019c57600080fd5b506100fa61033e565b348015610" + + "1b157600080fd5b5061011161035d565b3480156101c657600080fd5b506040805160206004803580820135" + + "83810280860185019096528085526100fa95369593946024949385019291829185019084908082843750949" + + "75061036c9650505050505050565b34801561021b57600080fd5b506100fa6004356103c6565b3480156102" + + "3357600080fd5b506101116103f7565b34801561024857600080fd5b50610111610406565b34801561025d5" + + "7600080fd5b506100fa600160a060020a0360043516602435610415565b34801561028157600080fd5b5061" + + "00fa600435602435151561044d565b34801561029e57600080fd5b506100fa610483565b600154604080518" + + "48152602081018490528151600160a060020a0390931692818301926000928290030181855af45050505050" + + "565b600654600160a060020a031681565b600354600160a060020a031681565b816080528060a0526000608" + + "060406080620100016000f4151561031c57600080fd5b5050565b600254600160a060020a031681565b6004" + + "54600160a060020a031681565b600354604051600160a060020a03909116906000818181855af4505050565" + + "b600554600160a060020a031681565b6005546040518251600160a060020a03909216918391908190602080" + + "8501910280838360005b838110156103aa578181015183820152602001610392565b5050505090500191505" + + "0600060405180830381855af450505050565b600654604080518381529051600160a060020a039092169160" + + "208083019260009291908290030181855af450505050565b600054600160a060020a031681565b600154600" + + "160a060020a031681565b6000805460408051600160a060020a038681168252602082018690528251931693" + + "81830193909290918290030181855af45050505050565b60045460408051848152831515602082015281516" + + "00160a060020a0390931692818301926000928290030181855af45050505050565b600254604051600160a0" + + "60020a03909116906000818181855af45050505600a165627a7a7230582076efe233a097282a46d3aefb879" + + "b720ed02a4ad3c6cf053cc5936a01e366c7dc0029"; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"frozen_Balance\",\"type\":\"uint256" + + "\"},{\"name\":\"frozen_Duration\",\"type\":\"uint256\"}],\"name\":\"freezeBalance\",\"o" + + "utputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}" + + ",{\"constant\":true,\"inputs\":[],\"name\":\"deleteProposalAddress\",\"outputs\":[{\"na" + + "me\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type" + + "\"" + + ":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"withdrawBalanceAddress\",\"o" + + "utputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\"" + + ":\"" + + "view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\"" + + ",\"type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteUs" + + "ingAssembly\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"typ" + + "e\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"unFreezeBalanceAddress\"" + + ",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability" + + "\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"approveP" + + "roposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false," + + "\"" + + "stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"n" + + "ame\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpay" + + "able\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"createProposa" + + "lAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"state" + + "Mutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":" + + "\"data\",\"type\":\"bytes32[]\"}],\"name\":\"createProposal\",\"outputs\":[],\"payable" + + "\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false," + + "\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"deleteProposal\",\"outpu" + + "ts\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"" + + "constant\":true,\"inputs\":[],\"name\":\"voteContractAddress\",\"outputs\":[{\"name\":" + + "\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"" + + "function\"},{\"constant\":true,\"inputs\":[],\"name\":\"freezeBalanceAddress\",\"output" + + "s\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view" + + "\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\",\"" + + "type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteForS" + + "ingleWitness\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t" + + "ype\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint25" + + "6\"},{\"name\":\"isApprove\",\"type\":\"bool\"}],\"name\":\"approveProposal\",\"output" + + "s\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"" + + "constant\":false,\"inputs\":[],\"name\":\"unFreezeBalance\",\"outputs\":[],\"payable\"" + + ":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + + Account account = PublicMethed.queryAccount(linkage003Address,blockingStubFull); + Long beforeBalance = account.getBalance(); + byte [] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 0,null,linkage002Key,linkage003Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + account = PublicMethed.queryAccount(linkage003Address,blockingStubFull); + Long afterBalance = account.getBalance(); + Assert.assertTrue(beforeBalance - afterBalance > 0); + accountResource = PublicMethed.getAccountResource(linkage003Address, blockingStubFull); + Assert.assertTrue(accountResource.getEnergyUsed() == 0L); + //Assert.assertTrue(accountResource.getStorageUsed() > 400); + + + + + } + + + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage004.java b/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage004.java new file mode 100644 index 00000000000..0bdd45f0ace --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/linkage/ContractLinkage004.java @@ -0,0 +1,215 @@ +package stest.tron.wallet.contract.linkage; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.TransactionInfo; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractLinkage004 { + + //testng001、testng002、testng003、testng004 + private final String testKey003 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey003); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + String contractName; + String code; + String abi; + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] linkage004Address = ecKey1.getAddress(); + String linkage004Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(linkage004Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(linkage004Address,20000000L,fromAddress, + testKey003,blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalance(linkage004Address,1000000L, + 3,linkage004Key,blockingStubFull)); + } + + @Test(enabled = true) + public void getTransactionInfoById() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(linkage004Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + final Long maxFeeLimit = 15000000L; + contractName = "tronNative"; + code = "608060405260008054600160a060020a03199081166201000117909155600180548216620100021" + + "790556002805482166201000317905560038054821662010004179055600480548216620100051790556005" + + "8054821662010006179055600680549091166201000717905534801561007757600080fd5b506104ce80610" + + "0876000396000f3006080604052600436106100da5763ffffffff7c01000000000000000000000000000000" + + "000000000000000000000000006000350416630a90265081146100df5780630dfb51ac146100fc57806345b" + + "d20101461012d5780634efaaa1b1461014257806352ae1b811461016657806353c4263f1461017b5780635f" + + "d8c710146101905780637c369c90146101a55780637f2b7f93146101ba5780638259d5531461020f5780639" + + "06fbec914610227578063961a8be71461023c578063cee14bb414610251578063ec9928bd14610275578063" + + "fb4f32aa14610292575b600080fd5b3480156100eb57600080fd5b506100fa6004356024356102a7565b005" + + "b34801561010857600080fd5b506101116102dc565b60408051600160a060020a0390921682525190819003" + + "60200190f35b34801561013957600080fd5b506101116102eb565b34801561014e57600080fd5b506100fa6" + + "00160a060020a03600435166024356102fa565b34801561017257600080fd5b50610111610320565b348015" + + "61018757600080fd5b5061011161032f565b34801561019c57600080fd5b506100fa61033e565b348015610" + + "1b157600080fd5b5061011161035d565b3480156101c657600080fd5b506040805160206004803580820135" + + "83810280860185019096528085526100fa95369593946024949385019291829185019084908082843750949" + + "75061036c9650505050505050565b34801561021b57600080fd5b506100fa6004356103c6565b3480156102" + + "3357600080fd5b506101116103f7565b34801561024857600080fd5b50610111610406565b34801561025d5" + + "7600080fd5b506100fa600160a060020a0360043516602435610415565b34801561028157600080fd5b5061" + + "00fa600435602435151561044d565b34801561029e57600080fd5b506100fa610483565b600154604080518" + + "48152602081018490528151600160a060020a0390931692818301926000928290030181855af45050505050" + + "565b600654600160a060020a031681565b600354600160a060020a031681565b816080528060a0526000608" + + "060406080620100016000f4151561031c57600080fd5b5050565b600254600160a060020a031681565b6004" + + "54600160a060020a031681565b600354604051600160a060020a03909116906000818181855af4505050565" + + "b600554600160a060020a031681565b6005546040518251600160a060020a03909216918391908190602080" + + "8501910280838360005b838110156103aa578181015183820152602001610392565b5050505090500191505" + + "0600060405180830381855af450505050565b600654604080518381529051600160a060020a039092169160" + + "208083019260009291908290030181855af450505050565b600054600160a060020a031681565b600154600" + + "160a060020a031681565b6000805460408051600160a060020a038681168252602082018690528251931693" + + "81830193909290918290030181855af45050505050565b60045460408051848152831515602082015281516" + + "00160a060020a0390931692818301926000928290030181855af45050505050565b600254604051600160a0" + + "60020a03909116906000818181855af45050505600a165627a7a7230582076efe233a097282a46d3aefb879" + + "b720ed02a4ad3c6cf053cc5936a01e366c7dc0029"; + abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"frozen_Balance\",\"type\":\"uint256" + + "\"},{\"name\":\"frozen_Duration\",\"type\":\"uint256\"}],\"name\":\"freezeBalance\",\"o" + + "utputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}" + + ",{\"constant\":true,\"inputs\":[],\"name\":\"deleteProposalAddress\",\"outputs\":[{\"na" + + "me\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type" + + "\"" + + ":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"withdrawBalanceAddress\",\"o" + + "utputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\"" + + ":\"" + + "view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\"" + + ",\"type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteUs" + + "ingAssembly\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"typ" + + "e\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"unFreezeBalanceAddress\"" + + ",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability" + + "\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"approveP" + + "roposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false," + + "\"" + + "stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"n" + + "ame\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpay" + + "able\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"createProposa" + + "lAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"state" + + "Mutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":" + + "\"data\",\"type\":\"bytes32[]\"}],\"name\":\"createProposal\",\"outputs\":[],\"payable" + + "\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false," + + "\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"deleteProposal\",\"outpu" + + "ts\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"" + + "constant\":true,\"inputs\":[],\"name\":\"voteContractAddress\",\"outputs\":[{\"name\":" + + "\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"" + + "function\"},{\"constant\":true,\"inputs\":[],\"name\":\"freezeBalanceAddress\",\"output" + + "s\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view" + + "\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\",\"" + + "type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteForS" + + "ingleWitness\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t" + + "ype\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint25" + + "6\"},{\"name\":\"isApprove\",\"type\":\"bool\"}],\"name\":\"approveProposal\",\"output" + + "s\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"" + + "constant\":false,\"inputs\":[],\"name\":\"unFreezeBalance\",\"outputs\":[],\"payable\"" + + ":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + + Account account = PublicMethed.queryAccount(linkage004Address,blockingStubFull); + Long beforeBalance = account.getBalance(); + String txid = PublicMethed.deployContractAndGetTransactionInfoById(contractName,abi,code, + "",maxFeeLimit, 0L, 50,null,linkage004Key,linkage004Address,blockingStubFull); + logger.info("This time txid is " + txid); + + Optional infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.isPresent()); + Assert.assertTrue(infoById.get().getFee() > 0); + //logger.info(Integer.toString(infoById.get().getResultValue())); + Assert.assertTrue(infoById.get().getResultValue() == 0); + Assert.assertTrue(infoById.get().getReceipt().getEnergyFee() > 0); + Assert.assertTrue(infoById.get().getReceipt().getEnergyUsage() == 0); + //Assert.assertTrue(infoById.get().getReceipt().getStorageFee() > 0); + //Assert.assertTrue(infoById.get().getReceipt().getStorageDelta() > 200); + } + + @Test(enabled = false) + public void testFeeLimitIsTooSmall() { + Account account = PublicMethed.queryAccount(linkage004Address,blockingStubFull); + Long maxFeeLimit = 0L; + //When the fee limit is 0. + String txid = PublicMethed.deployContractAndGetTransactionInfoById(contractName,abi,code, + "",maxFeeLimit, 0L, 50,null,linkage004Key,linkage004Address,blockingStubFull); + logger.info("testFeeLimitIsTooSmall, the txid is " + txid); + Optional infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + logger.info("0, Result valse is " + Integer.toString(infoById.get().getResultValue())); + Assert.assertTrue(infoById.get().getResultValue() == 1); + + //When the fee limit is only short with 1 sun. + maxFeeLimit = 14082200L - 1L; + txid = PublicMethed.deployContractAndGetTransactionInfoById(contractName,abi,code, + "",maxFeeLimit, 0L, 50,null,linkage004Key,linkage004Address,blockingStubFull); + logger.info("testFeeLimitIsTooSmall, the txid is " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + logger.info("1000, Result value is " + Integer.toString(infoById.get().getResultValue())); + Assert.assertTrue(infoById.get().getResultValue() == 1); + + //When the fee limit is just ok. + maxFeeLimit = 14082200L; + txid = PublicMethed.deployContractAndGetTransactionInfoById(contractName,abi,code, + "",maxFeeLimit, 0L, 50,null,linkage004Key,linkage004Address,blockingStubFull); + logger.info("testFeeLimitIsTooSmall, the txid is " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + logger.info("1000, Result value is " + Integer.toString(infoById.get().getResultValue())); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + + + + + + } + + + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } + + +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario001.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario001.java new file mode 100644 index 00000000000..58602175a64 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario001.java @@ -0,0 +1,118 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario001 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract001Address = ecKey1.getAddress(); + String contract001Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract001Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract001Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract001Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract001Address, 1000000L, + 3,1,contract001Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract001Address,contract001Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployAddressDemo() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract001Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "addressDemo"; + String code = "608060405234801561001057600080fd5b5060bf8061001f6000396000f3006080604052600436" + + "1060485763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041" + + "66313d1aa2e8114604d5780637995b15b146067575b600080fd5b348015605857600080fd5b506065600435" + + "602435608b565b005b348015607257600080fd5b506079608f565b60408051918252519081900360200190f" + + "35b5050565b42905600a165627a7a72305820086db30620ef850edcb987d91625ecf5a1c342dc87dbabb4fe" + + "4b29ec8c1623c10029"; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"start\",\"type\":\"uint256\"},{\"na" + + "me\":\"daysAfter\",\"type\":\"uint256\"}],\"name\":\"f\",\"outputs\":[],\"payable\":fal" + + "se,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inpu" + + "ts\":[],\"name\":\"nowInSeconds\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"" + + "payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract001Key,contract001Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(contract001Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage == 0L); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario002.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario002.java new file mode 100644 index 00000000000..aa32e514578 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario002.java @@ -0,0 +1,181 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario002 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract002Address = ecKey1.getAddress(); + String contract002Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract002Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract002Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract002Address, 5000000L, + 3,1,contract002Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract002Address,contract002Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployTronNative() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract002Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "tronNative"; + String code = "608060405260008054600160a060020a03199081166201000117909155600180548216620100021" + + "790556002805482166201000317905560038054821662010004179055600480548216620100051790556005" + + "8054821662010006179055600680549091166201000717905534801561007757600080fd5b506104ce80610" + + "0876000396000f3006080604052600436106100da5763ffffffff7c01000000000000000000000000000000" + + "000000000000000000000000006000350416630a90265081146100df5780630dfb51ac146100fc57806345b" + + "d20101461012d5780634efaaa1b1461014257806352ae1b811461016657806353c4263f1461017b5780635f" + + "d8c710146101905780637c369c90146101a55780637f2b7f93146101ba5780638259d5531461020f5780639" + + "06fbec914610227578063961a8be71461023c578063cee14bb414610251578063ec9928bd14610275578063" + + "fb4f32aa14610292575b600080fd5b3480156100eb57600080fd5b506100fa6004356024356102a7565b005" + + "b34801561010857600080fd5b506101116102dc565b60408051600160a060020a0390921682525190819003" + + "60200190f35b34801561013957600080fd5b506101116102eb565b34801561014e57600080fd5b506100fa6" + + "00160a060020a03600435166024356102fa565b34801561017257600080fd5b50610111610320565b348015" + + "61018757600080fd5b5061011161032f565b34801561019c57600080fd5b506100fa61033e565b348015610" + + "1b157600080fd5b5061011161035d565b3480156101c657600080fd5b506040805160206004803580820135" + + "83810280860185019096528085526100fa95369593946024949385019291829185019084908082843750949" + + "75061036c9650505050505050565b34801561021b57600080fd5b506100fa6004356103c6565b3480156102" + + "3357600080fd5b506101116103f7565b34801561024857600080fd5b50610111610406565b34801561025d5" + + "7600080fd5b506100fa600160a060020a0360043516602435610415565b34801561028157600080fd5b5061" + + "00fa600435602435151561044d565b34801561029e57600080fd5b506100fa610483565b600154604080518" + + "48152602081018490528151600160a060020a0390931692818301926000928290030181855af45050505050" + + "565b600654600160a060020a031681565b600354600160a060020a031681565b816080528060a0526000608" + + "060406080620100016000f4151561031c57600080fd5b5050565b600254600160a060020a031681565b6004" + + "54600160a060020a031681565b600354604051600160a060020a03909116906000818181855af4505050565" + + "b600554600160a060020a031681565b6005546040518251600160a060020a03909216918391908190602080" + + "8501910280838360005b838110156103aa578181015183820152602001610392565b5050505090500191505" + + "0600060405180830381855af450505050565b600654604080518381529051600160a060020a039092169160" + + "208083019260009291908290030181855af450505050565b600054600160a060020a031681565b600154600" + + "160a060020a031681565b6000805460408051600160a060020a038681168252602082018690528251931693" + + "81830193909290918290030181855af45050505050565b60045460408051848152831515602082015281516" + + "00160a060020a0390931692818301926000928290030181855af45050505050565b600254604051600160a0" + + "60020a03909116906000818181855af45050505600a165627a7a7230582076efe233a097282a46d3aefb879" + + "b720ed02a4ad3c6cf053cc5936a01e366c7dc0029"; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"frozen_Balance\",\"type\":\"uint256" + + "\"},{\"name\":\"frozen_Duration\",\"type\":\"uint256\"}],\"name\":\"freezeBalance\",\"o" + + "utputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}" + + ",{\"constant\":true,\"inputs\":[],\"name\":\"deleteProposalAddress\",\"outputs\":[{\"na" + + "me\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type" + + "\"" + + ":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"withdrawBalanceAddress\",\"o" + + "utputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\"" + + ":\"" + + "view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\"" + + ",\"type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteUs" + + "ingAssembly\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"typ" + + "e\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"unFreezeBalanceAddress\"" + + ",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability" + + "\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"approveP" + + "roposalAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false," + + "\"" + + "stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"n" + + "ame\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpay" + + "able\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"createProposa" + + "lAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"state" + + "Mutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":" + + "\"data\",\"type\":\"bytes32[]\"}],\"name\":\"createProposal\",\"outputs\":[],\"payable" + + "\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false," + + "\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"deleteProposal\",\"outpu" + + "ts\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"" + + "constant\":true,\"inputs\":[],\"name\":\"voteContractAddress\",\"outputs\":[{\"name\":" + + "\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"" + + "function\"},{\"constant\":true,\"inputs\":[],\"name\":\"freezeBalanceAddress\",\"output" + + "s\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view" + + "\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"witnessAddr\",\"" + + "type\":\"address\"},{\"name\":\"voteValue\",\"type\":\"uint256\"}],\"name\":\"voteForS" + + "ingleWitness\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t" + + "ype\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint25" + + "6\"},{\"name\":\"isApprove\",\"type\":\"bool\"}],\"name\":\"approveProposal\",\"output" + + "s\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"" + + "constant\":false,\"inputs\":[],\"name\":\"unFreezeBalance\",\"outputs\":[],\"payable\"" + + ":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract002Key,contract002Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(contract002Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + Assert.assertTrue(energyUsage > 0); + //Assert.assertTrue(storageUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @Test(enabled = true) + public void getContractWithInvaildAddress() { + byte[] contractAddress = contract002Address; + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + logger.info(smartContract.getAbi().toString()); + Assert.assertTrue(smartContract.getAbi().toString().isEmpty()); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario003.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario003.java new file mode 100644 index 00000000000..a6a1d757978 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario003.java @@ -0,0 +1,213 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario003 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract003Address = ecKey1.getAddress(); + String contract003Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract003Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract003Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract003Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract003Address, 1000000L, + 3,1,contract003Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract003Address,contract003Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployErc223() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract003Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "ERC223"; + String code = "60c0604052600560808190527f546f6b656e0000000000000000000000000000000000000000000" + + "0000000000060a090815261003e91600191906100f5565b506040805180820190915260038082527f544b4e" + + "000000000000000000000000000000000000000000000000000000000060209092019182526100839160029" + + "16100f5565b506003805460ff1916601217905534801561009d57600080fd5b50600354735624c12e308b03" + + "a1a6b21d9b86e3942fac1ab92b600090815260205260ff16600a0a622dc6c0027f6a00ac9bafe0f800e80be" + + "817904e734a2f65b971bcec55ae1c1a276cd920b066819055600455610190565b8280546001816001161561" + + "01000203166002900490600052602060002090601f016020900481019282601f1061013657805160ff19168" + + "38001178555610163565b82800160010185558215610163579182015b828111156101635782518255916020" + + "01919060010190610148565b5061016f929150610173565b5090565b61018d91905b8082111561016f57600" + + "08155600101610179565b90565b610a708061019f6000396000f30060806040526004361061007f5763ffff" + + "ffff60e060020a60003504166306fdde03811461008457806318160ddd1461010e578063313ce5671461013" + + "557806333a581d21461016057806370a082311461017557806395d89b4114610196578063a9059cbb146101" + + "ab578063be45fd62146101e3578063f6368f8a1461024c575b600080fd5b34801561009057600080fd5b506" + + "100996102f3565b6040805160208082528351818301528351919283929083019185019080838360005b8381" + + "10156100d35781810151838201526020016100bb565b50505050905090810190601f1680156101005780820" + + "380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561011a" + + "57600080fd5b50610123610388565b60408051918252519081900360200190f35b34801561014157600080f" + + "d5b5061014a61038e565b6040805160ff9092168252519081900360200190f35b34801561016c57600080fd" + + "5b50610123610397565b34801561018157600080fd5b50610123600160a060020a036004351661039d565b3" + + "480156101a257600080fd5b506100996103b8565b3480156101b757600080fd5b506101cf600160a060020a" + + "0360043516602435610416565b604080519115158252519081900360200190f35b3480156101ef57600080f" + + "d5b50604080516020600460443581810135601f81018490048402850184019095528484526101cf94823560" + + "0160a060020a031694602480359536959460649492019190819084018382808284375094975061044c96505" + + "05050505050565b34801561025857600080fd5b50604080516020600460443581810135601f810184900484" + + "02850184019095528484526101cf948235600160a060020a031694602480359536959460649492019190819" + + "084018382808284375050604080516020601f89358b01803591820183900483028401830190945280835297" + + "9a9998810197919650918201945092508291508401838280828437509497506104809650505050505050565" + + "b60018054604080516020601f60026000196101008789161502019095169490940493840181900481028201" + + "81019092528281526060939092909183018282801561037e5780601f1061035357610100808354040283529" + + "16020019161037e565b820191906000526020600020905b8154815290600101906020018083116103615782" + + "9003601f168201915b5050505050905090565b60045490565b60035460ff1690565b60001981565b600160a" + + "060020a031660009081526020819052604090205490565b60028054604080516020601f6000196101006001" + + "871615020190941685900493840181900481028201810190925282815260609390929091830182828015610" + + "37e5780601f106103535761010080835404028352916020019161037e565b60006060610423846106db565b" + + "1561043a576104338484836106e3565b9150610445565b6104338484836108e5565b5092915050565b60006" + + "10457846106db565b1561046e576104678484846106e3565b9050610479565b6104678484846108e5565b93" + + "92505050565b600061048b856106db565b156106c5578361049a3361039d565b10156104a557600080fd5b6" + + "104b76104b13361039d565b85610a17565b336000908152602081905260409020556104d96104d38661039d" + + "565b85610a2c565b600160a060020a038616600081815260208181526040808320949094559251855192939" + + "19286928291908401908083835b602083106105295780518252601f19909201916020918201910161050a56" + + "5b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910" + + "3902060e060020a9004903387876040518563ffffffff1660e060020a0281526004018084600160a060020a" + + "0316600160a060020a03168152602001838152602001828051906020019080838360005b838110156105bb5" + + "781810151838201526020016105a3565b50505050905090810190601f1680156105e8578082038051600183" + + "6020036101000a031916815260200191505b50935050505060006040518083038185885af19350505050151" + + "561060857fe5b84600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c" + + "8d2be5d310a2c67824cf3f15396e4c168686604051808381526020018060200182810382528381815181526" + + "0200191508051906020019080838360005b8381101561068257818101518382015260200161066a565b5050" + + "5050905090810190601f1680156106af5780820380516001836020036101000a031916815260200191505b5" + + "0935050505060405180910390a35060016106d3565b6106d08585856108e5565b90505b949350505050565b" + + "6000903b1190565b600080836106f03361039d565b10156106fb57600080fd5b6107076104b13361039d565" + + "b336000908152602081905260409020556107236104d38661039d565b600160a060020a0386166000818152" + + "602081815260408083209490945592517fc0ee0b8a000000000000000000000000000000000000000000000" + + "0000000000081523360048201818152602483018a90526060604484019081528951606485015289518c9850" + + "959663c0ee0b8a9693958c958c956084909101928601918190849084905b838110156107bf5781810151838" + + "201526020016107a7565b50505050905090810190601f1680156107ec578082038051600183602003610100" + + "0a031916815260200191505b50945050505050600060405180830381600087803b15801561080d57600080f" + + "d5b505af1158015610821573d6000803e3d6000fd5b5050505084600160a060020a031633600160a060020a" + + "03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1686866040518083815" + + "260200180602001828103825283818151815260200191508051906020019080838360005b8381101561089f" + + "578181015183820152602001610887565b50505050905090810190601f1680156108cc57808203805160018" + + "36020036101000a031916815260200191505b50935050505060405180910390a3506001949350505050565b" + + "6000826108f13361039d565b10156108fc57600080fd5b61090e6109083361039d565b84610a17565b33600" + + "09081526020819052604090205561093061092a8561039d565b84610a2c565b60008086600160a060020a03" + + "16600160a060020a031681526020019081526020016000208190555083600160a060020a031633600160a06" + + "0020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405180" + + "83815260200180602001828103825283818151815260200191508051906020019080838360005b838110156" + + "109d25781810151838201526020016109ba565b50505050905090810190601f1680156109ff578082038051" + + "6001836020036101000a031916815260200191505b50935050505060405180910390a350600193925050505" + + "65b600081831015610a2657600080fd5b50900390565b60008160001903831115610a3f57600080fd5b5001" + + "905600a165627a7a723058203115cc5fa7abcc4f08a54831c433f009dcc6c23769428a1373920a7539c8a72" + + "90029"; + String abi = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"_na" + + "me\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"fu" + + "nction\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"nam" + + "e\":\"_totalSupply\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"vie" + + "w\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"out" + + "puts\":[{\"name\":\"_decimals\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutabilit" + + "y\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"MAX_UIN" + + "T256\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMuta" + + "bility\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_ow" + + "ner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"balance\"," + + "\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"functi" + + "on\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"_sy" + + "mbol\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"" + + "function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"" + + "name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"" + + "success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"t" + + "ype\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"addre" + + "ss\"},{\"name\":\"_value\",\"type\":\"uint256\"},{\"name\":\"_data\",\"type\":\"bytes\"" + + "}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"paya" + + "ble\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":fa" + + "lse,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\"" + + ":\"uint256\"},{\"name\":\"_data\",\"type\":\"bytes\"},{\"name\":\"_custom_fallback\"," + + "\"type\":\"string\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type" + + "\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function" + + "\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"co" + + "nstructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"t" + + "ype\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed" + + "\":false,\"name\":\"_value\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_dat" + + "a\",\"type\":\"bytes\"}],\"name\":\"Transfer\",\"type\":\"event\"}]"; + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract003Key,contract003Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + accountResource = PublicMethed.getAccountResource(contract003Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage > 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario004.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario004.java new file mode 100644 index 00000000000..bd06c88ebf3 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario004.java @@ -0,0 +1,114 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario004 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract004Address = ecKey1.getAddress(); + String contract004Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract004Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract004Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract004Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract004Address, 1000000L, + 3,1,contract004Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract004Address,contract004Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployErc20TronToken() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract004Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "TRONTOKEN"; + String code = "60c0604052600660808190527f54726f6e6978000000000000000000000000000000000000000000000000000060a090815261003e916000919061013c565b506040805180820190915260038082527f545258000000000000000000000000000000000000000000000000000000000060209092019182526100839160019161013c565b506006600281905560006005558054600160a860020a03191690553480156100aa57600080fd5b50604051602080610abc83398101604081815291516006805461010060a860020a031916336101000217905567016345785d8a00006005819055600160a060020a03821660008181526003602090815286822084905592855294519294909390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3506101d7565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785556101aa565b828001600101855582156101aa579182015b828111156101aa57825182559160200191906001019061018f565b506101b69291506101ba565b5090565b6101d491905b808211156101b657600081556001016101c0565b90565b6108d6806101e66000396000f3006080604052600436106100cf5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100d457806307da68f51461015e578063095ea7b31461017557806318160ddd146101ad57806323b872dd146101d4578063313ce567146101fe57806342966c681461021357806370a082311461022b57806375f12b211461024c57806395d89b4114610261578063a9059cbb14610276578063be9a65551461029a578063c47f0027146102af578063dd62ed3e14610308575b600080fd5b3480156100e057600080fd5b506100e961032f565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012357818101518382015260200161010b565b50505050905090810190601f1680156101505780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016a57600080fd5b506101736103bd565b005b34801561018157600080fd5b50610199600160a060020a03600435166024356103e5565b604080519115158252519081900360200190f35b3480156101b957600080fd5b506101c261049e565b60408051918252519081900360200190f35b3480156101e057600080fd5b50610199600160a060020a03600435811690602435166044356104a4565b34801561020a57600080fd5b506101c26105c1565b34801561021f57600080fd5b506101736004356105c7565b34801561023757600080fd5b506101c2600160a060020a036004351661065e565b34801561025857600080fd5b50610199610670565b34801561026d57600080fd5b506100e9610679565b34801561028257600080fd5b50610199600160a060020a03600435166024356106d3565b3480156102a657600080fd5b5061017361079d565b3480156102bb57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101739436949293602493928401919081908401838280828437509497506107c29650505050505050565b34801561031457600080fd5b506101c2600160a060020a03600435811690602435166107f2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103b55780601f1061038a576101008083540402835291602001916103b5565b820191906000526020600020905b81548152906001019060200180831161039857829003601f168201915b505050505081565b6006546101009004600160a060020a031633146103d657fe5b6006805460ff19166001179055565b60065460009060ff16156103f557fe5b3315156103fe57fe5b81158061042c5750336000908152600460209081526040808320600160a060020a0387168452909152902054155b151561043757600080fd5b336000818152600460209081526040808320600160a060020a03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b60055481565b60065460009060ff16156104b457fe5b3315156104bd57fe5b600160a060020a0384166000908152600360205260409020548211156104e257600080fd5b600160a060020a038316600090815260036020526040902054828101101561050957600080fd5b600160a060020a038416600090815260046020908152604080832033845290915290205482111561053957600080fd5b600160a060020a03808416600081815260036020908152604080832080548801905593881680835284832080548890039055600482528483203384528252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060019392505050565b60025481565b336000908152600360205260409020548111156105e357600080fd5b336000818152600360209081526040808320805486900390558280527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff805486019055805185815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350565b60036020526000908152604090205481565b60065460ff1681565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103b55780601f1061038a576101008083540402835291602001916103b5565b60065460009060ff16156106e357fe5b3315156106ec57fe5b3360009081526003602052604090205482111561070857600080fd5b600160a060020a038316600090815260036020526040902054828101101561072f57600080fd5b33600081815260036020908152604080832080548790039055600160a060020a03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350600192915050565b6006546101009004600160a060020a031633146107b657fe5b6006805460ff19169055565b6006546101009004600160a060020a031633146107db57fe5b80516107ee90600090602084019061080f565b5050565b600460209081526000928352604080842090915290825290205481565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061085057805160ff191683800117855561087d565b8280016001018555821561087d579182015b8281111561087d578251825591602001919060010190610862565b5061088992915061088d565b5090565b6108a791905b808211156108895760008155600101610893565b905600a165627a7a72305820d00bcb788ca406de94859b8bc4bda50c3c65ca67e1217ccccee92f59a92ae5e20029"; + String abi = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"stop\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"stopped\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"start\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_addressFounder\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}]"; + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L,100,null,contract004Key,contract004Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + accountResource = PublicMethed.getAccountResource(contract004Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage > 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario005.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario005.java new file mode 100644 index 00000000000..6c49ba7ba01 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario005.java @@ -0,0 +1,114 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario005 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract005Address = ecKey1.getAddress(); + String contract005Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract005Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract005Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract005Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract005Address, 1000000L, + 3,1,contract005Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract005Address,contract005Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployIcoContract() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract005Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "ICO"; + String code = "60c0604052600660808190527f54726f6e6978000000000000000000000000000000000000000000000000000060a090815261003e916000919061013c565b506040805180820190915260038082527f545258000000000000000000000000000000000000000000000000000000000060209092019182526100839160019161013c565b506006600281905560006005558054600160a860020a03191690553480156100aa57600080fd5b50604051602080610abc83398101604081815291516006805461010060a860020a031916336101000217905567016345785d8a00006005819055600160a060020a03821660008181526003602090815286822084905592855294519294909390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3506101d7565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785556101aa565b828001600101855582156101aa579182015b828111156101aa57825182559160200191906001019061018f565b506101b69291506101ba565b5090565b6101d491905b808211156101b657600081556001016101c0565b90565b6108d6806101e66000396000f3006080604052600436106100cf5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100d457806307da68f51461015e578063095ea7b31461017557806318160ddd146101ad57806323b872dd146101d4578063313ce567146101fe57806342966c681461021357806370a082311461022b57806375f12b211461024c57806395d89b4114610261578063a9059cbb14610276578063be9a65551461029a578063c47f0027146102af578063dd62ed3e14610308575b600080fd5b3480156100e057600080fd5b506100e961032f565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012357818101518382015260200161010b565b50505050905090810190601f1680156101505780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561016a57600080fd5b506101736103bd565b005b34801561018157600080fd5b50610199600160a060020a03600435166024356103e5565b604080519115158252519081900360200190f35b3480156101b957600080fd5b506101c261049e565b60408051918252519081900360200190f35b3480156101e057600080fd5b50610199600160a060020a03600435811690602435166044356104a4565b34801561020a57600080fd5b506101c26105c1565b34801561021f57600080fd5b506101736004356105c7565b34801561023757600080fd5b506101c2600160a060020a036004351661065e565b34801561025857600080fd5b50610199610670565b34801561026d57600080fd5b506100e9610679565b34801561028257600080fd5b50610199600160a060020a03600435166024356106d3565b3480156102a657600080fd5b5061017361079d565b3480156102bb57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101739436949293602493928401919081908401838280828437509497506107c29650505050505050565b34801561031457600080fd5b506101c2600160a060020a03600435811690602435166107f2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103b55780601f1061038a576101008083540402835291602001916103b5565b820191906000526020600020905b81548152906001019060200180831161039857829003601f168201915b505050505081565b6006546101009004600160a060020a031633146103d657fe5b6006805460ff19166001179055565b60065460009060ff16156103f557fe5b3315156103fe57fe5b81158061042c5750336000908152600460209081526040808320600160a060020a0387168452909152902054155b151561043757600080fd5b336000818152600460209081526040808320600160a060020a03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b60055481565b60065460009060ff16156104b457fe5b3315156104bd57fe5b600160a060020a0384166000908152600360205260409020548211156104e257600080fd5b600160a060020a038316600090815260036020526040902054828101101561050957600080fd5b600160a060020a038416600090815260046020908152604080832033845290915290205482111561053957600080fd5b600160a060020a03808416600081815260036020908152604080832080548801905593881680835284832080548890039055600482528483203384528252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060019392505050565b60025481565b336000908152600360205260409020548111156105e357600080fd5b336000818152600360209081526040808320805486900390558280527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff805486019055805185815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350565b60036020526000908152604090205481565b60065460ff1681565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103b55780601f1061038a576101008083540402835291602001916103b5565b60065460009060ff16156106e357fe5b3315156106ec57fe5b3360009081526003602052604090205482111561070857600080fd5b600160a060020a038316600090815260036020526040902054828101101561072f57600080fd5b33600081815260036020908152604080832080548790039055600160a060020a03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350600192915050565b6006546101009004600160a060020a031633146107b657fe5b6006805460ff19169055565b6006546101009004600160a060020a031633146107db57fe5b80516107ee90600090602084019061080f565b5050565b600460209081526000928352604080842090915290825290205481565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061085057805160ff191683800117855561087d565b8280016001018555821561087d579182015b8281111561087d578251825591602001919060010190610862565b5061088992915061088d565b5090565b6108a791905b808211156108895760008155600101610893565b905600a165627a7a72305820d00bcb788ca406de94859b8bc4bda50c3c65ca67e1217ccccee92f59a92ae5e20029"; + String abi = "[{\"constant\":false,\"inputs\":[],\"name\":\"checkGoalReached\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"deadline\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"beneficiary\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"tokenReward\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"fundingGoal\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"amountRaised\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"price\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"safeWithdrawal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"ifSuccessfulSendTo\",\"type\":\"address\"},{\"name\":\"fundingGoalInEthers\",\"type\":\"uint256\"},{\"name\":\"durationInMinutes\",\"type\":\"uint256\"},{\"name\":\"finneyCostOfEachToken\",\"type\":\"uint256\"},{\"name\":\"addressOfTokenUsedAsReward\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"totalAmountRaised\",\"type\":\"uint256\"}],\"name\":\"GoalReached\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"backer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"isContribution\",\"type\":\"bool\"}],\"name\":\"FundTransfer\",\"type\":\"event\"}]"; + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract005Key,contract005Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + accountResource = PublicMethed.getAccountResource(contract005Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage > 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario006.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario006.java new file mode 100644 index 00000000000..3be48a9e6a6 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario006.java @@ -0,0 +1,114 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario006 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract006Address = ecKey1.getAddress(); + String contract006Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract006Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract006Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract006Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract006Address, 1000000L, + 3,1,contract006Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract006Address,contract006Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployFomo3D() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract006Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "Fomo3D"; + String code = "60c0604052600660808190527f464f4d4f3344000000000000000000000000000000000000000000000000000060a0908152620000409160009190620000b8565b506040805180820190915260038082527f463344000000000000000000000000000000000000000000000000000000000060209092019182526200008791600191620000b8565b5068056bc75e2d631000006002556000600855600b805460ff19169055348015620000b157600080fd5b506200015d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620000fb57805160ff19168380011785556200012b565b828001600101855582156200012b579182015b828111156200012b5782518255916020019190600101906200010e565b50620001399291506200013d565b5090565b6200015a91905b8082111562000139576000815560010162000144565b90565b611688806200016d6000396000f3006080604052600436106101685763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166265318b811461017657806306fdde03146101a957806310d0ffdd1461023357806318160ddd1461024b578063226093731461026057806327defa1f14610278578063313ce567146102a1578063392efb52146102cc5780633ccfd60b146102e45780634b750334146102fb57806356d399e814610310578063688abbf7146103255780636b2f46321461033f57806370a08231146103545780638328b610146103755780638620410b1461038d57806389135ae9146103a25780638fea64bd146103bf578063949e8acd146103d457806395d89b41146103e9578063a8e04f34146103fe578063a9059cbb14610413578063b84c824614610437578063c47f002714610490578063e4849b32146104e9578063e9fad8ee14610501578063f088d54714610516578063fdb5a03e1461052a575b61017334600061053f565b50005b34801561018257600080fd5b50610197600160a060020a0360043516610b15565b60408051918252519081900360200190f35b3480156101b557600080fd5b506101be610b50565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101f85781810151838201526020016101e0565b50505050905090810190601f1680156102255780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023f57600080fd5b50610197600435610bde565b34801561025757600080fd5b50610197610c0e565b34801561026c57600080fd5b50610197600435610c15565b34801561028457600080fd5b5061028d610c4e565b604080519115158252519081900360200190f35b3480156102ad57600080fd5b506102b6610c57565b6040805160ff9092168252519081900360200190f35b3480156102d857600080fd5b5061028d600435610c5c565b3480156102f057600080fd5b506102f9610c71565b005b34801561030757600080fd5b50610197610d44565b34801561031c57600080fd5b50610197610d98565b34801561033157600080fd5b506101976004351515610d9e565b34801561034b57600080fd5b50610197610de1565b34801561036057600080fd5b50610197600160a060020a0360043516610de6565b34801561038157600080fd5b506102f9600435610e01565b34801561039957600080fd5b50610197610e48565b3480156103ae57600080fd5b506102f96004356024351515610e90565b3480156103cb57600080fd5b506102f9610ef2565b3480156103e057600080fd5b50610197610ef4565b3480156103f557600080fd5b506101be610f07565b34801561040a57600080fd5b506102f9610f61565b34801561041f57600080fd5b5061028d600160a060020a0360043516602435610faf565b34801561044357600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102f99436949293602493928401919081908401838280828437509497506111699650505050505050565b34801561049c57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102f99436949293602493928401919081908401838280828437509497506111c29650505050505050565b3480156104f557600080fd5b506102f9600435611216565b34801561050d57600080fd5b506102f9611367565b610197600160a060020a0360043516611394565b34801561053657600080fd5b506102f96113a0565b60008060008060008060008060008a6000339050600b60009054906101000a900460ff16801561058157506801158e460913d000008261057d610de1565b0311155b1561088e57600160a060020a03811660009081526003602052604090205460ff16151560011480156105d65750600160a060020a038116600090815260076020526040902054670de0b6b3a764000090830111155b15156105e157600080fd5b600160a060020a0381166000908152600760205260409020546106049083611456565b600160a060020a03821660009081526007602052604090205533995061062b8d600561146c565b985061063889600361146c565b97506106448989611483565b96506106508d8a611483565b955061065b86611495565b9450680100000000000000008702935060008511801561068557506008546106838682611456565b115b151561069057600080fd5b600160a060020a038c16158015906106ba575089600160a060020a03168c600160a060020a031614155b80156106e05750600254600160a060020a038d1660009081526004602052604090205410155b1561072657600160a060020a038c166000908152600560205260409020546107089089611456565b600160a060020a038d16600090815260056020526040902055610741565b6107308789611456565b965068010000000000000000870293505b600060085411156107a55761075860085486611456565b600881905568010000000000000000880281151561077257fe5b6009805492909104909101905560085468010000000000000000880281151561079757fe5b0485028403840393506107ab565b60088590555b600160a060020a038a166000908152600460205260409020546107ce9086611456565b600460008c600160a060020a0316600160a060020a031681526020019081526020016000208190555083856009540203925082600660008c600160a060020a0316600160a060020a03168152602001908152602001600020600082825401925050819055508b600160a060020a03168a600160a060020a03167f022c0d992e4d873a3748436d960d5140c1f9721cf73f7ca5ec679d3d9f4fe2d58f88604051808381526020018281526020019250505060405180910390a3849a50610b05565b600b805460ff191690553399506108a68d600561146c565b98506108b389600361146c565b97506108bf8989611483565b96506108cb8d8a611483565b95506108d686611495565b9450680100000000000000008702935060008511801561090057506008546108fe8682611456565b115b151561090b57600080fd5b600160a060020a038c1615801590610935575089600160a060020a03168c600160a060020a031614155b801561095b5750600254600160a060020a038d1660009081526004602052604090205410155b156109a157600160a060020a038c166000908152600560205260409020546109839089611456565b600160a060020a038d166000908152600560205260409020556109bc565b6109ab8789611456565b965068010000000000000000870293505b60006008541115610a20576109d360085486611456565b60088190556801000000000000000088028115156109ed57fe5b60098054929091049091019055600854680100000000000000008802811515610a1257fe5b048502840384039350610a26565b60088590555b600160a060020a038a16600090815260046020526040902054610a499086611456565b600460008c600160a060020a0316600160a060020a031681526020019081526020016000208190555083856009540203925082600660008c600160a060020a0316600160a060020a03168152602001908152602001600020600082825401925050819055508b600160a060020a03168a600160a060020a03167f022c0d992e4d873a3748436d960d5140c1f9721cf73f7ca5ec679d3d9f4fe2d58f88604051808381526020018281526020019250505060405180910390a3849a505b5050505050505050505092915050565b600160a060020a0316600090815260066020908152604080832054600490925290912054600954680100000000000000009102919091030490565b6000805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610bd65780601f10610bab57610100808354040283529160200191610bd6565b820191906000526020600020905b815481529060010190602001808311610bb957829003601f168201915b505050505081565b6000808080610bee85600561146c565b9250610bfa8584611483565b9150610c0582611495565b95945050505050565b6008545b90565b6000806000806008548511151515610c2c57600080fd5b610c358561152d565b9250610c4283600561146c565b9150610c058383611483565b600b5460ff1681565b601281565b600a6020526000908152604090205460ff1681565b6000806000610c806001610d9e565b11610c8a57600080fd5b339150610c976000610d9e565b600160a060020a038316600081815260066020908152604080832080546801000000000000000087020190556005909152808220805490839055905193019350909183156108fc0291849190818181858888f19350505050158015610d00573d6000803e3d6000fd5b50604080518281529051600160a060020a038416917fccad973dcd043c7d680389db4378bd6b9775db7124092e9e0422c9e46d7985dc919081900360200190a25050565b60008060008060085460001415610d62576414f46b04009350610d92565b610d73670de0b6b3a764000061152d565b9250610d8083600561146c565b9150610d8c8383611483565b90508093505b50505090565b60025481565b60003382610db457610daf81610b15565b610dd8565b600160a060020a038116600090815260056020526040902054610dd682610b15565b015b91505b50919050565b303190565b600160a060020a031660009081526004602052604090205490565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff161515610e4257600080fd5b50600255565b60008060008060085460001415610e665764199c82cc009350610d92565b610e77670de0b6b3a764000061152d565b9250610e8483600561146c565b9150610d8c8383611456565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff161515610ed157600080fd5b506000918252600a6020526040909120805460ff1916911515919091179055565b565b600033610f0081610de6565b91505b5090565b60018054604080516020600284861615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610bd65780601f10610bab57610100808354040283529160200191610bd6565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff161515610fa257600080fd5b50600b805460ff19169055565b600080600080600080610fc0610ef4565b11610fca57600080fd5b600b5433945060ff16158015610ff85750600160a060020a0384166000908152600460205260409020548611155b151561100357600080fd5b600061100f6001610d9e565b111561101d5761101d610c71565b61102886600561146c565b92506110348684611483565b915061103f8361152d565b905061104d60085484611483565b600855600160a060020a0384166000908152600460205260409020546110739087611483565b600160a060020a0380861660009081526004602052604080822093909355908916815220546110a29083611456565b600160a060020a0388811660008181526004602090815260408083209590955560098054948a16835260069091528482208054948c02909403909355825491815292909220805492850290920190915554600854611116919068010000000000000000840281151561111057fe5b04611456565b600955604080518381529051600160a060020a03808a1692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35060019695505050505050565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff1615156111aa57600080fd5b81516111bd9060019060208501906115ce565b505050565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff16151561120357600080fd5b81516111bd9060009060208501906115ce565b6000806000806000806000611229610ef4565b1161123357600080fd5b3360008181526004602052604090205490965087111561125257600080fd5b86945061125e8561152d565b935061126b84600561146c565b92506112778484611483565b915061128560085486611483565b600855600160a060020a0386166000908152600460205260409020546112ab9086611483565b600160a060020a0387166000908152600460209081526040808320939093556009546006909152918120805492880268010000000000000000860201928390039055600854919250101561131b5761131760095460085468010000000000000000860281151561111057fe5b6009555b60408051868152602081018490528151600160a060020a038916927fc4823739c5787d2ca17e404aa47d5569ae71dfb49cbf21b3f6152ed238a31139928290030190a250505050505050565b33600081815260046020526040812054908111156113885761138881611216565b611390610c71565b5050565b6000610ddb348361053f565b6000806000806113b06001610d9e565b116113ba57600080fd5b6113c46000610d9e565b3360008181526006602090815260408083208054680100000000000000008702019055600590915281208054908290559092019450925061140690849061053f565b905081600160a060020a03167fbe339fc14b041c2b0e0f3dd2cd325d0c3668b78378001e53160eab36153264588483604051808381526020018281526020019250505060405180910390a2505050565b60008282018381101561146557fe5b9392505050565b600080828481151561147a57fe5b04949350505050565b60008282111561148f57fe5b50900390565b6008546000906c01431e0fae6d7217caa00000009082906402540be40061151a611514730380d4bd8a8678c1bb542c80deb4800000000000880268056bc75e2d631000006002860a02017005e0a1fd2712875988becaad0000000000850201780197d4df19d605767337e9f14d3eec8920e40000000000000001611599565b85611483565b81151561152357fe5b0403949350505050565b600854600090670de0b6b3a76400008381019181019083906115866414f46b04008285046402540be40002018702600283670de0b6b3a763ffff1982890a8b900301046402540be4000281151561158057fe5b04611483565b81151561158f57fe5b0495945050505050565b80600260018201045b81811015610ddb5780915060028182858115156115bb57fe5b04018115156115c657fe5b0490506115a2565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061160f57805160ff191683800117855561163c565b8280016001018555821561163c579182015b8281111561163c578251825591602001919060010190611621565b50610f0392610c129250905b80821115610f0357600081556001016116485600a165627a7a723058202986f1ef7924e33e9f5613300f260c5fd9f05700de3217343d70f3a5fea5f76d0029"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"_customerAddress\",\"type\":\"address\"}],\"name\":\"dividendsOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_ethereumToSpend\",\"type\":\"uint256\"}],\"name\":\"calculateTokensReceived\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokensToSell\",\"type\":\"uint256\"}],\"name\":\"calculateEthereumReceived\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"onlyAmbassadors\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"administrators\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"sellPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"stakingRequirement\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_includeReferralBonus\",\"type\":\"bool\"}],\"name\":\"myDividends\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalEthereumBalance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_customerAddress\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_amountOfTokens\",\"type\":\"uint256\"}],\"name\":\"setStakingRequirement\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"buyPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_identifier\",\"type\":\"bytes32\"},{\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"setAdministrator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"Hourglass\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"myTokens\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"disableInitialStage\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_toAddress\",\"type\":\"address\"},{\"name\":\"_amountOfTokens\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"setSymbol\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_amountOfTokens\",\"type\":\"uint256\"}],\"name\":\"sell\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"exit\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_referredBy\",\"type\":\"address\"}],\"name\":\"buy\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"reinvest\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"customerAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"incomingEthereum\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tokensMinted\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"referredBy\",\"type\":\"address\"}],\"name\":\"onTokenPurchase\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"customerAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokensBurned\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"ethereumEarned\",\"type\":\"uint256\"}],\"name\":\"onTokenSell\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"customerAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"ethereumReinvested\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tokensMinted\",\"type\":\"uint256\"}],\"name\":\"onReinvestment\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"customerAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"ethereumWithdrawn\",\"type\":\"uint256\"}],\"name\":\"onWithdraw\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"}]"; + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L,100,null, contract006Key,contract006Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + accountResource = PublicMethed.getAccountResource(contract006Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage > 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario007.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario007.java new file mode 100644 index 00000000000..198aa169ae9 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario007.java @@ -0,0 +1,119 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario007 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract007Address = ecKey1.getAddress(); + String contract007Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract007Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract007Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract007Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract007Address, 1000000L, + 3,1,contract007Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(4000000L,contract007Address,contract007Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployErc721CardMigration() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract007Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(contract007Key,blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 6000000L; + String contractName = "ERC721"; + String code = "6000805460a060020a60ff021916905560e0604052602360808190527f68747470733a2f2f6170692e676f6473756e636861696e65642e636f6d2f636160a09081527f72642f000000000000000000000000000000000000000000000000000000000060c0526200007491601091906200023e565b503480156200008257600080fd5b5060405160208062004212833981016040525160008054600160a060020a03191633179055620000db7f01ffc9a700000000000000000000000000000000000000000000000000000000640100000000620001d1810204565b6200010f7f80ac58cd00000000000000000000000000000000000000000000000000000000640100000000620001d1810204565b620001437f4f558e7900000000000000000000000000000000000000000000000000000000640100000000620001d1810204565b620001777f780e9d6300000000000000000000000000000000000000000000000000000000640100000000620001d1810204565b620001ab7f5b5e139f00000000000000000000000000000000000000000000000000000000640100000000620001d1810204565b60158054600160a060020a031916600160a060020a0392909216919091179055620002e3565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200020157600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600c60205260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200028157805160ff1916838001178555620002b1565b82800160010185558215620002b1579182015b82811115620002b157825182559160200191906001019062000294565b50620002bf929150620002c3565b5090565b620002e091905b80821115620002bf5760008155600101620002ca565b90565b613f1f80620002f36000396000f3006080604052600436106103425763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a7811461034757806305c4af9d1461037d57806306fdde031461040c578063081812fc14610496578063095ea7b3146104ca5780630bbe0ee3146104f05780630c340a241461055b5780630e359f1614610570578063100cdd911461058857806318160ddd146105dd57806319fa8f50146106045780631fa24aa71461063657806323b872dd1461065157806324a96d701461067b5780632f745c59146106c5578063396ed600146106e95780633cb4ff3c146107015780633f4ba83a1461071657806342842e0e1461072b57806342966c6814610755578063454b06081461076d5780634cc90115146107855780634f558e791461079d5780634f6ccce7146107b55780634fb31a6a146107cd578063524773ce1461080d5780635bd9d9a5146108225780635c975abb1461083d5780635dcbd8bb146108525780636352211e1461087b57806367025dcf1461089357806370a08231146108e95780637a8b9b851461090a578063818d4b5d14610925578063821f830f146109495780638456cb591461096a578063850e37601461097f5780638dc10768146109b15780638e7e879f146109ea5780639188d31214610a3f578063943b82f114610a5757806395d89b4114610a97578063986e82f214610aac578063a22cb46514610ac8578063a3f4df7e14610aee578063a5487e5114610b03578063a71aec7314610b1b578063a9059cbb14610b37578063ad94d90114610b4e578063b5cab1ce14610bb1578063b84c139214610bc6578063b88d4fde14610bde578063bc734f0f14610c4d578063bcb3962114610c62578063c42cf53514610c77578063c87b56dd14610c98578063c968aab314610cb0578063caa1916814610ccb578063ce9fdb7014610ced578063ced28d7714610d2c578063d7643e1814610d78578063d80f862114610d8d578063dfb6a75f14610da5578063e3c7336b14610dea578063e7cf548c14611007578063e985e9c51461101c578063eeffbe4e14611043578063f03034521461105b578063f5f23b52146110be578063f76f8d78146110d9578063fb36eba1146110ee575b600080fd5b34801561035357600080fd5b50610369600160e060020a03196004351661111c565b604080519115158252519081900360200190f35b34801561038957600080fd5b5061039961ffff6004351661113b565b604080518a1515815260ff808b166020830152898116928201929092529087166060820152608081018660048111156103ce57fe5b60ff90811682529586166020820152938516604080860191909152928516606085015250909216608082015290519081900360a00195509350505050f35b34801561041857600080fd5b50610421611296565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561045b578181015183820152602001610443565b50505050905090810190601f1680156104885780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104a257600080fd5b506104ae6004356112ce565b60408051600160a060020a039092168252519081900360200190f35b3480156104d657600080fd5b506104ee600160a060020a03600435166024356112e9565b005b3480156104fc57600080fd5b5060408051602060046044358181013583810280860185019096528085526104ee958335600160a060020a0390811696602480359092169636969560649592949301928291850190849080828437509497506113299650505050505050565b34801561056757600080fd5b506104ae611365565b34801561057c57600080fd5b50610369600435611374565b34801561059457600080fd5b50604080516020600480358082013583810280860185019096528085526104ee953695939460249493850192918291850190849080828437509497506113899650505050505050565b3480156105e957600080fd5b506105f26113bd565b60408051918252519081900360200190f35b34801561061057600080fd5b506106196113c3565b60408051600160e060020a03199092168252519081900360200190f35b34801561064257600080fd5b506104ee60ff600435166113e7565b34801561065d57600080fd5b506104ee600160a060020a036004358116906024351660443561143c565b34801561068757600080fd5b506106ae61ffff6004351660ff602435811690604435811690606435166084351515611469565b6040805161ffff9092168252519081900360200190f35b3480156106d157600080fd5b506105f2600160a060020a03600435166024356114ff565b3480156106f557600080fd5b506106ae60043561156f565b34801561070d57600080fd5b506105f26115a5565b34801561072257600080fd5b506104ee6115b8565b34801561073757600080fd5b506104ee600160a060020a036004358116906024351660443561162e565b34801561076157600080fd5b506104ee600435611660565b34801561077957600080fd5b506104ee600435611691565b34801561079157600080fd5b506106ae60043561180c565b3480156107a957600080fd5b5061036960043561181a565b3480156107c157600080fd5b506105f2600435611837565b3480156107d957600080fd5b506104ee61ffff6004351660ff60243581169060443581169060643581169060843581169060a43581169060c43516611850565b34801561081957600080fd5b506105f2611b03565b34801561082e57600080fd5b5061036960ff60043516611b09565b34801561084957600080fd5b50610369611b1e565b34801561085e57600080fd5b506104ee61ffff6004351667ffffffffffffffff60243516611b2e565b34801561088757600080fd5b506104ae600435611c0c565b6040805160206004602480358281013584810280870186019097528086526104ee968435600160a060020a031696369660449591949091019291829185019084908082843750949750611c369650505050505050565b3480156108f557600080fd5b506105f2600160a060020a0360043516611c6b565b34801561091657600080fd5b5061036960ff60043516611c86565b34801561093157600080fd5b50610369600160a060020a0360043516602435611c9b565b34801561095557600080fd5b506104ee600160a060020a0360043516611cc1565b34801561097657600080fd5b506104ee611d37565b34801561098b57600080fd5b5061099b61ffff60043516611db2565b6040805160ff9092168252519081900360200190f35b3480156109bd57600080fd5b506109c9600435611dc0565b6040805161ffff938416815291909216602082015281519081900390910190f35b3480156109f657600080fd5b50604080516020600480358082013583810280860185019096528085526104ee95369593946024949385019291829185019084908082843750949750611ded9650505050505050565b348015610a4b57600080fd5b506109c9600435611e21565b348015610a6357600080fd5b50610a7361ffff60043516611e75565b6040805167ffffffffffffffff909316835290151560208301528051918290030190f35b348015610aa357600080fd5b50610421611ecc565b348015610ab857600080fd5b50610a7361ffff60043516611f03565b348015610ad457600080fd5b506104ee600160a060020a03600435166024351515611f30565b348015610afa57600080fd5b50610421611fb4565b348015610b0f57600080fd5b506106ae600435611feb565b348015610b2757600080fd5b5061036961ffff60043516611ff9565b6104ee600160a060020a0360043516602435612029565b348015610b5a57600080fd5b50604080516020600460248035828101358481028087018601909752808652610369968435600160a060020a0316963696604495919490910192918291850190849080828437509497506120849650505050505050565b348015610bbd57600080fd5b506104216120e8565b348015610bd257600080fd5b506104ae600435612176565b348015610bea57600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526104ee94600160a060020a03813581169560248035909216956044359536956084940191819084018382808284375094975061219e9650505050505050565b348015610c5957600080fd5b506104ee6121d6565b348015610c6e57600080fd5b5061099b61225e565b348015610c8357600080fd5b506104ee600160a060020a0360043516612267565b348015610ca457600080fd5b506104216004356122ad565b348015610cbc57600080fd5b506104ee60ff6004351661234f565b348015610cd757600080fd5b506106ae60ff6004351661ffff602435166123a0565b348015610cf957600080fd5b506106ae61ffff6004351660ff60243581169060443581169060643581169060843581169060a4351660c4351515612534565b348015610d3857600080fd5b506106ae61ffff6004351660ff60243581169060443581169060643581169060843581169060a43581169060c43581169060e435166101043515156125cc565b348015610d8457600080fd5b506106ae61266c565b348015610d9957600080fd5b506106ae60043561267b565b348015610db157600080fd5b506106ae61ffff6004351660ff60243581169060443581169060643581169060843581169060a43581169060c4351660e4351515612689565b348015610df657600080fd5b50604080516020600480358082013583810280860185019096528085526106ae95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506127269650505050505050565b34801561101357600080fd5b506105f26128b5565b34801561102857600080fd5b50610369600160a060020a03600435811690602435166128bb565b34801561104f57600080fd5b506106ae6004356128e9565b34801561106757600080fd5b506040805160206004602480358281013584810280870186019097528086526104ee968435600160a060020a0316963696604495919490910192918291850190849080828437509497506128f79650505050505050565b3480156110ca57600080fd5b506104ee60ff6004351661292c565b3480156110e557600080fd5b50610421612961565b3480156110fa57600080fd5b506105f2600160a060020a036004351661ffff60243581169060443516612998565b600160e060020a0319166000908152600c602052604090205460ff1690565b6000806000806000806000806000611151613df2565b61ffff8b16600090815260066020908152604091829020825161012081018452815460ff8082161515835261010082048116948301949094526201000081048416948201949094526301000000840483166060820152929091608084019164010000000090041660048111156111c357fe5b60048111156111ce57fe5b81526020016000820160059054906101000a900460ff1660ff1660ff1681526020016000820160069054906101000a900460ff1660ff1660ff1681526020016000820160079054906101000a900460ff1660ff1660ff1681526020016000820160089054906101000a900460ff1660ff1660ff16815250509050806000015181602001518260400151836060015184608001518560a001518660c001518760e00151886101000151995099509950995099509950995099509950509193959799909294969850565b60408051808201909152600e81527f476f647320556e636861696e656400000000000000000000000000000000000060208201525b90565b6000908152600e6020526040902054600160a060020a031690565b6113106001828154811015156112fb57fe5b60009182526020909120015461ffff16611ff9565b151561131b57600080fd5b6113258282612b50565b5050565b60005b815181101561135f576113578484848481518110151561134857fe5b9060200190602002015161143c565b60010161132c565b50505050565b600054600160a060020a031681565b60166020526000908152604090205460ff1681565b60005b8151811015611325576113b582828151811015156113a657fe5b90602001906020020151611660565b60010161138c565b60015490565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b600054600160a060020a031633146113fe57600080fd5b60ff80821660009081526003602052604090205416151561141e57600080fd5b60ff166000908152600460205260409020805460ff19166001179055565b61144e6001828154811015156112fb57fe5b151561145957600080fd5b611464838383612c06565b505050565b6000611473613df2565b600054600160a060020a0316331461148a57600080fd5b6040805161012081018252600180825260ff808a16602084015260055416928201929092526060810191909152608081018660048111156114c757fe5b815260ff861660208201526000604082018190526060820181905260809091015290506114f5878285612c99565b5095945050505050565b600061150a83611c6b565b821061151557600080fd5b600160a060020a038316600090815260116020526040902080548390811061153957fe5b90600052602060002090600691828204019190066005029054906101000a900464ffffffffff1664ffffffffff16905092915050565b600b80548290811061157d57fe5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b60006013546115b26113bd565b03905090565b600054600160a060020a031633146115cf57600080fd5b60005460a060020a900460ff1615156115e757600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a1565b80611639338261312c565b151561164457600080fd5b61135f848484602060405190810160405280600081525061219e565b803361166b82611c0c565b600160a060020a03161461167e57600080fd5b601380546001019055611325338361318b565b6000818152601660205260408120548190819060ff16156116b157600080fd5b6000848152601660209081526040808320805460ff1916600117905560155481517f6352211e000000000000000000000000000000000000000000000000000000008152600481018990529151600160a060020a0390911693636352211e93602480850194919392918390030190829087803b15801561173057600080fd5b505af1158015611744573d6000803e3d6000fd5b505050506040513d602081101561175a57600080fd5b5051601554604080517f9188d312000000000000000000000000000000000000000000000000000000008152600481018890528151939650600160a060020a0390921692639188d3129260248082019392918290030181600087803b1580156117c257600080fd5b505af11580156117d6573d6000803e3d6000fd5b505050506040513d60408110156117ec57600080fd5b50805160209091015190925090506118058383836131c9565b5050505050565b600780548290811061157d57fe5b6000908152600d6020526040902054600160a060020a0316151590565b60006118416113bd565b821061184c57600080fd5b5090565b611858613df2565b600054600160a060020a0316331461186f57600080fd5b61ffff8816600090815260066020908152604091829020825161012081018452815460ff8082161515835261010082048116948301949094526201000081048416948201949094526301000000840483166060820152929091608084019164010000000090041660048111156118e157fe5b60048111156118ec57fe5b8152905460ff650100000000008204811660208085019190915266010000000000008304821660408086019190915267010000000000000084048316606086015268010000000000000000909304821660809094019390935283820151811660009081526003909352912054919250161561196657600080fd5b610120604051908101604052806001151581526020018860ff168152602001826040015160ff1681526020018760ff168152602001826080015160048111156119ab57fe5b815260ff87811660208084019190915287821660408085019190915287831660608086019190915287841660809586015261ffff8e166000908152600684528290208651815494880151938801519288015160ff199095169015151761ff001916610100938616939093029290921762ff0000191662010000918516919091021763ff00000019166301000000929093169190910291909117808255918301519091829064ff000000001916640100000000836004811115611a6957fe5b021790555060a0820151815460c084015160e08501516101009095015165ff0000000000199092166501000000000060ff948516021766ff00000000000019166601000000000000918416919091021767ff000000000000001916670100000000000000948316949094029390931768ff000000000000000019166801000000000000000091909316029190911790555050505050505050565b60135481565b60046020526000908152604090205460ff1681565b60005460a060020a900460ff1681565b611b36613e3e565b600054600160a060020a03163314611b4d57600080fd5b5061ffff821660009081526002602090815260409182902082518084019093525467ffffffffffffffff8116835268010000000000000000900460ff1615801591830191909152611b9d57600080fd5b5060408051808201825267ffffffffffffffff92831681526001602080830191825261ffff90951660009081526002909552919093209251835491511515680100000000000000000268ff0000000000000000199190931667ffffffffffffffff199092169190911716179055565b6000818152600d6020526040812054600160a060020a0316801515611c3057600080fd5b92915050565b60005b815181101561146457611c63838383815181101515611c5457fe5b90602001906020020151612029565b600101611c39565b600160a060020a031660009081526011602052604090205490565b60036020526000908152604090205460ff1681565b600082600160a060020a0316611cb083611c0c565b600160a060020a0316149392505050565b600054600160a060020a03163314611cd857600080fd5b601480546001810182556000919091527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec01805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600054600160a060020a03163314611d4e57600080fd5b60005460a060020a900460ff1615611d6557600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a1565b6103e861ffff919091160490565b6001805482908110611dce57fe5b60009182526020909120015461ffff8082169250620100009091041682565b60005b815181101561132557611e198282815181101515611e0a57fe5b90602001906020020151611691565b600101611df0565b600080611e2c613e3e565b6001805485908110611e3a57fe5b60009182526020918290206040805180820190915291015461ffff808216808452620100009092041691909201819052909590945092505050565b600080611e80613e3e565b50505061ffff1660009081526002602090815260409182902082518084019093525467ffffffffffffffff81168084526801000000000000000090910460ff1615159290910182905291565b60408051808201909152600481527f474f445300000000000000000000000000000000000000000000000000000000602082015290565b60026020526000908152604090205467ffffffffffffffff81169068010000000000000000900460ff1682565b600160a060020a038216331415611f4657600080fd5b336000818152600f60209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b60408051808201909152600e81527f476f647320556e636861696e6564000000000000000000000000000000000000602082015281565b600a80548290811061157d57fe5b61ffff1660009081526006602090815260408083205462010000900460ff90811684526003909252909120541690565b803361203482611c0c565b600160a060020a03161461204757600080fd5b6120596001838154811015156112fb57fe5b151561206457600080fd5b600160a060020a038316151561207957600080fd5b6114643384846132ae565b6000806000835111151561209757600080fd5b5060005b82518110156120dc576120c58484838151811015156120b657fe5b90602001906020020151611c9b565b15156120d457600091506120e1565b60010161209b565b600191505b5092915050565b6010805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561216e5780601f106121435761010080835404028352916020019161216e565b820191906000526020600020905b81548152906001019060200180831161215157829003601f168201915b505050505081565b601480548290811061218457fe5b600091825260209091200154600160a060020a0316905081565b816121a9338261312c565b15156121b457600080fd5b6121bf85858561143c565b6121cb85858585613300565b151561180557600080fd5b600054600160a060020a031633146121ed57600080fd5b60055460ff908116111561220057600080fd5b6005805460ff8082166001011660ff199091161790556000612223600782613e55565b506000612231600882613e55565b50600061223f600982613e55565b50600061224d600a82613e55565b50600061225b600b82613e55565b50565b60055460ff1681565b600054600160a060020a0316331461227e57600080fd5b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6010805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152606093611c30939192909183018282801561233c5780601f106123115761010080835404028352916020019161233c565b820191906000526020600020905b81548152906001019060200180831161231f57829003601f168201915b505050505061234a8461346d565b613560565b600054600160a060020a0316331461236657600080fd5b60ff808216600090815260046020526040902054161561238557600080fd5b60ff166000908152600360205260409020805460ff19169055565b600080808080808760048111156123b357fe5b141561240357600b805461ffff88168115156123cb57fe5b068154811015156123d857fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff16945061252a565b600187600481111561241157fe5b141561242957600a805461ffff88168115156123cb57fe5b600287600481111561243757fe5b141561244f576009805461ffff88168115156123cb57fe5b600387600481111561245d57fe5b1415612475576008805461ffff88168115156123cb57fe5b600487600481111561248357fe5b1415610342575060005b600754811015612518576007805461ffff881683018115156124ab57fe5b068154811015156124b857fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff1693506124e784611e75565b9093509150818015612503575060008367ffffffffffffffff16115b156125105783945061252a565b60010161248d565b6008805461ffff88168115156123cb57fe5b5050505092915050565b600061253e613df2565b600054600160a060020a0316331461255557600080fd5b60408051610120810182526001815260ff808b1660208301526005541691810191909152600360608201526080810188600481111561259057fe5b815260ff8089166020830152878116604083015286166060820152600060809091015290506125c0898285612c99565b50979650505050505050565b60006125d6613df2565b600054600160a060020a031633146125ed57600080fd5b60408051610120810182526001815260ff808d1660208301526005548116928201929092529086166060820152608081018a600481111561262a57fe5b81526020018960ff1681526020018860ff1681526020018760ff1681526020018560ff16815250905061265e8b8285612c99565b509998505050505050505050565b600554610100900461ffff1681565b600980548290811061157d57fe5b6000612693613df2565b600054600160a060020a031633146126aa57600080fd5b60408051610120810182526001815260ff808c166020830152600554169181019190915260026060820152608081018960048111156126e557fe5b81526020018860ff1681526020018760ff1681526020018660ff1681526020018560ff1681525090506127198a8285612c99565b5098975050505050505050565b600080612731613df2565b600054600160a060020a0316331461274857600080fd5b600091505b8b518210156128a657610120604051908101604052806001151581526020018c8481518110151561277a57fe5b602090810290910181015160ff9081168352600554169082015287516040909101908890859081106127a857fe5b9060200190602002015160ff1681526020018b848151811015156127c857fe5b9060200190602002015160048111156127dd57fe5b81526020018a848151811015156127f057fe5b9060200190602002015160ff168152602001898481518110151561281057fe5b9060200190602002015160ff168152602001888481518110151561283057fe5b9060200190602002015160ff168152602001868481518110151561285057fe5b9060200190602002015160ff16815250905061289b8c8381518110151561287357fe5b9060200190602002015182868581518110151561288c57fe5b90602001906020020151612c99565b60019091019061274d565b50509998505050505050505050565b60135490565b600160a060020a039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b600880548290811061157d57fe5b60005b81518110156114645761292483838381518110151561291557fe5b906020019060200201516112e9565b6001016128fa565b600054600160a060020a0316331461294357600080fd5b60ff166000908152600360205260409020805460ff19166001179055565b60408051808201909152600481527f474f445300000000000000000000000000000000000000000000000000000000602082015281565b60006129a2613df2565b60008054819060a060020a900460ff16156129bc57600080fd5b6129c461359c565b15156129cf57600080fd5b61ffff8616600090815260066020908152604091829020825161012081018452815460ff808216151583526101008204811694830194909452620100008104841694820194909452630100000084048316606082015292909160808401916401000000009004166004811115612a4157fe5b6004811115612a4c57fe5b8152905460ff6501000000000082048116602084015266010000000000008204811660408085019190915267010000000000000083048216606085015268010000000000000000909204811660809093019290925260055490830151929550918116911614612aba57600080fd5b600483608001516004811115612acc57fe5b1415612b3a57612adb86611e75565b9092509050801580612af7575060008267ffffffffffffffff16115b1515612b0257600080fd5b61ffff86166000908152600260205260409020805467ffffffffffffffff19811667ffffffffffffffff918216600019019091161790555b612b458787876131c9565b979650505050505050565b6000612b5b82611c0c565b9050600160a060020a038381169082161415612b7657600080fd5b33600160a060020a0382161480612b925750612b9281336128bb565b1515612b9d57600080fd5b6000828152600e6020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b80612c11338261312c565b1515612c1c57600080fd5b600160a060020a0384161515612c3157600080fd5b600160a060020a0383161515612c4657600080fd5b612c5084836135ed565b612c5a848361365c565b612c6483836138bd565b8183600160a060020a031685600160a060020a0316600080516020613ed483398151915260405160405180910390a450505050565b61ffff831660009081526006602052604081205460ff1615612cba57600080fd5b6001835261ffff8416600090815260066020908152604091829020855181549287015193870151606088015160ff199094169115159190911761ff00191661010060ff958616021762ff0000191662010000918516919091021763ff000000191663010000009390921692909202178082556080850151859291829064ff000000001916640100000000836004811115612d5057fe5b021790555060a08201518160000160056101000a81548160ff021916908360ff16021790555060c08201518160000160066101000a81548160ff021916908360ff16021790555060e08201518160000160076101000a81548160ff021916908360ff1602179055506101008201518160000160086101000a81548160ff021916908360ff1602179055509050506005600181819054906101000a900461ffff168092919060010191906101000a81548161ffff021916908361ffff160217905550507f2f7e8f79713fd202353aaa4d413bb73a3bc66d59a540f646415fd9acee7e59c684600560009054906101000a900460ff16856020015186608001518760a001518860c001518960e001518a606001518b61010001518b604051808b61ffff1661ffff1681526020018a60ff1660ff1681526020018960ff1660ff168152602001886004811115612e9f57fe5b60ff90811682529788166020820152958716604080880191909152948716606087015250918516608085015290931660a083015291151560c082015290519081900360e001945092505050a1811561135f575060808201516000816004811115612f0557fe5b1415612f6857600b80546001810182556000919091527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db960108204018054600f9092166002026101000a61ffff818102199093169287160291909117905561135f565b6001816004811115612f7657fe5b1415612fd957600a80546001810182556000919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a860108204018054600f9092166002026101000a61ffff818102199093169287160291909117905561135f565b6002816004811115612fe757fe5b141561304a57600980546001810182556000919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af60108204018054600f9092166002026101000a61ffff818102199093169287160291909117905561135f565b600381600481111561305857fe5b14156130bb57600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee360108204018054600f9092166002026101000a61ffff818102199093169287160291909117905561135f565b60048160048111156130c957fe5b141561034257600780546001810182556000919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860108204018054600f9092166002026101000a61ffff818102199093169287160291909117905561135f565b60008061313883611c0c565b905080600160a060020a031684600160a060020a03161480613173575083600160a060020a0316613168846112ce565b600160a060020a0316145b80613183575061318381856128bb565b949350505050565b61319582826135ed565b61319f828261365c565b6040518190600090600160a060020a03851690600080516020613ed4833981519152908390a45050565b60006131d3613e3e565b506040805180820190915261ffff80851682528381166020830190815260018054808201825560009190915283517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf68201805493518516620100000263ffff0000199290951661ffff199094169390931716929092179055613255868261398e565b6040805161ffff808816825286166020820152600160a060020a03881681830152905182917fe8a3345b7ca502cc541c08a705987fa4c03d9f59c0427175387a64cbd8f46594919081900360600190a295945050505050565b6132b883826135ed565b6132c2838261365c565b6132cc82826138bd565b8082600160a060020a031684600160a060020a0316600080516020613ed483398151915260405160405180910390a4505050565b60008061331585600160a060020a03166139d7565b15156133245760019150613464565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b838110156133b757818101518382015260200161339f565b50505050905090810190601f1680156133e45780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561340657600080fd5b505af115801561341a573d6000803e3d6000fd5b505050506040513d602081101561343057600080fd5b5051600160e060020a031981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b606060008082818515156134b65760408051808201909152600181527f300000000000000000000000000000000000000000000000000000000000000060208201529450613557565b8593505b83156134d157600190920191600a840493506134ba565b826040519080825280601f01601f1916602001820160405280156134ff578160200160208202803883390190505b5091505060001982015b851561355357815160001982019160f860020a6030600a8a06010291849190811061353057fe5b906020010190600160f860020a031916908160001a905350600a86049550613509565b8194505b50505050919050565b6040805160208181018352600080835283518083018552818152845192830190945281526060926135959286928692906139df565b9392505050565b6000805b6014548110156135e55760148054829081106135b857fe5b600091825260209091200154600160a060020a03163314156135dd576001915061184c565b6001016135a0565b600091505090565b81600160a060020a031661360082611c0c565b600160a060020a03161461361357600080fd5b6000818152600e6020526040902054600160a060020a031615611325576000908152600e60205260409020805473ffffffffffffffffffffffffffffffffffffffff1916905550565b600080600061366b8585613c40565b601280548590811061367957fe5b60009182526020808320600883040154600160a060020a0389168452601190915260409092205460079091166004026101000a90910463ffffffff90811694506136c79190600190613c9216565b600160a060020a0386166000908152601160205260409020805491935090839081106136ef57fe5b90600052602060002090600691828204019190066005029054906101000a900464ffffffffff169050806011600087600160a060020a0316600160a060020a031681526020019081526020016000208463ffffffff1681548110151561375157fe5b90600052602060002090600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff16021790555060006011600087600160a060020a0316600160a060020a03168152602001908152602001600020838154811015156137ba57fe5b90600052602060002090600691828204019190066005026101000a81548164ffffffffff021916908364ffffffffff1602179055506011600086600160a060020a0316600160a060020a031681526020019081526020016000208054809190600190036138279190613e89565b50600060128581548110151561383957fe5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508260128264ffffffffff1681548110151561388357fe5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055505050505050565b60006138c98383613ca4565b50600160a060020a03821660009081526011602052604090205463ffffffff811681146138f557600080fd5b600160a060020a038316600090815260116020908152604082208054600181018255908352912060068083049091018054919092066005026101000a64ffffffffff8181021990921691851602179055601280548291908490811061395657fe5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908363ffffffff160217905550505050565b600160a060020a03821615156139a357600080fd5b6139ad8282613d01565b6040518190600160a060020a03841690600090600080516020613ed4833981519152908290a45050565b6000903b1190565b6060806060806060806060806000808e98508d97508c96508b95508a94508451865188518a518c51010101016040519080825280601f01601f191660200182016040528015613a38578160200160208202803883390190505b50935083925060009150600090505b8851811015613aa5578881815181101515613a5e57fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613a8557fe5b906020010190600160f860020a031916908160001a905350600101613a47565b5060005b8751811015613b07578781815181101515613ac057fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613ae757fe5b906020010190600160f860020a031916908160001a905350600101613aa9565b5060005b8651811015613b69578681815181101515613b2257fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613b4957fe5b906020010190600160f860020a031916908160001a905350600101613b0b565b5060005b8551811015613bcb578581815181101515613b8457fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613bab57fe5b906020010190600160f860020a031916908160001a905350600101613b6d565b5060005b8451811015613c2d578481815181101515613be657fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613c0d57fe5b906020010190600160f860020a031916908160001a905350600101613bcf565b50909d9c50505050505050505050505050565b81600160a060020a0316613c5382611c0c565b600160a060020a031614613c6657600080fd5b6000908152600d60205260409020805473ffffffffffffffffffffffffffffffffffffffff1916905550565b600082821115613c9e57fe5b50900390565b6000818152600d6020526040902054600160a060020a031615613cc657600080fd5b6000908152600d60205260409020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6000613d0d8383613ca4565b50600160a060020a03821660009081526011602052604090205463ffffffff81168114613d3957600080fd5b600160a060020a039290921660009081526011602090815260408220805460018082018355918452918320600680840490910180549190930660050261010090810a64ffffffffff818102199093169690921691909102949094179091556012805491820181559091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344460088204018054600790921660040290920a63ffffffff818102199092169190931692909202919091179055565b6040805161012081018252600080825260208201819052918101829052606081018290529060808201908152600060208201819052604082018190526060820181905260809091015290565b604080518082019091526000808252602082015290565b81548183558181111561146457600f016010900481600f016010900483600052602060002091820191016114649190613eb9565b81548183558181111561146457600501600690048160050160069004836000526020600020918201910161146491905b6112cb91905b8082111561184c5760008155600101613ebf5600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a7230582010fa10dfd0372688e0f7a010b360af415423fe495c99c201f4e1bfab3b1c44210029000000000000000000000000512fbd15bde6570ff09e4438af27ede604024515"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"id\",\"type\":\"uint16\"}],\"name\":\"getProto\",\"outputs\":[{\"name\":\"exists\",\"type\":\"bool\"},{\"name\":\"god\",\"type\":\"uint8\"},{\"name\":\"season\",\"type\":\"uint8\"},{\"name\":\"cardType\",\"type\":\"uint8\"},{\"name\":\"rarity\",\"type\":\"uint8\"},{\"name\":\"mana\",\"type\":\"uint8\"},{\"name\":\"attack\",\"type\":\"uint8\"},{\"name\":\"health\",\"type\":\"uint8\"},{\"name\":\"tribe\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"transferAllFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"migrated\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"burnAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"InterfaceId_ERC165\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes4\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"season\",\"type\":\"uint8\"}],\"name\":\"makePermanantlyTradable\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"address\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"externalID\",\"type\":\"uint16\"},{\"name\":\"god\",\"type\":\"uint8\"},{\"name\":\"rarity\",\"type\":\"uint8\"},{\"name\":\"mana\",\"type\":\"uint8\"},{\"name\":\"packable\",\"type\":\"bool\"}],\"name\":\"addSpell\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"},{\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"tokenOfOwnerByIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"common\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getActiveCards\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"migrate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"mythic\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"exists\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"tokenByIndex\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"index\",\"type\":\"uint16\"},{\"name\":\"god\",\"type\":\"uint8\"},{\"name\":\"cardType\",\"type\":\"uint8\"},{\"name\":\"mana\",\"type\":\"uint8\"},{\"name\":\"attack\",\"type\":\"uint8\"},{\"name\":\"health\",\"type\":\"uint8\"},{\"name\":\"tribe\",\"type\":\"uint8\"}],\"name\":\"replaceProto\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"burnCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"name\":\"seasonTradabilityLocked\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint16\"},{\"name\":\"limit\",\"type\":\"uint64\"}],\"name\":\"setLimit\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"transferAll\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"name\":\"seasonTradable\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"proposed\",\"type\":\"address\"},{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"owns\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"approved\",\"type\":\"address\"}],\"name\":\"addPack\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"purity\",\"type\":\"uint16\"}],\"name\":\"getShine\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"cards\",\"outputs\":[{\"name\":\"proto\",\"type\":\"uint16\"},{\"name\":\"purity\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"migrateAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getCard\",\"outputs\":[{\"name\":\"proto\",\"type\":\"uint16\"},{\"name\":\"purity\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"id\",\"type\":\"uint16\"}],\"name\":\"getLimit\",\"outputs\":[{\"name\":\"limit\",\"type\":\"uint64\"},{\"name\":\"set\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"name\":\"limits\",\"outputs\":[{\"name\":\"limit\",\"type\":\"uint64\"},{\"name\":\"exists\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"rare\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"proto\",\"type\":\"uint16\"}],\"name\":\"isTradable\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"proposed\",\"type\":\"address\"},{\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"ownsAll\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"tokenMetadataBaseURI\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"packs\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"nextSeason\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"currentSeason\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_gov\",\"type\":\"address\"}],\"name\":\"setGovernor\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"season\",\"type\":\"uint8\"}],\"name\":\"makeUntradable\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"rarity\",\"type\":\"uint8\"},{\"name\":\"random\",\"type\":\"uint16\"}],\"name\":\"getRandomCard\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"externalID\",\"type\":\"uint16\"},{\"name\":\"god\",\"type\":\"uint8\"},{\"name\":\"rarity\",\"type\":\"uint8\"},{\"name\":\"mana\",\"type\":\"uint8\"},{\"name\":\"attack\",\"type\":\"uint8\"},{\"name\":\"durability\",\"type\":\"uint8\"},{\"name\":\"packable\",\"type\":\"bool\"}],\"name\":\"addWeapon\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"externalID\",\"type\":\"uint16\"},{\"name\":\"god\",\"type\":\"uint8\"},{\"name\":\"rarity\",\"type\":\"uint8\"},{\"name\":\"mana\",\"type\":\"uint8\"},{\"name\":\"attack\",\"type\":\"uint8\"},{\"name\":\"health\",\"type\":\"uint8\"},{\"name\":\"cardType\",\"type\":\"uint8\"},{\"name\":\"tribe\",\"type\":\"uint8\"},{\"name\":\"packable\",\"type\":\"bool\"}],\"name\":\"addProto\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protoCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"epic\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"externalID\",\"type\":\"uint16\"},{\"name\":\"god\",\"type\":\"uint8\"},{\"name\":\"rarity\",\"type\":\"uint8\"},{\"name\":\"mana\",\"type\":\"uint8\"},{\"name\":\"attack\",\"type\":\"uint8\"},{\"name\":\"health\",\"type\":\"uint8\"},{\"name\":\"tribe\",\"type\":\"uint8\"},{\"name\":\"packable\",\"type\":\"bool\"}],\"name\":\"addMinion\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"externalIDs\",\"type\":\"uint16[]\"},{\"name\":\"gods\",\"type\":\"uint8[]\"},{\"name\":\"rarities\",\"type\":\"uint8[]\"},{\"name\":\"manas\",\"type\":\"uint8[]\"},{\"name\":\"attacks\",\"type\":\"uint8[]\"},{\"name\":\"healths\",\"type\":\"uint8[]\"},{\"name\":\"cardTypes\",\"type\":\"uint8[]\"},{\"name\":\"tribes\",\"type\":\"uint8[]\"},{\"name\":\"packable\",\"type\":\"bool[]\"}],\"name\":\"addProtos\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getBurnCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"},{\"name\":\"_operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"legendary\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"approveAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"season\",\"type\":\"uint8\"}],\"name\":\"makeTradable\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"SYMBOL\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"proto\",\"type\":\"uint16\"},{\"name\":\"purity\",\"type\":\"uint16\"}],\"name\":\"createCard\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"previous\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"proto\",\"type\":\"uint16\"},{\"indexed\":false,\"name\":\"purity\",\"type\":\"uint16\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"CardCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_approved\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_operator\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"id\",\"type\":\"uint16\"},{\"indexed\":false,\"name\":\"season\",\"type\":\"uint8\"},{\"indexed\":false,\"name\":\"god\",\"type\":\"uint8\"},{\"indexed\":false,\"name\":\"rarity\",\"type\":\"uint8\"},{\"indexed\":false,\"name\":\"mana\",\"type\":\"uint8\"},{\"indexed\":false,\"name\":\"attack\",\"type\":\"uint8\"},{\"indexed\":false,\"name\":\"health\",\"type\":\"uint8\"},{\"indexed\":false,\"name\":\"cardType\",\"type\":\"uint8\"},{\"indexed\":false,\"name\":\"tribe\",\"type\":\"uint8\"},{\"indexed\":false,\"name\":\"packable\",\"type\":\"bool\"}],\"name\":\"NewProtoCard\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Pause\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Unpause\",\"type\":\"event\"}]"; + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract007Key,contract007Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + accountResource = PublicMethed.getAccountResource(contract007Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage > 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + account = PublicMethed.queryAccount(contract007Key,blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario008.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario008.java new file mode 100644 index 00000000000..e22d602f577 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario008.java @@ -0,0 +1,123 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario008 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract008Address = ecKey1.getAddress(); + String contract008Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract008Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract008Address,5000000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract008Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract008Address, 1000000L, + 3,1,contract008Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract008Address,contract008Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployErc721CryptoKitties() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract008Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(contract008Key,blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 900L; + //maxFeeLimit = 3900000000L; + String contractName = "Cat"; + String code = "606060409081526002805460a060020a60ff02191690556101c090519081016040908152603c82526078602083015261012c9082015261025860608201526107086080820152610e1060a0820152611c2060c082015261384060e082015261708061010082015261e100610120820152620151806101408201526202a3006101608201526205460061018082015262093a806101a0820152620000a790600390600e620004e4565b50600f60055566071afd498d0000600e553415620000c457600080fd5b6002805460008054600160a060020a033316600160a060020a03199182168117835560a060020a60ff02199093167401000000000000000000000000000000000000000017169091179091556200012f90808060001981640100000000620028f06200013682021704565b5062000649565b6000806200014362000587565b600063ffffffff891689146200015857600080fd5b63ffffffff881688146200016b57600080fd5b61ffff871687146200017c57600080fd5b600287049250600d8361ffff1611156200019557600d92505b61010060405190810160409081528782526001604060020a0342166020830152600090820181905263ffffffff808c1660608401528a16608083015260a082015261ffff80851660c0830152881660e082015260068054919350600191808301620002018382620005cb565b6000928352602090922085916002020181518155602082015160018201805467ffffffffffffffff19166001604060020a039290921691909117905560408201518160010160086101000a8154816001604060020a0302191690836001604060020a0316021790555060608201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060c082015181600101601c6101000a81548161ffff021916908361ffff16021790555060e08201516001909101805461ffff929092167e0100000000000000000000000000000000000000000000000000000000000002600160f060020a039092169190911790555003905063ffffffff811681146200035e57600080fd5b7f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad58582846060015163ffffffff16856080015163ffffffff168651604051600160a060020a03909516855260208501939093526040808501929092526060840152608083019190915260a0909101905180910390a1620003ef60008683640100000000620025e0620003fb82021704565b98975050505050505050565b600160a060020a03808316600081815260086020908152604080832080546001019055858352600790915290208054600160a060020a03191690911790558316156200048f57600160a060020a03831660009081526008602090815260408083208054600019019055838352600a82528083208054600160a060020a03199081169091556009909252909120805490911690555b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef838383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a1505050565b600283019183908215620005755791602002820160005b838211156200054157835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302620004fb565b8015620005735782816101000a81549063ffffffff021916905560040160208160030104928301926001030262000541565b505b5062000583929150620005ff565b5090565b6101006040519081016040908152600080835260208301819052908201819052606082018190526080820181905260a0820181905260c0820181905260e082015290565b815481835581811511620005fa57600202816002028360005260206000209182019101620005fa919062000626565b505050565b6200062391905b808211156200058357805463ffffffff1916815560010162000606565b90565b6200062391905b808211156200058357600080825560018201556002016200062d565b61309380620006596000396000f3006060604052600436106102a55763ffffffff60e060020a60003504166301ffc9a781146102dd5780630519ce79146103295780630560ff441461035857806305e45546146103f157806306fdde0314610416578063095ea7b3146104295780630a0f81681461044b5780630e583df01461045e57806314001f4c1461047157806318160ddd14610490578063183a7947146104a35780631940a936146104b657806319c2f201146104cc57806321717ebf146104df57806323b872dd146104f257806324e7a38a1461051a57806327d7874c146105395780632ba73c15146105585780633d7d3f5a146105775780633f4ba83a1461059657806346116e6f146105a957806346d22c70146105bf578063481af3d3146105d85780634ad8c938146105ee5780634b85fd551461060d5780634dfff04f146106235780634e0a33791461064557806356129134146106645780635663896e146106865780635c975abb1461069c5780635fd8c710146106af5780636352211e146106c2578063680eba27146106d85780636af04a57146106eb5780636fbde40d146106fe57806370a082311461071d578063715879881461073c5780637a7d49371461075b5780638456cb591461076e5780638462151c1461078157806388c2a0bf146107f357806391876e571461080957806395d89b411461081c5780639d6fac6f1461082f578063a45f4bfc1461085e578063a9059cbb14610874578063b047fb5014610896578063b0c35c05146108a9578063bc4006f5146108bc578063c3bea9af146108cf578063d3e6f49f146108e5578063defb9584146108fb578063e17b25af1461090e578063e6cbe3511461092d578063e98b7f4d14610940578063ed60ade6146109ae578063f1ca9410146109bc578063f2b47d52146109cf578063f7d8c883146109e2575b600b5433600160a060020a03908116911614806102d05750600c5433600160a060020a039081169116145b15156102db57600080fd5b005b34156102e857600080fd5b6103157fffffffff00000000000000000000000000000000000000000000000000000000600435166109f0565b604051901515815260200160405180910390f35b341561033457600080fd5b61033c610c77565b604051600160a060020a03909116815260200160405180910390f35b341561036357600080fd5b61037a600480359060248035908101910135610c86565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156103b657808201518382015260200161039e565b50505050905090810190601f1680156103e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103fc57600080fd5b610404610d63565b60405190815260200160405180910390f35b341561042157600080fd5b61037a610d69565b341561043457600080fd5b6102db600160a060020a0360043516602435610da0565b341561045657600080fd5b61033c610e2a565b341561046957600080fd5b610404610e39565b341561047c57600080fd5b6102db600160a060020a0360043516610e44565b341561049b57600080fd5b610404610ef1565b34156104ae57600080fd5b610404610efc565b34156104c157600080fd5b610315600435610f02565b34156104d757600080fd5b610404610f47565b34156104ea57600080fd5b61033c610f4e565b34156104fd57600080fd5b6102db600160a060020a0360043581169060243516604435610f5d565b341561052557600080fd5b6102db600160a060020a0360043516610fe4565b341561054457600080fd5b6102db600160a060020a0360043516611091565b341561056357600080fd5b6102db600160a060020a03600435166110e3565b341561058257600080fd5b6102db600435602435604435606435611135565b34156105a157600080fd5b6102db611214565b34156105b457600080fd5b61033c6004356112ac565b34156105ca57600080fd5b6103156004356024356112c7565b34156105e357600080fd5b61033c600435611347565b34156105f957600080fd5b6102db600435602435604435606435611362565b341561061857600080fd5b6102db600435611428565b341561062e57600080fd5b6102db600160a060020a0360043516602435611448565b341561065057600080fd5b6102db600160a060020a03600435166114a2565b341561066f57600080fd5b6102db600435600160a060020a03602435166114f4565b341561069157600080fd5b6102db600435611560565b34156106a757600080fd5b6103156115c8565b34156106ba57600080fd5b6102db6115d8565b34156106cd57600080fd5b61033c600435611649565b34156106e357600080fd5b61040461166d565b34156106f657600080fd5b61033c611673565b341561070957600080fd5b6102db600160a060020a0360043516611682565b341561072857600080fd5b610404600160a060020a036004351661172f565b341561074757600080fd5b6102db600160a060020a036004351661174a565b341561076657600080fd5b6104046117d8565b341561077957600080fd5b6102db6117de565b341561078c57600080fd5b6107a0600160a060020a036004351661186a565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156107df5780820151838201526020016107c7565b505050509050019250505060405180910390f35b34156107fe57600080fd5b61040460043561194b565b341561081457600080fd5b6102db611c1b565b341561082757600080fd5b61037a611d0e565b341561083a57600080fd5b610845600435611d45565b60405163ffffffff909116815260200160405180910390f35b341561086957600080fd5b61033c600435611d72565b341561087f57600080fd5b6102db600160a060020a0360043516602435611d8d565b34156108a157600080fd5b61033c611e30565b34156108b457600080fd5b610404611e3f565b34156108c757600080fd5b61033c611e45565b34156108da57600080fd5b6102db600435611e54565b34156108f057600080fd5b610315600435611f47565b341561090657600080fd5b610404612010565b341561091957600080fd5b6102db600160a060020a0360043516612016565b341561093857600080fd5b61033c612053565b341561094b57600080fd5b610956600435612062565b6040519915158a5297151560208a01526040808a01979097526060890195909552608088019390935260a087019190915260c086015260e0850152610100840152610120830191909152610140909101905180910390f35b6102db6004356024356121c3565b34156109c757600080fd5b610404612316565b34156109da57600080fd5b61033c61231c565b6102db60043560243561232b565b60006040517f737570706f727473496e7465726661636528627974657334290000000000000081526019016040518091039020600160e060020a03191682600160e060020a0319161480610c6f57506040517f746f6b656e4d657461646174612875696e743235362c737472696e67290000008152601d0160405180910390206040517f746f6b656e734f664f776e657228616464726573732900000000000000000000815260160160405180910390206040517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f7432353629000000000000000000000000000000000000000000000000000000602082015260250160405180910390206040517f7472616e7366657228616464726573732c75696e743235362900000000000000815260190160405180910390206040517f617070726f766528616464726573732c75696e74323536290000000000000000815260180160405180910390206040517f6f776e65724f662875696e743235362900000000000000000000000000000000815260100160405180910390206040517f62616c616e63654f662861646472657373290000000000000000000000000000815260120160405180910390206040517f746f74616c537570706c792829000000000000000000000000000000000000008152600d0160405180910390206040517f73796d626f6c2829000000000000000000000000000000000000000000000000815260080160405180910390206040517f6e616d652829000000000000000000000000000000000000000000000000000081526006016040518091039020181818181818181818600160e060020a03191682600160e060020a031916145b90505b919050565b600154600160a060020a031681565b610c8e612fa0565b610c96612fb2565b600d54600090600160a060020a03161515610cb057600080fd5b600d54600160a060020a031663cb4799f2878787600060405160a0015260405160e060020a63ffffffff861602815260048101848152604060248301908152604483018490529091606401848480828437820191505094505050505060a060405180830381600087803b1515610d2557600080fd5b6102c65a03f11515610d3657600080fd5b50505060405180608001805160209091016040529092509050610d59828261251d565b9695505050505050565b60115481565b60408051908101604052600d81527f43727970746f4b69747469657300000000000000000000000000000000000000602082015281565b60025460a060020a900460ff1615610db757600080fd5b610dc13382612572565b1515610dcc57600080fd5b610dd68183612592565b7f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925338383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15050565b600054600160a060020a031681565b662386f26fc1000081565b6000805433600160a060020a03908116911614610e6057600080fd5b5080600160a060020a0381166376190f8f6000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515610ea857600080fd5b6102c65a03f11515610eb957600080fd5b505050604051805190501515610ece57600080fd5b600c8054600160a060020a031916600160a060020a039290921691909117905550565b600654600019015b90565b600f5481565b6000808211610f1057600080fd5b6006805483908110610f1e57fe5b600091825260209091206002909102016001015460c060020a900463ffffffff16151592915050565b6201518081565b600c54600160a060020a031681565b60025460a060020a900460ff1615610f7457600080fd5b600160a060020a0382161515610f8957600080fd5b30600160a060020a031682600160a060020a031614151515610faa57600080fd5b610fb433826125c0565b1515610fbf57600080fd5b610fc98382612572565b1515610fd457600080fd5b610fdf8383836125e0565b505050565b6000805433600160a060020a0390811691161461100057600080fd5b5080600160a060020a0381166354c15b826000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561104857600080fd5b6102c65a03f1151561105957600080fd5b50505060405180519050151561106e57600080fd5b60108054600160a060020a031916600160a060020a039290921691909117905550565b60005433600160a060020a039081169116146110ac57600080fd5b600160a060020a03811615156110c157600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b60005433600160a060020a039081169116146110fe57600080fd5b600160a060020a038116151561111357600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b60025460a060020a900460ff161561114c57600080fd5b6111563385612572565b151561116157600080fd5b61116a84610f02565b1561117457600080fd5b600b5461118b908590600160a060020a0316612592565b600b54600160a060020a03166327ebe40a858585853360405160e060020a63ffffffff88160281526004810195909552602485019390935260448401919091526064830152600160a060020a0316608482015260a401600060405180830381600087803b15156111fa57600080fd5b6102c65a03f1151561120b57600080fd5b50505050505050565b60005433600160a060020a0390811691161461122f57600080fd5b60025460a060020a900460ff16151561124757600080fd5b600b54600160a060020a0316151561125e57600080fd5b600c54600160a060020a0316151561127557600080fd5b601054600160a060020a0316151561128c57600080fd5b601354600160a060020a0316156112a257600080fd5b6112aa6126c8565b565b600a60205260009081526040902054600160a060020a031681565b600080808085116112d757600080fd5b600084116112e457600080fd5b60068054869081106112f257fe5b9060005260206000209060020201915060068481548110151561131157fe5b9060005260206000209060020201905061132d8286838761271b565b801561133e575061133e848661289b565b95945050505050565b600960205260009081526040902054600160a060020a031681565b60025460a060020a900460ff161561137957600080fd5b6113833385612572565b151561138e57600080fd5b61139784611f47565b15156113a257600080fd5b600c546113b9908590600160a060020a0316612592565b600c54600160a060020a03166327ebe40a858585853360405160e060020a63ffffffff88160281526004810195909552602485019390935260448401919091526064830152600160a060020a0316608482015260a401600060405180830381600087803b15156111fa57600080fd5b60025433600160a060020a0390811691161461144357600080fd5b600e55565b60025460a060020a900460ff161561145f57600080fd5b6114693382612572565b151561147457600080fd5b6000908152600a602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b60005433600160a060020a039081169116146114bd57600080fd5b600160a060020a03811615156114d257600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b60025460009033600160a060020a0390811691161461151257600080fd5b5080600160a060020a03811615156115325750600254600160a060020a03165b601154611388901061154357600080fd5b60118054600101905561155a6000808086856128f0565b50505050565b60025433600160a060020a039081169116148061158b575060005433600160a060020a039081169116145b806115a4575060015433600160a060020a039081169116145b15156115af57600080fd5b60035463ffffffff1681106115c357600080fd5b600555565b60025460a060020a900460ff1681565b600154600090819033600160a060020a039081169116146115f857600080fd5b30600160a060020a0316319150600e54600f546001010290508082111561164557600154600160a060020a031681830380156108fc0290604051600060405180830381858888f150505050505b5050565b600081815260076020526040902054600160a060020a0316801515610c7257600080fd5b61afc881565b601354600160a060020a031681565b6000805433600160a060020a0390811691161461169e57600080fd5b5080600160a060020a0381166385b861886000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156116e657600080fd5b6102c65a03f115156116f757600080fd5b50505060405180519050151561170c57600080fd5b600b8054600160a060020a031916600160a060020a039290921691909117905550565b600160a060020a031660009081526008602052604090205490565b60005433600160a060020a0390811691161461176557600080fd5b60025460a060020a900460ff16151561177d57600080fd5b60138054600160a060020a031916600160a060020a0383161790557f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa44619930581604051600160a060020a03909116815260200160405180910390a150565b60055481565b60025433600160a060020a0390811691161480611809575060005433600160a060020a039081169116145b80611822575060015433600160a060020a039081169116145b151561182d57600080fd5b60025460a060020a900460ff161561184457600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055565b611872612fa0565b600061187c612fa0565b600080600061188a8761172f565b94508415156118ba5760006040518059106118a25750595b90808252806020026020018201604052509550611941565b846040518059106118c85750595b908082528060200260200182016040525093506118e3610ef1565b925060009150600190505b82811161193d57600081815260076020526040902054600160a060020a0388811691161415611935578084838151811061192457fe5b602090810290910101526001909101905b6001016118ee565b8395505b5050505050919050565b600080600080600080600080600260149054906101000a900460ff1615151561197357600080fd5b600680548a90811061198157fe5b60009182526020909120600290910201600181015490975067ffffffffffffffff1615156119ae57600080fd5b611a438761010060405190810160409081528254825260019092015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152612b9c565b1515611a4e57600080fd5b60018701546006805460c060020a90920463ffffffff1697509087908110611a7257fe5b600091825260209091206001808a015460029093029091019081015490965061ffff60f060020a92839004811696509190041684901115611ac057600185015460f060020a900461ffff1693505b6010548754865460018a0154600160a060020a0390931692630d9f5aed92919068010000000000000000900467ffffffffffffffff166000190160006040516020015260405160e060020a63ffffffff86160281526004810193909352602483019190915267ffffffffffffffff166044820152606401602060405180830381600087803b1515611b5057600080fd5b6102c65a03f11515611b6157600080fd5b505050604051805160008b81526007602052604090205460018a810154929650600160a060020a039091169450611bb092508b9160c060020a900463ffffffff1690870161ffff1686866128f0565b6001880180547bffffffff00000000000000000000000000000000000000000000000019169055600f8054600019019055600e54909150600160a060020a0333169080156108fc0290604051600060405180830381858888f150939c9b505050505050505050505050565b60025433600160a060020a0390811691161480611c46575060005433600160a060020a039081169116145b80611c5f575060015433600160a060020a039081169116145b1515611c6a57600080fd5b600b54600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b1515611ca957600080fd5b6102c65a03f11515611cba57600080fd5b5050600c54600160a060020a03169050635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b1515611cfd57600080fd5b6102c65a03f11515610fdf57600080fd5b60408051908101604052600281527f434b000000000000000000000000000000000000000000000000000000000000602082015281565b600381600e8110611d5257fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b600760205260009081526040902054600160a060020a031681565b60025460a060020a900460ff1615611da457600080fd5b600160a060020a0382161515611db957600080fd5b30600160a060020a031682600160a060020a031614151515611dda57600080fd5b600b54600160a060020a0383811691161415611df557600080fd5b600c54600160a060020a0383811691161415611e1057600080fd5b611e1a3382612572565b1515611e2557600080fd5b6116453383836125e0565b600254600160a060020a031681565b600e5481565b600d54600160a060020a031681565b60025460009033600160a060020a03908116911614611e7257600080fd5b60125461afc89010611e8357600080fd5b611e92600080600085306128f0565b600b54909150611eac908290600160a060020a0316612592565b600b54600160a060020a03166327ebe40a82611ec6612bd4565b6000620151803060405160e060020a63ffffffff88160281526004810195909552602485019390935260448401919091526064830152600160a060020a0316608482015260a401600060405180830381600087803b1515611f2657600080fd5b6102c65a03f11515611f3757600080fd5b5050601280546001019055505050565b600080808311611f5657600080fd5b6006805484908110611f6457fe5b906000526020600020906002020190506120098161010060405190810160409081528254825260019092015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152612c82565b9392505050565b61138881565b60005433600160a060020a0390811691161461203157600080fd5b600d8054600160a060020a031916600160a060020a0392909216919091179055565b600b54600160a060020a031681565b600080600080600080600080600080600060068c81548110151561208257fe5b906000526020600020906002020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159a50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161115995080600101601c9054906101000a900461ffff1661ffff1698508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160189054906101000a900463ffffffff1663ffffffff1696508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1695508060010160109054906101000a900463ffffffff1663ffffffff1694508060010160149054906101000a900463ffffffff1663ffffffff16935080600101601e9054906101000a900461ffff1661ffff16925080600001549150509193959799509193959799565b60025460009060a060020a900460ff16156121dd57600080fd5b6121e73383612572565b15156121f257600080fd5b6121fb82611f47565b151561220657600080fd5b6122108284612cb9565b151561221b57600080fd5b600c54600160a060020a031663c55d0f568460006040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561226c57600080fd5b6102c65a03f1151561227d57600080fd5b5050506040518051600e549092508201341015905061229b57600080fd5b600c54600e54600160a060020a039091169063454a2ab39034038560405160e060020a63ffffffff851602815260048101919091526024016000604051808303818588803b15156122eb57600080fd5b6125ee5a03f115156122fc57600080fd5b50505050610fdf8263ffffffff168463ffffffff16612d08565b60125481565b601054600160a060020a031681565b600254600090819060a060020a900460ff161561234757600080fd5b600e5434101561235657600080fd5b6123603385612572565b151561236b57600080fd5b612375838561289b565b151561238057600080fd5b600680548590811061238e57fe5b906000526020600020906002020191506124338261010060405190810160409081528254825260019092015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152612c82565b151561243e57600080fd5b600680548490811061244c57fe5b906000526020600020906002020190506124f18161010060405190810160409081528254825260019092015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152612c82565b15156124fc57600080fd5b6125088285838661271b565b151561251357600080fd5b61155a8484612d08565b612525612fa0565b61252d612fa0565b6000808460405180591061253e5750595b818152601f19601f8301168101602001604052905092505060208201905084612568828287612e72565b5090949350505050565b600090815260076020526040902054600160a060020a0391821691161490565b6000918252600960205260409091208054600160a060020a031916600160a060020a03909216919091179055565b600090815260096020526040902054600160a060020a0391821691161490565b600160a060020a03808316600081815260086020908152604080832080546001019055858352600790915290208054600160a060020a031916909117905583161561267357600160a060020a03831660009081526008602090815260408083208054600019019055838352600a82528083208054600160a060020a03199081169091556009909252909120805490911690555b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef838383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a1505050565b60005433600160a060020a039081169116146126e357600080fd5b60025460a060020a900460ff1615156126fb57600080fd5b6002805474ff000000000000000000000000000000000000000019169055565b60008184141561272d57506000612893565b6001850154608060020a900463ffffffff1682148061275c5750600185015460a060020a900463ffffffff1682145b1561276957506000612893565b6001830154608060020a900463ffffffff168414806127985750600183015460a060020a900463ffffffff1684145b156127a557506000612893565b6001830154608060020a900463ffffffff1615806127d257506001850154608060020a900463ffffffff16155b156127df57506001612893565b60018581015490840154608060020a9182900463ffffffff9081169290910416148061282a575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b1561283757506000612893565b6001808601549084015460a060020a900463ffffffff908116608060020a90920416148061288257506001858101549084015460a060020a9182900463ffffffff9081169290910416145b1561288f57506000612893565b5060015b949350505050565b6000818152600760205260408082205484835290822054600160a060020a0391821691168082148061133e57506000858152600a6020526040902054600160a060020a03908116908316149250505092915050565b6000806128fb612fdb565b600063ffffffff8916891461290f57600080fd5b63ffffffff8816881461292157600080fd5b61ffff8716871461293157600080fd5b600287049250600d8361ffff16111561294957600d92505b610100604051908101604090815287825267ffffffffffffffff42166020830152600090820181905263ffffffff808c1660608401528a16608083015260a082015261ffff80851660c0830152881660e0820152600680549193506001918083016129b4838261301f565b6000928352602090922085916002020181518155602082015160018201805467ffffffffffffffff191667ffffffffffffffff9290921691909117905560408201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060c082015181600101601c6101000a81548161ffff021916908361ffff16021790555060e08201516001909101805461ffff9290921660f060020a027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555003905063ffffffff81168114612b0f57600080fd5b7f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad58582846060015163ffffffff16856080015163ffffffff168651604051600160a060020a03909516855260208501939093526040808501929092526060840152608083019190915260a0909101905180910390a1612b90600086836125e0565b98975050505050505050565b60008160a0015163ffffffff1615801590610c6f57504367ffffffffffffffff16826040015167ffffffffffffffff16111592915050565b600b5460009081908190600160a060020a031663eac9d94c82604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515612c2257600080fd5b6102c65a03f11515612c3357600080fd5b50505060405180519250506fffffffffffffffffffffffffffffffff82168214612c5c57600080fd5b50600281048101662386f26fc10000811015612c7c5750662386f26fc100005b92915050565b60008160a0015163ffffffff16158015610c6f57504367ffffffffffffffff16826040015167ffffffffffffffff16111592915050565b6000806000600685815481101515612ccd57fe5b90600052602060002090600202019150600684815481101515612cec57fe5b9060005260206000209060020201905061133e8286838761271b565b600080600683815481101515612d1a57fe5b90600052602060002090600202019150600684815481101515612d3957fe5b600091825260209091206002909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff8716021790559050612d8982612eb7565b612d9281612eb7565b6000848152600a602090815260408083208054600160a060020a031990811690915586845281842080549091169055600f8054600190810190915587845260079092529182902054908301547f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b8092600160a060020a0390921691879187916801000000000000000090910467ffffffffffffffff1690518085600160a060020a0316600160a060020a031681526020018481526020018381526020018267ffffffffffffffff16815260200194505050505060405180910390a150505050565b60005b60208210612e985782518452602084019350602083019250602082039150612e75565b6001826020036101000a03905080198351168185511617909352505050565b600554600182015443919060039060e060020a900461ffff16600e8110612eda57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515612f0557fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600d60e060020a90910461ffff161015612f9d576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b60206040519081016040526000815290565b60806040519081016040526004815b60008152600019919091019060200181612fc15790505090565b6101006040519081016040908152600080835260208301819052908201819052606082018190526080820181905260a0820181905260c0820181905260e082015290565b815481835581811511610fdf57600083815260209020610fdf91610ef99160029182028101918502015b808211156130635760008082556001820155600201613049565b50905600a165627a7a72305820a6465fc1ce7ab1a92906ff7206b23d80a21bbd50b85b4bde6a91f8e6b2e3edde0029"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cfoAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_preferredTransport\",\"type\":\"string\"}],\"name\":\"tokenMetadata\",\"outputs\":[{\"name\":\"infoUrl\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"promoCreatedCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ceoAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_STARTING_PRICE\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setSiringAuctionAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pregnantKitties\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"}],\"name\":\"isPregnant\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_AUCTION_DURATION\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"siringAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setGeneScienceAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCEO\",\"type\":\"address\"}],\"name\":\"setCEO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCOO\",\"type\":\"address\"}],\"name\":\"setCOO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"}],\"name\":\"createSaleAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sireAllowedToAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"canBreedWith\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"kittyIndexToApproved\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"}],\"name\":\"createSiringAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"setAutoBirthFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_addr\",\"type\":\"address\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"approveSiring\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCFO\",\"type\":\"address\"}],\"name\":\"setCFO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_genes\",\"type\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"createPromoKitty\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"secs\",\"type\":\"uint256\"}],\"name\":\"setSecondsPerBlock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_CREATION_LIMIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"newContractAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setSaleAuctionAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"count\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_v2Address\",\"type\":\"address\"}],\"name\":\"setNewAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"secondsPerBlock\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"tokensOfOwner\",\"outputs\":[{\"name\":\"ownerTokens\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"}],\"name\":\"giveBirth\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawAuctionBalances\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"cooldowns\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"kittyIndexToOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cooAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"autoBirthFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"erc721Metadata\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_genes\",\"type\":\"uint256\"}],\"name\":\"createGen0Auction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"}],\"name\":\"isReadyToBreed\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"PROMO_CREATION_LIMIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_contractAddress\",\"type\":\"address\"}],\"name\":\"setMetadataAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"saleAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getKitty\",\"outputs\":[{\"name\":\"isGestating\",\"type\":\"bool\"},{\"name\":\"isReady\",\"type\":\"bool\"},{\"name\":\"cooldownIndex\",\"type\":\"uint256\"},{\"name\":\"nextActionAt\",\"type\":\"uint256\"},{\"name\":\"siringWithId\",\"type\":\"uint256\"},{\"name\":\"birthTime\",\"type\":\"uint256\"},{\"name\":\"matronId\",\"type\":\"uint256\"},{\"name\":\"sireId\",\"type\":\"uint256\"},{\"name\":\"generation\",\"type\":\"uint256\"},{\"name\":\"genes\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_sireId\",\"type\":\"uint256\"},{\"name\":\"_matronId\",\"type\":\"uint256\"}],\"name\":\"bidOnSiringAuction\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gen0CreatedCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"geneScience\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"breedWithAuto\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"matronId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"sireId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"cooldownEndBlock\",\"type\":\"uint256\"}],\"name\":\"Pregnant\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"kittyId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"matronId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"sireId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"genes\",\"type\":\"uint256\"}],\"name\":\"Birth\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"newContract\",\"type\":\"address\"}],\"name\":\"ContractUpgrade\",\"type\":\"event\"}]"; + + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract008Key,contract008Address,blockingStubFull); + maxFeeLimit = 3900000000L; + contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract008Key,contract008Address,blockingStubFull); + + final SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + accountResource = PublicMethed.getAccountResource(contract008Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(contract008Key,blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + //Assert.assertTrue(storageUsage > 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario009.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario009.java new file mode 100644 index 00000000000..cc3f8fd7e3c --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario009.java @@ -0,0 +1,115 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario009 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract009Address = ecKey1.getAddress(); + String contract009Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract009Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract009Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract009Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract009Address, 1000000L, + 3,1,contract009Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract009Address,contract009Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployContainLibraryContract() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract009Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "Library"; + String code = "608060405234801561001057600080fd5b50610139806100206000396000f3006080604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663f207564e8114610045575b600080fd5b34801561005157600080fd5b5061005d60043561005f565b005b73610199610030600b82828239805160001a6073146000811461002057610022565bfe5b5030600052607381538281f300730000000000000000000000000000000000000000301460806040526004361061006d5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663483b8a1481146100725780636ce8e081146100a1578063831cb739146100bc575b600080fd5b81801561007e57600080fd5b5061008d6004356024356100d7565b604080519115158252519081900360200190f35b8180156100ad57600080fd5b5061008d600435602435610117565b8180156100c857600080fd5b5061008d60043560243561012d565b60008181526020839052604081205460ff1615156100f757506000610111565b506000818152602083905260409020805460ff1916905560015b92915050565b6000908152602091909152604090205460ff1690565b60008181526020839052604081205460ff161561014c57506000610111565b50600090815260209190915260409020805460ff19166001908117909155905600a165627a7a723058200bc4068752b78840d32288f8eeffe2618c356d76fe09451d92f808cf28d4d22e0029"; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"self\",\"type\":\"Set.Data storage\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"remove\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"self\",\"type\":\"Set.Data storage\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"contains\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"self\",\"type\":\"Set.Data storage\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"insert\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + byte[] libraryAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract009Key,contract009Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(libraryAddress,blockingStubFull); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + logger.info(ByteArray.toHexString(smartContract.getContractAddress().toByteArray())); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + accountResource = PublicMethed.getAccountResource(contract009Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage == 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario010.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario010.java new file mode 100644 index 00000000000..32269eb367f --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario010.java @@ -0,0 +1,115 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario010 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract009Address = ecKey1.getAddress(); + String contract009Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract009Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract009Address,20000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract009Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract009Address, 1000000L, + 3,1,contract009Key,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(5000000L,contract009Address,contract009Key, + blockingStubFull));*/ + + } + + @Test(enabled = true) + public void deployContainLibraryContract() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract009Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 50000000L; + String contractName = "Tron_ERC721_Token"; + String code = "608060405234801561001057600080fd5b50610731806100206000396000f3006080604052600436106100a35763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100a8578063095ea7b31461013257806318160ddd146101585780632f745c591461017f5780636352211e146101a35780636914db60146101d757806370a08231146101ef57806395d89b4114610210578063a9059cbb14610225578063b2e6ceeb14610249575b600080fd5b3480156100b457600080fd5b506100bd610261565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100f75781810151838201526020016100df565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013e57600080fd5b50610156600160a060020a0360043516602435610298565b005b34801561016457600080fd5b5061016d61032d565b60408051918252519081900360200190f35b34801561018b57600080fd5b5061016d600160a060020a0360043516602435610336565b3480156101af57600080fd5b506101bb60043561035e565b60408051600160a060020a039092168252519081900360200190f35b3480156101e357600080fd5b506100bd600435610397565b3480156101fb57600080fd5b5061016d600160a060020a0360043516610438565b34801561021c57600080fd5b506100bd610453565b34801561023157600080fd5b50610156600160a060020a036004351660243561048a565b34801561025557600080fd5b5061015660043561059d565b60408051808201909152601181527f54726f6e2045524337323120546f6b656e000000000000000000000000000000602082015290565b6102a18161035e565b600160a060020a031633146102b557600080fd5b33600160a060020a03831614156102cb57600080fd5b336000818152600360209081526040808320600160a060020a03871680855290835292819020859055805185815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35050565b64e8d4a5100090565b600160a060020a03919091166000908152600460209081526040808320938352929052205490565b60008181526002602052604081205460ff16151561037b57600080fd5b50600090815260016020526040902054600160a060020a031690565b60008181526005602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526060939283018282801561042c5780601f106104015761010080835404028352916020019161042c565b820191906000526020600020905b81548152906001019060200180831161040f57829003601f168201915b50505050509050919050565b600160a060020a031660009081526020819052604090205490565b60408051808201909152600581527f5437323154000000000000000000000000000000000000000000000000000000602082015290565b6000818152600260205260408120543391849160ff1615156104ab57600080fd5b6104b48461035e565b600160a060020a038481169116146104cb57600080fd5b600160a060020a0383811690831614156104e457600080fd5b600160a060020a03821615156104f957600080fd5b508161050581856106a7565b600160a060020a0381811660008181526020818152604080832080546000190190558883526001808352818420805473ffffffffffffffffffffffffffffffffffffffff19169689169687179055858452838352928190208054909301909255815188815291517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050505050565b600081815260026020526040812054819060ff1615156105bc57600080fd5b6105c58361035e565b9150339050600160a060020a0382168114156105e057600080fd5b600160a060020a03808316600090815260036020908152604080832093851683529290522054831461061157600080fd5b600160a060020a0382811660008181526020818152604080832080546000190190558783526001808352818420805473ffffffffffffffffffffffffffffffffffffffff19169688169687179055858452838352928190208054909301909255815187815291517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3505050565b60005b600160a060020a0383166000908152600460209081526040808320848452909152902054821461070057600160a060020a03831660009081526004602090815260408083208484529091528120556001016106aa565b5050505600a165627a7a72305820d3ca2ca957b72f4c5028c633a6ad4bafe13572bf949793fabe72e34eb640d2c50029"; + String abi = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"name\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"supply\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"},{\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"tokenOfOwnerByIndex\",\"outputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenMetadata\",\"outputs\":[{\"name\":\"infoUrl\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"symbol\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"takeOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_approved\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}]"; + byte[] libraryAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract009Key,contract009Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(libraryAddress,blockingStubFull); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + logger.info(ByteArray.toHexString(smartContract.getContractAddress().toByteArray())); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + accountResource = PublicMethed.getAccountResource(contract009Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage == 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(energyLimit > 0); + Assert.assertTrue(energyUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario011.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario011.java new file mode 100644 index 00000000000..43475a70e15 --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario011.java @@ -0,0 +1,391 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.springframework.util.StringUtils; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.SmartContract; +import org.tron.protos.Protocol.TransactionInfo; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.Base58; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario011 { + + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + + String kittyCoreAddressAndCut = ""; + byte[] kittyCoreContractAddress = null; + byte[] saleClockAuctionContractAddress = null; + byte[] siringClockAuctionContractAddress = null; + byte[] geneScienceInterfaceContractAddress = null; + Integer consumeUserResourcePercent = 50; + String txid = ""; + Optional infoById = null; + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] deployAddress = ecKey1.getAddress(); + String deployKey = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + ECKey ecKey2 = new ECKey(Utils.getRandom()); + byte[] triggerAddress = ecKey2.getAddress(); + String triggerKey = ByteArray.toHexString(ecKey2.getPrivKeyBytes()); + + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(deployKey); + PublicMethed.printAddress(triggerKey); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(deployAddress, 50000000000L, fromAddress, + testKey002, blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(triggerAddress, 50000000000L, fromAddress, + testKey002, blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(deployAddress, 100000000L, + 3, 1, deployKey, blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalance(deployAddress, 100000000L, 3, + deployKey, blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalance(triggerAddress, 100000000L, 3, + triggerKey, blockingStubFull)); + + + } + + @Test(enabled = true) + public void deployErc721KittyCore() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(deployAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(deployAddress, blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "KittyCore"; + String code = "6002805460a060020a60ff0219169055610240604052603c6080908152607860a05261012c60c05261025860e05261070861010052610e1061012052611c2061014052613840610160526170806101805261e1006101a052620151806101c0526202a3006101e052620546006102005262093a80610220526200008790600390600e620004e3565b50600f6005556301312d00600e55348015620000a257600080fd5b506002805460008054600160a060020a031990811633908117835560a060020a60ff0219909316740100000000000000000000000000000000000000001716909117909155620001019080806000198164010000000062000108810204565b50620005f1565b6000806200011562000586565b600063ffffffff891689146200012a57600080fd5b63ffffffff881688146200013d57600080fd5b61ffff871687146200014e57600080fd5b600287049250600d8361ffff1611156200016757600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600680546001810182559c528a517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f60028e029081019190915598517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40909901805498519651955194519251915167ffffffffffffffff19909916998b1699909917604060020a608060020a0319166801000000000000000096909a169590950298909817608060020a63ffffffff021916700100000000000000000000000000000000938616939093029290921760a060020a63ffffffff02191674010000000000000000000000000000000000000000918516919091021760c060020a63ffffffff0219167801000000000000000000000000000000000000000000000000968416969096029590951760e060020a61ffff0219167c01000000000000000000000000000000000000000000000000000000009186169190910217600160f060020a03167e010000000000000000000000000000000000000000000000000000000000009290941691909102929092179055909190811681146200036f57600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a1620003f46000868364010000000062000400810204565b98975050505050505050565b600160a060020a03808316600081815260086020908152604080832080546001019055858352600790915290208054600160a060020a03191690911790558316156200049457600160a060020a03831660009081526008602090815260408083208054600019019055838352600a82528083208054600160a060020a03199081169091556009909252909120805490911690555b60408051600160a060020a0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b600283019183908215620005745791602002820160005b838211156200054057835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302620004fa565b8015620005725782816101000a81549063ffffffff021916905560040160208160030104928301926001030262000540565b505b5062000582929150620005ca565b5090565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b620005ee91905b808211156200058257805463ffffffff19168155600101620005d1565b90565b6130f380620006016000396000f3006080604052600436106102a55763ffffffff60e060020a60003504166301ffc9a781146102d55780630519ce79146103205780630560ff441461035157806305e45546146103ea57806306fdde0314610411578063095ea7b3146104265780630a0f81681461044a5780630e583df01461045f57806314001f4c1461047457806318160ddd14610495578063183a7947146104aa5780631940a936146104bf57806319c2f201146104d757806321717ebf146104ec57806323b872dd1461050157806324e7a38a1461052b57806327d7874c1461054c5780632ba73c151461056d5780633d7d3f5a1461058e5780633f4ba83a146105af57806346116e6f146105c457806346d22c70146105dc578063481af3d3146105f75780634ad8c9381461060f5780634b85fd55146106305780634dfff04f146106485780634e0a33791461066c578063561291341461068d5780635663896e146106b15780635c975abb146106c95780635fd8c710146106de5780636352211e146106f3578063680eba271461070b5780636af04a57146107205780636fbde40d1461073557806370a082311461075657806371587988146107775780637a7d4937146107985780638456cb59146107ad5780638462151c146107c257806388c2a0bf1461083357806391876e571461084b57806395d89b41146108605780639d6fac6f14610875578063a45f4bfc146108a6578063a9059cbb146108be578063b047fb50146108e2578063b0c35c05146108f7578063bc4006f51461090c578063c3bea9af14610921578063d3e6f49f14610939578063defb958414610951578063e17b25af14610966578063e6cbe35114610987578063e98b7f4d1461099c578063ed60ade614610a06578063f1ca941014610a14578063f2b47d5214610a29578063f7d8c88314610a3e575b600b54600160a060020a03163314806102c85750600c54600160a060020a031633145b15156102d357600080fd5b005b3480156102e157600080fd5b5061030c7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610a4c565b604080519115158252519081900360200190f35b34801561032c57600080fd5b50610335610cdf565b60408051600160a060020a039092168252519081900360200190f35b34801561035d57600080fd5b50610375600480359060248035908101910135610cee565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103af578181015183820152602001610397565b50505050905090810190601f1680156103dc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103f657600080fd5b506103ff610df1565b60408051918252519081900360200190f35b34801561041d57600080fd5b50610375610df7565b34801561043257600080fd5b506102d3600160a060020a0360043516602435610e2e565b34801561045657600080fd5b50610335610eb0565b34801561046b57600080fd5b506103ff610ebf565b34801561048057600080fd5b506102d3600160a060020a0360043516610ec6565b3480156104a157600080fd5b506103ff610f79565b3480156104b657600080fd5b506103ff610f83565b3480156104cb57600080fd5b5061030c600435610f89565b3480156104e357600080fd5b506103ff610fce565b3480156104f857600080fd5b50610335610fd5565b34801561050d57600080fd5b506102d3600160a060020a0360043581169060243516604435610fe4565b34801561053757600080fd5b506102d3600160a060020a0360043516611060565b34801561055857600080fd5b506102d3600160a060020a0360043516611113565b34801561057957600080fd5b506102d3600160a060020a0360043516611161565b34801561059a57600080fd5b506102d36004356024356044356064356111af565b3480156105bb57600080fd5b506102d36112a4565b3480156105d057600080fd5b50610335600435611338565b3480156105e857600080fd5b5061030c600435602435611353565b34801561060357600080fd5b506103356004356113d3565b34801561061b57600080fd5b506102d36004356024356044356064356113ee565b34801561063c57600080fd5b506102d36004356114c6565b34801561065457600080fd5b506102d3600160a060020a03600435166024356114e2565b34801561067857600080fd5b506102d3600160a060020a036004351661153c565b34801561069957600080fd5b506102d3600435600160a060020a036024351661158a565b3480156106bd57600080fd5b506102d36004356115f1565b3480156106d557600080fd5b5061030c61164d565b3480156106ea57600080fd5b506102d361165d565b3480156106ff57600080fd5b506103356004356116c1565b34801561071757600080fd5b506103ff6116e5565b34801561072c57600080fd5b506103356116eb565b34801561074157600080fd5b506102d3600160a060020a03600435166116fa565b34801561076257600080fd5b506103ff600160a060020a03600435166117ad565b34801561078357600080fd5b506102d3600160a060020a03600435166117c8565b3480156107a457600080fd5b506103ff61184b565b3480156107b957600080fd5b506102d3611851565b3480156107ce57600080fd5b506107e3600160a060020a03600435166118d1565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561081f578181015183820152602001610807565b505050509050019250505060405180910390f35b34801561083f57600080fd5b506103ff6004356119a3565b34801561085757600080fd5b506102d3611c7f565b34801561086c57600080fd5b50610375611d94565b34801561088157600080fd5b5061088d600435611dcb565b6040805163ffffffff9092168252519081900360200190f35b3480156108b257600080fd5b50610335600435611df8565b3480156108ca57600080fd5b506102d3600160a060020a0360043516602435611e13565b3480156108ee57600080fd5b50610335611eab565b34801561090357600080fd5b506103ff611eba565b34801561091857600080fd5b50610335611ec0565b34801561092d57600080fd5b506102d3600435611ecf565b34801561094557600080fd5b5061030c600435611fb9565b34801561095d57600080fd5b506103ff612088565b34801561097257600080fd5b506102d3600160a060020a036004351661208e565b34801561099357600080fd5b506103356120c7565b3480156109a857600080fd5b506109b46004356120d6565b604080519a15158b5298151560208b0152898901979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015251908190036101400190f35b6102d3600435602435612237565b348015610a2057600080fd5b506103ff6123d1565b348015610a3557600080fd5b506103356123d7565b6102d36004356024356123e6565b604080517f737570706f727473496e74657266616365286279746573342900000000000000815290519081900360190190206000907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1983811691161480610cd75750604080517f746f6b656e4d657461646174612875696e743235362c737472696e67290000008152815190819003601d0181207f746f6b656e734f664f776e657228616464726573732900000000000000000000825282519182900360160182207f7472616e7366657246726f6d28616464726573732c616464726573732c75696e83527f7432353629000000000000000000000000000000000000000000000000000000602084015283519283900360250183207f7472616e7366657228616464726573732c75696e743235362900000000000000845284519384900360190184207f617070726f766528616464726573732c75696e74323536290000000000000000855285519485900360180185207f6f776e65724f662875696e743235362900000000000000000000000000000000865286519586900360100186207f62616c616e63654f662861646472657373290000000000000000000000000000875287519687900360120187207f746f74616c537570706c792829000000000000000000000000000000000000008852885197889003600d0188207f73796d626f6c2829000000000000000000000000000000000000000000000000895289519889900360080189207f6e616d65282900000000000000000000000000000000000000000000000000008a529951988990036006019098207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff198c811691909a189098181818181818181891909116145b90505b919050565b600154600160a060020a031681565b6060610cf8613064565b600d54600090600160a060020a03161515610d1257600080fd5b600d54604080517fcb4799f2000000000000000000000000000000000000000000000000000000008152600481018981526024820192835260448201889052600160a060020a039093169263cb4799f2928a928a928a929091606401848480828437820191505094505050505060a060405180830381600087803b158015610d9957600080fd5b505af1158015610dad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525060a0811015610dd257600080fd5b5060808101519092509050610de782826125e4565b9695505050505050565b60115481565b60408051808201909152600d81527f43727970746f4b69747469657300000000000000000000000000000000000000602082015281565b60025460a060020a900460ff1615610e4557600080fd5b610e4f3382612638565b1515610e5a57600080fd5b610e648183612658565b60408051338152600160a060020a038416602082015280820183905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15050565b600054600160a060020a031681565b6298968081565b60008054600160a060020a03163314610ede57600080fd5b81905080600160a060020a03166376190f8f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f1f57600080fd5b505af1158015610f33573d6000803e3d6000fd5b505050506040513d6020811015610f4957600080fd5b50511515610f5657600080fd5b600c8054600160a060020a031916600160a060020a039290921691909117905550565b6006546000190190565b600f5481565b6000808211610f9757600080fd5b6006805483908110610fa557fe5b600091825260209091206002909102016001015460c060020a900463ffffffff16151592915050565b6201518081565b600c54600160a060020a031681565b60025460a060020a900460ff1615610ffb57600080fd5b600160a060020a038216151561101057600080fd5b600160a060020a03821630141561102657600080fd5b6110303382612686565b151561103b57600080fd5b6110458382612638565b151561105057600080fd5b61105b8383836126a6565b505050565b60008054600160a060020a0316331461107857600080fd5b81905080600160a060020a03166354c15b826040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156110b957600080fd5b505af11580156110cd573d6000803e3d6000fd5b505050506040513d60208110156110e357600080fd5b505115156110f057600080fd5b60108054600160a060020a031916600160a060020a039290921691909117905550565b600054600160a060020a0316331461112a57600080fd5b600160a060020a038116151561113f57600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331461117857600080fd5b600160a060020a038116151561118d57600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b60025460a060020a900460ff16156111c657600080fd5b6111d03385612638565b15156111db57600080fd5b6111e484610f89565b156111ee57600080fd5b600b54611205908590600160a060020a0316612658565b600b54604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b15801561128657600080fd5b505af115801561129a573d6000803e3d6000fd5b5050505050505050565b600054600160a060020a031633146112bb57600080fd5b60025460a060020a900460ff1615156112d357600080fd5b600b54600160a060020a031615156112ea57600080fd5b600c54600160a060020a0316151561130157600080fd5b601054600160a060020a0316151561131857600080fd5b601354600160a060020a03161561132e57600080fd5b611336612788565b565b600a60205260009081526040902054600160a060020a031681565b6000808080851161136357600080fd5b6000841161137057600080fd5b600680548690811061137e57fe5b9060005260206000209060020201915060068481548110151561139d57fe5b906000526020600020906002020190506113b9828683876127d7565b80156113ca57506113ca8486612957565b95945050505050565b600960205260009081526040902054600160a060020a031681565b60025460a060020a900460ff161561140557600080fd5b61140f3385612638565b151561141a57600080fd5b61142384611fb9565b151561142e57600080fd5b600c54611445908590600160a060020a0316612658565b600c54604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b15801561128657600080fd5b600254600160a060020a031633146114dd57600080fd5b600e55565b60025460a060020a900460ff16156114f957600080fd5b6115033382612638565b151561150e57600080fd5b6000908152600a602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331461155357600080fd5b600160a060020a038116151561156857600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b600254600090600160a060020a031633146115a457600080fd5b5080600160a060020a03811615156115c45750600254600160a060020a03165b601154611388116115d457600080fd5b6011805460010190556115eb6000808086856129ac565b50505050565b600254600160a060020a03163314806116145750600054600160a060020a031633145b806116295750600154600160a060020a031633145b151561163457600080fd5b60035463ffffffff16811061164857600080fd5b600555565b60025460a060020a900460ff1681565b6001546000908190600160a060020a0316331461167957600080fd5b5050600e54600f54303191600190910102808211156116bd57600154604051600160a060020a039091169082840380156108fc02916000818181858888f150505050505b5050565b600081815260076020526040902054600160a060020a0316801515610cda57600080fd5b61afc881565b601354600160a060020a031681565b60008054600160a060020a0316331461171257600080fd5b81905080600160a060020a03166385b861886040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561175357600080fd5b505af1158015611767573d6000803e3d6000fd5b505050506040513d602081101561177d57600080fd5b5051151561178a57600080fd5b600b8054600160a060020a031916600160a060020a039290921691909117905550565b600160a060020a031660009081526008602052604090205490565b600054600160a060020a031633146117df57600080fd5b60025460a060020a900460ff1615156117f757600080fd5b60138054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b60055481565b600254600160a060020a03163314806118745750600054600160a060020a031633145b806118895750600154600160a060020a031633145b151561189457600080fd5b60025460a060020a900460ff16156118ab57600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055565b60606000606060008060006118e5876117ad565b9450841515611904576040805160008152602081019091529550611999565b8460405190808252806020026020018201604052801561192e578160200160208202803883390190505b509350611939610f79565b925060009150600190505b82811161199557600081815260076020526040902054600160a060020a038881169116141561198d5780848381518110151561197c57fe5b602090810290910101526001909101905b600101611944565b8395505b5050505050919050565b600080600080600080600080600260149054906101000a900460ff161515156119cb57600080fd5b600680548a9081106119d957fe5b60009182526020909120600290910201600181015490975067ffffffffffffffff161515611a0657600080fd5b604080516101008101825288548152600189015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152611a9790612c89565b1515611aa257600080fd5b60018701546006805460c060020a90920463ffffffff1697509087908110611ac657fe5b600091825260209091206001808a015460029093029091019081015490965061ffff60f060020a928390048116965091900416841015611b1357600185015460f060020a900461ffff1693505b6010548754865460018a0154604080517f0d9f5aed0000000000000000000000000000000000000000000000000000000081526004810194909452602484019290925260001967ffffffffffffffff6801000000000000000090920482160116604483015251600160a060020a0390921691630d9f5aed916064808201926020929091908290030181600087803b158015611bad57600080fd5b505af1158015611bc1573d6000803e3d6000fd5b505050506040513d6020811015611bd757600080fd5b505160008a815260076020526040902054600189810154929550600160a060020a039091169350611c20918b9160c060020a90910463ffffffff1690870161ffff1686866129ac565b6001880180547bffffffff00000000000000000000000000000000000000000000000019169055600f8054600019019055600e54604051919250339181156108fc0291906000818181858888f150939c9b505050505050505050505050565b600254600160a060020a0316331480611ca25750600054600160a060020a031633145b80611cb75750600154600160a060020a031633145b1515611cc257600080fd5b600b60009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611d1557600080fd5b505af1158015611d29573d6000803e3d6000fd5b50505050600c60009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611d8057600080fd5b505af11580156115eb573d6000803e3d6000fd5b60408051808201909152600281527f434b000000000000000000000000000000000000000000000000000000000000602082015281565b600381600e8110611dd857fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b600760205260009081526040902054600160a060020a031681565b60025460a060020a900460ff1615611e2a57600080fd5b600160a060020a0382161515611e3f57600080fd5b600160a060020a038216301415611e5557600080fd5b600b54600160a060020a0383811691161415611e7057600080fd5b600c54600160a060020a0383811691161415611e8b57600080fd5b611e953382612638565b1515611ea057600080fd5b6116bd3383836126a6565b600254600160a060020a031681565b600e5481565b600d54600160a060020a031681565b600254600090600160a060020a03163314611ee957600080fd5b60125461afc811611ef957600080fd5b611f08600080600085306129ac565b600b54909150611f22908290600160a060020a0316612658565b600b54600160a060020a03166327ebe40a82611f3c612cb9565b6040805160e060020a63ffffffff861602815260048101939093526024830191909152600060448301819052620151806064840152306084840152905160a48084019382900301818387803b158015611f9457600080fd5b505af1158015611fa8573d6000803e3d6000fd5b505060128054600101905550505050565b600080808311611fc857600080fd5b6006805484908110611fd657fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e082015290915061208190612d7b565b9392505050565b61138881565b600054600160a060020a031633146120a557600080fd5b600d8054600160a060020a031916600160a060020a0392909216919091179055565b600b54600160a060020a031681565b600080600080600080600080600080600060068c8154811015156120f657fe5b906000526020600020906002020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159a50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161115995080600101601c9054906101000a900461ffff1661ffff1698508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160189054906101000a900463ffffffff1663ffffffff1696508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1695508060010160109054906101000a900463ffffffff1663ffffffff1694508060010160149054906101000a900463ffffffff1663ffffffff16935080600101601e9054906101000a900461ffff1661ffff16925080600001549150509193959799509193959799565b60025460009060a060020a900460ff161561225157600080fd5b61225b3383612638565b151561226657600080fd5b61226f82611fb9565b151561227a57600080fd5b6122848284612daa565b151561228f57600080fd5b600c54604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b1580156122f657600080fd5b505af115801561230a573d6000803e3d6000fd5b505050506040513d602081101561232057600080fd5b5051600e54909150810134101561233657600080fd5b600c54600e54604080517f454a2ab3000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a039093169263454a2ab39234039160248082019260009290919082900301818588803b1580156123a257600080fd5b505af11580156123b6573d6000803e3d6000fd5b505050505061105b8263ffffffff168463ffffffff16612df9565b60125481565b601054600160a060020a031681565b600254600090819060a060020a900460ff161561240257600080fd5b600e5434101561241157600080fd5b61241b3385612638565b151561242657600080fd5b6124308385612957565b151561243b57600080fd5b600680548590811061244957fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529092506124f490612d7b565b15156124ff57600080fd5b600680548490811061250d57fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529091506125b890612d7b565b15156125c357600080fd5b6125cf828583866127d7565b15156125da57600080fd5b6115eb8484612df9565b606080600080846040519080825280601f01601f191660200182016040528015612618578160200160208202803883390190505b509250506020820190508461262e828287612f37565b5090949350505050565b600090815260076020526040902054600160a060020a0391821691161490565b6000918252600960205260409091208054600160a060020a031916600160a060020a03909216919091179055565b600090815260096020526040902054600160a060020a0391821691161490565b600160a060020a03808316600081815260086020908152604080832080546001019055858352600790915290208054600160a060020a031916909117905583161561273957600160a060020a03831660009081526008602090815260408083208054600019019055838352600a82528083208054600160a060020a03199081169091556009909252909120805490911690555b60408051600160a060020a0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b600054600160a060020a0316331461279f57600080fd5b60025460a060020a900460ff1615156127b757600080fd5b6002805474ff000000000000000000000000000000000000000019169055565b6000818414156127e95750600061294f565b6001850154608060020a900463ffffffff168214806128185750600185015460a060020a900463ffffffff1682145b156128255750600061294f565b6001830154608060020a900463ffffffff168414806128545750600183015460a060020a900463ffffffff1684145b156128615750600061294f565b6001830154608060020a900463ffffffff16158061288e57506001850154608060020a900463ffffffff16155b1561289b5750600161294f565b60018581015490840154608060020a9182900463ffffffff908116929091041614806128e6575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b156128f35750600061294f565b6001808601549084015460a060020a900463ffffffff908116608060020a90920416148061293e57506001858101549084015460a060020a9182900463ffffffff9081169290910416145b1561294b5750600061294f565b5060015b949350505050565b6000818152600760205260408082205484835290822054600160a060020a039182169116808214806113ca57506000858152600a6020526040902054600160a060020a03908116908316149250505092915050565b6000806129b7613083565b600063ffffffff891689146129cb57600080fd5b63ffffffff881688146129dd57600080fd5b61ffff871687146129ed57600080fd5b600287049250600d8361ffff161115612a0557600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600680546001810182559c528a517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f60028e029081019190915598517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40909901805498519651955194519251915167ffffffffffffffff19909916998b16999099176fffffffffffffffff000000000000000019166801000000000000000096909a16959095029890981773ffffffff000000000000000000000000000000001916608060020a938616939093029290921777ffffffff0000000000000000000000000000000000000000191660a060020a91851691909102177bffffffff000000000000000000000000000000000000000000000000191660c060020a96841696909602959095177fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a91861691909102177dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a929094169190910292909217905590919081168114612c0357600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a1612c7d600086836126a6565b98975050505050505050565b60008160a0015163ffffffff16600014158015610cd75750506040015167ffffffffffffffff4381169116111590565b6000806000600b60009054906101000a9004600160a060020a0316600160a060020a031663eac9d94c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612d1157600080fd5b505af1158015612d25573d6000803e3d6000fd5b505050506040513d6020811015612d3b57600080fd5b505191506fffffffffffffffffffffffffffffffff82168214612d5d57600080fd5b5060028104810162989680811015612d755750629896805b92915050565b60008160a0015163ffffffff166000148015610cd75750506040015167ffffffffffffffff4381169116111590565b6000806000600685815481101515612dbe57fe5b90600052602060002090600202019150600684815481101515612ddd57fe5b906000526020600020906002020190506113ca828683876127d7565b600080600683815481101515612e0b57fe5b90600052602060002090600202019150600684815481101515612e2a57fe5b600091825260209091206002909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff8716021790559050612e7a82612f7b565b612e8381612f7b565b6000848152600a602090815260408083208054600160a060020a031990811690915586845281842080549091169055600f80546001908101909155878452600783529281902054928401548151600160a060020a0390941684529183018790528281018690526801000000000000000090910467ffffffffffffffff166060830152517f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80916080908290030190a150505050565b60005b60208210612f5c578251845260209384019390920191601f1990910190612f3a565b50905182516020929092036101000a6000190180199091169116179052565b600554600182015443919060039060e060020a900461ffff16600e8110612f9e57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515612fc957fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600d60e060020a90910461ffff161015613061576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b6080604051908101604052806004906020820280388339509192915050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152905600a165627a7a723058201424bf1db41fa7ec76f5506a53d8bbcb84ed5b5a6ade2df0bac8deaacb118a8b0029"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cfoAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_preferredTransport\",\"type\":\"string\"}],\"name\":\"tokenMetadata\",\"outputs\":[{\"name\":\"infoUrl\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"promoCreatedCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ceoAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_STARTING_PRICE\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setSiringAuctionAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pregnantKitties\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"}],\"name\":\"isPregnant\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_AUCTION_DURATION\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"siringAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setGeneScienceAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCEO\",\"type\":\"address\"}],\"name\":\"setCEO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCOO\",\"type\":\"address\"}],\"name\":\"setCOO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"}],\"name\":\"createSaleAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sireAllowedToAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"canBreedWith\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"kittyIndexToApproved\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"}],\"name\":\"createSiringAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"setAutoBirthFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_addr\",\"type\":\"address\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"approveSiring\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCFO\",\"type\":\"address\"}],\"name\":\"setCFO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_genes\",\"type\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"createPromoKitty\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"secs\",\"type\":\"uint256\"}],\"name\":\"setSecondsPerBlock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_CREATION_LIMIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"newContractAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setSaleAuctionAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"count\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_v2Address\",\"type\":\"address\"}],\"name\":\"setNewAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"secondsPerBlock\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"tokensOfOwner\",\"outputs\":[{\"name\":\"ownerTokens\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"}],\"name\":\"giveBirth\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawAuctionBalances\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"cooldowns\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"kittyIndexToOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cooAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"autoBirthFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"erc721Metadata\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_genes\",\"type\":\"uint256\"}],\"name\":\"createGen0Auction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"}],\"name\":\"isReadyToBreed\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"PROMO_CREATION_LIMIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_contractAddress\",\"type\":\"address\"}],\"name\":\"setMetadataAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"saleAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getKitty\",\"outputs\":[{\"name\":\"isGestating\",\"type\":\"bool\"},{\"name\":\"isReady\",\"type\":\"bool\"},{\"name\":\"cooldownIndex\",\"type\":\"uint256\"},{\"name\":\"nextActionAt\",\"type\":\"uint256\"},{\"name\":\"siringWithId\",\"type\":\"uint256\"},{\"name\":\"birthTime\",\"type\":\"uint256\"},{\"name\":\"matronId\",\"type\":\"uint256\"},{\"name\":\"sireId\",\"type\":\"uint256\"},{\"name\":\"generation\",\"type\":\"uint256\"},{\"name\":\"genes\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_sireId\",\"type\":\"uint256\"},{\"name\":\"_matronId\",\"type\":\"uint256\"}],\"name\":\"bidOnSiringAuction\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gen0CreatedCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"geneScience\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"breedWithAuto\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"matronId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"sireId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"cooldownEndBlock\",\"type\":\"uint256\"}],\"name\":\"Pregnant\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"kittyId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"matronId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"sireId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"genes\",\"type\":\"uint256\"}],\"name\":\"Birth\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"newContract\",\"type\":\"address\"}],\"name\":\"ContractUpgrade\",\"type\":\"event\"}]"; + + logger.info("Kitty Core"); + kittyCoreContractAddress = PublicMethed.deployContract(contractName, abi, code, "", + maxFeeLimit, 0L, consumeUserResourcePercent, null, deployKey, + deployAddress, blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(kittyCoreContractAddress, + blockingStubFull); + Assert.assertFalse(StringUtils.isEmpty(smartContract.getBytecode())); + + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(deployAddress, blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(deployKey, blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + logger.info(ByteArray.toHexString(kittyCoreContractAddress)); + logger.info(ByteArray.toHexString(kittyCoreContractAddress).substring(2)); + + kittyCoreAddressAndCut = "000000000000000000000000" + ByteArray + .toHexString(kittyCoreContractAddress).substring(2); + kittyCoreAddressAndCut = kittyCoreAddressAndCut + "0000000000000000000000000000000000000000000" + + "000000000000000000100"; + } + + @Test(enabled = true) + public void deploySaleClockAuction() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(deployAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(deployKey, blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "SaleClockAuction"; + String code = + "60806040526000805460a060020a60ff02191690556004805460ff1916600117905534801561002d57600080fd5b50604051604080610ee883398101604052805160209091015160008054600160a060020a031916331781558290829061271082111561006b57600080fd5b506002819055604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f9a20483d00000000000000000000000000000000000000000000000000000000600482015290518391600160a060020a038316916301ffc9a7916024808201926020929091908290030181600087803b1580156100f557600080fd5b505af1158015610109573d6000803e3d6000fd5b505050506040513d602081101561011f57600080fd5b5051151561012c57600080fd5b60018054600160a060020a03909216600160a060020a031990921691909117905550505050610d88806101606000396000f3006080604052600436106100fb5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327ebe40a81146101005780633f4ba83a1461012f578063454a2ab314610158578063484eccb4146101635780635c975abb1461018d5780635fd8c710146101a257806378bd7935146101b757806383b5ff8b146102045780638456cb591461021957806385b861881461022e578063878eb368146102435780638a98a9cc1461025b5780638da5cb5b1461027057806396b5a755146102a1578063c55d0f56146102b9578063dd1b7a0f146102d1578063eac9d94c146102e6578063f2fde38b146102fb575b600080fd5b34801561010c57600080fd5b5061012d600435602435604435606435600160a060020a036084351661031c565b005b34801561013b57600080fd5b50610144610414565b604080519115158252519081900360200190f35b61012d60043561048f565b34801561016f57600080fd5b5061017b6004356104f9565b60408051918252519081900360200190f35b34801561019957600080fd5b5061014461050d565b3480156101ae57600080fd5b5061012d61051d565b3480156101c357600080fd5b506101cf60043561057a565b60408051600160a060020a03909616865260208601949094528484019290925260608401526080830152519081900360a00190f35b34801561021057600080fd5b5061017b610610565b34801561022557600080fd5b50610144610616565b34801561023a57600080fd5b50610144610696565b34801561024f57600080fd5b5061012d60043561069f565b34801561026757600080fd5b5061017b61070c565b34801561027c57600080fd5b50610285610712565b60408051600160a060020a039092168252519081900360200190f35b3480156102ad57600080fd5b5061012d600435610721565b3480156102c557600080fd5b5061017b600435610766565b3480156102dd57600080fd5b50610285610798565b3480156102f257600080fd5b5061017b6107a7565b34801561030757600080fd5b5061012d600160a060020a03600435166107db565b610324610d2e565b6fffffffffffffffffffffffffffffffff8516851461034257600080fd5b6fffffffffffffffffffffffffffffffff8416841461036057600080fd5b67ffffffffffffffff8316831461037657600080fd5b600154600160a060020a0316331461038d57600080fd5b610397828761082d565b60a06040519081016040528083600160a060020a03168152602001866fffffffffffffffffffffffffffffffff168152602001856fffffffffffffffffffffffffffffffff1681526020018467ffffffffffffffff1681526020014267ffffffffffffffff16815250905061040c86826108b5565b505050505050565b60008054600160a060020a0316331461042c57600080fd5b60005460a060020a900460ff16151561044457600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a150600190565b600081815260036020526040812054600160a060020a0316906104b28334610a09565b90506104be3384610b2f565b600154600160a060020a03838116911614156104f45760058054829160069106600581106104e857fe5b01556005805460010190555b505050565b6006816005811061050657fe5b0154905081565b60005460a060020a900460ff1681565b60015460008054600160a060020a039283169216331480610546575033600160a060020a038316145b151561055157600080fd5b604051600160a060020a03831690303180156108fc02916000818181858888f150505050505050565b6000818152600360205260408120819081908190819061059981610b9d565b15156105a457600080fd5b80546001820154600290920154600160a060020a03909116986fffffffffffffffffffffffffffffffff8084169950700100000000000000000000000000000000909304909216965067ffffffffffffffff808216965068010000000000000000909104169350915050565b60025481565b60008054600160a060020a0316331461062e57600080fd5b60005460a060020a900460ff161561064557600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a150600190565b60045460ff1681565b6000805460a060020a900460ff1615156106b857600080fd5b600054600160a060020a031633146106cf57600080fd5b5060008181526003602052604090206106e781610b9d565b15156106f257600080fd5b8054610708908390600160a060020a0316610bbe565b5050565b60055481565b600054600160a060020a031681565b60008181526003602052604081209061073982610b9d565b151561074457600080fd5b508054600160a060020a031633811461075c57600080fd5b6104f48382610bbe565b600081815260036020526040812061077d81610b9d565b151561078857600080fd5b61079181610c08565b9392505050565b600154600160a060020a031681565b600080805b60058110156107d157600681600581106107c257fe5b015491909101906001016107ac565b5060059004919050565b600054600160a060020a031633146107f257600080fd5b600160a060020a0381161561082a576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b50565b600154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015230602483015260448201859052915191909216916323b872dd91606480830192600092919082900301818387803b1580156108a157600080fd5b505af115801561040c573d6000803e3d6000fd5b603c816060015167ffffffffffffffff16101515156108d357600080fd5b60008281526003602090815260409182902083518154600160a060020a0390911673ffffffffffffffffffffffffffffffffffffffff1990911617815581840151600182018054858701516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000081029482166fffffffffffffffffffffffffffffffff19909316831790911693909317909155606080870151600290940180546080808a015167ffffffffffffffff90811668010000000000000000026fffffffffffffffff0000000000000000199190981667ffffffffffffffff1990931683171696909617909155865189815295860192909252848601929092529083015291517fa9c8dfcda5664a5a124c713e386da27de87432d5b668e79458501eb296389ba7929181900390910190a15050565b60008281526003602052604081208180808080610a2586610b9d565b1515610a3057600080fd5b610a3986610c08565b945084881015610a4857600080fd5b8554600160a060020a03169350610a5e89610c98565b6000851115610ab057610a7085610ce5565b6040519093508386039250600160a060020a0385169083156108fc029084906000818181858888f19350505050158015610aae573d6000803e3d6000fd5b505b5060405184880390339082156108fc029083906000818181858888f19350505050158015610ae2573d6000803e3d6000fd5b50604080518a815260208101879052338183015290517f4fcc30d90a842164dd58501ab874a101a3749c3d4747139cefe7c876f4ccebd29181900360600190a15092979650505050505050565b600154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152602482018590529151919092169163a9059cbb91604480830192600092919082900301818387803b1580156108a157600080fd5b6002015460006801000000000000000090910467ffffffffffffffff161190565b610bc782610c98565b610bd18183610b2f565b6040805183815290517f2809c7e17bf978fbc7194c0a694b638c4215e9140cacc6c38ca36010b45697df9181900360200190a15050565b6002810154600090819068010000000000000000900467ffffffffffffffff16421115610c4e5750600282015468010000000000000000900467ffffffffffffffff1642035b60018301546002840154610791916fffffffffffffffffffffffffffffffff80821692700100000000000000000000000000000000909204169067ffffffffffffffff1684610cf1565b6000908152600360205260408120805473ffffffffffffffffffffffffffffffffffffffff19168155600181019190915560020180546fffffffffffffffffffffffffffffffff19169055565b60025461271091020490565b6000808080858510610d0557869350610d23565b878703925085858402811515610d1757fe5b05915081880190508093505b505050949350505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152905600a165627a7a723058203c3d7d4039d9d9a82dd65c7bc046590e8fe3580af952a66fe24052959889bef50029" + + kittyCoreAddressAndCut; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"},{\"name\":\"_seller\",\"type\":\"address\"}],\"name\":\"createAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"bid\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastGen0SalePrices\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getAuction\",\"outputs\":[{\"name\":\"seller\",\"type\":\"address\"},{\"name\":\"startingPrice\",\"type\":\"uint256\"},{\"name\":\"endingPrice\",\"type\":\"uint256\"},{\"name\":\"duration\",\"type\":\"uint256\"},{\"name\":\"startedAt\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ownerCut\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isSaleClockAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"cancelAuctionWhenPaused\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gen0SaleCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"cancelAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getCurrentPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"nonFungibleContract\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"averageGen0SalePrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_nftAddr\",\"type\":\"address\"},{\"name\":\"_cut\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"startingPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"endingPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"AuctionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"totalPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"winner\",\"type\":\"address\"}],\"name\":\"AuctionSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"AuctionCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Pause\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Unpause\",\"type\":\"event\"}]"; + logger.info("Sale Clock Auction"); + saleClockAuctionContractAddress = PublicMethed.deployContract(contractName, abi, code, + "", maxFeeLimit, 0L, consumeUserResourcePercent, null, deployKey, + deployAddress, blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(saleClockAuctionContractAddress, + blockingStubFull); + Assert.assertFalse(StringUtils.isEmpty(smartContract.getBytecode())); + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(deployAddress, blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(deployKey, blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @Test(enabled = true) + public void deploySiringClockAuction() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(deployAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(deployKey, blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "SiringClockAuction"; + String code = + "60806040526000805460a060020a60ff02191690556004805460ff1916600117905534801561002d57600080fd5b50604051604080610e1a83398101604052805160209091015160008054600160a060020a031916331781558290829061271082111561006b57600080fd5b506002819055604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f9a20483d00000000000000000000000000000000000000000000000000000000600482015290518391600160a060020a038316916301ffc9a7916024808201926020929091908290030181600087803b1580156100f557600080fd5b505af1158015610109573d6000803e3d6000fd5b505050506040513d602081101561011f57600080fd5b5051151561012c57600080fd5b60018054600160a060020a03909216600160a060020a031990921691909117905550505050610cba806101606000396000f3006080604052600436106100da5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327ebe40a81146100df5780633f4ba83a1461010e578063454a2ab3146101375780635c975abb146101425780635fd8c7101461015757806376190f8f1461016c57806378bd79351461018157806383b5ff8b146101ce5780638456cb59146101f5578063878eb3681461020a5780638da5cb5b1461022257806396b5a75514610253578063c55d0f561461026b578063dd1b7a0f14610283578063f2fde38b14610298575b600080fd5b3480156100eb57600080fd5b5061010c600435602435604435606435600160a060020a03608435166102b9565b005b34801561011a57600080fd5b506101236103b1565b604080519115158252519081900360200190f35b61010c60043561042c565b34801561014e57600080fd5b50610123610478565b34801561016357600080fd5b5061010c610488565b34801561017857600080fd5b506101236104e5565b34801561018d57600080fd5b506101996004356104ee565b60408051600160a060020a03909616865260208601949094528484019290925260608401526080830152519081900360a00190f35b3480156101da57600080fd5b506101e3610584565b60408051918252519081900360200190f35b34801561020157600080fd5b5061012361058a565b34801561021657600080fd5b5061010c60043561060a565b34801561022e57600080fd5b50610237610673565b60408051600160a060020a039092168252519081900360200190f35b34801561025f57600080fd5b5061010c600435610682565b34801561027757600080fd5b506101e36004356106cc565b34801561028f57600080fd5b506102376106fe565b3480156102a457600080fd5b5061010c600160a060020a036004351661070d565b6102c1610c60565b6fffffffffffffffffffffffffffffffff851685146102df57600080fd5b6fffffffffffffffffffffffffffffffff841684146102fd57600080fd5b67ffffffffffffffff8316831461031357600080fd5b600154600160a060020a0316331461032a57600080fd5b610334828761075f565b60a06040519081016040528083600160a060020a03168152602001866fffffffffffffffffffffffffffffffff168152602001856fffffffffffffffffffffffffffffffff1681526020018467ffffffffffffffff1681526020014267ffffffffffffffff1681525090506103a986826107e7565b505050505050565b60008054600160a060020a031633146103c957600080fd5b60005460a060020a900460ff1615156103e157600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a150600190565b600154600090600160a060020a0316331461044657600080fd5b50600081815260036020526040902054600160a060020a0316610469823461093b565b506104748183610a61565b5050565b60005460a060020a900460ff1681565b60015460008054600160a060020a0392831692163314806104b1575033600160a060020a038316145b15156104bc57600080fd5b604051600160a060020a03831690303180156108fc02916000818181858888f150505050505050565b60045460ff1681565b6000818152600360205260408120819081908190819061050d81610acf565b151561051857600080fd5b80546001820154600290920154600160a060020a03909116986fffffffffffffffffffffffffffffffff8084169950700100000000000000000000000000000000909304909216965067ffffffffffffffff808216965068010000000000000000909104169350915050565b60025481565b60008054600160a060020a031633146105a257600080fd5b60005460a060020a900460ff16156105b957600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a150600190565b6000805460a060020a900460ff16151561062357600080fd5b600054600160a060020a0316331461063a57600080fd5b50600081815260036020526040902061065281610acf565b151561065d57600080fd5b8054610474908390600160a060020a0316610af0565b600054600160a060020a031681565b60008181526003602052604081209061069a82610acf565b15156106a557600080fd5b508054600160a060020a03163381146106bd57600080fd5b6106c78382610af0565b505050565b60008181526003602052604081206106e381610acf565b15156106ee57600080fd5b6106f781610b3a565b9392505050565b600154600160a060020a031681565b600054600160a060020a0316331461072457600080fd5b600160a060020a0381161561075c576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b50565b600154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015230602483015260448201859052915191909216916323b872dd91606480830192600092919082900301818387803b1580156107d357600080fd5b505af11580156103a9573d6000803e3d6000fd5b603c816060015167ffffffffffffffff161015151561080557600080fd5b60008281526003602090815260409182902083518154600160a060020a0390911673ffffffffffffffffffffffffffffffffffffffff1990911617815581840151600182018054858701516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000081029482166fffffffffffffffffffffffffffffffff19909316831790911693909317909155606080870151600290940180546080808a015167ffffffffffffffff90811668010000000000000000026fffffffffffffffff0000000000000000199190981667ffffffffffffffff1990931683171696909617909155865189815295860192909252848601929092529083015291517fa9c8dfcda5664a5a124c713e386da27de87432d5b668e79458501eb296389ba7929181900390910190a15050565b6000828152600360205260408120818080808061095786610acf565b151561096257600080fd5b61096b86610b3a565b94508488101561097a57600080fd5b8554600160a060020a0316935061099089610bca565b60008511156109e2576109a285610c17565b6040519093508386039250600160a060020a0385169083156108fc029084906000818181858888f193505050501580156109e0573d6000803e3d6000fd5b505b5060405184880390339082156108fc029083906000818181858888f19350505050158015610a14573d6000803e3d6000fd5b50604080518a815260208101879052338183015290517f4fcc30d90a842164dd58501ab874a101a3749c3d4747139cefe7c876f4ccebd29181900360600190a15092979650505050505050565b600154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152602482018590529151919092169163a9059cbb91604480830192600092919082900301818387803b1580156107d357600080fd5b6002015460006801000000000000000090910467ffffffffffffffff161190565b610af982610bca565b610b038183610a61565b6040805183815290517f2809c7e17bf978fbc7194c0a694b638c4215e9140cacc6c38ca36010b45697df9181900360200190a15050565b6002810154600090819068010000000000000000900467ffffffffffffffff16421115610b805750600282015468010000000000000000900467ffffffffffffffff1642035b600183015460028401546106f7916fffffffffffffffffffffffffffffffff80821692700100000000000000000000000000000000909204169067ffffffffffffffff1684610c23565b6000908152600360205260408120805473ffffffffffffffffffffffffffffffffffffffff19168155600181019190915560020180546fffffffffffffffffffffffffffffffff19169055565b60025461271091020490565b6000808080858510610c3757869350610c55565b878703925085858402811515610c4957fe5b05915081880190508093505b505050949350505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152905600a165627a7a723058208d1842c4569ecc7005642ae981f6c77b856b1d9a921f3792bdb4219144ae25e00029" + + kittyCoreAddressAndCut; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"},{\"name\":\"_seller\",\"type\":\"address\"}],\"name\":\"createAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"bid\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isSiringClockAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getAuction\",\"outputs\":[{\"name\":\"seller\",\"type\":\"address\"},{\"name\":\"startingPrice\",\"type\":\"uint256\"},{\"name\":\"endingPrice\",\"type\":\"uint256\"},{\"name\":\"duration\",\"type\":\"uint256\"},{\"name\":\"startedAt\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ownerCut\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"cancelAuctionWhenPaused\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"cancelAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getCurrentPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"nonFungibleContract\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_nftAddr\",\"type\":\"address\"},{\"name\":\"_cut\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"startingPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"endingPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"AuctionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"totalPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"winner\",\"type\":\"address\"}],\"name\":\"AuctionSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"AuctionCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Pause\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Unpause\",\"type\":\"event\"}]"; + logger.info("Siring Clock Auction"); + siringClockAuctionContractAddress = PublicMethed.deployContract(contractName, abi, code, + "", maxFeeLimit, 0L, consumeUserResourcePercent, null, deployKey, + deployAddress, blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(siringClockAuctionContractAddress, + blockingStubFull); + Assert.assertFalse(StringUtils.isEmpty(smartContract.getBytecode())); + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(deployAddress, blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(deployKey, blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @Test(enabled = true) + public void deployGeneScienceInterface() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(deployAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(deployKey, blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "GeneScienceInterface"; + String code = "608060405234801561001057600080fd5b5060dc8061001f6000396000f30060806040526004361060485763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630d9f5aed8114604d57806354c15b8214607a575b600080fd5b348015605857600080fd5b50606860043560243560443560a0565b60408051918252519081900360200190f35b348015608557600080fd5b50608c60ab565b604080519115158252519081900360200190f35b600292909101010490565b6001905600a165627a7a72305820d9550024d511527e5124d542daf0a0f3168b9bece6a238bcbccba8b61d3f0bdb0029"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"genes1\",\"type\":\"uint256\"},{\"name\":\"genes2\",\"type\":\"uint256\"},{\"name\":\"targetBlock\",\"type\":\"uint256\"}],\"name\":\"mixGenes\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isGeneScience\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]"; + logger.info("gene Science Interface"); + geneScienceInterfaceContractAddress = PublicMethed.deployContract(contractName, abi, code, + "", maxFeeLimit, + 0L, consumeUserResourcePercent, null, deployKey, deployAddress, blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(geneScienceInterfaceContractAddress, + blockingStubFull); + Assert.assertFalse(StringUtils.isEmpty(smartContract.getBytecode())); + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(deployAddress, blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(deployKey, blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @Test(enabled = true) + public void triggerToSetThreeContractAddressToKittyCore() { + //Set SaleAuctionAddress to kitty core. + String saleContractString = "\"" + Base58.encode58Check(saleClockAuctionContractAddress) + "\""; + txid = PublicMethed.triggerContract(kittyCoreContractAddress, "setSaleAuctionAddress(address)", + saleContractString, false, 0, 10000000L, deployAddress, deployKey, blockingStubFull); + logger.info(txid); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + //Assert.assertTrue(infoById.get().getReceipt().getStorageDelta() > 50); + + //Set SiringAuctionAddress to kitty core. + String siringContractString = "\"" + Base58.encode58Check(siringClockAuctionContractAddress) + + "\""; + txid = PublicMethed + .triggerContract(kittyCoreContractAddress, "setSiringAuctionAddress(address)", + siringContractString, false, 0, 10000000L, deployAddress, deployKey, blockingStubFull); + logger.info(txid); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + //Assert.assertTrue(infoById.get().getReceipt().getStorageDelta() > 50); + + //Set gen contract to kitty core + String genContractString = "\"" + Base58.encode58Check(geneScienceInterfaceContractAddress) + + "\""; + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "setGeneScienceAddress(address)", genContractString, + false, 0, 10000000L, deployAddress, deployKey, blockingStubFull); + logger.info(txid); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + //Assert.assertTrue(infoById.get().getReceipt().getStorageDelta() > 50); + + //Start the game. + txid = PublicMethed.triggerContract(kittyCoreContractAddress, "unpause()", "", false, 0, + 10000000L, deployAddress, deployKey, blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + logger.info("start the game " + txid); + + //Create one gen0 cat. + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "createGen0Auction(uint256)", "-1000000000000000", false, + 0, 100000000L, deployAddress, deployKey, blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "gen0CreatedCount()", "#", false, + 0, 100000000L, deployAddress, deployKey, blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + /* txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "name()","#",false,0,10000000,triggerAddress, + triggerKey,blockingStubFull); + logger.info("getname " + txid);*/ + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "getKitty(uint256)", "1", false, 0, 10000000, triggerAddress, + triggerKey, blockingStubFull); + logger.info("getKitty " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + + + String newCxoAddress = "\"" + Base58.encode58Check(triggerAddress) + + "\""; + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "setCOO(address)",newCxoAddress,false,0,10000000,deployAddress, + deployKey,blockingStubFull); + logger.info("COO " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "setCFO(address)",newCxoAddress,false,0,10000000,deployAddress, + deployKey,blockingStubFull); + logger.info("CFO " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "setCEO(address)",newCxoAddress,false,0,1000000,deployAddress, + deployKey,blockingStubFull); + logger.info("CEO " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + } + + @Test(enabled = true) + public void triggerUseTriggerEnergyUsage() { + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "createGen0Auction(uint256)", "0", false, + 0, 100000000L, triggerAddress, triggerKey, blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + Assert.assertTrue(infoById.get().getReceipt().getEnergyUsage() == 0); + Assert.assertTrue(infoById.get().getReceipt().getEnergyFee() > 10000); + Assert.assertTrue(infoById.get().getReceipt().getOriginEnergyUsage() > 10000); + Assert.assertTrue(infoById.get().getReceipt().getEnergyUsageTotal() + == infoById.get().getReceipt().getEnergyFee() / 100 + infoById.get().getReceipt() + .getOriginEnergyUsage()); + logger.info("before EnergyUsage is " + infoById.get().getReceipt().getEnergyUsage()); + logger.info("before EnergyFee is " + infoById.get().getReceipt().getEnergyFee()); + logger.info("before OriginEnergyUsage is " + infoById.get().getReceipt().getOriginEnergyUsage()); + logger.info("before EnergyTotal is " + infoById.get().getReceipt().getEnergyUsageTotal()); + + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(triggerAddress,100000000L, + 3,1,triggerKey,blockingStubFull)); + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "createGen0Auction(uint256)", "0", false, + 0, 100000000L, triggerAddress, triggerKey, blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + logger.info("after EnergyUsage is " + infoById.get().getReceipt().getEnergyUsage()); + logger.info("after EnergyFee is " + infoById.get().getReceipt().getEnergyFee()); + logger.info("after OriginEnergyUsage is " + infoById.get().getReceipt().getOriginEnergyUsage()); + logger.info("after EnergyTotal is " + infoById.get().getReceipt().getEnergyUsageTotal()); + Assert.assertTrue(infoById.get().getReceipt().getEnergyUsage() > 10000); + Assert.assertTrue(infoById.get().getReceipt().getEnergyFee() == 0); + Assert.assertTrue(infoById.get().getReceipt().getOriginEnergyUsage() > 10000); + Assert.assertTrue(infoById.get().getReceipt().getEnergyUsageTotal() == infoById.get().getReceipt().getEnergyUsage() + infoById.get().getReceipt().getOriginEnergyUsage()); + Assert.assertTrue(infoById.get().getReceipt().getEnergyUsage() == infoById.get().getReceipt().getOriginEnergyUsage()); + } + + + + + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario012.java b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario012.java new file mode 100644 index 00000000000..2839509671a --- /dev/null +++ b/src/test/java/stest/tron/wallet/contract/scenario/ContractScenario012.java @@ -0,0 +1,136 @@ +package stest.tron.wallet.contract.scenario; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.SmartContract; +import org.tron.protos.Protocol.TransactionInfo; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.Base58; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class ContractScenario012 { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + byte[] contractAddress = null; + String txid = ""; + Optional infoById = null; + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract012Address = ecKey1.getAddress(); + String contract012Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + ECKey ecKey2 = new ECKey(Utils.getRandom()); + byte[] receiverAddress = ecKey2.getAddress(); + String receiverKey = ByteArray.toHexString(ecKey2.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract012Key); + PublicMethed.printAddress(receiverKey); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract012Address,2000000000L,fromAddress, + testKey002,blockingStubFull)); + } + + @Test(enabled = true) + public void deployTransactionCoin() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract012Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 5000000L; + String contractName = "TransactionCoin"; + String code = "60806040526000805561029f806100176000396000f3006080604052600436106100985763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166312065fe0811461009d5780632e52d606146100b7578063483f5a7f146100cc5780634f8632ba146100e25780635896476c146101135780638b47145f14610128578063b6b55f2514610144578063f46771d91461014f578063ff18253b14610163575b600080fd5b6100a561019b565b60408051918252519081900360200190f35b3480156100c357600080fd5b506100a56101a0565b6100e0600160a060020a03600435166101a6565b005b3480156100ee57600080fd5b506100f76101df565b60408051600160a060020a039092168252519081900360200190f35b34801561011f57600080fd5b506100e06101ee565b6101306101f9565b604080519115158252519081900360200190f35b610130600435610217565b6100e0600160a060020a036004351661023a565b34801561016f57600080fd5b5061017861026c565b60408051600160a060020a03909316835260208301919091528051918290030190f35b303190565b60005481565b604051600160a060020a038216903480156108fc02916000818181858888f193505050501580156101db573d6000803e3d6000fd5b5050565b600154600160a060020a031681565b600080546001019055565b6040516000903390829060019082818181858883f194505050505090565b604051600090339083156108fc0290849084818181858888f19695505050505050565b604051600160a060020a0382169060009060059082818181858883f193505050501580156101db573d6000803e3d6000fd5b33803190915600a165627a7a72305820fd081d59bd77b97252e4a657177023ae7352e1fe802dd638ec6b9fa5df59d6110029"; + String abi = "[{\"constant\":false,\"inputs\":[],\"name\":\"getBalance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"n\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"sendToAddress\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"user\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"nPlusOne\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"depositOneCoin\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"money\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"sendToAddress2\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getSenderBalance\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"constructor\"}]"; + contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,contract012Key,contract012Address,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + Assert.assertTrue(smartContract.getAbi() != null); + } + + @Test(enabled = false) + public void triggerTransactionCoin() { + //When the contract has no money,transaction coin failed. + String receiveAddress = "\"" + Base58.encode58Check(receiverAddress) + + "\""; + txid = PublicMethed.triggerContract(contractAddress, + "sendToAddress2(address)", receiveAddress, false, + 0, 100000000L, contract012Address, contract012Key, blockingStubFull); + logger.info(txid); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 1); + logger.info("energytotal is " + infoById.get().getReceipt().getEnergyUsageTotal()); + Assert.assertTrue(infoById.get().getReceipt().getEnergyUsageTotal() > 0); + Assert.assertTrue(infoById.get().getFee() == infoById.get().getReceipt().getEnergyFee()); + Assert.assertFalse(infoById.get().getContractAddress().isEmpty()); + + //Send some trx to the contract account. + Assert.assertTrue(PublicMethed.sendcoin(contractAddress,100000L,contract012Address, + contract012Key,blockingStubFull)); + + + //This time, trigger the methed sendToAddress2 is OK. + txid = PublicMethed.triggerContract(contractAddress, + "sendToAddress2(address)", receiveAddress, false, + 0, 100000000L, contract012Address, contract012Key, blockingStubFull); + logger.info(txid); + infoById = PublicMethed.getTransactionInfoById(txid, blockingStubFull); + logger.info("result is " + infoById.get().getResultValue()); + Assert.assertTrue(infoById.get().getResultValue() == 0); + Assert.assertTrue(infoById.get().getReceipt().getEnergyUsageTotal() > 0); + Assert.assertTrue(infoById.get().getFee() == infoById.get().getReceipt().getEnergyFee()); + Assert.assertFalse(infoById.get().getContractAddress().isEmpty()); + } + + + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/fulltest/SuperWitnessAllowance.java b/src/test/java/stest/tron/wallet/fulltest/SuperWitnessAllowance.java index cdabcaddc16..d4001e9e6d6 100644 --- a/src/test/java/stest/tron/wallet/fulltest/SuperWitnessAllowance.java +++ b/src/test/java/stest/tron/wallet/fulltest/SuperWitnessAllowance.java @@ -110,7 +110,8 @@ public void testCreate130Witness() { String lowBalTest = ByteArray.toHexString(ecKey.getPrivKeyBytes()); logger.info(lowBalTest); Assert.assertTrue(sendcoin(lowBalAddress, costForCreateWitness, fromAddress, testKey002)); - Assert.assertTrue(PublicMethed.freezeBalance(lowBalAddress,1000000,3,lowBalTest,blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalance(lowBalAddress,1000000, + 3,lowBalTest,blockingStubFull)); Assert.assertTrue(createWitness(lowBalAddress, createUrl, lowBalTest)); String voteStr = Base58.encode58Check(PublicMethed.getFinalAddress(lowBalTest)); HashMap smallVoteMap = new HashMap(); @@ -134,17 +135,18 @@ public void testQueryAllowance() { WitnessList witnessList = result.get(); Integer allowanceNum = 0; for (Integer i = 0; i < witnessList.getWitnessesCount(); i++) { -/* witnessList.getWitnesses(i).getAddress(); + /* witnessList.getWitnesses(i).getAddress(); witnessList.getWitnesses(i).getAddress(); witnessList.getWitnesses(i).getAddress(); witnessList.getWitnesses(i).getAddress();*/ - ByteString addressBS = witnessList.getWitnesses(i).getAddress(); - Account request = Account.newBuilder().setAddress(addressBS).build(); + ByteString addressBs = witnessList.getWitnesses(i).getAddress(); + Account request = Account.newBuilder().setAddress(addressBs).build(); request = blockingStubFull.getAccount(request); if (request.getAllowance() > 0) { allowanceNum++; } - logger.info("Account " + Integer.toString(i) + " allowance is " + Long.toString(request.getAllowance())); + logger.info("Account " + Integer.toString(i) + " allowance is " + Long.toString(request + .getAllowance())); } logger.info("Allowance num is " + Integer.toString(allowanceNum)); @@ -319,7 +321,7 @@ public Boolean voteWitness(HashMap witness, byte[] addRess, Stri } catch (Exception ex) { ex.printStackTrace(); } - ECKey ecKey = temKey; + final ECKey ecKey = temKey; Account beforeVote = PublicMethed.queryAccount(priKey,blockingStubFull); //Account beforeVote = queryAccount(ecKey, blockingStubFull); Long beforeVoteNum = 0L; @@ -331,7 +333,7 @@ public Boolean voteWitness(HashMap witness, byte[] addRess, Stri builder.setOwnerAddress(ByteString.copyFrom(addRess)); for (String addressBase58 : witness.keySet()) { String value = witness.get(addressBase58); - long count = Long.parseLong(value); + final long count = Long.parseLong(value); Contract.VoteWitnessContract.Vote.Builder voteBuilder = Contract.VoteWitnessContract.Vote .newBuilder(); byte[] address = WalletClient.decodeFromBase58Check(addressBase58); diff --git a/src/test/java/stest/tron/wallet/fulltest/TvmContract.java b/src/test/java/stest/tron/wallet/fulltest/TvmContract.java new file mode 100644 index 00000000000..8e3bf3f4d3f --- /dev/null +++ b/src/test/java/stest/tron/wallet/fulltest/TvmContract.java @@ -0,0 +1,147 @@ +package stest.tron.wallet.fulltest; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class TvmContract { + + //testng001、testng002、testng003、testng004 + private final String testKey002 = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] contract008Address = ecKey1.getAddress(); + String contract008Key = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = true) + public void beforeClass() { + PublicMethed.printAddress(contract008Key); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(contract008Address,500000000L,fromAddress, + testKey002,blockingStubFull)); + logger.info(Long.toString(PublicMethed.queryAccount(contract008Key,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(contract008Address, 1000000L, + 3,1,contract008Key,blockingStubFull)); + Assert.assertTrue(PublicMethed.buyStorage(50000000L,contract008Address,contract008Key, + blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalance(contract008Address,5000000L, + 3,contract008Key,blockingStubFull)); + + } + + @Test(enabled = false) + public void deployErc721CryptoKitties() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(contract008Address, + blockingStubFull); + Long energyLimit = accountResource.getEnergyLimit(); + Long storageLimit = accountResource.getStorageLimit(); + Long energyUsage = accountResource.getEnergyUsed(); + Long storageUsage = accountResource.getStorageUsed(); + + logger.info("before energy limit is " + Long.toString(energyLimit)); + logger.info("before energy usage is " + Long.toString(energyUsage)); + logger.info("before storage limit is " + Long.toString(storageLimit)); + logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 50000000L; + String contractName = "ERC721"; + String code = "606060409081526002805460a060020a60ff02191690556101c090519081016040908152603c82526078602083015261012c9082015261025860608201526107086080820152610e1060a0820152611c2060c082015261384060e082015261708061010082015261e100610120820152620151806101408201526202a3006101608201526205460061018082015262093a806101a0820152620000a790600390600e620004e4565b50600f60055566071afd498d0000600e553415620000c457600080fd5b6002805460008054600160a060020a033316600160a060020a03199182168117835560a060020a60ff02199093167401000000000000000000000000000000000000000017169091179091556200012f90808060001981640100000000620028f06200013682021704565b5062000649565b6000806200014362000587565b600063ffffffff891689146200015857600080fd5b63ffffffff881688146200016b57600080fd5b61ffff871687146200017c57600080fd5b600287049250600d8361ffff1611156200019557600d92505b61010060405190810160409081528782526001604060020a0342166020830152600090820181905263ffffffff808c1660608401528a16608083015260a082015261ffff80851660c0830152881660e082015260068054919350600191808301620002018382620005cb565b6000928352602090922085916002020181518155602082015160018201805467ffffffffffffffff19166001604060020a039290921691909117905560408201518160010160086101000a8154816001604060020a0302191690836001604060020a0316021790555060608201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060c082015181600101601c6101000a81548161ffff021916908361ffff16021790555060e08201516001909101805461ffff929092167e0100000000000000000000000000000000000000000000000000000000000002600160f060020a039092169190911790555003905063ffffffff811681146200035e57600080fd5b7f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad58582846060015163ffffffff16856080015163ffffffff168651604051600160a060020a03909516855260208501939093526040808501929092526060840152608083019190915260a0909101905180910390a1620003ef60008683640100000000620025e0620003fb82021704565b98975050505050505050565b600160a060020a03808316600081815260086020908152604080832080546001019055858352600790915290208054600160a060020a03191690911790558316156200048f57600160a060020a03831660009081526008602090815260408083208054600019019055838352600a82528083208054600160a060020a03199081169091556009909252909120805490911690555b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef838383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a1505050565b600283019183908215620005755791602002820160005b838211156200054157835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302620004fb565b8015620005735782816101000a81549063ffffffff021916905560040160208160030104928301926001030262000541565b505b5062000583929150620005ff565b5090565b6101006040519081016040908152600080835260208301819052908201819052606082018190526080820181905260a0820181905260c0820181905260e082015290565b815481835581811511620005fa57600202816002028360005260206000209182019101620005fa919062000626565b505050565b6200062391905b808211156200058357805463ffffffff1916815560010162000606565b90565b6200062391905b808211156200058357600080825560018201556002016200062d565b61309380620006596000396000f3006060604052600436106102a55763ffffffff60e060020a60003504166301ffc9a781146102dd5780630519ce79146103295780630560ff441461035857806305e45546146103f157806306fdde0314610416578063095ea7b3146104295780630a0f81681461044b5780630e583df01461045e57806314001f4c1461047157806318160ddd14610490578063183a7947146104a35780631940a936146104b657806319c2f201146104cc57806321717ebf146104df57806323b872dd146104f257806324e7a38a1461051a57806327d7874c146105395780632ba73c15146105585780633d7d3f5a146105775780633f4ba83a1461059657806346116e6f146105a957806346d22c70146105bf578063481af3d3146105d85780634ad8c938146105ee5780634b85fd551461060d5780634dfff04f146106235780634e0a33791461064557806356129134146106645780635663896e146106865780635c975abb1461069c5780635fd8c710146106af5780636352211e146106c2578063680eba27146106d85780636af04a57146106eb5780636fbde40d146106fe57806370a082311461071d578063715879881461073c5780637a7d49371461075b5780638456cb591461076e5780638462151c1461078157806388c2a0bf146107f357806391876e571461080957806395d89b411461081c5780639d6fac6f1461082f578063a45f4bfc1461085e578063a9059cbb14610874578063b047fb5014610896578063b0c35c05146108a9578063bc4006f5146108bc578063c3bea9af146108cf578063d3e6f49f146108e5578063defb9584146108fb578063e17b25af1461090e578063e6cbe3511461092d578063e98b7f4d14610940578063ed60ade6146109ae578063f1ca9410146109bc578063f2b47d52146109cf578063f7d8c883146109e2575b600b5433600160a060020a03908116911614806102d05750600c5433600160a060020a039081169116145b15156102db57600080fd5b005b34156102e857600080fd5b6103157fffffffff00000000000000000000000000000000000000000000000000000000600435166109f0565b604051901515815260200160405180910390f35b341561033457600080fd5b61033c610c77565b604051600160a060020a03909116815260200160405180910390f35b341561036357600080fd5b61037a600480359060248035908101910135610c86565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156103b657808201518382015260200161039e565b50505050905090810190601f1680156103e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103fc57600080fd5b610404610d63565b60405190815260200160405180910390f35b341561042157600080fd5b61037a610d69565b341561043457600080fd5b6102db600160a060020a0360043516602435610da0565b341561045657600080fd5b61033c610e2a565b341561046957600080fd5b610404610e39565b341561047c57600080fd5b6102db600160a060020a0360043516610e44565b341561049b57600080fd5b610404610ef1565b34156104ae57600080fd5b610404610efc565b34156104c157600080fd5b610315600435610f02565b34156104d757600080fd5b610404610f47565b34156104ea57600080fd5b61033c610f4e565b34156104fd57600080fd5b6102db600160a060020a0360043581169060243516604435610f5d565b341561052557600080fd5b6102db600160a060020a0360043516610fe4565b341561054457600080fd5b6102db600160a060020a0360043516611091565b341561056357600080fd5b6102db600160a060020a03600435166110e3565b341561058257600080fd5b6102db600435602435604435606435611135565b34156105a157600080fd5b6102db611214565b34156105b457600080fd5b61033c6004356112ac565b34156105ca57600080fd5b6103156004356024356112c7565b34156105e357600080fd5b61033c600435611347565b34156105f957600080fd5b6102db600435602435604435606435611362565b341561061857600080fd5b6102db600435611428565b341561062e57600080fd5b6102db600160a060020a0360043516602435611448565b341561065057600080fd5b6102db600160a060020a03600435166114a2565b341561066f57600080fd5b6102db600435600160a060020a03602435166114f4565b341561069157600080fd5b6102db600435611560565b34156106a757600080fd5b6103156115c8565b34156106ba57600080fd5b6102db6115d8565b34156106cd57600080fd5b61033c600435611649565b34156106e357600080fd5b61040461166d565b34156106f657600080fd5b61033c611673565b341561070957600080fd5b6102db600160a060020a0360043516611682565b341561072857600080fd5b610404600160a060020a036004351661172f565b341561074757600080fd5b6102db600160a060020a036004351661174a565b341561076657600080fd5b6104046117d8565b341561077957600080fd5b6102db6117de565b341561078c57600080fd5b6107a0600160a060020a036004351661186a565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156107df5780820151838201526020016107c7565b505050509050019250505060405180910390f35b34156107fe57600080fd5b61040460043561194b565b341561081457600080fd5b6102db611c1b565b341561082757600080fd5b61037a611d0e565b341561083a57600080fd5b610845600435611d45565b60405163ffffffff909116815260200160405180910390f35b341561086957600080fd5b61033c600435611d72565b341561087f57600080fd5b6102db600160a060020a0360043516602435611d8d565b34156108a157600080fd5b61033c611e30565b34156108b457600080fd5b610404611e3f565b34156108c757600080fd5b61033c611e45565b34156108da57600080fd5b6102db600435611e54565b34156108f057600080fd5b610315600435611f47565b341561090657600080fd5b610404612010565b341561091957600080fd5b6102db600160a060020a0360043516612016565b341561093857600080fd5b61033c612053565b341561094b57600080fd5b610956600435612062565b6040519915158a5297151560208a01526040808a01979097526060890195909552608088019390935260a087019190915260c086015260e0850152610100840152610120830191909152610140909101905180910390f35b6102db6004356024356121c3565b34156109c757600080fd5b610404612316565b34156109da57600080fd5b61033c61231c565b6102db60043560243561232b565b60006040517f737570706f727473496e7465726661636528627974657334290000000000000081526019016040518091039020600160e060020a03191682600160e060020a0319161480610c6f57506040517f746f6b656e4d657461646174612875696e743235362c737472696e67290000008152601d0160405180910390206040517f746f6b656e734f664f776e657228616464726573732900000000000000000000815260160160405180910390206040517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f7432353629000000000000000000000000000000000000000000000000000000602082015260250160405180910390206040517f7472616e7366657228616464726573732c75696e743235362900000000000000815260190160405180910390206040517f617070726f766528616464726573732c75696e74323536290000000000000000815260180160405180910390206040517f6f776e65724f662875696e743235362900000000000000000000000000000000815260100160405180910390206040517f62616c616e63654f662861646472657373290000000000000000000000000000815260120160405180910390206040517f746f74616c537570706c792829000000000000000000000000000000000000008152600d0160405180910390206040517f73796d626f6c2829000000000000000000000000000000000000000000000000815260080160405180910390206040517f6e616d652829000000000000000000000000000000000000000000000000000081526006016040518091039020181818181818181818600160e060020a03191682600160e060020a031916145b90505b919050565b600154600160a060020a031681565b610c8e612fa0565b610c96612fb2565b600d54600090600160a060020a03161515610cb057600080fd5b600d54600160a060020a031663cb4799f2878787600060405160a0015260405160e060020a63ffffffff861602815260048101848152604060248301908152604483018490529091606401848480828437820191505094505050505060a060405180830381600087803b1515610d2557600080fd5b6102c65a03f11515610d3657600080fd5b50505060405180608001805160209091016040529092509050610d59828261251d565b9695505050505050565b60115481565b60408051908101604052600d81527f43727970746f4b69747469657300000000000000000000000000000000000000602082015281565b60025460a060020a900460ff1615610db757600080fd5b610dc13382612572565b1515610dcc57600080fd5b610dd68183612592565b7f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925338383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a15050565b600054600160a060020a031681565b662386f26fc1000081565b6000805433600160a060020a03908116911614610e6057600080fd5b5080600160a060020a0381166376190f8f6000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515610ea857600080fd5b6102c65a03f11515610eb957600080fd5b505050604051805190501515610ece57600080fd5b600c8054600160a060020a031916600160a060020a039290921691909117905550565b600654600019015b90565b600f5481565b6000808211610f1057600080fd5b6006805483908110610f1e57fe5b600091825260209091206002909102016001015460c060020a900463ffffffff16151592915050565b6201518081565b600c54600160a060020a031681565b60025460a060020a900460ff1615610f7457600080fd5b600160a060020a0382161515610f8957600080fd5b30600160a060020a031682600160a060020a031614151515610faa57600080fd5b610fb433826125c0565b1515610fbf57600080fd5b610fc98382612572565b1515610fd457600080fd5b610fdf8383836125e0565b505050565b6000805433600160a060020a0390811691161461100057600080fd5b5080600160a060020a0381166354c15b826000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561104857600080fd5b6102c65a03f1151561105957600080fd5b50505060405180519050151561106e57600080fd5b60108054600160a060020a031916600160a060020a039290921691909117905550565b60005433600160a060020a039081169116146110ac57600080fd5b600160a060020a03811615156110c157600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b60005433600160a060020a039081169116146110fe57600080fd5b600160a060020a038116151561111357600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b60025460a060020a900460ff161561114c57600080fd5b6111563385612572565b151561116157600080fd5b61116a84610f02565b1561117457600080fd5b600b5461118b908590600160a060020a0316612592565b600b54600160a060020a03166327ebe40a858585853360405160e060020a63ffffffff88160281526004810195909552602485019390935260448401919091526064830152600160a060020a0316608482015260a401600060405180830381600087803b15156111fa57600080fd5b6102c65a03f1151561120b57600080fd5b50505050505050565b60005433600160a060020a0390811691161461122f57600080fd5b60025460a060020a900460ff16151561124757600080fd5b600b54600160a060020a0316151561125e57600080fd5b600c54600160a060020a0316151561127557600080fd5b601054600160a060020a0316151561128c57600080fd5b601354600160a060020a0316156112a257600080fd5b6112aa6126c8565b565b600a60205260009081526040902054600160a060020a031681565b600080808085116112d757600080fd5b600084116112e457600080fd5b60068054869081106112f257fe5b9060005260206000209060020201915060068481548110151561131157fe5b9060005260206000209060020201905061132d8286838761271b565b801561133e575061133e848661289b565b95945050505050565b600960205260009081526040902054600160a060020a031681565b60025460a060020a900460ff161561137957600080fd5b6113833385612572565b151561138e57600080fd5b61139784611f47565b15156113a257600080fd5b600c546113b9908590600160a060020a0316612592565b600c54600160a060020a03166327ebe40a858585853360405160e060020a63ffffffff88160281526004810195909552602485019390935260448401919091526064830152600160a060020a0316608482015260a401600060405180830381600087803b15156111fa57600080fd5b60025433600160a060020a0390811691161461144357600080fd5b600e55565b60025460a060020a900460ff161561145f57600080fd5b6114693382612572565b151561147457600080fd5b6000908152600a602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b60005433600160a060020a039081169116146114bd57600080fd5b600160a060020a03811615156114d257600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b60025460009033600160a060020a0390811691161461151257600080fd5b5080600160a060020a03811615156115325750600254600160a060020a03165b601154611388901061154357600080fd5b60118054600101905561155a6000808086856128f0565b50505050565b60025433600160a060020a039081169116148061158b575060005433600160a060020a039081169116145b806115a4575060015433600160a060020a039081169116145b15156115af57600080fd5b60035463ffffffff1681106115c357600080fd5b600555565b60025460a060020a900460ff1681565b600154600090819033600160a060020a039081169116146115f857600080fd5b30600160a060020a0316319150600e54600f546001010290508082111561164557600154600160a060020a031681830380156108fc0290604051600060405180830381858888f150505050505b5050565b600081815260076020526040902054600160a060020a0316801515610c7257600080fd5b61afc881565b601354600160a060020a031681565b6000805433600160a060020a0390811691161461169e57600080fd5b5080600160a060020a0381166385b861886000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156116e657600080fd5b6102c65a03f115156116f757600080fd5b50505060405180519050151561170c57600080fd5b600b8054600160a060020a031916600160a060020a039290921691909117905550565b600160a060020a031660009081526008602052604090205490565b60005433600160a060020a0390811691161461176557600080fd5b60025460a060020a900460ff16151561177d57600080fd5b60138054600160a060020a031916600160a060020a0383161790557f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa44619930581604051600160a060020a03909116815260200160405180910390a150565b60055481565b60025433600160a060020a0390811691161480611809575060005433600160a060020a039081169116145b80611822575060015433600160a060020a039081169116145b151561182d57600080fd5b60025460a060020a900460ff161561184457600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055565b611872612fa0565b600061187c612fa0565b600080600061188a8761172f565b94508415156118ba5760006040518059106118a25750595b90808252806020026020018201604052509550611941565b846040518059106118c85750595b908082528060200260200182016040525093506118e3610ef1565b925060009150600190505b82811161193d57600081815260076020526040902054600160a060020a0388811691161415611935578084838151811061192457fe5b602090810290910101526001909101905b6001016118ee565b8395505b5050505050919050565b600080600080600080600080600260149054906101000a900460ff1615151561197357600080fd5b600680548a90811061198157fe5b60009182526020909120600290910201600181015490975067ffffffffffffffff1615156119ae57600080fd5b611a438761010060405190810160409081528254825260019092015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152612b9c565b1515611a4e57600080fd5b60018701546006805460c060020a90920463ffffffff1697509087908110611a7257fe5b600091825260209091206001808a015460029093029091019081015490965061ffff60f060020a92839004811696509190041684901115611ac057600185015460f060020a900461ffff1693505b6010548754865460018a0154600160a060020a0390931692630d9f5aed92919068010000000000000000900467ffffffffffffffff166000190160006040516020015260405160e060020a63ffffffff86160281526004810193909352602483019190915267ffffffffffffffff166044820152606401602060405180830381600087803b1515611b5057600080fd5b6102c65a03f11515611b6157600080fd5b505050604051805160008b81526007602052604090205460018a810154929650600160a060020a039091169450611bb092508b9160c060020a900463ffffffff1690870161ffff1686866128f0565b6001880180547bffffffff00000000000000000000000000000000000000000000000019169055600f8054600019019055600e54909150600160a060020a0333169080156108fc0290604051600060405180830381858888f150939c9b505050505050505050505050565b60025433600160a060020a0390811691161480611c46575060005433600160a060020a039081169116145b80611c5f575060015433600160a060020a039081169116145b1515611c6a57600080fd5b600b54600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b1515611ca957600080fd5b6102c65a03f11515611cba57600080fd5b5050600c54600160a060020a03169050635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b1515611cfd57600080fd5b6102c65a03f11515610fdf57600080fd5b60408051908101604052600281527f434b000000000000000000000000000000000000000000000000000000000000602082015281565b600381600e8110611d5257fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b600760205260009081526040902054600160a060020a031681565b60025460a060020a900460ff1615611da457600080fd5b600160a060020a0382161515611db957600080fd5b30600160a060020a031682600160a060020a031614151515611dda57600080fd5b600b54600160a060020a0383811691161415611df557600080fd5b600c54600160a060020a0383811691161415611e1057600080fd5b611e1a3382612572565b1515611e2557600080fd5b6116453383836125e0565b600254600160a060020a031681565b600e5481565b600d54600160a060020a031681565b60025460009033600160a060020a03908116911614611e7257600080fd5b60125461afc89010611e8357600080fd5b611e92600080600085306128f0565b600b54909150611eac908290600160a060020a0316612592565b600b54600160a060020a03166327ebe40a82611ec6612bd4565b6000620151803060405160e060020a63ffffffff88160281526004810195909552602485019390935260448401919091526064830152600160a060020a0316608482015260a401600060405180830381600087803b1515611f2657600080fd5b6102c65a03f11515611f3757600080fd5b5050601280546001019055505050565b600080808311611f5657600080fd5b6006805484908110611f6457fe5b906000526020600020906002020190506120098161010060405190810160409081528254825260019092015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152612c82565b9392505050565b61138881565b60005433600160a060020a0390811691161461203157600080fd5b600d8054600160a060020a031916600160a060020a0392909216919091179055565b600b54600160a060020a031681565b600080600080600080600080600080600060068c81548110151561208257fe5b906000526020600020906002020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159a50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161115995080600101601c9054906101000a900461ffff1661ffff1698508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160189054906101000a900463ffffffff1663ffffffff1696508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1695508060010160109054906101000a900463ffffffff1663ffffffff1694508060010160149054906101000a900463ffffffff1663ffffffff16935080600101601e9054906101000a900461ffff1661ffff16925080600001549150509193959799509193959799565b60025460009060a060020a900460ff16156121dd57600080fd5b6121e73383612572565b15156121f257600080fd5b6121fb82611f47565b151561220657600080fd5b6122108284612cb9565b151561221b57600080fd5b600c54600160a060020a031663c55d0f568460006040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561226c57600080fd5b6102c65a03f1151561227d57600080fd5b5050506040518051600e549092508201341015905061229b57600080fd5b600c54600e54600160a060020a039091169063454a2ab39034038560405160e060020a63ffffffff851602815260048101919091526024016000604051808303818588803b15156122eb57600080fd5b6125ee5a03f115156122fc57600080fd5b50505050610fdf8263ffffffff168463ffffffff16612d08565b60125481565b601054600160a060020a031681565b600254600090819060a060020a900460ff161561234757600080fd5b600e5434101561235657600080fd5b6123603385612572565b151561236b57600080fd5b612375838561289b565b151561238057600080fd5b600680548590811061238e57fe5b906000526020600020906002020191506124338261010060405190810160409081528254825260019092015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152612c82565b151561243e57600080fd5b600680548490811061244c57fe5b906000526020600020906002020190506124f18161010060405190810160409081528254825260019092015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152612c82565b15156124fc57600080fd5b6125088285838661271b565b151561251357600080fd5b61155a8484612d08565b612525612fa0565b61252d612fa0565b6000808460405180591061253e5750595b818152601f19601f8301168101602001604052905092505060208201905084612568828287612e72565b5090949350505050565b600090815260076020526040902054600160a060020a0391821691161490565b6000918252600960205260409091208054600160a060020a031916600160a060020a03909216919091179055565b600090815260096020526040902054600160a060020a0391821691161490565b600160a060020a03808316600081815260086020908152604080832080546001019055858352600790915290208054600160a060020a031916909117905583161561267357600160a060020a03831660009081526008602090815260408083208054600019019055838352600a82528083208054600160a060020a03199081169091556009909252909120805490911690555b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef838383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a1505050565b60005433600160a060020a039081169116146126e357600080fd5b60025460a060020a900460ff1615156126fb57600080fd5b6002805474ff000000000000000000000000000000000000000019169055565b60008184141561272d57506000612893565b6001850154608060020a900463ffffffff1682148061275c5750600185015460a060020a900463ffffffff1682145b1561276957506000612893565b6001830154608060020a900463ffffffff168414806127985750600183015460a060020a900463ffffffff1684145b156127a557506000612893565b6001830154608060020a900463ffffffff1615806127d257506001850154608060020a900463ffffffff16155b156127df57506001612893565b60018581015490840154608060020a9182900463ffffffff9081169290910416148061282a575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b1561283757506000612893565b6001808601549084015460a060020a900463ffffffff908116608060020a90920416148061288257506001858101549084015460a060020a9182900463ffffffff9081169290910416145b1561288f57506000612893565b5060015b949350505050565b6000818152600760205260408082205484835290822054600160a060020a0391821691168082148061133e57506000858152600a6020526040902054600160a060020a03908116908316149250505092915050565b6000806128fb612fdb565b600063ffffffff8916891461290f57600080fd5b63ffffffff8816881461292157600080fd5b61ffff8716871461293157600080fd5b600287049250600d8361ffff16111561294957600d92505b610100604051908101604090815287825267ffffffffffffffff42166020830152600090820181905263ffffffff808c1660608401528a16608083015260a082015261ffff80851660c0830152881660e0820152600680549193506001918083016129b4838261301f565b6000928352602090922085916002020181518155602082015160018201805467ffffffffffffffff191667ffffffffffffffff9290921691909117905560408201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060c082015181600101601c6101000a81548161ffff021916908361ffff16021790555060e08201516001909101805461ffff9290921660f060020a027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555003905063ffffffff81168114612b0f57600080fd5b7f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad58582846060015163ffffffff16856080015163ffffffff168651604051600160a060020a03909516855260208501939093526040808501929092526060840152608083019190915260a0909101905180910390a1612b90600086836125e0565b98975050505050505050565b60008160a0015163ffffffff1615801590610c6f57504367ffffffffffffffff16826040015167ffffffffffffffff16111592915050565b600b5460009081908190600160a060020a031663eac9d94c82604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515612c2257600080fd5b6102c65a03f11515612c3357600080fd5b50505060405180519250506fffffffffffffffffffffffffffffffff82168214612c5c57600080fd5b50600281048101662386f26fc10000811015612c7c5750662386f26fc100005b92915050565b60008160a0015163ffffffff16158015610c6f57504367ffffffffffffffff16826040015167ffffffffffffffff16111592915050565b6000806000600685815481101515612ccd57fe5b90600052602060002090600202019150600684815481101515612cec57fe5b9060005260206000209060020201905061133e8286838761271b565b600080600683815481101515612d1a57fe5b90600052602060002090600202019150600684815481101515612d3957fe5b600091825260209091206002909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff8716021790559050612d8982612eb7565b612d9281612eb7565b6000848152600a602090815260408083208054600160a060020a031990811690915586845281842080549091169055600f8054600190810190915587845260079092529182902054908301547f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b8092600160a060020a0390921691879187916801000000000000000090910467ffffffffffffffff1690518085600160a060020a0316600160a060020a031681526020018481526020018381526020018267ffffffffffffffff16815260200194505050505060405180910390a150505050565b60005b60208210612e985782518452602084019350602083019250602082039150612e75565b6001826020036101000a03905080198351168185511617909352505050565b600554600182015443919060039060e060020a900461ffff16600e8110612eda57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515612f0557fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600d60e060020a90910461ffff161015612f9d576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b60206040519081016040526000815290565b60806040519081016040526004815b60008152600019919091019060200181612fc15790505090565b6101006040519081016040908152600080835260208301819052908201819052606082018190526080820181905260a0820181905260c0820181905260e082015290565b815481835581811511610fdf57600083815260209020610fdf91610ef99160029182028101918502015b808211156130635760008082556001820155600201613049565b50905600a165627a7a72305820a6465fc1ce7ab1a92906ff7206b23d80a21bbd50b85b4bde6a91f8e6b2e3edde0029"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cfoAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_preferredTransport\",\"type\":\"string\"}],\"name\":\"tokenMetadata\",\"outputs\":[{\"name\":\"infoUrl\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"promoCreatedCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ceoAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_STARTING_PRICE\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setSiringAuctionAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pregnantKitties\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"}],\"name\":\"isPregnant\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_AUCTION_DURATION\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"siringAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setGeneScienceAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCEO\",\"type\":\"address\"}],\"name\":\"setCEO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCOO\",\"type\":\"address\"}],\"name\":\"setCOO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"}],\"name\":\"createSaleAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sireAllowedToAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"canBreedWith\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"kittyIndexToApproved\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"}],\"name\":\"createSiringAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"setAutoBirthFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_addr\",\"type\":\"address\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"approveSiring\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCFO\",\"type\":\"address\"}],\"name\":\"setCFO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_genes\",\"type\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"createPromoKitty\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"secs\",\"type\":\"uint256\"}],\"name\":\"setSecondsPerBlock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_CREATION_LIMIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"newContractAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setSaleAuctionAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"count\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_v2Address\",\"type\":\"address\"}],\"name\":\"setNewAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"secondsPerBlock\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"tokensOfOwner\",\"outputs\":[{\"name\":\"ownerTokens\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"}],\"name\":\"giveBirth\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawAuctionBalances\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"cooldowns\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"kittyIndexToOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cooAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"autoBirthFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"erc721Metadata\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_genes\",\"type\":\"uint256\"}],\"name\":\"createGen0Auction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"}],\"name\":\"isReadyToBreed\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"PROMO_CREATION_LIMIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_contractAddress\",\"type\":\"address\"}],\"name\":\"setMetadataAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"saleAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getKitty\",\"outputs\":[{\"name\":\"isGestating\",\"type\":\"bool\"},{\"name\":\"isReady\",\"type\":\"bool\"},{\"name\":\"cooldownIndex\",\"type\":\"uint256\"},{\"name\":\"nextActionAt\",\"type\":\"uint256\"},{\"name\":\"siringWithId\",\"type\":\"uint256\"},{\"name\":\"birthTime\",\"type\":\"uint256\"},{\"name\":\"matronId\",\"type\":\"uint256\"},{\"name\":\"sireId\",\"type\":\"uint256\"},{\"name\":\"generation\",\"type\":\"uint256\"},{\"name\":\"genes\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_sireId\",\"type\":\"uint256\"},{\"name\":\"_matronId\",\"type\":\"uint256\"}],\"name\":\"bidOnSiringAuction\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gen0CreatedCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"geneScience\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"breedWithAuto\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"matronId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"sireId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"cooldownEndBlock\",\"type\":\"uint256\"}],\"name\":\"Pregnant\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"kittyId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"matronId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"sireId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"genes\",\"type\":\"uint256\"}],\"name\":\"Birth\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"newContract\",\"type\":\"address\"}],\"name\":\"ContractUpgrade\",\"type\":\"event\"}]"; + + Long m = 0L; + Long freeNet; + accountResource = PublicMethed.getAccountResource(contract008Address,blockingStubFull); + Long net = accountResource.getFreeNetUsed(); + Account account = PublicMethed.queryAccount(contract008Key,blockingStubFull); + Long netUsed = account.getNetUsage(); + logger.info("before net used is " + Long.toString(netUsed)); + logger.info("before balance is " + account.getBalance()); + + for (Integer i = 0; i < 1; i++) { + byte[] contractAddress = PublicMethed.deployContract("1",abi,code,"", + 30000000L,0L, 1,null,contract008Key,contract008Address,blockingStubFull); + accountResource = PublicMethed.getAccountResource(contract008Address,blockingStubFull); + freeNet = accountResource.getFreeNetUsed(); + energyUsage = accountResource.getEnergyUsed(); + logger.info( + "Time " + Integer.toString(i) + ": energy usage is " + Long.toString(energyUsage - m)); + logger.info("Time " + Integer.toString(i) + ": free net used is " + Long + .toString(freeNet - net)); + account = PublicMethed.queryAccount(contract008Key,blockingStubFull); + logger.info("after balance is " + account.getBalance()); + netUsed = account.getNetUsage(); + logger.info("after net used is " + Long.toString(netUsed)); + net = freeNet; + m = energyUsage; + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + //SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + + //Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + //Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + //Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + accountResource = PublicMethed.getAccountResource(contract008Address,blockingStubFull); + energyLimit = accountResource.getEnergyLimit(); + storageLimit = accountResource.getStorageLimit(); + energyUsage = accountResource.getEnergyUsed(); + storageUsage = accountResource.getStorageUsed(); + //Assert.assertTrue(storageUsage > 0); + //Assert.assertTrue(storageLimit > 0); + //Assert.assertTrue(energyLimit > 0); + //Assert.assertTrue(energyUsage > 0); + + logger.info("after energy limit is " + Long.toString(energyLimit)); + logger.info("after energy usage is " + Long.toString(energyUsage)); + logger.info("after storage limit is " + Long.toString(storageLimit)); + logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/fulltest/createAddressAndKey.java b/src/test/java/stest/tron/wallet/fulltest/createAddressAndKey.java index 28d44b452a5..71230d7fc11 100644 --- a/src/test/java/stest/tron/wallet/fulltest/createAddressAndKey.java +++ b/src/test/java/stest/tron/wallet/fulltest/createAddressAndKey.java @@ -1,14 +1,16 @@ package stest.tron.wallet.fulltest; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; -//import java.io.*; -import java.io.File; import java.util.HashMap; import lombok.extern.slf4j.Slf4j; import org.spongycastle.util.encoders.Base64; @@ -21,18 +23,7 @@ import org.tron.common.utils.Utils; import org.tron.core.Wallet; import stest.tron.wallet.common.client.Parameter.CommonConstant; -import stest.tron.wallet.common.client.utils.Base58; -import java.io.BufferedWriter; -import java.io.FileWriter; import stest.tron.wallet.common.client.utils.PublicMethed; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonArray; -import com.google.gson.Gson; -import java.util.List; -import java.util.ArrayList; - - @Slf4j public class createAddressAndKey { @@ -74,11 +65,11 @@ public void createAddressAndKey() { byte[] address = ecKey1.getAddress(); String addressString = ByteArray.toHexString(address); byte[] key = ecKey1.getPrivKeyBytes(); - String keyString = ByteArray.toHexString(key); + final String keyString = ByteArray.toHexString(key); logger.info(ByteArray.toStr(Base64.encode(key))); logger.info(ByteArray.toStr(Base64.encode(address))); - JsonObject userBaseObj2=new JsonObject(); + JsonObject userBaseObj2 = new JsonObject(); userBaseObj2.addProperty("address",addressString); userBaseObj2.addProperty("key",keyString); //userBaseObj2.addProperty("address",ByteArray.toStr(Base64.encode(address))); @@ -98,20 +89,19 @@ public void shutdown() throws InterruptedException { - public static boolean createFile(String fileName,String filecontent){ + public static boolean createFile(String fileName,String filecontent) { Boolean bool = false; filenameTemp = fileName;//文件路径+名称+文件类型 File file = new File(filenameTemp); try { //如果文件不存在,则创建新的文件 - if(!file.exists()){ + if (!file.exists()) { file.createNewFile(); bool = true; - System.out.println("success create file,the file is "+filenameTemp); + System.out.println("success create file,the file is " + filenameTemp); //创建文件成功后,写入内容到文件里 writeFileContent(filenameTemp, filecontent); - } - else { + } else { clearInfoForFile(filenameTemp); writeFileContent(filenameTemp, filecontent); @@ -127,12 +117,12 @@ public static boolean createFile(String fileName,String filecontent){ public static void clearInfoForFile(String fileName) { - File file =new File(fileName); + File file = new File(fileName); try { - if(!file.exists()) { + if (!file.exists()) { file.createNewFile(); } - FileWriter fileWriter =new FileWriter(file); + FileWriter fileWriter = new FileWriter(file); fileWriter.write(""); fileWriter.flush(); fileWriter.close(); @@ -142,16 +132,9 @@ public static void clearInfoForFile(String fileName) { } - /** - * 向文件中写入内容 - * @param filepath 文件路径与名称 - * @param newstr 写入的内容 - * @return - * @throws IOException - */ - public static boolean writeFileContent(String filepath,String newstr) throws IOException{ + public static boolean writeFileContent(String filepath,String newstr) throws IOException { Boolean bool = false; - String filein = newstr+"\r\n";//新写入的行,换行 + String filein = newstr + "\r\n"; String temp = ""; FileInputStream fis = null; @@ -160,17 +143,14 @@ public static boolean writeFileContent(String filepath,String newstr) throws IOE FileOutputStream fos = null; PrintWriter pw = null; try { - File file = new File(filepath);//文件路径(包括文件名称) - //将文件读入输入流 + File file = new File(filepath); fis = new FileInputStream(file); isr = new InputStreamReader(fis); br = new BufferedReader(isr); StringBuffer buffer = new StringBuffer(); - //文件原有内容 - for(int i=0;(temp =br.readLine())!=null;i++){ + for (int i = 0;(temp = br.readLine()) != null;i++) { buffer.append(temp); - // 行与行之间的分隔符 相当于“\n” buffer = buffer.append(System.getProperty("line.separator")); } buffer.append(filein); @@ -183,8 +163,7 @@ public static boolean writeFileContent(String filepath,String newstr) throws IOE } catch (Exception e) { // TODO: handle exception e.printStackTrace(); - }finally { - //不要忘记关闭 + } finally { if (pw != null) { pw.close(); } @@ -204,17 +183,12 @@ public static boolean writeFileContent(String filepath,String newstr) throws IOE return bool; } - /** - * 删除文件 - * @param fileName 文件名称 - * @return - */ - public static boolean delFile(String fileName){ + public static boolean delFile(String fileName) { Boolean bool = false; - filenameTemp = path+fileName+".txt"; + filenameTemp = path + fileName + ".txt"; File file = new File(filenameTemp); try { - if(file.exists()){ + if (file.exists()) { file.delete(); bool = true; } diff --git a/src/test/java/stest/tron/wallet/fulltest/fuzzytest.java b/src/test/java/stest/tron/wallet/fulltest/fuzzytest.java index 0e27c4d35dc..2618f5fb6cd 100644 --- a/src/test/java/stest/tron/wallet/fulltest/fuzzytest.java +++ b/src/test/java/stest/tron/wallet/fulltest/fuzzytest.java @@ -137,7 +137,7 @@ public void tooManyChannelFull() { blockingStubFull = WalletGrpc.newBlockingStub(channelFull); GrpcAPI.NodeList nodeList = blockingStubFull .listNodes(GrpcAPI.EmptyMessage.newBuilder().build()); - if (i%100 == 0) { + if (i % 100 == 0) { logger.info(Integer.toString(i)); } @@ -149,7 +149,7 @@ public void tooManyChannelFull() { @AfterClass(enabled = true) public void shutdown() throws InterruptedException { -/* if (channelFull != null) { + /* if (channelFull != null) { channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); } if (channelSolidity != null) { diff --git a/src/test/java/stest/tron/wallet/onlineStress/MainNetTransferSendOrAsset.java b/src/test/java/stest/tron/wallet/onlineStress/MainNetTransferSendOrAsset.java index ad48a25f0a9..8e3cbc73f53 100644 --- a/src/test/java/stest/tron/wallet/onlineStress/MainNetTransferSendOrAsset.java +++ b/src/test/java/stest/tron/wallet/onlineStress/MainNetTransferSendOrAsset.java @@ -1,11 +1,10 @@ -package stest.tron.wallet.onlineStress; +package stest.tron.wallet.onlinestress; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import java.util.Random; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; -import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeSuite; @@ -66,7 +65,7 @@ public void beforeSuite() { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); } - @BeforeClass(enabled = true) + @BeforeClass(enabled = false) public void beforeClass() { channelFull = ManagedChannelBuilder.forTarget(fullnode) .usePlaintext(true) @@ -85,7 +84,7 @@ public void beforeClass() { 100000L, 1L, 1L, testKey001, blockingStubFull); } beforeToBalance = toAccount.getBalance(); - beforeToAssetBalance =toAccount.getAssetMap().get("testNetAsset"); + beforeToAssetBalance = toAccount.getAssetMap().get("testNetAsset"); Account fromSendAccount = PublicMethed.queryAccount(testKey003,blockingStubFull); Account toSendAccount = PublicMethed.queryAccount(testKey004,blockingStubFull); @@ -98,12 +97,11 @@ public void beforeClass() { start = System.currentTimeMillis(); } - //@Test(enabled = ) @Test(enabled = false,threadPoolSize = 20, invocationCount = 100000) public void freezeAnd() throws InterruptedException { Random rand = new Random(); Integer randNum = 0; - randNum= rand.nextInt(1000); + randNum = rand.nextInt(1000); try { Thread.sleep(randNum); } catch (InterruptedException e) { @@ -114,13 +112,15 @@ public void freezeAnd() throws InterruptedException { Integer i = 0; while (i < 60) { PublicMethed - .transferAsset(toAddress,"testNetAsset".getBytes(),transferAmount,fromAddress,testKey001,blockingStubFull); + .transferAsset(toAddress,"testNetAsset".getBytes(),transferAmount,fromAddress, + testKey001,blockingStubFull); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } - PublicMethed.sendcoin(toSendAddress, sendAmount, fromSendAddress, testKey003, blockingStubFull); + PublicMethed.sendcoin(toSendAddress, sendAmount, fromSendAddress, testKey003, + blockingStubFull); try { Thread.sleep(200); } catch (InterruptedException e) { @@ -129,14 +129,14 @@ public void freezeAnd() throws InterruptedException { } } - @AfterClass(enabled = true) + @AfterClass(enabled = false) public void shutdown() throws InterruptedException { end = System.currentTimeMillis(); logger.info("Time is " + Long.toString(end - start)); Account fromAccount = PublicMethed.queryAccount(testKey001,blockingStubFull); Account toAccount = PublicMethed.queryAccount(testKey002,blockingStubFull); afterToBalance = toAccount.getBalance(); - afterToAssetBalance =toAccount.getAssetMap().get("testNetAsset"); + afterToAssetBalance = toAccount.getAssetMap().get("testNetAsset"); logger.info("Success times is " + Long.toString(afterToAssetBalance - beforeToAssetBalance)); if (channelFull != null) { diff --git a/src/test/java/stest/tron/wallet/onlineStress/MainNetVoteOrFreezeOrCreate.java b/src/test/java/stest/tron/wallet/onlineStress/MainNetVoteOrFreezeOrCreate.java index 3fe64988994..e53fb7c51db 100644 --- a/src/test/java/stest/tron/wallet/onlineStress/MainNetVoteOrFreezeOrCreate.java +++ b/src/test/java/stest/tron/wallet/onlineStress/MainNetVoteOrFreezeOrCreate.java @@ -1,4 +1,4 @@ -package stest.tron.wallet.onlineStress; +package stest.tron.wallet.onlinestress; import com.google.protobuf.ByteString; import io.grpc.ManagedChannel; @@ -11,7 +11,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.spongycastle.util.encoders.Hex; -import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeSuite; @@ -26,8 +25,6 @@ import org.tron.common.utils.Utils; import org.tron.core.Wallet; import org.tron.protos.Contract; -import org.tron.protos.Contract.FreezeBalanceContract; -import org.tron.protos.Contract.UnfreezeBalanceContract; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Account; import org.tron.protos.Protocol.Block; @@ -94,7 +91,7 @@ public void beforeSuite() { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); } - @BeforeClass(enabled = true) + @BeforeClass(enabled = false) public void beforeClass() { channelFull = ManagedChannelBuilder.forTarget(fullnode) .usePlaintext(true) @@ -103,12 +100,12 @@ public void beforeClass() { startTime = System.currentTimeMillis(); } - //@Test(enabled = true) + //@Test(enabled = false) @Test(enabled = false,threadPoolSize = 2, invocationCount = 2) public void freezeAndSendcoin() throws InterruptedException { Random rand = new Random(); Integer randNum = 0; - randNum= rand.nextInt(1000); + randNum = rand.nextInt(1000); try { Thread.sleep(randNum); } catch (InterruptedException e) { @@ -161,7 +158,7 @@ public void freezeAndSendcoin() throws InterruptedException { blockingStubFull); logger.info("freezeBalance"); } -/* ret = false; + /* ret = false; while (!ret) { ret = PublicMethed .transferAsset(toAddress, name.getBytes(), 10L, accountAddress, testKeyAccount, @@ -180,7 +177,7 @@ public void freezeAndSendcoin() throws InterruptedException { } } - @AfterClass(enabled = true) + @AfterClass(enabled = false) public void shutdown() throws InterruptedException { endTime = System.currentTimeMillis(); logger.info("Time is " + Long.toString(endTime - startTime)); @@ -212,7 +209,7 @@ public Boolean voteWitness(HashMap witness, byte[] addRess, Stri builder.setOwnerAddress(ByteString.copyFrom(addRess)); for (String addressBase58 : witness.keySet()) { String value = witness.get(addressBase58); - long count = Long.parseLong(value); + final long count = Long.parseLong(value); Contract.VoteWitnessContract.Vote.Builder voteBuilder = Contract.VoteWitnessContract.Vote .newBuilder(); byte[] address = WalletClient.decodeFromBase58Check(addressBase58); @@ -229,7 +226,8 @@ public Boolean voteWitness(HashMap witness, byte[] addRess, Stri Transaction transaction = blockingStubFull.voteWitnessAccount(contract); if (transaction == null || transaction.getRawData().getContractCount() == 0) { - //logger.info("transaction == null,\n contract:{},\n transaction:{}" , contract.toString(),transaction.toString()); + //logger.info("transaction == null,\n contract:{},\n transaction:{}" , contract.toString(), + // transaction.toString()); logger.info("transaction == null"); return false; } @@ -241,7 +239,7 @@ public Boolean voteWitness(HashMap witness, byte[] addRess, Stri //logger.info(response.getCode().toString()); return false; } -/* try { + /* try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/src/test/java/stest/tron/wallet/onlineStress/TestNetErc721Cat.java b/src/test/java/stest/tron/wallet/onlineStress/TestNetErc721Cat.java new file mode 100644 index 00000000000..0ac3592d0c8 --- /dev/null +++ b/src/test/java/stest/tron/wallet/onlineStress/TestNetErc721Cat.java @@ -0,0 +1,389 @@ +package stest.tron.wallet.onlinestress; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.Utils; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.SmartContract; +import org.tron.protos.Protocol.TransactionInfo; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.Base58; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class TestNetErc721Cat { + + //testng001、testng002、testng003、testng004 + //testng001、testng002、testng003、testng004 + private final String testKey002 = + //"7306c6044ad7c03709980aa188b8555288b7e0608f5edbf76ff2381c5a7a15a8"; + "3a54ba30e3ee41b602eca8fb3a3ca1f99f49a3d3ab5d8d646a2ccdd3ffd9c21d"; + //fromAddress + //"FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + private final byte[] fromAddress = PublicMethed.getFinalAddress(testKey002); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + + String kittyCoreAddressAndCut = ""; + byte[] kittyCoreContractAddress = null; + byte[] saleClockAuctionContractAddress = null; + byte[] siringClockAuctionContractAddress = null; + byte[] geneScienceInterfaceContractAddress = null; + Integer consumeUserResourcePercent = 20; + String txid = ""; + Optional infoById = null; + + ECKey ecKey1 = new ECKey(Utils.getRandom()); + byte[] deployAddress = ecKey1.getAddress(); + String deployKey = ByteArray.toHexString(ecKey1.getPrivKeyBytes()); + + ECKey ecKey2 = new ECKey(Utils.getRandom()); + byte[] triggerAddress = ecKey2.getAddress(); + String triggerKey = ByteArray.toHexString(ecKey2.getPrivKeyBytes()); + + + + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = false) + public void beforeClass() { + PublicMethed.printAddress(deployKey); + PublicMethed.printAddress(triggerKey); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + Assert.assertTrue(PublicMethed.sendcoin(deployAddress,50000000000L,fromAddress, + testKey002,blockingStubFull)); + Assert.assertTrue(PublicMethed.sendcoin(triggerAddress,50000000000L,fromAddress, + testKey002,blockingStubFull)); + /*Assert.assertTrue(PublicMethed.freezeBalanceGetCpu(deployAddress,100000000L, + 3,1,deployKey,blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalanceGetCpu(triggerAddress,100000000L, + 3,1,triggerKey,blockingStubFull)); + Assert.assertTrue(PublicMethed.buyStorage(500000000L,deployAddress,deployKey, + blockingStubFull)); + Assert.assertTrue(PublicMethed.buyStorage(500000000L,triggerAddress,triggerKey, + blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalance(deployAddress,100000000L,3, + deployKey,blockingStubFull)); + Assert.assertTrue(PublicMethed.freezeBalance(triggerAddress,100000000L,3, + triggerKey,blockingStubFull));*/ + + + } + + @Test(enabled = false) + public void deployErc721KittyCore() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(deployAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(deployAddress,blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "KittyCore"; + String code = "6002805460a060020a60ff0219169055610240604052603c6080908152607860a05261012c60c05261025860e05261070861010052610e1061012052611c2061014052613840610160526170806101805261e1006101a052620151806101c0526202a3006101e052620546006102005262093a80610220526200008790600390600e620004e3565b50600f6005556301312d00600e55348015620000a257600080fd5b506002805460008054600160a060020a031990811633908117835560a060020a60ff0219909316740100000000000000000000000000000000000000001716909117909155620001019080806000198164010000000062000108810204565b50620005f1565b6000806200011562000586565b600063ffffffff891689146200012a57600080fd5b63ffffffff881688146200013d57600080fd5b61ffff871687146200014e57600080fd5b600287049250600d8361ffff1611156200016757600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600680546001810182559c528a517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f60028e029081019190915598517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40909901805498519651955194519251915167ffffffffffffffff19909916998b1699909917604060020a608060020a0319166801000000000000000096909a169590950298909817608060020a63ffffffff021916700100000000000000000000000000000000938616939093029290921760a060020a63ffffffff02191674010000000000000000000000000000000000000000918516919091021760c060020a63ffffffff0219167801000000000000000000000000000000000000000000000000968416969096029590951760e060020a61ffff0219167c01000000000000000000000000000000000000000000000000000000009186169190910217600160f060020a03167e010000000000000000000000000000000000000000000000000000000000009290941691909102929092179055909190811681146200036f57600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a1620003f46000868364010000000062000400810204565b98975050505050505050565b600160a060020a03808316600081815260086020908152604080832080546001019055858352600790915290208054600160a060020a03191690911790558316156200049457600160a060020a03831660009081526008602090815260408083208054600019019055838352600a82528083208054600160a060020a03199081169091556009909252909120805490911690555b60408051600160a060020a0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b600283019183908215620005745791602002820160005b838211156200054057835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302620004fa565b8015620005725782816101000a81549063ffffffff021916905560040160208160030104928301926001030262000540565b505b5062000582929150620005ca565b5090565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b620005ee91905b808211156200058257805463ffffffff19168155600101620005d1565b90565b6130f380620006016000396000f3006080604052600436106102a55763ffffffff60e060020a60003504166301ffc9a781146102d55780630519ce79146103205780630560ff441461035157806305e45546146103ea57806306fdde0314610411578063095ea7b3146104265780630a0f81681461044a5780630e583df01461045f57806314001f4c1461047457806318160ddd14610495578063183a7947146104aa5780631940a936146104bf57806319c2f201146104d757806321717ebf146104ec57806323b872dd1461050157806324e7a38a1461052b57806327d7874c1461054c5780632ba73c151461056d5780633d7d3f5a1461058e5780633f4ba83a146105af57806346116e6f146105c457806346d22c70146105dc578063481af3d3146105f75780634ad8c9381461060f5780634b85fd55146106305780634dfff04f146106485780634e0a33791461066c578063561291341461068d5780635663896e146106b15780635c975abb146106c95780635fd8c710146106de5780636352211e146106f3578063680eba271461070b5780636af04a57146107205780636fbde40d1461073557806370a082311461075657806371587988146107775780637a7d4937146107985780638456cb59146107ad5780638462151c146107c257806388c2a0bf1461083357806391876e571461084b57806395d89b41146108605780639d6fac6f14610875578063a45f4bfc146108a6578063a9059cbb146108be578063b047fb50146108e2578063b0c35c05146108f7578063bc4006f51461090c578063c3bea9af14610921578063d3e6f49f14610939578063defb958414610951578063e17b25af14610966578063e6cbe35114610987578063e98b7f4d1461099c578063ed60ade614610a06578063f1ca941014610a14578063f2b47d5214610a29578063f7d8c88314610a3e575b600b54600160a060020a03163314806102c85750600c54600160a060020a031633145b15156102d357600080fd5b005b3480156102e157600080fd5b5061030c7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610a4c565b604080519115158252519081900360200190f35b34801561032c57600080fd5b50610335610cdf565b60408051600160a060020a039092168252519081900360200190f35b34801561035d57600080fd5b50610375600480359060248035908101910135610cee565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103af578181015183820152602001610397565b50505050905090810190601f1680156103dc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103f657600080fd5b506103ff610df1565b60408051918252519081900360200190f35b34801561041d57600080fd5b50610375610df7565b34801561043257600080fd5b506102d3600160a060020a0360043516602435610e2e565b34801561045657600080fd5b50610335610eb0565b34801561046b57600080fd5b506103ff610ebf565b34801561048057600080fd5b506102d3600160a060020a0360043516610ec6565b3480156104a157600080fd5b506103ff610f79565b3480156104b657600080fd5b506103ff610f83565b3480156104cb57600080fd5b5061030c600435610f89565b3480156104e357600080fd5b506103ff610fce565b3480156104f857600080fd5b50610335610fd5565b34801561050d57600080fd5b506102d3600160a060020a0360043581169060243516604435610fe4565b34801561053757600080fd5b506102d3600160a060020a0360043516611060565b34801561055857600080fd5b506102d3600160a060020a0360043516611113565b34801561057957600080fd5b506102d3600160a060020a0360043516611161565b34801561059a57600080fd5b506102d36004356024356044356064356111af565b3480156105bb57600080fd5b506102d36112a4565b3480156105d057600080fd5b50610335600435611338565b3480156105e857600080fd5b5061030c600435602435611353565b34801561060357600080fd5b506103356004356113d3565b34801561061b57600080fd5b506102d36004356024356044356064356113ee565b34801561063c57600080fd5b506102d36004356114c6565b34801561065457600080fd5b506102d3600160a060020a03600435166024356114e2565b34801561067857600080fd5b506102d3600160a060020a036004351661153c565b34801561069957600080fd5b506102d3600435600160a060020a036024351661158a565b3480156106bd57600080fd5b506102d36004356115f1565b3480156106d557600080fd5b5061030c61164d565b3480156106ea57600080fd5b506102d361165d565b3480156106ff57600080fd5b506103356004356116c1565b34801561071757600080fd5b506103ff6116e5565b34801561072c57600080fd5b506103356116eb565b34801561074157600080fd5b506102d3600160a060020a03600435166116fa565b34801561076257600080fd5b506103ff600160a060020a03600435166117ad565b34801561078357600080fd5b506102d3600160a060020a03600435166117c8565b3480156107a457600080fd5b506103ff61184b565b3480156107b957600080fd5b506102d3611851565b3480156107ce57600080fd5b506107e3600160a060020a03600435166118d1565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561081f578181015183820152602001610807565b505050509050019250505060405180910390f35b34801561083f57600080fd5b506103ff6004356119a3565b34801561085757600080fd5b506102d3611c7f565b34801561086c57600080fd5b50610375611d94565b34801561088157600080fd5b5061088d600435611dcb565b6040805163ffffffff9092168252519081900360200190f35b3480156108b257600080fd5b50610335600435611df8565b3480156108ca57600080fd5b506102d3600160a060020a0360043516602435611e13565b3480156108ee57600080fd5b50610335611eab565b34801561090357600080fd5b506103ff611eba565b34801561091857600080fd5b50610335611ec0565b34801561092d57600080fd5b506102d3600435611ecf565b34801561094557600080fd5b5061030c600435611fb9565b34801561095d57600080fd5b506103ff612088565b34801561097257600080fd5b506102d3600160a060020a036004351661208e565b34801561099357600080fd5b506103356120c7565b3480156109a857600080fd5b506109b46004356120d6565b604080519a15158b5298151560208b0152898901979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015251908190036101400190f35b6102d3600435602435612237565b348015610a2057600080fd5b506103ff6123d1565b348015610a3557600080fd5b506103356123d7565b6102d36004356024356123e6565b604080517f737570706f727473496e74657266616365286279746573342900000000000000815290519081900360190190206000907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1983811691161480610cd75750604080517f746f6b656e4d657461646174612875696e743235362c737472696e67290000008152815190819003601d0181207f746f6b656e734f664f776e657228616464726573732900000000000000000000825282519182900360160182207f7472616e7366657246726f6d28616464726573732c616464726573732c75696e83527f7432353629000000000000000000000000000000000000000000000000000000602084015283519283900360250183207f7472616e7366657228616464726573732c75696e743235362900000000000000845284519384900360190184207f617070726f766528616464726573732c75696e74323536290000000000000000855285519485900360180185207f6f776e65724f662875696e743235362900000000000000000000000000000000865286519586900360100186207f62616c616e63654f662861646472657373290000000000000000000000000000875287519687900360120187207f746f74616c537570706c792829000000000000000000000000000000000000008852885197889003600d0188207f73796d626f6c2829000000000000000000000000000000000000000000000000895289519889900360080189207f6e616d65282900000000000000000000000000000000000000000000000000008a529951988990036006019098207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff198c811691909a189098181818181818181891909116145b90505b919050565b600154600160a060020a031681565b6060610cf8613064565b600d54600090600160a060020a03161515610d1257600080fd5b600d54604080517fcb4799f2000000000000000000000000000000000000000000000000000000008152600481018981526024820192835260448201889052600160a060020a039093169263cb4799f2928a928a928a929091606401848480828437820191505094505050505060a060405180830381600087803b158015610d9957600080fd5b505af1158015610dad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525060a0811015610dd257600080fd5b5060808101519092509050610de782826125e4565b9695505050505050565b60115481565b60408051808201909152600d81527f43727970746f4b69747469657300000000000000000000000000000000000000602082015281565b60025460a060020a900460ff1615610e4557600080fd5b610e4f3382612638565b1515610e5a57600080fd5b610e648183612658565b60408051338152600160a060020a038416602082015280820183905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15050565b600054600160a060020a031681565b6298968081565b60008054600160a060020a03163314610ede57600080fd5b81905080600160a060020a03166376190f8f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f1f57600080fd5b505af1158015610f33573d6000803e3d6000fd5b505050506040513d6020811015610f4957600080fd5b50511515610f5657600080fd5b600c8054600160a060020a031916600160a060020a039290921691909117905550565b6006546000190190565b600f5481565b6000808211610f9757600080fd5b6006805483908110610fa557fe5b600091825260209091206002909102016001015460c060020a900463ffffffff16151592915050565b6201518081565b600c54600160a060020a031681565b60025460a060020a900460ff1615610ffb57600080fd5b600160a060020a038216151561101057600080fd5b600160a060020a03821630141561102657600080fd5b6110303382612686565b151561103b57600080fd5b6110458382612638565b151561105057600080fd5b61105b8383836126a6565b505050565b60008054600160a060020a0316331461107857600080fd5b81905080600160a060020a03166354c15b826040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156110b957600080fd5b505af11580156110cd573d6000803e3d6000fd5b505050506040513d60208110156110e357600080fd5b505115156110f057600080fd5b60108054600160a060020a031916600160a060020a039290921691909117905550565b600054600160a060020a0316331461112a57600080fd5b600160a060020a038116151561113f57600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331461117857600080fd5b600160a060020a038116151561118d57600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b60025460a060020a900460ff16156111c657600080fd5b6111d03385612638565b15156111db57600080fd5b6111e484610f89565b156111ee57600080fd5b600b54611205908590600160a060020a0316612658565b600b54604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b15801561128657600080fd5b505af115801561129a573d6000803e3d6000fd5b5050505050505050565b600054600160a060020a031633146112bb57600080fd5b60025460a060020a900460ff1615156112d357600080fd5b600b54600160a060020a031615156112ea57600080fd5b600c54600160a060020a0316151561130157600080fd5b601054600160a060020a0316151561131857600080fd5b601354600160a060020a03161561132e57600080fd5b611336612788565b565b600a60205260009081526040902054600160a060020a031681565b6000808080851161136357600080fd5b6000841161137057600080fd5b600680548690811061137e57fe5b9060005260206000209060020201915060068481548110151561139d57fe5b906000526020600020906002020190506113b9828683876127d7565b80156113ca57506113ca8486612957565b95945050505050565b600960205260009081526040902054600160a060020a031681565b60025460a060020a900460ff161561140557600080fd5b61140f3385612638565b151561141a57600080fd5b61142384611fb9565b151561142e57600080fd5b600c54611445908590600160a060020a0316612658565b600c54604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b15801561128657600080fd5b600254600160a060020a031633146114dd57600080fd5b600e55565b60025460a060020a900460ff16156114f957600080fd5b6115033382612638565b151561150e57600080fd5b6000908152600a602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331461155357600080fd5b600160a060020a038116151561156857600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b600254600090600160a060020a031633146115a457600080fd5b5080600160a060020a03811615156115c45750600254600160a060020a03165b601154611388116115d457600080fd5b6011805460010190556115eb6000808086856129ac565b50505050565b600254600160a060020a03163314806116145750600054600160a060020a031633145b806116295750600154600160a060020a031633145b151561163457600080fd5b60035463ffffffff16811061164857600080fd5b600555565b60025460a060020a900460ff1681565b6001546000908190600160a060020a0316331461167957600080fd5b5050600e54600f54303191600190910102808211156116bd57600154604051600160a060020a039091169082840380156108fc02916000818181858888f150505050505b5050565b600081815260076020526040902054600160a060020a0316801515610cda57600080fd5b61afc881565b601354600160a060020a031681565b60008054600160a060020a0316331461171257600080fd5b81905080600160a060020a03166385b861886040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561175357600080fd5b505af1158015611767573d6000803e3d6000fd5b505050506040513d602081101561177d57600080fd5b5051151561178a57600080fd5b600b8054600160a060020a031916600160a060020a039290921691909117905550565b600160a060020a031660009081526008602052604090205490565b600054600160a060020a031633146117df57600080fd5b60025460a060020a900460ff1615156117f757600080fd5b60138054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b60055481565b600254600160a060020a03163314806118745750600054600160a060020a031633145b806118895750600154600160a060020a031633145b151561189457600080fd5b60025460a060020a900460ff16156118ab57600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055565b60606000606060008060006118e5876117ad565b9450841515611904576040805160008152602081019091529550611999565b8460405190808252806020026020018201604052801561192e578160200160208202803883390190505b509350611939610f79565b925060009150600190505b82811161199557600081815260076020526040902054600160a060020a038881169116141561198d5780848381518110151561197c57fe5b602090810290910101526001909101905b600101611944565b8395505b5050505050919050565b600080600080600080600080600260149054906101000a900460ff161515156119cb57600080fd5b600680548a9081106119d957fe5b60009182526020909120600290910201600181015490975067ffffffffffffffff161515611a0657600080fd5b604080516101008101825288548152600189015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152611a9790612c89565b1515611aa257600080fd5b60018701546006805460c060020a90920463ffffffff1697509087908110611ac657fe5b600091825260209091206001808a015460029093029091019081015490965061ffff60f060020a928390048116965091900416841015611b1357600185015460f060020a900461ffff1693505b6010548754865460018a0154604080517f0d9f5aed0000000000000000000000000000000000000000000000000000000081526004810194909452602484019290925260001967ffffffffffffffff6801000000000000000090920482160116604483015251600160a060020a0390921691630d9f5aed916064808201926020929091908290030181600087803b158015611bad57600080fd5b505af1158015611bc1573d6000803e3d6000fd5b505050506040513d6020811015611bd757600080fd5b505160008a815260076020526040902054600189810154929550600160a060020a039091169350611c20918b9160c060020a90910463ffffffff1690870161ffff1686866129ac565b6001880180547bffffffff00000000000000000000000000000000000000000000000019169055600f8054600019019055600e54604051919250339181156108fc0291906000818181858888f150939c9b505050505050505050505050565b600254600160a060020a0316331480611ca25750600054600160a060020a031633145b80611cb75750600154600160a060020a031633145b1515611cc257600080fd5b600b60009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611d1557600080fd5b505af1158015611d29573d6000803e3d6000fd5b50505050600c60009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611d8057600080fd5b505af11580156115eb573d6000803e3d6000fd5b60408051808201909152600281527f434b000000000000000000000000000000000000000000000000000000000000602082015281565b600381600e8110611dd857fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b600760205260009081526040902054600160a060020a031681565b60025460a060020a900460ff1615611e2a57600080fd5b600160a060020a0382161515611e3f57600080fd5b600160a060020a038216301415611e5557600080fd5b600b54600160a060020a0383811691161415611e7057600080fd5b600c54600160a060020a0383811691161415611e8b57600080fd5b611e953382612638565b1515611ea057600080fd5b6116bd3383836126a6565b600254600160a060020a031681565b600e5481565b600d54600160a060020a031681565b600254600090600160a060020a03163314611ee957600080fd5b60125461afc811611ef957600080fd5b611f08600080600085306129ac565b600b54909150611f22908290600160a060020a0316612658565b600b54600160a060020a03166327ebe40a82611f3c612cb9565b6040805160e060020a63ffffffff861602815260048101939093526024830191909152600060448301819052620151806064840152306084840152905160a48084019382900301818387803b158015611f9457600080fd5b505af1158015611fa8573d6000803e3d6000fd5b505060128054600101905550505050565b600080808311611fc857600080fd5b6006805484908110611fd657fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e082015290915061208190612d7b565b9392505050565b61138881565b600054600160a060020a031633146120a557600080fd5b600d8054600160a060020a031916600160a060020a0392909216919091179055565b600b54600160a060020a031681565b600080600080600080600080600080600060068c8154811015156120f657fe5b906000526020600020906002020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159a50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161115995080600101601c9054906101000a900461ffff1661ffff1698508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160189054906101000a900463ffffffff1663ffffffff1696508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1695508060010160109054906101000a900463ffffffff1663ffffffff1694508060010160149054906101000a900463ffffffff1663ffffffff16935080600101601e9054906101000a900461ffff1661ffff16925080600001549150509193959799509193959799565b60025460009060a060020a900460ff161561225157600080fd5b61225b3383612638565b151561226657600080fd5b61226f82611fb9565b151561227a57600080fd5b6122848284612daa565b151561228f57600080fd5b600c54604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b1580156122f657600080fd5b505af115801561230a573d6000803e3d6000fd5b505050506040513d602081101561232057600080fd5b5051600e54909150810134101561233657600080fd5b600c54600e54604080517f454a2ab3000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a039093169263454a2ab39234039160248082019260009290919082900301818588803b1580156123a257600080fd5b505af11580156123b6573d6000803e3d6000fd5b505050505061105b8263ffffffff168463ffffffff16612df9565b60125481565b601054600160a060020a031681565b600254600090819060a060020a900460ff161561240257600080fd5b600e5434101561241157600080fd5b61241b3385612638565b151561242657600080fd5b6124308385612957565b151561243b57600080fd5b600680548590811061244957fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529092506124f490612d7b565b15156124ff57600080fd5b600680548490811061250d57fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529091506125b890612d7b565b15156125c357600080fd5b6125cf828583866127d7565b15156125da57600080fd5b6115eb8484612df9565b606080600080846040519080825280601f01601f191660200182016040528015612618578160200160208202803883390190505b509250506020820190508461262e828287612f37565b5090949350505050565b600090815260076020526040902054600160a060020a0391821691161490565b6000918252600960205260409091208054600160a060020a031916600160a060020a03909216919091179055565b600090815260096020526040902054600160a060020a0391821691161490565b600160a060020a03808316600081815260086020908152604080832080546001019055858352600790915290208054600160a060020a031916909117905583161561273957600160a060020a03831660009081526008602090815260408083208054600019019055838352600a82528083208054600160a060020a03199081169091556009909252909120805490911690555b60408051600160a060020a0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b600054600160a060020a0316331461279f57600080fd5b60025460a060020a900460ff1615156127b757600080fd5b6002805474ff000000000000000000000000000000000000000019169055565b6000818414156127e95750600061294f565b6001850154608060020a900463ffffffff168214806128185750600185015460a060020a900463ffffffff1682145b156128255750600061294f565b6001830154608060020a900463ffffffff168414806128545750600183015460a060020a900463ffffffff1684145b156128615750600061294f565b6001830154608060020a900463ffffffff16158061288e57506001850154608060020a900463ffffffff16155b1561289b5750600161294f565b60018581015490840154608060020a9182900463ffffffff908116929091041614806128e6575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b156128f35750600061294f565b6001808601549084015460a060020a900463ffffffff908116608060020a90920416148061293e57506001858101549084015460a060020a9182900463ffffffff9081169290910416145b1561294b5750600061294f565b5060015b949350505050565b6000818152600760205260408082205484835290822054600160a060020a039182169116808214806113ca57506000858152600a6020526040902054600160a060020a03908116908316149250505092915050565b6000806129b7613083565b600063ffffffff891689146129cb57600080fd5b63ffffffff881688146129dd57600080fd5b61ffff871687146129ed57600080fd5b600287049250600d8361ffff161115612a0557600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600680546001810182559c528a517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f60028e029081019190915598517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40909901805498519651955194519251915167ffffffffffffffff19909916998b16999099176fffffffffffffffff000000000000000019166801000000000000000096909a16959095029890981773ffffffff000000000000000000000000000000001916608060020a938616939093029290921777ffffffff0000000000000000000000000000000000000000191660a060020a91851691909102177bffffffff000000000000000000000000000000000000000000000000191660c060020a96841696909602959095177fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a91861691909102177dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a929094169190910292909217905590919081168114612c0357600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a1612c7d600086836126a6565b98975050505050505050565b60008160a0015163ffffffff16600014158015610cd75750506040015167ffffffffffffffff4381169116111590565b6000806000600b60009054906101000a9004600160a060020a0316600160a060020a031663eac9d94c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612d1157600080fd5b505af1158015612d25573d6000803e3d6000fd5b505050506040513d6020811015612d3b57600080fd5b505191506fffffffffffffffffffffffffffffffff82168214612d5d57600080fd5b5060028104810162989680811015612d755750629896805b92915050565b60008160a0015163ffffffff166000148015610cd75750506040015167ffffffffffffffff4381169116111590565b6000806000600685815481101515612dbe57fe5b90600052602060002090600202019150600684815481101515612ddd57fe5b906000526020600020906002020190506113ca828683876127d7565b600080600683815481101515612e0b57fe5b90600052602060002090600202019150600684815481101515612e2a57fe5b600091825260209091206002909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff8716021790559050612e7a82612f7b565b612e8381612f7b565b6000848152600a602090815260408083208054600160a060020a031990811690915586845281842080549091169055600f80546001908101909155878452600783529281902054928401548151600160a060020a0390941684529183018790528281018690526801000000000000000090910467ffffffffffffffff166060830152517f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80916080908290030190a150505050565b60005b60208210612f5c578251845260209384019390920191601f1990910190612f3a565b50905182516020929092036101000a6000190180199091169116179052565b600554600182015443919060039060e060020a900461ffff16600e8110612f9e57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515612fc957fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600d60e060020a90910461ffff161015613061576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b6080604051908101604052806004906020820280388339509192915050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152905600a165627a7a723058201424bf1db41fa7ec76f5506a53d8bbcb84ed5b5a6ade2df0bac8deaacb118a8b0029"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cfoAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_preferredTransport\",\"type\":\"string\"}],\"name\":\"tokenMetadata\",\"outputs\":[{\"name\":\"infoUrl\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"promoCreatedCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ceoAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_STARTING_PRICE\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setSiringAuctionAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pregnantKitties\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"}],\"name\":\"isPregnant\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_AUCTION_DURATION\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"siringAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setGeneScienceAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCEO\",\"type\":\"address\"}],\"name\":\"setCEO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCOO\",\"type\":\"address\"}],\"name\":\"setCOO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"}],\"name\":\"createSaleAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sireAllowedToAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"canBreedWith\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"kittyIndexToApproved\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"}],\"name\":\"createSiringAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"val\",\"type\":\"uint256\"}],\"name\":\"setAutoBirthFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_addr\",\"type\":\"address\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"approveSiring\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newCFO\",\"type\":\"address\"}],\"name\":\"setCFO\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_genes\",\"type\":\"uint256\"},{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"createPromoKitty\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"secs\",\"type\":\"uint256\"}],\"name\":\"setSecondsPerBlock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GEN0_CREATION_LIMIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"newContractAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setSaleAuctionAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"count\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_v2Address\",\"type\":\"address\"}],\"name\":\"setNewAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"secondsPerBlock\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"tokensOfOwner\",\"outputs\":[{\"name\":\"ownerTokens\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"}],\"name\":\"giveBirth\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawAuctionBalances\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"cooldowns\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"kittyIndexToOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cooAddress\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"autoBirthFee\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"erc721Metadata\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_genes\",\"type\":\"uint256\"}],\"name\":\"createGen0Auction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_kittyId\",\"type\":\"uint256\"}],\"name\":\"isReadyToBreed\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"PROMO_CREATION_LIMIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_contractAddress\",\"type\":\"address\"}],\"name\":\"setMetadataAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"saleAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getKitty\",\"outputs\":[{\"name\":\"isGestating\",\"type\":\"bool\"},{\"name\":\"isReady\",\"type\":\"bool\"},{\"name\":\"cooldownIndex\",\"type\":\"uint256\"},{\"name\":\"nextActionAt\",\"type\":\"uint256\"},{\"name\":\"siringWithId\",\"type\":\"uint256\"},{\"name\":\"birthTime\",\"type\":\"uint256\"},{\"name\":\"matronId\",\"type\":\"uint256\"},{\"name\":\"sireId\",\"type\":\"uint256\"},{\"name\":\"generation\",\"type\":\"uint256\"},{\"name\":\"genes\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_sireId\",\"type\":\"uint256\"},{\"name\":\"_matronId\",\"type\":\"uint256\"}],\"name\":\"bidOnSiringAuction\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gen0CreatedCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"geneScience\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_matronId\",\"type\":\"uint256\"},{\"name\":\"_sireId\",\"type\":\"uint256\"}],\"name\":\"breedWithAuto\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"matronId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"sireId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"cooldownEndBlock\",\"type\":\"uint256\"}],\"name\":\"Pregnant\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"kittyId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"matronId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"sireId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"genes\",\"type\":\"uint256\"}],\"name\":\"Birth\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"newContract\",\"type\":\"address\"}],\"name\":\"ContractUpgrade\",\"type\":\"event\"}]"; + + logger.info("Kitty Core"); + kittyCoreContractAddress = PublicMethed.deployContract(contractName,abi,code,"", + maxFeeLimit, 0L, consumeUserResourcePercent,null,deployKey, + deployAddress,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(kittyCoreContractAddress, + blockingStubFull); + + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(deployAddress,blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(deployKey,blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + logger.info(ByteArray.toHexString(kittyCoreContractAddress)); + logger.info(ByteArray.toHexString(kittyCoreContractAddress).substring(2)); + + kittyCoreAddressAndCut = "000000000000000000000000" + ByteArray + .toHexString(kittyCoreContractAddress).substring(2); + kittyCoreAddressAndCut = kittyCoreAddressAndCut + "0000000000000000000000000000000000000000000" + + "000000000000000000100"; + } + + @Test(enabled = false) + public void deploySaleClockAuction() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(deployAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(deployKey,blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "SaleClockAuction"; + String code = "60806040526000805460a060020a60ff02191690556004805460ff1916600117905534801561002d57600080fd5b50604051604080610ee883398101604052805160209091015160008054600160a060020a031916331781558290829061271082111561006b57600080fd5b506002819055604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f9a20483d00000000000000000000000000000000000000000000000000000000600482015290518391600160a060020a038316916301ffc9a7916024808201926020929091908290030181600087803b1580156100f557600080fd5b505af1158015610109573d6000803e3d6000fd5b505050506040513d602081101561011f57600080fd5b5051151561012c57600080fd5b60018054600160a060020a03909216600160a060020a031990921691909117905550505050610d88806101606000396000f3006080604052600436106100fb5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327ebe40a81146101005780633f4ba83a1461012f578063454a2ab314610158578063484eccb4146101635780635c975abb1461018d5780635fd8c710146101a257806378bd7935146101b757806383b5ff8b146102045780638456cb591461021957806385b861881461022e578063878eb368146102435780638a98a9cc1461025b5780638da5cb5b1461027057806396b5a755146102a1578063c55d0f56146102b9578063dd1b7a0f146102d1578063eac9d94c146102e6578063f2fde38b146102fb575b600080fd5b34801561010c57600080fd5b5061012d600435602435604435606435600160a060020a036084351661031c565b005b34801561013b57600080fd5b50610144610414565b604080519115158252519081900360200190f35b61012d60043561048f565b34801561016f57600080fd5b5061017b6004356104f9565b60408051918252519081900360200190f35b34801561019957600080fd5b5061014461050d565b3480156101ae57600080fd5b5061012d61051d565b3480156101c357600080fd5b506101cf60043561057a565b60408051600160a060020a03909616865260208601949094528484019290925260608401526080830152519081900360a00190f35b34801561021057600080fd5b5061017b610610565b34801561022557600080fd5b50610144610616565b34801561023a57600080fd5b50610144610696565b34801561024f57600080fd5b5061012d60043561069f565b34801561026757600080fd5b5061017b61070c565b34801561027c57600080fd5b50610285610712565b60408051600160a060020a039092168252519081900360200190f35b3480156102ad57600080fd5b5061012d600435610721565b3480156102c557600080fd5b5061017b600435610766565b3480156102dd57600080fd5b50610285610798565b3480156102f257600080fd5b5061017b6107a7565b34801561030757600080fd5b5061012d600160a060020a03600435166107db565b610324610d2e565b6fffffffffffffffffffffffffffffffff8516851461034257600080fd5b6fffffffffffffffffffffffffffffffff8416841461036057600080fd5b67ffffffffffffffff8316831461037657600080fd5b600154600160a060020a0316331461038d57600080fd5b610397828761082d565b60a06040519081016040528083600160a060020a03168152602001866fffffffffffffffffffffffffffffffff168152602001856fffffffffffffffffffffffffffffffff1681526020018467ffffffffffffffff1681526020014267ffffffffffffffff16815250905061040c86826108b5565b505050505050565b60008054600160a060020a0316331461042c57600080fd5b60005460a060020a900460ff16151561044457600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a150600190565b600081815260036020526040812054600160a060020a0316906104b28334610a09565b90506104be3384610b2f565b600154600160a060020a03838116911614156104f45760058054829160069106600581106104e857fe5b01556005805460010190555b505050565b6006816005811061050657fe5b0154905081565b60005460a060020a900460ff1681565b60015460008054600160a060020a039283169216331480610546575033600160a060020a038316145b151561055157600080fd5b604051600160a060020a03831690303180156108fc02916000818181858888f150505050505050565b6000818152600360205260408120819081908190819061059981610b9d565b15156105a457600080fd5b80546001820154600290920154600160a060020a03909116986fffffffffffffffffffffffffffffffff8084169950700100000000000000000000000000000000909304909216965067ffffffffffffffff808216965068010000000000000000909104169350915050565b60025481565b60008054600160a060020a0316331461062e57600080fd5b60005460a060020a900460ff161561064557600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a150600190565b60045460ff1681565b6000805460a060020a900460ff1615156106b857600080fd5b600054600160a060020a031633146106cf57600080fd5b5060008181526003602052604090206106e781610b9d565b15156106f257600080fd5b8054610708908390600160a060020a0316610bbe565b5050565b60055481565b600054600160a060020a031681565b60008181526003602052604081209061073982610b9d565b151561074457600080fd5b508054600160a060020a031633811461075c57600080fd5b6104f48382610bbe565b600081815260036020526040812061077d81610b9d565b151561078857600080fd5b61079181610c08565b9392505050565b600154600160a060020a031681565b600080805b60058110156107d157600681600581106107c257fe5b015491909101906001016107ac565b5060059004919050565b600054600160a060020a031633146107f257600080fd5b600160a060020a0381161561082a576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b50565b600154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015230602483015260448201859052915191909216916323b872dd91606480830192600092919082900301818387803b1580156108a157600080fd5b505af115801561040c573d6000803e3d6000fd5b603c816060015167ffffffffffffffff16101515156108d357600080fd5b60008281526003602090815260409182902083518154600160a060020a0390911673ffffffffffffffffffffffffffffffffffffffff1990911617815581840151600182018054858701516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000081029482166fffffffffffffffffffffffffffffffff19909316831790911693909317909155606080870151600290940180546080808a015167ffffffffffffffff90811668010000000000000000026fffffffffffffffff0000000000000000199190981667ffffffffffffffff1990931683171696909617909155865189815295860192909252848601929092529083015291517fa9c8dfcda5664a5a124c713e386da27de87432d5b668e79458501eb296389ba7929181900390910190a15050565b60008281526003602052604081208180808080610a2586610b9d565b1515610a3057600080fd5b610a3986610c08565b945084881015610a4857600080fd5b8554600160a060020a03169350610a5e89610c98565b6000851115610ab057610a7085610ce5565b6040519093508386039250600160a060020a0385169083156108fc029084906000818181858888f19350505050158015610aae573d6000803e3d6000fd5b505b5060405184880390339082156108fc029083906000818181858888f19350505050158015610ae2573d6000803e3d6000fd5b50604080518a815260208101879052338183015290517f4fcc30d90a842164dd58501ab874a101a3749c3d4747139cefe7c876f4ccebd29181900360600190a15092979650505050505050565b600154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152602482018590529151919092169163a9059cbb91604480830192600092919082900301818387803b1580156108a157600080fd5b6002015460006801000000000000000090910467ffffffffffffffff161190565b610bc782610c98565b610bd18183610b2f565b6040805183815290517f2809c7e17bf978fbc7194c0a694b638c4215e9140cacc6c38ca36010b45697df9181900360200190a15050565b6002810154600090819068010000000000000000900467ffffffffffffffff16421115610c4e5750600282015468010000000000000000900467ffffffffffffffff1642035b60018301546002840154610791916fffffffffffffffffffffffffffffffff80821692700100000000000000000000000000000000909204169067ffffffffffffffff1684610cf1565b6000908152600360205260408120805473ffffffffffffffffffffffffffffffffffffffff19168155600181019190915560020180546fffffffffffffffffffffffffffffffff19169055565b60025461271091020490565b6000808080858510610d0557869350610d23565b878703925085858402811515610d1757fe5b05915081880190508093505b505050949350505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152905600a165627a7a723058203c3d7d4039d9d9a82dd65c7bc046590e8fe3580af952a66fe24052959889bef50029" + kittyCoreAddressAndCut; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"},{\"name\":\"_seller\",\"type\":\"address\"}],\"name\":\"createAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"bid\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastGen0SalePrices\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getAuction\",\"outputs\":[{\"name\":\"seller\",\"type\":\"address\"},{\"name\":\"startingPrice\",\"type\":\"uint256\"},{\"name\":\"endingPrice\",\"type\":\"uint256\"},{\"name\":\"duration\",\"type\":\"uint256\"},{\"name\":\"startedAt\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ownerCut\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isSaleClockAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"cancelAuctionWhenPaused\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gen0SaleCount\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"cancelAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getCurrentPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"nonFungibleContract\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"averageGen0SalePrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_nftAddr\",\"type\":\"address\"},{\"name\":\"_cut\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"startingPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"endingPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"AuctionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"totalPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"winner\",\"type\":\"address\"}],\"name\":\"AuctionSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"AuctionCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Pause\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Unpause\",\"type\":\"event\"}]"; + logger.info("Sale Clock Auction"); + saleClockAuctionContractAddress = PublicMethed.deployContract(contractName,abi,code, + "",maxFeeLimit, 0L, consumeUserResourcePercent,null,deployKey, + deployAddress,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(saleClockAuctionContractAddress, + blockingStubFull); + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(deployAddress,blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(deployKey,blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @Test(enabled = false) + public void deploySiringClockAuction() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(deployAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(deployKey,blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "SiringClockAuction"; + String code = "60806040526000805460a060020a60ff02191690556004805460ff1916600117905534801561002d57600080fd5b50604051604080610e1a83398101604052805160209091015160008054600160a060020a031916331781558290829061271082111561006b57600080fd5b506002819055604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f9a20483d00000000000000000000000000000000000000000000000000000000600482015290518391600160a060020a038316916301ffc9a7916024808201926020929091908290030181600087803b1580156100f557600080fd5b505af1158015610109573d6000803e3d6000fd5b505050506040513d602081101561011f57600080fd5b5051151561012c57600080fd5b60018054600160a060020a03909216600160a060020a031990921691909117905550505050610cba806101606000396000f3006080604052600436106100da5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166327ebe40a81146100df5780633f4ba83a1461010e578063454a2ab3146101375780635c975abb146101425780635fd8c7101461015757806376190f8f1461016c57806378bd79351461018157806383b5ff8b146101ce5780638456cb59146101f5578063878eb3681461020a5780638da5cb5b1461022257806396b5a75514610253578063c55d0f561461026b578063dd1b7a0f14610283578063f2fde38b14610298575b600080fd5b3480156100eb57600080fd5b5061010c600435602435604435606435600160a060020a03608435166102b9565b005b34801561011a57600080fd5b506101236103b1565b604080519115158252519081900360200190f35b61010c60043561042c565b34801561014e57600080fd5b50610123610478565b34801561016357600080fd5b5061010c610488565b34801561017857600080fd5b506101236104e5565b34801561018d57600080fd5b506101996004356104ee565b60408051600160a060020a03909616865260208601949094528484019290925260608401526080830152519081900360a00190f35b3480156101da57600080fd5b506101e3610584565b60408051918252519081900360200190f35b34801561020157600080fd5b5061012361058a565b34801561021657600080fd5b5061010c60043561060a565b34801561022e57600080fd5b50610237610673565b60408051600160a060020a039092168252519081900360200190f35b34801561025f57600080fd5b5061010c600435610682565b34801561027757600080fd5b506101e36004356106cc565b34801561028f57600080fd5b506102376106fe565b3480156102a457600080fd5b5061010c600160a060020a036004351661070d565b6102c1610c60565b6fffffffffffffffffffffffffffffffff851685146102df57600080fd5b6fffffffffffffffffffffffffffffffff841684146102fd57600080fd5b67ffffffffffffffff8316831461031357600080fd5b600154600160a060020a0316331461032a57600080fd5b610334828761075f565b60a06040519081016040528083600160a060020a03168152602001866fffffffffffffffffffffffffffffffff168152602001856fffffffffffffffffffffffffffffffff1681526020018467ffffffffffffffff1681526020014267ffffffffffffffff1681525090506103a986826107e7565b505050505050565b60008054600160a060020a031633146103c957600080fd5b60005460a060020a900460ff1615156103e157600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a150600190565b600154600090600160a060020a0316331461044657600080fd5b50600081815260036020526040902054600160a060020a0316610469823461093b565b506104748183610a61565b5050565b60005460a060020a900460ff1681565b60015460008054600160a060020a0392831692163314806104b1575033600160a060020a038316145b15156104bc57600080fd5b604051600160a060020a03831690303180156108fc02916000818181858888f150505050505050565b60045460ff1681565b6000818152600360205260408120819081908190819061050d81610acf565b151561051857600080fd5b80546001820154600290920154600160a060020a03909116986fffffffffffffffffffffffffffffffff8084169950700100000000000000000000000000000000909304909216965067ffffffffffffffff808216965068010000000000000000909104169350915050565b60025481565b60008054600160a060020a031633146105a257600080fd5b60005460a060020a900460ff16156105b957600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a150600190565b6000805460a060020a900460ff16151561062357600080fd5b600054600160a060020a0316331461063a57600080fd5b50600081815260036020526040902061065281610acf565b151561065d57600080fd5b8054610474908390600160a060020a0316610af0565b600054600160a060020a031681565b60008181526003602052604081209061069a82610acf565b15156106a557600080fd5b508054600160a060020a03163381146106bd57600080fd5b6106c78382610af0565b505050565b60008181526003602052604081206106e381610acf565b15156106ee57600080fd5b6106f781610b3a565b9392505050565b600154600160a060020a031681565b600054600160a060020a0316331461072457600080fd5b600160a060020a0381161561075c576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b50565b600154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015230602483015260448201859052915191909216916323b872dd91606480830192600092919082900301818387803b1580156107d357600080fd5b505af11580156103a9573d6000803e3d6000fd5b603c816060015167ffffffffffffffff161015151561080557600080fd5b60008281526003602090815260409182902083518154600160a060020a0390911673ffffffffffffffffffffffffffffffffffffffff1990911617815581840151600182018054858701516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000081029482166fffffffffffffffffffffffffffffffff19909316831790911693909317909155606080870151600290940180546080808a015167ffffffffffffffff90811668010000000000000000026fffffffffffffffff0000000000000000199190981667ffffffffffffffff1990931683171696909617909155865189815295860192909252848601929092529083015291517fa9c8dfcda5664a5a124c713e386da27de87432d5b668e79458501eb296389ba7929181900390910190a15050565b6000828152600360205260408120818080808061095786610acf565b151561096257600080fd5b61096b86610b3a565b94508488101561097a57600080fd5b8554600160a060020a0316935061099089610bca565b60008511156109e2576109a285610c17565b6040519093508386039250600160a060020a0385169083156108fc029084906000818181858888f193505050501580156109e0573d6000803e3d6000fd5b505b5060405184880390339082156108fc029083906000818181858888f19350505050158015610a14573d6000803e3d6000fd5b50604080518a815260208101879052338183015290517f4fcc30d90a842164dd58501ab874a101a3749c3d4747139cefe7c876f4ccebd29181900360600190a15092979650505050505050565b600154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152602482018590529151919092169163a9059cbb91604480830192600092919082900301818387803b1580156107d357600080fd5b6002015460006801000000000000000090910467ffffffffffffffff161190565b610af982610bca565b610b038183610a61565b6040805183815290517f2809c7e17bf978fbc7194c0a694b638c4215e9140cacc6c38ca36010b45697df9181900360200190a15050565b6002810154600090819068010000000000000000900467ffffffffffffffff16421115610b805750600282015468010000000000000000900467ffffffffffffffff1642035b600183015460028401546106f7916fffffffffffffffffffffffffffffffff80821692700100000000000000000000000000000000909204169067ffffffffffffffff1684610c23565b6000908152600360205260408120805473ffffffffffffffffffffffffffffffffffffffff19168155600181019190915560020180546fffffffffffffffffffffffffffffffff19169055565b60025461271091020490565b6000808080858510610c3757869350610c55565b878703925085858402811515610c4957fe5b05915081880190508093505b505050949350505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152905600a165627a7a723058208d1842c4569ecc7005642ae981f6c77b856b1d9a921f3792bdb4219144ae25e00029" + kittyCoreAddressAndCut; + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"},{\"name\":\"_startingPrice\",\"type\":\"uint256\"},{\"name\":\"_endingPrice\",\"type\":\"uint256\"},{\"name\":\"_duration\",\"type\":\"uint256\"},{\"name\":\"_seller\",\"type\":\"address\"}],\"name\":\"createAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"unpause\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"bid\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isSiringClockAuction\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getAuction\",\"outputs\":[{\"name\":\"seller\",\"type\":\"address\"},{\"name\":\"startingPrice\",\"type\":\"uint256\"},{\"name\":\"endingPrice\",\"type\":\"uint256\"},{\"name\":\"duration\",\"type\":\"uint256\"},{\"name\":\"startedAt\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ownerCut\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pause\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"cancelAuctionWhenPaused\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"cancelAuction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"getCurrentPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"nonFungibleContract\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_nftAddr\",\"type\":\"address\"},{\"name\":\"_cut\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"startingPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"endingPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"AuctionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"totalPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"winner\",\"type\":\"address\"}],\"name\":\"AuctionSuccessful\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"AuctionCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Pause\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Unpause\",\"type\":\"event\"}]"; + logger.info("Siring Clock Auction"); + siringClockAuctionContractAddress = PublicMethed.deployContract(contractName,abi,code, + "",maxFeeLimit, 0L, consumeUserResourcePercent,null,deployKey, + deployAddress,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(siringClockAuctionContractAddress, + blockingStubFull); + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(deployAddress,blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(deployKey,blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @Test(enabled = false) + public void deployGeneScienceInterface() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(deployAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(deployKey,blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "GeneScienceInterface"; + String code = "608060405234801561001057600080fd5b5060dc8061001f6000396000f30060806040526004361060485763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630d9f5aed8114604d57806354c15b8214607a575b600080fd5b348015605857600080fd5b50606860043560243560443560a0565b60408051918252519081900360200190f35b348015608557600080fd5b50608c60ab565b604080519115158252519081900360200190f35b600292909101010490565b6001905600a165627a7a72305820d9550024d511527e5124d542daf0a0f3168b9bece6a238bcbccba8b61d3f0bdb0029"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"genes1\",\"type\":\"uint256\"},{\"name\":\"genes2\",\"type\":\"uint256\"},{\"name\":\"targetBlock\",\"type\":\"uint256\"}],\"name\":\"mixGenes\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isGeneScience\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]"; + logger.info("gene Science Interface"); + geneScienceInterfaceContractAddress = PublicMethed.deployContract(contractName,abi,code, + "",maxFeeLimit, + 0L, consumeUserResourcePercent,null,deployKey,deployAddress,blockingStubFull); + SmartContract smartContract = PublicMethed.getContract(geneScienceInterfaceContractAddress, + blockingStubFull); + Assert.assertTrue(smartContract.getAbi() != null); + accountResource = PublicMethed.getAccountResource(deployAddress,blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(deployKey,blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + } + + @Test(enabled = false) + public void triggerToSetThreeContractAddressToKittyCore() { + //Set SaleAuctionAddress to kitty core. + String saleContractString = "\"" + Base58.encode58Check(saleClockAuctionContractAddress) + "\""; + txid = PublicMethed.triggerContract(kittyCoreContractAddress,"setSaleAuctionAddress(address)",saleContractString,false, 0,10000000L,deployAddress,deployKey,blockingStubFull); + logger.info(txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + //Assert.assertTrue(infoById.get().getReceipt().getStorageDelta() > 50); + + //Set SiringAuctionAddress to kitty core. + String siringContractString = "\"" + Base58.encode58Check(siringClockAuctionContractAddress) + + "\""; + txid = PublicMethed.triggerContract(kittyCoreContractAddress,"setSiringAuctionAddress(address)",siringContractString,false, 0,10000000L,deployAddress,deployKey,blockingStubFull); + logger.info(txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + //Assert.assertTrue(infoById.get().getReceipt().getStorageDelta() > 50); + + //Set gen contract to kitty core + String genContractString = "\"" + Base58.encode58Check(geneScienceInterfaceContractAddress) + + "\""; + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "setGeneScienceAddress(address)",genContractString, + false, 0,10000000L,deployAddress,deployKey,blockingStubFull); + logger.info(txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + //Assert.assertTrue(infoById.get().getReceipt().getStorageDelta() > 50); + + //Start the game. + txid = PublicMethed.triggerContract(kittyCoreContractAddress,"unpause()","",false, 0, + 10000000L,deployAddress,deployKey,blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + logger.info("start the game " + txid); + + //Create one gen0 cat. + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "createGen0Auction(uint256)","-1000000000000000",false, + 0,100000000L,deployAddress,deployKey,blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "gen0CreatedCount()","#",false, + 0,100000000L,deployAddress,deployKey,blockingStubFull); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + /* txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "name()","#",false,0,10000000,triggerAddress, + triggerKey,blockingStubFull); + logger.info("getname " + txid);*/ + + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "getKitty(uint256)","1",false,0,10000000,triggerAddress, + triggerKey,blockingStubFull); + logger.info("getKitty " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + + + String newCxoAddress = "\"" + Base58.encode58Check(triggerAddress) + + "\""; + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "setCOO(address)",newCxoAddress,false,0,10000000,deployAddress, + deployKey,blockingStubFull); + logger.info("COO " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "setCFO(address)",newCxoAddress,false,0,10000000,deployAddress, + deployKey,blockingStubFull); + logger.info("CFO " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "setCEO(address)",newCxoAddress,false,0,1000000,deployAddress, + deployKey,blockingStubFull); + logger.info("CEO " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0); + } + + @Test(enabled = false,threadPoolSize = 1, invocationCount = 1) + public void unCreateKitty() { + Integer times = 0; + logger.info("In create kitty, kitty core address is " + ByteArray + .toHexString(kittyCoreContractAddress)); + while (times++ < 2) { + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "createGen0Auction(uint256)","0",false, + 0,100000000L,triggerAddress,triggerKey,blockingStubFull); + logger.info("createGen0 " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + //Assert.assertTrue(infoById.get().getResultValue() == 0); + /* String promoKitty = "\"" + times.toString() + "\",\"" + + Base58.encode58Check(kittyCoreContractAddress) + "\""; + logger.info(promoKitty); + txid = PublicMethed.triggerContract(kittyCoreContractAddress, + "createPromoKitty(uint256,address)", promoKitty,false, + 0,10000000L,triggerAddress,triggerKey,blockingStubFull); + logger.info("createPromoKitty " + txid); + infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + Assert.assertTrue(infoById.get().getResultValue() == 0);*/ + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //infoById = PublicMethed.getTransactionInfoById(txid,blockingStubFull); + } + + } + + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/onlineStress/TestNetFomo3D.java b/src/test/java/stest/tron/wallet/onlineStress/TestNetFomo3D.java new file mode 100644 index 00000000000..3759ac33426 --- /dev/null +++ b/src/test/java/stest/tron/wallet/onlineStress/TestNetFomo3D.java @@ -0,0 +1,114 @@ +package stest.tron.wallet.onlinestress; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.tron.api.GrpcAPI.AccountResourceMessage; +import org.tron.api.WalletGrpc; +import org.tron.core.Wallet; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.SmartContract; +import stest.tron.wallet.common.client.Configuration; +import stest.tron.wallet.common.client.Parameter.CommonConstant; +import stest.tron.wallet.common.client.utils.PublicMethed; + +@Slf4j +public class TestNetFomo3D { + + //testng001、testng002、testng003、testng004 + private final String testNetAccountKey = + "FC8BF0238748587B9617EB6D15D47A66C0E07C1A1959033CF249C6532DC29FE6"; + //"BC70ADC5A0971BA3F7871FBB7249E345D84CE7E5458828BE1E28BF8F98F2795B"; + private final byte[] testNetAccountAddress = PublicMethed.getFinalAddress(testNetAccountKey); + + private ManagedChannel channelFull = null; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private String fullnode = Configuration.getByPath("testng.conf") + .getStringList("fullnode.ip.list").get(0); + + + @BeforeSuite + public void beforeSuite() { + Wallet wallet = new Wallet(); + Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); + } + + @BeforeClass(enabled = false) + public void beforeClass() { + PublicMethed.printAddress(testNetAccountKey); + channelFull = ManagedChannelBuilder.forTarget(fullnode) + .usePlaintext(true) + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + logger.info(Long.toString(PublicMethed.queryAccount(testNetAccountKey,blockingStubFull) + .getBalance())); + Assert.assertTrue(PublicMethed.freezeBalanceGetEnergy(testNetAccountAddress,10000000L, + 3,1,testNetAccountKey,blockingStubFull)); + /* Assert.assertTrue(PublicMethed.buyStorage(50000000L,testNetAccountAddress,testNetAccountKey, + blockingStubFull));*/ + + } + + @Test(enabled = false) + public void deployErc721CryptoKitties() { + AccountResourceMessage accountResource = PublicMethed.getAccountResource(testNetAccountAddress, + blockingStubFull); + Long cpuLimit = accountResource.getEnergyLimit(); + //Long storageLimit = accountResource.getStorageLimit(); + Long cpuUsage = accountResource.getEnergyUsed(); + //Long storageUsage = accountResource.getStorageUsed(); + Account account = PublicMethed.queryAccount(testNetAccountKey,blockingStubFull); + logger.info("before balance is " + Long.toString(account.getBalance())); + logger.info("before cpu limit is " + Long.toString(cpuLimit)); + logger.info("before cpu usage is " + Long.toString(cpuUsage)); + //logger.info("before storage limit is " + Long.toString(storageLimit)); + //logger.info("before storage usaged is " + Long.toString(storageUsage)); + Long maxFeeLimit = 3900000000L; + String contractName = "Fomo3D"; + String code = "60c0604052600660808190527f464f4d4f3344000000000000000000000000000000000000000000000000000060a0908152620000409160009190620000b3565b506040805180820190915260038082527f463344000000000000000000000000000000000000000000000000000000000060209092019182526200008791600191620000b3565b506305f5e1006002556000600855600b805460ff19169055348015620000ac57600080fd5b5062000158565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620000f657805160ff191683800117855562000126565b8280016001018555821562000126579182015b828111156200012657825182559160200191906001019062000109565b506200013492915062000138565b5090565b6200015591905b808211156200013457600081556001016200013f565b90565b61165980620001686000396000f3006080604052600436106101685763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166265318b811461017657806306fdde03146101a957806310d0ffdd1461023357806318160ddd1461024b578063226093731461026057806327defa1f14610278578063313ce567146102a1578063392efb52146102cc5780633ccfd60b146102e45780634b750334146102fb57806356d399e814610310578063688abbf7146103255780636b2f46321461033f57806370a08231146103545780638328b610146103755780638620410b1461038d57806389135ae9146103a25780638fea64bd146103bf578063949e8acd146103d457806395d89b41146103e9578063a8e04f34146103fe578063a9059cbb14610413578063b84c824614610437578063c47f002714610490578063e4849b32146104e9578063e9fad8ee14610501578063f088d54714610516578063fdb5a03e1461052a575b61017334600061053f565b50005b34801561018257600080fd5b50610197600160a060020a0360043516610b15565b60408051918252519081900360200190f35b3480156101b557600080fd5b506101be610b50565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101f85781810151838201526020016101e0565b50505050905090810190601f1680156102255780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023f57600080fd5b50610197600435610bde565b34801561025757600080fd5b50610197610c0e565b34801561026c57600080fd5b50610197600435610c15565b34801561028457600080fd5b5061028d610c4e565b604080519115158252519081900360200190f35b3480156102ad57600080fd5b506102b6610c57565b6040805160ff9092168252519081900360200190f35b3480156102d857600080fd5b5061028d600435610c5c565b3480156102f057600080fd5b506102f9610c71565b005b34801561030757600080fd5b50610197610d44565b34801561031c57600080fd5b50610197610d93565b34801561033157600080fd5b506101976004351515610d99565b34801561034b57600080fd5b50610197610ddc565b34801561036057600080fd5b50610197600160a060020a0360043516610de1565b34801561038157600080fd5b506102f9600435610dfc565b34801561039957600080fd5b50610197610e43565b3480156103ae57600080fd5b506102f96004356024351515610e87565b3480156103cb57600080fd5b506102f9610ee9565b3480156103e057600080fd5b50610197610eeb565b3480156103f557600080fd5b506101be610efe565b34801561040a57600080fd5b506102f9610f58565b34801561041f57600080fd5b5061028d600160a060020a0360043516602435610fa6565b34801561044357600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102f99436949293602493928401919081908401838280828437509497506111609650505050505050565b34801561049c57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102f99436949293602493928401919081908401838280828437509497506111b99650505050505050565b3480156104f557600080fd5b506102f960043561120d565b34801561050d57600080fd5b506102f961135e565b610197600160a060020a036004351661138b565b34801561053657600080fd5b506102f9611397565b60008060008060008060008060008a6000339050600b60009054906101000a900460ff16801561058157506801158e460913d000008261057d610ddc565b0311155b1561088e57600160a060020a03811660009081526003602052604090205460ff16151560011480156105d65750600160a060020a038116600090815260076020526040902054670de0b6b3a764000090830111155b15156105e157600080fd5b600160a060020a038116600090815260076020526040902054610604908361144d565b600160a060020a03821660009081526007602052604090205533995061062b8d6005611463565b9850610638896003611463565b9750610644898961147a565b96506106508d8a61147a565b955061065b8661148c565b945068010000000000000000870293506000851180156106855750600854610683868261144d565b115b151561069057600080fd5b600160a060020a038c16158015906106ba575089600160a060020a03168c600160a060020a031614155b80156106e05750600254600160a060020a038d1660009081526004602052604090205410155b1561072657600160a060020a038c16600090815260056020526040902054610708908961144d565b600160a060020a038d16600090815260056020526040902055610741565b610730878961144d565b965068010000000000000000870293505b600060085411156107a5576107586008548661144d565b600881905568010000000000000000880281151561077257fe5b6009805492909104909101905560085468010000000000000000880281151561079757fe5b0485028403840393506107ab565b60088590555b600160a060020a038a166000908152600460205260409020546107ce908661144d565b600460008c600160a060020a0316600160a060020a031681526020019081526020016000208190555083856009540203925082600660008c600160a060020a0316600160a060020a03168152602001908152602001600020600082825401925050819055508b600160a060020a03168a600160a060020a03167f022c0d992e4d873a3748436d960d5140c1f9721cf73f7ca5ec679d3d9f4fe2d58f88604051808381526020018281526020019250505060405180910390a3849a50610b05565b600b805460ff191690553399506108a68d6005611463565b98506108b3896003611463565b97506108bf898961147a565b96506108cb8d8a61147a565b95506108d68661148c565b9450680100000000000000008702935060008511801561090057506008546108fe868261144d565b115b151561090b57600080fd5b600160a060020a038c1615801590610935575089600160a060020a03168c600160a060020a031614155b801561095b5750600254600160a060020a038d1660009081526004602052604090205410155b156109a157600160a060020a038c16600090815260056020526040902054610983908961144d565b600160a060020a038d166000908152600560205260409020556109bc565b6109ab878961144d565b965068010000000000000000870293505b60006008541115610a20576109d36008548661144d565b60088190556801000000000000000088028115156109ed57fe5b60098054929091049091019055600854680100000000000000008802811515610a1257fe5b048502840384039350610a26565b60088590555b600160a060020a038a16600090815260046020526040902054610a49908661144d565b600460008c600160a060020a0316600160a060020a031681526020019081526020016000208190555083856009540203925082600660008c600160a060020a0316600160a060020a03168152602001908152602001600020600082825401925050819055508b600160a060020a03168a600160a060020a03167f022c0d992e4d873a3748436d960d5140c1f9721cf73f7ca5ec679d3d9f4fe2d58f88604051808381526020018281526020019250505060405180910390a3849a505b5050505050505050505092915050565b600160a060020a0316600090815260066020908152604080832054600490925290912054600954680100000000000000009102919091030490565b6000805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610bd65780601f10610bab57610100808354040283529160200191610bd6565b820191906000526020600020905b815481529060010190602001808311610bb957829003601f168201915b505050505081565b6000808080610bee856005611463565b9250610bfa858461147a565b9150610c058261148c565b95945050505050565b6008545b90565b6000806000806008548511151515610c2c57600080fd5b610c3585611508565b9250610c42836005611463565b9150610c05838361147a565b600b5460ff1681565b600681565b600a6020526000908152604090205460ff1681565b6000806000610c806001610d99565b11610c8a57600080fd5b339150610c976000610d99565b600160a060020a038316600081815260066020908152604080832080546801000000000000000087020190556005909152808220805490839055905193019350909183156108fc0291849190818181858888f19350505050158015610d00573d6000803e3d6000fd5b50604080518281529051600160a060020a038416917fccad973dcd043c7d680389db4378bd6b9775db7124092e9e0422c9e46d7985dc919081900360200190a25050565b60008060008060085460001415610d625764d18c2e28009350610d8d565b610d6e620f4240611508565b9250610d7b836005611463565b9150610d87838361147a565b90508093505b50505090565b60025481565b60003382610daf57610daa81610b15565b610dd3565b600160a060020a038116600090815260056020526040902054610dd182610b15565b015b91505b50919050565b303190565b600160a060020a031660009081526004602052604090205490565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff161515610e3d57600080fd5b50600255565b60008060008060085460001415610e62576501001d1bf8009350610d8d565b610e6e620f4240611508565b9250610e7b836005611463565b9150610d87838361144d565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff161515610ec857600080fd5b506000918252600a6020526040909120805460ff1916911515919091179055565b565b600033610ef781610de1565b91505b5090565b60018054604080516020600284861615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610bd65780601f10610bab57610100808354040283529160200191610bd6565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff161515610f9957600080fd5b50600b805460ff19169055565b600080600080600080610fb7610eeb565b11610fc157600080fd5b600b5433945060ff16158015610fef5750600160a060020a0384166000908152600460205260409020548611155b1515610ffa57600080fd5b60006110066001610d99565b111561101457611014610c71565b61101f866005611463565b925061102b868461147a565b915061103683611508565b90506110446008548461147a565b600855600160a060020a03841660009081526004602052604090205461106a908761147a565b600160a060020a038086166000908152600460205260408082209390935590891681522054611099908361144d565b600160a060020a0388811660008181526004602090815260408083209590955560098054948a16835260069091528482208054948c0290940390935582549181529290922080549285029092019091555460085461110d919068010000000000000000840281151561110757fe5b0461144d565b600955604080518381529051600160a060020a03808a1692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35060019695505050505050565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff1615156111a157600080fd5b81516111b490600190602085019061159f565b505050565b604080516c010000000000000000000000003390810282528251918290036014019091206000908152600a602052919091205460ff1615156111fa57600080fd5b81516111b490600090602085019061159f565b6000806000806000806000611220610eeb565b1161122a57600080fd5b3360008181526004602052604090205490965087111561124957600080fd5b86945061125585611508565b9350611262846005611463565b925061126e848461147a565b915061127c6008548661147a565b600855600160a060020a0386166000908152600460205260409020546112a2908661147a565b600160a060020a038716600090815260046020908152604080832093909355600954600690915291812080549288026801000000000000000086020192839003905560085491925010156113125761130e60095460085468010000000000000000860281151561110757fe5b6009555b60408051868152602081018490528151600160a060020a038916927fc4823739c5787d2ca17e404aa47d5569ae71dfb49cbf21b3f6152ed238a31139928290030190a250505050505050565b336000818152600460205260408120549081111561137f5761137f8161120d565b611387610c71565b5050565b6000610dd6348361053f565b6000806000806113a76001610d99565b116113b157600080fd5b6113bb6000610d99565b336000818152600660209081526040808320805468010000000000000000870201905560059091528120805490829055909201945092506113fd90849061053f565b905081600160a060020a03167fbe339fc14b041c2b0e0f3dd2cd325d0c3668b78378001e53160eab36153264588483604051808381526020018281526020019250505060405180910390a2505050565b60008282018381101561145c57fe5b9392505050565b600080828481151561147157fe5b04949350505050565b60008282111561148657fe5b50900390565b600854600090670de0b6b3a764000090829064174876e8006114f56114ef692a5a058fc295ed000000880269021e19e0c9bab24000006002860a02016c02863c1f5cdae42f95400000008502016ec097ce7bc90715b34b9f10000000000161156a565b8561147a565b8115156114fe57fe5b0403949350505050565b600854600090620f424083810191810190839061155764d18c2e280082850464174876e80002018702600283620f423f1982890a8b9003010464174876e8000281151561155157fe5b0461147a565b81151561156057fe5b0495945050505050565b80600260018201045b81811015610dd657809150600281828581151561158c57fe5b040181151561159757fe5b049050611573565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106115e057805160ff191683800117855561160d565b8280016001018555821561160d579182015b8281111561160d5782518255916020019190600101906115f2565b50610efa92610c129250905b80821115610efa57600081556001016116195600a165627a7a72305820bf757ace6c45263e75b0a8eb6c539065f0ca610f7bf4378df93a0eff2d0551060029"; + String abi = "[{\"constant\":true,\"inputs\":[{\"name\":\"_customerAddress\",\"type\":\"address\"}],\"name\":\"dividendsOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_ethereumToSpend\",\"type\":\"uint256\"}],\"name\":\"calculateTokensReceived\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_tokensToSell\",\"type\":\"uint256\"}],\"name\":\"calculateEthereumReceived\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"onlyAmbassadors\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"administrators\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"sellPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"stakingRequirement\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_includeReferralBonus\",\"type\":\"bool\"}],\"name\":\"myDividends\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalEthereumBalance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_customerAddress\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_amountOfTokens\",\"type\":\"uint256\"}],\"name\":\"setStakingRequirement\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"buyPrice\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_identifier\",\"type\":\"bytes32\"},{\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"setAdministrator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"Hourglass\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"myTokens\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"disableInitialStage\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_toAddress\",\"type\":\"address\"},{\"name\":\"_amountOfTokens\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"setSymbol\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_amountOfTokens\",\"type\":\"uint256\"}],\"name\":\"sell\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"exit\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_referredBy\",\"type\":\"address\"}],\"name\":\"buy\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"reinvest\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"customerAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"incomingEthereum\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tokensMinted\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"referredBy\",\"type\":\"address\"}],\"name\":\"onTokenPurchase\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"customerAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokensBurned\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"ethereumEarned\",\"type\":\"uint256\"}],\"name\":\"onTokenSell\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"customerAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"ethereumReinvested\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tokensMinted\",\"type\":\"uint256\"}],\"name\":\"onReinvestment\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"customerAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"ethereumWithdrawn\",\"type\":\"uint256\"}],\"name\":\"onWithdraw\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"}]"; + + byte[] contractAddress = PublicMethed.deployContract(contractName,abi,code,"",maxFeeLimit, + 0L, 100,null,testNetAccountKey,testNetAccountAddress,blockingStubFull); + final SmartContract smartContract = PublicMethed.getContract(contractAddress,blockingStubFull); + accountResource = PublicMethed.getAccountResource(testNetAccountAddress,blockingStubFull); + cpuLimit = accountResource.getEnergyLimit(); + //storageLimit = accountResource.getStorageLimit(); + cpuUsage = accountResource.getEnergyUsed(); + //storageUsage = accountResource.getStorageUsed(); + account = PublicMethed.queryAccount(testNetAccountKey,blockingStubFull); + logger.info("after balance is " + Long.toString(account.getBalance())); + logger.info("after cpu limit is " + Long.toString(cpuLimit)); + logger.info("after cpu usage is " + Long.toString(cpuUsage)); + //logger.info("after storage limit is " + Long.toString(storageLimit)); + //logger.info("after storage usaged is " + Long.toString(storageUsage)); + //Assert.assertTrue(storageUsage > 0); + //Assert.assertTrue(storageLimit > 0); + Assert.assertTrue(cpuLimit > 0); + Assert.assertTrue(cpuUsage > 0); + + Assert.assertFalse(smartContract.getAbi().toString().isEmpty()); + Assert.assertTrue(smartContract.getName().equalsIgnoreCase(contractName)); + Assert.assertFalse(smartContract.getBytecode().toString().isEmpty()); + //logger.info(smartContract.getName()); + //logger.info(smartContract.getAbi().toString()); + + + + } + + @AfterClass + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + } +} + + diff --git a/src/test/java/stest/tron/wallet/transfer/WalletTestTransfer001.java b/src/test/java/stest/tron/wallet/transfer/WalletTestTransfer001.java index 823ea75e97d..2c087b0abf4 100644 --- a/src/test/java/stest/tron/wallet/transfer/WalletTestTransfer001.java +++ b/src/test/java/stest/tron/wallet/transfer/WalletTestTransfer001.java @@ -114,6 +114,7 @@ public void testSendCoin() { receiptAccount = PublicMethed.queryAccount(receiptAccountKey,blockingStubFull); Long receiptAccountAfterBalance = receiptAccount.getBalance(); + logger.info(Long.toString(receiptAccountAfterBalance)); Assert.assertTrue(receiptAccountAfterBalance == 49880000000L); diff --git a/src/test/java/stest/tron/wallet/wallettestp0/WallettestP0001.java b/src/test/java/stest/tron/wallet/wallettestp0/WallettestP0001.java index 802eeb0d74b..ee32f91ca58 100644 --- a/src/test/java/stest/tron/wallet/wallettestp0/WallettestP0001.java +++ b/src/test/java/stest/tron/wallet/wallettestp0/WallettestP0001.java @@ -73,7 +73,7 @@ public void beforeSuite() { Wallet.setAddressPreFixByte(CommonConstant.ADD_PRE_FIX_BYTE_MAINNET); } - @BeforeClass + @BeforeClass(enabled = false) public void beforeClass() { walletClient = new WalletClient(testKey002); walletClient.init(0); @@ -192,7 +192,7 @@ public boolean checkEnv() { return true; } - @Test(enabled = true) + @Test(enabled = false) public void checkNode() { Optional result = walletClient.listNodes(); @@ -210,7 +210,7 @@ public void checkNode() { } - @AfterClass(enabled = true) + @AfterClass(enabled = false) public void shutdown() throws InterruptedException { if (channelFull != null) { channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); diff --git a/src/test/java/stest/tron/wallet/witness/WalletTestWitness001.java b/src/test/java/stest/tron/wallet/witness/WalletTestWitness001.java index 1b097b48c30..a6e9c68594e 100644 --- a/src/test/java/stest/tron/wallet/witness/WalletTestWitness001.java +++ b/src/test/java/stest/tron/wallet/witness/WalletTestWitness001.java @@ -82,7 +82,7 @@ public void beforeClass() { searchBlockingStubFull = WalletGrpc.newBlockingStub(searchChannelFull); } - @Test(enabled = false) + @Test(enabled = true) public void testVoteWitness() { Base58.encode58Check(fromAddress); logger.info(Base58.encode58Check(fromAddress)); diff --git a/src/test/resources/testng.conf b/src/test/resources/testng.conf index e7bcad09e14..07e9850c5fc 100644 --- a/src/test/resources/testng.conf +++ b/src/test/resources/testng.conf @@ -14,8 +14,8 @@ fullnode = { #MainNet #"54.236.37.243:50051", #"52.53.189.99:50051", - #TestNet - + #testnet + #"47.254.144.25:50051", ] } diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index 0b3302792c7..0186430e7e1 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -2,13 +2,16 @@ + + + \ No newline at end of file