Browse Source

Refactored Encoding of MerkleTree data node;

tags/1.1.2^2
huanghaiquan 4 years ago
parent
commit
893be96105
2 changed files with 98 additions and 84 deletions
  1. +4
    -84
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleTree.java
  2. +94
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleTreeEncoder.java

+ 4
- 84
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleTree.java View File

@@ -285,7 +285,7 @@ public class MerkleTree implements Transactional {
if (sn > MAX_SN) {
throw new IllegalArgumentException("The sn is great than MAX[" + MAX_SN + "]!");
}
DataNode dataNode = DataNode.newDataNode(setting.getHashAlgorithm(), sn, key, version, hashedData);
DataNode dataNode = MerkleTreeEncoder.newDataNode(setting.getHashAlgorithm(), sn, key, version, hashedData);
updatedDataNodes.put(sn, dataNode);
return dataNode;
}
@@ -844,7 +844,7 @@ public class MerkleTree implements Transactional {
if (bytes == null || bytes.length == 0) {
return null;
}
DataNode dataNode = DataNode.parse(bytes);
DataNode dataNode = MerkleTreeEncoder.parse(bytes);
if (verify && !hashBytes.equals(dataNode.nodeHash)) {
String keyStr = hashBytes.toBase58();
String actualHashStr = dataNode.nodeHash.toBase58();
@@ -1429,7 +1429,7 @@ public class MerkleTree implements Transactional {
* @author huanghaiquan
*
*/
private static class DataNode extends AbstractMerkleNode implements MerkleDataNode {
static class DataNode extends AbstractMerkleNode implements MerkleDataNode {

private long sn;

@@ -1439,7 +1439,7 @@ public class MerkleTree implements Transactional {

private byte[] dataNodeBytes;

private DataNode(long sn, Bytes key, long version, HashDigest dataHash, byte[] dataBytes) {
DataNode(long sn, Bytes key, long version, HashDigest dataHash, byte[] dataBytes) {
this.sn = sn;
this.key = key;
this.version = version;
@@ -1447,55 +1447,6 @@ public class MerkleTree implements Transactional {
this.dataNodeBytes = dataBytes;
}

@SuppressWarnings("unused")
private static DataNode newDataNode(CryptoAlgorithm hashAlgorithm, long sn, Bytes key, long version,
byte[] hashedData) {
return newDataNode(hashAlgorithm.code(), sn, key, version, hashedData);
}

private static DataNode newDataNode(short hashAlgorithm, long sn, Bytes key, long version, byte[] hashedData) {
// byte[] keyStrBytes = BytesUtils.toBytes(key);
// int maskSize = NumberMask.SHORT.getMaskLength(keyStrBytes.length);
int keySize = key.size();
int maskSize = NumberMask.SHORT.getMaskLength(keySize);

// int bodySize = 8 + maskSize + keyStrBytes.length + 8;// sn + key + version;
int bodySize = 8 + maskSize + keySize + 8;// sn + key + version;
byte[] bodyBytes = new byte[bodySize];

int offset = 0;
offset += BytesUtils.toBytes(sn, bodyBytes, 0);

// NumberMask.SHORT.writeMask(keyStrBytes.length, bodyBytes, offset);
NumberMask.SHORT.writeMask(keySize, bodyBytes, offset);
offset += maskSize;

// System.arraycopy(keyStrBytes, 0, bodyBytes, offset, keyStrBytes.length);
// System.arraycopy(keyStrBytes, 0, bodyBytes, offset, keyStrBytes.length);
// offset += keyStrBytes.length;
offset += key.copyTo(bodyBytes, offset, keySize);

// TODO: version;
offset += BytesUtils.toBytes(version, bodyBytes, offset);

byte[] dataBytes = BytesUtils.concat(bodyBytes, hashedData);

HashFunction hashFunc = Crypto.getHashFunction(hashAlgorithm);
HashDigest dataHash = hashFunc.hash(dataBytes);

int hashMaskSize = NumberMask.TINY.getMaskLength(dataHash.size());
int dataNodeSize = bodySize + hashMaskSize + dataHash.size();
byte[] dataNodeBytes = new byte[dataNodeSize];

offset = 0;
System.arraycopy(bodyBytes, 0, dataNodeBytes, offset, bodySize);
offset += bodySize;
NumberMask.TINY.writeMask(dataHash.size(), dataNodeBytes, offset);
offset += hashMaskSize;
System.arraycopy(dataHash.toBytes(), 0, dataNodeBytes, offset, dataHash.size());

return new DataNode(sn, key, version, dataHash, dataNodeBytes);
}

@Override
protected long getStartingSN() {
@@ -1577,37 +1528,6 @@ public class MerkleTree implements Transactional {
return dataNodeBytes;
}

private static DataNode parse(byte[] bytes) {
// InputStream in = new ByteArrayInputStream(bytes);

int offset = 0;
long sn = BytesUtils.toLong(bytes, offset);
offset += 8;

// byte[] keyBytes = BytesEncoding.read(NumberMask.SHORT, in);
// String key = BytesUtils.toString(keyBytes);
int keySize = NumberMask.SHORT.resolveMaskedNumber(bytes, offset);
offset += NumberMask.SHORT.getMaskLength(keySize);
byte[] keyBytes = new byte[keySize];
System.arraycopy(bytes, offset, keyBytes, 0, keySize);
offset += keySize;
// String key = BytesUtils.toString(keyBytes);
Bytes key = new Bytes(keyBytes);

// long version = BytesUtils.readLong(in);
long version = BytesUtils.toLong(bytes, offset);
offset += 8;

// byte[] dataHashBytes = BytesEncoding.read(NumberMask.SHORT, in);
int hashSize = NumberMask.TINY.resolveMaskedNumber(bytes, offset);
offset += NumberMask.TINY.getMaskLength(hashSize);
byte[] dataHashBytes = new byte[hashSize];
System.arraycopy(bytes, offset, dataHashBytes, 0, hashSize);
offset += hashSize;
HashDigest dataHash = new HashDigest(dataHashBytes);
return new DataNode(sn, key, version, dataHash, bytes);
}

@Override
public int hashCode() {
return nodeHash.hashCode();


+ 94
- 0
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleTreeEncoder.java View File

@@ -0,0 +1,94 @@
package com.jd.blockchain.ledger.core;

import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.CryptoAlgorithm;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.HashFunction;
import com.jd.blockchain.ledger.core.MerkleTree.DataNode;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.io.BytesUtils;
import com.jd.blockchain.utils.io.NumberMask;

public class MerkleTreeEncoder {
static DataNode newDataNode(CryptoAlgorithm hashAlgorithm, long sn, Bytes key, long version,
byte[] hashedData) {
return newDataNode(hashAlgorithm.code(), sn, key, version, hashedData);
}
static DataNode newDataNode(short hashAlgorithm, long sn, Bytes key, long version, byte[] hashedData) {
// byte[] keyStrBytes = BytesUtils.toBytes(key);
// int maskSize = NumberMask.SHORT.getMaskLength(keyStrBytes.length);
int keySize = key.size();
int maskSize = NumberMask.SHORT.getMaskLength(keySize);

// int bodySize = 8 + maskSize + keyStrBytes.length + 8;// sn + key + version;
int bodySize = 8 + maskSize + keySize + 8;// sn + key + version;
byte[] bodyBytes = new byte[bodySize];

int offset = 0;
offset += BytesUtils.toBytes(sn, bodyBytes, 0);

// NumberMask.SHORT.writeMask(keyStrBytes.length, bodyBytes, offset);
NumberMask.SHORT.writeMask(keySize, bodyBytes, offset);
offset += maskSize;

// System.arraycopy(keyStrBytes, 0, bodyBytes, offset, keyStrBytes.length);
// System.arraycopy(keyStrBytes, 0, bodyBytes, offset, keyStrBytes.length);
// offset += keyStrBytes.length;
offset += key.copyTo(bodyBytes, offset, keySize);

// TODO: version;
offset += BytesUtils.toBytes(version, bodyBytes, offset);

byte[] dataBytes = BytesUtils.concat(bodyBytes, hashedData);

HashFunction hashFunc = Crypto.getHashFunction(hashAlgorithm);
HashDigest dataHash = hashFunc.hash(dataBytes);

int hashMaskSize = NumberMask.TINY.getMaskLength(dataHash.size());
int dataNodeSize = bodySize + hashMaskSize + dataHash.size();
byte[] dataNodeBytes = new byte[dataNodeSize];

offset = 0;
System.arraycopy(bodyBytes, 0, dataNodeBytes, offset, bodySize);
offset += bodySize;
NumberMask.TINY.writeMask(dataHash.size(), dataNodeBytes, offset);
offset += hashMaskSize;
System.arraycopy(dataHash.toBytes(), 0, dataNodeBytes, offset, dataHash.size());

return new DataNode(sn, key, version, dataHash, dataNodeBytes);
}
static DataNode parse(byte[] bytes) {
// InputStream in = new ByteArrayInputStream(bytes);

int offset = 0;
long sn = BytesUtils.toLong(bytes, offset);
offset += 8;

// byte[] keyBytes = BytesEncoding.read(NumberMask.SHORT, in);
// String key = BytesUtils.toString(keyBytes);
int keySize = NumberMask.SHORT.resolveMaskedNumber(bytes, offset);
offset += NumberMask.SHORT.getMaskLength(keySize);
byte[] keyBytes = new byte[keySize];
System.arraycopy(bytes, offset, keyBytes, 0, keySize);
offset += keySize;
// String key = BytesUtils.toString(keyBytes);
Bytes key = new Bytes(keyBytes);

// long version = BytesUtils.readLong(in);
long version = BytesUtils.toLong(bytes, offset);
offset += 8;

// byte[] dataHashBytes = BytesEncoding.read(NumberMask.SHORT, in);
int hashSize = NumberMask.TINY.resolveMaskedNumber(bytes, offset);
offset += NumberMask.TINY.getMaskLength(hashSize);
byte[] dataHashBytes = new byte[hashSize];
System.arraycopy(bytes, offset, dataHashBytes, 0, hashSize);
offset += hashSize;
HashDigest dataHash = new HashDigest(dataHashBytes);
return new DataNode(sn, key, version, dataHash, bytes);
}
}

Loading…
Cancel
Save