|
|
@@ -4,12 +4,15 @@ import java.util.LinkedHashMap; |
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
import com.jd.blockchain.binaryproto.DConstructor;
|
|
|
|
import com.jd.blockchain.binaryproto.DataContractRegistry;
|
|
|
|
import com.jd.blockchain.binaryproto.FieldSetter;
|
|
|
|
import com.jd.blockchain.crypto.AddressEncoding;
|
|
|
|
import com.jd.blockchain.crypto.HashDigest;
|
|
|
|
import com.jd.blockchain.ledger.*;
|
|
|
|
import com.jd.blockchain.ledger.BlockchainIdentity;
|
|
|
|
import com.jd.blockchain.ledger.DigitalSignature;
|
|
|
|
import com.jd.blockchain.ledger.MagicNumber;
|
|
|
|
import com.jd.blockchain.ledger.NodeRequest;
|
|
|
|
import com.jd.blockchain.ledger.TransactionContent;
|
|
|
|
import com.jd.blockchain.ledger.TransactionRequest;
|
|
|
|
import com.jd.blockchain.utils.Bytes;
|
|
|
|
|
|
|
|
/**
|
|
|
@@ -39,345 +42,344 @@ import com.jd.blockchain.utils.Bytes; |
|
|
|
*/
|
|
|
|
public class TxRequestMessage implements TransactionRequest {// , Externalizable {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 交易参与者的个数的最大值;
|
|
|
|
*/
|
|
|
|
public static final int MAX_TX_PARTICIPANT_COUNT = 0xFF;
|
|
|
|
|
|
|
|
private HashDigest hash;
|
|
|
|
|
|
|
|
private TransactionContent transactionContent;
|
|
|
|
|
|
|
|
private Map<Bytes, DigitalSignature> endpointSignatureMap = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
private Map<Bytes, DigitalSignature> nodeSignatureMap = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
// private CryptoAlgorithm defaultHashAlgorithm = CryptoAlgorithm.SHA_256;
|
|
|
|
|
|
|
|
// public TxRequestMessage() {
|
|
|
|
// }
|
|
|
|
|
|
|
|
static {
|
|
|
|
DataContractRegistry.register(NodeRequest.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
@DConstructor(name = "TxRequestMessage")
|
|
|
|
public TxRequestMessage(@FieldSetter(name = "getTransactionContent", type = "TransactionContent ")TransactionContent txContent) {
|
|
|
|
// if (!(txContent instanceof BytesWriter)) {
|
|
|
|
// throw new IllegalArgumentException("The tx content must be instance of BytesWriter!");
|
|
|
|
// }
|
|
|
|
this.transactionContent = txContent;
|
|
|
|
}
|
|
|
|
|
|
|
|
public TxRequestMessage(TransactionRequest txRequest) {
|
|
|
|
this.transactionContent = txRequest.getTransactionContent();
|
|
|
|
setHash(txRequest.getHash());
|
|
|
|
setEndpointSignatures(txRequest.getEndpointSignatures());
|
|
|
|
setNodeSignatures(txRequest.getNodeSignatures());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public TransactionContent getTransactionContent() {
|
|
|
|
return this.transactionContent;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public DigitalSignature[] getEndpointSignatures() {
|
|
|
|
return endpointSignatureMap.values().toArray(new DigitalSignature[endpointSignatureMap.size()]);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public DigitalSignature[] getNodeSignatures() {
|
|
|
|
return nodeSignatureMap.values().toArray(new DigitalSignature[nodeSignatureMap.size()]);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEndpointSignatures(Object[] endpointSignatures) {
|
|
|
|
if (endpointSignatures != null) {
|
|
|
|
for (Object object : endpointSignatures) {
|
|
|
|
DigitalSignature endpointSignature = (DigitalSignature)object;
|
|
|
|
addEndpointSignatures(endpointSignature);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setNodeSignatures(Object[] nodeSignatures) {
|
|
|
|
if (nodeSignatures != null) {
|
|
|
|
for (Object object : nodeSignatures) {
|
|
|
|
DigitalSignature nodeSignature = (DigitalSignature)object;
|
|
|
|
addNodeSignatures(nodeSignature);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void doAddEndpointSignature(DigitalSignature signature) {
|
|
|
|
Bytes address = AddressEncoding.generateAddress(signature.getPubKey());
|
|
|
|
if (endpointSignatureMap.containsKey(address)) {
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
String.format("Participant signature of Address[%s] already exist!", address));
|
|
|
|
}
|
|
|
|
endpointSignatureMap.put(address, signature);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 从参与者签名列表中检查是否包含指定的参与者;
|
|
|
|
*
|
|
|
|
* @param userBid
|
|
|
|
* 参与者的身份;
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public boolean containsEndpointSignature(BlockchainIdentity userBid) {
|
|
|
|
return endpointSignatureMap.containsKey(userBid.getAddress());
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsEndpointSignature(Bytes userAddress) {
|
|
|
|
return endpointSignatureMap.containsKey(userAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addEndpointSignatures(DigitalSignature... signature) {
|
|
|
|
for (DigitalSignature sign : signature) {
|
|
|
|
doAddEndpointSignature(sign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addEndpointSignatures(List<DigitalSignature> signature) {
|
|
|
|
for (DigitalSignature sign : signature) {
|
|
|
|
doAddEndpointSignature(sign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 从节点签名列表中检查是否包含指定的节点;
|
|
|
|
*
|
|
|
|
* @param nodeBid
|
|
|
|
* 节点的身份;
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public boolean containsNodeSignature(BlockchainIdentity nodeBid) {
|
|
|
|
return nodeSignatureMap.containsKey(nodeBid.getAddress());
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsNodeSignature(Bytes nodeAddress) {
|
|
|
|
return nodeSignatureMap.containsKey(nodeAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void doAddNodeSignatures(DigitalSignature signature) {
|
|
|
|
Bytes address = AddressEncoding.generateAddress(signature.getPubKey());
|
|
|
|
if (nodeSignatureMap.containsKey(address)) {
|
|
|
|
throw new IllegalArgumentException(String.format("Node signature of Address[%s] already exist!", address));
|
|
|
|
}
|
|
|
|
nodeSignatureMap.put(address, signature);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addNodeSignatures(DigitalSignature... signature) {
|
|
|
|
for (DigitalSignature sign : signature) {
|
|
|
|
doAddNodeSignatures(sign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addNodeSignatures(List<DigitalSignature> signature) {
|
|
|
|
for (DigitalSignature sign : signature) {
|
|
|
|
doAddNodeSignatures(sign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public HashDigest getHash() {
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setHash(HashDigest hash) {
|
|
|
|
this.hash = hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public HashDigest updateHash() {
|
|
|
|
// return computeHash(this.defaultHashAlgorithm);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public HashDigest updateHash(CryptoAlgorithm hashAlgorithm) {
|
|
|
|
// return computeHash(hashAlgorithm);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// private HashDigest computeHash(CryptoAlgorithm hashAlgorithm) {
|
|
|
|
// byte[] reqBody = getRequestBody();
|
|
|
|
// this.hash = CryptoUtils.hash(hashAlgorithm).hash(reqBody);
|
|
|
|
// return this.hash;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// @Override
|
|
|
|
// public void resolvFrom(InputStream in) throws IOException {
|
|
|
|
// // 解析校验交易请求魔数;
|
|
|
|
// byte[] buff = new byte[1];
|
|
|
|
// int len = in.read(buff, 0, 1);
|
|
|
|
// if (len < 1) {
|
|
|
|
// throw new IllegalArgumentException("No bytes was read for the magic number
|
|
|
|
// [TX_REQUEST]!");
|
|
|
|
// }
|
|
|
|
// if (MagicNumber.TX_REQUEST != buff[0]) {
|
|
|
|
// throw new IllegalArgumentException("Magic number [TX_REQUEST] dismatch!");
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 解析交易内容;
|
|
|
|
// TxContentBlob txContentBlob = new TxContentBlob();
|
|
|
|
// txContentBlob.resolvFrom(in);
|
|
|
|
//
|
|
|
|
// // 解析参与者签名列表;
|
|
|
|
// int participantCount = NumberMask.TINY.resolveMaskedNumber(in);
|
|
|
|
// List<DigitalSignature> partiSignList = new ArrayList<>();
|
|
|
|
// for (int i = 0; i < participantCount; i++) {
|
|
|
|
// DigitalSignatureBlob signature = new DigitalSignatureBlob();
|
|
|
|
// signature.resolvFrom(in);
|
|
|
|
//
|
|
|
|
// partiSignList.add(signature);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 解析节点签名列表;
|
|
|
|
// int nodeCount = NumberMask.TINY.resolveMaskedNumber(in);
|
|
|
|
// List<DigitalSignature> nodeSignList = new ArrayList<>();
|
|
|
|
// for (int i = 0; i < nodeCount; i++) {
|
|
|
|
// DigitalSignatureBlob nodeSign = new DigitalSignatureBlob();
|
|
|
|
// nodeSign.resolvFrom(in);
|
|
|
|
// nodeSignList.add(nodeSign);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 解析哈希算法标识符;
|
|
|
|
// HashAlgorithm hashAlgorithm = HashAlgorithm.valueOf((byte) in.read());
|
|
|
|
//
|
|
|
|
// // 解析原始的哈希;
|
|
|
|
// ByteArray hash = HashEncoding.read(in);
|
|
|
|
//
|
|
|
|
// this.txContent = txContentBlob;
|
|
|
|
// addParticipantSignatures(partiSignList);
|
|
|
|
// addNodeSignatures(nodeSignList);
|
|
|
|
// this.hash = hash;
|
|
|
|
//
|
|
|
|
// // 校验原始哈希;
|
|
|
|
// byte[] bodyBytes = getRequestBody();
|
|
|
|
// ByteArray rHash = HashEncoding.computeHash(bodyBytes, hashAlgorithm);
|
|
|
|
// if (!rHash.equals(hash)) {
|
|
|
|
// throw new IllegalArgumentException("The hash is not match with request
|
|
|
|
// content!");
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// /**
|
|
|
|
// * 输出交易请求消息;
|
|
|
|
// *
|
|
|
|
// * 注:此方法不会自动重新计算hash;如果消息的内容发生改变后,需要调用主动调用 {@link #updateHash()} 方法重新计算 hash;
|
|
|
|
// */
|
|
|
|
// @Override
|
|
|
|
// public void writeTo(OutputStream out) throws IOException {
|
|
|
|
// if (this.hash == null) {
|
|
|
|
// updateHash();
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// buildRequestBody(out);
|
|
|
|
//
|
|
|
|
// // 写入 hash 值;
|
|
|
|
// HashEncoding.write(hash, out);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * 生成请求体,包括:交易请求魔数、交易内容、参与者签名者列表、哈希算法代号;
|
|
|
|
// *
|
|
|
|
// * @param out
|
|
|
|
// * @throws IOException
|
|
|
|
// */
|
|
|
|
// private void buildRequestBody(OutputStream out) throws IOException {
|
|
|
|
//
|
|
|
|
// buildParticipantRequest(out);
|
|
|
|
//
|
|
|
|
// // 写入节点签名列表;
|
|
|
|
// NumberMask.TINY.writeMask(nodeSignatureMap.size(), out);
|
|
|
|
// for (DigitalSignature nodeSignatureBlob : nodeSignatureMap.values()) {
|
|
|
|
// nodeSignatureBlob.writeTo(out);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 写入 hash 算法代号;
|
|
|
|
// out.write(hashAlgorithm.getAlgorithm());
|
|
|
|
// }
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * 生成参与者的请求数据;
|
|
|
|
// *
|
|
|
|
// * <br>
|
|
|
|
// * 参与者的请求数据仅包含“交易请求模数({@link MagicNumber#TX_REQUEST })”
|
|
|
|
// * “交易内容({@link #getTransactionContent()})”
|
|
|
|
// * 和“参与者签名列表({@link #getParticipantSignatures()})”三项属性;
|
|
|
|
// *
|
|
|
|
// * @param out
|
|
|
|
// */
|
|
|
|
// public void buildParticipantRequest(OutputStream out) {
|
|
|
|
// try {
|
|
|
|
// // 写入魔数;
|
|
|
|
// out.write(MagicNumber.TX_REQUEST);
|
|
|
|
//
|
|
|
|
// // 写入交易内容;
|
|
|
|
// txContent.writeTo(out);
|
|
|
|
//
|
|
|
|
// // 写入 1 个字节的参与者签名数量;
|
|
|
|
// if (participantSignatureMap.size() > MAX_TX_PARTICIPANT_COUNT) {
|
|
|
|
// throw new IllegalArgumentException("The number of participant signatures is
|
|
|
|
// out of the max count["
|
|
|
|
// + MAX_TX_PARTICIPANT_COUNT + "]!");
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// NumberMask.TINY.writeMask(participantSignatureMap.size(), out);
|
|
|
|
// // 写入参与者签名列表;
|
|
|
|
// for (DigitalSignature digitalSignatureBlob :
|
|
|
|
// participantSignatureMap.values()) {
|
|
|
|
// digitalSignatureBlob.writeTo(out);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// } catch (IOException e) {
|
|
|
|
// throw new RuntimeIOException(e.getMessage(), e);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// @Override
|
|
|
|
// public void writeExternal(ObjectOutput out) throws IOException {
|
|
|
|
// ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
|
|
// writeTo(os);
|
|
|
|
// byte[] bts = os.toByteArray();
|
|
|
|
// out.writeInt(bts.length);
|
|
|
|
// out.write(bts);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// @Override
|
|
|
|
// public void readExternal(ObjectInput in) throws IOException,
|
|
|
|
// ClassNotFoundException {
|
|
|
|
// int len = in.readInt();
|
|
|
|
// byte[] bts = new byte[len];
|
|
|
|
// in.readFully(bts);
|
|
|
|
// this.resolvFrom(new ByteArrayInputStream(bts));
|
|
|
|
// }
|
|
|
|
|
|
|
|
// @Override
|
|
|
|
// public byte[] toBytes() {
|
|
|
|
// ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
|
// try {
|
|
|
|
// writeTo(out);
|
|
|
|
// } catch (IOException e) {
|
|
|
|
// throw new RuntimeIOException(e.getMessage(), e);
|
|
|
|
// }
|
|
|
|
// return out.toByteArray();
|
|
|
|
// }
|
|
|
|
|
|
|
|
// @Override
|
|
|
|
// public ByteArray getHashData() {
|
|
|
|
// return ByteArray.wrap(getRequestBody());
|
|
|
|
// }
|
|
|
|
|
|
|
|
// private byte[] getRequestBody() {
|
|
|
|
// try {
|
|
|
|
// ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
|
// buildRequestBody(out);
|
|
|
|
//
|
|
|
|
// return out.toByteArray();
|
|
|
|
// } catch (IOException e) {
|
|
|
|
// throw new RuntimeIOException(e.getMessage(), e);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
/**
|
|
|
|
* 交易参与者的个数的最大值;
|
|
|
|
*/
|
|
|
|
public static final int MAX_TX_PARTICIPANT_COUNT = 0xFF;
|
|
|
|
|
|
|
|
private HashDigest hash;
|
|
|
|
|
|
|
|
private TransactionContent transactionContent;
|
|
|
|
|
|
|
|
private Map<Bytes, DigitalSignature> endpointSignatureMap = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
private Map<Bytes, DigitalSignature> nodeSignatureMap = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
// private CryptoAlgorithm defaultHashAlgorithm = CryptoAlgorithm.SHA_256;
|
|
|
|
|
|
|
|
// public TxRequestMessage() {
|
|
|
|
// }
|
|
|
|
|
|
|
|
static {
|
|
|
|
DataContractRegistry.register(NodeRequest.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
public TxRequestMessage(TransactionContent txContent) {
|
|
|
|
// if (!(txContent instanceof BytesWriter)) {
|
|
|
|
// throw new IllegalArgumentException("The tx content must be instance of
|
|
|
|
// BytesWriter!");
|
|
|
|
// }
|
|
|
|
this.transactionContent = txContent;
|
|
|
|
}
|
|
|
|
|
|
|
|
public TxRequestMessage(TransactionRequest txRequest) {
|
|
|
|
this.transactionContent = txRequest.getTransactionContent();
|
|
|
|
setHash(txRequest.getHash());
|
|
|
|
setEndpointSignatures(txRequest.getEndpointSignatures());
|
|
|
|
setNodeSignatures(txRequest.getNodeSignatures());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public TransactionContent getTransactionContent() {
|
|
|
|
return this.transactionContent;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public DigitalSignature[] getEndpointSignatures() {
|
|
|
|
return endpointSignatureMap.values().toArray(new DigitalSignature[endpointSignatureMap.size()]);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public DigitalSignature[] getNodeSignatures() {
|
|
|
|
return nodeSignatureMap.values().toArray(new DigitalSignature[nodeSignatureMap.size()]);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEndpointSignatures(Object[] endpointSignatures) {
|
|
|
|
if (endpointSignatures != null) {
|
|
|
|
for (Object object : endpointSignatures) {
|
|
|
|
DigitalSignature endpointSignature = (DigitalSignature) object;
|
|
|
|
addEndpointSignatures(endpointSignature);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setNodeSignatures(Object[] nodeSignatures) {
|
|
|
|
if (nodeSignatures != null) {
|
|
|
|
for (Object object : nodeSignatures) {
|
|
|
|
DigitalSignature nodeSignature = (DigitalSignature) object;
|
|
|
|
addNodeSignatures(nodeSignature);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void doAddEndpointSignature(DigitalSignature signature) {
|
|
|
|
Bytes address = AddressEncoding.generateAddress(signature.getPubKey());
|
|
|
|
if (endpointSignatureMap.containsKey(address)) {
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
String.format("Participant signature of Address[%s] already exist!", address));
|
|
|
|
}
|
|
|
|
endpointSignatureMap.put(address, signature);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 从参与者签名列表中检查是否包含指定的参与者;
|
|
|
|
*
|
|
|
|
* @param userBid
|
|
|
|
* 参与者的身份;
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public boolean containsEndpointSignature(BlockchainIdentity userBid) {
|
|
|
|
return endpointSignatureMap.containsKey(userBid.getAddress());
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsEndpointSignature(Bytes userAddress) {
|
|
|
|
return endpointSignatureMap.containsKey(userAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addEndpointSignatures(DigitalSignature... signature) {
|
|
|
|
for (DigitalSignature sign : signature) {
|
|
|
|
doAddEndpointSignature(sign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addEndpointSignatures(List<DigitalSignature> signature) {
|
|
|
|
for (DigitalSignature sign : signature) {
|
|
|
|
doAddEndpointSignature(sign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 从节点签名列表中检查是否包含指定的节点;
|
|
|
|
*
|
|
|
|
* @param nodeBid
|
|
|
|
* 节点的身份;
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public boolean containsNodeSignature(BlockchainIdentity nodeBid) {
|
|
|
|
return nodeSignatureMap.containsKey(nodeBid.getAddress());
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsNodeSignature(Bytes nodeAddress) {
|
|
|
|
return nodeSignatureMap.containsKey(nodeAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void doAddNodeSignatures(DigitalSignature signature) {
|
|
|
|
Bytes address = AddressEncoding.generateAddress(signature.getPubKey());
|
|
|
|
if (nodeSignatureMap.containsKey(address)) {
|
|
|
|
throw new IllegalArgumentException(String.format("Node signature of Address[%s] already exist!", address));
|
|
|
|
}
|
|
|
|
nodeSignatureMap.put(address, signature);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addNodeSignatures(DigitalSignature... signature) {
|
|
|
|
for (DigitalSignature sign : signature) {
|
|
|
|
doAddNodeSignatures(sign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addNodeSignatures(List<DigitalSignature> signature) {
|
|
|
|
for (DigitalSignature sign : signature) {
|
|
|
|
doAddNodeSignatures(sign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public HashDigest getHash() {
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setHash(HashDigest hash) {
|
|
|
|
this.hash = hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public HashDigest updateHash() {
|
|
|
|
// return computeHash(this.defaultHashAlgorithm);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// public HashDigest updateHash(CryptoAlgorithm hashAlgorithm) {
|
|
|
|
// return computeHash(hashAlgorithm);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// private HashDigest computeHash(CryptoAlgorithm hashAlgorithm) {
|
|
|
|
// byte[] reqBody = getRequestBody();
|
|
|
|
// this.hash = CryptoUtils.hash(hashAlgorithm).hash(reqBody);
|
|
|
|
// return this.hash;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// @Override
|
|
|
|
// public void resolvFrom(InputStream in) throws IOException {
|
|
|
|
// // 解析校验交易请求魔数;
|
|
|
|
// byte[] buff = new byte[1];
|
|
|
|
// int len = in.read(buff, 0, 1);
|
|
|
|
// if (len < 1) {
|
|
|
|
// throw new IllegalArgumentException("No bytes was read for the magic number
|
|
|
|
// [TX_REQUEST]!");
|
|
|
|
// }
|
|
|
|
// if (MagicNumber.TX_REQUEST != buff[0]) {
|
|
|
|
// throw new IllegalArgumentException("Magic number [TX_REQUEST] dismatch!");
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 解析交易内容;
|
|
|
|
// TxContentBlob txContentBlob = new TxContentBlob();
|
|
|
|
// txContentBlob.resolvFrom(in);
|
|
|
|
//
|
|
|
|
// // 解析参与者签名列表;
|
|
|
|
// int participantCount = NumberMask.TINY.resolveMaskedNumber(in);
|
|
|
|
// List<DigitalSignature> partiSignList = new ArrayList<>();
|
|
|
|
// for (int i = 0; i < participantCount; i++) {
|
|
|
|
// DigitalSignatureBlob signature = new DigitalSignatureBlob();
|
|
|
|
// signature.resolvFrom(in);
|
|
|
|
//
|
|
|
|
// partiSignList.add(signature);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 解析节点签名列表;
|
|
|
|
// int nodeCount = NumberMask.TINY.resolveMaskedNumber(in);
|
|
|
|
// List<DigitalSignature> nodeSignList = new ArrayList<>();
|
|
|
|
// for (int i = 0; i < nodeCount; i++) {
|
|
|
|
// DigitalSignatureBlob nodeSign = new DigitalSignatureBlob();
|
|
|
|
// nodeSign.resolvFrom(in);
|
|
|
|
// nodeSignList.add(nodeSign);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 解析哈希算法标识符;
|
|
|
|
// HashAlgorithm hashAlgorithm = HashAlgorithm.valueOf((byte) in.read());
|
|
|
|
//
|
|
|
|
// // 解析原始的哈希;
|
|
|
|
// ByteArray hash = HashEncoding.read(in);
|
|
|
|
//
|
|
|
|
// this.txContent = txContentBlob;
|
|
|
|
// addParticipantSignatures(partiSignList);
|
|
|
|
// addNodeSignatures(nodeSignList);
|
|
|
|
// this.hash = hash;
|
|
|
|
//
|
|
|
|
// // 校验原始哈希;
|
|
|
|
// byte[] bodyBytes = getRequestBody();
|
|
|
|
// ByteArray rHash = HashEncoding.computeHash(bodyBytes, hashAlgorithm);
|
|
|
|
// if (!rHash.equals(hash)) {
|
|
|
|
// throw new IllegalArgumentException("The hash is not match with request
|
|
|
|
// content!");
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// /**
|
|
|
|
// * 输出交易请求消息;
|
|
|
|
// *
|
|
|
|
// * 注:此方法不会自动重新计算hash;如果消息的内容发生改变后,需要调用主动调用 {@link #updateHash()} 方法重新计算 hash;
|
|
|
|
// */
|
|
|
|
// @Override
|
|
|
|
// public void writeTo(OutputStream out) throws IOException {
|
|
|
|
// if (this.hash == null) {
|
|
|
|
// updateHash();
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// buildRequestBody(out);
|
|
|
|
//
|
|
|
|
// // 写入 hash 值;
|
|
|
|
// HashEncoding.write(hash, out);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * 生成请求体,包括:交易请求魔数、交易内容、参与者签名者列表、哈希算法代号;
|
|
|
|
// *
|
|
|
|
// * @param out
|
|
|
|
// * @throws IOException
|
|
|
|
// */
|
|
|
|
// private void buildRequestBody(OutputStream out) throws IOException {
|
|
|
|
//
|
|
|
|
// buildParticipantRequest(out);
|
|
|
|
//
|
|
|
|
// // 写入节点签名列表;
|
|
|
|
// NumberMask.TINY.writeMask(nodeSignatureMap.size(), out);
|
|
|
|
// for (DigitalSignature nodeSignatureBlob : nodeSignatureMap.values()) {
|
|
|
|
// nodeSignatureBlob.writeTo(out);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // 写入 hash 算法代号;
|
|
|
|
// out.write(hashAlgorithm.getAlgorithm());
|
|
|
|
// }
|
|
|
|
|
|
|
|
// /**
|
|
|
|
// * 生成参与者的请求数据;
|
|
|
|
// *
|
|
|
|
// * <br>
|
|
|
|
// * 参与者的请求数据仅包含“交易请求模数({@link MagicNumber#TX_REQUEST })”
|
|
|
|
// * “交易内容({@link #getTransactionContent()})”
|
|
|
|
// * 和“参与者签名列表({@link #getParticipantSignatures()})”三项属性;
|
|
|
|
// *
|
|
|
|
// * @param out
|
|
|
|
// */
|
|
|
|
// public void buildParticipantRequest(OutputStream out) {
|
|
|
|
// try {
|
|
|
|
// // 写入魔数;
|
|
|
|
// out.write(MagicNumber.TX_REQUEST);
|
|
|
|
//
|
|
|
|
// // 写入交易内容;
|
|
|
|
// txContent.writeTo(out);
|
|
|
|
//
|
|
|
|
// // 写入 1 个字节的参与者签名数量;
|
|
|
|
// if (participantSignatureMap.size() > MAX_TX_PARTICIPANT_COUNT) {
|
|
|
|
// throw new IllegalArgumentException("The number of participant signatures is
|
|
|
|
// out of the max count["
|
|
|
|
// + MAX_TX_PARTICIPANT_COUNT + "]!");
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// NumberMask.TINY.writeMask(participantSignatureMap.size(), out);
|
|
|
|
// // 写入参与者签名列表;
|
|
|
|
// for (DigitalSignature digitalSignatureBlob :
|
|
|
|
// participantSignatureMap.values()) {
|
|
|
|
// digitalSignatureBlob.writeTo(out);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// } catch (IOException e) {
|
|
|
|
// throw new RuntimeIOException(e.getMessage(), e);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// @Override
|
|
|
|
// public void writeExternal(ObjectOutput out) throws IOException {
|
|
|
|
// ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
|
|
// writeTo(os);
|
|
|
|
// byte[] bts = os.toByteArray();
|
|
|
|
// out.writeInt(bts.length);
|
|
|
|
// out.write(bts);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// @Override
|
|
|
|
// public void readExternal(ObjectInput in) throws IOException,
|
|
|
|
// ClassNotFoundException {
|
|
|
|
// int len = in.readInt();
|
|
|
|
// byte[] bts = new byte[len];
|
|
|
|
// in.readFully(bts);
|
|
|
|
// this.resolvFrom(new ByteArrayInputStream(bts));
|
|
|
|
// }
|
|
|
|
|
|
|
|
// @Override
|
|
|
|
// public byte[] toBytes() {
|
|
|
|
// ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
|
// try {
|
|
|
|
// writeTo(out);
|
|
|
|
// } catch (IOException e) {
|
|
|
|
// throw new RuntimeIOException(e.getMessage(), e);
|
|
|
|
// }
|
|
|
|
// return out.toByteArray();
|
|
|
|
// }
|
|
|
|
|
|
|
|
// @Override
|
|
|
|
// public ByteArray getHashData() {
|
|
|
|
// return ByteArray.wrap(getRequestBody());
|
|
|
|
// }
|
|
|
|
|
|
|
|
// private byte[] getRequestBody() {
|
|
|
|
// try {
|
|
|
|
// ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
|
// buildRequestBody(out);
|
|
|
|
//
|
|
|
|
// return out.toByteArray();
|
|
|
|
// } catch (IOException e) {
|
|
|
|
// throw new RuntimeIOException(e.getMessage(), e);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|