use of com.jd.blockchain.ledger.proof.MerkleSequenceTree.DataNode in project jdchain-core by blockchain-jd-com.
the class MerkleDataNodeEncoder_V0 method create.
@Deprecated
@Override
public DataNode create(short hashAlgorithm, long sn, Bytes key, long version, byte[] value) {
// Header is composed of sn, key and version;
// So the size of header is: 8 + "mask of key size" + "key bytes" + 8;
int keySize = key.size();
int maskSize = NumberMask.SHORT.getMaskLength(keySize);
int headerSize = 8 + maskSize + keySize + 8;
byte[] headerBytes = new byte[headerSize];
int offset = 0;
// write sn;
offset += BytesUtils.toBytes(sn, headerBytes, 0);
// write the size of key bytes;
NumberMask.SHORT.writeMask(keySize, headerBytes, offset);
offset += maskSize;
// write the key bytes;
offset += key.copyTo(headerBytes, offset, keySize);
// version;
offset += BytesUtils.toBytes(version, headerBytes, offset);
// compute node hash from the combination of header and data value;
byte[] dataBytes = BytesUtils.concat(headerBytes, value);
HashFunction hashFunc = Crypto.getHashFunction(hashAlgorithm);
HashDigest dataNodeHash = hashFunc.hash(dataBytes);
// build bytes of data node, which is composed of sn, key, version and node
// hash;
int hashMaskSize = NumberMask.TINY.getMaskLength(dataNodeHash.size());
int dataNodeSize = headerSize + hashMaskSize + dataNodeHash.size();
byte[] nodeBytes = new byte[dataNodeSize];
offset = 0;
System.arraycopy(headerBytes, 0, nodeBytes, offset, headerSize);
offset += headerSize;
NumberMask.TINY.writeMask(dataNodeHash.size(), nodeBytes, offset);
offset += hashMaskSize;
System.arraycopy(dataNodeHash.toBytes(), 0, nodeBytes, offset, dataNodeHash.size());
// implementation;
return new DataNode(dataNodeHash, sn, key, version, null, nodeBytes);
}
use of com.jd.blockchain.ledger.proof.MerkleSequenceTree.DataNode in project jdchain-core by blockchain-jd-com.
the class MerkleDataNodeEncoder_V1 method resolve.
/**
* Parse DataNode from it's bytes sequence;
* <p>
* the bytes sequence is: sn + key + version + data_hash;
*
* @param bytes
* @return
*/
@Override
public DataNode resolve(byte[] bytes) {
if (bytes[0] != getFormatVersion()) {
throw new IllegalArgumentException("Unsupported version of data node bytes sequence[" + bytes[0] + "]! ");
}
// resolve SN;
byte[] snBytes = new byte[8];
snBytes[0] = 0x0;
System.arraycopy(bytes, 1, snBytes, 1, 7);
long sn = BytesUtils.toLong(snBytes);
// skip bytes of SN;
int offset = 8;
// resolve key of data;
// First, resolve the number mask of the key size;
// Second, read the key bytes;
int keySize = (int) NumberMask.SHORT.resolveMaskedNumber(bytes, offset);
offset += NumberMask.SHORT.getMaskLength(keySize);
byte[] keyBytes = new byte[keySize];
System.arraycopy(bytes, offset, keyBytes, 0, keySize);
offset += keySize;
Bytes key = new Bytes(keyBytes);
// Resolve version of key;
long version = BytesUtils.toLong(bytes, offset);
offset += 8;
// resovle data hash;
int dataHashSize = (int) NumberMask.TINY.resolveMaskedNumber(bytes, offset);
offset += NumberMask.TINY.getMaskLength(dataHashSize);
byte[] dataHashBytes = new byte[dataHashSize];
System.arraycopy(bytes, offset, dataHashBytes, 0, dataHashSize);
offset += dataHashSize;
HashDigest dataHash = Crypto.resolveAsHashDigest(dataHashBytes);
// resovle node hash;
int nodeHashSize = (int) NumberMask.TINY.resolveMaskedNumber(bytes, offset);
offset += NumberMask.TINY.getMaskLength(nodeHashSize);
byte[] nodeHashBytes = new byte[nodeHashSize];
System.arraycopy(bytes, offset, nodeHashBytes, 0, nodeHashSize);
offset += nodeHashSize;
HashDigest nodeHash = Crypto.resolveAsHashDigest(nodeHashBytes);
return new DataNode(nodeHash, sn, key, version, dataHash, bytes);
}
use of com.jd.blockchain.ledger.proof.MerkleSequenceTree.DataNode in project jdchain-core by blockchain-jd-com.
the class MerkleDataNodeEncoder_V1 method create.
/**
* Data node's bytes sequence is composited by header( reference:
* {@link #buildKeyHeaderBytes(long, Bytes, long)} ) and data hash;
*
* <p>
* In general, the bytes sequence is: sn + key + version + data_hash +
* node_hash;
*
* @param hashFunc
* @param sn
* @param key
* @param version
* @param dataHash
* @return
*/
private DataNode create(HashFunction hashFunc, long sn, Bytes key, long version, HashDigest dataHash) {
byte[] headerBytes = buildKeyHeaderBytes(sn, key, version);
int headerSize = headerBytes.length;
// 单独对头部和数据进行哈希,以便在提供 Merkle 证明时能够不必传递原始数据即可进行哈希验证;
HashDigest headerHash = hashFunc.hash(headerBytes);
byte[] dataHashBytes = BytesUtils.concat(headerHash.getRawDigest(), dataHash.getRawDigest());
HashDigest dataNodeHash = hashFunc.hash(dataHashBytes);
int dataHashSize = dataHash.size();
int nodeHashSize = dataNodeHash.size();
int dataHashMaskSize = NumberMask.TINY.getMaskLength(dataHashSize);
int nodeHashMaskSize = NumberMask.TINY.getMaskLength(nodeHashSize);
int nodeSize = headerSize + dataHashMaskSize + dataHashSize + nodeHashMaskSize + nodeHashSize;
byte[] nodeBytes = new byte[nodeSize];
// write header;
int offset = 0;
System.arraycopy(headerBytes, 0, nodeBytes, offset, headerSize);
offset += headerSize;
// write data hash;
NumberMask.TINY.writeMask(dataHashSize, nodeBytes, offset);
offset += dataHashMaskSize;
System.arraycopy(dataHash.toBytes(), 0, nodeBytes, offset, dataHashSize);
offset += dataHashSize;
// write node hash;
NumberMask.TINY.writeMask(nodeHashSize, nodeBytes, offset);
offset += nodeHashMaskSize;
System.arraycopy(dataNodeHash.toBytes(), 0, nodeBytes, offset, nodeHashSize);
// set format version;
nodeBytes[0] = getFormatVersion();
return new DataNode(dataNodeHash, sn, key, version, dataHash, nodeBytes);
}
Aggregations