From 03eb3c70ed3e0b1ec6233681c8d30d691363efd7 Mon Sep 17 00:00:00 2001 From: shaozhuguang Date: Mon, 16 Sep 2019 17:09:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=8E=B7=E5=8F=96=E8=B4=A6?= =?UTF-8?q?=E6=9C=AC=E5=9F=BA=E6=9C=AC=E4=BF=A1=E6=81=AF=E6=A0=88=E6=BA=A2?= =?UTF-8?q?=E5=87=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contract/contract-maven-plugin/ReadME.MD | 2 +- .../gateway/service/GatewayQueryService.java | 4 +- .../service/GatewayQueryServiceHandler.java | 56 +++--- .../gateway/web/BlockBrowserController.java | 13 +- .../ledger/core/LedgerAdminInfoData.java | 161 ++++++++++++++++++ .../ledger/core/LedgerRepositoryImpl.java | 15 +- ...tSettings.java => LedgerBaseSettings.java} | 2 +- .../sdk/proxy/HttpBlockchainQueryService.java | 14 +- 8 files changed, 227 insertions(+), 40 deletions(-) create mode 100644 source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminInfoData.java rename source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/{LedgerInitSettings.java => LedgerBaseSettings.java} (98%) diff --git a/source/contract/contract-maven-plugin/ReadME.MD b/source/contract/contract-maven-plugin/ReadME.MD index fce27392..1cc457b6 100644 --- a/source/contract/contract-maven-plugin/ReadME.MD +++ b/source/contract/contract-maven-plugin/ReadME.MD @@ -35,7 +35,7 @@ + 3)executions->execution->phase:建议使用package及其后续阶段(若不了解phase含义,请自行查阅相关信息); + 4)executions->execution->goals->goal:必须使用compile; + 5)mainClass:必填,该类为需要发布的合约执行类(注意此处是类,不是接口),必须正确配置; - + 6)finalName:必填,最终在编译正常的情况下,会产生{finalName}-jdchain-contract.jar文件,只有该文件是可以发布到JDChain的合约包; + + 6)finalName:必填,最终在编译正常的情况下,会产生{finalName}-JDChain-Contract.jar文件,只有该文件是可以发布到JDChain的合约包; ### 2、执行命令 diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryService.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryService.java index d88f49aa..8a856953 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryService.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryService.java @@ -3,7 +3,7 @@ package com.jd.blockchain.gateway.service; import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.ledger.ParticipantNode; import com.jd.blockchain.sdk.ContractSettings; -import com.jd.blockchain.sdk.LedgerInitSettings; +import com.jd.blockchain.sdk.LedgerBaseSettings; /** * queryService only for gateway; @@ -34,7 +34,7 @@ public interface GatewayQueryService { * 账本Hash * @return */ - LedgerInitSettings getLedgerInitSettings(HashDigest ledgerHash); + LedgerBaseSettings getLedgerBaseSettings(HashDigest ledgerHash); /** * 获取账本指定合约信息 diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryServiceHandler.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryServiceHandler.java index 451beec4..aeedd64c 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryServiceHandler.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayQueryServiceHandler.java @@ -10,7 +10,7 @@ import com.jd.blockchain.ledger.LedgerAdminInfo; import com.jd.blockchain.ledger.LedgerMetadata; import com.jd.blockchain.ledger.ParticipantNode; import com.jd.blockchain.sdk.ContractSettings; -import com.jd.blockchain.sdk.LedgerInitSettings; +import com.jd.blockchain.sdk.LedgerBaseSettings; import com.jd.blockchain.utils.QueryUtil; import com.jd.blockchain.utils.codec.HexUtils; import com.jd.blockchain.utils.decompiler.utils.DecompilerUtils; @@ -31,30 +31,26 @@ public class GatewayQueryServiceHandler implements GatewayQueryService { @Override public HashDigest[] getLedgersHash(int fromIndex, int count) { - HashDigest ledgersHash[] = peerService.getQueryService().getLedgerHashs(); - int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex,count,ledgersHash.length); - HashDigest ledgersHashNew[] = Arrays.copyOfRange(ledgersHash,indexAndCount[0],indexAndCount[0]+indexAndCount[1]); - return ledgersHashNew; + HashDigest[] ledgersHashs = peerService.getQueryService().getLedgerHashs(); + int[] indexAndCount = QueryUtil.calFromIndexAndCount(fromIndex, count, ledgersHashs.length); + return Arrays.copyOfRange(ledgersHashs, indexAndCount[0], indexAndCount[0] + indexAndCount[1]); } @Override public ParticipantNode[] getConsensusParticipants(HashDigest ledgerHash, int fromIndex, int count) { - ParticipantNode participantNode[] = peerService.getQueryService().getConsensusParticipants(ledgerHash); - int indexAndCount[] = QueryUtil.calFromIndexAndCount(fromIndex,count,participantNode.length); - ParticipantNode participantNodesNew[] = Arrays.copyOfRange(participantNode,indexAndCount[0],indexAndCount[0]+indexAndCount[1]); - return participantNodesNew; + ParticipantNode[] participantNodes = peerService.getQueryService().getConsensusParticipants(ledgerHash); + int[] indexAndCount = QueryUtil.calFromIndexAndCount(fromIndex, count, participantNodes.length); + ParticipantNode[] participantNodesNews = Arrays.copyOfRange(participantNodes, indexAndCount[0], + indexAndCount[0] + indexAndCount[1]); + return participantNodesNews; } @Override - public LedgerInitSettings getLedgerInitSettings(HashDigest ledgerHash) { - - ParticipantNode[] participantNodes = peerService.getQueryService().getConsensusParticipants(ledgerHash); - - LedgerMetadata ledgerMetadata = peerService.getQueryService().getLedgerMetadata(ledgerHash); + public LedgerBaseSettings getLedgerBaseSettings(HashDigest ledgerHash) { LedgerAdminInfo ledgerAdminInfo = peerService.getQueryService().getLedgerAdminInfo(ledgerHash); - return initLedgerInitSettings(participantNodes, ledgerMetadata, ledgerAdminInfo); + return initLedgerBaseSettings(ledgerAdminInfo); } @Override @@ -73,36 +69,38 @@ public class GatewayQueryServiceHandler implements GatewayQueryService { } /** - * 初始化账本配置 + * 初始化账本的基本配置 + * + * @param ledgerAdminInfo + * 账本信息 * - * @param participantNodes - * 参与方列表 - * @param ledgerMetadata - * 账本元数据 * @return */ - private LedgerInitSettings initLedgerInitSettings(ParticipantNode[] participantNodes, LedgerMetadata ledgerMetadata, LedgerAdminInfo ledgerAdminInfo) { - LedgerInitSettings ledgerInitSettings = new LedgerInitSettings(); + private LedgerBaseSettings initLedgerBaseSettings(LedgerAdminInfo ledgerAdminInfo) { + + LedgerMetadata ledgerMetadata = ledgerAdminInfo.getMetadata(); + + LedgerBaseSettings ledgerBaseSettings = new LedgerBaseSettings(); // 设置参与方 - ledgerInitSettings.setParticipantNodes(participantNodes); + ledgerBaseSettings.setParticipantNodes(ledgerAdminInfo.getParticipants()); // 设置共识设置 - ledgerInitSettings.setConsensusSettings(initConsensusSettings(ledgerAdminInfo)); + ledgerBaseSettings.setConsensusSettings(initConsensusSettings(ledgerAdminInfo)); // 设置参与方根Hash - ledgerInitSettings.setParticipantsHash(ledgerMetadata.getParticipantsHash()); + ledgerBaseSettings.setParticipantsHash(ledgerMetadata.getParticipantsHash()); // 设置算法配置 - ledgerInitSettings.setCryptoSetting(ledgerAdminInfo.getSettings().getCryptoSetting()); + ledgerBaseSettings.setCryptoSetting(ledgerAdminInfo.getSettings().getCryptoSetting()); // 设置种子 - ledgerInitSettings.setSeed(initSeed(ledgerMetadata.getSeed())); + ledgerBaseSettings.setSeed(initSeed(ledgerMetadata.getSeed())); // 设置共识协议 - ledgerInitSettings.setConsensusProtocol(ledgerAdminInfo.getSettings().getConsensusProvider()); + ledgerBaseSettings.setConsensusProtocol(ledgerAdminInfo.getSettings().getConsensusProvider()); - return ledgerInitSettings; + return ledgerBaseSettings; } /** diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java index 7de12a75..a6ef2f9b 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java @@ -5,6 +5,8 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; +import com.jd.blockchain.gateway.service.GatewayQueryService; +import com.jd.blockchain.sdk.LedgerBaseSettings; import com.jd.blockchain.utils.decompiler.utils.DecompilerUtils; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -47,6 +49,9 @@ public class BlockBrowserController implements BlockchainExtendQueryService { @Autowired private PeerService peerService; + @Autowired + private GatewayQueryService gatewayQueryService; + @Autowired private DataRetrievalService dataRetrievalService; @@ -86,10 +91,10 @@ public class BlockBrowserController implements BlockchainExtendQueryService { return peerService.getQueryService().getLedgerMetadata(ledgerHash); } -// @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/settings") -// public LedgerInitSettings getLedgerInitSettings(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { -// return gatewayQueryService.getLedgerInitSettings(ledgerHash); -// } + @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/settings") + public LedgerBaseSettings getLedgerInitSettings(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + return gatewayQueryService.getLedgerBaseSettings(ledgerHash); + } @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/blocks") public LedgerBlock[] getBlocks(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminInfoData.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminInfoData.java new file mode 100644 index 00000000..6c2660fa --- /dev/null +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAdminInfoData.java @@ -0,0 +1,161 @@ +package com.jd.blockchain.ledger.core; + +import com.jd.blockchain.binaryproto.BinaryProtocol; +import com.jd.blockchain.binaryproto.DataContractRegistry; +import com.jd.blockchain.crypto.Crypto; +import com.jd.blockchain.crypto.HashDigest; +import com.jd.blockchain.crypto.HashFunction; +import com.jd.blockchain.ledger.LedgerMetadata; +import com.jd.blockchain.ledger.*; +import com.jd.blockchain.storage.service.ExPolicyKVStorage; +import com.jd.blockchain.storage.service.VersioningKVStorage; +import com.jd.blockchain.utils.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.jd.blockchain.ledger.core.LedgerAdminDataset.*; + +/** + * @author shaozhuguang + * @date 2019-09-16 + * + * LedgerAdminInfo的独立实现类,主要用于页面展示,区分 {@link LedgerAdminDataset} + */ +public class LedgerAdminInfoData implements LedgerAdminInfo { + + static { + DataContractRegistry.register(LedgerMetadata.class); + DataContractRegistry.register(LedgerMetadata_V2.class); + } + + private static Logger LOGGER = LoggerFactory.getLogger(LedgerAdminInfoData.class); + + private final Bytes metaPrefix; + + private final Bytes settingPrefix; + + private LedgerMetadata_V2 origMetadata; + + private LedgerAdminDataset.LedgerMetadataInfo metadata; + + /** + * 原来的账本设置; + * + *
+ * 对 LedgerMetadata 修改的新配置不能立即生效,需要达成共识后,在下一次区块计算中才生效; + */ + private LedgerSettings previousSettings; + + /** + * 账本的参与节点; + */ + private ParticipantDataset participants; + + /** + * 账本参数配置; + */ + private LedgerSettings settings; + + private ExPolicyKVStorage storage; + + public LedgerAdminInfoData(HashDigest adminAccountHash, String keyPrefix, ExPolicyKVStorage kvStorage, + VersioningKVStorage versioningKVStorage, boolean readonly) { + + this.metaPrefix = Bytes.fromString(keyPrefix + LEDGER_META_PREFIX); + this.settingPrefix = Bytes.fromString(keyPrefix + LEDGER_SETTING_PREFIX); + this.storage = kvStorage; + this.origMetadata = loadAndVerifyMetadata(adminAccountHash); + this.metadata = new LedgerMetadataInfo(origMetadata); + this.settings = loadAndVerifySettings(metadata.getSettingsHash()); + // 复制记录一份配置作为上一个区块的原始配置,该实例仅供读取,不做修改,也不会回写到存储; + this.previousSettings = new LedgerConfiguration(settings); + + String partiPrefix = keyPrefix + LEDGER_PARTICIPANT_PREFIX; + this.participants = new ParticipantDataset(metadata.getParticipantsHash(), previousSettings.getCryptoSetting(), + partiPrefix, kvStorage, versioningKVStorage, readonly); + } + + private LedgerMetadata_V2 loadAndVerifyMetadata(HashDigest adminAccountHash) { + Bytes key = encodeMetadataKey(adminAccountHash); + byte[] bytes = storage.get(key); + HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm()); + if (!hashFunc.verify(adminAccountHash, bytes)) { + String errorMsg = "Verification of the hash for ledger metadata failed! --[HASH=" + key + "]"; + LOGGER.error(errorMsg); + throw new LedgerException(errorMsg); + } + return deserializeMetadata(bytes); + } + + + private LedgerSettings loadAndVerifySettings(HashDigest settingsHash) { + if (settingsHash == null) { + return null; + } + Bytes key = encodeSettingsKey(settingsHash); + byte[] bytes = storage.get(key); + HashFunction hashFunc = Crypto.getHashFunction(settingsHash.getAlgorithm()); + if (!hashFunc.verify(settingsHash, bytes)) { + String errorMsg = "Verification of the hash for ledger setting failed! --[HASH=" + key + "]"; + LOGGER.error(errorMsg); + throw new LedgerException(errorMsg); + } + return deserializeSettings(bytes); + } + + private Bytes encodeMetadataKey(HashDigest metadataHash) { + return metaPrefix.concat(metadataHash); + } + + private LedgerMetadata_V2 deserializeMetadata(byte[] bytes) { + return BinaryProtocol.decode(bytes); + } + + private LedgerSettings deserializeSettings(byte[] bytes) { + return BinaryProtocol.decode(bytes); + } + + private Bytes encodeSettingsKey(HashDigest settingsHash) { + return settingPrefix.concat(settingsHash); + } + + /** + * 返回元数据配置信息 + * + * @return + */ + @Override + public LedgerMetadata_V2 getMetadata() { + return metadata; + } + + /** + * 返回当前设置的账本配置; + * + * @return + */ + @Override + public LedgerSettings getSettings() { + return settings; + } + + /** + * 返回当前参与方的数量 + * + * @return + */ + @Override + public long getParticipantCount() { + return participants.getParticipantCount(); + } + + /** + * 返回当前参与方列表 + * + * @return + */ + @Override + public ParticipantNode[] getParticipants() { + return participants.getParticipants(); + } +} diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerRepositoryImpl.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerRepositoryImpl.java index caba630f..90890e4e 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerRepositoryImpl.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerRepositoryImpl.java @@ -245,7 +245,7 @@ class LedgerRepositoryImpl implements LedgerRepository { @Override public LedgerAdminInfo getAdminInfo() { - return getAdminSettings(getLatestBlock()); + return createAdminData(getLatestBlock()); } private LedgerBlock deserialize(byte[] blockBytes) { @@ -267,7 +267,7 @@ class LedgerRepositoryImpl implements LedgerRepository { @Override public LedgerAdminInfo getAdminInfo(LedgerBlock block) { - return getAdminSettings(block); + return createAdminData(block); } @Override @@ -285,6 +285,17 @@ class LedgerRepositoryImpl implements LedgerRepository { return createAdminDataset(block); } + /** + * 生成LedgerAdminInfoData对象 + * 该对象主要用于页面展示 + * + * @param block + * @return + */ + private LedgerAdminInfoData createAdminData(LedgerBlock block) { + return new LedgerAdminInfoData(block.getAdminAccountHash(), keyPrefix, exPolicyStorage, versioningStorage, true); + } + private LedgerAdminDataset createAdminDataset(LedgerBlock block) { return new LedgerAdminDataset(block.getAdminAccountHash(), keyPrefix, exPolicyStorage, versioningStorage, true); } diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerInitSettings.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerBaseSettings.java similarity index 98% rename from source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerInitSettings.java rename to source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerBaseSettings.java index d4f287ab..7cc58594 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerInitSettings.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/LedgerBaseSettings.java @@ -14,7 +14,7 @@ import com.jd.blockchain.ledger.ParticipantNode; * @since 1.0.0 * */ -public class LedgerInitSettings { +public class LedgerBaseSettings { /** * 账本初始化种子 diff --git a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java index 838ad829..ccd5ceec 100644 --- a/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java +++ b/source/sdk/sdk-base/src/main/java/com/jd/blockchain/sdk/proxy/HttpBlockchainQueryService.java @@ -8,6 +8,8 @@ import com.jd.blockchain.transaction.BlockchainQueryService; import com.jd.blockchain.utils.http.*; import com.jd.blockchain.utils.web.client.WebResponseConverterFactory; import com.jd.blockchain.sdk.converters.HashDigestToStringConverter; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; /** * 作为内部使用的适配接口,用于声明 HTTP 协议的服务请求; @@ -194,6 +196,17 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService @Override long getAdditionalContractCount(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash); + + /** + * 获取账本信息; + * + * @param ledgerHash + * @return 账本对象;如果不存在,则返回 null; + */ + @HttpAction(method=HttpMethod.GET, path="ledgers/{ledgerHash}/admininfo") + @Override + LedgerAdminInfo getLedgerAdminInfo(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash); + /** * 返回指定账本的参与列表 * @@ -204,7 +217,6 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService @Override ParticipantNode[] getConsensusParticipants(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash); - /** * 返回指定账本的元数据 *