diff --git a/.codeclimate.yml b/.codeclimate.yml index 72109288061..164135dd2de 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,6 +1,6 @@ -version: "2" -plugins: - sonar-java: - enabled: true - config: +version: "2" +plugins: + sonar-java: + enabled: true + config: sonar.java.source: 8 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 653abf1be53..0b036c33f9f 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,13 +1,13 @@ -Please answer these questions before submitting your issue. Thanks! - -1. What did you do? -If possible, provide a recipe for reproducing the error. - - -2. What did you expect to see? - - - -3. What did you see instead? - - +Please answer these questions before submitting your issue. Thanks! + +1. What did you do? +If possible, provide a recipe for reproducing the error. + + +2. What did you expect to see? + + + +3. What did you see instead? + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8eabd5369c9..7166b0949a5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,12 +1,12 @@ -**What does this PR do?** - -**Why are these changes required?** - -**This PR has been tested by:** -- Unit Tests -- Manual Testing - -**Follow up** - -**Extra details** - +**What does this PR do?** + +**Why are these changes required?** + +**This PR has been tested by:** +- Unit Tests +- Manual Testing + +**Follow up** + +**Extra details** + diff --git a/README.md b/README.md index 547c0ab3af1..15d2adbaaed 100644 --- a/README.md +++ b/README.md @@ -19,101 +19,15 @@ TRON is a block chain-based decentralized smart protocol and an application deve TRON is a product of Web 4.0 and the decentralized internet of next generation. -# Quick Start - -> Note: This repository is a IDEA project which you can simply download and import. - -**Download and build** - -```shell -> git clone https://github.com/tronprotocol/java-tron.git -> cd java-tron -> gradle build -``` - -**Import project to IDEA** - -- [File] -> [New] -> [Project from Existing Sources...] -- Select java-tron/build.gradle -- Dialog [Import Project from Gradle], confirm [Use auto-import] and [Use gradle wrapper task configuration] have been - selected,then select Gradle JVM(JDK 1.8)and click [OK] - -# Testing - -**Install Kafka and create two topics (block and transaction)** + -**Update the configuration** - - -**Starting program** - -IDEA: -- [Edit Configurations...] -> [Add New Configuration] -> [Application] -- [Edit Configurations...] -> [Main Class]: `org.tron.example.Tron` -- [Edit Configurations...] -> [Use classpath of module]: `java-tron_main` -- [Edit Configurations...] -> [Program arguments]: `--type server` -- Run - -![run](https://github.com/tronprotocol/wiki/blob/master/images/commands/default-set.gif) - -or simply from terminal: -- ./gradlew run -Pserver=true - -**Complete process** +# Quick Start -![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/process.gif) +Read the [Quick Srart](http://wiki.tron.network/en/latest/quick_start.html). -**Other nodes to join need to modify the connection ip** -![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/node-ip.gif) # Commands -**help** - -| Description | Example | -| --- | --- | -| Help tips | `help` | - -![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/help.gif) - -**account** - -| Description | Example | -| --- | --- | -| Get address | `account` | - -![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/account.gif) - -**getbalance** - -| Description | Example | -| --- | --- | -| Get balance | `getbalance` | - -![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/getbalance.gif) - -**send [to] [balance]** - -| Description | Example | -| --- | --- | -| Send balance to address | `send 2cddf5707aefefb199cb16430fb0f6220d460dfe 2` | - -![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/send1.gif) - -**printblockchain** - -| Description | Example | -| --- | --- | -| Print blockchain | `printblockchain`| - -![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/printblockchain.gif) - -**exit** - -| Description | Example | -| --- | --- | -| Exit | `exit` | - -![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/exit.gif) +Read the [Commands](http://wiki.tron.network/en/latest/quick_start.html#commands). # Contact diff --git a/build.gradle b/build.gradle index 519dbc2702d..c7045bbb356 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ apply plugin: 'application' apply plugin: 'checkstyle' sourceCompatibility = 1.8 -mainClassName = 'org.tron.program.example.Tron' +mainClassName = 'org.tron.program.FullNode' repositories { mavenCentral() @@ -112,8 +112,9 @@ dependencies { compile group: 'io.grpc', name: 'grpc-stub', version: '1.9.0' // end google grpc - - + compile group: 'io.scalecube', name: 'scalecube-services', version: '1.0.7' + compile group: 'io.scalecube', name: 'scalecube-cluster', version: '1.0.7' + compile group: 'io.scalecube', name: 'scalecube-transport', version: '1.0.7' } task lint(type: Checkstyle) { @@ -148,9 +149,9 @@ sourceSets { proto { - srcDir 'src/proto' - } + srcDir 'src/proto' } + } } @@ -171,7 +172,7 @@ protobuf { generateProtoTasks { all().each { task -> task.builtins { - java {outputSubDir = "gen"} + java { outputSubDir = "gen" } } } all()*.plugins { diff --git a/docker/Dockerfile b/docker/Dockerfile index 824c8a8745c..a069a3351f4 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,7 +2,7 @@ FROM tronprotocol/centos7-jdk8 MAINTAINER tronprotocol # Install dependencies && Download java-tron -RUN yum update && \ +RUN yum update -y && \ yum install -y git && \ git clone https://github.com/tronprotocol/java-tron.git /home/java-tron diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4c637cca379..92165eede80 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 diff --git a/src/main/java/org/tron/common/application/Application.java b/src/main/java/org/tron/common/application/Application.java index 8eaaadb07d2..1d8dbf5920f 100644 --- a/src/main/java/org/tron/common/application/Application.java +++ b/src/main/java/org/tron/common/application/Application.java @@ -12,59 +12,32 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package org.tron.common.application; -import com.google.inject.Injector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.tron.core.db.BlockStore; import org.tron.core.net.node.Node; -import org.tron.core.net.node.NodeImpl; - -public class Application { - - private static final Logger logger = LoggerFactory.getLogger("Application"); - private Injector injector; - - private NodeImpl p2pnode; +import org.tron.program.Args; - private ServiceContainer services; +public interface Application { - public Application(Injector injector) { - this.injector = injector; + void setOptions(Args args); - } + void init(String path, Args args); - public Application() { - this.services = new ServiceContainer(); - p2pnode = new NodeImpl(); - } + void initServices(Args args); - public Injector getInjector() { - return injector; - } + void startup(); - public void addService(Service service) { - this.services.add(service); - } + void shutdown(); - public BlockStore getBlockStoreS() { - return p2pnode.getBlockdb(); - } + void startServies(); - public Node getP2pNode() { - return p2pnode.getP2pNode(); - } - public void run() { - p2pnode.start(); - this.services.start(); - } + void shutdownServices(); + Node getP2pNode(); - public void shutdown() { - logger.info("shutting down"); - this.services.stop(); - System.exit(0); - } + BlockStore getBlockStoreS(); + void addService(Service service); } diff --git a/src/main/java/org/tron/common/application/ApplicationFactory.java b/src/main/java/org/tron/common/application/ApplicationFactory.java index 76dd1fdf27f..de353505b7e 100644 --- a/src/main/java/org/tron/common/application/ApplicationFactory.java +++ b/src/main/java/org/tron/common/application/ApplicationFactory.java @@ -12,6 +12,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package org.tron.common.application; import com.google.inject.Guice; @@ -20,7 +21,7 @@ public class ApplicationFactory { /** - * Build a Guice instance + * Build a Guice instance. * * @return Guice */ @@ -30,24 +31,19 @@ public Injector buildGuice() { } /** - * Build a new application - * - * @return + * Build a new application. */ public Application build() { - return new Application(buildGuice()); + return new ApplicationImpl(); } /** - * Build a new cli application - * - * @return + * Build a new cli application. */ - public CliApplication buildCli() { - return new CliApplication(buildGuice()); - } - - public static Application create() { - return new Application(); + //public CliApplication buildCli() { + // return new CliApplication(buildGuice()); + //} + public static Application create() { + return new ApplicationImpl(); } } diff --git a/src/main/java/org/tron/common/application/CliApplication.java b/src/main/java/org/tron/common/application/CliApplication.java index 9abdf3d608c..c04a2ac9205 100644 --- a/src/main/java/org/tron/common/application/CliApplication.java +++ b/src/main/java/org/tron/common/application/CliApplication.java @@ -14,17 +14,68 @@ */ package org.tron.common.application; -import com.google.inject.Injector; +import org.tron.core.db.BlockStore; +import org.tron.core.net.node.Node; import org.tron.core.peer.Peer; +import org.tron.program.Args; -public class CliApplication extends Application { +public class CliApplication implements Application { + @Override + public void setOptions(Args args) { - private Peer peer; + } + + @Override + public void init(String path, Args args) { + + } + + @Override + public void initServices(Args args) { + + } + + @Override + public void startup() { + + } + + @Override + public void shutdown() { + + } + + @Override + public void startServies() { + + } + + @Override + public void shutdownServices() { + + } + + @Override + public Node getP2pNode() { + return null; + } + + @Override + public BlockStore getBlockStoreS() { + return null; + } + + @Override + public void addService(Service service) { - public CliApplication(Injector injector) { - super(injector); } + private Peer peer; + +// public CliApplication(Injector injector) { +// super(injector); +// } + public Peer getPeer() { return peer; } diff --git a/src/main/java/org/tron/common/application/Service.java b/src/main/java/org/tron/common/application/Service.java index a123a389ee7..8a38bceb764 100644 --- a/src/main/java/org/tron/common/application/Service.java +++ b/src/main/java/org/tron/common/application/Service.java @@ -15,7 +15,8 @@ package org.tron.common.application; public interface Service { - + void init(); void start(); + void stop(); } diff --git a/src/main/java/org/tron/common/application/ServiceContainer.java b/src/main/java/org/tron/common/application/ServiceContainer.java index 640c7d0cb3e..d39f3a4cfbf 100644 --- a/src/main/java/org/tron/common/application/ServiceContainer.java +++ b/src/main/java/org/tron/common/application/ServiceContainer.java @@ -14,10 +14,11 @@ */ package org.tron.common.application; -import java.util.ArrayList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; + public class ServiceContainer implements Service { private static final Logger logger = LoggerFactory.getLogger("Services"); @@ -31,6 +32,14 @@ public void add(Service service) { this.services.add(service); } + @Override + public void init() { + for (Service service : this.services) { + logger.debug("Initing " + service.getClass().getSimpleName()); + service.init(); + } + } + @Override public void start() { logger.debug("Starting services"); diff --git a/src/main/java/org/tron/common/command/Cli.java b/src/main/java/org/tron/common/command/Cli.java index 7200d791277..01691330aeb 100644 --- a/src/main/java/org/tron/common/command/Cli.java +++ b/src/main/java/org/tron/common/command/Cli.java @@ -15,9 +15,10 @@ package org.tron.common.command; +import org.tron.common.application.CliApplication; + import java.util.Arrays; import java.util.Scanner; -import org.tron.common.application.CliApplication; public class Cli { @@ -50,7 +51,7 @@ public void run(CliApplication app) { new GetBalanceCommand().execute(app, cmdParameters); break; case "send": - app.getInjector().getInstance(ConsensusCommand.class).execute(app, cmdParameters); + //app.getInjector().getInstance(ConsensusCommand.class).execute(app, cmdParameters); break; case "printblockchain": new PrintBlockchainCommand().execute(app, cmdParameters); diff --git a/src/main/java/org/tron/common/command/HelpCommand.java b/src/main/java/org/tron/common/command/HelpCommand.java index 1717b0d8885..4edf1752483 100644 --- a/src/main/java/org/tron/common/command/HelpCommand.java +++ b/src/main/java/org/tron/common/command/HelpCommand.java @@ -15,10 +15,10 @@ package org.tron.common.command; -import static org.fusesource.jansi.Ansi.ansi; - import org.tron.common.application.CliApplication; +import static org.fusesource.jansi.Ansi.ansi; + public class HelpCommand extends Command { public HelpCommand() { @@ -50,7 +50,7 @@ public void execute(CliApplication app, String[] parameters) { break; case "consensus": case "listen": - app.getInjector().getInstance(ConsensusCommand.class).usage(); + //app.getInjector().getInstance(ConsensusCommand.class).usage(); break; case "exit": case "quit": diff --git a/src/main/java/org/tron/common/command/PrintBlockchainCommand.java b/src/main/java/org/tron/common/command/PrintBlockchainCommand.java index abdfc5e24ec..43f9069c7c2 100644 --- a/src/main/java/org/tron/common/command/PrintBlockchainCommand.java +++ b/src/main/java/org/tron/common/command/PrintBlockchainCommand.java @@ -25,19 +25,20 @@ import org.tron.protos.core.TronBlock; public class PrintBlockchainCommand extends Command { + public PrintBlockchainCommand() { } - @Override - public void execute(CliApplication app, String[] parameters) { - Peer peer = app.getPeer(); - Blockchain blockchain = peer.getUTXOSet().getBlockchain(); - BlockchainIterator bi = new BlockchainIterator(blockchain); - while (bi.hasNext()) { - TronBlock.Block block = bi.next(); - System.out.println(BlockUtils.toPrintString(block)); - } + @Override + public void execute(CliApplication app, String[] parameters) { + Peer peer = app.getPeer(); + Blockchain blockchain = peer.getUTXOSet().getBlockchain(); + BlockchainIterator bi = new BlockchainIterator(blockchain); + while (bi.hasNext()) { + TronBlock.Block block = bi.next(); + System.out.println(BlockUtils.toPrintString(block)); } + } @Override public void usage() { diff --git a/src/main/java/org/tron/common/crypto/ECKey.java b/src/main/java/org/tron/common/crypto/ECKey.java index d603d36f5e6..e312b8e5cef 100644 --- a/src/main/java/org/tron/common/crypto/ECKey.java +++ b/src/main/java/org/tron/common/crypto/ECKey.java @@ -18,6 +18,28 @@ package org.tron.common.crypto; +import static org.tron.common.utils.BIUtil.isLessThan; +import static org.tron.common.utils.ByteUtil.bigIntegerToBytes; + +import java.io.IOException; +import java.io.Serializable; +import java.math.BigInteger; +import java.nio.charset.Charset; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.SignatureException; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import javax.annotation.Nullable; +import javax.crypto.KeyAgreement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.asn1.ASN1InputStream; @@ -30,7 +52,11 @@ import org.spongycastle.crypto.digests.SHA256Digest; import org.spongycastle.crypto.engines.AESFastEngine; import org.spongycastle.crypto.modes.SICBlockCipher; -import org.spongycastle.crypto.params.*; +import org.spongycastle.crypto.params.ECDomainParameters; +import org.spongycastle.crypto.params.ECPrivateKeyParameters; +import org.spongycastle.crypto.params.ECPublicKeyParameters; +import org.spongycastle.crypto.params.KeyParameter; +import org.spongycastle.crypto.params.ParametersWithIV; import org.spongycastle.crypto.signers.ECDSASigner; import org.spongycastle.crypto.signers.HMacDSAKCalculator; import org.spongycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; @@ -44,1227 +70,1166 @@ import org.spongycastle.util.BigIntegers; import org.spongycastle.util.encoders.Base64; import org.spongycastle.util.encoders.Hex; -import org.tron.common.crypto.jce.*; +import org.tron.common.crypto.jce.ECKeyAgreement; +import org.tron.common.crypto.jce.ECKeyFactory; +import org.tron.common.crypto.jce.ECKeyPairGenerator; +import org.tron.common.crypto.jce.ECSignatureFactory; +import org.tron.common.crypto.jce.TronCastleProvider; import org.tron.common.utils.ByteUtil; -import javax.annotation.Nullable; -import javax.crypto.KeyAgreement; -import java.io.IOException; -import java.io.Serializable; -import java.math.BigInteger; -import java.nio.charset.Charset; -import java.security.*; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.util.Arrays; - -import static org.tron.common.utils.BIUtil.isLessThan; -import static org.tron.common.utils.ByteUtil.bigIntegerToBytes; - public class ECKey implements Serializable { - /** - * The parameters of the secp256k1 curve. - */ - public static final ECDomainParameters CURVE; - public static final ECParameterSpec CURVE_SPEC; - /** - * Equal to CURVE.getN().shiftRight(1), used for canonicalising the S - * value of a signature. - * ECDSA signatures are mutable in the sense that for a given (R, S) pair, - * then both (R, S) and (R, N - S mod N) are valid signatures. - * Canonical signatures are those where 1 <= S <= N/2 - *

- * See https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki - * #Low_S_values_in_signatures - */ - public static final BigInteger HALF_CURVE_ORDER; - private static final Logger logger = LoggerFactory.getLogger(ECKey.class); - private static final BigInteger SECP256K1N = new BigInteger - ("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16); - private static final SecureRandom secureRandom; - private static final long serialVersionUID = -728224901792295832L; - - static { - // All clients must agree on the curve to use by agreement. - X9ECParameters params = SECNamedCurves.getByName("secp256k1"); - CURVE = new ECDomainParameters(params.getCurve(), params.getG(), - params.getN(), params.getH()); - CURVE_SPEC = new ECParameterSpec(params.getCurve(), params.getG(), - params.getN(), params.getH()); - HALF_CURVE_ORDER = params.getN().shiftRight(1); - secureRandom = new SecureRandom(); - } - protected final ECPoint pub; - // The two parts of the key. If "priv" is set, "pub" can always be - // calculated. If "pub" is set but not "priv", we - // can only verify signatures not make them. - // TODO: Redesign this class to use consistent internals and more - // efficient serialization. - private final PrivateKey privKey; - // the Java Cryptographic Architecture provider to use for Signature - // this is set along with the PrivateKey privKey and must be compatible - // this provider will be used when selecting a Signature instance - // https://docs.oracle.com/javase/8/docs/technotes/guides/security - // /SunProviders.html - private final Provider provider; - - // Transient because it's calculated on demand. - transient private byte[] pubKeyHash; - transient private byte[] nodeId; - - /** - * Generates an entirely new keypair. - *

- * BouncyCastle will be used as the Java Security Provider - */ - public ECKey() { - this(secureRandom); + /** + * The parameters of the secp256k1 curve. + */ + public static final ECDomainParameters CURVE; + public static final ECParameterSpec CURVE_SPEC; + /** + * Equal to CURVE.getN().shiftRight(1), used for canonicalising the S value of a signature. ECDSA + * signatures are mutable in the sense that for a given (R, S) pair, then both (R, S) and (R, N - + * S mod N) are valid signatures. Canonical signatures are those where 1 <= S <= N/2

See + * https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki #Low_S_values_in_signatures + */ + public static final BigInteger HALF_CURVE_ORDER; + private static final Logger logger = LoggerFactory.getLogger(ECKey.class); + private static final BigInteger SECP256K1N = new BigInteger + ("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16); + private static final SecureRandom secureRandom; + private static final long serialVersionUID = -728224901792295832L; + + static { + // All clients must agree on the curve to use by agreement. + X9ECParameters params = SECNamedCurves.getByName("secp256k1"); + CURVE = new ECDomainParameters(params.getCurve(), params.getG(), + params.getN(), params.getH()); + CURVE_SPEC = new ECParameterSpec(params.getCurve(), params.getG(), + params.getN(), params.getH()); + HALF_CURVE_ORDER = params.getN().shiftRight(1); + secureRandom = new SecureRandom(); + } + + protected final ECPoint pub; + // The two parts of the key. If "priv" is set, "pub" can always be + // calculated. If "pub" is set but not "priv", we + // can only verify signatures not make them. + // TODO: Redesign this class to use consistent internals and more + // efficient serialization. + private final PrivateKey privKey; + // the Java Cryptographic Architecture provider to use for Signature + // this is set along with the PrivateKey privKey and must be compatible + // this provider will be used when selecting a Signature instance + // https://docs.oracle.com/javase/8/docs/technotes/guides/security + // /SunProviders.html + private final Provider provider; + + // Transient because it's calculated on demand. + transient private byte[] pubKeyHash; + transient private byte[] nodeId; + + /** + * Generates an entirely new keypair.

BouncyCastle will be used as the Java Security Provider + */ + public ECKey() { + this(secureRandom); + } + + /** + * Generate a new keypair using the given Java Security Provider.

All private key operations + * will use the provider. + */ + public ECKey(Provider provider, SecureRandom secureRandom) { + this.provider = provider; + + final KeyPairGenerator keyPairGen = ECKeyPairGenerator.getInstance + (provider, secureRandom); + final KeyPair keyPair = keyPairGen.generateKeyPair(); + + this.privKey = keyPair.getPrivate(); + + final PublicKey pubKey = keyPair.getPublic(); + if (pubKey instanceof BCECPublicKey) { + pub = ((BCECPublicKey) pubKey).getQ(); + } else if (pubKey instanceof ECPublicKey) { + pub = extractPublicKey((ECPublicKey) pubKey); + } else { + throw new AssertionError( + "Expected Provider " + provider.getName() + + " to produce a subtype of ECPublicKey, found " + + pubKey.getClass()); } - - /** - * Generate a new keypair using the given Java Security Provider. - *

- * All private key operations will use the provider. - */ - public ECKey(Provider provider, SecureRandom secureRandom) { - this.provider = provider; - - final KeyPairGenerator keyPairGen = ECKeyPairGenerator.getInstance - (provider, secureRandom); - final KeyPair keyPair = keyPairGen.generateKeyPair(); - - this.privKey = keyPair.getPrivate(); - - final PublicKey pubKey = keyPair.getPublic(); - if (pubKey instanceof BCECPublicKey) { - pub = ((BCECPublicKey) pubKey).getQ(); - } else if (pubKey instanceof ECPublicKey) { - pub = extractPublicKey((ECPublicKey) pubKey); - } else { - throw new AssertionError( - "Expected Provider " + provider.getName() + - " to produce a subtype of ECPublicKey, found " + - pubKey.getClass()); - } + } + + /** + * Generates an entirely new keypair with the given {@link SecureRandom} object.

BouncyCastle + * will be used as the Java Security Provider + * + * @param secureRandom - + */ + public ECKey(SecureRandom secureRandom) { + this(TronCastleProvider.getInstance(), secureRandom); + } + + /** + * Pair a private key with a public EC point.

All private key operations will use the + * provider. + */ + public ECKey(Provider provider, @Nullable PrivateKey privKey, ECPoint pub) { + this.provider = provider; + + if (privKey == null || isECPrivateKey(privKey)) { + this.privKey = privKey; + } else { + throw new IllegalArgumentException( + "Expected EC private key, given a private key object with" + + " class " + + privKey.getClass().toString() + + " and algorithm " + privKey.getAlgorithm()); } - /** - * Generates an entirely new keypair with the given {@link SecureRandom} - * object. - *

- * BouncyCastle will be used as the Java Security Provider - * - * @param secureRandom - - */ - public ECKey(SecureRandom secureRandom) { - this(TronCastleProvider.getInstance(), secureRandom); + if (pub == null) { + throw new IllegalArgumentException("Public key may not be null"); + } else { + this.pub = pub; } - - /** - * Pair a private key with a public EC point. - *

- * All private key operations will use the provider. - */ - public ECKey(Provider provider, @Nullable PrivateKey privKey, ECPoint pub) { - this.provider = provider; - - if (privKey == null || isECPrivateKey(privKey)) { - this.privKey = privKey; - } else { - throw new IllegalArgumentException( - "Expected EC private key, given a private key object with" + - " class " + - privKey.getClass().toString() + - " and algorithm " + privKey.getAlgorithm()); - } - - if (pub == null) { - throw new IllegalArgumentException("Public key may not be null"); - } else { - this.pub = pub; - } + } + + /** + * Pair a private key integer with a public EC point

BouncyCastle will be used as the Java + * Security Provider + */ + public ECKey(@Nullable BigInteger priv, ECPoint pub) { + this( + TronCastleProvider.getInstance(), + privateKeyFromBigInteger(priv), + pub + ); + } + + /* Convert a Java JCE ECPublicKey into a BouncyCastle ECPoint + */ + private static ECPoint extractPublicKey(final ECPublicKey ecPublicKey) { + final java.security.spec.ECPoint publicPointW = ecPublicKey.getW(); + final BigInteger xCoord = publicPointW.getAffineX(); + final BigInteger yCoord = publicPointW.getAffineY(); + + return CURVE.getCurve().createPoint(xCoord, yCoord); + } + + /* Test if a generic private key is an EC private key + * + * it is not sufficient to check that privKey is a subtype of ECPrivateKey + * as the SunPKCS11 Provider will return a generic PrivateKey instance + * a fallback that covers this case is to check the key algorithm + */ + private static boolean isECPrivateKey(PrivateKey privKey) { + return privKey instanceof ECPrivateKey || privKey.getAlgorithm() + .equals("EC"); + } + + /* Convert a BigInteger into a PrivateKey object + */ + private static PrivateKey privateKeyFromBigInteger(BigInteger priv) { + if (priv == null) { + return null; + } else { + try { + return ECKeyFactory + .getInstance(TronCastleProvider.getInstance()) + .generatePrivate(new ECPrivateKeySpec(priv, + CURVE_SPEC)); + } catch (InvalidKeySpecException ex) { + throw new AssertionError("Assumed correct key spec statically"); + } } - - /** - * Pair a private key integer with a public EC point - *

- * BouncyCastle will be used as the Java Security Provider - */ - public ECKey(@Nullable BigInteger priv, ECPoint pub) { - this( - TronCastleProvider.getInstance(), - privateKeyFromBigInteger(priv), - pub - ); + } + + /** + * Utility for compressing an elliptic curve point. Returns the same point if it's already + * compressed. See the ECKey class docs for a discussion of point compression. + * + * @param uncompressed - + * @return - + * @deprecated per-point compression property will be removed in Bouncy Castle + */ + public static ECPoint compressPoint(ECPoint uncompressed) { + return CURVE.getCurve().decodePoint(uncompressed.getEncoded(true)); + } + + /** + * Utility for decompressing an elliptic curve point. Returns the same point if it's already + * compressed. See the ECKey class docs for a discussion of point compression. + * + * @param compressed - + * @return - + * @deprecated per-point compression property will be removed in Bouncy Castle + */ + public static ECPoint decompressPoint(ECPoint compressed) { + return CURVE.getCurve().decodePoint(compressed.getEncoded(false)); + } + + /** + * Creates an ECKey given the private key only. + * + * @param privKey - + * @return - + */ + public static ECKey fromPrivate(BigInteger privKey) { + return new ECKey(privKey, CURVE.getG().multiply(privKey)); + } + + /** + * Creates an ECKey given the private key only. + * + * @param privKeyBytes - + * @return - + */ + public static ECKey fromPrivate(byte[] privKeyBytes) { + return fromPrivate(new BigInteger(1, privKeyBytes)); + } + + /** + * Creates an ECKey that simply trusts the caller to ensure that point is really the result of + * multiplying the generator point by the private key. This is used to speed things up when you + * know you have the right values already. The compression state of pub will be preserved. + * + * @param priv - + * @param pub - + * @return - + */ + public static ECKey fromPrivateAndPrecalculatedPublic(BigInteger priv, + ECPoint pub) { + return new ECKey(priv, pub); + } + + /** + * Creates an ECKey that simply trusts the caller to ensure that point is really the result of + * multiplying the generator point by the private key. This is used to speed things up when you + * know you have the right values already. The compression state of the point will be preserved. + * + * @param priv - + * @param pub - + * @return - + */ + public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] + pub) { + check(priv != null, "Private key must not be null"); + check(pub != null, "Public key must not be null"); + return new ECKey(new BigInteger(1, priv), CURVE.getCurve() + .decodePoint(pub)); + } + + /** + * Creates an ECKey that cannot be used for signing, only verifying signatures, from the given + * point. The compression state of pub will be preserved. + * + * @param pub - + * @return - + */ + public static ECKey fromPublicOnly(ECPoint pub) { + return new ECKey(null, pub); + } + + /** + * Creates an ECKey that cannot be used for signing, only verifying signatures, from the given + * encoded point. The compression state of pub will be preserved. + * + * @param pub - + * @return - + */ + public static ECKey fromPublicOnly(byte[] pub) { + return new ECKey(null, CURVE.getCurve().decodePoint(pub)); + } + + /** + * Returns public key bytes from the given private key. To convert a byte array into a BigInteger, + * use new BigInteger(1, bytes); + * + * @param privKey - + * @param compressed - + * @return - + */ + public static byte[] publicKeyFromPrivate(BigInteger privKey, boolean + compressed) { + ECPoint point = CURVE.getG().multiply(privKey); + return point.getEncoded(compressed); + } + + /** + * Compute an address from an encoded public key. + * + * @param pubBytes an encoded (uncompressed) public key + * @return 20-byte address + */ + public static byte[] computeAddress(byte[] pubBytes) { + return Hash.sha3omit12( + Arrays.copyOfRange(pubBytes, 1, pubBytes.length)); + } + + /** + * Compute an address from a public point. + * + * @param pubPoint a public point + * @return 20-byte address + */ + public static byte[] computeAddress(ECPoint pubPoint) { + return computeAddress(pubPoint.getEncoded(/* uncompressed */ false)); + } + + /** + * Compute the encoded X, Y coordinates of a public point.

This is the encoded public key + * without the leading byte. + * + * @param pubPoint a public point + * @return 64-byte X,Y point pair + */ + public static byte[] pubBytesWithoutFormat(ECPoint pubPoint) { + final byte[] pubBytes = pubPoint.getEncoded(/* uncompressed */ false); + return Arrays.copyOfRange(pubBytes, 1, pubBytes.length); + } + + /** + * Recover the public key from an encoded node id. + * + * @param nodeId a 64-byte X,Y point pair + */ + public static ECKey fromNodeId(byte[] nodeId) { + check(nodeId.length == 64, "Expected a 64 byte node id"); + byte[] pubBytes = new byte[65]; + System.arraycopy(nodeId, 0, pubBytes, 1, nodeId.length); + pubBytes[0] = 0x04; // uncompressed + return ECKey.fromPublicOnly(pubBytes); + } + + public static byte[] signatureToKeyBytes(byte[] messageHash, String + signatureBase64) throws SignatureException { + byte[] signatureEncoded; + try { + signatureEncoded = Base64.decode(signatureBase64); + } catch (RuntimeException e) { + // This is what you getData back from Bouncy Castle if base64 doesn't + // decode :( + throw new SignatureException("Could not decode base64", e); } - - /* Convert a Java JCE ECPublicKey into a BouncyCastle ECPoint - */ - private static ECPoint extractPublicKey(final ECPublicKey ecPublicKey) { - final java.security.spec.ECPoint publicPointW = ecPublicKey.getW(); - final BigInteger xCoord = publicPointW.getAffineX(); - final BigInteger yCoord = publicPointW.getAffineY(); - - return CURVE.getCurve().createPoint(xCoord, yCoord); + // Parse the signature bytes into r/s and the selector value. + if (signatureEncoded.length < 65) { + throw new SignatureException("Signature truncated, expected 65 " + + "bytes and got " + signatureEncoded.length); } - /* Test if a generic private key is an EC private key - * - * it is not sufficient to check that privKey is a subtype of ECPrivateKey - * as the SunPKCS11 Provider will return a generic PrivateKey instance - * a fallback that covers this case is to check the key algorithm - */ - private static boolean isECPrivateKey(PrivateKey privKey) { - return privKey instanceof ECPrivateKey || privKey.getAlgorithm() - .equals("EC"); + return signatureToKeyBytes( + messageHash, + ECDSASignature.fromComponents( + Arrays.copyOfRange(signatureEncoded, 1, 33), + Arrays.copyOfRange(signatureEncoded, 33, 65), + (byte) (signatureEncoded[0] & 0xFF))); + } + + public static byte[] signatureToKeyBytes(byte[] messageHash, + ECDSASignature sig) throws + SignatureException { + check(messageHash.length == 32, "messageHash argument has length " + + messageHash.length); + int header = sig.v; + // The header byte: 0x1B = first key with even y, 0x1C = first key + // with odd y, + // 0x1D = second key with even y, 0x1E = second key + // with odd y + if (header < 27 || header > 34) { + throw new SignatureException("Header byte out of range: " + header); } - - /* Convert a BigInteger into a PrivateKey object - */ - private static PrivateKey privateKeyFromBigInteger(BigInteger priv) { - if (priv == null) { - return null; - } else { - try { - return ECKeyFactory - .getInstance(TronCastleProvider.getInstance()) - .generatePrivate(new ECPrivateKeySpec(priv, - CURVE_SPEC)); - } catch (InvalidKeySpecException ex) { - throw new AssertionError("Assumed correct key spec statically"); - } - } + if (header >= 31) { + header -= 4; } - - /** - * Utility for compressing an elliptic curve point. Returns the same - * point if it's already compressed. - * See the ECKey class docs for a discussion of point compression. - * - * @param uncompressed - - * @return - - * @deprecated per-point compression property will be removed in Bouncy - * Castle - */ - public static ECPoint compressPoint(ECPoint uncompressed) { - return CURVE.getCurve().decodePoint(uncompressed.getEncoded(true)); + int recId = header - 27; + byte[] key = ECKey.recoverPubBytesFromSignature(recId, sig, + messageHash); + if (key == null) { + throw new SignatureException("Could not recover public key from " + + "signature"); } - - /** - * Utility for decompressing an elliptic curve point. Returns the same - * point if it's already compressed. - * See the ECKey class docs for a discussion of point compression. - * - * @param compressed - - * @return - - * @deprecated per-point compression property will be removed in Bouncy - * Castle - */ - public static ECPoint decompressPoint(ECPoint compressed) { - return CURVE.getCurve().decodePoint(compressed.getEncoded(false)); + return key; + } + + /** + * Compute the address of the key that signed the given signature. + * + * @param messageHash 32-byte hash of message + * @param signatureBase64 Base-64 encoded signature + * @return 20-byte address + */ + public static byte[] signatureToAddress(byte[] messageHash, String + signatureBase64) throws SignatureException { + return computeAddress(signatureToKeyBytes(messageHash, + signatureBase64)); + } + + /** + * Compute the address of the key that signed the given signature. + * + * @param messageHash 32-byte hash of message + * @param sig - + * @return 20-byte address + */ + public static byte[] signatureToAddress(byte[] messageHash, + ECDSASignature sig) throws + SignatureException { + return computeAddress(signatureToKeyBytes(messageHash, sig)); + } + + /** + * Compute the key that signed the given signature. + * + * @param messageHash 32-byte hash of message + * @param signatureBase64 Base-64 encoded signature + * @return ECKey + */ + public static ECKey signatureToKey(byte[] messageHash, String + signatureBase64) throws SignatureException { + final byte[] keyBytes = signatureToKeyBytes(messageHash, + signatureBase64); + return ECKey.fromPublicOnly(keyBytes); + } + + /** + * Compute the key that signed the given signature. + * + * @param messageHash 32-byte hash of message + * @param sig - + * @return ECKey + */ + public static ECKey signatureToKey(byte[] messageHash, ECDSASignature + sig) throws SignatureException { + final byte[] keyBytes = signatureToKeyBytes(messageHash, sig); + return ECKey.fromPublicOnly(keyBytes); + } + + /** + *

Verifies the given ECDSA signature against the message bytes using the public key bytes.

+ *

When using native ECDSA verification, data must be 32 bytes, and no element may be + * larger than 520 bytes.

+ * + * @param data Hash of the data to verify. + * @param signature signature. + * @param pub The public key bytes to use. + * @return - + */ + public static boolean verify(byte[] data, ECDSASignature signature, + byte[] pub) { + ECDSASigner signer = new ECDSASigner(); + ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE + .getCurve().decodePoint(pub), CURVE); + signer.init(false, params); + try { + return signer.verifySignature(data, signature.r, signature.s); + } catch (NullPointerException npe) { + // Bouncy Castle contains a bug that can cause NPEs given + // specially crafted signatures. + // Those signatures are inherently invalid/attack sigs so we just + // fail them here rather than crash the thread. + logger.error("Caught NPE inside bouncy castle", npe); + return false; } - - /** - * Creates an ECKey given the private key only. - * - * @param privKey - - * @return - - */ - public static ECKey fromPrivate(BigInteger privKey) { - return new ECKey(privKey, CURVE.getG().multiply(privKey)); + } + + /** + * Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key. + * + * @param data Hash of the data to verify. + * @param signature signature. + * @param pub The public key bytes to use. + * @return - + */ + public static boolean verify(byte[] data, byte[] signature, byte[] pub) { + return verify(data, ECDSASignature.decodeFromDER(signature), pub); + } + + /** + * Returns true if the given pubkey is canonical, i.e. the correct length taking into account + * compression. + * + * @param pubkey - + * @return - + */ + public static boolean isPubKeyCanonical(byte[] pubkey) { + if (pubkey[0] == 0x04) { + // Uncompressed pubkey + return pubkey.length == 65; + } else if (pubkey[0] == 0x02 || pubkey[0] == 0x03) { + // Compressed pubkey + return pubkey.length == 33; + } else { + return false; } - - /** - * Creates an ECKey given the private key only. - * - * @param privKeyBytes - - * @return - - */ - public static ECKey fromPrivate(byte[] privKeyBytes) { - return fromPrivate(new BigInteger(1, privKeyBytes)); + } + + /** + *

Given the components of a signature and a selector value, recover and return the public key + * that generated the signature according to the algorithm in SEC1v2 section 4.1.6.

The + * recId is an index from 0 to 3 which indicates which of the 4 possible allKeys is the correct + * one. Because the key recovery operation yields multiple potential allKeys, the correct key must + * either be stored alongside the signature, or you must be willing to try each recId in turn + * until you find one that outputs the key you are expecting.

If this method returns + * null it means recovery was not possible and recId should be iterated.

Given the + * above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the + * output is null OR a key that is not the one you expect, you try again with the next recId.

+ * + * @param recId Which possible key to recover. + * @param sig the R and S components of the signature, wrapped. + * @param messageHash Hash of the data that was signed. + * @return 65-byte encoded public key + */ + @Nullable + public static byte[] recoverPubBytesFromSignature(int recId, + ECDSASignature sig, + byte[] messageHash) { + check(recId >= 0, "recId must be positive"); + check(sig.r.signum() >= 0, "r must be positive"); + check(sig.s.signum() >= 0, "s must be positive"); + check(messageHash != null, "messageHash must not be null"); + // 1.0 For j from 0 to h (h == recId here and the loop is outside + // this function) + // 1.1 Let x = r + jn + BigInteger n = CURVE.getN(); // Curve order. + BigInteger i = BigInteger.valueOf((long) recId / 2); + BigInteger x = sig.r.add(i.multiply(n)); + // 1.2. Convert the integer x to an octet string X of length mlen + // using the conversion routine + // specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or + // mlen = ⌈m/8⌉. + // 1.3. Convert the octet string (16 set binary digits)||X to an + // elliptic curve point R using the + // conversion routine specified in Section 2.3.4. If this + // conversion routine outputs “invalid”, then + // do another iteration of Step 1. + // + // More concisely, what these points mean is to use X as a compressed + // public key. + ECCurve.Fp curve = (ECCurve.Fp) CURVE.getCurve(); + BigInteger prime = curve.getQ(); // Bouncy Castle is not consistent + // about the letter it uses for the prime. + if (x.compareTo(prime) >= 0) { + // Cannot have point co-ordinates larger than this as everything + // takes place modulo Q. + return null; } - - /** - * Creates an ECKey that simply trusts the caller to ensure that point is - * really the result of multiplying the - * generator point by the private key. This is used to speed things up - * when you know you have the right values - * already. The compression state of pub will be preserved. - * - * @param priv - - * @param pub - - * @return - - */ - public static ECKey fromPrivateAndPrecalculatedPublic(BigInteger priv, - ECPoint pub) { - return new ECKey(priv, pub); + // Compressed allKeys require you to know an extra bit of data about the + // y-coord as there are two possibilities. + // So it's encoded in the recId. + ECPoint R = decompressKey(x, (recId & 1) == 1); + // 1.4. If nR != point at infinity, then do another iteration of + // Step 1 (callers responsibility). + if (!R.multiply(n).isInfinity()) { + return null; } - - /** - * Creates an ECKey that simply trusts the caller to ensure that point is - * really the result of multiplying the - * generator point by the private key. This is used to speed things up - * when you know you have the right values - * already. The compression state of the point will be preserved. - * - * @param priv - - * @param pub - - * @return - - */ - public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] - pub) { - check(priv != null, "Private key must not be null"); - check(pub != null, "Public key must not be null"); - return new ECKey(new BigInteger(1, priv), CURVE.getCurve() - .decodePoint(pub)); + // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature + // verification. + BigInteger e = new BigInteger(1, messageHash); + // 1.6. For k from 1 to 2 do the following. (loop is outside this + // function via iterating recId) + // 1.6.1. Compute a candidate public key as: + // Q = mi(r) * (sR - eG) + // + // Where mi(x) is the modular multiplicative inverse. We transform + // this into the following: + // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) + // Where -e is the modular additive inverse of e, that is z such that + // z + e = 0 (mod n). In the above equation + // ** is point multiplication and + is point addition (the EC group + // operator). + // + // We can find the additive inverse by subtracting e from zero then + // taking the mod. For example the additive + // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod + // 11 = 8. + BigInteger eInv = BigInteger.ZERO.subtract(e).mod(n); + BigInteger rInv = sig.r.modInverse(n); + BigInteger srInv = rInv.multiply(sig.s).mod(n); + BigInteger eInvrInv = rInv.multiply(eInv).mod(n); + ECPoint.Fp q = (ECPoint.Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE + .getG(), eInvrInv, R, srInv); + return q.getEncoded(/* compressed */ false); + } + + /** + * @param recId Which possible key to recover. + * @param sig the R and S components of the signature, wrapped. + * @param messageHash Hash of the data that was signed. + * @return 20-byte address + */ + @Nullable + public static byte[] recoverAddressFromSignature(int recId, + ECDSASignature sig, + byte[] messageHash) { + final byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, + messageHash); + if (pubBytes == null) { + return null; + } else { + return computeAddress(pubBytes); } - - /** - * Creates an ECKey that cannot be used for signing, only verifying - * signatures, from the given point. The - * compression state of pub will be preserved. - * - * @param pub - - * @return - - */ - public static ECKey fromPublicOnly(ECPoint pub) { - return new ECKey(null, pub); + } + + /** + * @param recId Which possible key to recover. + * @param sig the R and S components of the signature, wrapped. + * @param messageHash Hash of the data that was signed. + * @return ECKey + */ + @Nullable + public static ECKey recoverFromSignature(int recId, ECDSASignature sig, + byte[] messageHash) { + final byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, + messageHash); + if (pubBytes == null) { + return null; + } else { + return ECKey.fromPublicOnly(pubBytes); } - - /** - * Creates an ECKey that cannot be used for signing, only verifying - * signatures, from the given encoded point. - * The compression state of pub will be preserved. - * - * @param pub - - * @return - - */ - public static ECKey fromPublicOnly(byte[] pub) { - return new ECKey(null, CURVE.getCurve().decodePoint(pub)); + } + + /** + * Decompress a compressed public key (x co-ord and low-bit of y-coord). + * + * @param xBN - + * @param yBit - + * @return - + */ + private static ECPoint decompressKey(BigInteger xBN, boolean yBit) { + X9IntegerConverter x9 = new X9IntegerConverter(); + byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE + .getCurve())); + compEnc[0] = (byte) (yBit ? 0x03 : 0x02); + return CURVE.getCurve().decodePoint(compEnc); + } + + private static void check(boolean test, String message) { + if (!test) { + throw new IllegalArgumentException(message); } - - /** - * Returns public key bytes from the given private key. To convert a byte - * array into a BigInteger, use - * new BigInteger(1, bytes); - * - * @param privKey - - * @param compressed - - * @return - - */ - public static byte[] publicKeyFromPrivate(BigInteger privKey, boolean - compressed) { - ECPoint point = CURVE.getG().multiply(privKey); - return point.getEncoded(compressed); + } + + /** + * Returns a copy of this key, but with the public point represented in uncompressed form. + * Normally you would never need this: it's for specialised scenarios or when backwards + * compatibility in encoded form is necessary. + * + * @return - + * @deprecated per-point compression property will be removed in Bouncy Castle + */ + public ECKey decompress() { + if (!pub.isCompressed()) { + return this; + } else { + return new ECKey(this.provider, this.privKey, decompressPoint(pub)); } - - /** - * Compute an address from an encoded public key. - * - * @param pubBytes an encoded (uncompressed) public key - * @return 20-byte address - */ - public static byte[] computeAddress(byte[] pubBytes) { - return Hash.sha3omit12( - Arrays.copyOfRange(pubBytes, 1, pubBytes.length)); + } + + /** + * @deprecated per-point compression property will be removed in Bouncy Castle + */ + public ECKey compress() { + if (pub.isCompressed()) { + return this; + } else { + return new ECKey(this.provider, this.privKey, compressPoint(pub)); } - - /** - * Compute an address from a public point. - * - * @param pubPoint a public point - * @return 20-byte address - */ - public static byte[] computeAddress(ECPoint pubPoint) { - return computeAddress(pubPoint.getEncoded(/* uncompressed */ false)); + } + + /** + * Returns true if this key doesn't have access to private key bytes. This may be because it was + * never given any private key bytes to begin with (a watching key). + * + * @return - + */ + public boolean isPubKeyOnly() { + return privKey == null; + } + + /** + * Returns true if this key has access to private key bytes. Does the opposite of {@link + * #isPubKeyOnly()}. + * + * @return - + */ + public boolean hasPrivKey() { + return privKey != null; + } + + /** + * Gets the address form of the public key. + * + * @return 20-byte address + */ + public byte[] getAddress() { + if (pubKeyHash == null) { + pubKeyHash = computeAddress(this.pub); } - - /** - * Compute the encoded X, Y coordinates of a public point. - *

- * This is the encoded public key without the leading byte. - * - * @param pubPoint a public point - * @return 64-byte X,Y point pair - */ - public static byte[] pubBytesWithoutFormat(ECPoint pubPoint) { - final byte[] pubBytes = pubPoint.getEncoded(/* uncompressed */ false); - return Arrays.copyOfRange(pubBytes, 1, pubBytes.length); + return pubKeyHash; + } + + /** + * Generates the NodeID based on this key, that is the public key without first format byte + */ + public byte[] getNodeId() { + if (nodeId == null) { + nodeId = pubBytesWithoutFormat(this.pub); } - - /** - * Recover the public key from an encoded node id. - * - * @param nodeId a 64-byte X,Y point pair - */ - public static ECKey fromNodeId(byte[] nodeId) { - check(nodeId.length == 64, "Expected a 64 byte node id"); - byte[] pubBytes = new byte[65]; - System.arraycopy(nodeId, 0, pubBytes, 1, nodeId.length); - pubBytes[0] = 0x04; // uncompressed - return ECKey.fromPublicOnly(pubBytes); + return nodeId; + } + + /** + * Gets the encoded public key value. + * + * @return 65-byte encoded public key + */ + public byte[] getPubKey() { + return pub.getEncoded(/* compressed */ false); + } + + /** + * Gets the public key in the form of an elliptic curve point object from Bouncy Castle. + * + * @return - + */ + public ECPoint getPubKeyPoint() { + return pub; + } + + /** + * Gets the private key in the form of an integer field element. The public key is derived by + * performing EC point addition this number of times (i.e. point multiplying). + * + * @return - + * @throws IllegalStateException if the private key bytes are not available. + */ + public BigInteger getPrivKey() { + if (privKey == null) { + throw new MissingPrivateKeyException(); + } else if (privKey instanceof BCECPrivateKey) { + return ((BCECPrivateKey) privKey).getD(); + } else { + throw new MissingPrivateKeyException(); } - - public static byte[] signatureToKeyBytes(byte[] messageHash, String - signatureBase64) throws SignatureException { - byte[] signatureEncoded; - try { - signatureEncoded = Base64.decode(signatureBase64); - } catch (RuntimeException e) { - // This is what you getData back from Bouncy Castle if base64 doesn't - // decode :( - throw new SignatureException("Could not decode base64", e); - } - // Parse the signature bytes into r/s and the selector value. - if (signatureEncoded.length < 65) { - throw new SignatureException("Signature truncated, expected 65 " + - "bytes and got " + signatureEncoded.length); - } - - return signatureToKeyBytes( - messageHash, - ECDSASignature.fromComponents( - Arrays.copyOfRange(signatureEncoded, 1, 33), - Arrays.copyOfRange(signatureEncoded, 33, 65), - (byte) (signatureEncoded[0] & 0xFF))); + } + + /** + * Returns whether this key is using the compressed form or not. Compressed pubkeys are only 33 + * bytes, not 64. + * + * @return - + */ + public boolean isCompressed() { + return pub.isCompressed(); + } + + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("pub:").append(Hex.toHexString(pub.getEncoded(false))); + return b.toString(); + } + + /** + * Produce a string rendering of the ECKey INCLUDING the private key. Unless you absolutely need + * the private key it is better for security reasons to just use toString(). + * + * @return - + */ + public String toStringWithPrivate() { + StringBuilder b = new StringBuilder(); + b.append(toString()); + if (privKey != null && privKey instanceof BCECPrivateKey) { + b.append(" priv:").append(Hex.toHexString(((BCECPrivateKey) + privKey).getD().toByteArray())); } - - public static byte[] signatureToKeyBytes(byte[] messageHash, - ECDSASignature sig) throws - SignatureException { - check(messageHash.length == 32, "messageHash argument has length " + - messageHash.length); - int header = sig.v; - // The header byte: 0x1B = first key with even y, 0x1C = first key - // with odd y, - // 0x1D = second key with even y, 0x1E = second key - // with odd y - if (header < 27 || header > 34) { - throw new SignatureException("Header byte out of range: " + header); - } - if (header >= 31) { - header -= 4; - } - int recId = header - 27; - byte[] key = ECKey.recoverPubBytesFromSignature(recId, sig, - messageHash); - if (key == null) { - throw new SignatureException("Could not recover public key from " + - "signature"); - } - return key; + return b.toString(); + } + + /** + * Signs the given hash and returns the R and S components as BigIntegers and putData them in + * ECDSASignature + * + * @param input to sign + * @return ECDSASignature signature that contains the R and S components + */ + public ECDSASignature doSign(byte[] input) { + if (input.length != 32) { + throw new IllegalArgumentException("Expected 32 byte input to " + + "ECDSA signature, not " + input.length); } - - /** - * Compute the address of the key that signed the given signature. - * - * @param messageHash 32-byte hash of message - * @param signatureBase64 Base-64 encoded signature - * @return 20-byte address - */ - public static byte[] signatureToAddress(byte[] messageHash, String - signatureBase64) throws SignatureException { - return computeAddress(signatureToKeyBytes(messageHash, - signatureBase64)); + // No decryption of private key required. + if (privKey == null) { + throw new MissingPrivateKeyException(); } - - /** - * Compute the address of the key that signed the given signature. - * - * @param messageHash 32-byte hash of message - * @param sig - - * @return 20-byte address - */ - public static byte[] signatureToAddress(byte[] messageHash, - ECDSASignature sig) throws - SignatureException { - return computeAddress(signatureToKeyBytes(messageHash, sig)); + if (privKey instanceof BCECPrivateKey) { + ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new + SHA256Digest())); + ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters + (((BCECPrivateKey) privKey).getD(), CURVE); + signer.init(true, privKeyParams); + BigInteger[] components = signer.generateSignature(input); + return new ECDSASignature(components[0], components[1]) + .toCanonicalised(); + } else { + try { + final Signature ecSig = ECSignatureFactory.getRawInstance + (provider); + ecSig.initSign(privKey); + ecSig.update(input); + final byte[] derSignature = ecSig.sign(); + return ECDSASignature.decodeFromDER(derSignature) + .toCanonicalised(); + } catch (SignatureException | InvalidKeyException ex) { + throw new RuntimeException("ECKey signing error", ex); + } } - - /** - * Compute the key that signed the given signature. - * - * @param messageHash 32-byte hash of message - * @param signatureBase64 Base-64 encoded signature - * @return ECKey - */ - public static ECKey signatureToKey(byte[] messageHash, String - signatureBase64) throws SignatureException { - final byte[] keyBytes = signatureToKeyBytes(messageHash, - signatureBase64); - return ECKey.fromPublicOnly(keyBytes); + } + + /** + * Takes the keccak hash (32 bytes) of data and returns the ECDSA signature + * + * @param messageHash - + * @return - + * @throws IllegalStateException if this ECKey does not have the private part. + */ + public ECDSASignature sign(byte[] messageHash) { + ECDSASignature sig = doSign(messageHash); + // Now we have to work backwards to figure out the recId needed to + // recover the signature. + int recId = -1; + byte[] thisKey = this.pub.getEncoded(/* compressed */ false); + for (int i = 0; i < 4; i++) { + byte[] k = ECKey.recoverPubBytesFromSignature(i, sig, messageHash); + if (k != null && Arrays.equals(k, thisKey)) { + recId = i; + break; + } } - - /** - * Compute the key that signed the given signature. - * - * @param messageHash 32-byte hash of message - * @param sig - - * @return ECKey - */ - public static ECKey signatureToKey(byte[] messageHash, ECDSASignature - sig) throws SignatureException { - final byte[] keyBytes = signatureToKeyBytes(messageHash, sig); - return ECKey.fromPublicOnly(keyBytes); + if (recId == -1) { + throw new RuntimeException("Could not construct a recoverable key" + + ". This should never happen."); } - - /** - *

Verifies the given ECDSA signature against the message bytes using - * the public key bytes.

- *

- *

When using native ECDSA verification, data must be 32 bytes, and no - * element may be - * larger than 520 bytes.

- * - * @param data Hash of the data to verify. - * @param signature signature. - * @param pub The public key bytes to use. - * @return - - */ - public static boolean verify(byte[] data, ECDSASignature signature, - byte[] pub) { - ECDSASigner signer = new ECDSASigner(); - ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE - .getCurve().decodePoint(pub), CURVE); - signer.init(false, params); - try { - return signer.verifySignature(data, signature.r, signature.s); - } catch (NullPointerException npe) { - // Bouncy Castle contains a bug that can cause NPEs given - // specially crafted signatures. - // Those signatures are inherently invalid/attack sigs so we just - // fail them here rather than crash the thread. - logger.error("Caught NPE inside bouncy castle", npe); - return false; - } + sig.v = (byte) (recId + 27); + return sig; + } + + public BigInteger keyAgreement(ECPoint otherParty) { + if (privKey == null) { + throw new MissingPrivateKeyException(); + } else if (privKey instanceof BCECPrivateKey) { + final ECDHBasicAgreement agreement = new ECDHBasicAgreement(); + agreement.init(new ECPrivateKeyParameters(((BCECPrivateKey) + privKey).getD(), CURVE)); + return agreement.calculateAgreement(new ECPublicKeyParameters + (otherParty, CURVE)); + } else { + try { + final KeyAgreement agreement = ECKeyAgreement.getInstance + (this.provider); + agreement.init(this.privKey); + agreement.doPhase( + ECKeyFactory.getInstance(this.provider) + .generatePublic(new ECPublicKeySpec + (otherParty, CURVE_SPEC)), + /* lastPhase */ true); + return new BigInteger(1, agreement.generateSecret()); + } catch (IllegalStateException | InvalidKeyException | + InvalidKeySpecException ex) { + throw new RuntimeException("ECDH key agreement failure", ex); + } } - - /** - * Verifies the given ASN.1 encoded ECDSA signature against a hash using - * the public key. - * - * @param data Hash of the data to verify. - * @param signature signature. - * @param pub The public key bytes to use. - * @return - - */ - public static boolean verify(byte[] data, byte[] signature, byte[] pub) { - return verify(data, ECDSASignature.decodeFromDER(signature), pub); + } + + /** + * Decrypt cipher by AES in SIC(also know as CTR) mode + * + * @param cipher -proper cipher + * @return decrypted cipher, equal length to the cipher. + * @deprecated should not use EC private scalar value as an AES key + */ + public byte[] decryptAES(byte[] cipher) { + + if (privKey == null) { + throw new MissingPrivateKeyException(); } - - /** - * Returns true if the given pubkey is canonical, i.e. the correct length - * taking into account compression. - * - * @param pubkey - - * @return - - */ - public static boolean isPubKeyCanonical(byte[] pubkey) { - if (pubkey[0] == 0x04) { - // Uncompressed pubkey - return pubkey.length == 65; - } else if (pubkey[0] == 0x02 || pubkey[0] == 0x03) { - // Compressed pubkey - return pubkey.length == 33; - } else { - return false; - } + if (!(privKey instanceof BCECPrivateKey)) { + throw new UnsupportedOperationException("Cannot use the private " + + "key as an AES key"); } - /** - *

Given the components of a signature and a selector value, recover - * and return the public key - * that generated the signature according to the algorithm in SEC1v2 - * section 4.1.6.

- *

- *

The recId is an index from 0 to 3 which indicates which of the 4 - * possible allKeys is the correct one. Because - * the key recovery operation yields multiple potential allKeys, the correct - * key must either be stored alongside the - * signature, or you must be willing to try each recId in turn until you - * find one that outputs the key you are - * expecting.

- *

- *

If this method returns null it means recovery was not possible and - * recId should be iterated.

- *

- *

Given the above two points, a correct usage of this method is - * inside a for loop from 0 to 3, and if the - * output is null OR a key that is not the one you expect, you try again - * with the next recId.

- * - * @param recId Which possible key to recover. - * @param sig the R and S components of the signature, wrapped. - * @param messageHash Hash of the data that was signed. - * @return 65-byte encoded public key - */ - @Nullable - public static byte[] recoverPubBytesFromSignature(int recId, - ECDSASignature sig, - byte[] messageHash) { - check(recId >= 0, "recId must be positive"); - check(sig.r.signum() >= 0, "r must be positive"); - check(sig.s.signum() >= 0, "s must be positive"); - check(messageHash != null, "messageHash must not be null"); - // 1.0 For j from 0 to h (h == recId here and the loop is outside - // this function) - // 1.1 Let x = r + jn - BigInteger n = CURVE.getN(); // Curve order. - BigInteger i = BigInteger.valueOf((long) recId / 2); - BigInteger x = sig.r.add(i.multiply(n)); - // 1.2. Convert the integer x to an octet string X of length mlen - // using the conversion routine - // specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or - // mlen = ⌈m/8⌉. - // 1.3. Convert the octet string (16 set binary digits)||X to an - // elliptic curve point R using the - // conversion routine specified in Section 2.3.4. If this - // conversion routine outputs “invalid”, then - // do another iteration of Step 1. - // - // More concisely, what these points mean is to use X as a compressed - // public key. - ECCurve.Fp curve = (ECCurve.Fp) CURVE.getCurve(); - BigInteger prime = curve.getQ(); // Bouncy Castle is not consistent - // about the letter it uses for the prime. - if (x.compareTo(prime) >= 0) { - // Cannot have point co-ordinates larger than this as everything - // takes place modulo Q. - return null; - } - // Compressed allKeys require you to know an extra bit of data about the - // y-coord as there are two possibilities. - // So it's encoded in the recId. - ECPoint R = decompressKey(x, (recId & 1) == 1); - // 1.4. If nR != point at infinity, then do another iteration of - // Step 1 (callers responsibility). - if (!R.multiply(n).isInfinity()) { - return null; - } - // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature - // verification. - BigInteger e = new BigInteger(1, messageHash); - // 1.6. For k from 1 to 2 do the following. (loop is outside this - // function via iterating recId) - // 1.6.1. Compute a candidate public key as: - // Q = mi(r) * (sR - eG) - // - // Where mi(x) is the modular multiplicative inverse. We transform - // this into the following: - // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) - // Where -e is the modular additive inverse of e, that is z such that - // z + e = 0 (mod n). In the above equation - // ** is point multiplication and + is point addition (the EC group - // operator). - // - // We can find the additive inverse by subtracting e from zero then - // taking the mod. For example the additive - // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod - // 11 = 8. - BigInteger eInv = BigInteger.ZERO.subtract(e).mod(n); - BigInteger rInv = sig.r.modInverse(n); - BigInteger srInv = rInv.multiply(sig.s).mod(n); - BigInteger eInvrInv = rInv.multiply(eInv).mod(n); - ECPoint.Fp q = (ECPoint.Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE - .getG(), eInvrInv, R, srInv); - return q.getEncoded(/* compressed */ false); - } + AESFastEngine engine = new AESFastEngine(); + SICBlockCipher ctrEngine = new SICBlockCipher(engine); - /** - * @param recId Which possible key to recover. - * @param sig the R and S components of the signature, wrapped. - * @param messageHash Hash of the data that was signed. - * @return 20-byte address - */ - @Nullable - public static byte[] recoverAddressFromSignature(int recId, - ECDSASignature sig, - byte[] messageHash) { - final byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, - messageHash); - if (pubBytes == null) { - return null; - } else { - return computeAddress(pubBytes); - } - } + KeyParameter key = new KeyParameter(BigIntegers.asUnsignedByteArray(( + (BCECPrivateKey) privKey).getD())); + ParametersWithIV params = new ParametersWithIV(key, new byte[16]); - /** - * @param recId Which possible key to recover. - * @param sig the R and S components of the signature, wrapped. - * @param messageHash Hash of the data that was signed. - * @return ECKey - */ - @Nullable - public static ECKey recoverFromSignature(int recId, ECDSASignature sig, - byte[] messageHash) { - final byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, - messageHash); - if (pubBytes == null) { - return null; - } else { - return ECKey.fromPublicOnly(pubBytes); - } - } + ctrEngine.init(false, params); - /** - * Decompress a compressed public key (x co-ord and low-bit of y-coord). - * - * @param xBN - - * @param yBit - - * @return - - */ - private static ECPoint decompressKey(BigInteger xBN, boolean yBit) { - X9IntegerConverter x9 = new X9IntegerConverter(); - byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE - .getCurve())); - compEnc[0] = (byte) (yBit ? 0x03 : 0x02); - return CURVE.getCurve().decodePoint(compEnc); + int i = 0; + byte[] out = new byte[cipher.length]; + while (i < cipher.length) { + ctrEngine.processBlock(cipher, i, out, i); + i += engine.getBlockSize(); + if (cipher.length - i < engine.getBlockSize()) { + break; + } } - private static void check(boolean test, String message) { - if (!test) { - throw new IllegalArgumentException(message); - } + // process left bytes + if (cipher.length - i > 0) { + byte[] tmpBlock = new byte[16]; + System.arraycopy(cipher, i, tmpBlock, 0, cipher.length - i); + ctrEngine.processBlock(tmpBlock, 0, tmpBlock, 0); + System.arraycopy(tmpBlock, 0, out, i, cipher.length - i); } - /** - * Returns a copy of this key, but with the public point represented in - * uncompressed form. Normally you would - * never need this: it's for specialised scenarios or when backwards - * compatibility in encoded form is necessary. - * - * @return - - * @deprecated per-point compression property will be removed in Bouncy - * Castle - */ - public ECKey decompress() { - if (!pub.isCompressed()) { - return this; - } else { - return new ECKey(this.provider, this.privKey, decompressPoint(pub)); - } + return out; + } + + /** + * Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key. + * + * @param data Hash of the data to verify. + * @param signature signature. + * @return - + */ + public boolean verify(byte[] data, byte[] signature) { + return ECKey.verify(data, signature, getPubKey()); + } + + /** + * Verifies the given R/S pair (signature) against a hash using the public key. + * + * @param sigHash - + * @param signature - + * @return - + */ + public boolean verify(byte[] sigHash, ECDSASignature signature) { + return ECKey.verify(sigHash, signature, getPubKey()); + } + + /** + * Returns true if this pubkey is canonical, i.e. the correct length taking into account + * compression. + * + * @return - + */ + public boolean isPubKeyCanonical() { + return isPubKeyCanonical(pub.getEncoded(/* uncompressed */ false)); + } + + /** + * Returns a 32 byte array containing the private key, or null if the key is encrypted or public + * only + * + * @return - + */ + @Nullable + public byte[] getPrivKeyBytes() { + if (privKey == null) { + return null; + } else if (privKey instanceof BCECPrivateKey) { + return bigIntegerToBytes(((BCECPrivateKey) privKey).getD(), 32); + } else { + return null; } + } - /** - * @deprecated per-point compression property will be removed in Bouncy - * Castle - */ - public ECKey compress() { - if (pub.isCompressed()) { - return this; - } else { - return new ECKey(this.provider, this.privKey, compressPoint(pub)); - } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - /** - * Returns true if this key doesn't have access to private key bytes. - * This may be because it was never - * given any private key bytes to begin with (a watching key). - * - * @return - - */ - public boolean isPubKeyOnly() { - return privKey == null; + if (o == null || !(o instanceof ECKey)) { + return false; } - /** - * Returns true if this key has access to private key bytes. Does the - * opposite of - * {@link #isPubKeyOnly()}. - * - * @return - - */ - public boolean hasPrivKey() { - return privKey != null; - } + ECKey ecKey = (ECKey) o; - /** - * Gets the address form of the public key. - * - * @return 20-byte address - */ - public byte[] getAddress() { - if (pubKeyHash == null) { - pubKeyHash = computeAddress(this.pub); - } - return pubKeyHash; + if (privKey != null && !privKey.equals(ecKey.privKey)) { + return false; } + return pub == null || pub.equals(ecKey.pub); + } - /** - * Generates the NodeID based on this key, that is the public key without - * first format byte - */ - public byte[] getNodeId() { - if (nodeId == null) { - nodeId = pubBytesWithoutFormat(this.pub); - } - return nodeId; - } + @Override + public int hashCode() { + return Arrays.hashCode(getPubKey()); + } - /** - * Gets the encoded public key value. - * - * @return 65-byte encoded public key - */ - public byte[] getPubKey() { - return pub.getEncoded(/* compressed */ false); - } + public static class ECDSASignature { /** - * Gets the public key in the form of an elliptic curve point object from - * Bouncy Castle. - * - * @return - + * The two components of the signature. */ - public ECPoint getPubKeyPoint() { - return pub; - } + public final BigInteger r, s; + public byte v; /** - * Gets the private key in the form of an integer field element. The - * public key is derived by performing EC - * point addition this number of times (i.e. point multiplying). + * Constructs a signature with the given components. Does NOT automatically canonicalise the + * signature. * - * @return - - * @throws IllegalStateException if the private key bytes are not available. + * @param r - + * @param s - */ - public BigInteger getPrivKey() { - if (privKey == null) { - throw new MissingPrivateKeyException(); - } else if (privKey instanceof BCECPrivateKey) { - return ((BCECPrivateKey) privKey).getD(); - } else { - throw new MissingPrivateKeyException(); - } + public ECDSASignature(BigInteger r, BigInteger s) { + this.r = r; + this.s = s; } /** - * Returns whether this key is using the compressed form or not. - * Compressed pubkeys are only 33 bytes, not 64. + * t * * @return - */ - public boolean isCompressed() { - return pub.isCompressed(); - } - - public String toString() { - StringBuilder b = new StringBuilder(); - b.append("pub:").append(Hex.toHexString(pub.getEncoded(false))); - return b.toString(); + private static ECDSASignature fromComponents(byte[] r, byte[] s) { + return new ECDSASignature(new BigInteger(1, r), new BigInteger(1, + s)); } /** - * Produce a string rendering of the ECKey INCLUDING the private key. - * Unless you absolutely need the private key it is better for security - * reasons to just use toString(). - * + * @param r - + * @param s - + * @param v - * @return - */ - public String toStringWithPrivate() { - StringBuilder b = new StringBuilder(); - b.append(toString()); - if (privKey != null && privKey instanceof BCECPrivateKey) { - b.append(" priv:").append(Hex.toHexString(((BCECPrivateKey) - privKey).getD().toByteArray())); - } - return b.toString(); + public static ECDSASignature fromComponents(byte[] r, byte[] s, byte + v) { + ECDSASignature signature = fromComponents(r, s); + signature.v = v; + return signature; } - /** - * Signs the given hash and returns the R and S components as BigIntegers - * and putData them in ECDSASignature - * - * @param input to sign - * @return ECDSASignature signature that contains the R and S components - */ - public ECDSASignature doSign(byte[] input) { - if (input.length != 32) { - throw new IllegalArgumentException("Expected 32 byte input to " + - "ECDSA signature, not " + input.length); - } - // No decryption of private key required. - if (privKey == null) { - throw new MissingPrivateKeyException(); - } - if (privKey instanceof BCECPrivateKey) { - ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new - SHA256Digest())); - ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters - (((BCECPrivateKey) privKey).getD(), CURVE); - signer.init(true, privKeyParams); - BigInteger[] components = signer.generateSignature(input); - return new ECDSASignature(components[0], components[1]) - .toCanonicalised(); - } else { - try { - final Signature ecSig = ECSignatureFactory.getRawInstance - (provider); - ecSig.initSign(privKey); - ecSig.update(input); - final byte[] derSignature = ecSig.sign(); - return ECDSASignature.decodeFromDER(derSignature) - .toCanonicalised(); - } catch (SignatureException | InvalidKeyException ex) { - throw new RuntimeException("ECKey signing error", ex); - } - } - } + public static boolean validateComponents(BigInteger r, BigInteger s, + byte v) { - /** - * Takes the keccak hash (32 bytes) of data and returns the ECDSA signature - * - * @param messageHash - - * @return - - * @throws IllegalStateException if this ECKey does not have the private - * part. - */ - public ECDSASignature sign(byte[] messageHash) { - ECDSASignature sig = doSign(messageHash); - // Now we have to work backwards to figure out the recId needed to - // recover the signature. - int recId = -1; - byte[] thisKey = this.pub.getEncoded(/* compressed */ false); - for (int i = 0; i < 4; i++) { - byte[] k = ECKey.recoverPubBytesFromSignature(i, sig, messageHash); - if (k != null && Arrays.equals(k, thisKey)) { - recId = i; - break; - } - } - if (recId == -1) { - throw new RuntimeException("Could not construct a recoverable key" + - ". This should never happen."); - } - sig.v = (byte) (recId + 27); - return sig; - } + if (v != 27 && v != 28) { + return false; + } - public BigInteger keyAgreement(ECPoint otherParty) { - if (privKey == null) { - throw new MissingPrivateKeyException(); - } else if (privKey instanceof BCECPrivateKey) { - final ECDHBasicAgreement agreement = new ECDHBasicAgreement(); - agreement.init(new ECPrivateKeyParameters(((BCECPrivateKey) - privKey).getD(), CURVE)); - return agreement.calculateAgreement(new ECPublicKeyParameters - (otherParty, CURVE)); - } else { - try { - final KeyAgreement agreement = ECKeyAgreement.getInstance - (this.provider); - agreement.init(this.privKey); - agreement.doPhase( - ECKeyFactory.getInstance(this.provider) - .generatePublic(new ECPublicKeySpec - (otherParty, CURVE_SPEC)), - /* lastPhase */ true); - return new BigInteger(1, agreement.generateSecret()); - } catch (IllegalStateException | InvalidKeyException | - InvalidKeySpecException ex) { - throw new RuntimeException("ECDH key agreement failure", ex); - } - } - } + if (isLessThan(r, BigInteger.ONE)) { + return false; + } + if (isLessThan(s, BigInteger.ONE)) { + return false; + } - /** - * Decrypt cipher by AES in SIC(also know as CTR) mode - * - * @param cipher -proper cipher - * @return decrypted cipher, equal length to the cipher. - * @deprecated should not use EC private scalar value as an AES key - */ - public byte[] decryptAES(byte[] cipher) { + if (!isLessThan(r, SECP256K1N)) { + return false; + } + return isLessThan(s, SECP256K1N); + } - if (privKey == null) { - throw new MissingPrivateKeyException(); - } - if (!(privKey instanceof BCECPrivateKey)) { - throw new UnsupportedOperationException("Cannot use the private " + - "key as an AES key"); + public static ECDSASignature decodeFromDER(byte[] bytes) { + ASN1InputStream decoder = null; + try { + decoder = new ASN1InputStream(bytes); + DLSequence seq = (DLSequence) decoder.readObject(); + if (seq == null) { + throw new RuntimeException("Reached past end of ASN.1 " + + "stream."); } - - - AESFastEngine engine = new AESFastEngine(); - SICBlockCipher ctrEngine = new SICBlockCipher(engine); - - KeyParameter key = new KeyParameter(BigIntegers.asUnsignedByteArray(( - (BCECPrivateKey) privKey).getD())); - ParametersWithIV params = new ParametersWithIV(key, new byte[16]); - - ctrEngine.init(false, params); - - int i = 0; - byte[] out = new byte[cipher.length]; - while (i < cipher.length) { - ctrEngine.processBlock(cipher, i, out, i); - i += engine.getBlockSize(); - if (cipher.length - i < engine.getBlockSize()) { - break; - } + ASN1Integer r, s; + try { + r = (ASN1Integer) seq.getObjectAt(0); + s = (ASN1Integer) seq.getObjectAt(1); + } catch (ClassCastException e) { + throw new IllegalArgumentException(e); } - - // process left bytes - if (cipher.length - i > 0) { - byte[] tmpBlock = new byte[16]; - System.arraycopy(cipher, i, tmpBlock, 0, cipher.length - i); - ctrEngine.processBlock(tmpBlock, 0, tmpBlock, 0); - System.arraycopy(tmpBlock, 0, out, i, cipher.length - i); + // OpenSSL deviates from the DER spec by interpreting these + // values as unsigned, though they should not be + // Thus, we always use the positive versions. See: + // http://r6.ca/blog/20111119T211504Z.html + return new ECDSASignature(r.getPositiveValue(), s + .getPositiveValue()); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + if (decoder != null) { + try { + decoder.close(); + } catch (IOException x) { + } } + } + } - return out; + public boolean validateComponents() { + return validateComponents(r, s, v); } - /** - * Verifies the given ASN.1 encoded ECDSA signature against a hash using - * the public key. - * - * @param data Hash of the data to verify. - * @param signature signature. - * @return - - */ - public boolean verify(byte[] data, byte[] signature) { - return ECKey.verify(data, signature, getPubKey()); + public ECDSASignature toCanonicalised() { + if (s.compareTo(HALF_CURVE_ORDER) > 0) { + // The order of the curve is the number of valid points that + // exist on that curve. If S is in the upper + // half of the number of valid points, then bring it back to + // the lower half. Otherwise, imagine that + // N = 10 + // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) + // are valid solutions. + // 10 - 8 == 2, giving us always the latter solution, + // which is canonical. + return new ECDSASignature(r, CURVE.getN().subtract(s)); + } else { + return this; + } } /** - * Verifies the given R/S pair (signature) against a hash using the - * public key. - * - * @param sigHash - - * @param signature - * @return - */ - public boolean verify(byte[] sigHash, ECDSASignature signature) { - return ECKey.verify(sigHash, signature, getPubKey()); + public String toBase64() { + byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 + // bytes for S + sigData[0] = v; + System.arraycopy(bigIntegerToBytes(this.r, 32), 0, sigData, 1, 32); + System.arraycopy(bigIntegerToBytes(this.s, 32), 0, sigData, 33, 32); + return new String(Base64.encode(sigData), Charset.forName("UTF-8")); } - /** - * Returns true if this pubkey is canonical, i.e. the correct length - * taking into account compression. - * - * @return - - */ - public boolean isPubKeyCanonical() { - return isPubKeyCanonical(pub.getEncoded(/* uncompressed */ false)); + public byte[] toByteArray() { + final byte fixedV = this.v >= 27 + ? (byte) (this.v - 27) + : this.v; + + return ByteUtil.merge( + ByteUtil.bigIntegerToBytes(this.r), + ByteUtil.bigIntegerToBytes(this.s), + new byte[]{fixedV}); } - /** - * Returns a 32 byte array containing the private key, or null if the key - * is encrypted or public only - * - * @return - - */ - @Nullable - public byte[] getPrivKeyBytes() { - if (privKey == null) { - return null; - } else if (privKey instanceof BCECPrivateKey) { - return bigIntegerToBytes(((BCECPrivateKey) privKey).getD(), 32); - } else { - return null; - } + public String toHex() { + return Hex.toHexString(toByteArray()); } @Override public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || !(o instanceof ECKey)) { - return false; - } - - ECKey ecKey = (ECKey) o; - - if (privKey != null && !privKey.equals(ecKey.privKey)) { - return false; - } - return pub == null || pub.equals(ecKey.pub); + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ECDSASignature signature = (ECDSASignature) o; + + if (!r.equals(signature.r)) { + return false; + } + return s.equals(signature.s); } @Override public int hashCode() { - return Arrays.hashCode(getPubKey()); + int result = r.hashCode(); + result = 31 * result + s.hashCode(); + return result; } + } - public static class ECDSASignature { - /** - * The two components of the signature. - */ - public final BigInteger r, s; - public byte v; - - /** - * Constructs a signature with the given components. Does NOT - * automatically canonicalise the signature. - * - * @param r - - * @param s - - */ - public ECDSASignature(BigInteger r, BigInteger s) { - this.r = r; - this.s = s; - } + @SuppressWarnings("serial") + public static class MissingPrivateKeyException extends RuntimeException { - /** - * t - * - * @param r - * @param s - * @return - - */ - private static ECDSASignature fromComponents(byte[] r, byte[] s) { - return new ECDSASignature(new BigInteger(1, r), new BigInteger(1, - s)); - } - - /** - * @param r - - * @param s - - * @param v - - * @return - - */ - public static ECDSASignature fromComponents(byte[] r, byte[] s, byte - v) { - ECDSASignature signature = fromComponents(r, s); - signature.v = v; - return signature; - } - - public static boolean validateComponents(BigInteger r, BigInteger s, - byte v) { - - if (v != 27 && v != 28) { - return false; - } - - if (isLessThan(r, BigInteger.ONE)) { - return false; - } - if (isLessThan(s, BigInteger.ONE)) { - return false; - } - - if (!isLessThan(r, SECP256K1N)) { - return false; - } - return isLessThan(s, SECP256K1N); - } - - public static ECDSASignature decodeFromDER(byte[] bytes) { - ASN1InputStream decoder = null; - try { - decoder = new ASN1InputStream(bytes); - DLSequence seq = (DLSequence) decoder.readObject(); - if (seq == null) { - throw new RuntimeException("Reached past end of ASN.1 " + - "stream."); - } - ASN1Integer r, s; - try { - r = (ASN1Integer) seq.getObjectAt(0); - s = (ASN1Integer) seq.getObjectAt(1); - } catch (ClassCastException e) { - throw new IllegalArgumentException(e); - } - // OpenSSL deviates from the DER spec by interpreting these - // values as unsigned, though they should not be - // Thus, we always use the positive versions. See: - // http://r6.ca/blog/20111119T211504Z.html - return new ECDSASignature(r.getPositiveValue(), s - .getPositiveValue()); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - if (decoder != null) { - try { - decoder.close(); - } catch (IOException x) { - } - } - } - } - - public boolean validateComponents() { - return validateComponents(r, s, v); - } - - public ECDSASignature toCanonicalised() { - if (s.compareTo(HALF_CURVE_ORDER) > 0) { - // The order of the curve is the number of valid points that - // exist on that curve. If S is in the upper - // half of the number of valid points, then bring it back to - // the lower half. Otherwise, imagine that - // N = 10 - // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) - // are valid solutions. - // 10 - 8 == 2, giving us always the latter solution, - // which is canonical. - return new ECDSASignature(r, CURVE.getN().subtract(s)); - } else { - return this; - } - } - - /** - * @return - - */ - public String toBase64() { - byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 - // bytes for S - sigData[0] = v; - System.arraycopy(bigIntegerToBytes(this.r, 32), 0, sigData, 1, 32); - System.arraycopy(bigIntegerToBytes(this.s, 32), 0, sigData, 33, 32); - return new String(Base64.encode(sigData), Charset.forName("UTF-8")); - } - - public byte[] toByteArray() { - final byte fixedV = this.v >= 27 - ? (byte) (this.v - 27) - : this.v; - - return ByteUtil.merge( - ByteUtil.bigIntegerToBytes(this.r), - ByteUtil.bigIntegerToBytes(this.s), - new byte[]{fixedV}); - } - - public String toHex() { - return Hex.toHexString(toByteArray()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ECDSASignature signature = (ECDSASignature) o; - - if (!r.equals(signature.r)) { - return false; - } - return s.equals(signature.s); - } - - @Override - public int hashCode() { - int result = r.hashCode(); - result = 31 * result + s.hashCode(); - return result; - } - } - - @SuppressWarnings("serial") - public static class MissingPrivateKeyException extends RuntimeException { - } + } } diff --git a/src/main/java/org/tron/common/crypto/Hash.java b/src/main/java/org/tron/common/crypto/Hash.java index fbe5f6457a7..5c173065f73 100644 --- a/src/main/java/org/tron/common/crypto/Hash.java +++ b/src/main/java/org/tron/common/crypto/Hash.java @@ -18,120 +18,118 @@ package org.tron.common.crypto; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.tron.common.crypto.jce.TronCastleProvider; +import static java.util.Arrays.copyOfRange; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Security; - -import static java.util.Arrays.copyOfRange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.tron.common.crypto.jce.TronCastleProvider; public class Hash { - private static final Logger LOG = LoggerFactory.getLogger(Hash.class); - private static final Provider CRYPTO_PROVIDER; + private static final Logger LOG = LoggerFactory.getLogger(Hash.class); + private static final Provider CRYPTO_PROVIDER; - private static final String HASH_256_ALGORITHM_NAME; - private static final String HASH_512_ALGORITHM_NAME; + private static final String HASH_256_ALGORITHM_NAME; + private static final String HASH_512_ALGORITHM_NAME; - private static final MessageDigest sha256digest; - - static { - Security.addProvider(TronCastleProvider.getInstance()); - CRYPTO_PROVIDER = Security.getProvider("SC"); - HASH_256_ALGORITHM_NAME = "TRON-KECCAK-256"; - HASH_512_ALGORITHM_NAME = "TRON-KECCAK-512"; - try { - sha256digest = MessageDigest.getInstance("SHA-256"); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't initialize HashUtils", e); - throw new RuntimeException(e); // Can't happen. - } - - } - - /** - * @param input - data for hashing - * @return - sha256 hash of the data - */ - public static byte[] sha256(byte[] input) { - return sha256digest.digest(input); - } - - public static byte[] sha3(byte[] input) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, - CRYPTO_PROVIDER); - digest.update(input); - return digest.digest(); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't find such algorithm", e); - throw new RuntimeException(e); - } + private static final MessageDigest sha256digest; + static { + Security.addProvider(TronCastleProvider.getInstance()); + CRYPTO_PROVIDER = Security.getProvider("SC"); + HASH_256_ALGORITHM_NAME = "TRON-KECCAK-256"; + HASH_512_ALGORITHM_NAME = "TRON-KECCAK-512"; + try { + sha256digest = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't initialize HashUtils", e); + throw new RuntimeException(e); // Can't happen. } - public static byte[] sha3(byte[] input1, byte[] input2) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, - CRYPTO_PROVIDER); - digest.update(input1, 0, input1.length); - digest.update(input2, 0, input2.length); - return digest.digest(); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't find such algorithm", e); - throw new RuntimeException(e); - } + } + + /** + * @param input - data for hashing + * @return - sha256 hash of the data + */ + public static byte[] sha256(byte[] input) { + return sha256digest.digest(input); + } + + public static byte[] sha3(byte[] input) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, + CRYPTO_PROVIDER); + digest.update(input); + return digest.digest(); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't find such algorithm", e); + throw new RuntimeException(e); } - /** - * hashing chunk of the data - * - * @param input - data for hash - * @param start - start of hashing chunk - * @param length - length of hashing chunk - * @return - keccak hash of the chunk - */ - public static byte[] sha3(byte[] input, int start, int length) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, - CRYPTO_PROVIDER); - digest.update(input, start, length); - return digest.digest(); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't find such algorithm", e); - throw new RuntimeException(e); - } + } + + public static byte[] sha3(byte[] input1, byte[] input2) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, + CRYPTO_PROVIDER); + digest.update(input1, 0, input1.length); + digest.update(input2, 0, input2.length); + return digest.digest(); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't find such algorithm", e); + throw new RuntimeException(e); } - - public static byte[] sha512(byte[] input) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(HASH_512_ALGORITHM_NAME, - CRYPTO_PROVIDER); - digest.update(input); - return digest.digest(); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't find such algorithm", e); - throw new RuntimeException(e); - } + } + + /** + * hashing chunk of the data + * + * @param input - data for hash + * @param start - start of hashing chunk + * @param length - length of hashing chunk + * @return - keccak hash of the chunk + */ + public static byte[] sha3(byte[] input, int start, int length) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, + CRYPTO_PROVIDER); + digest.update(input, start, length); + return digest.digest(); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't find such algorithm", e); + throw new RuntimeException(e); } - - /** - * Calculates RIGTMOST160(SHA3(input)). This is used in address - * calculations. * - * - * @param input - data - * @return - 20 right bytes of the hash keccak of the data - */ - public static byte[] sha3omit12(byte[] input) { - byte[] hash = sha3(input); - return copyOfRange(hash, 12, hash.length); + } + + public static byte[] sha512(byte[] input) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance(HASH_512_ALGORITHM_NAME, + CRYPTO_PROVIDER); + digest.update(input); + return digest.digest(); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't find such algorithm", e); + throw new RuntimeException(e); } + } + + /** + * Calculates RIGTMOST160(SHA3(input)). This is used in address calculations. * + * + * @param input - data + * @return - 20 right bytes of the hash keccak of the data + */ + public static byte[] sha3omit12(byte[] input) { + byte[] hash = sha3(input); + return copyOfRange(hash, 12, hash.length); + } } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/Digest.java b/src/main/java/org/tron/common/crypto/cryptohash/Digest.java index c46c4586018..bc62556e220 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/Digest.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/Digest.java @@ -21,132 +21,118 @@ /** * Copyright (c) 2007-2010 Projet RNRT SAPHIR * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ public interface Digest { - /** - * Insert one more input data byte. - * - * @param in the input byte - */ - void update(byte in); + /** + * Insert one more input data byte. + * + * @param in the input byte + */ + void update(byte in); - /** - * Insert some more bytes. - * - * @param inbuf the data bytes - */ - void update(byte[] inbuf); + /** + * Insert some more bytes. + * + * @param inbuf the data bytes + */ + void update(byte[] inbuf); - /** - * Insert some more bytes. - * - * @param inbuf the data buffer - * @param off the data offset in {@code inbuf} - * @param len the data length (in bytes) - */ - void update(byte[] inbuf, int off, int len); + /** + * Insert some more bytes. + * + * @param inbuf the data buffer + * @param off the data offset in {@code inbuf} + * @param len the data length (in bytes) + */ + void update(byte[] inbuf, int off, int len); - /** - * Finalize the current hash computation and return the hash value - * in a newly-allocated array. The object is resetted. - * - * @return the hash output - */ - byte[] digest(); + /** + * Finalize the current hash computation and return the hash value in a newly-allocated array. The + * object is resetted. + * + * @return the hash output + */ + byte[] digest(); - /** - * Input some bytes, then finalize the current hash computation - * and return the hash value in a newly-allocated array. The object - * is resetted. - * - * @param inbuf the input data - * @return the hash output - */ - byte[] digest(byte[] inbuf); + /** + * Input some bytes, then finalize the current hash computation and return the hash value in a + * newly-allocated array. The object is resetted. + * + * @param inbuf the input data + * @return the hash output + */ + byte[] digest(byte[] inbuf); - /** - * Finalize the current hash computation and store the hash value - * in the provided output buffer. The {@code len} parameter - * contains the maximum number of bytes that should be written; - * no more bytes than the natural hash function output length will - * be produced. If {@code len} is smaller than the natural - * hash output length, the hash output is truncated to its first - * {@code len} bytes. The object is resetted. - * - * @param outbuf the output buffer - * @param off the output offset within {@code outbuf} - * @param len the requested hash output length (in bytes) - * @return the number of bytes actually written in {@code outbuf} - */ - int digest(byte[] outbuf, int off, int len); + /** + * Finalize the current hash computation and store the hash value in the provided output buffer. + * The {@code len} parameter contains the maximum number of bytes that should be written; no more + * bytes than the natural hash function output length will be produced. If {@code len} is smaller + * than the natural hash output length, the hash output is truncated to its first {@code len} + * bytes. The object is resetted. + * + * @param outbuf the output buffer + * @param off the output offset within {@code outbuf} + * @param len the requested hash output length (in bytes) + * @return the number of bytes actually written in {@code outbuf} + */ + int digest(byte[] outbuf, int off, int len); - /** - * Get the natural hash function output length (in bytes). - * - * @return the digest output length (in bytes) - */ - int getDigestLength(); + /** + * Get the natural hash function output length (in bytes). + * + * @return the digest output length (in bytes) + */ + int getDigestLength(); - /** - * Reset the object: this makes it suitable for a new hash - * computation. The current computation, if any, is discarded. - */ - void reset(); + /** + * Reset the object: this makes it suitable for a new hash computation. The current computation, + * if any, is discarded. + */ + void reset(); - /** - * Clone the current state. The returned object evolves independantly - * of this object. - * - * @return the clone - */ - Digest copy(); + /** + * Clone the current state. The returned object evolves independantly of this object. + * + * @return the clone + */ + Digest copy(); - /** - *

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

- *

- *

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

- * - * @return the internal block length (in bytes), or {@code -n} - */ - int getBlockLength(); + /** + *

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

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

+ * + * @return the internal block length (in bytes), or {@code -n} + */ + int getBlockLength(); - /** - *

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

- * - * @see Object - */ - String toString(); + /** + *

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

+ * + * @see Object + */ + String toString(); } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java b/src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java index e1939646b05..baf6735b75d 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java @@ -22,220 +22,208 @@ public abstract class DigestEngine extends MessageDigest implements Digest { - private int digestLen, blockLen, inputLen; - private byte[] inputBuf, outputBuf; - private long blockCount; - - /** - * Instantiate the engine. - */ - public DigestEngine(String alg) { - super(alg); - doInit(); - digestLen = engineGetDigestLength(); - blockLen = getInternalBlockLength(); - inputBuf = new byte[blockLen]; - outputBuf = new byte[digestLen]; - inputLen = 0; - blockCount = 0; - } - - /** - * Reset the hash algorithm state. - */ - protected abstract void engineReset(); - - /** - * Process one block of data. - * - * @param data the data block - */ - protected abstract void processBlock(byte[] data); - - /** - * Perform the final padding and store the result in the - * provided buffer. This method shall call {@link #flush} - * and then {@link #update} with the appropriate padding - * data in order to getData the full input data. - * - * @param buf the output buffer - * @param off the output offset - */ - protected abstract void doPadding(byte[] buf, int off); - - /** - * This function is called at object creation time; the - * implementation should use it to perform initialization tasks. - * After this method is called, the implementation should be ready - * to process data or meaningfully honour calls such as - * {@link #engineGetDigestLength} - */ - protected abstract void doInit(); - - private void adjustDigestLen() { - if (digestLen == 0) { - digestLen = engineGetDigestLength(); - outputBuf = new byte[digestLen]; - } + private int digestLen, blockLen, inputLen; + private byte[] inputBuf, outputBuf; + private long blockCount; + + /** + * Instantiate the engine. + */ + public DigestEngine(String alg) { + super(alg); + doInit(); + digestLen = engineGetDigestLength(); + blockLen = getInternalBlockLength(); + inputBuf = new byte[blockLen]; + outputBuf = new byte[digestLen]; + inputLen = 0; + blockCount = 0; + } + + /** + * Reset the hash algorithm state. + */ + protected abstract void engineReset(); + + /** + * Process one block of data. + * + * @param data the data block + */ + protected abstract void processBlock(byte[] data); + + /** + * Perform the final padding and store the result in the provided buffer. This method shall call + * {@link #flush} and then {@link #update} with the appropriate padding data in order to getData + * the full input data. + * + * @param buf the output buffer + * @param off the output offset + */ + protected abstract void doPadding(byte[] buf, int off); + + /** + * This function is called at object creation time; the implementation should use it to perform + * initialization tasks. After this method is called, the implementation should be ready to + * process data or meaningfully honour calls such as {@link #engineGetDigestLength} + */ + protected abstract void doInit(); + + private void adjustDigestLen() { + if (digestLen == 0) { + digestLen = engineGetDigestLength(); + outputBuf = new byte[digestLen]; } - - /** - * @see Digest - */ - public byte[] digest() { - adjustDigestLen(); - byte[] result = new byte[digestLen]; - digest(result, 0, digestLen); - return result; - } - - /** - * @see Digest - */ - public byte[] digest(byte[] input) { - update(input, 0, input.length); - return digest(); + } + + /** + * @see Digest + */ + public byte[] digest() { + adjustDigestLen(); + byte[] result = new byte[digestLen]; + digest(result, 0, digestLen); + return result; + } + + /** + * @see Digest + */ + public byte[] digest(byte[] input) { + update(input, 0, input.length); + return digest(); + } + + /** + * @see Digest + */ + public int digest(byte[] buf, int offset, int len) { + adjustDigestLen(); + if (len >= digestLen) { + doPadding(buf, offset); + reset(); + return digestLen; + } else { + doPadding(outputBuf, 0); + System.arraycopy(outputBuf, 0, buf, offset, len); + reset(); + return len; } - - /** - * @see Digest - */ - public int digest(byte[] buf, int offset, int len) { - adjustDigestLen(); - if (len >= digestLen) { - doPadding(buf, offset); - reset(); - return digestLen; - } else { - doPadding(outputBuf, 0); - System.arraycopy(outputBuf, 0, buf, offset, len); - reset(); - return len; - } + } + + /** + * @see Digest + */ + public void reset() { + engineReset(); + inputLen = 0; + blockCount = 0; + } + + /** + * @see Digest + */ + public void update(byte input) { + inputBuf[inputLen++] = input; + if (inputLen == blockLen) { + processBlock(inputBuf); + blockCount++; + inputLen = 0; } - - /** - * @see Digest - */ - public void reset() { - engineReset(); + } + + /** + * @see Digest + */ + public void update(byte[] input) { + update(input, 0, input.length); + } + + /** + * @see Digest + */ + public void update(byte[] input, int offset, int len) { + while (len > 0) { + int copyLen = blockLen - inputLen; + if (copyLen > len) { + copyLen = len; + } + System.arraycopy(input, offset, inputBuf, inputLen, + copyLen); + offset += copyLen; + inputLen += copyLen; + len -= copyLen; + if (inputLen == blockLen) { + processBlock(inputBuf); + blockCount++; inputLen = 0; - blockCount = 0; - } - - /** - * @see Digest - */ - public void update(byte input) { - inputBuf[inputLen++] = input; - if (inputLen == blockLen) { - processBlock(inputBuf); - blockCount++; - inputLen = 0; - } - } - - /** - * @see Digest - */ - public void update(byte[] input) { - update(input, 0, input.length); - } - - /** - * @see Digest - */ - public void update(byte[] input, int offset, int len) { - while (len > 0) { - int copyLen = blockLen - inputLen; - if (copyLen > len) { - copyLen = len; - } - System.arraycopy(input, offset, inputBuf, inputLen, - copyLen); - offset += copyLen; - inputLen += copyLen; - len -= copyLen; - if (inputLen == blockLen) { - processBlock(inputBuf); - blockCount++; - inputLen = 0; - } - } - } - - /** - * Get the internal block length. This is the length (in - * bytes) of the array which will be passed as parameter to - * {@link #processBlock}. The default implementation of this - * method calls {@link #getBlockLength} and returns the same - * value. Overriding this method is useful when the advertised - * block length (which is used, for instance, by HMAC) is - * suboptimal with regards to internal buffering needs. - * - * @return the internal block length (in bytes) - */ - protected int getInternalBlockLength() { - return getBlockLength(); - } - - /** - * Flush internal buffers, so that less than a block of data - * may at most be upheld. - * - * @return the number of bytes still unprocessed after the flush - */ - protected final int flush() { - return inputLen; - } - - /** - * Get a reference to an internal buffer with the same size - * than a block. The contents of that buffer are defined only - * immediately after a call to {@link #flush()}: if - * {@link #flush()} return the value {@code n}, then the - * first {@code n} bytes of the array returned by this method - * are the {@code n} bytes of input data which are still - * unprocessed. The values of the remaining bytes are - * undefined and may be altered at will. - * - * @return a block-sized internal buffer - */ - protected final byte[] getBlockBuffer() { - return inputBuf; - } - - /** - * Get the "block count": this is the number of times the - * {@link #processBlock} method has been invoked for the - * current hash operation. That counter is incremented - * after the call to {@link #processBlock}. - * - * @return the block count - */ - protected long getBlockCount() { - return blockCount; - } - - /** - * This function copies the internal buffering state to some - * other instance of a class extending {@code DigestEngine}. - * It returns a reference to the copy. This method is intended - * to be called by the implementation of the {@link #copy} - * method. - * - * @param dest the copy - * @return the value {@code dest} - */ - protected Digest copyState(DigestEngine dest) { - dest.inputLen = inputLen; - dest.blockCount = blockCount; - System.arraycopy(inputBuf, 0, dest.inputBuf, 0, - inputBuf.length); - adjustDigestLen(); - dest.adjustDigestLen(); - System.arraycopy(outputBuf, 0, dest.outputBuf, 0, - outputBuf.length); - return dest; + } } + } + + /** + * Get the internal block length. This is the length (in bytes) of the array which will be passed + * as parameter to {@link #processBlock}. The default implementation of this method calls {@link + * #getBlockLength} and returns the same value. Overriding this method is useful when the + * advertised block length (which is used, for instance, by HMAC) is suboptimal with regards to + * internal buffering needs. + * + * @return the internal block length (in bytes) + */ + protected int getInternalBlockLength() { + return getBlockLength(); + } + + /** + * Flush internal buffers, so that less than a block of data may at most be upheld. + * + * @return the number of bytes still unprocessed after the flush + */ + protected final int flush() { + return inputLen; + } + + /** + * Get a reference to an internal buffer with the same size than a block. The contents of that + * buffer are defined only immediately after a call to {@link #flush()}: if {@link #flush()} + * return the value {@code n}, then the first {@code n} bytes of the array returned by this method + * are the {@code n} bytes of input data which are still unprocessed. The values of the remaining + * bytes are undefined and may be altered at will. + * + * @return a block-sized internal buffer + */ + protected final byte[] getBlockBuffer() { + return inputBuf; + } + + /** + * Get the "block count": this is the number of times the {@link #processBlock} method has been + * invoked for the current hash operation. That counter is incremented after the call to + * {@link #processBlock}. + * + * @return the block count + */ + protected long getBlockCount() { + return blockCount; + } + + /** + * This function copies the internal buffering state to some other instance of a class extending + * {@code DigestEngine}. It returns a reference to the copy. This method is intended to be called + * by the implementation of the {@link #copy} method. + * + * @param dest the copy + * @return the value {@code dest} + */ + protected Digest copyState(DigestEngine dest) { + dest.inputLen = inputLen; + dest.blockCount = blockCount; + System.arraycopy(inputBuf, 0, dest.inputBuf, 0, + inputBuf.length); + adjustDigestLen(); + dest.adjustDigestLen(); + System.arraycopy(outputBuf, 0, dest.outputBuf, 0, + outputBuf.length); + return dest; + } } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/Keccak256.java b/src/main/java/org/tron/common/crypto/cryptohash/Keccak256.java index 7d069da98fa..ea11f4a13a4 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/Keccak256.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/Keccak256.java @@ -20,31 +20,31 @@ public class Keccak256 extends KeccakCore { - /** - * Create the engine. - */ - public Keccak256() { - super("tron-keccak-256"); - } - - public Digest copy() { - return copyState(new Keccak256()); - } - - public int engineGetDigestLength() { - return 32; - } - - @Override - protected byte[] engineDigest() { - return null; - } - - @Override - protected void engineUpdate(byte arg0) { - } - - @Override - protected void engineUpdate(byte[] arg0, int arg1, int arg2) { - } + /** + * Create the engine. + */ + public Keccak256() { + super("tron-keccak-256"); + } + + public Digest copy() { + return copyState(new Keccak256()); + } + + public int engineGetDigestLength() { + return 32; + } + + @Override + protected byte[] engineDigest() { + return null; + } + + @Override + protected void engineUpdate(byte arg0) { + } + + @Override + protected void engineUpdate(byte[] arg0, int arg1, int arg2) { + } } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java b/src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java index 6d8eef58a03..824e3b2afde 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java @@ -20,31 +20,31 @@ public class Keccak512 extends KeccakCore { - /** - * Create the engine. - */ - public Keccak512() { - super("tron-keccak-512"); - } - - public Digest copy() { - return copyState(new Keccak512()); - } - - public int engineGetDigestLength() { - return 64; - } - - @Override - protected byte[] engineDigest() { - return null; - } - - @Override - protected void engineUpdate(byte input) { - } - - @Override - protected void engineUpdate(byte[] input, int offset, int len) { - } + /** + * Create the engine. + */ + public Keccak512() { + super("tron-keccak-512"); + } + + public Digest copy() { + return copyState(new Keccak512()); + } + + public int engineGetDigestLength() { + return 64; + } + + @Override + protected byte[] engineDigest() { + return null; + } + + @Override + protected void engineUpdate(byte input) { + } + + @Override + protected void engineUpdate(byte[] input, int offset, int len) { + } } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java b/src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java index 770238c4ed6..3fa7e660d5a 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java @@ -20,533 +20,531 @@ abstract class KeccakCore extends DigestEngine { - private static final long[] RC = { - 0x0000000000000001L, 0x0000000000008082L, - 0x800000000000808AL, 0x8000000080008000L, - 0x000000000000808BL, 0x0000000080000001L, - 0x8000000080008081L, 0x8000000000008009L, - 0x000000000000008AL, 0x0000000000000088L, - 0x0000000080008009L, 0x000000008000000AL, - 0x000000008000808BL, 0x800000000000008BL, - 0x8000000000008089L, 0x8000000000008003L, - 0x8000000000008002L, 0x8000000000000080L, - 0x000000000000800AL, 0x800000008000000AL, - 0x8000000080008081L, 0x8000000000008080L, - 0x0000000080000001L, 0x8000000080008008L - }; - private long[] A; - private byte[] tmpOut; + private static final long[] RC = { + 0x0000000000000001L, 0x0000000000008082L, + 0x800000000000808AL, 0x8000000080008000L, + 0x000000000000808BL, 0x0000000080000001L, + 0x8000000080008081L, 0x8000000000008009L, + 0x000000000000008AL, 0x0000000000000088L, + 0x0000000080008009L, 0x000000008000000AL, + 0x000000008000808BL, 0x800000000000008BL, + 0x8000000000008089L, 0x8000000000008003L, + 0x8000000000008002L, 0x8000000000000080L, + 0x000000000000800AL, 0x800000008000000AL, + 0x8000000080008081L, 0x8000000000008080L, + 0x0000000080000001L, 0x8000000080008008L + }; + private long[] A; + private byte[] tmpOut; - KeccakCore(String alg) { - super(alg); - } + KeccakCore(String alg) { + super(alg); + } - /** - * Encode the 64-bit word {@code val} into the array - * {@code buf} at offset {@code off}, in little-endian - * convention (least significant byte first). - * - * @param val the value to encode - * @param buf the destination buffer - * @param off the destination offset - */ - private static void encodeLELong(long val, byte[] buf, int off) { - buf[off + 0] = (byte) val; - buf[off + 1] = (byte) (val >>> 8); - buf[off + 2] = (byte) (val >>> 16); - buf[off + 3] = (byte) (val >>> 24); - buf[off + 4] = (byte) (val >>> 32); - buf[off + 5] = (byte) (val >>> 40); - buf[off + 6] = (byte) (val >>> 48); - buf[off + 7] = (byte) (val >>> 56); - } + /** + * Encode the 64-bit word {@code val} into the array {@code buf} at offset {@code off}, in + * little-endian convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static void encodeLELong(long val, byte[] buf, int off) { + buf[off + 0] = (byte) val; + buf[off + 1] = (byte) (val >>> 8); + buf[off + 2] = (byte) (val >>> 16); + buf[off + 3] = (byte) (val >>> 24); + buf[off + 4] = (byte) (val >>> 32); + buf[off + 5] = (byte) (val >>> 40); + buf[off + 6] = (byte) (val >>> 48); + buf[off + 7] = (byte) (val >>> 56); + } - /** - * Decode a 64-bit little-endian word from the array {@code buf} - * at offset {@code off}. - * - * @param buf the source buffer - * @param off the source offset - * @return the decoded value - */ - private static long decodeLELong(byte[] buf, int off) { - return (buf[off + 0] & 0xFFL) - | ((buf[off + 1] & 0xFFL) << 8) - | ((buf[off + 2] & 0xFFL) << 16) - | ((buf[off + 3] & 0xFFL) << 24) - | ((buf[off + 4] & 0xFFL) << 32) - | ((buf[off + 5] & 0xFFL) << 40) - | ((buf[off + 6] & 0xFFL) << 48) - | ((buf[off + 7] & 0xFFL) << 56); - } + /** + * Decode a 64-bit little-endian word from the array {@code buf} at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static long decodeLELong(byte[] buf, int off) { + return (buf[off + 0] & 0xFFL) + | ((buf[off + 1] & 0xFFL) << 8) + | ((buf[off + 2] & 0xFFL) << 16) + | ((buf[off + 3] & 0xFFL) << 24) + | ((buf[off + 4] & 0xFFL) << 32) + | ((buf[off + 5] & 0xFFL) << 40) + | ((buf[off + 6] & 0xFFL) << 48) + | ((buf[off + 7] & 0xFFL) << 56); + } - protected void engineReset() { - doReset(); - } + protected void engineReset() { + doReset(); + } - protected void processBlock(byte[] data) { - /* Input block */ - for (int i = 0; i < data.length; i += 8) { - A[i >>> 3] ^= decodeLELong(data, i); - } + protected void processBlock(byte[] data) { + /* Input block */ + for (int i = 0; i < data.length; i += 8) { + A[i >>> 3] ^= decodeLELong(data, i); + } - long t0, t1, t2, t3, t4; - long tt0, tt1, tt2, tt3, tt4; - long t, kt; - long c0, c1, c2, c3, c4, bnn; + long t0, t1, t2, t3, t4; + long tt0, tt1, tt2, tt3, tt4; + long t, kt; + long c0, c1, c2, c3, c4, bnn; - /* - * Unrolling four rounds kills performance big time - * on Intel x86 Core2, in both 32-bit and 64-bit modes - * (less than 1 MB/s instead of 55 MB/s on x86-64). - * Unrolling two rounds appears to be fine. - */ - for (int j = 0; j < 24; j += 2) { + /* + * Unrolling four rounds kills performance big time + * on Intel x86 Core2, in both 32-bit and 64-bit modes + * (less than 1 MB/s instead of 55 MB/s on x86-64). + * Unrolling two rounds appears to be fine. + */ + for (int j = 0; j < 24; j += 2) { - tt0 = A[1] ^ A[6]; - tt1 = A[11] ^ A[16]; - tt0 ^= A[21] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[4] ^ A[9]; - tt3 = A[14] ^ A[19]; - tt0 ^= A[24]; - tt2 ^= tt3; - t0 = tt0 ^ tt2; + tt0 = A[1] ^ A[6]; + tt1 = A[11] ^ A[16]; + tt0 ^= A[21] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[4] ^ A[9]; + tt3 = A[14] ^ A[19]; + tt0 ^= A[24]; + tt2 ^= tt3; + t0 = tt0 ^ tt2; - tt0 = A[2] ^ A[7]; - tt1 = A[12] ^ A[17]; - tt0 ^= A[22] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[0] ^ A[5]; - tt3 = A[10] ^ A[15]; - tt0 ^= A[20]; - tt2 ^= tt3; - t1 = tt0 ^ tt2; + tt0 = A[2] ^ A[7]; + tt1 = A[12] ^ A[17]; + tt0 ^= A[22] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[0] ^ A[5]; + tt3 = A[10] ^ A[15]; + tt0 ^= A[20]; + tt2 ^= tt3; + t1 = tt0 ^ tt2; - tt0 = A[3] ^ A[8]; - tt1 = A[13] ^ A[18]; - tt0 ^= A[23] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[1] ^ A[6]; - tt3 = A[11] ^ A[16]; - tt0 ^= A[21]; - tt2 ^= tt3; - t2 = tt0 ^ tt2; + tt0 = A[3] ^ A[8]; + tt1 = A[13] ^ A[18]; + tt0 ^= A[23] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[1] ^ A[6]; + tt3 = A[11] ^ A[16]; + tt0 ^= A[21]; + tt2 ^= tt3; + t2 = tt0 ^ tt2; - tt0 = A[4] ^ A[9]; - tt1 = A[14] ^ A[19]; - tt0 ^= A[24] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[2] ^ A[7]; - tt3 = A[12] ^ A[17]; - tt0 ^= A[22]; - tt2 ^= tt3; - t3 = tt0 ^ tt2; + tt0 = A[4] ^ A[9]; + tt1 = A[14] ^ A[19]; + tt0 ^= A[24] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[2] ^ A[7]; + tt3 = A[12] ^ A[17]; + tt0 ^= A[22]; + tt2 ^= tt3; + t3 = tt0 ^ tt2; - tt0 = A[0] ^ A[5]; - tt1 = A[10] ^ A[15]; - tt0 ^= A[20] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[3] ^ A[8]; - tt3 = A[13] ^ A[18]; - tt0 ^= A[23]; - tt2 ^= tt3; - t4 = tt0 ^ tt2; + tt0 = A[0] ^ A[5]; + tt1 = A[10] ^ A[15]; + tt0 ^= A[20] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[3] ^ A[8]; + tt3 = A[13] ^ A[18]; + tt0 ^= A[23]; + tt2 ^= tt3; + t4 = tt0 ^ tt2; - A[0] = A[0] ^ t0; - A[5] = A[5] ^ t0; - A[10] = A[10] ^ t0; - A[15] = A[15] ^ t0; - A[20] = A[20] ^ t0; - A[1] = A[1] ^ t1; - A[6] = A[6] ^ t1; - A[11] = A[11] ^ t1; - A[16] = A[16] ^ t1; - A[21] = A[21] ^ t1; - A[2] = A[2] ^ t2; - A[7] = A[7] ^ t2; - A[12] = A[12] ^ t2; - A[17] = A[17] ^ t2; - A[22] = A[22] ^ t2; - A[3] = A[3] ^ t3; - A[8] = A[8] ^ t3; - A[13] = A[13] ^ t3; - A[18] = A[18] ^ t3; - A[23] = A[23] ^ t3; - A[4] = A[4] ^ t4; - A[9] = A[9] ^ t4; - A[14] = A[14] ^ t4; - A[19] = A[19] ^ t4; - A[24] = A[24] ^ t4; - A[5] = (A[5] << 36) | (A[5] >>> (64 - 36)); - A[10] = (A[10] << 3) | (A[10] >>> (64 - 3)); - A[15] = (A[15] << 41) | (A[15] >>> (64 - 41)); - A[20] = (A[20] << 18) | (A[20] >>> (64 - 18)); - A[1] = (A[1] << 1) | (A[1] >>> (64 - 1)); - A[6] = (A[6] << 44) | (A[6] >>> (64 - 44)); - A[11] = (A[11] << 10) | (A[11] >>> (64 - 10)); - A[16] = (A[16] << 45) | (A[16] >>> (64 - 45)); - A[21] = (A[21] << 2) | (A[21] >>> (64 - 2)); - A[2] = (A[2] << 62) | (A[2] >>> (64 - 62)); - A[7] = (A[7] << 6) | (A[7] >>> (64 - 6)); - A[12] = (A[12] << 43) | (A[12] >>> (64 - 43)); - A[17] = (A[17] << 15) | (A[17] >>> (64 - 15)); - A[22] = (A[22] << 61) | (A[22] >>> (64 - 61)); - A[3] = (A[3] << 28) | (A[3] >>> (64 - 28)); - A[8] = (A[8] << 55) | (A[8] >>> (64 - 55)); - A[13] = (A[13] << 25) | (A[13] >>> (64 - 25)); - A[18] = (A[18] << 21) | (A[18] >>> (64 - 21)); - A[23] = (A[23] << 56) | (A[23] >>> (64 - 56)); - A[4] = (A[4] << 27) | (A[4] >>> (64 - 27)); - A[9] = (A[9] << 20) | (A[9] >>> (64 - 20)); - A[14] = (A[14] << 39) | (A[14] >>> (64 - 39)); - A[19] = (A[19] << 8) | (A[19] >>> (64 - 8)); - A[24] = (A[24] << 14) | (A[24] >>> (64 - 14)); - bnn = ~A[12]; - kt = A[6] | A[12]; - c0 = A[0] ^ kt; - kt = bnn | A[18]; - c1 = A[6] ^ kt; - kt = A[18] & A[24]; - c2 = A[12] ^ kt; - kt = A[24] | A[0]; - c3 = A[18] ^ kt; - kt = A[0] & A[6]; - c4 = A[24] ^ kt; - A[0] = c0; - A[6] = c1; - A[12] = c2; - A[18] = c3; - A[24] = c4; - bnn = ~A[22]; - kt = A[9] | A[10]; - c0 = A[3] ^ kt; - kt = A[10] & A[16]; - c1 = A[9] ^ kt; - kt = A[16] | bnn; - c2 = A[10] ^ kt; - kt = A[22] | A[3]; - c3 = A[16] ^ kt; - kt = A[3] & A[9]; - c4 = A[22] ^ kt; - A[3] = c0; - A[9] = c1; - A[10] = c2; - A[16] = c3; - A[22] = c4; - bnn = ~A[19]; - kt = A[7] | A[13]; - c0 = A[1] ^ kt; - kt = A[13] & A[19]; - c1 = A[7] ^ kt; - kt = bnn & A[20]; - c2 = A[13] ^ kt; - kt = A[20] | A[1]; - c3 = bnn ^ kt; - kt = A[1] & A[7]; - c4 = A[20] ^ kt; - A[1] = c0; - A[7] = c1; - A[13] = c2; - A[19] = c3; - A[20] = c4; - bnn = ~A[17]; - kt = A[5] & A[11]; - c0 = A[4] ^ kt; - kt = A[11] | A[17]; - c1 = A[5] ^ kt; - kt = bnn | A[23]; - c2 = A[11] ^ kt; - kt = A[23] & A[4]; - c3 = bnn ^ kt; - kt = A[4] | A[5]; - c4 = A[23] ^ kt; - A[4] = c0; - A[5] = c1; - A[11] = c2; - A[17] = c3; - A[23] = c4; - bnn = ~A[8]; - kt = bnn & A[14]; - c0 = A[2] ^ kt; - kt = A[14] | A[15]; - c1 = bnn ^ kt; - kt = A[15] & A[21]; - c2 = A[14] ^ kt; - kt = A[21] | A[2]; - c3 = A[15] ^ kt; - kt = A[2] & A[8]; - c4 = A[21] ^ kt; - A[2] = c0; - A[8] = c1; - A[14] = c2; - A[15] = c3; - A[21] = c4; - A[0] = A[0] ^ RC[j + 0]; + A[0] = A[0] ^ t0; + A[5] = A[5] ^ t0; + A[10] = A[10] ^ t0; + A[15] = A[15] ^ t0; + A[20] = A[20] ^ t0; + A[1] = A[1] ^ t1; + A[6] = A[6] ^ t1; + A[11] = A[11] ^ t1; + A[16] = A[16] ^ t1; + A[21] = A[21] ^ t1; + A[2] = A[2] ^ t2; + A[7] = A[7] ^ t2; + A[12] = A[12] ^ t2; + A[17] = A[17] ^ t2; + A[22] = A[22] ^ t2; + A[3] = A[3] ^ t3; + A[8] = A[8] ^ t3; + A[13] = A[13] ^ t3; + A[18] = A[18] ^ t3; + A[23] = A[23] ^ t3; + A[4] = A[4] ^ t4; + A[9] = A[9] ^ t4; + A[14] = A[14] ^ t4; + A[19] = A[19] ^ t4; + A[24] = A[24] ^ t4; + A[5] = (A[5] << 36) | (A[5] >>> (64 - 36)); + A[10] = (A[10] << 3) | (A[10] >>> (64 - 3)); + A[15] = (A[15] << 41) | (A[15] >>> (64 - 41)); + A[20] = (A[20] << 18) | (A[20] >>> (64 - 18)); + A[1] = (A[1] << 1) | (A[1] >>> (64 - 1)); + A[6] = (A[6] << 44) | (A[6] >>> (64 - 44)); + A[11] = (A[11] << 10) | (A[11] >>> (64 - 10)); + A[16] = (A[16] << 45) | (A[16] >>> (64 - 45)); + A[21] = (A[21] << 2) | (A[21] >>> (64 - 2)); + A[2] = (A[2] << 62) | (A[2] >>> (64 - 62)); + A[7] = (A[7] << 6) | (A[7] >>> (64 - 6)); + A[12] = (A[12] << 43) | (A[12] >>> (64 - 43)); + A[17] = (A[17] << 15) | (A[17] >>> (64 - 15)); + A[22] = (A[22] << 61) | (A[22] >>> (64 - 61)); + A[3] = (A[3] << 28) | (A[3] >>> (64 - 28)); + A[8] = (A[8] << 55) | (A[8] >>> (64 - 55)); + A[13] = (A[13] << 25) | (A[13] >>> (64 - 25)); + A[18] = (A[18] << 21) | (A[18] >>> (64 - 21)); + A[23] = (A[23] << 56) | (A[23] >>> (64 - 56)); + A[4] = (A[4] << 27) | (A[4] >>> (64 - 27)); + A[9] = (A[9] << 20) | (A[9] >>> (64 - 20)); + A[14] = (A[14] << 39) | (A[14] >>> (64 - 39)); + A[19] = (A[19] << 8) | (A[19] >>> (64 - 8)); + A[24] = (A[24] << 14) | (A[24] >>> (64 - 14)); + bnn = ~A[12]; + kt = A[6] | A[12]; + c0 = A[0] ^ kt; + kt = bnn | A[18]; + c1 = A[6] ^ kt; + kt = A[18] & A[24]; + c2 = A[12] ^ kt; + kt = A[24] | A[0]; + c3 = A[18] ^ kt; + kt = A[0] & A[6]; + c4 = A[24] ^ kt; + A[0] = c0; + A[6] = c1; + A[12] = c2; + A[18] = c3; + A[24] = c4; + bnn = ~A[22]; + kt = A[9] | A[10]; + c0 = A[3] ^ kt; + kt = A[10] & A[16]; + c1 = A[9] ^ kt; + kt = A[16] | bnn; + c2 = A[10] ^ kt; + kt = A[22] | A[3]; + c3 = A[16] ^ kt; + kt = A[3] & A[9]; + c4 = A[22] ^ kt; + A[3] = c0; + A[9] = c1; + A[10] = c2; + A[16] = c3; + A[22] = c4; + bnn = ~A[19]; + kt = A[7] | A[13]; + c0 = A[1] ^ kt; + kt = A[13] & A[19]; + c1 = A[7] ^ kt; + kt = bnn & A[20]; + c2 = A[13] ^ kt; + kt = A[20] | A[1]; + c3 = bnn ^ kt; + kt = A[1] & A[7]; + c4 = A[20] ^ kt; + A[1] = c0; + A[7] = c1; + A[13] = c2; + A[19] = c3; + A[20] = c4; + bnn = ~A[17]; + kt = A[5] & A[11]; + c0 = A[4] ^ kt; + kt = A[11] | A[17]; + c1 = A[5] ^ kt; + kt = bnn | A[23]; + c2 = A[11] ^ kt; + kt = A[23] & A[4]; + c3 = bnn ^ kt; + kt = A[4] | A[5]; + c4 = A[23] ^ kt; + A[4] = c0; + A[5] = c1; + A[11] = c2; + A[17] = c3; + A[23] = c4; + bnn = ~A[8]; + kt = bnn & A[14]; + c0 = A[2] ^ kt; + kt = A[14] | A[15]; + c1 = bnn ^ kt; + kt = A[15] & A[21]; + c2 = A[14] ^ kt; + kt = A[21] | A[2]; + c3 = A[15] ^ kt; + kt = A[2] & A[8]; + c4 = A[21] ^ kt; + A[2] = c0; + A[8] = c1; + A[14] = c2; + A[15] = c3; + A[21] = c4; + A[0] = A[0] ^ RC[j + 0]; - tt0 = A[6] ^ A[9]; - tt1 = A[7] ^ A[5]; - tt0 ^= A[8] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[24] ^ A[22]; - tt3 = A[20] ^ A[23]; - tt0 ^= A[21]; - tt2 ^= tt3; - t0 = tt0 ^ tt2; + tt0 = A[6] ^ A[9]; + tt1 = A[7] ^ A[5]; + tt0 ^= A[8] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[24] ^ A[22]; + tt3 = A[20] ^ A[23]; + tt0 ^= A[21]; + tt2 ^= tt3; + t0 = tt0 ^ tt2; - tt0 = A[12] ^ A[10]; - tt1 = A[13] ^ A[11]; - tt0 ^= A[14] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[0] ^ A[3]; - tt3 = A[1] ^ A[4]; - tt0 ^= A[2]; - tt2 ^= tt3; - t1 = tt0 ^ tt2; + tt0 = A[12] ^ A[10]; + tt1 = A[13] ^ A[11]; + tt0 ^= A[14] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[0] ^ A[3]; + tt3 = A[1] ^ A[4]; + tt0 ^= A[2]; + tt2 ^= tt3; + t1 = tt0 ^ tt2; - tt0 = A[18] ^ A[16]; - tt1 = A[19] ^ A[17]; - tt0 ^= A[15] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[6] ^ A[9]; - tt3 = A[7] ^ A[5]; - tt0 ^= A[8]; - tt2 ^= tt3; - t2 = tt0 ^ tt2; + tt0 = A[18] ^ A[16]; + tt1 = A[19] ^ A[17]; + tt0 ^= A[15] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[6] ^ A[9]; + tt3 = A[7] ^ A[5]; + tt0 ^= A[8]; + tt2 ^= tt3; + t2 = tt0 ^ tt2; - tt0 = A[24] ^ A[22]; - tt1 = A[20] ^ A[23]; - tt0 ^= A[21] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[12] ^ A[10]; - tt3 = A[13] ^ A[11]; - tt0 ^= A[14]; - tt2 ^= tt3; - t3 = tt0 ^ tt2; + tt0 = A[24] ^ A[22]; + tt1 = A[20] ^ A[23]; + tt0 ^= A[21] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[12] ^ A[10]; + tt3 = A[13] ^ A[11]; + tt0 ^= A[14]; + tt2 ^= tt3; + t3 = tt0 ^ tt2; - tt0 = A[0] ^ A[3]; - tt1 = A[1] ^ A[4]; - tt0 ^= A[2] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[18] ^ A[16]; - tt3 = A[19] ^ A[17]; - tt0 ^= A[15]; - tt2 ^= tt3; - t4 = tt0 ^ tt2; + tt0 = A[0] ^ A[3]; + tt1 = A[1] ^ A[4]; + tt0 ^= A[2] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[18] ^ A[16]; + tt3 = A[19] ^ A[17]; + tt0 ^= A[15]; + tt2 ^= tt3; + t4 = tt0 ^ tt2; - A[0] = A[0] ^ t0; - A[3] = A[3] ^ t0; - A[1] = A[1] ^ t0; - A[4] = A[4] ^ t0; - A[2] = A[2] ^ t0; - A[6] = A[6] ^ t1; - A[9] = A[9] ^ t1; - A[7] = A[7] ^ t1; - A[5] = A[5] ^ t1; - A[8] = A[8] ^ t1; - A[12] = A[12] ^ t2; - A[10] = A[10] ^ t2; - A[13] = A[13] ^ t2; - A[11] = A[11] ^ t2; - A[14] = A[14] ^ t2; - A[18] = A[18] ^ t3; - A[16] = A[16] ^ t3; - A[19] = A[19] ^ t3; - A[17] = A[17] ^ t3; - A[15] = A[15] ^ t3; - A[24] = A[24] ^ t4; - A[22] = A[22] ^ t4; - A[20] = A[20] ^ t4; - A[23] = A[23] ^ t4; - A[21] = A[21] ^ t4; - A[3] = (A[3] << 36) | (A[3] >>> (64 - 36)); - A[1] = (A[1] << 3) | (A[1] >>> (64 - 3)); - A[4] = (A[4] << 41) | (A[4] >>> (64 - 41)); - A[2] = (A[2] << 18) | (A[2] >>> (64 - 18)); - A[6] = (A[6] << 1) | (A[6] >>> (64 - 1)); - A[9] = (A[9] << 44) | (A[9] >>> (64 - 44)); - A[7] = (A[7] << 10) | (A[7] >>> (64 - 10)); - A[5] = (A[5] << 45) | (A[5] >>> (64 - 45)); - A[8] = (A[8] << 2) | (A[8] >>> (64 - 2)); - A[12] = (A[12] << 62) | (A[12] >>> (64 - 62)); - A[10] = (A[10] << 6) | (A[10] >>> (64 - 6)); - A[13] = (A[13] << 43) | (A[13] >>> (64 - 43)); - A[11] = (A[11] << 15) | (A[11] >>> (64 - 15)); - A[14] = (A[14] << 61) | (A[14] >>> (64 - 61)); - A[18] = (A[18] << 28) | (A[18] >>> (64 - 28)); - A[16] = (A[16] << 55) | (A[16] >>> (64 - 55)); - A[19] = (A[19] << 25) | (A[19] >>> (64 - 25)); - A[17] = (A[17] << 21) | (A[17] >>> (64 - 21)); - A[15] = (A[15] << 56) | (A[15] >>> (64 - 56)); - A[24] = (A[24] << 27) | (A[24] >>> (64 - 27)); - A[22] = (A[22] << 20) | (A[22] >>> (64 - 20)); - A[20] = (A[20] << 39) | (A[20] >>> (64 - 39)); - A[23] = (A[23] << 8) | (A[23] >>> (64 - 8)); - A[21] = (A[21] << 14) | (A[21] >>> (64 - 14)); - bnn = ~A[13]; - kt = A[9] | A[13]; - c0 = A[0] ^ kt; - kt = bnn | A[17]; - c1 = A[9] ^ kt; - kt = A[17] & A[21]; - c2 = A[13] ^ kt; - kt = A[21] | A[0]; - c3 = A[17] ^ kt; - kt = A[0] & A[9]; - c4 = A[21] ^ kt; - A[0] = c0; - A[9] = c1; - A[13] = c2; - A[17] = c3; - A[21] = c4; - bnn = ~A[14]; - kt = A[22] | A[1]; - c0 = A[18] ^ kt; - kt = A[1] & A[5]; - c1 = A[22] ^ kt; - kt = A[5] | bnn; - c2 = A[1] ^ kt; - kt = A[14] | A[18]; - c3 = A[5] ^ kt; - kt = A[18] & A[22]; - c4 = A[14] ^ kt; - A[18] = c0; - A[22] = c1; - A[1] = c2; - A[5] = c3; - A[14] = c4; - bnn = ~A[23]; - kt = A[10] | A[19]; - c0 = A[6] ^ kt; - kt = A[19] & A[23]; - c1 = A[10] ^ kt; - kt = bnn & A[2]; - c2 = A[19] ^ kt; - kt = A[2] | A[6]; - c3 = bnn ^ kt; - kt = A[6] & A[10]; - c4 = A[2] ^ kt; - A[6] = c0; - A[10] = c1; - A[19] = c2; - A[23] = c3; - A[2] = c4; - bnn = ~A[11]; - kt = A[3] & A[7]; - c0 = A[24] ^ kt; - kt = A[7] | A[11]; - c1 = A[3] ^ kt; - kt = bnn | A[15]; - c2 = A[7] ^ kt; - kt = A[15] & A[24]; - c3 = bnn ^ kt; - kt = A[24] | A[3]; - c4 = A[15] ^ kt; - A[24] = c0; - A[3] = c1; - A[7] = c2; - A[11] = c3; - A[15] = c4; - bnn = ~A[16]; - kt = bnn & A[20]; - c0 = A[12] ^ kt; - kt = A[20] | A[4]; - c1 = bnn ^ kt; - kt = A[4] & A[8]; - c2 = A[20] ^ kt; - kt = A[8] | A[12]; - c3 = A[4] ^ kt; - kt = A[12] & A[16]; - c4 = A[8] ^ kt; - A[12] = c0; - A[16] = c1; - A[20] = c2; - A[4] = c3; - A[8] = c4; - A[0] = A[0] ^ RC[j + 1]; - t = A[5]; - A[5] = A[18]; - A[18] = A[11]; - A[11] = A[10]; - A[10] = A[6]; - A[6] = A[22]; - A[22] = A[20]; - A[20] = A[12]; - A[12] = A[19]; - A[19] = A[15]; - A[15] = A[24]; - A[24] = A[8]; - A[8] = t; - t = A[1]; - A[1] = A[9]; - A[9] = A[14]; - A[14] = A[2]; - A[2] = A[13]; - A[13] = A[23]; - A[23] = A[4]; - A[4] = A[21]; - A[21] = A[16]; - A[16] = A[3]; - A[3] = A[17]; - A[17] = A[7]; - A[7] = t; - } + A[0] = A[0] ^ t0; + A[3] = A[3] ^ t0; + A[1] = A[1] ^ t0; + A[4] = A[4] ^ t0; + A[2] = A[2] ^ t0; + A[6] = A[6] ^ t1; + A[9] = A[9] ^ t1; + A[7] = A[7] ^ t1; + A[5] = A[5] ^ t1; + A[8] = A[8] ^ t1; + A[12] = A[12] ^ t2; + A[10] = A[10] ^ t2; + A[13] = A[13] ^ t2; + A[11] = A[11] ^ t2; + A[14] = A[14] ^ t2; + A[18] = A[18] ^ t3; + A[16] = A[16] ^ t3; + A[19] = A[19] ^ t3; + A[17] = A[17] ^ t3; + A[15] = A[15] ^ t3; + A[24] = A[24] ^ t4; + A[22] = A[22] ^ t4; + A[20] = A[20] ^ t4; + A[23] = A[23] ^ t4; + A[21] = A[21] ^ t4; + A[3] = (A[3] << 36) | (A[3] >>> (64 - 36)); + A[1] = (A[1] << 3) | (A[1] >>> (64 - 3)); + A[4] = (A[4] << 41) | (A[4] >>> (64 - 41)); + A[2] = (A[2] << 18) | (A[2] >>> (64 - 18)); + A[6] = (A[6] << 1) | (A[6] >>> (64 - 1)); + A[9] = (A[9] << 44) | (A[9] >>> (64 - 44)); + A[7] = (A[7] << 10) | (A[7] >>> (64 - 10)); + A[5] = (A[5] << 45) | (A[5] >>> (64 - 45)); + A[8] = (A[8] << 2) | (A[8] >>> (64 - 2)); + A[12] = (A[12] << 62) | (A[12] >>> (64 - 62)); + A[10] = (A[10] << 6) | (A[10] >>> (64 - 6)); + A[13] = (A[13] << 43) | (A[13] >>> (64 - 43)); + A[11] = (A[11] << 15) | (A[11] >>> (64 - 15)); + A[14] = (A[14] << 61) | (A[14] >>> (64 - 61)); + A[18] = (A[18] << 28) | (A[18] >>> (64 - 28)); + A[16] = (A[16] << 55) | (A[16] >>> (64 - 55)); + A[19] = (A[19] << 25) | (A[19] >>> (64 - 25)); + A[17] = (A[17] << 21) | (A[17] >>> (64 - 21)); + A[15] = (A[15] << 56) | (A[15] >>> (64 - 56)); + A[24] = (A[24] << 27) | (A[24] >>> (64 - 27)); + A[22] = (A[22] << 20) | (A[22] >>> (64 - 20)); + A[20] = (A[20] << 39) | (A[20] >>> (64 - 39)); + A[23] = (A[23] << 8) | (A[23] >>> (64 - 8)); + A[21] = (A[21] << 14) | (A[21] >>> (64 - 14)); + bnn = ~A[13]; + kt = A[9] | A[13]; + c0 = A[0] ^ kt; + kt = bnn | A[17]; + c1 = A[9] ^ kt; + kt = A[17] & A[21]; + c2 = A[13] ^ kt; + kt = A[21] | A[0]; + c3 = A[17] ^ kt; + kt = A[0] & A[9]; + c4 = A[21] ^ kt; + A[0] = c0; + A[9] = c1; + A[13] = c2; + A[17] = c3; + A[21] = c4; + bnn = ~A[14]; + kt = A[22] | A[1]; + c0 = A[18] ^ kt; + kt = A[1] & A[5]; + c1 = A[22] ^ kt; + kt = A[5] | bnn; + c2 = A[1] ^ kt; + kt = A[14] | A[18]; + c3 = A[5] ^ kt; + kt = A[18] & A[22]; + c4 = A[14] ^ kt; + A[18] = c0; + A[22] = c1; + A[1] = c2; + A[5] = c3; + A[14] = c4; + bnn = ~A[23]; + kt = A[10] | A[19]; + c0 = A[6] ^ kt; + kt = A[19] & A[23]; + c1 = A[10] ^ kt; + kt = bnn & A[2]; + c2 = A[19] ^ kt; + kt = A[2] | A[6]; + c3 = bnn ^ kt; + kt = A[6] & A[10]; + c4 = A[2] ^ kt; + A[6] = c0; + A[10] = c1; + A[19] = c2; + A[23] = c3; + A[2] = c4; + bnn = ~A[11]; + kt = A[3] & A[7]; + c0 = A[24] ^ kt; + kt = A[7] | A[11]; + c1 = A[3] ^ kt; + kt = bnn | A[15]; + c2 = A[7] ^ kt; + kt = A[15] & A[24]; + c3 = bnn ^ kt; + kt = A[24] | A[3]; + c4 = A[15] ^ kt; + A[24] = c0; + A[3] = c1; + A[7] = c2; + A[11] = c3; + A[15] = c4; + bnn = ~A[16]; + kt = bnn & A[20]; + c0 = A[12] ^ kt; + kt = A[20] | A[4]; + c1 = bnn ^ kt; + kt = A[4] & A[8]; + c2 = A[20] ^ kt; + kt = A[8] | A[12]; + c3 = A[4] ^ kt; + kt = A[12] & A[16]; + c4 = A[8] ^ kt; + A[12] = c0; + A[16] = c1; + A[20] = c2; + A[4] = c3; + A[8] = c4; + A[0] = A[0] ^ RC[j + 1]; + t = A[5]; + A[5] = A[18]; + A[18] = A[11]; + A[11] = A[10]; + A[10] = A[6]; + A[6] = A[22]; + A[22] = A[20]; + A[20] = A[12]; + A[12] = A[19]; + A[19] = A[15]; + A[15] = A[24]; + A[24] = A[8]; + A[8] = t; + t = A[1]; + A[1] = A[9]; + A[9] = A[14]; + A[14] = A[2]; + A[2] = A[13]; + A[13] = A[23]; + A[23] = A[4]; + A[4] = A[21]; + A[21] = A[16]; + A[16] = A[3]; + A[3] = A[17]; + A[17] = A[7]; + A[7] = t; } + } - protected void doPadding(byte[] out, int off) { - int ptr = flush(); - byte[] buf = getBlockBuffer(); - if ((ptr + 1) == buf.length) { - buf[ptr] = (byte) 0x81; - } else { - buf[ptr] = (byte) 0x01; - for (int i = ptr + 1; i < (buf.length - 1); i++) { - buf[i] = 0; - } - buf[buf.length - 1] = (byte) 0x80; - } - processBlock(buf); - A[1] = ~A[1]; - A[2] = ~A[2]; - A[8] = ~A[8]; - A[12] = ~A[12]; - A[17] = ~A[17]; - A[20] = ~A[20]; - int dlen = engineGetDigestLength(); - for (int i = 0; i < dlen; i += 8) { - encodeLELong(A[i >>> 3], tmpOut, i); - } - System.arraycopy(tmpOut, 0, out, off, dlen); + protected void doPadding(byte[] out, int off) { + int ptr = flush(); + byte[] buf = getBlockBuffer(); + if ((ptr + 1) == buf.length) { + buf[ptr] = (byte) 0x81; + } else { + buf[ptr] = (byte) 0x01; + for (int i = ptr + 1; i < (buf.length - 1); i++) { + buf[i] = 0; + } + buf[buf.length - 1] = (byte) 0x80; } - - protected void doInit() { - A = new long[25]; - tmpOut = new byte[(engineGetDigestLength() + 7) & ~7]; - doReset(); + processBlock(buf); + A[1] = ~A[1]; + A[2] = ~A[2]; + A[8] = ~A[8]; + A[12] = ~A[12]; + A[17] = ~A[17]; + A[20] = ~A[20]; + int dlen = engineGetDigestLength(); + for (int i = 0; i < dlen; i += 8) { + encodeLELong(A[i >>> 3], tmpOut, i); } + System.arraycopy(tmpOut, 0, out, off, dlen); + } - public int getBlockLength() { - return 200 - 2 * engineGetDigestLength(); - } + protected void doInit() { + A = new long[25]; + tmpOut = new byte[(engineGetDigestLength() + 7) & ~7]; + doReset(); + } - private final void doReset() { - for (int i = 0; i < 25; i++) { - A[i] = 0; - } - A[1] = 0xFFFFFFFFFFFFFFFFL; - A[2] = 0xFFFFFFFFFFFFFFFFL; - A[8] = 0xFFFFFFFFFFFFFFFFL; - A[12] = 0xFFFFFFFFFFFFFFFFL; - A[17] = 0xFFFFFFFFFFFFFFFFL; - A[20] = 0xFFFFFFFFFFFFFFFFL; - } + public int getBlockLength() { + return 200 - 2 * engineGetDigestLength(); + } - protected Digest copyState(KeccakCore dst) { - System.arraycopy(A, 0, dst.A, 0, 25); - return super.copyState(dst); + private final void doReset() { + for (int i = 0; i < 25; i++) { + A[i] = 0; } + A[1] = 0xFFFFFFFFFFFFFFFFL; + A[2] = 0xFFFFFFFFFFFFFFFFL; + A[8] = 0xFFFFFFFFFFFFFFFFL; + A[12] = 0xFFFFFFFFFFFFFFFFL; + A[17] = 0xFFFFFFFFFFFFFFFFL; + A[20] = 0xFFFFFFFFFFFFFFFFL; + } - public String toString() { - return "Keccak-" + (engineGetDigestLength() << 3); - } + protected Digest copyState(KeccakCore dst) { + System.arraycopy(A, 0, dst.A, 0, 25); + return super.copyState(dst); + } + + public String toString() { + return "Keccak-" + (engineGetDigestLength() << 3); + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECAlgorithmParameters.java b/src/main/java/org/tron/common/crypto/jce/ECAlgorithmParameters.java index 4a1a5a0058a..82794754e93 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECAlgorithmParameters.java +++ b/src/main/java/org/tron/common/crypto/jce/ECAlgorithmParameters.java @@ -27,47 +27,48 @@ public final class ECAlgorithmParameters { - public static final String ALGORITHM = "EC"; - public static final String CURVE_NAME = "secp256k1"; + public static final String ALGORITHM = "EC"; + public static final String CURVE_NAME = "secp256k1"; - private ECAlgorithmParameters() { - } + private ECAlgorithmParameters() { + } - public static ECParameterSpec getParameterSpec() { - try { - return Holder.INSTANCE.getParameterSpec(ECParameterSpec.class); - } catch (InvalidParameterSpecException ex) { - throw new AssertionError( - "Assumed correct key spec statically", ex); - } + public static ECParameterSpec getParameterSpec() { + try { + return Holder.INSTANCE.getParameterSpec(ECParameterSpec.class); + } catch (InvalidParameterSpecException ex) { + throw new AssertionError( + "Assumed correct key spec statically", ex); } + } - public static byte[] getASN1Encoding() { - try { - return Holder.INSTANCE.getEncoded(); - } catch (IOException ex) { - throw new AssertionError( - "Assumed algo params has been initialized", ex); - } + public static byte[] getASN1Encoding() { + try { + return Holder.INSTANCE.getEncoded(); + } catch (IOException ex) { + throw new AssertionError( + "Assumed algo params has been initialized", ex); } + } + + private static class Holder { - private static class Holder { - private static final AlgorithmParameters INSTANCE; + private static final AlgorithmParameters INSTANCE; - private static final ECGenParameterSpec SECP256K1_CURVE - = new ECGenParameterSpec(CURVE_NAME); + private static final ECGenParameterSpec SECP256K1_CURVE + = new ECGenParameterSpec(CURVE_NAME); - static { - try { - INSTANCE = AlgorithmParameters.getInstance(ALGORITHM); - INSTANCE.init(SECP256K1_CURVE); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError( - "Assumed the JRE supports EC algorithm params", ex); - } catch (InvalidParameterSpecException ex) { - throw new AssertionError( - "Assumed correct key spec statically", ex); - } - } + static { + try { + INSTANCE = AlgorithmParameters.getInstance(ALGORITHM); + INSTANCE.init(SECP256K1_CURVE); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError( + "Assumed the JRE supports EC algorithm params", ex); + } catch (InvalidParameterSpecException ex) { + throw new AssertionError( + "Assumed correct key spec statically", ex); + } } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECKeyAgreement.java b/src/main/java/org/tron/common/crypto/jce/ECKeyAgreement.java index ec0f384c447..ef94579cbf8 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECKeyAgreement.java +++ b/src/main/java/org/tron/common/crypto/jce/ECKeyAgreement.java @@ -18,43 +18,43 @@ package org.tron.common.crypto.jce; -import javax.crypto.KeyAgreement; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; +import javax.crypto.KeyAgreement; public final class ECKeyAgreement { - public static final String ALGORITHM = "ECDH"; + public static final String ALGORITHM = "ECDH"; - private static final String algorithmAssertionMsg = - "Assumed the JRE supports EC key agreement"; + private static final String algorithmAssertionMsg = + "Assumed the JRE supports EC key agreement"; - private ECKeyAgreement() { - } + private ECKeyAgreement() { + } - public static KeyAgreement getInstance() { - try { - return KeyAgreement.getInstance(ALGORITHM); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + public static KeyAgreement getInstance() { + try { + return KeyAgreement.getInstance(ALGORITHM); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } - - public static KeyAgreement getInstance(final String provider) throws - NoSuchProviderException { - try { - return KeyAgreement.getInstance(ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + } + + public static KeyAgreement getInstance(final String provider) throws + NoSuchProviderException { + try { + return KeyAgreement.getInstance(ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } + } - public static KeyAgreement getInstance(final Provider provider) { - try { - return KeyAgreement.getInstance(ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + public static KeyAgreement getInstance(final Provider provider) { + try { + return KeyAgreement.getInstance(ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECKeyFactory.java b/src/main/java/org/tron/common/crypto/jce/ECKeyFactory.java index 3b396cc700a..8bae0c2cdd5 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECKeyFactory.java +++ b/src/main/java/org/tron/common/crypto/jce/ECKeyFactory.java @@ -25,44 +25,45 @@ public final class ECKeyFactory { - public static final String ALGORITHM = "EC"; + public static final String ALGORITHM = "EC"; - private static final String algorithmAssertionMsg = - "Assumed the JRE supports EC key factories"; + private static final String algorithmAssertionMsg = + "Assumed the JRE supports EC key factories"; - private ECKeyFactory() { - } + private ECKeyFactory() { + } - public static KeyFactory getInstance() { - return Holder.INSTANCE; - } + public static KeyFactory getInstance() { + return Holder.INSTANCE; + } - public static KeyFactory getInstance(final String provider) throws - NoSuchProviderException { - try { - return KeyFactory.getInstance(ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + public static KeyFactory getInstance(final String provider) throws + NoSuchProviderException { + try { + return KeyFactory.getInstance(ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } + } - public static KeyFactory getInstance(final Provider provider) { - try { - return KeyFactory.getInstance(ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + public static KeyFactory getInstance(final Provider provider) { + try { + return KeyFactory.getInstance(ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } + } + + private static class Holder { - private static class Holder { - private static final KeyFactory INSTANCE; + private static final KeyFactory INSTANCE; - static { - try { - INSTANCE = KeyFactory.getInstance(ALGORITHM); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } - } + static { + try { + INSTANCE = KeyFactory.getInstance(ALGORITHM); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); + } } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECKeyPairGenerator.java b/src/main/java/org/tron/common/crypto/jce/ECKeyPairGenerator.java index d371539f364..61a5b90faec 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECKeyPairGenerator.java +++ b/src/main/java/org/tron/common/crypto/jce/ECKeyPairGenerator.java @@ -18,70 +18,77 @@ package org.tron.common.crypto.jce; -import java.security.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.SecureRandom; import java.security.spec.ECGenParameterSpec; public final class ECKeyPairGenerator { - public static final String ALGORITHM = "EC"; - public static final String CURVE_NAME = "secp256k1"; + public static final String ALGORITHM = "EC"; + public static final String CURVE_NAME = "secp256k1"; - private static final String algorithmAssertionMsg = - "Assumed JRE supports EC key pair generation"; + private static final String algorithmAssertionMsg = + "Assumed JRE supports EC key pair generation"; - private static final String keySpecAssertionMsg = - "Assumed correct key spec statically"; + private static final String keySpecAssertionMsg = + "Assumed correct key spec statically"; - private static final ECGenParameterSpec SECP256K1_CURVE - = new ECGenParameterSpec(CURVE_NAME); + private static final ECGenParameterSpec SECP256K1_CURVE + = new ECGenParameterSpec(CURVE_NAME); - private ECKeyPairGenerator() { - } + private ECKeyPairGenerator() { + } - public static KeyPair generateKeyPair() { - return Holder.INSTANCE.generateKeyPair(); - } + public static KeyPair generateKeyPair() { + return Holder.INSTANCE.generateKeyPair(); + } - public static KeyPairGenerator getInstance(final String provider, final - SecureRandom random) throws NoSuchProviderException { - try { - final KeyPairGenerator gen = KeyPairGenerator.getInstance - (ALGORITHM, provider); - gen.initialize(SECP256K1_CURVE, random); - return gen; - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } catch (InvalidAlgorithmParameterException ex) { - throw new AssertionError(keySpecAssertionMsg, ex); - } + public static KeyPairGenerator getInstance(final String provider, final + SecureRandom random) throws NoSuchProviderException { + try { + final KeyPairGenerator gen = KeyPairGenerator.getInstance + (ALGORITHM, provider); + gen.initialize(SECP256K1_CURVE, random); + return gen; + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); + } catch (InvalidAlgorithmParameterException ex) { + throw new AssertionError(keySpecAssertionMsg, ex); } + } - public static KeyPairGenerator getInstance(final Provider provider, final - SecureRandom random) { - try { - final KeyPairGenerator gen = KeyPairGenerator.getInstance - (ALGORITHM, provider); - gen.initialize(SECP256K1_CURVE, random); - return gen; - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } catch (InvalidAlgorithmParameterException ex) { - throw new AssertionError(keySpecAssertionMsg, ex); - } + public static KeyPairGenerator getInstance(final Provider provider, final + SecureRandom random) { + try { + final KeyPairGenerator gen = KeyPairGenerator.getInstance + (ALGORITHM, provider); + gen.initialize(SECP256K1_CURVE, random); + return gen; + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); + } catch (InvalidAlgorithmParameterException ex) { + throw new AssertionError(keySpecAssertionMsg, ex); } + } + + private static class Holder { - private static class Holder { - private static final KeyPairGenerator INSTANCE; + private static final KeyPairGenerator INSTANCE; - static { - try { - INSTANCE = KeyPairGenerator.getInstance(ALGORITHM); - INSTANCE.initialize(SECP256K1_CURVE); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } catch (InvalidAlgorithmParameterException ex) { - throw new AssertionError(keySpecAssertionMsg, ex); - } - } + static { + try { + INSTANCE = KeyPairGenerator.getInstance(ALGORITHM); + INSTANCE.initialize(SECP256K1_CURVE); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); + } catch (InvalidAlgorithmParameterException ex) { + throw new AssertionError(keySpecAssertionMsg, ex); + } } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECSignatureFactory.java b/src/main/java/org/tron/common/crypto/jce/ECSignatureFactory.java index 5caa7b3f886..9953e0ebf70 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECSignatureFactory.java +++ b/src/main/java/org/tron/common/crypto/jce/ECSignatureFactory.java @@ -25,36 +25,36 @@ public final class ECSignatureFactory { - public static final String RAW_ALGORITHM = "NONEwithECDSA"; + public static final String RAW_ALGORITHM = "NONEwithECDSA"; - private static final String rawAlgorithmAssertionMsg = - "Assumed the JRE supports NONEwithECDSA signatures"; + private static final String rawAlgorithmAssertionMsg = + "Assumed the JRE supports NONEwithECDSA signatures"; - private ECSignatureFactory() { - } + private ECSignatureFactory() { + } - public static Signature getRawInstance() { - try { - return Signature.getInstance(RAW_ALGORITHM); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(rawAlgorithmAssertionMsg, ex); - } + public static Signature getRawInstance() { + try { + return Signature.getInstance(RAW_ALGORITHM); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(rawAlgorithmAssertionMsg, ex); } - - public static Signature getRawInstance(final String provider) throws - NoSuchProviderException { - try { - return Signature.getInstance(RAW_ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(rawAlgorithmAssertionMsg, ex); - } + } + + public static Signature getRawInstance(final String provider) throws + NoSuchProviderException { + try { + return Signature.getInstance(RAW_ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(rawAlgorithmAssertionMsg, ex); } + } - public static Signature getRawInstance(final Provider provider) { - try { - return Signature.getInstance(RAW_ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(rawAlgorithmAssertionMsg, ex); - } + public static Signature getRawInstance(final Provider provider) { + try { + return Signature.getInstance(RAW_ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(rawAlgorithmAssertionMsg, ex); } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java b/src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java index 7639420573e..9132fe2536e 100644 --- a/src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java +++ b/src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java @@ -18,29 +18,29 @@ package org.tron.common.crypto.jce; -import org.spongycastle.jce.provider.BouncyCastleProvider; - import java.security.Provider; import java.security.Security; +import org.spongycastle.jce.provider.BouncyCastleProvider; public final class TronCastleProvider { - public static Provider getInstance() { - return Holder.INSTANCE; - } + public static Provider getInstance() { + return Holder.INSTANCE; + } + + private static class Holder { - private static class Holder { - private static final Provider INSTANCE; + private static final Provider INSTANCE; - static { - Provider p = Security.getProvider("SC"); + static { + Provider p = Security.getProvider("SC"); - INSTANCE = (p != null) ? p : new BouncyCastleProvider(); + INSTANCE = (p != null) ? p : new BouncyCastleProvider(); - INSTANCE.put("MessageDigest.TRON-KECCAK-256", "org.tron.common.crypto" + - ".cryptohash.Keccak256"); - INSTANCE.put("MessageDigest.TRON-KECCAK-512", "org.tron.common.crypto" + - ".cryptohash.Keccak512"); - } + INSTANCE.put("MessageDigest.TRON-KECCAK-256", "org.tron.common.crypto" + + ".cryptohash.Keccak256"); + INSTANCE.put("MessageDigest.TRON-KECCAK-512", "org.tron.common.crypto" + + ".cryptohash.Keccak512"); } + } } diff --git a/src/main/java/org/tron/common/overlay/example/LocalNode.java b/src/main/java/org/tron/common/overlay/example/LocalNode.java deleted file mode 100644 index 935b6d27c92..00000000000 --- a/src/main/java/org/tron/common/overlay/example/LocalNode.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.tron.common.overlay.example; - -import org.apache.gossip.GossipSettings; -import org.apache.gossip.LocalMember; -import org.apache.gossip.Member; -import org.apache.gossip.RemoteMember; -import org.apache.gossip.crdt.OrSet; -import org.apache.gossip.manager.GossipManager; -import org.apache.gossip.manager.GossipManagerBuilder; -import org.apache.gossip.model.SharedDataMessage; -import org.tron.common.overlay.Net; -import org.tron.common.overlay.message.Message; -import org.tron.common.overlay.message.Type; - -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import static org.tron.core.Constant.TOPIC_BLOCK; -import static org.tron.core.Constant.TOPIC_TRANSACTION; - -public class LocalNode implements Net { - public static final String INDEX_KEY_FOR_SET = "block"; - - // is the name of the cluster - private String cluster; - - // is a URI object containing IP/hostname and port to use on the default adapter on the - // node's machine - private String uri; - - // is a unique id for this node(you can use any string) - private String id; - - private GossipManager gossipManager = null; - - public LocalNode(String cluster, String uri, String id) { - setCluster(cluster); - setUri(uri); - setId(id); - - initGossipManager(cluster, uri, id); - initGossipService(); - } - - public static void addData(String val, GossipManager gossipService) { - SharedDataMessage m = new SharedDataMessage(); - m.setExpireAt(Long.MAX_VALUE); - m.setKey(INDEX_KEY_FOR_SET); - m.setPayload(new OrSet(val)); - m.setTimestamp(System.currentTimeMillis()); - gossipService.merge(m); - } - - public static SharedDataMessage sharedNodeData(String key, String value) { - SharedDataMessage g = new SharedDataMessage(); - g.setExpireAt(Long.MAX_VALUE); - g.setKey(key); - g.setPayload(value); - g.setTimestamp(System.currentTimeMillis()); - return g; - } - - public void initGossipManager(String cluster, String uri, String id) { - GossipSettings s = new GossipSettings(); - s.setWindowSize(1000); - s.setGossipInterval(100); - GossipManager gossipService = GossipManagerBuilder.newBuilder().cluster(cluster) - .uri(URI.create(uri)).id(id) - .gossipMembers(getGossipMembers()) - .gossipSettings(s).build(); - setGossipManager(gossipService); - } - - public void initGossipService() { - gossipManager.init(); - } - - public void printLiveMembers() { - List members = gossipManager.getLiveMembers(); - if (members.isEmpty()) { - System.out.println("Live: (none)"); - return; - } - System.out.println("Live: " + members.get(0)); - for (int i = 1; i < members.size(); i++) { - System.out.println(" : " + members.get(i)); - } - } - - public void printDeadMambers() { - List members = gossipManager.getDeadMembers(); - if (members.isEmpty()) { - System.out.println("Dead: (none)"); - return; - } - System.out.println("Dead: " + members.get(0)); - for (int i = 1; i < members.size(); i++) { - System.out.println(" : " + members.get(i)); - } - } - - private List getGossipMembers() { - return Collections - .singletonList(new RemoteMember(cluster, URI.create("udp://192.168.0.102:10000"), - "192.168.0.102:10000")); - } - - public String getCluster() { - return cluster; - } - - public void setCluster(String cluster) { - this.cluster = cluster; - } - - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public GossipManager getGossipManager() { - return gossipManager; - } - - public void setGossipManager(GossipManager gossipManager) { - this.gossipManager = gossipManager; - } - - @Override - public void broadcast(Message message) { - String topic = ""; - String value = message.getMessage(); - - if (message.getType() == Type.BLOCK) { - topic = TOPIC_BLOCK; - } else if (message.getType() == Type.TRANSACTION) { - topic = TOPIC_TRANSACTION; - } - - getGossipManager().gossipSharedData(LocalNode.sharedNodeData(topic, value)); - } - - @Override - public void deliver(Message message) { - - } -} diff --git a/src/main/java/org/tron/common/overlay/example/Node.java b/src/main/java/org/tron/common/overlay/example/Node.java deleted file mode 100644 index 7aaeb31872b..00000000000 --- a/src/main/java/org/tron/common/overlay/example/Node.java +++ /dev/null @@ -1,70 +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.overlay.example; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Scanner; - -public class Node { - private final static String CLUSTER = "mycluster"; - private final static String PORT = ":10000"; - - public static void main(String[] args) { - String uri = ""; - String id = ""; - try { - String ip = InetAddress.getLocalHost().getHostAddress(); - uri = "udp://" + ip + PORT; - id = ip + PORT; - } catch (UnknownHostException e) { - e.printStackTrace(); - } - - System.out.println("start node: " + uri); - System.out.println("id: " + id); - LocalNode standNode = new LocalNode(CLUSTER, uri, id); - - standNode.getGossipManager().registerSharedDataSubscriber((key, oldValue, newValue) -> { - System.out.println("new message: " + newValue); - }); - - Scanner scanner = new Scanner(System.in); - System.out.println("enter your message:"); - while (true) { - String v = scanner.nextLine(); - - String[] inputStrings = v.trim().split("\\s+", 2); - - switch (inputStrings[0]) { - case "send": - if (inputStrings.length > 1) { - standNode.getGossipManager().gossipSharedData(LocalNode.sharedNodeData("test", - inputStrings[1])); - } - break; - case "live": - standNode.printLiveMembers(); - break; - case "dead": - standNode.printDeadMambers(); - break; - default: - break; - } - - } - } -} diff --git a/src/main/java/org/tron/common/overlay/gossip/LocalNode.java b/src/main/java/org/tron/common/overlay/gossip/LocalNode.java deleted file mode 100644 index 84a515fa8ae..00000000000 --- a/src/main/java/org/tron/common/overlay/gossip/LocalNode.java +++ /dev/null @@ -1,187 +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.overlay.gossip; - -import com.alibaba.fastjson.JSON; -import com.google.common.io.ByteStreams; -import org.apache.gossip.GossipSettings; -import org.apache.gossip.LocalMember; -import org.apache.gossip.Member; -import org.apache.gossip.RemoteMember; -import org.apache.gossip.manager.GossipManager; -import org.apache.gossip.manager.GossipManagerBuilder; -import org.apache.gossip.model.SharedDataMessage; -import org.tron.core.config.Configer; -import org.tron.core.net.message.Message; -import org.tron.core.net.message.MessageTypes; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class LocalNode { - private final String CLUSTER = Configer.getConf().getString("overlay.cluster"); - private final String IP = Configer.getConf().getString("overlay.ip"); - private final String PORT = Configer.getConf().getString("overlay.port"); - - // is the name of the cluster - private String cluster; - - // is a URI object containing IP/hostname and port to use on the default adapter on the - // node's machine - private String uri; - - // is a unique id for this node(you can use any string) - private String id; - - private GossipManager gossipManager = null; - - private static final LocalNode INSTANCE = new LocalNode(); - - private LocalNode() { - setCluster(CLUSTER); - setUri("udp://" + IP + PORT); - setId(IP + PORT); - - System.out.println("cluster: " + CLUSTER + ", uri: " + "udp://" + IP + PORT + ", id: " + IP + PORT); - - initGossipManager(CLUSTER, uri, id); - initGossipService(); - } - - public static LocalNode getInstance() { - return INSTANCE; - } - - private SharedDataMessage sharedNodeData(String key, String value) { - SharedDataMessage g = new SharedDataMessage(); - g.setExpireAt(Long.MAX_VALUE); - g.setKey(key); - g.setPayload(value); - g.setTimestamp(System.currentTimeMillis()); - return g; - } - - public void initGossipManager(String cluster, String uri, String id) { - GossipSettings s = new GossipSettings(); - s.setWindowSize(1000); - s.setGossipInterval(100); - GossipManager gossipService = GossipManagerBuilder.newBuilder().cluster(cluster) - .uri(URI.create(uri)).id(id) - .gossipMembers(getGossipMembers()) - .gossipSettings(s).build(); - setGossipManager(gossipService); - } - - public void initGossipService() { - gossipManager.init(); - } - - private List getGossipMembers() { - List members = loadSeedNode(); - - if (members.isEmpty()) { - return Collections - .singletonList(new RemoteMember(CLUSTER, URI.create("udp://127.0.0.1:10000"), - "127.0.0.1:10000")); - } - - return members; - } - - private List loadSeedNode() { - List members = new ArrayList<>(); - - InputStream is = getClass().getClassLoader().getResourceAsStream(Configer.getConf().getString("seed" + - ".directory")); - - String json = null; - - try { - json = new String(ByteStreams.toByteArray(is)); - } catch (IOException e) { - e.printStackTrace(); - } - - SeedNodes seedNodes = JSON.parseObject(json, SeedNodes.class); - - for (SeedNode seedNode : seedNodes.getSeedNodes()) { - members.add(new RemoteMember(CLUSTER, URI.create(seedNode.getUri()), - seedNode.getId())); - } - - return members; - } - - public String getCluster() { - return cluster; - } - - public void setCluster(String cluster) { - this.cluster = cluster; - } - - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public GossipManager getGossipManager() { - return gossipManager; - } - - public void setGossipManager(GossipManager gossipManager) { - this.gossipManager = gossipManager; - } - - public void broadcast(Message message) { - MessageTypes type = message.getType(); - byte[] value = message.getData(); - - if (gossipManager == null) { - return; - } - - try { - gossipManager.gossipSharedData(sharedNodeData(type.toString(), new String(value, "ISO-8859-1"))); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - } - - public List getLiveMembers() { - return gossipManager.getLiveMembers(); - } - - public List getDeadMembers() { - return gossipManager.getDeadMembers(); - } -} diff --git a/src/main/java/org/tron/common/overlay/gossip/Node.java b/src/main/java/org/tron/common/overlay/gossip/Node.java deleted file mode 100644 index 2ff134cd2cb..00000000000 --- a/src/main/java/org/tron/common/overlay/gossip/Node.java +++ /dev/null @@ -1,32 +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.overlay.gossip; - -import org.apache.gossip.LocalMember; -import org.tron.common.overlay.message.Message; - -import java.util.List; - -/** - * gossip node manager - */ -public interface Node { - - void broadcast(Message message); - - List getLiveMembers(); - - List getDeadMembers(); -} diff --git a/src/main/java/org/tron/common/overlay/gossip/NodeSingleton.java b/src/main/java/org/tron/common/overlay/gossip/NodeSingleton.java deleted file mode 100644 index e4ac564ba92..00000000000 --- a/src/main/java/org/tron/common/overlay/gossip/NodeSingleton.java +++ /dev/null @@ -1,72 +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.overlay.gossip; -// -//import org.tron.common.overlay.message.Message; -//import org.tron.common.overlay.message.Type; -// -//import java.net.InetAddress; -//import java.net.UnknownHostException; -//import java.util.Scanner; -// -//public class NodeSingleton { -// private final static String CLUSTER = "mycluster"; -// private final static String PORT = ":10000"; -// -// public static void main(String[] args) { -// String uri = ""; -// String id = ""; -// try { -// String ip = InetAddress.getLocalHost().getHostAddress(); -// uri = "udp://" + ip + PORT; -// id = ip + PORT; -// } catch (UnknownHostException e) { -// e.printStackTrace(); -// } -// -// System.out.println("start node: " + uri); -// System.out.println("id: " + id); -// LocalNode standNode = new LocalNode(CLUSTER, uri, id); -// -// standNode.getGossipManager().registerSharedDataSubscriber((key, oldValue, newValue) -> { -// System.out.println("new message: " + newValue); -// }); -// -// Scanner scanner = new Scanner(System.in); -// System.out.println("enter your message:"); -// while (true) { -// String v = scanner.nextLine(); -// -// String[] inputStrings = v.trim().split("\\s+", 2); -// -// switch (inputStrings[0]) { -// case "send": -// if (inputStrings.length > 1) { -// standNode.broadcast(new Message(inputStrings[1], Type.BLOCK)); -// } -// break; -// case "live": -// standNode.printLiveMembers(); -// break; -// case "dead": -// standNode.printDeadMambers(); -// break; -// default: -// break; -// } -// -// } -// } -//} diff --git a/src/main/java/org/tron/common/overlay/gossip/SeedNode.java b/src/main/java/org/tron/common/overlay/gossip/SeedNode.java deleted file mode 100644 index 2133df66387..00000000000 --- a/src/main/java/org/tron/common/overlay/gossip/SeedNode.java +++ /dev/null @@ -1,47 +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.overlay.gossip; - -public class SeedNode { - // gossip node id: 127.0.0.1:10000 - private String id; - - // gossip node uri: udp://127.0.0.1:10000 - private String uri; - - public SeedNode() { - } - - public SeedNode(String id, String uri) { - this.id = id; - this.uri = uri; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } -} diff --git a/src/main/java/org/tron/common/overlay/gossip/SeedNodes.java b/src/main/java/org/tron/common/overlay/gossip/SeedNodes.java deleted file mode 100644 index a8631b22b8a..00000000000 --- a/src/main/java/org/tron/common/overlay/gossip/SeedNodes.java +++ /dev/null @@ -1,37 +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.overlay.gossip; - -import java.util.List; - -public class SeedNodes { - // - private List seedNodes; - - public SeedNodes() { - } - - public SeedNodes(List seedNodes) { - this.seedNodes = seedNodes; - } - - public List getSeedNodes() { - return seedNodes; - } - - public void setSeedNodes(List seedNodes) { - this.seedNodes = seedNodes; - } -} diff --git a/src/main/java/org/tron/common/overlay/kafka/Kafka.java b/src/main/java/org/tron/common/overlay/kafka/Kafka.java index 21ccfd42664..9c86cb9af34 100644 --- a/src/main/java/org/tron/common/overlay/kafka/Kafka.java +++ b/src/main/java/org/tron/common/overlay/kafka/Kafka.java @@ -36,6 +36,7 @@ import org.tron.common.overlay.message.Type; public class Kafka implements Net { + public static final String KAFKA_HOST = "kafka.host"; public static final String KAFKA_PORT = "kafka.port"; diff --git a/src/main/java/org/tron/common/storage/BatchSourceInter.java b/src/main/java/org/tron/common/storage/BatchSourceInter.java index 3a6d411bfd6..c11376cf065 100644 --- a/src/main/java/org/tron/common/storage/BatchSourceInter.java +++ b/src/main/java/org/tron/common/storage/BatchSourceInter.java @@ -15,6 +15,7 @@ * 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.storage; import java.util.Map; @@ -23,5 +24,5 @@ public interface BatchSourceInter extends SourceInter { - void updateByBatch(Map rows); + void updateByBatch(Map rows); } diff --git a/src/main/java/org/tron/common/storage/DbSourceInter.java b/src/main/java/org/tron/common/storage/DbSourceInter.java index 7a5123fc496..8bb37bfb074 100644 --- a/src/main/java/org/tron/common/storage/DbSourceInter.java +++ b/src/main/java/org/tron/common/storage/DbSourceInter.java @@ -23,18 +23,18 @@ public interface DbSourceInter extends BatchSourceInter { - String getDBName(); + String getDBName(); - void setDBName(String name); + void setDBName(String name); - void initDB(); + void initDB(); - boolean isAlive(); + boolean isAlive(); - void closeDB(); + void closeDB(); - Set allKeys() throws RuntimeException; + Set allKeys() throws RuntimeException; } diff --git a/src/main/java/org/tron/common/storage/SourceInter.java b/src/main/java/org/tron/common/storage/SourceInter.java index d3e62bcf071..b68384c408c 100644 --- a/src/main/java/org/tron/common/storage/SourceInter.java +++ b/src/main/java/org/tron/common/storage/SourceInter.java @@ -21,15 +21,15 @@ public interface SourceInter { - void putData(K key, V val); + void putData(K key, V val); - V getData(K key); + V getData(K key); - void deleteData(K key); + void deleteData(K key); - boolean flush(); + boolean flush(); } diff --git a/src/main/java/org/tron/common/utils/ALock.java b/src/main/java/org/tron/common/utils/ALock.java index 6f2bba129bd..ac35bdd569b 100644 --- a/src/main/java/org/tron/common/utils/ALock.java +++ b/src/main/java/org/tron/common/utils/ALock.java @@ -22,12 +22,10 @@ /** * AutoClosable Lock wrapper. Use case: - *

- * try (ALock l = wLock.lock()) { - * // do smth under lock - * } + * try (ALock l = wLock.lock()) { // do smth under lock } */ public final class ALock implements AutoCloseable { + private final Lock lock; public ALock(Lock l) { diff --git a/src/main/java/org/tron/common/utils/BIUtil.java b/src/main/java/org/tron/common/utils/BIUtil.java index ff7ac496f34..a4ef55f4538 100644 --- a/src/main/java/org/tron/common/utils/BIUtil.java +++ b/src/main/java/org/tron/common/utils/BIUtil.java @@ -15,18 +15,19 @@ * 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.utils; import java.math.BigInteger; public class BIUtil { - /** - * @param valueA - not null - * @param valueB - not null - * @return true - if the valueA is less than valueB is zero - */ - public static boolean isLessThan(BigInteger valueA, BigInteger valueB) { - return valueA.compareTo(valueB) < 0; - } + /** + * @param valueA - not null + * @param valueB - not null + * @return true - if the valueA is less than valueB is zero + */ + public static boolean isLessThan(BigInteger valueA, BigInteger valueB) { + return valueA.compareTo(valueB) < 0; + } } diff --git a/src/main/java/org/tron/common/utils/ByteArray.java b/src/main/java/org/tron/common/utils/ByteArray.java index 273db855729..2d8e3ed11f9 100644 --- a/src/main/java/org/tron/common/utils/ByteArray.java +++ b/src/main/java/org/tron/common/utils/ByteArray.java @@ -18,55 +18,55 @@ package org.tron.common.utils; -import org.spongycastle.util.encoders.Hex; - import java.math.BigInteger; import java.nio.ByteBuffer; +import org.spongycastle.util.encoders.Hex; public class ByteArray { - public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - public static String toHexString(byte[] data) { - return data == null ? "" : Hex.toHexString(data); - } + public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - public static byte[] fromHexString(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); - } + public static String toHexString(byte[] data) { + return data == null ? "" : Hex.toHexString(data); + } - public static long toLong(byte[] b) { - if (b == null || b.length == 0) { - return 0; - } - return new BigInteger(1, b).longValue(); + public static byte[] fromHexString(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); + } - public static byte[] fromString(String str) { - if (str == null) { - return null; - } + public static long toLong(byte[] b) { + if (b == null || b.length == 0) { + return 0; + } + return new BigInteger(1, b).longValue(); + } - return str.getBytes(); + public static byte[] fromString(String str) { + if (str == null) { + return null; } - public static String toStr(byte[] byteArray) { - if (byteArray == null) { - return null; - } + return str.getBytes(); + } - return new String(byteArray); + public static String toStr(byte[] byteArray) { + if (byteArray == null) { + return null; } - public static byte[] fromLong(long val) { - return ByteBuffer.allocate(8).putLong(val).array(); - } + return new String(byteArray); + } + + public static byte[] fromLong(long val) { + return ByteBuffer.allocate(8).putLong(val).array(); + } } diff --git a/src/main/java/org/tron/common/utils/ByteArrayMap.java b/src/main/java/org/tron/common/utils/ByteArrayMap.java index 7362b62cf50..ba08ab89407 100644 --- a/src/main/java/org/tron/common/utils/ByteArrayMap.java +++ b/src/main/java/org/tron/common/utils/ByteArrayMap.java @@ -19,188 +19,194 @@ package org.tron.common.utils; -import org.tron.core.dbStore.ByteArrayWrapper; - -import java.util.*; +import java.util.AbstractMap; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import org.tron.core.dbstore.ByteArrayWrapper; public class ByteArrayMap implements Map { - private final Map delegate; - public ByteArrayMap() { - this(new HashMap()); + private final Map delegate; + + public ByteArrayMap() { + this(new HashMap()); + } + + public ByteArrayMap(Map delegate) { + this.delegate = delegate; + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return delegate.containsKey(new ByteArrayWrapper((byte[]) key)); + } + + @Override + public boolean containsValue(Object value) { + return delegate.containsValue(value); + } + + @Override + public V get(Object key) { + return delegate.get(new ByteArrayWrapper((byte[]) key)); + } + + @Override + public V put(byte[] key, V value) { + return delegate.put(new ByteArrayWrapper(key), value); + } + + @Override + public V remove(Object key) { + return delegate.remove(new ByteArrayWrapper((byte[]) key)); + } + + @Override + public void putAll(Map m) { + for (Entry entry : m.entrySet()) { + delegate.put(new ByteArrayWrapper(entry.getKey()), entry.getValue()); } + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public Set keySet() { + return new ByteArraySet(new SetAdapter<>(delegate)); + } + + @Override + public Collection values() { + return delegate.values(); + } + + @Override + public Set> entrySet() { + return new MapEntrySet(delegate.entrySet()); + } + + @Override + public boolean equals(Object o) { + return delegate.equals(o); + } + + @Override + public int hashCode() { + return delegate.hashCode(); + } + + @Override + public String toString() { + return delegate.toString(); + } + + private class MapEntrySet implements Set> { + + private final Set> delegate; - public ByteArrayMap(Map delegate) { - this.delegate = delegate; + private MapEntrySet(Set> delegate) { + this.delegate = delegate; } @Override public int size() { - return delegate.size(); + return delegate.size(); } @Override public boolean isEmpty() { - return delegate.isEmpty(); + return delegate.isEmpty(); } @Override - public boolean containsKey(Object key) { - return delegate.containsKey(new ByteArrayWrapper((byte[]) key)); + public boolean contains(Object o) { + throw new RuntimeException("Not implemented"); } @Override - public boolean containsValue(Object value) { - return delegate.containsValue(value); - } + public Iterator> iterator() { + final Iterator> it = delegate.iterator(); + return new Iterator>() { - @Override - public V get(Object key) { - return delegate.get(new ByteArrayWrapper((byte[]) key)); - } + @Override + public boolean hasNext() { + return it.hasNext(); + } - @Override - public V put(byte[] key, V value) { - return delegate.put(new ByteArrayWrapper(key), value); - } + @Override + public Entry next() { + Entry next = it.next(); + return new AbstractMap.SimpleImmutableEntry(next.getKey().getData(), next.getValue()); + } - @Override - public V remove(Object key) { - return delegate.remove(new ByteArrayWrapper((byte[]) key)); + @Override + public void remove() { + it.remove(); + } + }; } @Override - public void putAll(Map m) { - for (Entry entry : m.entrySet()) { - delegate.put(new ByteArrayWrapper(entry.getKey()), entry.getValue()); - } + public Object[] toArray() { + throw new RuntimeException("Not implemented"); } @Override - public void clear() { - delegate.clear(); + public T[] toArray(T[] a) { + throw new RuntimeException("Not implemented"); } @Override - public Set keySet() { - return new ByteArraySet(new SetAdapter<>(delegate)); + public boolean add(Entry vEntry) { + throw new RuntimeException("Not implemented"); } @Override - public Collection values() { - return delegate.values(); + public boolean remove(Object o) { + throw new RuntimeException("Not implemented"); } @Override - public Set> entrySet() { - return new MapEntrySet(delegate.entrySet()); + public boolean containsAll(Collection c) { + throw new RuntimeException("Not implemented"); } @Override - public boolean equals(Object o) { - return delegate.equals(o); + public boolean addAll(Collection> c) { + throw new RuntimeException("Not implemented"); } @Override - public int hashCode() { - return delegate.hashCode(); + public boolean retainAll(Collection c) { + throw new RuntimeException("Not implemented"); } @Override - public String toString() { - return delegate.toString(); + public boolean removeAll(Collection c) { + throw new RuntimeException("Not implemented"); } - private class MapEntrySet implements Set> { - private final Set> delegate; - - private MapEntrySet(Set> delegate) { - this.delegate = delegate; - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean contains(Object o) { - throw new RuntimeException("Not implemented"); - } - - @Override - public Iterator> iterator() { - final Iterator> it = delegate.iterator(); - return new Iterator>() { - - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public Entry next() { - Entry next = it.next(); - return new AbstractMap.SimpleImmutableEntry(next.getKey().getData(), next.getValue()); - } - - @Override - public void remove() { - it.remove(); - } - }; - } - - @Override - public Object[] toArray() { - throw new RuntimeException("Not implemented"); - } - - @Override - public T[] toArray(T[] a) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean add(Entry vEntry) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean remove(Object o) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean containsAll(Collection c) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean addAll(Collection> c) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean retainAll(Collection c) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean removeAll(Collection c) { - throw new RuntimeException("Not implemented"); - } - - @Override - public void clear() { - throw new RuntimeException("Not implemented"); + @Override + public void clear() { + throw new RuntimeException("Not implemented"); - } } + } } diff --git a/src/main/java/org/tron/common/utils/ByteArraySet.java b/src/main/java/org/tron/common/utils/ByteArraySet.java index 8055a0d3153..91e2ea59e40 100644 --- a/src/main/java/org/tron/common/utils/ByteArraySet.java +++ b/src/main/java/org/tron/common/utils/ByteArraySet.java @@ -19,125 +19,125 @@ package org.tron.common.utils; -import org.tron.core.dbStore.ByteArrayWrapper; - import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import org.tron.core.dbstore.ByteArrayWrapper; public class ByteArraySet implements Set { - Set delegate; - - public ByteArraySet() { - this(new HashSet()); - } - - ByteArraySet(Set delegate) { - this.delegate = delegate; - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return delegate.contains(new ByteArrayWrapper((byte[]) o)); - } - - @Override - public Iterator iterator() { - return new Iterator() { - - Iterator it = delegate.iterator(); - - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public byte[] next() { - return it.next().getData(); - } - - @Override - public void remove() { - it.remove(); - } - }; - } - - @Override - public Object[] toArray() { - byte[][] ret = new byte[size()][]; - - ByteArrayWrapper[] arr = delegate.toArray(new ByteArrayWrapper[size()]); - for (int i = 0; i < arr.length; i++) { - ret[i] = arr[i].getData(); - } - return ret; - } - @Override - public T[] toArray(T[] a) { - return (T[]) toArray(); - } - - @Override - public boolean add(byte[] bytes) { - return delegate.add(new ByteArrayWrapper(bytes)); - } - - @Override - public boolean remove(Object o) { - return delegate.remove(new ByteArrayWrapper((byte[]) o)); - } - - @Override - public boolean containsAll(Collection c) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean addAll(Collection c) { - boolean ret = false; - for (byte[] bytes : c) { - ret |= add(bytes); - } - return ret; - } - - @Override - public boolean retainAll(Collection c) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean removeAll(Collection c) { - throw new RuntimeException("Not implemented"); - } - - @Override - public void clear() { - delegate.clear(); - } - - @Override - public boolean equals(Object o) { - throw new RuntimeException("Not implemented"); - } - - @Override - public int hashCode() { - throw new RuntimeException("Not implemented"); - } + Set delegate; + + public ByteArraySet() { + this(new HashSet()); + } + + ByteArraySet(Set delegate) { + this.delegate = delegate; + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return delegate.contains(new ByteArrayWrapper((byte[]) o)); + } + + @Override + public Iterator iterator() { + return new Iterator() { + + Iterator it = delegate.iterator(); + + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public byte[] next() { + return it.next().getData(); + } + + @Override + public void remove() { + it.remove(); + } + }; + } + + @Override + public Object[] toArray() { + byte[][] ret = new byte[size()][]; + + ByteArrayWrapper[] arr = delegate.toArray(new ByteArrayWrapper[size()]); + for (int i = 0; i < arr.length; i++) { + ret[i] = arr[i].getData(); + } + return ret; + } + + @Override + public T[] toArray(T[] a) { + return (T[]) toArray(); + } + + @Override + public boolean add(byte[] bytes) { + return delegate.add(new ByteArrayWrapper(bytes)); + } + + @Override + public boolean remove(Object o) { + return delegate.remove(new ByteArrayWrapper((byte[]) o)); + } + + @Override + public boolean containsAll(Collection c) { + throw new RuntimeException("Not implemented"); + } + + @Override + public boolean addAll(Collection c) { + boolean ret = false; + for (byte[] bytes : c) { + ret |= add(bytes); + } + return ret; + } + + @Override + public boolean retainAll(Collection c) { + throw new RuntimeException("Not implemented"); + } + + @Override + public boolean removeAll(Collection c) { + throw new RuntimeException("Not implemented"); + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public boolean equals(Object o) { + throw new RuntimeException("Not implemented"); + } + + @Override + public int hashCode() { + throw new RuntimeException("Not implemented"); + } } diff --git a/src/main/java/org/tron/common/utils/ByteUtil.java b/src/main/java/org/tron/common/utils/ByteUtil.java index bcbf9b248dd..b54ae4376fd 100644 --- a/src/main/java/org/tron/common/utils/ByteUtil.java +++ b/src/main/java/org/tron/common/utils/ByteUtil.java @@ -18,24 +18,21 @@ package org.tron.common.utils; -import org.spongycastle.util.encoders.Hex; - import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.Arrays; +import org.spongycastle.util.encoders.Hex; public class ByteUtil { public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - public static final byte[] ZERO_BYTE_ARRAY = new byte[] {0}; + public static final byte[] ZERO_BYTE_ARRAY = new byte[]{0}; /** - * The regular {@link java.math.BigInteger#toByteArray()} method isn't - * quite what we often need: - * it appends a leading zero to indicate that the number is positive and - * may need padding. + * The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need: + * it appends a leading zero to indicate that the number is positive and may need padding. * - * @param b the integer to format into a byte array + * @param b the integer to format into a byte array * @param numBytes the desired size of the resulting byte array * @return numBytes byte long array. */ @@ -52,17 +49,11 @@ public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) { } /** - * Omitting sign indication byte. - *

- * Instead of - * {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)} - *
we use this custom method to avoid an empty array in case of - * BigInteger.ZERO + * Omitting sign indication byte.

Instead of {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)} + *
we use this custom method to avoid an empty array in case of BigInteger.ZERO * - * @param value - any big integer number. A null-value will - * return null - * @return A byte array without a leading zero byte if present in the - * signed encoding. + * @param value - any big integer number. A null-value will return null + * @return A byte array without a leading zero byte if present in the signed encoding. * BigInteger.ZERO will return an array with length 1 and byte-value 0. */ public static byte[] bigIntegerToBytes(BigInteger value) { @@ -112,12 +103,10 @@ public static byte[] appendByte(byte[] bytes, byte b) { } /** - * Turn nibbles to a pretty looking output string - *

- * Example. [ 1, 2, 3, 4, 5 ] becomes '\x11\x23\x45' + * Turn nibbles to a pretty looking output string

Example. [ 1, 2, 3, 4, 5 ] becomes + * '\x11\x23\x45' * - * @param nibbles - getting byte of data [ 04 ] and turning - * it to a '\x04' representation + * @param nibbles - getting byte of data [ 04 ] and turning it to a '\x04' representation * @return pretty string of nibbles */ public static String nibblesToPrettyString(byte[] nibbles) { @@ -138,13 +127,12 @@ public static String oneByteToHexString(byte value) { } /** - * Convert a byte-array into a hex String.
- * Works similar to {@link Hex#toHexString} - * but allows for null + * Convert a byte-array into a hex String.
Works similar to {@link Hex#toHexString} but allows + * for null * * @param data - byte-array to convert to a hex-string - * @return hex representation of the data.
- * Returns an empty String if the input is null + * @return hex representation of the data.
Returns an empty String if the input is + * null * @see Hex#toHexString */ public static String toHexString(byte[] data) { @@ -152,9 +140,7 @@ public static String toHexString(byte[] data) { } /** - * Cast hex encoded value from byte[] to int - *

- * Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes) + * Cast hex encoded value from byte[] to int

Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes) * * @param b array contains the values * @return unsigned positive int value. diff --git a/src/main/java/org/tron/common/utils/CompactEncoder.java b/src/main/java/org/tron/common/utils/CompactEncoder.java index dd3754fed40..e59544a3931 100644 --- a/src/main/java/org/tron/common/utils/CompactEncoder.java +++ b/src/main/java/org/tron/common/utils/CompactEncoder.java @@ -18,125 +18,125 @@ package org.tron.common.utils; -import java.io.ByteArrayOutputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - import static java.util.Arrays.copyOf; import static java.util.Arrays.copyOfRange; import static org.spongycastle.util.Arrays.concatenate; import static org.spongycastle.util.encoders.Hex.encode; import static org.tron.common.utils.ByteUtil.appendByte; +import java.io.ByteArrayOutputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + public class CompactEncoder { - private final static byte TERMINATOR = 16; - private final static Map hexMap = new HashMap<>(); - - static { - hexMap.put('0', (byte) 0x0); - hexMap.put('1', (byte) 0x1); - hexMap.put('2', (byte) 0x2); - hexMap.put('3', (byte) 0x3); - hexMap.put('4', (byte) 0x4); - hexMap.put('5', (byte) 0x5); - hexMap.put('6', (byte) 0x6); - hexMap.put('7', (byte) 0x7); - hexMap.put('8', (byte) 0x8); - hexMap.put('9', (byte) 0x9); - hexMap.put('a', (byte) 0xa); - hexMap.put('b', (byte) 0xb); - hexMap.put('c', (byte) 0xc); - hexMap.put('d', (byte) 0xd); - hexMap.put('e', (byte) 0xe); - hexMap.put('f', (byte) 0xf); + private final static byte TERMINATOR = 16; + private final static Map hexMap = new HashMap<>(); + + static { + hexMap.put('0', (byte) 0x0); + hexMap.put('1', (byte) 0x1); + hexMap.put('2', (byte) 0x2); + hexMap.put('3', (byte) 0x3); + hexMap.put('4', (byte) 0x4); + hexMap.put('5', (byte) 0x5); + hexMap.put('6', (byte) 0x6); + hexMap.put('7', (byte) 0x7); + hexMap.put('8', (byte) 0x8); + hexMap.put('9', (byte) 0x9); + hexMap.put('a', (byte) 0xa); + hexMap.put('b', (byte) 0xb); + hexMap.put('c', (byte) 0xc); + hexMap.put('d', (byte) 0xd); + hexMap.put('e', (byte) 0xe); + hexMap.put('f', (byte) 0xf); + } + + /** + * Pack nibbles to binary + * + * @param nibbles sequence. may have a terminator + * @return hex-encoded byte array + */ + public static byte[] packNibbles(byte[] nibbles) { + int terminator = 0; + + if (nibbles[nibbles.length - 1] == TERMINATOR) { + terminator = 1; + nibbles = copyOf(nibbles, nibbles.length - 1); } - - /** - * Pack nibbles to binary - * - * @param nibbles sequence. may have a terminator - * @return hex-encoded byte array - */ - public static byte[] packNibbles(byte[] nibbles) { - int terminator = 0; - - if (nibbles[nibbles.length - 1] == TERMINATOR) { - terminator = 1; - nibbles = copyOf(nibbles, nibbles.length - 1); - } - int oddlen = nibbles.length % 2; - int flag = 2 * terminator + oddlen; - if (oddlen != 0) { - byte[] flags = new byte[]{(byte) flag}; - nibbles = concatenate(flags, nibbles); - } else { - byte[] flags = new byte[]{(byte) flag, 0}; - nibbles = concatenate(flags, nibbles); - } - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - for (int i = 0; i < nibbles.length; i += 2) { - buffer.write(16 * nibbles[i] + nibbles[i + 1]); - } - return buffer.toByteArray(); + int oddlen = nibbles.length % 2; + int flag = 2 * terminator + oddlen; + if (oddlen != 0) { + byte[] flags = new byte[]{(byte) flag}; + nibbles = concatenate(flags, nibbles); + } else { + byte[] flags = new byte[]{(byte) flag, 0}; + nibbles = concatenate(flags, nibbles); } - - public static boolean hasTerminator(byte[] packedKey) { - return ((packedKey[0] >> 4) & 2) != 0; + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + for (int i = 0; i < nibbles.length; i += 2) { + buffer.write(16 * nibbles[i] + nibbles[i + 1]); } - - /** - * Unpack a binary string to its nibbles equivalent - * - * @param str of binary data - * @return array of nibbles in byte-format - */ - public static byte[] unpackToNibbles(byte[] str) { - byte[] base = binToNibbles(str); - base = copyOf(base, base.length - 1); - if (base[0] >= 2) { - base = appendByte(base, TERMINATOR); - } - if (base[0] % 2 == 1) { - base = copyOfRange(base, 1, base.length); - } else { - base = copyOfRange(base, 2, base.length); - } - return base; + return buffer.toByteArray(); + } + + public static boolean hasTerminator(byte[] packedKey) { + return ((packedKey[0] >> 4) & 2) != 0; + } + + /** + * Unpack a binary string to its nibbles equivalent + * + * @param str of binary data + * @return array of nibbles in byte-format + */ + public static byte[] unpackToNibbles(byte[] str) { + byte[] base = binToNibbles(str); + base = copyOf(base, base.length - 1); + if (base[0] >= 2) { + base = appendByte(base, TERMINATOR); } - - /** - * Transforms a binary array to hexadecimal format + terminator - * - * @param str byte[] - * @return array with each individual nibble adding a terminator at the end - */ - public static byte[] binToNibbles(byte[] str) { - - byte[] hexEncoded = encode(str); - byte[] hexEncodedTerminated = Arrays.copyOf(hexEncoded, hexEncoded.length + 1); - - for (int i = 0; i < hexEncoded.length; ++i) { - byte b = hexEncodedTerminated[i]; - hexEncodedTerminated[i] = hexMap.get((char) b); - } - - hexEncodedTerminated[hexEncodedTerminated.length - 1] = TERMINATOR; - return hexEncodedTerminated; + if (base[0] % 2 == 1) { + base = copyOfRange(base, 1, base.length); + } else { + base = copyOfRange(base, 2, base.length); + } + return base; + } + + /** + * Transforms a binary array to hexadecimal format + terminator + * + * @param str byte[] + * @return array with each individual nibble adding a terminator at the end + */ + public static byte[] binToNibbles(byte[] str) { + + byte[] hexEncoded = encode(str); + byte[] hexEncodedTerminated = Arrays.copyOf(hexEncoded, hexEncoded.length + 1); + + for (int i = 0; i < hexEncoded.length; ++i) { + byte b = hexEncodedTerminated[i]; + hexEncodedTerminated[i] = hexMap.get((char) b); } + hexEncodedTerminated[hexEncodedTerminated.length - 1] = TERMINATOR; + return hexEncodedTerminated; + } - public static byte[] binToNibblesNoTerminator(byte[] str) { - byte[] hexEncoded = encode(str); + public static byte[] binToNibblesNoTerminator(byte[] str) { - for (int i = 0; i < hexEncoded.length; ++i) { - byte b = hexEncoded[i]; - hexEncoded[i] = hexMap.get((char) b); - } + byte[] hexEncoded = encode(str); - return hexEncoded; + for (int i = 0; i < hexEncoded.length; ++i) { + byte b = hexEncoded[i]; + hexEncoded[i] = hexMap.get((char) b); } + + return hexEncoded; + } } diff --git a/src/main/java/org/tron/common/utils/DecodeResult.java b/src/main/java/org/tron/common/utils/DecodeResult.java index 8b046259f2e..da9498a8a73 100644 --- a/src/main/java/org/tron/common/utils/DecodeResult.java +++ b/src/main/java/org/tron/common/utils/DecodeResult.java @@ -18,45 +18,44 @@ package org.tron.common.utils; -import org.spongycastle.util.encoders.Hex; - import java.io.Serializable; +import org.spongycastle.util.encoders.Hex; @SuppressWarnings("serial") public class DecodeResult implements Serializable { - private int pos; - private Object decoded; - - public DecodeResult(int pos, Object decoded) { - this.pos = pos; - this.decoded = decoded; - } - - public int getPos() { - return pos; - } - - public Object getDecoded() { - return decoded; - } - - public String toString() { - return asString(this.decoded); - } - - private String asString(Object decoded) { - if (decoded instanceof String) { - return (String) decoded; - } else if (decoded instanceof byte[]) { - return Hex.toHexString((byte[]) decoded); - } else if (decoded instanceof Object[]) { - String result = ""; - for (Object item : (Object[]) decoded) { - result += asString(item); - } - return result; - } - throw new RuntimeException("Not a valid type. Should not occur"); + private int pos; + private Object decoded; + + public DecodeResult(int pos, Object decoded) { + this.pos = pos; + this.decoded = decoded; + } + + public int getPos() { + return pos; + } + + public Object getDecoded() { + return decoded; + } + + public String toString() { + return asString(this.decoded); + } + + private String asString(Object decoded) { + if (decoded instanceof String) { + return (String) decoded; + } else if (decoded instanceof byte[]) { + return Hex.toHexString((byte[]) decoded); + } else if (decoded instanceof Object[]) { + String result = ""; + for (Object item : (Object[]) decoded) { + result += asString(item); + } + return result; } + throw new RuntimeException("Not a valid type. Should not occur"); + } } diff --git a/src/main/java/org/tron/common/utils/ExecutorPipeline.java b/src/main/java/org/tron/common/utils/ExecutorPipeline.java deleted file mode 100644 index 5cd49cee943..00000000000 --- a/src/main/java/org/tron/common/utils/ExecutorPipeline.java +++ /dev/null @@ -1,139 +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.utils; - - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Consumer; -import java.util.function.Function; - -public class ExecutorPipeline { - - private static AtomicInteger pipeNumber = new AtomicInteger(1); - private BlockingQueue queue; - private ThreadPoolExecutor exce; - private boolean preserveOrder = false; - private Function processor; - private ExecutorPipeline next; - private Consumer exceptionHandler; - private String threadPoolName; - private AtomicLong orderCounter = new AtomicLong(); - private ReentrantLock lock = new ReentrantLock(); - private long nextOutTaskNumber = 0; - private Map orderMap = new HashMap<>(); - private AtomicInteger threadNumber = new AtomicInteger(1); - - public ExecutorPipeline(int threads, int queueSize, boolean preserveOrder, - Function processor, - Consumer exceptionHandler) { - queue = new LimitedQueue<>(queueSize); - exce = new ThreadPoolExecutor(threads, threads, 0L, TimeUnit.MILLISECONDS, queue, - r -> new Thread(r, threadPoolName + "-" + threadNumber.getAndIncrement())); - this.preserveOrder = preserveOrder; - this.processor = processor; - this.exceptionHandler = exceptionHandler; - this.threadPoolName = "pipe-" + pipeNumber.getAndIncrement(); - } - - public ExecutorPipeline add(int threads, int queueSize, final Consumer consumer) { - return add(threads, queueSize, false, out -> { - consumer.accept(out); - return null; - }); - } - - public ExecutorPipeline add(int threads, int queueSize, - boolean preserveOrder, - Function processor) { - ExecutorPipeline ret = new ExecutorPipeline<>(threads, queueSize, preserveOrder, - processor, - exceptionHandler); - next = ret; - return ret; - } - - private void pushNext(long order, Out res) { - if (next != null) { - if (!preserveOrder) { - next.push(res); - } else { - lock.lock(); - try { - if (order == nextOutTaskNumber) { - next.push(res); - while (true) { - nextOutTaskNumber++; - Out out = orderMap.remove(nextOutTaskNumber); - if (out == null) { - break; - } - next.push(out); - } - } else { - orderMap.put(order, res); - } - } finally { - lock.unlock(); - } - } - } - } - - public void push(final In in) { - final long order = orderCounter.getAndIncrement(); - exce.execute(new Runnable() { - @Override - public void run() { - try { - pushNext(order, processor.apply(in)); - } catch (Throwable e) { - exceptionHandler.accept(e); - } - } - }); - } - - private static class LimitedQueue extends LinkedBlockingQueue { - public LimitedQueue(int maxSize) { - super(maxSize); - } - - @Override - public boolean offer(E e) { - // turn offer() and add() into a blocking calls (unless interrupted) - try { - put(e); - return true; - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } - return false; - } - } - - -} diff --git a/src/main/java/org/tron/common/utils/FileUtil.java b/src/main/java/org/tron/common/utils/FileUtil.java index 53fd1e3907f..e4e94dae191 100644 --- a/src/main/java/org/tron/common/utils/FileUtil.java +++ b/src/main/java/org/tron/common/utils/FileUtil.java @@ -17,7 +17,12 @@ */ package org.tron.common.utils; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; @@ -30,55 +35,89 @@ 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, String data, boolean append) { + try { + File priFile = new File(filePath); + priFile.createNewFile(); + FileWriter fw = new FileWriter(priFile, append); + BufferedWriter bw = new BufferedWriter(fw); + bw.write(data); + bw.flush(); + bw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static int readData(String filePath, char[] buf) { + int len; + try { + File file = new File(filePath); + FileReader fileReader = new FileReader(file); + if (null == fileReader) { + return 0; + } + BufferedReader bufRead = new BufferedReader(fileReader); + len = bufRead.read(buf, 0, buf.length); + bufRead.close(); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + return 0; + } catch (IOException ex) { + ex.printStackTrace(); + return 0; + } + return len; + } } diff --git a/src/main/java/org/tron/common/utils/SetAdapter.java b/src/main/java/org/tron/common/utils/SetAdapter.java index dd3c1b4a6e1..990ae44fd42 100644 --- a/src/main/java/org/tron/common/utils/SetAdapter.java +++ b/src/main/java/org/tron/common/utils/SetAdapter.java @@ -23,83 +23,84 @@ import java.util.Set; public class SetAdapter implements Set { - private static final Object DummyValue = new Object(); - Map delegate; - public SetAdapter(Map delegate) { - this.delegate = (Map) delegate; + private static final Object DummyValue = new Object(); + Map delegate; + + public SetAdapter(Map delegate) { + this.delegate = (Map) delegate; + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return delegate.containsKey(o); + } + + @Override + public Iterator iterator() { + return delegate.keySet().iterator(); + } + + @Override + public Object[] toArray() { + return delegate.keySet().toArray(); + } + + @Override + public T[] toArray(T[] a) { + return delegate.keySet().toArray(a); + } + + @Override + public boolean add(E e) { + return delegate.put(e, DummyValue) == null; + } + + @Override + public boolean remove(Object o) { + return delegate.remove(o) != null; + } + + @Override + public boolean containsAll(Collection c) { + return delegate.keySet().containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + boolean ret = false; + for (E e : c) { + ret |= add(e); } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return delegate.containsKey(o); - } - - @Override - public Iterator iterator() { - return delegate.keySet().iterator(); - } - - @Override - public Object[] toArray() { - return delegate.keySet().toArray(); - } - - @Override - public T[] toArray(T[] a) { - return delegate.keySet().toArray(a); - } - - @Override - public boolean add(E e) { - return delegate.put(e, DummyValue) == null; - } - - @Override - public boolean remove(Object o) { - return delegate.remove(o) != null; - } - - @Override - public boolean containsAll(Collection c) { - return delegate.keySet().containsAll(c); - } - - @Override - public boolean addAll(Collection c) { - boolean ret = false; - for (E e : c) { - ret |= add(e); - } - return ret; - } - - @Override - public boolean retainAll(Collection c) { - throw new RuntimeException("Not implemented"); // TODO add later if required + return ret; + } + + @Override + public boolean retainAll(Collection c) { + throw new RuntimeException("Not implemented"); // TODO add later if required + } + + @Override + public boolean removeAll(Collection c) { + boolean ret = false; + for (Object e : c) { + ret |= remove(e); } + return ret; + } - @Override - public boolean removeAll(Collection c) { - boolean ret = false; - for (Object e : c) { - ret |= remove(e); - } - return ret; - } - - @Override - public void clear() { - delegate.clear(); - } + @Override + public void clear() { + delegate.clear(); + } } diff --git a/src/main/java/org/tron/common/utils/Utils.java b/src/main/java/org/tron/common/utils/Utils.java index 16027763235..5de667c5f16 100644 --- a/src/main/java/org/tron/common/utils/Utils.java +++ b/src/main/java/org/tron/common/utils/Utils.java @@ -19,6 +19,8 @@ package org.tron.common.utils; import java.security.SecureRandom; +import java.nio.*; +import java.nio.charset.Charset; public class Utils { private static SecureRandom random = new SecureRandom(); @@ -26,4 +28,24 @@ public class Utils { public static SecureRandom getRandom() { return random; } + + public static byte[] getBytes (char[] chars) { + Charset cs = Charset.forName ("UTF-8"); + CharBuffer cb = CharBuffer.allocate (chars.length); + cb.put (chars); + cb.flip (); + ByteBuffer bb = cs.encode (cb); + + return bb.array(); + } + + private char[] getChars (byte[] bytes) { + Charset cs = Charset.forName ("UTF-8"); + ByteBuffer bb = ByteBuffer.allocate (bytes.length); + bb.put (bytes); + bb.flip (); + CharBuffer cb = cs.decode (bb); + + return cb.array(); + } } diff --git a/src/main/java/org/tron/common/utils/Value.java b/src/main/java/org/tron/common/utils/Value.java index daba7c3dff1..b46433e709e 100644 --- a/src/main/java/org/tron/common/utils/Value.java +++ b/src/main/java/org/tron/common/utils/Value.java @@ -18,340 +18,339 @@ package org.tron.common.utils; import com.cedarsoftware.util.DeepEquals; -import org.spongycastle.util.encoders.Hex; - import java.math.BigInteger; import java.util.Arrays; import java.util.List; +import org.spongycastle.util.encoders.Hex; /** * Class to encapsulate an object and provide utilities for conversion */ public class Value { - private Object value; - private byte[] serializable; - private byte[] sha3; + private Object value; + private byte[] serializable; + private byte[] sha3; - private boolean decoded = false; + private boolean decoded = false; - public Value() { - } + public Value() { + } - public Value(Object obj) { + public Value(Object obj) { - this.decoded = true; - if (obj == null) { - return; - } + this.decoded = true; + if (obj == null) { + return; + } - if (obj instanceof Value) { - this.value = ((Value) obj).asObj(); - } else { - this.value = obj; - } + if (obj instanceof Value) { + this.value = ((Value) obj).asObj(); + } else { + this.value = obj; } + } - public static Value fromSerEncoded(byte[] data) { + public static Value fromSerEncoded(byte[] data) { - if (data != null && data.length != 0) { - Value v = new Value(); - v.init(data); - return v; - } - return null; + if (data != null && data.length != 0) { + Value v = new Value(); + v.init(data); + return v; } + return null; + } - public void init(byte[] serializable) { - this.serializable = serializable; - } + public void init(byte[] serializable) { + this.serializable = serializable; + } - public Value withHash(byte[] hash) { - sha3 = hash; - return this; - } + public Value withHash(byte[] hash) { + sha3 = hash; + return this; + } /* ***************** * Convert * *****************/ - public Object asObj() { - // decode(); - return value; + public Object asObj() { + // decode(); + return value; + } + + public List asList() { + // decode(); + Object[] valueArray = (Object[]) value; + return Arrays.asList(valueArray); + } + + public int asInt() { + //decode(); + if (isInt()) { + return (Integer) value; + } else if (isBytes()) { + return new BigInteger(1, asBytes()).intValue(); } - - public List asList() { - // decode(); - Object[] valueArray = (Object[]) value; - return Arrays.asList(valueArray); + return 0; + } + + public long asLong() { + // decode(); + if (isLong()) { + return (Long) value; + } else if (isBytes()) { + return new BigInteger(1, asBytes()).longValue(); } - - public int asInt() { - //decode(); - if (isInt()) { - return (Integer) value; - } else if (isBytes()) { - return new BigInteger(1, asBytes()).intValue(); - } - return 0; + return 0; + } + + public BigInteger asBigInt() { + // decode(); + return (BigInteger) value; + } + + public String asString() { + // decode(); + if (isBytes()) { + return new String((byte[]) value); + } else if (isString()) { + return (String) value; } - - public long asLong() { - // decode(); - if (isLong()) { - return (Long) value; - } else if (isBytes()) { - return new BigInteger(1, asBytes()).longValue(); - } - return 0; + return ""; + } + + public byte[] asBytes() { + // decode(); + if (isBytes()) { + return (byte[]) value; + } else if (isString()) { + return asString().getBytes(); } + return ByteUtil.EMPTY_BYTE_ARRAY; + } - public BigInteger asBigInt() { - // decode(); - return (BigInteger) value; - } - public String asString() { - // decode(); - if (isBytes()) { - return new String((byte[]) value); - } else if (isString()) { - return (String) value; - } - return ""; - } + public int[] asSlice() { + return (int[]) value; + } - public byte[] asBytes() { - // decode(); - if (isBytes()) { - return (byte[]) value; - } else if (isString()) { - return asString().getBytes(); - } - return ByteUtil.EMPTY_BYTE_ARRAY; - } - - - public int[] asSlice() { - return (int[]) value; - } - - public Value get(int index) { - if (isList()) { - // Guard for OutOfBounds - if (asList().size() <= index) { - return new Value(null); - } - if (index < 0) { - throw new RuntimeException("Negative index not allowed"); - } - return new Value(asList().get(index)); - } - // If this wasn't a slice you probably shouldn't be using this function + public Value get(int index) { + if (isList()) { + // Guard for OutOfBounds + if (asList().size() <= index) { return new Value(null); + } + if (index < 0) { + throw new RuntimeException("Negative index not allowed"); + } + return new Value(asList().get(index)); } + // If this wasn't a slice you probably shouldn't be using this function + return new Value(null); + } /* ***************** * Utility * *****************/ - public boolean cmp(Value o) { - return DeepEquals.deepEquals(this, o); - } + public boolean cmp(Value o) { + return DeepEquals.deepEquals(this, o); + } /* ***************** * Checks * *****************/ - public boolean isList() { + public boolean isList() { // decode(); - return value != null && value.getClass().isArray() && !value.getClass().getComponentType() - .isPrimitive(); - } + return value != null && value.getClass().isArray() && !value.getClass().getComponentType() + .isPrimitive(); + } - public boolean isString() { + public boolean isString() { // decode(); - return value instanceof String; + return value instanceof String; + } + + public boolean isInt() { + //decode(); + return value instanceof Integer; + } + + public boolean isLong() { + //decode(); + return value instanceof Long; + } + + public boolean isBigInt() { + // decode(); + return value instanceof BigInteger; + } + + public boolean isBytes() { + //decode(); + return value instanceof byte[]; + } + + // it's only if the isBytes() = true; + public boolean isReadableString() { + + // decode(); + int readableChars = 0; + byte[] data = (byte[]) value; + + if (data.length == 1 && data[0] > 31 && data[0] < 126) { + return true; } - public boolean isInt() { - //decode(); - return value instanceof Integer; + for (byte aData : data) { + if (aData > 32 && aData < 126) { + ++readableChars; + } } - public boolean isLong() { - //decode(); - return value instanceof Long; - } + return (double) readableChars / (double) data.length > 0.55; + } - public boolean isBigInt() { - // decode(); - return value instanceof BigInteger; - } + // it's only if the isBytes() = true; + public boolean isHexString() { - public boolean isBytes() { - //decode(); - return value instanceof byte[]; - } + //decode(); + int hexChars = 0; + byte[] data = (byte[]) value; - // it's only if the isBytes() = true; - public boolean isReadableString() { + for (byte aData : data) { - // decode(); - int readableChars = 0; - byte[] data = (byte[]) value; + if ((aData >= 48 && aData <= 57) + || (aData >= 97 && aData <= 102)) { + ++hexChars; + } + } - if (data.length == 1 && data[0] > 31 && data[0] < 126) { - return true; - } + return (double) hexChars / (double) data.length > 0.9; + } - for (byte aData : data) { - if (aData > 32 && aData < 126) { - ++readableChars; - } - } + public boolean isHashCode() { + //decode(); + return this.asBytes().length == 32; + } - return (double) readableChars / (double) data.length > 0.55; + public boolean isNull() { + //decode(); + return value == null; + } + + public boolean isEmpty() { + // decode(); + if (isNull()) { + return true; + } + if (isBytes() && asBytes().length == 0) { + return true; + } + if (isList() && asList().isEmpty()) { + return true; } + return isString() && asString().equals(""); + + } + + public int length() { + //decode(); + if (isList()) { + return asList().size(); + } else if (isBytes()) { + return asBytes().length; + } else if (isString()) { + return asString().length(); + } + return 0; + } - // it's only if the isBytes() = true; - public boolean isHexString() { + public String toString() { - //decode(); - int hexChars = 0; - byte[] data = (byte[]) value; + //decode(); + StringBuilder stringBuilder = new StringBuilder(); - for (byte aData : data) { + if (isList()) { - if ((aData >= 48 && aData <= 57) - || (aData >= 97 && aData <= 102)) { - ++hexChars; - } - } + Object[] list = (Object[]) value; - return (double) hexChars / (double) data.length > 0.9; - } + // special case - key/value node + if (list.length == 2) { - public boolean isHashCode() { - //decode(); - return this.asBytes().length == 32; - } + stringBuilder.append("[ "); - public boolean isNull() { - //decode(); - return value == null; - } + Value key = new Value(list[0]); - public boolean isEmpty() { - // decode(); - if (isNull()) { - return true; - } - if (isBytes() && asBytes().length == 0) { - return true; - } - if (isList() && asList().isEmpty()) { - return true; - } - return isString() && asString().equals(""); + byte[] keyNibbles = CompactEncoder.binToNibblesNoTerminator(key.asBytes()); + String keyString = ByteUtil.nibblesToPrettyString(keyNibbles); + stringBuilder.append(keyString); - } + stringBuilder.append(","); - public int length() { - //decode(); - if (isList()) { - return asList().size(); - } else if (isBytes()) { - return asBytes().length; - } else if (isString()) { - return asString().length(); - } - return 0; - } + Value val = new Value(list[1]); + stringBuilder.append(val.toString()); + + stringBuilder.append(" ]"); + return stringBuilder.toString(); + } + stringBuilder.append(" ["); - public String toString() { - - //decode(); - StringBuilder stringBuilder = new StringBuilder(); - - if (isList()) { - - Object[] list = (Object[]) value; - - // special case - key/value node - if (list.length == 2) { - - stringBuilder.append("[ "); - - Value key = new Value(list[0]); - - byte[] keyNibbles = CompactEncoder.binToNibblesNoTerminator(key.asBytes()); - String keyString = ByteUtil.nibblesToPrettyString(keyNibbles); - stringBuilder.append(keyString); - - stringBuilder.append(","); - - Value val = new Value(list[1]); - stringBuilder.append(val.toString()); - - stringBuilder.append(" ]"); - return stringBuilder.toString(); - } - stringBuilder.append(" ["); - - for (int i = 0; i < list.length; ++i) { - Value val = new Value(list[i]); - if (val.isString() || val.isEmpty()) { - stringBuilder.append("'").append(val.toString()).append("'"); - } else { - stringBuilder.append(val.toString()); - } - if (i < list.length - 1) { - stringBuilder.append(", "); - } - } - stringBuilder.append("] "); - - return stringBuilder.toString(); - } else if (isEmpty()) { - return ""; - } else if (isBytes()) { - - StringBuilder output = new StringBuilder(); - if (isHashCode()) { - output.append(Hex.toHexString(asBytes())); - } else if (isReadableString()) { - output.append("'"); - for (byte oneByte : asBytes()) { - if (oneByte < 16) { - output.append("\\x").append(ByteUtil.oneByteToHexString(oneByte)); - } else { - output.append(Character.valueOf((char) oneByte)); - } - } - output.append("'"); - return output.toString(); - } - return Hex.toHexString(this.asBytes()); - } else if (isString()) { - return asString(); + for (int i = 0; i < list.length; ++i) { + Value val = new Value(list[i]); + if (val.isString() || val.isEmpty()) { + stringBuilder.append("'").append(val.toString()).append("'"); + } else { + stringBuilder.append(val.toString()); } - return "Unexpected type"; + if (i < list.length - 1) { + stringBuilder.append(", "); + } + } + stringBuilder.append("] "); + + return stringBuilder.toString(); + } else if (isEmpty()) { + return ""; + } else if (isBytes()) { + + StringBuilder output = new StringBuilder(); + if (isHashCode()) { + output.append(Hex.toHexString(asBytes())); + } else if (isReadableString()) { + output.append("'"); + for (byte oneByte : asBytes()) { + if (oneByte < 16) { + output.append("\\x").append(ByteUtil.oneByteToHexString(oneByte)); + } else { + output.append(Character.valueOf((char) oneByte)); + } + } + output.append("'"); + return output.toString(); + } + return Hex.toHexString(this.asBytes()); + } else if (isString()) { + return asString(); } + return "Unexpected type"; + } - public int countBranchNodes() { + public int countBranchNodes() { // decode(); - if (this.isList()) { - List objList = this.asList(); - int i = 0; - for (Object obj : objList) { - i += (new Value(obj)).countBranchNodes(); - } - return i; - } else if (this.isBytes()) { - this.asBytes(); - } - return 0; + if (this.isList()) { + List objList = this.asList(); + int i = 0; + for (Object obj : objList) { + i += (new Value(obj)).countBranchNodes(); + } + return i; + } else if (this.isBytes()) { + this.asBytes(); } + return 0; + } } diff --git a/src/main/java/org/tron/core/BlockSummary.java b/src/main/java/org/tron/core/BlockSummary.java index 3efb4d7d3de..5be7d3117b9 100644 --- a/src/main/java/org/tron/core/BlockSummary.java +++ b/src/main/java/org/tron/core/BlockSummary.java @@ -18,24 +18,22 @@ package org.tron.core; - -import org.tron.protos.core.TronBlock; - import java.math.BigInteger; import java.util.Map; +import org.tron.protos.core.TronBlock; public class BlockSummary { - private final TronBlock.Block block; - private final Map rewards; - private BigInteger totalDifficulty = BigInteger.ZERO; + private final TronBlock.Block block; + private final Map rewards; + private BigInteger totalDifficulty = BigInteger.ZERO; - public BlockSummary(TronBlock.Block block, Map rewards) { - this.block = block; - this.rewards = rewards; - } + public BlockSummary(TronBlock.Block block, Map rewards) { + this.block = block; + this.rewards = rewards; + } - public void setTotalDifficulty(BigInteger totalDifficulty) { - this.totalDifficulty = totalDifficulty; - } + public void setTotalDifficulty(BigInteger totalDifficulty) { + this.totalDifficulty = totalDifficulty; + } } diff --git a/src/main/java/org/tron/core/BlockUtils.java b/src/main/java/org/tron/core/BlockUtils.java index 6be0338dfc5..2ab909bb944 100644 --- a/src/main/java/org/tron/core/BlockUtils.java +++ b/src/main/java/org/tron/core/BlockUtils.java @@ -15,8 +15,8 @@ package org.tron.core; -import static org.tron.core.Constant.LAST_HASH; import static org.tron.common.crypto.Hash.sha3; +import static org.tron.core.Constant.LAST_HASH; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; @@ -28,12 +28,12 @@ import java.util.Optional; import org.spongycastle.util.Arrays; import org.spongycastle.util.BigIntegers; +import org.tron.common.utils.ByteArray; import org.tron.core.peer.Validator; import org.tron.protos.core.TronBlock; import org.tron.protos.core.TronBlock.Block; import org.tron.protos.core.TronBlockHeader.BlockHeader; import org.tron.protos.core.TronTransaction.Transaction; -import org.tron.common.utils.ByteArray; public class BlockUtils { @@ -41,7 +41,7 @@ public class BlockUtils { private byte[] serializEncode; /** - * getData a new block + * getData a new block. * * @return {@link Block} block */ @@ -56,11 +56,6 @@ public static Block newBlock(List transactions, ByteString ); } - //Chain programming -// BlockHeader.Builder builder = BlockHeader.newBuilder() -// .setParentHash(parentHash).setDifficulty(difficulty) -// .setNumber(number).setTimestamp(System.currentTimeMillis()); - BlockHeader.Builder blockHeaderBuilder = BlockHeader.newBuilder(); blockHeaderBuilder.setParentHash(parentHash); @@ -78,13 +73,12 @@ public static Block newBlock(List transactions, ByteString } /** - * new genesis block + * new genesis block. * * @return {@link Block} block */ public static Block newGenesisBlock(Transaction coinbase) { - Block.Builder genesisBlock = Block.newBuilder(); genesisBlock.addTransactions(coinbase); @@ -125,7 +119,7 @@ public static Block newGenesisBlock(List transactions) { } /** - * getData prepare data of the block + * getData prepare data of the block. * * @param block {@link Block} block * @return byte[] data @@ -143,7 +137,7 @@ public static byte[] prepareData(Block block) { } /** - * the proof block + * the proof block. * * @param block {@link Block} block * @return boolean is it the proof block @@ -153,7 +147,7 @@ public static boolean isValidate(Block block) { } /** - * getData print string of the block + * getData print string of the block. * * @param block {@link Block} block * @return String format string of the block diff --git a/src/main/java/org/tron/core/Blockchain.java b/src/main/java/org/tron/core/Blockchain.java index 244837cf23e..837e4040a80 100644 --- a/src/main/java/org/tron/core/Blockchain.java +++ b/src/main/java/org/tron/core/Blockchain.java @@ -35,18 +35,18 @@ import javax.inject.Named; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.tron.core.config.Configer; -import org.tron.core.events.BlockchainListener; import org.tron.common.crypto.ECKey; import org.tron.common.overlay.Net; +import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; +import org.tron.common.utils.ByteArray; +import org.tron.core.config.Configer; +import org.tron.core.events.BlockchainListener; import org.tron.core.peer.Peer; import org.tron.protos.core.TronBlock.Block; import org.tron.protos.core.TronTXInput.TXInput; import org.tron.protos.core.TronTXOutput.TXOutput; import org.tron.protos.core.TronTXOutputs.TXOutputs; import org.tron.protos.core.TronTransaction.Transaction; -import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; -import org.tron.common.utils.ByteArray; public class Blockchain { @@ -144,9 +144,9 @@ public static boolean dbExists() { public Transaction findTransaction(ByteString id) { Transaction transaction = Transaction.newBuilder().build(); - BlockchainIterator bi = new BlockchainIterator(this); - while (bi.hasNext()) { - Block block = bi.next(); + BlockchainIterator bi = new BlockchainIterator(this); + while (bi.hasNext()) { + Block block = bi.next(); for (Transaction tx : block.getTransactionsList()) { String txID = ByteArray.toHexString(tx.getId().toByteArray()); @@ -169,12 +169,12 @@ public HashMap findUTXO() { HashMap utxo = new HashMap<>(); HashMap spenttxos = new HashMap<>(); - BlockchainIterator bi = new BlockchainIterator(this); - while (bi.hasNext()) { - Block block = bi.next(); + BlockchainIterator bi = new BlockchainIterator(this); + while (bi.hasNext()) { + Block block = bi.next(); - for (Transaction transaction : block.getTransactionsList()) { - String txid = ByteArray.toHexString(transaction.getId().toByteArray()); + for (Transaction transaction : block.getTransactionsList()) { + String txid = ByteArray.toHexString(transaction.getId().toByteArray()); output: for (int outIdx = 0; outIdx < transaction.getVoutList().size @@ -223,8 +223,6 @@ public HashMap findUTXO() { /** * add a block into database - * - * @param block */ public void addBlock(Block block) { byte[] blockInDB = blockDB.getData(block.getBlockHeader().getHash().toByteArray()); @@ -304,7 +302,7 @@ public void addBlock(List transactions) { /** * receive a block and save it into database,update caching at the same time. * - * @param block block + * @param block block * @param utxoSet utxoSet */ public void receiveBlock(Block block, UTXOSet utxoSet, Peer peer) { diff --git a/src/main/java/org/tron/core/TransactionUtils.java b/src/main/java/org/tron/core/TransactionUtils.java index b2304633180..63ad0aa5722 100644 --- a/src/main/java/org/tron/core/TransactionUtils.java +++ b/src/main/java/org/tron/core/TransactionUtils.java @@ -89,7 +89,7 @@ public static Transaction newTransaction(Wallet wallet, String to, long amount, /** * new coinbase transaction * - * @param to String to sender's address + * @param to String to sender's address * @param data String transaction data * @return {@link Transaction} */ @@ -101,7 +101,7 @@ public static Transaction newCoinbaseTransaction(String to, String data, long su data = "" + ByteArray.toHexString(randBytes); } - TXInput txi = TXInputUtils.newTXInput(new byte[] {}, -1, new byte[] {}, + TXInput txi = TXInputUtils.newTXInput(new byte[]{}, -1, new byte[]{}, ByteArray.fromHexString(data)); TXOutput txo = TXOutputUtils.newTXOutput(RESERVE_BALANCE, to); @@ -144,7 +144,6 @@ public static String toPrintString(Transaction transaction) { .toByteArray()) + "\n" + "\tvin=[\n"); - for (int i = 0, vinCount = transaction.getVinCount(); i < vinCount; i++) { TXInput vin = transaction.getVin(i); @@ -166,7 +165,6 @@ public static String toPrintString(Transaction transaction) { sb.append("\t],\n\tvout=[\n"); - for (int i = 0, voutCount = transaction.getVoutCount(); i < voutCount; i++) { TXOutput vout = transaction.getVout(i); sb.append("\t\t{\n" + @@ -197,6 +195,46 @@ public static boolean isCoinbaseTransaction(Transaction transaction) { .getTxID().size() == 0 && transaction.getVin(0).getVout() == -1; } + public static Transaction sign(Transaction transaction, ECKey myKey, + List pubKeyHashList) { + if (TransactionUtils.isCoinbaseTransaction(transaction)) { + return null; + } + + for (int i = 0; i < transaction.getVinList().size(); i++) { + TXInput vin = transaction.getVin(i); + ByteString prevTxPubKeyHash = pubKeyHashList.get(i); + if (prevTxPubKeyHash == null || prevTxPubKeyHash.isEmpty()) { + logger + .error( + "ERROR: Previous transaction is not correct, the " + i + "PubKeyHash is empty !!!"); + return null; + } + Transaction.Builder transactionCopyBuilder = transaction + .toBuilder(); + TXInput.Builder vinBuilder = vin.toBuilder(); + vinBuilder.clearSignature(); + vinBuilder.setPubKey(prevTxPubKeyHash); + transactionCopyBuilder.setVin(i, vinBuilder.build()); + transactionCopyBuilder.setId(ByteString.copyFrom(TransactionUtils + .getHash(transactionCopyBuilder.build()))); + vinBuilder.clearPubKey(); + transactionCopyBuilder.setVin(i, vinBuilder.build()); + + Transaction.Builder transactionBuilder = transaction.toBuilder().setVin(i, vin.toBuilder() + .setSignature(ByteString.copyFrom(myKey.sign + (transactionCopyBuilder.getId().toByteArray()) + .toByteArray())).build()); + + transactionBuilder + .setId(ByteString.copyFrom(TransactionUtils.getHash(transactionBuilder.build()))); + + transaction = transactionBuilder.build(); + } + + return transaction; + } + public static Transaction sign(Transaction transaction, ECKey myKey, HashMap prevTXs) { if (TransactionUtils.isCoinbaseTransaction(transaction)) { @@ -216,7 +254,6 @@ public static Transaction sign(Transaction transaction, ECKey myKey, Transaction prevTx = prevTXs.get(ByteArray.toHexString(vin .getTxID().toByteArray())); - Transaction.Builder transactionCopyBuilder = transaction .toBuilder(); TXInput.Builder vinBuilder = vin.toBuilder(); @@ -260,7 +297,6 @@ public static boolean verify(ECKey myKey, Transaction transaction, Transaction prevTx = prevTXs.get(ByteArray.toHexString(vin .getTxID().toByteArray())); - Transaction.Builder transactionCopyBuilder = transaction .toBuilder(); TXInput.Builder vinBuilder = vin.toBuilder(); diff --git a/src/main/java/org/tron/core/TronBlockChain.java b/src/main/java/org/tron/core/TronBlockChain.java index 1edeacd6a31..57e43036067 100644 --- a/src/main/java/org/tron/core/TronBlockChain.java +++ b/src/main/java/org/tron/core/TronBlockChain.java @@ -19,7 +19,7 @@ import java.math.BigInteger; -import org.tron.core.dbStore.BlockStoreInput; +import org.tron.core.dbstore.BlockStoreInput; import org.tron.protos.core.TronBlock; public interface TronBlockChain { diff --git a/src/main/java/org/tron/core/TronBlockChainImpl.java b/src/main/java/org/tron/core/TronBlockChainImpl.java index 83003a5f4b0..65270dce96b 100644 --- a/src/main/java/org/tron/core/TronBlockChainImpl.java +++ b/src/main/java/org/tron/core/TronBlockChainImpl.java @@ -32,10 +32,10 @@ import org.spongycastle.util.encoders.Hex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; import org.tron.core.config.SystemProperties; -import org.tron.core.dbStore.BlockStoreInput; +import org.tron.core.dbstore.BlockStoreInput; import org.tron.protos.core.TronBlock; -import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; @Component public class TronBlockChainImpl implements TronBlockChain, org.tron.core.facade.TronBlockChain { diff --git a/src/main/java/org/tron/core/Wallet.java b/src/main/java/org/tron/core/Wallet.java index e53e6a82ac7..8ba86180a51 100644 --- a/src/main/java/org/tron/core/Wallet.java +++ b/src/main/java/org/tron/core/Wallet.java @@ -18,17 +18,32 @@ package org.tron.core; +import java.util.ArrayList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.tron.common.application.Application; import org.tron.common.crypto.ECKey; import org.tron.common.utils.ByteArray; import org.tron.common.utils.Utils; +import org.tron.core.db.BlockStore; +import org.tron.core.db.UTXOStore; +import org.tron.core.net.message.Message; +import org.tron.core.net.message.TransactionMessage; +import org.tron.core.net.node.Node; +import org.tron.protos.Protocal.Transaction; +import org.tron.protos.core.TronTXOutput.TXOutput; + public class Wallet { private static final Logger logger = LoggerFactory.getLogger("Wallet"); + private static BlockStore db; private final ECKey ecKey; + private UTXOStore utxoStore; + private Application app; + private Node p2pnode; + private UTXOSet utxoSet; /** * Creates a new Wallet with a random ECKey. @@ -37,11 +52,17 @@ public Wallet() { this.ecKey = new ECKey(Utils.getRandom()); } + public Wallet(Application app) { + this.app = app; + this.p2pnode = app.getP2pNode(); + this.db = app.getBlockStoreS(); + this.ecKey = new ECKey(Utils.getRandom()); + } + /** * Creates a Wallet with an existing ECKey. - * - * @param ECKey ecKey Existing Key */ + public Wallet(final ECKey ecKey) { this.ecKey = ecKey; logger.info("wallet address: {}", ByteArray.toHexString(this.ecKey.getAddress())); @@ -55,4 +76,88 @@ public byte[] getAddress() { return ecKey.getAddress(); } + /** + * Get balance by address + */ + public long getBalance(byte[] address) { + + ArrayList utxos = utxoStore.findUTXO(address); + long balance = 0; + + for (TXOutput txOutput : utxos) { + balance += txOutput.getValue(); + } + + logger.info("balance = {}", balance); + return balance; + } + +// /** +// * Build a transaction +// */ +// public Transaction buildTransaction(List txInputs, List txOutputs) { +// Transaction.Builder transactionBuilder = Transaction.newBuilder(); +// +// for (int i = 0; i < txInputs.size(); i++) { +// transactionBuilder.addVin(txInputs.get(i)); +// } +// +// for (int i = 0; i < txOutputs.size(); i++) { +// transactionBuilder.addVout(txOutputs.get(i)); +// } +// +// Transaction transaction = transactionBuilder.build(); +// return transaction; +// } + + /** + * Create a transaction + */ + + public Transaction createTransaction(byte[] address, String to, long amount) { + Transaction transaction = null; + + if (check(address, to, amount)) { + transaction = Transaction.newBuilder().build(); + logger.info("Transaction create succeeded!"); + } else { + logger.error("Transaction create failed!"); + } + + return transaction; + } + + /** + * Broadcast a transaction + */ + public boolean broadcastTransaction(Transaction signaturedTransaction) { + if (signaturedTransaction != null) { + Message message = new TransactionMessage(signaturedTransaction); + p2pnode.broadcast(message); + return true; + } + return false; + } + + public boolean check(byte[] address, String to, long amount) { + + if (to.length() != 40) { + logger.error("address invalid"); + return false; + } + + if (amount <= 0) { + logger.error("amount required a positive number"); + return false; + } + + if (amount > getBalance(address)) { + logger.error("don't have enough money"); + return false; + } + + return true; + } + + } diff --git a/src/main/java/org/tron/core/config/Configer.java b/src/main/java/org/tron/core/config/Configer.java index f1976b2d49f..3c318400125 100644 --- a/src/main/java/org/tron/core/config/Configer.java +++ b/src/main/java/org/tron/core/config/Configer.java @@ -20,75 +20,80 @@ import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; -import org.tron.core.Constant; import org.tron.common.crypto.ECKey; import org.tron.common.utils.ByteArray; - -import java.io.*; -import java.util.Properties; +import org.tron.core.Constant; public class Configer { - private static final Logger logger = LoggerFactory.getLogger("Configer"); - private final static String DATABASE_DIRECTORY = Constant.DATABASE_DIR; - public static String TRON_CONF = Constant.NORMAL_CONF; - private static String generatedNodePrivateKey; - static { - try { - File file = new File(Configer.getConf().getString - (DATABASE_DIRECTORY), "nodeId.properties"); - Properties props = new Properties(); - if (file.canRead()) { - try (Reader r = new FileReader(file)) { - props.load(r); - } - } else { - ECKey key = new ECKey(); + private static final Logger logger = LoggerFactory.getLogger("Configer"); + private final static String DATABASE_DIRECTORY = Constant.DATABASE_DIR; + public static String TRON_CONF = Constant.NORMAL_CONF; + private static String generatedNodePrivateKey; - byte[] privKeyBytes = key.getPrivKeyBytes(); + static { + try { + File file = new File(Configer.getConf().getString + (DATABASE_DIRECTORY), "nodeId.properties"); + Properties props = new Properties(); + if (file.canRead()) { + try (Reader r = new FileReader(file)) { + props.load(r); + } + } else { + ECKey key = new ECKey(); - String nodeIdPrivateKey = ByteArray.toHexString(privKeyBytes); + byte[] privKeyBytes = key.getPrivKeyBytes(); - props.setProperty("nodeIdPrivateKey", nodeIdPrivateKey); - props.setProperty("nodeId", Hex.toHexString(key.getNodeId - ())); - file.getParentFile().mkdirs(); - try (Writer w = new FileWriter(file)) { - props.store(w, "Generated NodeID."); - } - logger.info("New nodeID generated: " + props.getProperty - ("nodeId")); - logger.info("Generated nodeID and its private key stored " + - "in " + file); - } - generatedNodePrivateKey = props.getProperty("nodeIdPrivateKey"); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + String nodeIdPrivateKey = ByteArray.toHexString(privKeyBytes); - public static Config getConf() { - return ConfigFactory.load(TRON_CONF); + props.setProperty("nodeIdPrivateKey", nodeIdPrivateKey); + props.setProperty("nodeId", Hex.toHexString(key.getNodeId + ())); + file.getParentFile().mkdirs(); + try (Writer w = new FileWriter(file)) { + props.store(w, "Generated NodeID."); + } + logger.info("New nodeID generated: " + props.getProperty + ("nodeId")); + logger.info("Generated nodeID and its private key stored " + + "in " + file); + } + generatedNodePrivateKey = props.getProperty("nodeIdPrivateKey"); + } catch (IOException e) { + throw new RuntimeException(e); } + } - public static Config getConf(String conf) { + public static Config getConf() { + return ConfigFactory.load(TRON_CONF); + } - if (conf == null || "".equals(conf)) { - return ConfigFactory.load(TRON_CONF); - } else { - return ConfigFactory.load(conf); - } + public static Config getConf(String conf) { + if (conf == null || "".equals(conf)) { + return ConfigFactory.load(TRON_CONF); + } else { + return ConfigFactory.load(conf); } - public static ECKey getMyKey() { - return ECKey.fromPrivate(Hex.decode(generatedNodePrivateKey)); - } + } - public static String getGNPK() { - return generatedNodePrivateKey; - } + public static ECKey getMyKey() { + return ECKey.fromPrivate(Hex.decode(generatedNodePrivateKey)); + } + + public static String getGNPK() { + return generatedNodePrivateKey; + } } diff --git a/src/main/java/org/tron/core/consensus/client/BlockchainClientListener.java b/src/main/java/org/tron/core/consensus/client/BlockchainClientListener.java index 3db172aa5b2..101bbb9ede2 100644 --- a/src/main/java/org/tron/core/consensus/client/BlockchainClientListener.java +++ b/src/main/java/org/tron/core/consensus/client/BlockchainClientListener.java @@ -14,14 +14,14 @@ */ package org.tron.core.consensus.client; -import org.tron.core.events.BlockchainListener; import org.tron.common.overlay.Net; import org.tron.common.overlay.message.Message; import org.tron.common.overlay.message.Type; +import org.tron.common.utils.ByteArray; +import org.tron.core.events.BlockchainListener; import org.tron.core.peer.Peer; import org.tron.core.peer.PeerType; import org.tron.protos.core.TronBlock; -import org.tron.common.utils.ByteArray; public class BlockchainClientListener implements BlockchainListener { diff --git a/src/main/java/org/tron/core/consensus/client/Client.java b/src/main/java/org/tron/core/consensus/client/Client.java index d064bd8d030..debcdf4602a 100644 --- a/src/main/java/org/tron/core/consensus/client/Client.java +++ b/src/main/java/org/tron/core/consensus/client/Client.java @@ -24,10 +24,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.concurrent.CompletableFuture; -import org.tron.core.consensus.common.GetQuery; -import org.tron.core.consensus.common.PutCommand; import org.tron.common.overlay.message.Message; import org.tron.common.overlay.message.Type; +import org.tron.core.consensus.common.GetQuery; +import org.tron.core.consensus.common.PutCommand; import org.tron.core.peer.Peer; public class Client { @@ -124,10 +124,10 @@ public void getMessage(Peer peer, String key) { //preTime[0] = client.submit(new GetQuery("time")).join().toString(); Object pretime = client.submit(new GetQuery("time")).join(); try { - if (!(pretime == null)){ + if (!(pretime == null)) { preTime[0] = pretime.toString(); } - }catch (NullPointerException e) { + } catch (NullPointerException e) { e.printStackTrace(); } if (key.equals("transaction")) { diff --git a/src/main/java/org/tron/core/consensus/common/MapstateMachine.java b/src/main/java/org/tron/core/consensus/common/MapstateMachine.java index b1a73d3d74b..4e72eaa90fb 100644 --- a/src/main/java/org/tron/core/consensus/common/MapstateMachine.java +++ b/src/main/java/org/tron/core/consensus/common/MapstateMachine.java @@ -27,6 +27,7 @@ import java.util.Set; public class MapstateMachine extends StateMachine implements Snapshottable, SessionListener { + private Map map = new HashMap<>(); private Set sessions = new HashSet<>(); private Set listeners = new HashSet<>(); diff --git a/src/main/java/org/tron/core/consensus/server/Server.java b/src/main/java/org/tron/core/consensus/server/Server.java index 4974bd90426..1062942c039 100644 --- a/src/main/java/org/tron/core/consensus/server/Server.java +++ b/src/main/java/org/tron/core/consensus/server/Server.java @@ -20,19 +20,25 @@ import io.atomix.copycat.server.CopycatServer; import io.atomix.copycat.server.storage.Storage; import io.atomix.copycat.server.storage.StorageLevel; -import java.io.File; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.concurrent.CompletableFuture; import org.tron.common.application.Service; import org.tron.core.consensus.common.GetQuery; import org.tron.core.consensus.common.MapstateMachine; import org.tron.core.consensus.common.PutCommand; +import java.io.File; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.CompletableFuture; + public class Server implements Service { private CopycatServer server; + @Override + public void init() { + + } + @Override public void start() { InetAddress localhost = null; diff --git a/src/main/java/org/tron/core/db/AbstractBlockstore.java b/src/main/java/org/tron/core/db/AbstractBlockstore.java index 18e6a9c84f5..53f3dc1a3e8 100644 --- a/src/main/java/org/tron/core/db/AbstractBlockstore.java +++ b/src/main/java/org/tron/core/db/AbstractBlockstore.java @@ -1,5 +1,5 @@ -package org.tron.core.db; - -public abstract class AbstractBlockstore implements BlockStoreInput { - -} +package org.tron.core.db; + +public abstract class AbstractBlockstore implements BlockStoreInput { + +} diff --git a/src/main/java/org/tron/core/db/BlockStore.java b/src/main/java/org/tron/core/db/BlockStore.java index 8e6d028fdea..65cc85be632 100644 --- a/src/main/java/org/tron/core/db/BlockStore.java +++ b/src/main/java/org/tron/core/db/BlockStore.java @@ -15,57 +15,88 @@ package org.tron.core.db; +import java.util.List; +import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; +import org.tron.protos.Protocal; import org.tron.protos.core.TronTransaction; -import java.util.Vector; +public class BlockStore extends Database { -public class BlockStore { public static final Logger logger = LoggerFactory.getLogger("BlockStore"); private LevelDbDataSourceImpl blockDbDataSource; private LevelDbDataSourceImpl unSpendCache; private Vector pendingTrans; - public BlockStore() { + private BlockStore(String dbName) { + super(dbName); + } + + private static BlockStore instance; + + public static BlockStore Create(String dbName) { + if (instance == null) { + synchronized (AccountStore.class) { + if (instance == null) { + instance = new BlockStore(dbName); + } + } + } + return instance; + } + + + public byte[] getHeadBlockHash() { + return "".getBytes(); } - public BlockStore(String parentName, String childName) { - blockDbDataSource = new LevelDbDataSourceImpl(parentName, childName); - blockDbDataSource.initDB(); + public boolean hasItem(byte[] hash, String type) { + if (type == "trx") { + return hasTranscation(hash); + } else if (type == "block") { + return hasBlock(hash); + } + return false; } - public void initBlockDbSource(String parentName, String childName) { - blockDbDataSource = new LevelDbDataSourceImpl(parentName, childName); - blockDbDataSource.initDB(); + public boolean hasBlock(byte[] blockHash) { + return false; } - public void initUnspendDbSource(String parentName, String childName) { - unSpendCache = new LevelDbDataSourceImpl(parentName, childName); - unSpendCache.initDB(); + public boolean hasTranscation(byte[] trxHash) { + return false; + } + + public boolean isIncludeBlock(byte[] hash) { + return false; } /** * */ - public void pushTransactions(TronTransaction.Transaction trx) { - pendingTrans.add(trx); + public void pushTransactions(Protocal.Transaction trx) { + //pendingTrans.add(trx); } /** * Generate Block */ - public void generateBlock() { + //public void generateBlock() { + + //} + /** + * Generate Block return Block + */ + public Protocal.Block generateBlock(List transactions) { + return null; } /** * save a block - * - * @param blockHash - * @param blockData */ public void saveBlock(byte[] blockHash, byte[] blockData) { blockDbDataSource.putData(blockHash, blockData); @@ -74,18 +105,17 @@ public void saveBlock(byte[] blockHash, byte[] blockData) { /** * find a block by it's hash - * - * @param blockHash - * @return */ public byte[] findBlockByHash(byte[] blockHash) { return blockDbDataSource.getData(blockHash); } + public byte[] findTrasactionByHash(byte[] trxHash) { + return "".getBytes(); + } + /** * deleteData a block - * - * @param blockHash */ public void deleteBlock(byte[] blockHash) { blockDbDataSource.deleteData(blockHash); @@ -96,6 +126,7 @@ public void getUnspend(byte[] key) { } + /*** * resetDB the database */ @@ -109,4 +140,18 @@ public void close() { blockDbDataSource.closeDB(); } + @Override + void add() { + + } + + @Override + void del() { + + } + + @Override + void fetch() { + + } } diff --git a/src/main/java/org/tron/core/db/BlockStoreInput.java b/src/main/java/org/tron/core/db/BlockStoreInput.java index 323d54964c4..e7a317c0a1d 100644 --- a/src/main/java/org/tron/core/db/BlockStoreInput.java +++ b/src/main/java/org/tron/core/db/BlockStoreInput.java @@ -1,33 +1,33 @@ -/* - * 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.core.db; - -import org.tron.protos.core.TronBlock; - -public interface BlockStoreInput { - - TronBlock.Block getBestBlock(); - - TronBlock.Block getChainBlockByNumber(long blockNumber); - - boolean isBlockExist(byte[] hash); - - TronBlock.Block getBlockByHash(byte[] hash); - -} +/* + * 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.core.db; + +import org.tron.protos.core.TronBlock; + +public interface BlockStoreInput { + + TronBlock.Block getBestBlock(); + + TronBlock.Block getChainBlockByNumber(long blockNumber); + + boolean isBlockExist(byte[] hash); + + TronBlock.Block getBlockByHash(byte[] hash); + +} diff --git a/src/main/java/org/tron/core/db/ByteArrayWrapper.java b/src/main/java/org/tron/core/db/ByteArrayWrapper.java index 67f69aa5604..c6f26f08446 100644 --- a/src/main/java/org/tron/core/db/ByteArrayWrapper.java +++ b/src/main/java/org/tron/core/db/ByteArrayWrapper.java @@ -1,72 +1,72 @@ -/* - * 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.core.db; - - -import org.spongycastle.util.encoders.Hex; -import org.tron.common.utils.FastByteComparisons; - -import java.io.Serializable; -import java.util.Arrays; - - -public class ByteArrayWrapper implements Comparable, Serializable { - - private final byte[] data; - private int hashCode = 0; - - public ByteArrayWrapper(byte[] data) { - if (data == null) { - throw new NullPointerException("Data must not be null"); - } - this.data = data; - this.hashCode = Arrays.hashCode(data); - } - - public boolean equals(Object other) { - if (!(other instanceof ByteArrayWrapper)) { - 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); - } -} +/* + * 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.core.db; + + +import org.spongycastle.util.encoders.Hex; +import org.tron.common.utils.FastByteComparisons; + +import java.io.Serializable; +import java.util.Arrays; + + +public class ByteArrayWrapper implements Comparable, Serializable { + + private final byte[] data; + private int hashCode = 0; + + public ByteArrayWrapper(byte[] data) { + if (data == null) { + throw new NullPointerException("Data must not be null"); + } + this.data = data; + this.hashCode = Arrays.hashCode(data); + } + + public boolean equals(Object other) { + if (!(other instanceof ByteArrayWrapper)) { + 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/main/java/org/tron/core/db/UTXOStore.java b/src/main/java/org/tron/core/db/UTXOStore.java index 15471bbe31c..fe5d0f5ca61 100644 --- a/src/main/java/org/tron/core/db/UTXOStore.java +++ b/src/main/java/org/tron/core/db/UTXOStore.java @@ -1,61 +1,151 @@ -/* - * 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 org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; - -import java.util.Set; - -public class UTXOStore { - - public static final Logger logger = LoggerFactory.getLogger("UTXOStore"); - private LevelDbDataSourceImpl uTXODataSource; - - public UTXOStore(String parentName, String childName) { - uTXODataSource = new LevelDbDataSourceImpl(parentName, childName); - uTXODataSource.initDB(); - } - - - public void reSet() { - uTXODataSource.resetDB(); - } - - public byte[] find(byte[] key) { - return uTXODataSource.getData(key); - } - - - public Set getKeys() { - return uTXODataSource.allKeys(); - } - - /** - * save utxo - * - * @param utxoKey - * @param utxoData - */ - public void saveUTXO(byte[] utxoKey, byte[] utxoData) { - uTXODataSource.putData(utxoKey, utxoData); - } - - public void close() { - uTXODataSource.closeDB(); - } -} +/* + * 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.Map.Entry; +import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.tron.common.crypto.ECKey; +import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; +import org.tron.common.utils.ByteArray; +import org.tron.core.Blockchain; +import org.tron.protos.core.TronTXOutput.TXOutput; +import org.tron.protos.core.TronTXOutputs.TXOutputs; + +public class UTXOStore extends Database { + + public static final Logger logger = LoggerFactory.getLogger("UTXOStore"); + private Blockchain blockchain; + private LevelDbDataSourceImpl uTXODataSource; + + private UTXOStore(String dbName) { + super(dbName); + } + + @Override + void add() { + + } + + @Override + void del() { + + } + + @Override + void fetch() { + + } + + private static UTXOStore instance; + + /** + * + * @param dbName + * @return + */ + public static UTXOStore Create(String dbName) { + if (instance == null) { + synchronized (UTXOStore.class) { + if (instance == null) { + instance = new UTXOStore(dbName); + } + } + } + return instance; + } + + + public void reSet() { + this.dbSource.resetDB(); + } + + 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); + } + + /** + * store and find related utxos + */ + + public void storeUTXO() { + logger.info("storeUTXO"); + + uTXODataSource.resetDB(); + + HashMap utxo = blockchain.findUTXO(); + + Set> entrySet = utxo.entrySet(); + + for (Entry entry : entrySet) { + String key = entry.getKey(); + TXOutputs value = entry.getValue(); + + for (TXOutput ignored : value.getOutputsList()) { + uTXODataSource.putData(ByteArray.fromHexString(key), value.toByteArray()); + } + } + } + + /** + * Find UTXO + */ + public ArrayList findUTXO(byte[] address) { + ArrayList utxos = new ArrayList<>(); + + Set keySet = uTXODataSource.allKeys(); + + for (byte[] key : keySet) { + byte[] txData = uTXODataSource.getData(key); + try { + TXOutputs txOutputs = TXOutputs.parseFrom(txData); + for (TXOutput txOutput : txOutputs.getOutputsList()) { + if (ByteArray.toHexString(ECKey.computeAddress(address)) + .equals(ByteArray.toHexString(txOutput + .getPubKeyHash() + .toByteArray()))) { + utxos.add(txOutput); + } + } + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + } + + return utxos; + } + + public void close() { + dbSource.closeDB(); + } +} diff --git a/src/main/java/org/tron/core/dbStore/AbstractBlockstore.java b/src/main/java/org/tron/core/dbStore/AbstractBlockstore.java index 3f562861514..e1f006da20c 100644 --- a/src/main/java/org/tron/core/dbStore/AbstractBlockstore.java +++ b/src/main/java/org/tron/core/dbStore/AbstractBlockstore.java @@ -1,4 +1,4 @@ -package org.tron.core.dbStore; +package org.tron.core.dbstore; public abstract class AbstractBlockstore implements BlockStoreInput { diff --git a/src/main/java/org/tron/core/dbStore/BlockStoreInput.java b/src/main/java/org/tron/core/dbStore/BlockStoreInput.java index 041c79ffe1a..fd303bb98e9 100644 --- a/src/main/java/org/tron/core/dbStore/BlockStoreInput.java +++ b/src/main/java/org/tron/core/dbStore/BlockStoreInput.java @@ -16,7 +16,7 @@ * along with the ethereumJ library. If not, see . */ -package org.tron.core.dbStore; +package org.tron.core.dbstore; import org.tron.protos.core.TronBlock; diff --git a/src/main/java/org/tron/core/dbStore/BlockStores.java b/src/main/java/org/tron/core/dbStore/BlockStores.java index 892ff60183f..86cd8668505 100644 --- a/src/main/java/org/tron/core/dbStore/BlockStores.java +++ b/src/main/java/org/tron/core/dbStore/BlockStores.java @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -package org.tron.core.dbStore; +package org.tron.core.dbstore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/tron/core/dbStore/ByteArrayWrapper.java b/src/main/java/org/tron/core/dbStore/ByteArrayWrapper.java index 510a6ef3ce8..4ccc94a7216 100644 --- a/src/main/java/org/tron/core/dbStore/ByteArrayWrapper.java +++ b/src/main/java/org/tron/core/dbStore/ByteArrayWrapper.java @@ -16,14 +16,13 @@ * along with the ethereumJ library. If not, see . */ -package org.tron.core.dbStore; +package org.tron.core.dbstore; -import org.spongycastle.util.encoders.Hex; -import org.tron.common.utils.FastByteComparisons; - 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 { diff --git a/src/main/java/org/tron/core/dbStore/UTXOStore.java b/src/main/java/org/tron/core/dbStore/UTXOStore.java index ec558ca4e58..31bc6977111 100644 --- a/src/main/java/org/tron/core/dbStore/UTXOStore.java +++ b/src/main/java/org/tron/core/dbStore/UTXOStore.java @@ -13,14 +13,13 @@ * along with this program. If not, see . */ -package org.tron.core.dbStore; +package org.tron.core.dbstore; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; -import java.util.Set; - public class UTXOStore { public static final Logger logger = LoggerFactory.getLogger("UTXOStore"); diff --git a/src/main/java/org/tron/core/manager/TronBlockLoader.java b/src/main/java/org/tron/core/manager/TronBlockLoader.java deleted file mode 100644 index f655e8ea997..00000000000 --- a/src/main/java/org/tron/core/manager/TronBlockLoader.java +++ /dev/null @@ -1,107 +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.core.manager; - -import java.io.FileInputStream; -import java.util.Scanner; -import java.util.function.Function; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.spongycastle.util.encoders.Hex; -import org.springframework.beans.factory.annotation.Autowired; -import org.tron.core.config.SystemProperties; -import org.tron.core.TransactionUtils; -import org.tron.core.TronBlockChainImpl; -import org.tron.protos.core.TronBlock; -import org.tron.protos.core.TronTransaction; -import org.tron.common.utils.ExecutorPipeline; - -public class TronBlockLoader { - - private static final Logger logger = LoggerFactory.getLogger("TronBlockLoader"); - @Autowired - SystemProperties config; - Scanner scanner = null; - ExecutorPipeline exce1; - ExecutorPipeline exce2; - @Autowired - private TronBlockChainImpl blockchain; - - public void loadBlocks() { - - exce1 = new ExecutorPipeline(8, 1000, true, - (Function) block -> { - if (block.getBlockHeader().getNumber() >= blockchain - .getBlockStoreInter().getBestBlock().getBlockHeader() - .getNumber()) { - for (TronTransaction.Transaction tx : block - .getTransactionsList()) { - TransactionUtils.getSender(tx); - - } - } - return block; - }, throwable -> logger.error("Unhandled exception: ", throwable)); - - exce2 = exce1.add(1, 1000, block -> { - try { - blockWork(block); - } catch (Exception e) { - e.printStackTrace(); - } - }); - - String fileSrc = config.blocksLoader(); - - try { - final String blocksFormat = config.getConfig().hasPath("blocks" + - ".format") ? config.getConfig().getString - ("blocks.format") : null; - System.out.println("Loading blocks: " + fileSrc + ", format: " + - blocksFormat); - - FileInputStream inputStream = new FileInputStream(fileSrc); - - scanner = new Scanner(inputStream, "UTF-8"); - - while (scanner.hasNext()) { - byte[] blockBytes = Hex.decode(scanner.nextLine()); - TronBlock.Block block = TronBlock.Block.parseFrom(blockBytes); - - exce1.push(block); - } - - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - - } - - private void blockWork(TronBlock.Block block) { - if (block.getBlockHeader().getNumber() >= blockchain.getBlockStoreInter() - .getBestBlock().getBlockHeader().getNumber() - || blockchain.getBlockStoreInter().getBlockByHash(block - .getBlockHeader().getHash().toByteArray()) == null) { - if (block.getBlockHeader().getNumber() > 0) { - throw new RuntimeException(); - } - } - } -} diff --git a/src/main/java/org/tron/core/net/message/BlockHeadersMessage.java b/src/main/java/org/tron/core/net/message/BlockHeadersMessage.java index 1c2895f8e4e..32dd8d36ecc 100644 --- a/src/main/java/org/tron/core/net/message/BlockHeadersMessage.java +++ b/src/main/java/org/tron/core/net/message/BlockHeadersMessage.java @@ -1,16 +1,21 @@ package org.tron.core.net.message; import com.google.protobuf.InvalidProtocolBufferException; +import org.tron.protos.Protocal.Items; +import org.tron.protos.Protocal.BlockHeader; + +import java.util.ArrayList; +import java.util.List; public class BlockHeadersMessage extends Message { - private org.tron.protos.core.Tron.BlockHeaders blockHeaders; + private List blockHeaders = new ArrayList<>(); public BlockHeadersMessage(byte[] packed) { super(packed); } - public BlockHeadersMessage(org.tron.protos.core.Tron.BlockHeaders blockHeaders) { + public BlockHeadersMessage(List blockHeaders) { this.blockHeaders = blockHeaders; unpacked = true; } @@ -31,10 +36,18 @@ public byte[] getData() { return data; } + public List getBlockHeaders() { + unPack(); + return blockHeaders; + } + private synchronized void unPack() { if (unpacked) return; try { - this.blockHeaders = org.tron.protos.core.Tron.BlockHeaders.parseFrom(data); + Items items = Items.parseFrom(data); + if (items.getType() == Items.ItemType.BLOCKHEADER) { + blockHeaders = items.getBlockHeadersList(); + } } catch (InvalidProtocolBufferException e) { logger.debug(e.getMessage()); } @@ -42,7 +55,10 @@ private synchronized void unPack() { } private void pack() { - this.data = this.blockHeaders.toByteArray(); + Items.Builder itemsBuilder = Items.newBuilder(); + itemsBuilder.setType(Items.ItemType.BLOCKHEADER); + itemsBuilder.addAllBlockHeaders(this.blockHeaders); + this.data = itemsBuilder.build().toByteArray(); } } diff --git a/src/main/java/org/tron/core/net/message/BlockMessage.java b/src/main/java/org/tron/core/net/message/BlockMessage.java index 66cf8bce3de..60f95ece06f 100644 --- a/src/main/java/org/tron/core/net/message/BlockMessage.java +++ b/src/main/java/org/tron/core/net/message/BlockMessage.java @@ -1,52 +1,62 @@ package org.tron.core.net.message; import com.google.protobuf.InvalidProtocolBufferException; -import org.tron.protos.core.TronBlock; +import org.tron.protos.Protocal.Block; + public class BlockMessage extends Message { - private TronBlock.Block block; + private Block block; - public BlockMessage(byte[] packed) { - super(packed); - } + public BlockMessage(byte[] packed) { + super(packed); + } - public BlockMessage(TronBlock.Block block) { - this.block = block; - unpacked = true; - } + public BlockMessage(Block block) { + this.block = block; + unpacked = true; + } - @Override - public MessageTypes getType() { - return MessageTypes.BLOCK; - } + @Override + public MessageTypes getType() { + return MessageTypes.BLOCK; + } - @Override - public String toString() { - return null; - } + @Override + public String toString() { + return null; + } - @Override - public byte[] getData() { - if(data == null) pack(); - return data; + @Override + public byte[] getData() { + if (data == null) { + pack(); } + return data; + } - private synchronized void unPack() { - if(unpacked) return; - - try { - this.block = TronBlock.Block.parseFrom(data); - } catch (InvalidProtocolBufferException e) { - logger.debug(e.getMessage()); - } + public Block getBlock() { + unPack(); + return block; + } - unpacked = true; + private synchronized void unPack() { + if (unpacked) { + return; } - private void pack() { - this.data = this.block.toByteArray(); + try { + this.block = Block.parseFrom(data); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage()); } + unpacked = true; + } + + private void pack() { + this.data = this.block.toByteArray(); + } + } diff --git a/src/main/java/org/tron/core/net/message/BlocksMessage.java b/src/main/java/org/tron/core/net/message/BlocksMessage.java index 74d33b70d68..b052e31b8f5 100644 --- a/src/main/java/org/tron/core/net/message/BlocksMessage.java +++ b/src/main/java/org/tron/core/net/message/BlocksMessage.java @@ -1,52 +1,66 @@ package org.tron.core.net.message; import com.google.protobuf.InvalidProtocolBufferException; +import java.util.List; +import org.tron.protos.Protocal.Block; +import org.tron.protos.Protocal.Items; -public class BlocksMessage extends Message{ +public class BlocksMessage extends Message { - private org.tron.protos.core.Tron.Blocks blocks; + private List blocks; - public BlocksMessage() { - super(); - } + public BlocksMessage() { + super(); + } - public BlocksMessage(byte[] packed) { - super(packed); - } + public BlocksMessage(byte[] packed) { + super(packed); + } - public BlocksMessage(org.tron.protos.core.Tron.Blocks blocks) { - this.blocks = blocks; - unpacked = true; - } + public BlocksMessage(List blocks) { + this.blocks = blocks; + unpacked = true; + } - @Override - public byte[] getData() { - return new byte[0]; - } + public List getBlocks() { + unPack(); + return blocks; + } - @Override - public String toString() { - return null; - } + @Override + public byte[] getData() { + return new byte[0]; + } - @Override - public MessageTypes getType() { - return MessageTypes.BLOCKS; - } - - private synchronized void unPack() { - if(unpacked) return; + @Override + public String toString() { + return null; + } - try { - this.blocks = org.tron.protos.core.Tron.Blocks.parseFrom(data); - } catch (InvalidProtocolBufferException e) { - logger.debug(e.getMessage()); - } + @Override + public MessageTypes getType() { + return MessageTypes.BLOCKS; + } - unpacked = true; + private synchronized void unPack() { + if (unpacked) { + return; } - - private void pack() { - this.data = this.blocks.toByteArray(); + try { + Items items = Items.parseFrom(data); + if (items.getType() == Items.ItemType.BLOCK) { + blocks = items.getBlocksList(); + } + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage()); } + unpacked = true; + } + + private void pack() { + Items.Builder itemsBuilder = Items.newBuilder(); + itemsBuilder.setType(Items.ItemType.BLOCK); + itemsBuilder.addAllBlocks(this.blocks); + this.data = itemsBuilder.build().toByteArray(); + } } diff --git a/src/main/java/org/tron/core/net/message/GetDataMessage.java b/src/main/java/org/tron/core/net/message/GetDataMessage.java deleted file mode 100644 index ee4f4fe3ae9..00000000000 --- a/src/main/java/org/tron/core/net/message/GetDataMessage.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.tron.core.net.message; - -public class GetDataMessage extends Message{ - public GetDataMessage() { - super(); - } - - - - public GetDataMessage(byte[] packed) { - super(packed); - } - - @Override - public byte[] getData() { - return new byte[0]; - } - - @Override - public String toString() { - return null; - } - - @Override - public MessageTypes getType() { - return null; - } -} diff --git a/src/main/java/org/tron/core/net/message/GetInvertoryItemsMessage.java b/src/main/java/org/tron/core/net/message/GetInvertoryItemsMessage.java deleted file mode 100644 index 056d57f7d8d..00000000000 --- a/src/main/java/org/tron/core/net/message/GetInvertoryItemsMessage.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.tron.core.net.message; - -import com.google.protobuf.InvalidProtocolBufferException; - - -public class GetInvertoryItemsMessage extends Message { - - private org.tron.protos.core.TronInventoryItems.InventoryItems items; - - public GetInvertoryItemsMessage() { - super(); - } - - public GetInvertoryItemsMessage(byte[] packed) { - super(packed); - } - - public GetInvertoryItemsMessage(org.tron.protos.core.TronInventoryItems.InventoryItems items) { - this.items = items; - unpacked = true; - } - - @Override - public byte[] getData() { - if(data == null) pack(); - return data; - } - - @Override - public String toString() { - return null; - } - - @Override - public MessageTypes getType() { - return MessageTypes.GETITEMS; - } - - private synchronized void unPack() { - if(unpacked) return; - - try { - this.items = org.tron.protos.core.TronInventoryItems.InventoryItems.parseFrom(data); - } catch (InvalidProtocolBufferException e) { - logger.debug(e.getMessage()); - } - - unpacked = true; - } - - private void pack() { - this.data = this.items.toByteArray(); - } -} diff --git a/src/main/java/org/tron/core/net/message/InvertoryMessage.java b/src/main/java/org/tron/core/net/message/InvertoryMessage.java new file mode 100644 index 00000000000..e0f6f5db328 --- /dev/null +++ b/src/main/java/org/tron/core/net/message/InvertoryMessage.java @@ -0,0 +1,60 @@ +package org.tron.core.net.message; + +import com.google.protobuf.InvalidProtocolBufferException; +import org.tron.protos.Protocal.Inventory; + + +public class InvertoryMessage extends Message { + + private Inventory inv; + + public InvertoryMessage(byte[] packed) { + super(packed); + } + + public InvertoryMessage(Inventory inv) { + this.inv = inv; + unpacked = true; + } + + @Override + public byte[] getData() { + if (data == null) { + pack(); + } + return data; + } + + @Override + public String toString() { + return null; + } + + @Override + public MessageTypes getType() { + return MessageTypes.INVENTORY; + } + + public Inventory getInventory() { + unPack(); + return inv; + } + + private synchronized void unPack() { + if (unpacked) { + return; + } + + try { + this.inv = Inventory.parseFrom(data); + } catch (InvalidProtocolBufferException e) { + logger.debug(e.getMessage()); + } + + unpacked = true; + } + + private void pack() { + this.data = this.inv.toByteArray(); + } +} diff --git a/src/main/java/org/tron/core/net/message/ItemNotFound.java b/src/main/java/org/tron/core/net/message/ItemNotFound.java new file mode 100644 index 00000000000..d173ef582dc --- /dev/null +++ b/src/main/java/org/tron/core/net/message/ItemNotFound.java @@ -0,0 +1,32 @@ +package org.tron.core.net.message; + +import org.tron.protos.Protocal; + +public class ItemNotFound extends Message { + + private org.tron.protos.Protocal.Items notFound; + + /** + * means can not find this block or trx. + */ + public ItemNotFound() { + Protocal.Items.Builder itemsBuilder = Protocal.Items.newBuilder(); + itemsBuilder.setType(Protocal.Items.ItemType.ERR); + notFound = itemsBuilder.build(); + } + + @Override + public byte[] getData() { + return notFound.toByteArray(); + } + + @Override + public String toString() { + return "item not found"; + } + + @Override + public MessageTypes getType() { + return MessageTypes.ITEM_NOT_FOUND; + } +} diff --git a/src/main/java/org/tron/core/net/message/Message.java b/src/main/java/org/tron/core/net/message/Message.java index 81ba6dc3578..26c5bf4c2d8 100644 --- a/src/main/java/org/tron/core/net/message/Message.java +++ b/src/main/java/org/tron/core/net/message/Message.java @@ -5,26 +5,26 @@ public abstract class Message { - protected static final Logger logger = LoggerFactory.getLogger("net"); + protected static final Logger logger = LoggerFactory.getLogger("net"); - protected boolean unpacked; - protected byte[] data; - protected byte type; + protected boolean unpacked; + protected byte[] data; + protected byte type; - public Message() { - } + public Message() { + } - public Message(byte[] packed) { - this.data = packed; - unpacked = false; - } + public Message(byte[] packed) { + this.data = packed; + unpacked = false; + } - public abstract byte[] getData(); + public abstract byte[] getData(); - public abstract String toString(); + public abstract String toString(); - //public byte getCode() { return type; } + //public byte getCode() { return type; } - public abstract MessageTypes getType(); + public abstract MessageTypes getType(); } diff --git a/src/main/java/org/tron/core/net/message/MessageFactory.java b/src/main/java/org/tron/core/net/message/MessageFactory.java index 999a5cd79fd..3626562c284 100644 --- a/src/main/java/org/tron/core/net/message/MessageFactory.java +++ b/src/main/java/org/tron/core/net/message/MessageFactory.java @@ -1,24 +1,33 @@ package org.tron.core.net.message; +/** + * msg factory. + */ public class MessageFactory { - public Message create(byte code, byte[] packed) { - MessageTypes receivedTypes = MessageTypes.fromByte(code); - switch (receivedTypes) { - case TRX: - return new TransationMessage(packed); - case TRXS: - return new TransationsMessage(packed); - case BLOCK: - return new BlockMessage(packed); - case BLOCKS: - return new BlocksMessage(packed); - case BLOCKHEADERS: - return new BlockHeadersMessage(packed); - case GETITEMS: - return new GetInvertoryItemsMessage(packed); - default: - throw new IllegalArgumentException("No such message"); - } + /** + * create msg. + * @param type msg type + * @param packed msg data + * @return + */ + public Message create(byte type, byte[] packed) { + MessageTypes receivedTypes = MessageTypes.fromByte(type); + switch (receivedTypes) { + case TRX: + return new TransactionMessage(packed); + case TRXS: + return new TransactionsMessage(packed); + case BLOCK: + return new BlockMessage(packed); + case BLOCKS: + return new BlocksMessage(packed); + case BLOCKHEADERS: + return new BlockHeadersMessage(packed); + case INVENTORY: + return new InvertoryMessage(packed); + default: + throw new IllegalArgumentException("No such message"); } + } } diff --git a/src/main/java/org/tron/core/net/message/MessageTypes.java b/src/main/java/org/tron/core/net/message/MessageTypes.java index 51122329905..d817cb8702a 100644 --- a/src/main/java/org/tron/core/net/message/MessageTypes.java +++ b/src/main/java/org/tron/core/net/message/MessageTypes.java @@ -5,66 +5,58 @@ public enum MessageTypes { - FIRST(0x00), - - TRX(0x01), - - BLOCK(0x02), - - TRXS(0x03), - - BLOCKS(0x04), - - BLOCKHEADERS(0x05), - - GETITEMS(0x06), - - LAST(0xFF); - -// trx_message_type = 1000, -// block_message_type = 1001, -// core_message_type_first = 5000, -// item_ids_inventory_message_type = 5001, -// blockchain_item_ids_inventory_message_type = 5002, -// fetch_blockchain_item_ids_message_type = 5003, -// fetch_items_message_type = 5004, -// item_not_available_message_type = 5005, -// hello_message_type = 5006, -// connection_accepted_message_type = 5007, -// connection_rejected_message_type = 5008, -// address_request_message_type = 5009, -// address_message_type = 5010, -// closing_connection_message_type = 5011, -// current_time_request_message_type = 5012, -// current_time_reply_message_type = 5013, -// check_firewall_message_type = 5014, -// check_firewall_reply_message_type = 5015, -// get_current_connections_request_message_type = 5016, -// get_current_connections_reply_message_type = 5017, -// core_message_type_last = 5099 - - private final int type; - - private static final Map intToTypeMap = new HashMap<>(); - - static { - for (MessageTypes type : MessageTypes.values()) { - intToTypeMap.put(type.type, type); - } - } + FIRST(0x00), - private MessageTypes(int type) { this.type = type;} + TRX(0x01), + BLOCK(0x02), - public static MessageTypes fromByte(byte i) { - return intToTypeMap.get((int) i); - } + TRXS(0x03), - public static boolean inRange(byte code) { - return code < LAST.asByte(); - } + BLOCKS(0x04), + + BLOCKHEADERS(0x05), + + INVENTORY(0x06), + + FETCH_BLOCKS(0x07), + + SYNC_BLOCK_CHAIN(0x08), + + ITEM_NOT_FOUND(0x09), + + FETCH_BLOCK_HEADERS(0x10), + + BLOCK_INVENTORY(0x11), - public byte asByte() { - return (byte) (type); + LAST(0xFF); + + private final int type; + + private static final Map intToTypeMap = new HashMap<>(); + + static { + for (MessageTypes type : MessageTypes.values()) { + intToTypeMap.put(type.type, type); } + } + + private MessageTypes(int type) { + this.type = type; + } + + + public static MessageTypes fromByte(byte i) { + return intToTypeMap.get((int) i); + } + + public static boolean inRange(byte code) { + return code < LAST.asByte(); + } + + public byte asByte() { + return (byte) (type); + } } + + diff --git a/src/main/java/org/tron/core/net/message/TransationMessage.java b/src/main/java/org/tron/core/net/message/TransationMessage.java deleted file mode 100644 index 3740bece081..00000000000 --- a/src/main/java/org/tron/core/net/message/TransationMessage.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.tron.core.net.message; - -import com.google.protobuf.InvalidProtocolBufferException; -import org.tron.protos.core.TronTransaction; - -public class TransationMessage extends Message{ - - private TronTransaction.Transaction trx; - - public TransationMessage(byte[] packed) { - super(packed); - } - - public TransationMessage(TronTransaction.Transaction trx) { - this.trx = trx; - unpacked = true; - } - - public TransationMessage(String msg) { - - } - - @Override - public MessageTypes getType() { - return MessageTypes.TRX; - } - - @Override - public String toString() { - return null; - } - - @Override - public byte[] getData() { - if(data == null) pack(); - return data; - } - - private synchronized void unPack() { - if(unpacked) return; - - try { - this.trx = TronTransaction.Transaction.parseFrom(data); - } catch (InvalidProtocolBufferException e) { - logger.debug(e.getMessage()); - } - - unpacked = true; - } - - private void pack() { - this.data = this.trx.toByteArray(); - } - -} diff --git a/src/main/java/org/tron/core/net/message/TransationsMessage.java b/src/main/java/org/tron/core/net/message/TransationsMessage.java deleted file mode 100644 index 0b179bbf799..00000000000 --- a/src/main/java/org/tron/core/net/message/TransationsMessage.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.tron.core.net.message; - -import com.google.protobuf.InvalidProtocolBufferException; - -public class TransationsMessage extends Message{ - - private org.tron.protos.core.Tron.Transactions trxs; - - public TransationsMessage() { - super(); - } - - public TransationsMessage(org.tron.protos.core.Tron.Transactions trx) { - this.trxs = trx; - unpacked = true; - } - - public TransationsMessage(byte[] packed) { - super(packed); - } - - @Override - public byte[] getData() { - if(data == null) pack(); - return data; - } - - @Override - public String toString() { - return null; - } - - @Override - public MessageTypes getType() { - return MessageTypes.TRXS; - } - - private void pack() { - this.data = this.trxs.toByteArray(); - } - - private synchronized void unPack() { - if(unpacked) return; - - try { - this.trxs = org.tron.protos.core.Tron.Transactions.parseFrom(data); - } catch (InvalidProtocolBufferException e) { - logger.debug(e.getMessage()); - } - - unpacked = true; - } -} diff --git a/src/main/java/org/tron/core/net/node/Node.java b/src/main/java/org/tron/core/net/node/Node.java index 991813dd70e..e3a4a91f6af 100644 --- a/src/main/java/org/tron/core/net/node/Node.java +++ b/src/main/java/org/tron/core/net/node/Node.java @@ -1,63 +1,16 @@ package org.tron.core.net.node; -import org.tron.common.overlay.gossip.LocalNode; -import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.Message; -import org.tron.core.net.message.MessageTypes; -import org.tron.core.net.message.TransationMessage; -import java.io.UnsupportedEncodingException; +public interface Node { -public class Node { + void setNodeDelegate(NodeDelegate nodeDel); - private NodeDelegate nodeDel; - private LocalNode localNode; + void broadcast(Message msg); - public void setNodeDelegate(NodeDelegate nodeDel) { - this.nodeDel = nodeDel; - } - - public Node() { - localNode = LocalNode.getInstance(); - } - - public void start() { - localNode.getGossipManager().registerSharedDataSubscriber((key, oldValue, newValue) -> { - byte[] newValueBytes = null; - try { - newValueBytes = newValue.toString().getBytes("ISO-8859-1"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - - recieve(key, newValueBytes); - }); - } - - public void recieve(String key, byte[] msgStr) { - switch (MessageTypes.valueOf(key)) { - case BLOCK: - handleBlock(new BlockMessage(msgStr)); - break; - case TRX: - handleTranscation(new TransationMessage(msgStr)); - break; - default: - throw new IllegalArgumentException("No such message"); - } - } - - public void broadcast(Message msg) { - localNode.broadcast(msg); - } - - private void handleBlock(BlockMessage msg) { - nodeDel.handleBlock(msg); - } - - private void handleTranscation(TransationMessage msg) { - nodeDel.handleTransation(msg); - } + void listenOn(String endPoint); + void connectToP2PNetWork(); + void syncFrom(byte[] myHeadBlockHash); } 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 6c6c7f9c61a..8aa6811688e 100644 --- a/src/main/java/org/tron/core/net/node/NodeDelegate.java +++ b/src/main/java/org/tron/core/net/node/NodeDelegate.java @@ -1,37 +1,34 @@ package org.tron.core.net.node; +import java.util.ArrayList; import org.tron.core.net.message.BlockMessage; import org.tron.core.net.message.Message; -import org.tron.core.net.message.TransationMessage; - -import java.util.ArrayList; +import org.tron.core.net.message.TransactionMessage; +import org.tron.protos.Protocal.Inventory; public interface NodeDelegate { - void reset(); - - void start(); + void handleBlock(BlockMessage blkMsg); - void stop(); + void handleTransation(TransactionMessage trxMsg); - void handleBlock(BlockMessage blkMsg); + boolean isIncludedBlock(byte[] hash); - void handleTransation(TransationMessage trxMsg); + Inventory getBlockIds(Inventory inv); - void handleMsg(Message msg); - boolean isIncludedBlock(int blkId); + ArrayList getBlockChainSynopsis(byte[] refPoint, int num); - ArrayList getBlockIds(ArrayList blockChainSynopsis); + Message getData(byte[] hash); - ArrayList getBlockChainSynopsis(int refPoint, int num); + void syncToCli(); - void sync(); + void getBlockNum(byte[] hash); - void getBlockNum(int blkId); + void getBlockTime(byte[] hash); - void getBlockTime(int blkId); + byte[] getHeadBlockId(); - void getHeadBlockId(); + boolean hasItem(byte[] hash); } 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 0d25ffbb34d..a16859d1e9c 100644 --- a/src/main/java/org/tron/core/net/node/NodeImpl.java +++ b/src/main/java/org/tron/core/net/node/NodeImpl.java @@ -1,127 +1,163 @@ package org.tron.core.net.node; -import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.ByteString; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.tron.core.BlockUtils; -import org.tron.core.TransactionUtils; -import org.tron.core.db.BlockStore; +import org.tron.common.overlay.node.GossipLocalNode; +import org.tron.common.utils.ExecutorLoop; +import org.tron.core.net.message.BlockInventoryMessage; import org.tron.core.net.message.BlockMessage; +import org.tron.core.net.message.FetchBlocksMessage; import org.tron.core.net.message.Message; -import org.tron.core.net.message.TransationMessage; -import org.tron.protos.core.TronBlock; -import org.tron.protos.core.TronTransaction; - -import java.util.ArrayList; - -public class NodeImpl implements NodeDelegate { - - private static final Logger logger = LoggerFactory.getLogger("NodeImpl"); - private Node p2pNode; - private BlockStore blockdb; - - // set seeds - @java.lang.Override - public void reset() { - p2pNode = new Node(); - p2pNode.setNodeDelegate(this); - } - - @java.lang.Override - public void start() { - // init database - logger.info("init database"); - blockdb = new BlockStore(); - blockdb.initBlockDbSource("database-test", "block"); - blockdb.initUnspendDbSource("database-test", "trx"); - - logger.info("reset p2p network"); - reset(); - - } - - @java.lang.Override - public void stop() { - - } - - @java.lang.Override - public void handleBlock(BlockMessage blkMsg) { - TronBlock.Block block = null; - try { - block = TronBlock.Block.parseFrom(blkMsg.getData()); - } catch (InvalidProtocolBufferException e) { - e.printStackTrace(); - } - System.out.println("handle block: "); - System.out.println(BlockUtils.toPrintString(block)); - } - - @java.lang.Override - public void handleTransation(TransationMessage trxMsg) { - TronTransaction.Transaction transaction = null; - try { - transaction = TronTransaction.Transaction.parseFrom(trxMsg.getData()); - } catch (InvalidProtocolBufferException e) { - e.printStackTrace(); - } - System.out.println("handle transaction: "); - System.out.println(TransactionUtils.toPrintString(transaction)); - } - - @java.lang.Override - public void handleMsg(Message msg) { - - } - - @java.lang.Override - public boolean isIncludedBlock(int blkId) { - return false; - } - - @java.lang.Override - public ArrayList getBlockIds(ArrayList blockChainSynopsis) { - return null; - } - - @java.lang.Override - public ArrayList getBlockChainSynopsis(int refPoint, int num) { - return null; - } - - @java.lang.Override - public void sync() { - - } - - @java.lang.Override - public void getBlockNum(int blkId) { - - } - - @java.lang.Override - public void getBlockTime(int blkId) { - - } - - @java.lang.Override - public void getHeadBlockId() { - - } - - public Node getP2pNode() { - return p2pNode; - } - - public void setP2pNode(Node p2pNode) { - this.p2pNode = p2pNode; - } - - public BlockStore getBlockdb() { - return blockdb; - } - - public void setBlockdb(BlockStore blockdb) { - this.blockdb = blockdb; - } +import org.tron.core.net.message.SyncBlockChainMessage; +import org.tron.core.net.message.TransactionMessage; +import org.tron.core.net.peer.PeerConnection; +import org.tron.protos.Protocal; + +public class NodeImpl extends PeerConnection implements Node { + + private static final Logger logger = LoggerFactory.getLogger("Node"); + + + private HashMap messageCache = new HashMap<>(); + + private List newInventory = new ArrayList<>(); + + private NodeDelegate del; + + private GossipLocalNode gossipNode = GossipLocalNode.getInstance(); + + //loop + ExecutorLoop loopAdvertiseBlock; + + ExecutorLoop loopAdvertiseTrx; + + ExecutorLoop loopSyncBlockChain; + + ExecutorLoop loopFetchBlocks; + + @Override + public void onMessage(PeerConnection peer, Message msg) { + switch (msg.getType()) { + case BLOCK: + onHandleBlockMessage((BlockMessage) msg); + break; + case TRX: + onHandleTranscationMessage((TransactionMessage) msg); + break; + case SYNC_BLOCK_CHAIN: + onHandleSycnBlockChainMessage((SyncBlockChainMessage) msg); + break; + case FETCH_BLOCKS: + onHandleFetchBlocksMessage((FetchBlocksMessage) msg); + break; + case BLOCK_INVENTORY: + onHandleBlockInventoryMssage((BlockInventoryMessage) msg); + break; + default: + throw new IllegalArgumentException("No such message"); + } + } + + @Override + public Message getMessage(byte[] itemHash) { + return messageCache.get(itemHash); + + } + + @Override + public void setNodeDelegate(NodeDelegate nodeDel) { + this.del = nodeDel; + } + + /** + * broadcast msg. + * + * @param msg msg to bradcast + */ + public void broadcast(Message msg) { + newInventory.add(msg); + messageCache.put(msg.getData(), msg); + } + + @Override + public void listenOn(String endPoint) { + return; + } + + @Override + public void connectToP2PNetWork() { + gossipNode.start(this); + loopAdvertiseBlock = new ExecutorLoop<>(8, 10, a -> { + gossipNode.broadcast(a); + return null; + }, throwable -> logger.error("Unhandled exception: ", throwable)); + + loopAdvertiseTrx = new ExecutorLoop<>(2, 100, b -> { + gossipNode.broadcast(b); + return null; + }, throwable -> logger.error("Unhandled exception: ", throwable)); + + loopFetchBlocks = new ExecutorLoop<>(2, 10, c -> { + gossipNode.sendMessage(c.getPeer(), c); + return null; + }, throwable -> logger.error("Unhandled exception: ", throwable)); + + loopSyncBlockChain = new ExecutorLoop<>(2, 10, d -> { + gossipNode.sendMessage(d.getPeer(), d); + return null; + }, throwable -> logger.error("Unhandled exception: ", throwable)); + } + + @Override + public void syncFrom(byte[] myHeadBlockHash) { + ArrayList hashList = del.getBlockChainSynopsis(myHeadBlockHash, 100); + + Protocal.Inventory.Builder invBuild = Protocal.Inventory.newBuilder(); + invBuild.setType(Protocal.Inventory.InventoryType.BLOCK); + int i = 0; + for (byte[] hash : + hashList) { + invBuild.setIds(i++, ByteString.copyFrom(hash, 0, 31)); + } + + if (gossipNode.getMembers().size() == 0) { + //todo: a loop here to wait the peers to sync blocks. + logger.debug("other peer is nil, please wait ... "); + return; + } + loopSyncBlockChain.push(new SyncBlockChainMessage(invBuild.build(), + gossipNode.getMembers().iterator().next())); + } + + private void onHandleBlockMessage(BlockMessage blkMsg) { + del.handleBlock(blkMsg); + } + + private void onHandleTranscationMessage(TransactionMessage trxMsg) { + del.handleTransation(trxMsg); + } + + private void onHandleSycnBlockChainMessage(SyncBlockChainMessage syncMsg) { + Protocal.Inventory inv = del.getBlockIds(syncMsg.getInventory()); + BlockInventoryMessage blkInvMsg = new BlockInventoryMessage(inv, syncMsg.getPeer()); + gossipNode.sendMessage(blkInvMsg.getPeer(), blkInvMsg); + } + + private void onHandleFetchBlocksMessage(FetchBlocksMessage fetchBlksMsg) { + Protocal.Inventory inv = fetchBlksMsg.getInventory(); + for (ByteString hash : + inv.getIdsList()) { + gossipNode.sendMessage(fetchBlksMsg.getPeer(), del.getData(hash.toByteArray())); + } + } + + private void onHandleBlockInventoryMssage(BlockInventoryMessage msg) { + Protocal.Inventory inv = del.getBlockIds(msg.getInventory()); + FetchBlocksMessage fetchMsg = new FetchBlocksMessage(inv, msg.getPeer()); + loopFetchBlocks.push(fetchMsg); + } } diff --git a/src/main/java/org/tron/core/peer/Peer.java b/src/main/java/org/tron/core/peer/Peer.java index 0da0bfa901d..d3412df54f4 100644 --- a/src/main/java/org/tron/core/peer/Peer.java +++ b/src/main/java/org/tron/core/peer/Peer.java @@ -17,18 +17,18 @@ import com.google.protobuf.InvalidProtocolBufferException; import org.tron.common.command.ConsensusCommand; -import org.tron.core.consensus.client.BlockchainClientListener; -import org.tron.core.consensus.client.Client; +import org.tron.common.crypto.ECKey; +import org.tron.common.overlay.Net; +import org.tron.common.utils.ByteArray; import org.tron.core.Blockchain; import org.tron.core.PendingStateImpl; import org.tron.core.TransactionUtils; import org.tron.core.UTXOSet; -import org.tron.common.crypto.ECKey; -import org.tron.common.overlay.Net; +import org.tron.core.Wallet; +import org.tron.core.consensus.client.BlockchainClientListener; +import org.tron.core.consensus.client.Client; import org.tron.protos.core.TronBlock; import org.tron.protos.core.TronTransaction; -import org.tron.common.utils.ByteArray; -import org.tron.core.Wallet; public class Peer { diff --git a/src/main/java/org/tron/core/peer/PeerBuilder.java b/src/main/java/org/tron/core/peer/PeerBuilder.java index bb0c259e0ed..7c149ab5754 100644 --- a/src/main/java/org/tron/core/peer/PeerBuilder.java +++ b/src/main/java/org/tron/core/peer/PeerBuilder.java @@ -15,16 +15,15 @@ package org.tron.core.peer; import javax.inject.Inject; - -import org.tron.core.consensus.client.Client; +import org.tron.common.crypto.ECKey; import org.tron.core.Blockchain; import org.tron.core.UTXOSet; -import org.tron.common.crypto.ECKey; import org.tron.core.Wallet; +import org.tron.core.consensus.client.Client; /** * Builds a peer - *

+ * * Set the key and type before calling build */ public class PeerBuilder { diff --git a/src/main/java/org/tron/core/peer/ValidationRuleFactory.java b/src/main/java/org/tron/core/peer/ValidationRuleFactory.java index c446fedf056..58091e83233 100644 --- a/src/main/java/org/tron/core/peer/ValidationRuleFactory.java +++ b/src/main/java/org/tron/core/peer/ValidationRuleFactory.java @@ -16,11 +16,12 @@ package org.tron.core.peer; public class ValidationRuleFactory { - public static ValidationRule create(String type) { - if (type.equals("Validation")) { - return null; - } - return null; + public static ValidationRule create(String type) { + if (type.equals("Validation")) { + return null; } + + return null; + } } diff --git a/src/main/java/org/tron/core/services/RpcApiService.java b/src/main/java/org/tron/core/services/RpcApiService.java index 1b0caf08bf4..6b30bd9ea64 100644 --- a/src/main/java/org/tron/core/services/RpcApiService.java +++ b/src/main/java/org/tron/core/services/RpcApiService.java @@ -1,62 +1,124 @@ package org.tron.core.services; +import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; + +import com.google.protobuf.ByteString; import io.grpc.Server; import io.grpc.ServerBuilder; import io.grpc.stub.StreamObserver; import org.tron.api.GrpcAPI; import org.tron.common.application.Application; import org.tron.common.application.Service; +import org.tron.core.Wallet; +import org.tron.protos.Protocal.Transaction; +import org.tron.protos.core.TronTransactionAndlockSript.TransactionAndlockSript; import java.io.IOException; import java.util.logging.Logger; public class RpcApiService implements Service { - private static final Logger logger = Logger.getLogger(RpcApiService.class.getName()); - private int port = 50051; - private Server ApiServer; + + private static final Logger logger = Logger.getLogger(RpcApiService.class.getName()); + private int port = 50051; + private Server ApiServer; + private Application app; + + public RpcApiService(Application app) { + this.app = app; + } + + @Override + public void init() { + + } + + @Override + public void start() { + try { + ApiServer = ServerBuilder.forPort(port) + .addService(new WalletApi(app)) + .build() + .start(); + } catch (IOException e) { + e.printStackTrace(); + } + + logger.info("Server started, listening on " + port); + + Runtime.getRuntime().addShutdownHook(new Thread() { + + @Override + public void run() { + + System.err.println("*** shutting down gRPC server since JVM is shutting down"); + //server.this.stop(); + System.err.println("*** server shut down"); + } + }); + } + + private class WalletApi extends org.tron.api.WalletGrpc.WalletImplBase { + private Application app; + private Wallet wallet; - public RpcApiService(Application app) { - this.app = app; + public WalletApi(Application app) { + this.app = app; + this.wallet = new Wallet(this.app); } @Override - public void start() { - try { - ApiServer = ServerBuilder.forPort(10086) - .addService(new WalletApi(app)) - .build() - .start(); - } catch (IOException e) { - e.printStackTrace(); - } - - logger.info("Server started, listening on "+ port); - - Runtime.getRuntime().addShutdownHook(new Thread(){ - - @Override - public void run(){ - - System.err.println("*** shutting down gRPC server since JVM is shutting down"); - //server.this.stop(); - System.err.println("*** server shut down"); - } - }); + public void getBalance(GrpcAPI.Account req, StreamObserver responseObserver) { + ByteString addressBS = req.getAddress(); + if ( addressBS != null ) { + byte[] addressBA = addressBS.toByteArray(); + long balance = wallet.getBalance(addressBA); + GrpcAPI.Account reply = GrpcAPI.Account.newBuilder().setBalance(balance).build(); + responseObserver.onNext(reply); + }else{ + responseObserver.onNext(null); + } + responseObserver.onCompleted(); } + @Override + public void createTransaction(GrpcAPI.Coin req, StreamObserver responseObserver) { + ByteString fromBS = req.getFrom(); + ByteString toBS = req.getFrom(); + long amount = req.getAmount(); + if ( fromBS != null && toBS != null && amount > 0 ) { + byte[] fromBA = fromBS.toByteArray(); + String toBA = toBS.toString(); - private class WalletApi extends org.tron.api.WalletGrpc.WalletImplBase { - private Application app; - public WalletApi(Application app) { - this.app = app; - } - @Override - public void getBalance(GrpcAPI.Balance req, StreamObserver responseObserver){ - - } + Transaction trx = wallet.createTransaction(fromBA, toBA, amount); + responseObserver.onNext(trx); + } + else { + responseObserver.onNext(null); + } + responseObserver.onCompleted(); } + @Override - public void stop() { + public void broadcastTransaction(Transaction req, StreamObserver responseObserver) { + boolean ret = wallet.broadcastTransaction(req); + GrpcAPI.Return retur = GrpcAPI.Return.newBuilder().setResult(ret).build(); + responseObserver.onNext(retur); + responseObserver.onCompleted(); + } + } + + @Override + public void stop() { + + } + public void blockUntilShutdown() { + if (ApiServer != null) { + try { + ApiServer.awaitTermination(); + } catch (InterruptedException e) { + e.printStackTrace(); + } } + } } diff --git a/src/main/java/org/tron/core/services/WitnessService.java b/src/main/java/org/tron/core/services/WitnessService.java index 87dc912701b..dc7deebe246 100644 --- a/src/main/java/org/tron/core/services/WitnessService.java +++ b/src/main/java/org/tron/core/services/WitnessService.java @@ -4,6 +4,11 @@ public class WitnessService implements Service { + @Override + public void init() { + + } + @Override public void start() { GereateBlockLoop loop = new GereateBlockLoop(); diff --git a/src/main/java/org/tron/program/FullNode.java b/src/main/java/org/tron/program/FullNode.java index 94ce123ae32..5761ea8b673 100644 --- a/src/main/java/org/tron/program/FullNode.java +++ b/src/main/java/org/tron/program/FullNode.java @@ -2,17 +2,21 @@ import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; -import org.tron.core.net.node.Node; import org.tron.core.services.RpcApiService; import org.tron.core.services.WitnessService; public class FullNode { public static void main(String args[]) { Application tApp = ApplicationFactory.create(); - tApp.addService(new RpcApiService(tApp)); + tApp.init("/configPath", new Args()); + + RpcApiService rpcApiService = new RpcApiService(tApp); + tApp.addService(rpcApiService); tApp.addService(new WitnessService()); - tApp.run(); + + tApp.startServies(); + tApp.startup(); + + rpcApiService.blockUntilShutdown(); } } diff --git a/src/main/java/org/tron/program/example/GossipNode.java b/src/main/java/org/tron/program/example/GossipNode.java index 5a956bd7933..580376102aa 100644 --- a/src/main/java/org/tron/program/example/GossipNode.java +++ b/src/main/java/org/tron/program/example/GossipNode.java @@ -14,70 +14,50 @@ */ package org.tron.program.example; -import org.apache.gossip.LocalMember; -import org.tron.common.overlay.gossip.LocalNode; - -import java.util.List; +import io.scalecube.cluster.Member; +import io.scalecube.transport.Message; +import java.util.Collection; import java.util.Scanner; +import org.tron.common.overlay.node.GossipLocalNode; public class GossipNode { - private static LocalNode localNode = LocalNode.getInstance(); - - public static void main(String[] args) { - localNode.getGossipManager().registerSharedDataSubscriber((key, oldValue, newValue) -> { - System.out.println("new message: " + newValue); - }); - - Scanner scanner = new Scanner(System.in); - System.out.println("enter your message:"); - while (true) { - String v = scanner.nextLine(); - - String[] inputStrings = v.trim().split("\\s+", 2); - - switch (inputStrings[0]) { - case "send": - if (inputStrings.length > 1) { - } - break; - case "live": - printLiveMembers(); - break; - case "dead": - printDeadMembers(); - break; - default: - break; - } - - } - } - - public static void printLiveMembers() { - List memberList = localNode.getLiveMembers(); - - if (memberList.isEmpty()) { - System.out.println("live none"); - return; - } - - for (LocalMember member : - memberList) { - System.out.println(member); - } - } - - public static void printDeadMembers() { - List memberList = localNode.getDeadMembers(); - if (memberList.isEmpty()) { - System.out.println("dead none"); - return; - } + private static GossipLocalNode localNode = GossipLocalNode.getInstance(); + + public static void main(String[] args) { + localNode.getCluster().listen().subscribe(msg -> { + System.out.println(msg); + }); + + Scanner scanner = new Scanner(System.in); + System.out.println("enter your message:"); + while (true) { + String v = scanner.nextLine(); + + String[] inputStrings = v.trim().split("\\s+", 2); + + switch (inputStrings[0]) { + case "send": + if (inputStrings.length > 1) { + localNode.getCluster().otherMembers().forEach(member -> { + localNode.getCluster().send(member, Message.fromData(inputStrings[1])); + }); + } + break; + case "members": + Collection memberList = localNode.getMembers(); + for (Member m : memberList) { + System.out.println(m); + } + break; + case "shutdown": + localNode.getCluster().shutdown(); + System.exit(0); + break; + default: + break; + } - for (LocalMember member : - memberList) { - System.out.println(member); - } } + } } diff --git a/src/main/java/org/tron/program/example/Tron.java b/src/main/java/org/tron/program/example/Tron.java index 9ceace8dacf..3b47a949d4f 100644 --- a/src/main/java/org/tron/program/example/Tron.java +++ b/src/main/java/org/tron/program/example/Tron.java @@ -17,14 +17,11 @@ import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; -import org.tron.common.application.ApplicationFactory; -import org.tron.common.application.CliApplication; -import org.tron.common.command.Cli; -import org.tron.core.config.Configer; -import org.tron.core.consensus.server.Server; +import org.tron.common.application.ApplicationImpl; +import org.tron.common.application.Application; import org.tron.core.peer.Peer; -import org.tron.core.peer.PeerBuilder; import org.tron.core.peer.PeerType; +import org.tron.program.Args; public class Tron { @@ -48,20 +45,25 @@ public static Peer getPeer() { public void run() { - CliApplication app = new ApplicationFactory() - .buildCli(); +// CliApplication app = new ApplicationFactory() +// .buildCli(); + Application app = new ApplicationImpl(); + app.initServices(new Args()); + app.startServies(); + app.startup(); - app.addService(new Server()); - app.run(); +// app.(new Server()); +// app. +// app.r - Peer peer = app.getInjector().getInstance(PeerBuilder.class) - .setKey(Configer.getMyKey()) - .setType(type) - .build(); +// Peer peer = app.getInjector().getInstance(PeerBuilder.class) +// .setKey(Configer.getMyKey()) +// .setType(type) +// .build(); - app.setPeer(peer); + // app.setPeer(peer); - Cli cli = new Cli(); - cli.run(app); +// Cli cli = new Cli(); +// cli.run(app); } } diff --git a/src/main/proto/api/api.proto b/src/main/proto/api/api.proto index 01476c9d63e..817928a51fd 100644 --- a/src/main/proto/api/api.proto +++ b/src/main/proto/api/api.proto @@ -1,20 +1,25 @@ syntax = "proto3"; -package proto; +package protocal; +import "core/Tron.proto"; + option java_package = "org.tron.api"; //Specify the name of the package that generated the Java file option java_outer_classname = "GrpcAPI"; //Specify the class name of the generated Java file -// just a example service Wallet { - // get account balance - rpc GetBalance (Balance) returns (Balance) {}; - // rpc GetBalance2 () returns (Balance) -}; -message Balance { - int32 balance = 1; + rpc GetBalance (Account) returns (Account) {}; + rpc CreateTransaction(Coin) returns (Transaction) {}; + rpc BroadcastTransaction(Transaction) returns (Return) {}; }; -// end just a example - - - - +message Return { + bool result = 1; +} +message Coin { + bytes from = 1; + bytes to = 2; + int64 amount = 3; +}; +message Account { + int64 balance = 1; + bytes address = 2; +}; \ No newline at end of file diff --git a/src/main/proto/core/Tron.proto b/src/main/proto/core/Tron.proto index f93fe6e03ae..f71ac2388ac 100644 --- a/src/main/proto/core/Tron.proto +++ b/src/main/proto/core/Tron.proto @@ -1,22 +1,65 @@ syntax = "proto3"; -package protos; +package protocal; -import "core/TronTransaction.proto"; -import "core/TronBlockHeader.proto"; -import "core/TronBlock.proto"; +option java_package = "org.tron.protos"; //Specify the name of the package that generated the Java file +option java_outer_classname = "Protocal"; //Specify the class name of the generated Java file -option java_package = "org.tron.protos.core"; //Specify the name of the package that generated the Java file -option java_outer_classname = "Tron"; //Specify the class name of the generated Java file -message Blocks { - repeated Block blocks = 1; +message Transaction { + message TXOutput { + int64 value = 1; + bytes pubKeyHash = 2; + } + + message TXInput { + bytes txID = 1; + int64 vout = 2; + bytes signature = 3; + bytes pubKey = 4; + } + + bytes id = 1; + repeated TXInput vin = 2; + repeated TXOutput vout = 3; } -message BlockHeaders { - repeated BlockHeader blockHeaders = 1; +message BlockHeader{ + int64 timestamp = 1; + bytes txTrieRoot = 2; + bytes parentHash = 3; + bytes hash = 4; + bytes nonce = 5; + bytes difficulty = 6; + int64 number = 7; } -message Transactions { +message Block { repeated Transaction transactions = 1; + BlockHeader blockHeader = 2; +} + +message Inventory { + enum InventoryType //枚举消息类型 + { + TRX = 0; + BLOCK = 1; + } + InventoryType type = 1; + repeated bytes ids = 2; +} + +message Items { + enum ItemType //枚举消息类型 + { + ERR= 0; //proto3版本中,首成员必须为0,成员不应有相同的值 + TRX = 1; + BLOCK = 2; + BLOCKHEADER = 3; + } + + ItemType type = 1; + repeated Block blocks = 2; + repeated BlockHeader blockHeaders = 3; + repeated Transaction transactions = 4; } \ No newline at end of file diff --git a/src/main/proto/core/TronBlock.proto b/src/main/proto/core/TronBlock.proto deleted file mode 100644 index 00f0fadbd48..00000000000 --- a/src/main/proto/core/TronBlock.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package protos; - -import "core/TronTransaction.proto"; -import "core/TronBlockHeader.proto"; - -option java_package = "org.tron.protos.core"; //Specify the name of the package that generated the Java file -option java_outer_classname = "TronBlock"; //Specify the class name of the generated Java file - -message Block { - repeated Transaction transactions = 1; - BlockHeader blockHeader = 2; -} \ No newline at end of file diff --git a/src/main/proto/core/TronBlockHeader.proto b/src/main/proto/core/TronBlockHeader.proto deleted file mode 100644 index cfd059cc64c..00000000000 --- a/src/main/proto/core/TronBlockHeader.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package protos; - -option java_package = "org.tron.protos.core"; //Specify the name of the package that generated the Java file -option java_outer_classname = "TronBlockHeader"; //Specify the class name of the generated Java file - -message BlockHeader{ - int64 timestamp = 1; - bytes txTrieRoot = 2; - bytes parentHash = 3; - bytes hash = 4; - bytes nonce = 5; - bytes difficulty = 6; - int64 number = 7; -} \ No newline at end of file diff --git a/src/main/proto/core/TronInventoryItems.proto b/src/main/proto/core/TronInventoryItems.proto deleted file mode 100644 index 64bef6f2f85..00000000000 --- a/src/main/proto/core/TronInventoryItems.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package protos; - -import "core/TronTransaction.proto"; -import "core/TronBlockHeader.proto"; - -option java_package = "org.tron.protos.core"; //Specify the name of the package that generated the Java file -option java_outer_classname = "TronInventoryItems"; //Specify the class name of the generated Java file - -message InventoryItems { - int32 type = 1; - repeated bytes items = 2; -} \ No newline at end of file diff --git a/src/main/proto/core/TronTXInput.proto b/src/main/proto/core/TronTXInput.proto deleted file mode 100644 index f98187ace90..00000000000 --- a/src/main/proto/core/TronTXInput.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package protos; - -option java_package = "org.tron.protos.core"; //Specify the name of the package that generated the Java file -option java_outer_classname = "TronTXInput"; //Specify the class name of the generated Java file - -message TXInput { - bytes txID = 1; - int64 vout = 2; - bytes signature = 3; - bytes pubKey = 4; -} \ No newline at end of file diff --git a/src/main/proto/core/TronTXOutput.proto b/src/main/proto/core/TronTXOutput.proto deleted file mode 100644 index 6521e4adb20..00000000000 --- a/src/main/proto/core/TronTXOutput.proto +++ /dev/null @@ -1,11 +0,0 @@ -syntax = "proto3"; - -package protos; - -option java_package = "org.tron.protos.core"; //Specify the name of the package that generated the Java file -option java_outer_classname = "TronTXOutput"; //Specify the class name of the generated Java file - -message TXOutput { - int64 value = 1; - bytes pubKeyHash = 2; -} \ No newline at end of file diff --git a/src/main/proto/core/TronTXOutputs.proto b/src/main/proto/core/TronTXOutputs.proto deleted file mode 100644 index 01b57168239..00000000000 --- a/src/main/proto/core/TronTXOutputs.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; - -package protos; - -import "core/TronTXOutput.proto"; - -option java_package = "org.tron.protos.core"; //Specify the name of the package that generated the Java file -option java_outer_classname = "TronTXOutputs"; //Specify the class name of the generated Java file - -message TXOutputs { - repeated TXOutput outputs = 1; -} \ No newline at end of file diff --git a/src/main/proto/core/TronTransaction.proto b/src/main/proto/core/TronTransaction.proto deleted file mode 100644 index 66f525e062d..00000000000 --- a/src/main/proto/core/TronTransaction.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package protos; - -import "core/TronTXInput.proto"; -import "core/TronTXOutput.proto"; - -option java_package = "org.tron.protos.core"; //Specify the name of the package that generated the Java file -option java_outer_classname = "TronTransaction"; //Specify the class name of the generated Java file - -message Transaction { - bytes id = 1; - repeated TXInput vin = 2; - repeated TXOutput vout = 3; -} \ No newline at end of file diff --git a/src/main/resources/seed.json b/src/main/resources/seed.json index 9c1eeaa2564..8596f983098 100644 --- a/src/main/resources/seed.json +++ b/src/main/resources/seed.json @@ -1,8 +1,8 @@ { "seedNodes": [ - { - "id": "127.0.0.1:10000", - "uri": "udp://127.0.0.1:10000" - } + // { + // "ip": "127.0.0.1", + // "port": 7080 + // } ] } diff --git a/src/main/resources/tron.conf b/src/main/resources/tron.conf index 346f680fdd1..8946905466e 100644 --- a/src/main/resources/tron.conf +++ b/src/main/resources/tron.conf @@ -1,23 +1,21 @@ -# levelDB -leveldb { - directory = "tron-data" - utxodir = "tron-utxo-data" - -} - -# database directory -database { - directory = "database" -} - -# overlay -overlay { - cluster = "mycluster" - ip = "127.0.0.1" - port = ":10000" -} - -# seed node -seed { - directory = "seed.json" +# levelDB +leveldb { + directory = "tron-data" + utxodir = "tron-utxo-data" + +} + +# database directory +database { + directory = "database" +} + +# overlay +overlay { + port = 7080 +} + +# seed node +seed { + directory = "seed.json" } \ No newline at end of file diff --git a/src/test/java/org/tron/command/CliTest.java b/src/test/java/org/tron/command/CliTest.java index 8bfbb44505d..e64cd5aac99 100644 --- a/src/test/java/org/tron/command/CliTest.java +++ b/src/test/java/org/tron/command/CliTest.java @@ -19,11 +19,12 @@ import org.slf4j.LoggerFactory; public class CliTest { + private static final Logger logger = LoggerFactory.getLogger("Test"); -// @Test -// public void testCli() { -// Cli cli = new Cli(); -// cli.run(Peer.getInstance(Peer.PEER_NORMAL)); -// } + // @Test + // public void testCli() { + // Cli cli = new Cli(); + // cli.run(Peer.getInstance(Peer.PEER_NORMAL)); + // } } diff --git a/src/test/java/org/tron/config/ConfigerTest.java b/src/test/java/org/tron/config/ConfigerTest.java index 13806d00444..beb6cd55f08 100644 --- a/src/test/java/org/tron/config/ConfigerTest.java +++ b/src/test/java/org/tron/config/ConfigerTest.java @@ -23,12 +23,13 @@ import org.tron.core.config.Configer; public class ConfigerTest { - private static final Logger logger = LoggerFactory.getLogger("Test"); - @Test - public void testGetECKey() { - ECKey key = Configer.getMyKey(); + private static final Logger logger = LoggerFactory.getLogger("Test"); - logger.info("address = {}", ByteArray.toHexString(key.getAddress())); - } + @Test + public void testGetECKey() { + ECKey key = Configer.getMyKey(); + + logger.info("address = {}", ByteArray.toHexString(key.getAddress())); + } } diff --git a/src/test/java/org/tron/consensus/client/ClientTest.java b/src/test/java/org/tron/consensus/client/ClientTest.java index d1bbe21aecc..901f50c7498 100644 --- a/src/test/java/org/tron/consensus/client/ClientTest.java +++ b/src/test/java/org/tron/consensus/client/ClientTest.java @@ -18,64 +18,64 @@ import io.atomix.catalyst.transport.Address; import io.atomix.catalyst.transport.netty.NettyTransport; import io.atomix.copycat.client.CopycatClient; -import org.tron.core.consensus.common.GetQuery; -import org.tron.core.consensus.common.PutCommand; - import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collection; import java.util.concurrent.CompletableFuture; +import org.tron.core.consensus.common.GetQuery; +import org.tron.core.consensus.common.PutCommand; public class ClientTest { - public static void main(String[] args) { - CopycatClient.Builder builder = CopycatClient.builder(); - builder.withTransport(NettyTransport.builder() - .withThreads(2) - .build()); + public static void main(String[] args) { + CopycatClient.Builder builder = CopycatClient.builder(); + + builder.withTransport(NettyTransport.builder() + .withThreads(2) + .build()); - CopycatClient client = builder.build(); + CopycatClient client = builder.build(); - client.serializer().register(PutCommand.class); - client.serializer().register(GetQuery.class); + client.serializer().register(PutCommand.class); + client.serializer().register(GetQuery.class); - InetAddress localhost = null; - try { - localhost = InetAddress.getLocalHost(); - System.out.println(localhost); - Collection

cluster = Arrays.asList( - new Address(localhost.getHostAddress(), 5000) - ); - CompletableFuture future = client.connect(cluster); - future.join(); - } catch (UnknownHostException e) { - e.printStackTrace(); + InetAddress localhost = null; + try { + localhost = InetAddress.getLocalHost(); + System.out.println(localhost); + Collection
cluster = Arrays.asList( + new Address(localhost.getHostAddress(), 5000) + ); + CompletableFuture future = client.connect(cluster); + future.join(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + client.submit(new GetQuery("block")).thenAccept(result1 -> { + System.out.println("foo is: " + result1.toString()); + }); + int i = 1; + //客户端提交查询 + boolean f = true; + while (f) { + String key = "block" + i; + Object result = client.submit(new GetQuery(key)).join(); + try { + if (!(result == null)) { + System.out.println("空指针异常没有发生,为null"); + System.out.println("Consensus " + key + " is: " + result); + f = true; + i = i + 1; + } else { + f = false; } - client.submit(new GetQuery("block")).thenAccept(result1 -> { - System.out.println("foo is: " + result1.toString()); - }); - int i = 1; - //客户端提交查询 - boolean f = true; - while (f) { - String key = "block" + i; - Object result = client.submit(new GetQuery(key)).join(); - try { - if (!(result == null)) { - System.out.println("空指针异常没有发生,为null"); - System.out.println("Consensus " + key + " is: " + result); - f = true; - i = i + 1; - } else { - f = false; - } - } catch (NullPointerException e) { - System.out.println("object == null不会导致空指针异常发生"); - f = false; - } + } catch (NullPointerException e) { + System.out.println("object == null不会导致空指针异常发生"); + f = false; + } - } } + } } diff --git a/src/test/java/org/tron/core/BlockUtilsTest.java b/src/test/java/org/tron/core/BlockUtilsTest.java index ed73a92cce0..d824a25e607 100644 --- a/src/test/java/org/tron/core/BlockUtilsTest.java +++ b/src/test/java/org/tron/core/BlockUtilsTest.java @@ -15,101 +15,102 @@ package org.tron.core; +import static org.tron.core.Blockchain.GENESIS_COINBASE_DATA; + import com.google.protobuf.ByteString; import org.junit.Test; import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.tron.protos.core.TronBlock.Block; -import org.tron.protos.core.TronTransaction.Transaction; import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; import org.tron.common.utils.ByteArray; - -import static org.tron.core.Blockchain.GENESIS_COINBASE_DATA; +import org.tron.protos.core.TronBlock.Block; +import org.tron.protos.core.TronTransaction.Transaction; public class BlockUtilsTest { - private static final Logger logger = LoggerFactory.getLogger("Test"); - - @Test - public void testNewBlock() { - ByteString parentHash = ByteString.copyFrom(ByteArray.fromHexString - ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85")); - ByteString difficulty = ByteString.copyFrom(ByteArray.fromHexString - ("2001")); - Block block = BlockUtils.newBlock(null, parentHash, difficulty, 0); - - logger.info("test new block: {}", BlockUtils.toPrintString(block)); - } - - @Test - public void testNewGenesisBlock() { - Transaction coinbase = TransactionUtils.newCoinbaseTransaction - ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, - 0); - Block genesisBlock = BlockUtils.newGenesisBlock(coinbase); - - logger.info("test new genesis block: {}", BlockUtils.toPrintString - (genesisBlock)); - } - - @Test - public void testPrepareData() { - Transaction coinbase = TransactionUtils.newCoinbaseTransaction - ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, - 0); - logger.info("test prepare data: {}", - "12580a2015f3988aa8d56eab3bfca45144bad77fc60acce50437a0a9d794a03a83c15c5e120e10ffffffffffffffffff012201001a24080a12200304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b8532022001" - .equals(ByteArray - .toHexString(BlockUtils.prepareData(BlockUtils.newGenesisBlock(coinbase))))); - } - - @Test - public void testIsValidate() { - Transaction coinbase = TransactionUtils.newCoinbaseTransaction - ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, - 0); - Block genesisBlock = BlockUtils.newGenesisBlock(coinbase); - logger.info("nonce: {}", ByteArray.toHexString(genesisBlock.getBlockHeader().getNonce - ().toByteArray())); - } - - @Test - public void testToPrintString() { - Transaction coinbase = TransactionUtils.newCoinbaseTransaction - ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, - 0); - logger.info("test to print string: {}", BlockUtils.toPrintString - (BlockUtils.newGenesisBlock(coinbase))); - } - - @Test - public void testGetMineValue() { - Transaction coinbase = TransactionUtils.newCoinbaseTransaction - ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, - 0); - logger.info("test get mine value: {}", ByteArray.toHexString - (BlockUtils.getMineValue(BlockUtils.newGenesisBlock(coinbase) - ))); - } - - @Test - public void testGetPowBoundary() { - Transaction coinbase = TransactionUtils.newCoinbaseTransaction - ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, - 0); - logger.info("test get pow boundary: {}", ByteArray.toHexString - (BlockUtils.getPowBoundary(BlockUtils.newGenesisBlock - (coinbase)))); - } - - @Test - public void testGetIncreaseNumber() { - LevelDbDataSourceImpl mockDb = Mockito.mock(LevelDbDataSourceImpl.class); - - Blockchain mockBlockchain = Mockito.mock(Blockchain.class); - Mockito.when(mockBlockchain.getBlockDB()).thenReturn(mockDb); - - logger.info("test getData increase number: {}", BlockUtils - .getIncreaseNumber(mockBlockchain)); - } + + private static final Logger logger = LoggerFactory.getLogger("Test"); + + @Test + public void testNewBlock() { + ByteString parentHash = ByteString.copyFrom(ByteArray.fromHexString + ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85")); + ByteString difficulty = ByteString.copyFrom(ByteArray.fromHexString + ("2001")); + Block block = BlockUtils.newBlock(null, parentHash, difficulty, 0); + + logger.info("test new block: {}", BlockUtils.toPrintString(block)); + } + + @Test + public void testNewGenesisBlock() { + Transaction coinbase = TransactionUtils.newCoinbaseTransaction + ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, + 0); + Block genesisBlock = BlockUtils.newGenesisBlock(coinbase); + + logger.info("test new genesis block: {}", BlockUtils.toPrintString + (genesisBlock)); + } + + @Test + public void testPrepareData() { + Transaction coinbase = TransactionUtils.newCoinbaseTransaction + ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, + 0); + logger.info("test prepare data: {}", + "12580a2015f3988aa8d56eab3bfca45144bad77fc60acce50437a0a9d794a03a83c15c5e120e10ffffffffffffffffff012201001a24080a12200304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b8532022001" + .equals(ByteArray + .toHexString(BlockUtils.prepareData(BlockUtils.newGenesisBlock(coinbase))))); + } + + @Test + public void testIsValidate() { + Transaction coinbase = TransactionUtils.newCoinbaseTransaction + ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, + 0); + Block genesisBlock = BlockUtils.newGenesisBlock(coinbase); + logger.info("nonce: {}", ByteArray.toHexString(genesisBlock.getBlockHeader().getNonce + ().toByteArray())); + } + + @Test + public void testToPrintString() { + Transaction coinbase = TransactionUtils.newCoinbaseTransaction + ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, + 0); + logger.info("test to print string: {}", BlockUtils.toPrintString + (BlockUtils.newGenesisBlock(coinbase))); + } + + @Test + public void testGetMineValue() { + Transaction coinbase = TransactionUtils.newCoinbaseTransaction + ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, + 0); + logger.info("test get mine value: {}", ByteArray.toHexString + (BlockUtils.getMineValue(BlockUtils.newGenesisBlock(coinbase) + ))); + } + + @Test + public void testGetPowBoundary() { + Transaction coinbase = TransactionUtils.newCoinbaseTransaction + ("0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b85", GENESIS_COINBASE_DATA, + 0); + logger.info("test get pow boundary: {}", ByteArray.toHexString + (BlockUtils.getPowBoundary(BlockUtils.newGenesisBlock + (coinbase)))); + } + + @Test + public void testGetIncreaseNumber() { + LevelDbDataSourceImpl mockDb = Mockito.mock(LevelDbDataSourceImpl.class); + + Blockchain mockBlockchain = Mockito.mock(Blockchain.class); + Mockito.when(mockBlockchain.getBlockDB()).thenReturn(mockDb); + + logger.info("test getData increase number: {}", BlockUtils + .getIncreaseNumber(mockBlockchain)); + } } diff --git a/src/test/java/org/tron/core/BlockchainTest.java b/src/test/java/org/tron/core/BlockchainTest.java index 2fae801bd9d..ef88e5cd06d 100644 --- a/src/test/java/org/tron/core/BlockchainTest.java +++ b/src/test/java/org/tron/core/BlockchainTest.java @@ -30,13 +30,14 @@ import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; +import org.tron.common.utils.ByteArray; import org.tron.protos.core.TronBlock.Block; import org.tron.protos.core.TronTXOutputs; import org.tron.protos.core.TronTransaction.Transaction; -import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; -import org.tron.common.utils.ByteArray; public class BlockchainTest { + private static final Logger logger = LoggerFactory.getLogger("Test"); private static Blockchain blockchain; private static LevelDbDataSourceImpl mockBlockDB; @@ -77,13 +78,13 @@ public void testBlockchainNew() { } } - @Test - public void testFindTransaction() { - Transaction transaction = blockchain.findTransaction(ByteString - .copyFrom(ByteArray.fromHexString - ("15f3988aa8d56eab3bfca45144bad77fc60acce50437a0a9d794a03a83c15c5e"))); - logger.info("{}", TransactionUtils.toPrintString(transaction)); - } + @Test + public void testFindTransaction() { + Transaction transaction = blockchain.findTransaction(ByteString + .copyFrom(ByteArray.fromHexString + ("15f3988aa8d56eab3bfca45144bad77fc60acce50437a0a9d794a03a83c15c5e"))); + logger.info("{}", TransactionUtils.toPrintString(transaction)); + } @Test public void testFindUTXO() { @@ -102,8 +103,8 @@ public void testFindUTXO() { List transactions = new ArrayList<>(); transactions.add(transaction); blockchain.addBlock(BlockUtils.newBlock(transactions, ByteString - .copyFrom(new byte[] {1}), ByteString - .copyFrom(new byte[] {1}), 1)); + .copyFrom(new byte[]{1}), ByteString + .copyFrom(new byte[]{1}), 1)); HashMap utxo = blockchain.findUTXO(); } diff --git a/src/test/java/org/tron/core/dbStore/BlockStoresTest.java b/src/test/java/org/tron/core/dbStore/BlockStoresTest.java index c1a702f67d1..20c5c29360e 100644 --- a/src/test/java/org/tron/core/dbStore/BlockStoresTest.java +++ b/src/test/java/org/tron/core/dbStore/BlockStoresTest.java @@ -13,14 +13,14 @@ * along with this program. If not, see . */ -package org.tron.core.dbStore; +package org.tron.core.dbstore; + +import static org.tron.core.Constant.BLOCK_DB_NAME; import org.junit.Ignore; import org.junit.Test; -import org.tron.core.Constant; import org.tron.common.utils.ByteArray; - -import static org.tron.core.Constant.BLOCK_DB_NAME; +import org.tron.core.Constant; @Ignore public class BlockStoresTest { diff --git a/src/test/java/org/tron/core/dbStore/UTXOStoreTest.java b/src/test/java/org/tron/core/dbStore/UTXOStoreTest.java index 80ea6fd96a8..c80c8dc2486 100644 --- a/src/test/java/org/tron/core/dbStore/UTXOStoreTest.java +++ b/src/test/java/org/tron/core/dbStore/UTXOStoreTest.java @@ -13,14 +13,14 @@ * along with this program. If not, see . */ -package org.tron.core.dbStore; +package org.tron.core.dbstore; import static org.tron.core.Constant.BLOCK_DB_NAME; import org.junit.Ignore; import org.junit.Test; -import org.tron.core.Constant; import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; @Ignore public class UTXOStoreTest { diff --git a/src/test/java/org/tron/core/net/node/NodeTest.java b/src/test/java/org/tron/core/net/node/NodeTest.java index cd1e311b5b6..94c0af7bbf6 100644 --- a/src/test/java/org/tron/core/net/node/NodeTest.java +++ b/src/test/java/org/tron/core/net/node/NodeTest.java @@ -14,38 +14,30 @@ */ package org.tron.core.net.node; -import com.google.protobuf.ByteString; - import org.junit.Test; -import org.tron.core.BlockUtils; -import org.tron.core.TransactionUtils; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.message.Message; -import org.tron.core.net.message.TransationMessage; import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; public class NodeTest { - private Semaphore lock = new Semaphore(0); @Test public void testNode() throws InterruptedException { - Node node = new Node(); - node.setNodeDelegate(new NodeImpl()); - node.start(); - - lock.tryAcquire(1, TimeUnit.SECONDS); - Message messageBlock = new BlockMessage(BlockUtils.newBlock(null, ByteString.copyFrom(new byte[]{1}), - ByteString - .copyFrom(new byte[]{2}), 3L)); - - node.broadcast(messageBlock); - lock.tryAcquire(1, TimeUnit.SECONDS); - - Message messageTransaction = new TransationMessage(TransactionUtils.newCoinbaseTransaction("12", "", 0)); - - node.broadcast(messageTransaction); - lock.tryAcquire(1, TimeUnit.SECONDS); +// INode node = new NodeImpl(); +// node.setNodeDelegate(new ApplicationImpl()); +// node. +// +// lock.tryAcquire(1, TimeUnit.SECONDS); +// Message messageBlock = new BlockMessage(BlockUtils.newBlock(null, ByteString.copyFrom(new byte[]{1}), +// ByteString +// .copyFrom(new byte[]{2}), 3L)); +// +// node.broadcast(messageBlock); +// lock.tryAcquire(1, TimeUnit.SECONDS); +// +// Message messageTransaction = new TransationMessage(TransactionUtils.newCoinbaseTransaction("12", "", 0)); +// +// node.broadcast(messageTransaction); +// lock.tryAcquire(1, TimeUnit.SECONDS); } + } diff --git a/src/test/java/org/tron/dbStore/BlockStoresTest.java b/src/test/java/org/tron/dbStore/BlockStoresTest.java index 8ac2cce1ff8..642d21f4b5c 100644 --- a/src/test/java/org/tron/dbStore/BlockStoresTest.java +++ b/src/test/java/org/tron/dbStore/BlockStoresTest.java @@ -13,31 +13,31 @@ * along with this program. If not, see . */ -package org.tron.dbStore; +package org.tron.dbstore; + +import static org.tron.core.Constant.BLOCK_DB_NAME; import org.junit.Ignore; import org.junit.Test; import org.tron.common.utils.ByteArray; import org.tron.core.Constant; -import org.tron.core.dbStore.BlockStores; - -import static org.tron.core.Constant.BLOCK_DB_NAME; +import org.tron.core.dbstore.BlockStores; @Ignore public class BlockStoresTest { - @Test - public void saveBlock() { - BlockStores blockStores = new BlockStores(Constant.TEST, BLOCK_DB_NAME); - blockStores.saveBlock("0001245".getBytes(), "xxdfrgds".getBytes()); - blockStores.close(); - } + @Test + public void saveBlock() { + BlockStores blockStores = new BlockStores(Constant.TEST, BLOCK_DB_NAME); + blockStores.saveBlock("0001245".getBytes(), "xxdfrgds".getBytes()); + blockStores.close(); + } - @Test - public void findBlockByHash() { - BlockStores blockStores = new BlockStores(Constant.TEST, BLOCK_DB_NAME); - byte[] blockByHash = blockStores.findBlockByHash("0001245".getBytes()); - blockStores.close(); - System.out.println(ByteArray.toStr(blockByHash)); - } + @Test + public void findBlockByHash() { + BlockStores blockStores = new BlockStores(Constant.TEST, BLOCK_DB_NAME); + byte[] blockByHash = blockStores.findBlockByHash("0001245".getBytes()); + blockStores.close(); + System.out.println(ByteArray.toStr(blockByHash)); + } } \ No newline at end of file diff --git a/src/test/java/org/tron/dbStore/UTXOStoreTest.java b/src/test/java/org/tron/dbStore/UTXOStoreTest.java index 5803e9431cc..d197e536132 100644 --- a/src/test/java/org/tron/dbStore/UTXOStoreTest.java +++ b/src/test/java/org/tron/dbStore/UTXOStoreTest.java @@ -13,34 +13,34 @@ * along with this program. If not, see . */ -package org.tron.dbStore; +package org.tron.dbstore; + +import static org.tron.core.Constant.BLOCK_DB_NAME; import org.junit.Ignore; import org.junit.Test; import org.tron.common.utils.ByteArray; import org.tron.core.Constant; -import org.tron.core.dbStore.UTXOStore; - -import static org.tron.core.Constant.BLOCK_DB_NAME; +import org.tron.core.dbstore.UTXOStore; @Ignore public class UTXOStoreTest { - /** - * save utxo - */ - @Test - public void saveUTXO() { - UTXOStore utxoStore = new UTXOStore(Constant.TEST, BLOCK_DB_NAME); - utxoStore.saveUTXO("00012546".getBytes(), "300".getBytes()); - utxoStore.close(); - } + /** + * save utxo + */ + @Test + public void saveUTXO() { + UTXOStore utxoStore = new UTXOStore(Constant.TEST, BLOCK_DB_NAME); + utxoStore.saveUTXO("00012546".getBytes(), "300".getBytes()); + utxoStore.close(); + } - @Test - public void find() { - UTXOStore utxoStore = new UTXOStore(Constant.TEST, BLOCK_DB_NAME); - byte[] bytes = utxoStore.find("00012546".getBytes()); - utxoStore.close(); - System.out.println(ByteArray.toStr(bytes)); - } + @Test + public void find() { + UTXOStore utxoStore = new UTXOStore(Constant.TEST, BLOCK_DB_NAME); + byte[] bytes = utxoStore.find("00012546".getBytes()); + utxoStore.close(); + System.out.println(ByteArray.toStr(bytes)); + } } \ No newline at end of file diff --git a/src/test/java/org/tron/gossip/GossipTest.java b/src/test/java/org/tron/gossip/GossipTest.java deleted file mode 100644 index 9e7c68208c5..00000000000 --- a/src/test/java/org/tron/gossip/GossipTest.java +++ /dev/null @@ -1,81 +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.gossip; - -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import org.apache.gossip.LocalMember; -import org.junit.Test; -import org.tron.common.overlay.gossip.LocalNode; -import org.tron.core.BlockUtils; -import org.tron.core.net.message.BlockMessage; -import org.tron.core.net.message.Message; -import org.tron.protos.core.TronBlock; - -import java.io.UnsupportedEncodingException; -import java.util.List; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -public class GossipTest { - private static LocalNode standNode = LocalNode.getInstance(); - private Semaphore lock = new Semaphore(0); - - @Test - public void testGossipBroadcast() throws InterruptedException { - standNode.getGossipManager().registerSharedDataSubscriber((key, oldValue, newValue) -> { - byte[] newValueBytes = null; - try { - newValueBytes = newValue.toString().getBytes("ISO-8859-1"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - - TronBlock.Block block = null; - - try { - block = TronBlock.Block.parseFrom(newValueBytes); - } catch (InvalidProtocolBufferException e) { - e.printStackTrace(); - } - - System.out.println(BlockUtils.toPrintString(block)); - }); - - Message message = new BlockMessage(BlockUtils.newBlock(null, ByteString.copyFrom(new byte[]{1}), ByteString - .copyFrom(new byte[]{2}), 3L)); - standNode.broadcast(message); - lock.tryAcquire(10, TimeUnit.SECONDS); - } - - @Test - public void testGossipGetLiveMembers() { - List memberList = standNode.getLiveMembers(); - - for (LocalMember l : memberList) { - System.out.println(l); - } - } - - @Test - public void testGossipGetDeadMembers() { - List memberList = standNode.getDeadMembers(); - - for (LocalMember l : memberList) { - System.out.println(l); - } - } -} diff --git a/src/test/java/org/tron/storage/leveldb/LevelDbDataSourceImplTest.java b/src/test/java/org/tron/storage/leveldb/LevelDbDataSourceImplTest.java index b590167c829..7660ea2e26b 100644 --- a/src/test/java/org/tron/storage/leveldb/LevelDbDataSourceImplTest.java +++ b/src/test/java/org/tron/storage/leveldb/LevelDbDataSourceImplTest.java @@ -17,54 +17,54 @@ */ package org.tron.storage.leveldb; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import org.junit.Ignore; import org.junit.Test; import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; import org.tron.common.utils.ByteArray; import org.tron.core.Constant; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - @Ignore public class LevelDbDataSourceImplTest { - @Test - public void testGet() { - LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(Constant.TEST, "test"); - dataSource.initDB(); - String key1 = "000134yyyhy"; - byte[] key = key1.getBytes(); - byte[] value = dataSource.getData(key); - String s = ByteArray.toStr(value); - dataSource.closeDB(); - System.out.println(s); - } + @Test + public void testGet() { + LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(Constant.TEST, "test"); + dataSource.initDB(); + String key1 = "000134yyyhy"; + byte[] key = key1.getBytes(); + byte[] value = dataSource.getData(key); + String s = ByteArray.toStr(value); + dataSource.closeDB(); + System.out.println(s); + } - @Test - public void testPut() { - LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(Constant.TEST, "test"); - dataSource.initDB(); - String key1 = "000134yyyhy"; - byte[] key = key1.getBytes(); + @Test + public void testPut() { + LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(Constant.TEST, "test"); + dataSource.initDB(); + String key1 = "000134yyyhy"; + byte[] key = key1.getBytes(); - String value1 = "50000"; - byte[] value = value1.getBytes(); + String value1 = "50000"; + byte[] value = value1.getBytes(); - dataSource.putData(key, value); + dataSource.putData(key, value); - assertNotNull(dataSource.getData(key)); - assertEquals(1, dataSource.allKeys().size()); + assertNotNull(dataSource.getData(key)); + assertEquals(1, dataSource.allKeys().size()); - dataSource.closeDB(); - } + dataSource.closeDB(); + } - @Test - public void testRest() { + @Test + public void testRest() { - LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(Constant.TEST_CONF, "test"); - dataSource.resetDB(); - dataSource.closeDB(); - } + LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl(Constant.TEST_CONF, "test"); + dataSource.resetDB(); + dataSource.closeDB(); + } } \ No newline at end of file diff --git a/src/test/java/org/tron/utils/ByteArrayTest.java b/src/test/java/org/tron/utils/ByteArrayTest.java index c2cd817c2bd..c290387b82a 100644 --- a/src/test/java/org/tron/utils/ByteArrayTest.java +++ b/src/test/java/org/tron/utils/ByteArrayTest.java @@ -22,41 +22,42 @@ import org.tron.common.utils.ByteArray; public class ByteArrayTest { - private static final Logger logger = LoggerFactory.getLogger("Test"); - - @Test - public void testToHexString() { - logger.info("Byte: byte 16 to hex string = {}", ByteArray.toHexString - (new byte[]{16})); - } - - @Test - public void testHexStringToByte() { - logger.info("Byte: hex string 0x11 to byte = {}", ByteArray - .fromHexString("0x11")); - logger.info("Byte: hex string 10 to byte = {}", ByteArray - .fromHexString("10")); - logger.info("Byte: hex string 1 to byte = {}", ByteArray - .fromHexString("1")); - } - - @Test - public void testToLong() { - logger.info("Byte: byte 13 to long = {}", ByteArray.toLong(new - byte[]{13})); - } - - @Test - public void testFromLong() { - logger.info("Byte: long 127L to byte = {}", ByteArray.fromLong(127L)); - } - - @Test - public void test2ToHexString() { - byte[] bs = new byte[]{}; - - logger.info("utils.ByteArray.toHexString: {}", ByteArray.toHexString - (bs)); - logger.info("Hex.toHexString: {}", Hex.toHexString(bs)); - } + + private static final Logger logger = LoggerFactory.getLogger("Test"); + + @Test + public void testToHexString() { + logger.info("Byte: byte 16 to hex string = {}", ByteArray.toHexString + (new byte[]{16})); + } + + @Test + public void testHexStringToByte() { + logger.info("Byte: hex string 0x11 to byte = {}", ByteArray + .fromHexString("0x11")); + logger.info("Byte: hex string 10 to byte = {}", ByteArray + .fromHexString("10")); + logger.info("Byte: hex string 1 to byte = {}", ByteArray + .fromHexString("1")); + } + + @Test + public void testToLong() { + logger.info("Byte: byte 13 to long = {}", ByteArray.toLong(new + byte[]{13})); + } + + @Test + public void testFromLong() { + logger.info("Byte: long 127L to byte = {}", ByteArray.fromLong(127L)); + } + + @Test + public void test2ToHexString() { + byte[] bs = new byte[]{}; + + logger.info("utils.ByteArray.toHexString: {}", ByteArray.toHexString + (bs)); + logger.info("Hex.toHexString: {}", Hex.toHexString(bs)); + } } diff --git a/src/test/java/org/tron/wallet/WalletTest.java b/src/test/java/org/tron/wallet/WalletTest.java index 3b7c319f995..aa9a1a2eec9 100644 --- a/src/test/java/org/tron/wallet/WalletTest.java +++ b/src/test/java/org/tron/wallet/WalletTest.java @@ -18,7 +18,9 @@ package org.tron.wallet; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import org.junit.Test; import org.slf4j.Logger; @@ -29,6 +31,7 @@ import org.tron.core.Wallet; public class WalletTest { + private static final Logger logger = LoggerFactory.getLogger("Test"); @Test