diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractCompileMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractCompileMojo.java index b0304ba0..61a3dfff 100644 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractCompileMojo.java +++ b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractCompileMojo.java @@ -15,16 +15,24 @@ public class ContractCompileMojo extends SingleAssemblyMojo { // 要求必须有MainClass try { String mainClass = super.getJarArchiveConfiguration().getManifest().getMainClass(); + // 校验MainClass,要求MainClass必须不能为空 + if (mainClass == null || mainClass.length() == 0) { + throw new MojoFailureException("MainClass is NULL !!!"); + } super.getLog().debug("MainClass is " + mainClass); } catch (Exception e) { throw new MojoFailureException("MainClass is null: " + e.getMessage(), e ); } + + // 此参数用于设置将所有第三方依赖的Jar包打散为.class,与主代码打包在一起,生成一个jar包 super.setDescriptorRefs(new String[]{JAR_DEPENDENCE}); + // 执行打包命令 super.execute(); ContractResolveEngine engine = new ContractResolveEngine(getLog(), getProject(), getFinalName()); + // 打包并进行校验 engine.compileAndVerify(); } } diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractResolveEngine.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractResolveEngine.java index 7ce0b0a1..06619a84 100644 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractResolveEngine.java +++ b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractResolveEngine.java @@ -20,9 +20,9 @@ import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import static com.jd.blockchain.contract.ContractJarUtils.*; import static com.jd.blockchain.contract.maven.ContractCompileMojo.JAR_DEPENDENCE; import static com.jd.blockchain.utils.decompiler.utils.DecompilerUtils.decompileJarFile; -import static com.jd.blockchain.utils.jar.ContractJarUtils.*; public class ContractResolveEngine { diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java index 2f3d215e..44f22aad 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java @@ -1,11 +1,10 @@ package com.jd.blockchain.gateway.service; +import com.jd.blockchain.contract.ContractJarUtils; import com.jd.blockchain.gateway.PeerService; import com.jd.blockchain.ledger.ContractCodeDeployOperation; import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.ledger.TransactionRequest; -import com.jd.blockchain.utils.IllegalDataException; -import com.jd.blockchain.utils.jar.ContractJarUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/AbtractContractEventHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/AbstractContractEventHandle.java similarity index 97% rename from source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/AbtractContractEventHandle.java rename to source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/AbstractContractEventHandle.java index 40f6e2c2..0b2189ae 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/AbtractContractEventHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/AbstractContractEventHandle.java @@ -18,7 +18,7 @@ import com.jd.blockchain.ledger.core.impl.LedgerQueryService; import com.jd.blockchain.ledger.core.impl.OperationHandleContext; @Service -public abstract class AbtractContractEventHandle implements OperationHandle { +public abstract class AbstractContractEventHandle implements OperationHandle { @Override public boolean support(Class operationType) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java index fd4dc617..ed7b1981 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java @@ -1,6 +1,6 @@ package com.jd.blockchain.ledger.core.impl.handles; -import com.jd.blockchain.utils.jar.ContractJarUtils; +import com.jd.blockchain.contract.ContractJarUtils; import org.springframework.stereotype.Service; import com.jd.blockchain.ledger.BytesValue; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/JVMContractEventSendOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/JVMContractEventSendOperationHandle.java index da4da430..f32b7f41 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/JVMContractEventSendOperationHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/JVMContractEventSendOperationHandle.java @@ -5,12 +5,17 @@ import com.jd.blockchain.contract.engine.ContractEngine; import com.jd.blockchain.contract.engine.ContractServiceProviders; import com.jd.blockchain.ledger.core.ContractAccount; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import static com.jd.blockchain.utils.BaseConstant.CONTRACT_SERVICE_PROVIDER; -public class JVMContractEventSendOperationHandle extends AbtractContractEventHandle { +public class JVMContractEventSendOperationHandle extends AbstractContractEventHandle { private static final ContractEngine JVM_ENGINE; + private static final Lock JVM_LOAD_LOCK = new ReentrantLock(); + static { JVM_ENGINE = ContractServiceProviders.getProvider(CONTRACT_SERVICE_PROVIDER).getEngine(); } @@ -19,9 +24,18 @@ public class JVMContractEventSendOperationHandle extends AbtractContractEventHan protected ContractCode loadContractCode(ContractAccount contract) { ContractCode contractCode = JVM_ENGINE.getContract(contract.getAddress(), contract.getChaincodeVersion()); if (contractCode == null) { - // 装载合约; - contractCode = JVM_ENGINE.setupContract(contract.getAddress(), contract.getChaincodeVersion(), - contract.getChainCode()); + JVM_LOAD_LOCK.lock(); + try { + // Double Check + contractCode = JVM_ENGINE.getContract(contract.getAddress(), contract.getChaincodeVersion()); + if (contractCode == null) { + // 装载合约; + contractCode = JVM_ENGINE.setupContract(contract.getAddress(), contract.getChaincodeVersion(), + contract.getChainCode()); + } + } finally { + JVM_LOAD_LOCK.unlock(); + } } return contractCode; } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java index c0a31321..553cac68 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java @@ -8,10 +8,10 @@ import com.jd.blockchain.contract.engine.ContractCode; import com.jd.blockchain.contract.jvm.AbstractContractCode; import com.jd.blockchain.contract.jvm.ContractDefinition; import com.jd.blockchain.ledger.core.ContractAccount; -import com.jd.blockchain.ledger.core.impl.handles.AbtractContractEventHandle; +import com.jd.blockchain.ledger.core.impl.handles.AbstractContractEventHandle; import com.jd.blockchain.utils.Bytes; -public class ContractInvokingHandle extends AbtractContractEventHandle { +public class ContractInvokingHandle extends AbstractContractEventHandle { private Map contractInstances = new ConcurrentHashMap(); diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractJarUtils.java similarity index 87% rename from source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java rename to source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractJarUtils.java index 5ec66dde..5a183006 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractJarUtils.java @@ -1,5 +1,9 @@ -package com.jd.blockchain.utils.jar; +package com.jd.blockchain.contract; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.crypto.HashFunction; +import com.jd.blockchain.utils.io.BytesUtils; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -17,13 +21,15 @@ public class ContractJarUtils { private static final String CONTRACT_MF = "META-INF/CONTRACT.MF"; - private static final int JDCHAIN_HASH_LENGTH = 69; + private static final HashFunction HASH_FUNCTION = Crypto.getHashFunction("SHA256"); private static final Random FILE_RANDOM = new Random(); + private static final byte[] JDCHAIN_MARK = "JDChain".getBytes(StandardCharsets.UTF_8); + public static void verify(byte[] chainCode) { if (chainCode == null || chainCode.length == 0) { - throw new IllegalStateException("ChainCode is empty !!!"); + throw new IllegalStateException("Contract's chaincode is empty !!!"); } // 首先生成合约文件 File jarFile = newJarFile(); @@ -51,7 +57,7 @@ public class ContractJarUtils { throw new IllegalStateException(CONTRACT_MF + " IS NULL !!!"); } byte[] bytes = IOUtils.toByteArray(inputStream); - if (bytes == null || bytes.length != JDCHAIN_HASH_LENGTH) { + if (bytes == null || bytes.length == 0) { throw new IllegalStateException(CONTRACT_MF + " IS Illegal !!!"); } // 获取对应的Hash内容 @@ -107,8 +113,8 @@ public class ContractJarUtils { } public static String contractMF(byte[] content) { - // hash=Hex(hash(content)) - return "hash:" + DigestUtils.sha256Hex(content); + HashDigest hashDigest = HASH_FUNCTION.hash(BytesUtils.concat(content, JDCHAIN_MARK)); + return "hash:" + hashDigest.toBase58(); } public static JarEntry contractMFJarEntry() { diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java index 93f0e3c7..00d79f35 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java @@ -1,31 +1,11 @@ package com.jd.blockchain.transaction; -import java.io.*; -import java.net.URL; -import java.nio.charset.StandardCharsets; +import com.jd.blockchain.ledger.*; +import com.jd.blockchain.utils.Bytes; + import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarOutputStream; - -import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.BytesValue; -import com.jd.blockchain.ledger.BytesValueList; -import com.jd.blockchain.ledger.ContractCodeDeployOperation; -import com.jd.blockchain.ledger.ContractEventSendOperation; -import com.jd.blockchain.ledger.DataAccountKVSetOperation; -import com.jd.blockchain.ledger.DataAccountRegisterOperation; -import com.jd.blockchain.ledger.LedgerInitOperation; -import com.jd.blockchain.ledger.LedgerInitSetting; -import com.jd.blockchain.ledger.Operation; -import com.jd.blockchain.ledger.UserRegisterOperation; -import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.jar.ContractJarUtils; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.io.FileUtils; /** * @author huanghaiquan diff --git a/source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractJarUtilsTest.java similarity index 87% rename from source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java rename to source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractJarUtilsTest.java index 02376434..06e2bf44 100644 --- a/source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java +++ b/source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/data/ContractJarUtilsTest.java @@ -1,4 +1,4 @@ -package test.my.utils; +package test.com.jd.blockchain.ledger.data; import org.apache.commons.io.FileUtils; import org.junit.Test; @@ -7,7 +7,7 @@ import org.springframework.core.io.ClassPathResource; import java.io.File; import java.nio.charset.StandardCharsets; -import static com.jd.blockchain.utils.jar.ContractJarUtils.*; +import static com.jd.blockchain.contract.ContractJarUtils.*; import static org.junit.Assert.fail; public class ContractJarUtilsTest { @@ -59,6 +59,11 @@ public class ContractJarUtilsTest { } catch (Exception e) { fail("Verify Fail !!"); } + } + @Test + public void testSign() { + byte[] test = "zhangsan".getBytes(StandardCharsets.UTF_8); + System.out.println(contractMF(test)); } } diff --git a/source/runtime/runtime-modular-booter/src/main/java/com/jd/blockchain/runtime/boot/HomeBooter.java b/source/runtime/runtime-modular-booter/src/main/java/com/jd/blockchain/runtime/boot/HomeBooter.java index 6000f04c..1e8329b2 100644 --- a/source/runtime/runtime-modular-booter/src/main/java/com/jd/blockchain/runtime/boot/HomeBooter.java +++ b/source/runtime/runtime-modular-booter/src/main/java/com/jd/blockchain/runtime/boot/HomeBooter.java @@ -91,7 +91,7 @@ public class HomeBooter { runtimeDir.mkdirs(); } - // 以 ExtClassLoader 作为所有创建的ClassLoader的 Parrent; + // 以 ExtClassLoader 作为所有创建的ClassLoader的 Parent; ClassLoader extClassLoader = HomeBooter.class.getClassLoader().getParent(); URL[] libJars = loadClassPaths(libDir); diff --git a/source/runtime/runtime-modular/src/main/java/com/jd/blockchain/runtime/modular/ModularFactory.java b/source/runtime/runtime-modular/src/main/java/com/jd/blockchain/runtime/modular/ModularFactory.java index b9615482..b23dbfe8 100644 --- a/source/runtime/runtime-modular/src/main/java/com/jd/blockchain/runtime/modular/ModularFactory.java +++ b/source/runtime/runtime-modular/src/main/java/com/jd/blockchain/runtime/modular/ModularFactory.java @@ -6,7 +6,7 @@ public class ModularFactory { * 启动系统; */ public static void startSystem(String runtimeDir, boolean productMode, - ClassLoader libClassLoader,String mainClassName, ClassLoader systemClassLoader, String[] args) { + ClassLoader libClassLoader, String mainClassName, ClassLoader systemClassLoader, String[] args) { JarsModule libModule = new JarsModule("LibModule", libClassLoader);