From 9a6a9e4fd166faa80b4f918bde7dffdfb2ec6796 Mon Sep 17 00:00:00 2001 From: zhangshuang Date: Mon, 6 May 2019 16:26:21 +0800 Subject: [PATCH] adjustment code --- .../statetransfer/DataSequenceReaderImpl.java | 264 +++++++------- .../statetransfer/DataSequenceWriterImpl.java | 340 +++++++++--------- .../statetransfer/DataSequence.java | 5 +- .../callback}/DataSequenceReaderImpl.java | 8 +- .../callback/DataSequenceWriter.java | 2 +- .../callback/DataSequenceWriterImpl.java | 142 ++++++++ .../statetransfer/DataSequenceWriterImpl.java | 68 ---- .../statetransfer/StateTransferLayerTest.java | 3 + 8 files changed, 453 insertions(+), 379 deletions(-) rename source/state-transfer/src/{test/java/test => main/java}/com/jd/blockchain/statetransfer/DataSequence.java (92%) rename source/state-transfer/src/{test/java/test/com/jd/blockchain/statetransfer => main/java/com/jd/blockchain/statetransfer/callback}/DataSequenceReaderImpl.java (90%) create mode 100644 source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java delete mode 100644 source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequenceWriterImpl.java diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceReaderImpl.java b/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceReaderImpl.java index 620efcc5..71161411 100644 --- a/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceReaderImpl.java +++ b/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceReaderImpl.java @@ -1,132 +1,132 @@ -package com.jd.blockchain.peer.statetransfer; - -import com.jd.blockchain.binaryproto.BinaryEncodingUtils; -import com.jd.blockchain.crypto.hash.HashDigest; -import com.jd.blockchain.ledger.LedgerBlock; -import com.jd.blockchain.ledger.LedgerTransaction; -import com.jd.blockchain.ledger.core.LedgerManage; -import com.jd.blockchain.ledger.core.LedgerRepository; -import com.jd.blockchain.ledger.core.TransactionSet; -import com.jd.blockchain.statetransfer.DataSequenceElement; -import com.jd.blockchain.statetransfer.DataSequenceInfo; -import com.jd.blockchain.statetransfer.callback.DataSequenceReader; -import com.jd.blockchain.storage.service.DbConnection; -import com.jd.blockchain.storage.service.DbConnectionFactory; -import com.jd.blockchain.tools.initializer.LedgerBindingConfig; -import com.jd.blockchain.utils.codec.Base58Utils; -import com.jd.blockchain.utils.codec.HexUtils; -import org.springframework.beans.factory.annotation.Autowired; - -/** - *数据序列差异的提供者需要使用的回调接口实现类 - * @author zhangshuang - * @create 2019/4/11 - * @since 1.0.0 - */ -public class DataSequenceReaderImpl implements DataSequenceReader { - - private LedgerManage ledgerManager; - - private DbConnectionFactory connFactory; - - private LedgerBindingConfig config; - - public DataSequenceReaderImpl(LedgerBindingConfig config, LedgerManage ledgerManager, DbConnectionFactory connFactory) { - this.config = config; - this.ledgerManager = ledgerManager; - this.connFactory = connFactory; - } - - - /** - * @param id 账本哈希的Base58编码 - * @return DataSequenceInfo 数据序列信息 - */ - @Override - public DataSequenceInfo getDSInfo(String id) { - - byte[] hashBytes = Base58Utils.decode(id); - - HashDigest ledgerHash = new HashDigest(hashBytes); - - LedgerBindingConfig.BindingConfig bindingConfig = config.getLedger(ledgerHash); - DbConnection dbConnNew = connFactory.connect(bindingConfig.getDbConnection().getUri(), - bindingConfig.getDbConnection().getPassword()); - LedgerRepository ledgerRepository = ledgerManager.register(ledgerHash, dbConnNew.getStorageService()); - - return new DataSequenceInfo(id, ledgerRepository.getLatestBlockHeight()); - } - - /** - * - * @param id 账本哈希的Base58编码 - * @param from 数据序列复制的起始高度 - * @param to 数据序列复制的结束高度 - * @return DataSequenceElement【】数据序列差异数据元素的数组 - */ - @Override - public DataSequenceElement[] getDSDiffContent(String id, long from, long to) { - - DataSequenceElement[] dataSequenceElements = new DataSequenceElement[(int)(to - from + 1)]; - for (long i = from; i < to + 1; i++) { - dataSequenceElements[(int)(i - from)] = getDSDiffContent(id, i); - } - - return dataSequenceElements; - } - - /** - * 账本交易序列化 - * @param transaction 账本交易 - * @return byte[] 对账本交易进行序列化的结果 - */ - private byte[] serialize(LedgerTransaction transaction) { - return BinaryEncodingUtils.encode(transaction, LedgerTransaction.class); - } - - /** - * 获得账本某一高度区块上的所有交易 - * @param id 账本哈希的Base58编码 - * @param height 账本的某个区块高度 - * @return DataSequenceElement 数据序列差异数据元素 - */ - @Override - public DataSequenceElement getDSDiffContent(String id, long height) { - - int lastHeightTxTotalNums = 0; - - byte[][] transacionDatas = null; - - byte[] hashBytes = Base58Utils.decode(id); - - HashDigest ledgerHash = new HashDigest(hashBytes); - - LedgerBindingConfig.BindingConfig bindingConfig = config.getLedger(ledgerHash); - DbConnection dbConnNew = connFactory.connect(bindingConfig.getDbConnection().getUri(), - bindingConfig.getDbConnection().getPassword()); - LedgerRepository ledgerRepository = ledgerManager.register(ledgerHash, dbConnNew.getStorageService()); - - LedgerBlock ledgerBlock = ledgerRepository.getBlock(height); - TransactionSet transactionSet = ledgerRepository.getTransactionSet(ledgerBlock); - - if (height > 0) { - lastHeightTxTotalNums = (int) ledgerRepository.getTransactionSet(ledgerRepository.getBlock(height - 1)).getTotalCount(); - } - - int currentHeightTxTotalNums = (int)ledgerRepository.getTransactionSet(ledgerRepository.getBlock(height)).getTotalCount(); - - // get all transactions from current height block - int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; - - LedgerTransaction[] transactions = transactionSet.getTxs(lastHeightTxTotalNums , currentHeightTxNums); - - for (int i = 0; i < transactions.length; i++) { - byte[] transactionData = serialize(transactions[i]); - transacionDatas[i] = transactionData; - } - - return new DataSequenceElement(id, height, transacionDatas); - } - - -} +//package com.jd.blockchain.peer.statetransfer; +// +//import com.jd.blockchain.binaryproto.BinaryEncodingUtils; +//import com.jd.blockchain.crypto.hash.HashDigest; +//import com.jd.blockchain.ledger.LedgerBlock; +//import com.jd.blockchain.ledger.LedgerTransaction; +//import com.jd.blockchain.ledger.core.LedgerManage; +//import com.jd.blockchain.ledger.core.LedgerRepository; +//import com.jd.blockchain.ledger.core.TransactionSet; +//import com.jd.blockchain.statetransfer.DataSequenceElement; +//import com.jd.blockchain.statetransfer.DataSequenceInfo; +//import com.jd.blockchain.statetransfer.callback.DataSequenceReader; +//import com.jd.blockchain.storage.service.DbConnection; +//import com.jd.blockchain.storage.service.DbConnectionFactory; +//import com.jd.blockchain.tools.initializer.LedgerBindingConfig; +//import com.jd.blockchain.utils.codec.Base58Utils; +//import com.jd.blockchain.utils.codec.HexUtils; +//import org.springframework.beans.factory.annotation.Autowired; +// +///** +// *数据序列差异的提供者需要使用的回调接口实现类 +// * @author zhangshuang +// * @create 2019/4/11 +// * @since 1.0.0 +// */ +//public class DataSequenceReaderImpl implements DataSequenceReader { +// +// private LedgerManage ledgerManager; +// +// private DbConnectionFactory connFactory; +// +// private LedgerBindingConfig config; +// +// public DataSequenceReaderImpl(LedgerBindingConfig config, LedgerManage ledgerManager, DbConnectionFactory connFactory) { +// this.config = config; +// this.ledgerManager = ledgerManager; +// this.connFactory = connFactory; +// } +// +// +// /** +// * @param id 账本哈希的Base58编码 +// * @return DataSequenceInfo 数据序列信息 +// */ +// @Override +// public DataSequenceInfo getDSInfo(String id) { +// +// byte[] hashBytes = Base58Utils.decode(id); +// +// HashDigest ledgerHash = new HashDigest(hashBytes); +// +// LedgerBindingConfig.BindingConfig bindingConfig = config.getLedger(ledgerHash); +// DbConnection dbConnNew = connFactory.connect(bindingConfig.getDbConnection().getUri(), +// bindingConfig.getDbConnection().getPassword()); +// LedgerRepository ledgerRepository = ledgerManager.register(ledgerHash, dbConnNew.getStorageService()); +// +// return new DataSequenceInfo(id, ledgerRepository.getLatestBlockHeight()); +// } +// +// /** +// * +// * @param id 账本哈希的Base58编码 +// * @param from 数据序列复制的起始高度 +// * @param to 数据序列复制的结束高度 +// * @return DataSequenceElement【】数据序列差异数据元素的数组 +// */ +// @Override +// public DataSequenceElement[] getDSDiffContent(String id, long from, long to) { +// +// DataSequenceElement[] dataSequenceElements = new DataSequenceElement[(int)(to - from + 1)]; +// for (long i = from; i < to + 1; i++) { +// dataSequenceElements[(int)(i - from)] = getDSDiffContent(id, i); +// } +// +// return dataSequenceElements; +// } +// +// /** +// * 账本交易序列化 +// * @param transaction 账本交易 +// * @return byte[] 对账本交易进行序列化的结果 +// */ +// private byte[] serialize(LedgerTransaction transaction) { +// return BinaryEncodingUtils.encode(transaction, LedgerTransaction.class); +// } +// +// /** +// * 获得账本某一高度区块上的所有交易 +// * @param id 账本哈希的Base58编码 +// * @param height 账本的某个区块高度 +// * @return DataSequenceElement 数据序列差异数据元素 +// */ +// @Override +// public DataSequenceElement getDSDiffContent(String id, long height) { +// +// int lastHeightTxTotalNums = 0; +// +// byte[][] transacionDatas = null; +// +// byte[] hashBytes = Base58Utils.decode(id); +// +// HashDigest ledgerHash = new HashDigest(hashBytes); +// +// LedgerBindingConfig.BindingConfig bindingConfig = config.getLedger(ledgerHash); +// DbConnection dbConnNew = connFactory.connect(bindingConfig.getDbConnection().getUri(), +// bindingConfig.getDbConnection().getPassword()); +// LedgerRepository ledgerRepository = ledgerManager.register(ledgerHash, dbConnNew.getStorageService()); +// +// LedgerBlock ledgerBlock = ledgerRepository.getBlock(height); +// TransactionSet transactionSet = ledgerRepository.getTransactionSet(ledgerBlock); +// +// if (height > 0) { +// lastHeightTxTotalNums = (int) ledgerRepository.getTransactionSet(ledgerRepository.getBlock(height - 1)).getTotalCount(); +// } +// +// int currentHeightTxTotalNums = (int)ledgerRepository.getTransactionSet(ledgerRepository.getBlock(height)).getTotalCount(); +// +// // get all transactions from current height block +// int currentHeightTxNums = currentHeightTxTotalNums - lastHeightTxTotalNums; +// +// LedgerTransaction[] transactions = transactionSet.getTxs(lastHeightTxTotalNums , currentHeightTxNums); +// +// for (int i = 0; i < transactions.length; i++) { +// byte[] transactionData = serialize(transactions[i]); +// transacionDatas[i] = transactionData; +// } +// +// return new DataSequenceElement(id, height, transacionDatas); +// } +// +// +//} diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceWriterImpl.java b/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceWriterImpl.java index 61cfde0f..774e69b5 100644 --- a/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceWriterImpl.java +++ b/source/peer/src/main/java/com/jd/blockchain/peer/statetransfer/DataSequenceWriterImpl.java @@ -1,170 +1,170 @@ -package com.jd.blockchain.peer.statetransfer; - -import com.jd.blockchain.consensus.service.MessageHandle; -import com.jd.blockchain.ledger.TransactionState; -import com.jd.blockchain.statetransfer.DataSequenceElement; -import com.jd.blockchain.statetransfer.DataSequenceInfo; -import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; -import com.jd.blockchain.statetransfer.comparator.DataSequenceComparator; - -import java.util.ArrayList; -import java.util.Collections; - -/** - *数据序列差异的请求者需要使用的回调接口实现类 - * @author zhangshuang - * @create 2019/4/11 - * @since 1.0.0 - */ -public class DataSequenceWriterImpl implements DataSequenceWriter { - - private long currHeight; - private ArrayList deceidedElements = new ArrayList(); - - private MessageHandle batchMessageHandle; - - - public DataSequenceWriterImpl(MessageHandle batchMessageHandle) { - this.batchMessageHandle = batchMessageHandle; - } - - /** - * 检查数据序列差异元素中的高度是否合理; - * @param currHeight 当前结点的账本高度 - * @param dsUpdateElements 需要更新到本地结点的数据序列元素List - * @return - */ - private int checkElementsHeight(long currHeight, ArrayList dsUpdateElements) { - boolean lossMiddleElements = false; - - // lose first element - if (currHeight + 1 < dsUpdateElements.get(0).getHeight()){ - System.out.println("Diff response loss first element error!"); - return DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE; - } - else { - for (int i = 0; i < dsUpdateElements.size(); i++) { - if (dsUpdateElements.get(i).getHeight() == currHeight + 1 + i) { - deceidedElements.add(dsUpdateElements.get(i)); - } - // lose middle elements - else { - lossMiddleElements = true; - break; - } - } - - if (lossMiddleElements) { - System.out.println("Diff response loss middle elements error!"); - return DataSequenceErrorType.DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT.CODE; - } - - System.out.println("Diff response elements height normal!"); - return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; - } - - } - - /** - * 对本地结点执行账本更新 - * @param realmName 账本哈希的Base58编码 - * @return void - */ - private void exeUpdate(String realmName) { - - for (int i = 0; i < deceidedElements.size(); i++) { - byte[][] element = deceidedElements.get(i).getData(); - - String batchId = batchMessageHandle.beginBatch(realmName); - try { - int msgId = 0; - for (byte[] txContent : element) { - batchMessageHandle.processOrdered(msgId++, txContent, realmName, batchId); - } - // 结块 - batchMessageHandle.completeBatch(realmName, batchId); - batchMessageHandle.commitBatch(realmName, batchId); - } catch (Exception e) { - // todo 需要处理应答码 404 - batchMessageHandle.rollbackBatch(realmName, batchId, TransactionState.DATA_SEQUENCE_UPDATE_ERROR.CODE); - } - } - - } - - /** - * @param dsInfo 当前结点的数据序列信息 - * @param diffContents 数据序列差异的数据元素数组 - * @return int 更新结果码 - */ - @Override - public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement[] diffContents) { - int result = 0; - - try { - ArrayList dsUpdateElements = new ArrayList(); - //remove unexpected elements - for (int i = 0 ; i < diffContents.length; i++) { - if (diffContents[i].getId().equals(dsInfo.getId())) { - dsUpdateElements.add(diffContents[i]); - } - } - - // sort elements by height - Collections.sort(dsUpdateElements, new DataSequenceComparator()); - - currHeight = dsInfo.getHeight(); - - // check element's height - result = checkElementsHeight(currHeight, dsUpdateElements); - - // cann't exe update - if (result == DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE) { - return result; - } - // exe elements update - else { - exeUpdate(dsInfo.getId()); - return result; - } - } catch (Exception e) { - System.out.println(e.getMessage()); - e.printStackTrace(); - } - - return result; - } - - @Override - public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement diffContents) { - return 0; - } - - - /** - * 数据序列更新错误码 - * @param - * @return - */ - public enum DataSequenceErrorType { - DATA_SEQUENCE_LOSS_FIRST_ELEMENT((byte) 0x1), - DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT((byte) 0x2), - DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL((byte) 0x3), - ; - public final int CODE; - - private DataSequenceErrorType(byte code) { - this.CODE = code; - } - - public static DataSequenceErrorType valueOf(byte code) { - for (DataSequenceErrorType errorType : DataSequenceErrorType.values()) { - if (errorType.CODE == code) { - return errorType; - } - } - throw new IllegalArgumentException("Unsupported code[" + code + "] of errorType!"); - } - } - -} +//package com.jd.blockchain.peer.statetransfer; +// +//import com.jd.blockchain.consensus.service.MessageHandle; +//import com.jd.blockchain.ledger.TransactionState; +//import com.jd.blockchain.statetransfer.DataSequenceElement; +//import com.jd.blockchain.statetransfer.DataSequenceInfo; +//import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; +//import com.jd.blockchain.statetransfer.comparator.DataSequenceComparator; +// +//import java.util.ArrayList; +//import java.util.Collections; +// +///** +// *数据序列差异的请求者需要使用的回调接口实现类 +// * @author zhangshuang +// * @create 2019/4/11 +// * @since 1.0.0 +// */ +//public class DataSequenceWriterImpl implements DataSequenceWriter { +// +// private long currHeight; +// private ArrayList deceidedElements = new ArrayList(); +// +// private MessageHandle batchMessageHandle; +// +// +// public DataSequenceWriterImpl(MessageHandle batchMessageHandle) { +// this.batchMessageHandle = batchMessageHandle; +// } +// +// /** +// * 检查数据序列差异元素中的高度是否合理; +// * @param currHeight 当前结点的账本高度 +// * @param dsUpdateElements 需要更新到本地结点的数据序列元素List +// * @return +// */ +// private int checkElementsHeight(long currHeight, ArrayList dsUpdateElements) { +// boolean lossMiddleElements = false; +// +// // lose first element +// if (currHeight + 1 < dsUpdateElements.get(0).getHeight()){ +// System.out.println("Diff response loss first element error!"); +// return DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE; +// } +// else { +// for (int i = 0; i < dsUpdateElements.size(); i++) { +// if (dsUpdateElements.get(i).getHeight() == currHeight + 1 + i) { +// deceidedElements.add(dsUpdateElements.get(i)); +// } +// // lose middle elements +// else { +// lossMiddleElements = true; +// break; +// } +// } +// +// if (lossMiddleElements) { +// System.out.println("Diff response loss middle elements error!"); +// return DataSequenceErrorType.DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT.CODE; +// } +// +// System.out.println("Diff response elements height normal!"); +// return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; +// } +// +// } +// +// /** +// * 对本地结点执行账本更新 +// * @param realmName 账本哈希的Base58编码 +// * @return void +// */ +// private void exeUpdate(String realmName) { +// +// for (int i = 0; i < deceidedElements.size(); i++) { +// byte[][] element = deceidedElements.get(i).getData(); +// +// String batchId = batchMessageHandle.beginBatch(realmName); +// try { +// int msgId = 0; +// for (byte[] txContent : element) { +// batchMessageHandle.processOrdered(msgId++, txContent, realmName, batchId); +// } +// // 结块 +// batchMessageHandle.completeBatch(realmName, batchId); +// batchMessageHandle.commitBatch(realmName, batchId); +// } catch (Exception e) { +// // todo 需要处理应答码 404 +// batchMessageHandle.rollbackBatch(realmName, batchId, TransactionState.DATA_SEQUENCE_UPDATE_ERROR.CODE); +// } +// } +// +// } +// +// /** +// * @param dsInfo 当前结点的数据序列信息 +// * @param diffContents 数据序列差异的数据元素数组 +// * @return int 更新结果码 +// */ +// @Override +// public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement[] diffContents) { +// int result = 0; +// +// try { +// ArrayList dsUpdateElements = new ArrayList(); +// //remove unexpected elements +// for (int i = 0 ; i < diffContents.length; i++) { +// if (diffContents[i].getId().equals(dsInfo.getId())) { +// dsUpdateElements.add(diffContents[i]); +// } +// } +// +// // sort elements by height +// Collections.sort(dsUpdateElements, new DataSequenceComparator()); +// +// currHeight = dsInfo.getHeight(); +// +// // check element's height +// result = checkElementsHeight(currHeight, dsUpdateElements); +// +// // cann't exe update +// if (result == DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE) { +// return result; +// } +// // exe elements update +// else { +// exeUpdate(dsInfo.getId()); +// return result; +// } +// } catch (Exception e) { +// System.out.println(e.getMessage()); +// e.printStackTrace(); +// } +// +// return result; +// } +// +// @Override +// public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement diffContents) { +// return 0; +// } +// +// +// /** +// * 数据序列更新错误码 +// * @param +// * @return +// */ +// public enum DataSequenceErrorType { +// DATA_SEQUENCE_LOSS_FIRST_ELEMENT((byte) 0x1), +// DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT((byte) 0x2), +// DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL((byte) 0x3), +// ; +// public final int CODE; +// +// private DataSequenceErrorType(byte code) { +// this.CODE = code; +// } +// +// public static DataSequenceErrorType valueOf(byte code) { +// for (DataSequenceErrorType errorType : DataSequenceErrorType.values()) { +// if (errorType.CODE == code) { +// return errorType; +// } +// } +// throw new IllegalArgumentException("Unsupported code[" + code + "] of errorType!"); +// } +// } +// +//} diff --git a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequence.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequence.java similarity index 92% rename from source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequence.java rename to source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequence.java index fcb932c3..237a6d47 100644 --- a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequence.java +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/DataSequence.java @@ -1,7 +1,4 @@ -package test.com.jd.blockchain.statetransfer; - -import com.jd.blockchain.statetransfer.DataSequenceElement; -import com.jd.blockchain.statetransfer.DataSequenceInfo; +package com.jd.blockchain.statetransfer; import java.net.InetSocketAddress; import java.util.LinkedList; diff --git a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequenceReaderImpl.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReaderImpl.java similarity index 90% rename from source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequenceReaderImpl.java rename to source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReaderImpl.java index 84b5477c..3d581b2d 100644 --- a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequenceReaderImpl.java +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceReaderImpl.java @@ -1,14 +1,13 @@ -package test.com.jd.blockchain.statetransfer; +package com.jd.blockchain.statetransfer.callback; +import com.jd.blockchain.statetransfer.DataSequence; import com.jd.blockchain.statetransfer.DataSequenceElement; import com.jd.blockchain.statetransfer.DataSequenceInfo; -import com.jd.blockchain.statetransfer.callback.DataSequenceReader; -import java.net.InetSocketAddress; import java.util.LinkedList; /** - * 数据序列差异的提供者需要使用的回调接口实现类(测试) + * 数据序列差异的提供者需要使用的回调接口实现类 * @author zhangshuang * @create 2019/4/22 * @since 1.0.0 @@ -57,3 +56,4 @@ public class DataSequenceReaderImpl implements DataSequenceReader { return null; } } + diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java index a38362c7..b45eb3ac 100644 --- a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriter.java @@ -25,6 +25,6 @@ public interface DataSequenceWriter { * @param diffContent 需要更新的差异元素 * @return 更新结果编码 */ - int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement diffContent); +// int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement diffContent); } diff --git a/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java new file mode 100644 index 00000000..c510e843 --- /dev/null +++ b/source/state-transfer/src/main/java/com/jd/blockchain/statetransfer/callback/DataSequenceWriterImpl.java @@ -0,0 +1,142 @@ +package com.jd.blockchain.statetransfer.callback; + +import com.jd.blockchain.statetransfer.DataSequence; +import com.jd.blockchain.statetransfer.DataSequenceElement; +import com.jd.blockchain.statetransfer.DataSequenceInfo; + +import java.util.ArrayList; + +/** + * 数据序列差异的请求者需要使用的回调接口实现类 + * @author zhangshuang + * @create 2019/4/22 + * @since 1.0.0 + */ +public class DataSequenceWriterImpl implements DataSequenceWriter { + + private long currHeight; + private DataSequence currDataSequence; + private ArrayList deceidedElements = new ArrayList(); + + public DataSequenceWriterImpl(DataSequence currDataSequence) { + this.currDataSequence = currDataSequence; + } + + /** + * 检查数据序列差异元素中的高度是否合理; + * @param currHeight 当前结点的账本高度 + * @param dsUpdateElements 需要更新到本地结点的数据序列元素List + * @return + */ + private int checkElementsHeight(long currHeight, ArrayList dsUpdateElements) { + boolean lossMiddleElements = false; + + // lose first element + if (currHeight + 1 < dsUpdateElements.get(0).getHeight()){ + System.out.println("Diff response loss first element error!"); + return DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE; + } + else { + for (int i = 0; i < dsUpdateElements.size(); i++) { + if (dsUpdateElements.get(i).getHeight() == currHeight + 1 + i) { + deceidedElements.add(dsUpdateElements.get(i)); + } + // lose middle elements + else { + lossMiddleElements = true; + break; + } + } + + if (lossMiddleElements) { + System.out.println("Diff response loss middle elements error!"); + return DataSequenceErrorType.DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT.CODE; + } + + System.out.println("Diff response elements height normal!"); + return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; + } + + } + + @Override + public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement[] diffContents) { + + int result = 0; + + try { + ArrayList dsUpdateElements = new ArrayList(); + + if (diffContents == null) { + throw new IllegalArgumentException("Update diffContents is null!"); + } + + //remove unexpected elements + for (int i = 0 ; i < diffContents.length; i++) { + if (diffContents[i].getId().equals(dsInfo.getId())) { + dsUpdateElements.add(diffContents[i]); + } + } + + currHeight = dsInfo.getHeight(); + + // check element's height + result = checkElementsHeight(currHeight, dsUpdateElements); + + // cann't exe update + if (result == DataSequenceErrorType.DATA_SEQUENCE_LOSS_FIRST_ELEMENT.CODE) { + return result; + } + // exe elements update + else { + System.out.println("Old data sequence state: "); + System.out.println(" Current height = " + currDataSequence.getDataSequenceElements().getLast().getHeight()); + currDataSequence.addElements(deceidedElements.toArray(new DataSequenceElement[deceidedElements.size()])); + + System.out.println("Update diffContents is completed!"); + System.out.println("New data sequence state: "); + System.out.println(" Current height = " + currDataSequence.getDataSequenceElements().getLast().getHeight()); + + return result; + } + + + + } catch (Exception e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + + return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; + + } + +// @Override +// public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement diffContent) { +// currDataSequence.addElement(diffContent); +// return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; +// } + + public enum DataSequenceErrorType { + DATA_SEQUENCE_LOSS_FIRST_ELEMENT((byte) 0x1), + DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT((byte) 0x2), + DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL((byte) 0x3), + ; + public final int CODE; + + private DataSequenceErrorType(byte code) { + this.CODE = code; + } + + public static DataSequenceErrorType valueOf(byte code) { + for (DataSequenceErrorType errorType : DataSequenceErrorType.values()) { + if (errorType.CODE == code) { + return errorType; + } + } + throw new IllegalArgumentException("Unsupported code[" + code + "] of errorType!"); + } + } + +} + diff --git a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequenceWriterImpl.java b/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequenceWriterImpl.java deleted file mode 100644 index c3fb037e..00000000 --- a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/DataSequenceWriterImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package test.com.jd.blockchain.statetransfer; - -import com.jd.blockchain.statetransfer.DataSequenceElement; -import com.jd.blockchain.statetransfer.DataSequenceInfo; -import com.jd.blockchain.statetransfer.callback.DataSequenceWriter; - -/** - * 数据序列差异的请求者需要使用的回调接口实现类(测试) - * @author zhangshuang - * @create 2019/4/22 - * @since 1.0.0 - */ -public class DataSequenceWriterImpl implements DataSequenceWriter { - - DataSequence currDataSequence; - - public DataSequenceWriterImpl(DataSequence currDataSequence) { - this.currDataSequence = currDataSequence; - } - - @Override - public int updateDSInfo(DataSequenceInfo dsInfo, DataSequenceElement[] diffContents) { - - if (diffContents == null) { - throw new IllegalArgumentException("Update diffContents is null!"); - } - - System.out.println("Old data sequence state: "); - System.out.println(" Current height = " + currDataSequence.getDataSequenceElements().getLast().getHeight()); - currDataSequence.addElements(diffContents); - - System.out.println("Update diffContents is completed!"); - System.out.println("New data sequence state: "); - System.out.println(" Current height = " + currDataSequence.getDataSequenceElements().getLast().getHeight()); - - - return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; - - } - - @Override - public int updateDSInfo(DataSequenceInfo id, DataSequenceElement diffContent) { - currDataSequence.addElement(diffContent); - return DataSequenceErrorType.DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL.CODE; - } - - public enum DataSequenceErrorType { - DATA_SEQUENCE_LOSS_FIRST_ELEMENT((byte) 0x1), - DATA_SEQUENCE_LOSS_MIDDLE_ELEMENT((byte) 0x2), - DATA_SEQUENCE_ELEMENT_HEIGHT_NORMAL((byte) 0x3), - ; - public final int CODE; - - private DataSequenceErrorType(byte code) { - this.CODE = code; - } - - public static DataSequenceErrorType valueOf(byte code) { - for (DataSequenceErrorType errorType : DataSequenceErrorType.values()) { - if (errorType.CODE == code) { - return errorType; - } - } - throw new IllegalArgumentException("Unsupported code[" + code + "] of errorType!"); - } - } - -} diff --git a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java b/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java index b42c0b4e..5741262e 100644 --- a/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java +++ b/source/state-transfer/src/test/java/test/com/jd/blockchain/statetransfer/StateTransferLayerTest.java @@ -1,7 +1,10 @@ package test.com.jd.blockchain.statetransfer; +import com.jd.blockchain.statetransfer.DataSequence; import com.jd.blockchain.statetransfer.DataSequenceElement; import com.jd.blockchain.statetransfer.DataSequenceInfo; +import com.jd.blockchain.statetransfer.callback.DataSequenceReaderImpl; +import com.jd.blockchain.statetransfer.callback.DataSequenceWriterImpl; import com.jd.blockchain.statetransfer.process.DSProcessManager; import com.jd.blockchain.utils.codec.Base58Utils; import org.junit.Before;