Browse Source

Completed test case about compatibility of Merkle DataNode bytes sequence encoding;

tags/1.1.2^2
huanghaiquan 5 years ago
parent
commit
263d1e8b8b
2 changed files with 268 additions and 20 deletions
  1. +77
    -20
      source/ledger/ledger-core/src/test/java/com/jd/blockchain/ledger/core/MerkleDataNodeEncoderTest.java
  2. +191
    -0
      source/ledger/ledger-core/src/test/java/com/jd/blockchain/ledger/core/PreviousDataNode.java

+ 77
- 20
source/ledger/ledger-core/src/test/java/com/jd/blockchain/ledger/core/MerkleDataNodeEncoderTest.java View File

@@ -18,26 +18,39 @@ public class MerkleDataNodeEncoderTest {

@Test
public void testEnocoderV0() {
MerkleDataNodeEncoder encoderV0 = new MerkleDataNodeEncoder_V0();

Random rand = new Random();

byte[] data = new byte[512];
byte[] key = new byte[256];
byte[] keyBytes = new byte[256];

rand.nextBytes(data);
rand.nextBytes(key);
rand.nextBytes(keyBytes);
Bytes key = new Bytes(keyBytes);

long sn = 1024;
long version = 1;

DataNode nodeV0 = encoderV0.create(ClassicAlgorithm.SHA256.code(), sn, new Bytes(key), version, data);
doTestV0(sn, version, key, data);
sn = 0;
version = 1000;
doTestV0(sn, version, key, data);
sn = (1 << 56) -1;
version = 1000;
doTestV0(sn, version, key, data);
}
private void doTestV0(long sn, long version, Bytes key, byte[] data) {
MerkleDataNodeEncoder encoderV0 = new MerkleDataNodeEncoder_V0();
DataNode nodeV0 = encoderV0.create(ClassicAlgorithm.SHA256.code(), sn, key, version, data);

assertNull(nodeV0.getValueHash());

assertEquals(sn, nodeV0.getSN());
assertEquals(version, nodeV0.getVersion());
assertEquals(new Bytes(key), nodeV0.getKey());
assertEquals(key, nodeV0.getKey());

byte[] nodeBytes = nodeV0.toBytes();

@@ -47,37 +60,47 @@ public class MerkleDataNodeEncoderTest {
assertEquals(nodeV0.getNodeHash(), nodeV0_reversed.getNodeHash());
assertEquals(encoderV0.getFormatVersion(), nodeBytes[0]);


assertEquals(sn, nodeV0_reversed.getSN());
assertEquals(version, nodeV0_reversed.getVersion());
assertEquals(new Bytes(key), nodeV0_reversed.getKey());
assertEquals(key, nodeV0_reversed.getKey());
}

@Test
public void testEnocoderV1() {
MerkleDataNodeEncoder encoderV1 = new MerkleDataNodeEncoder_V1();

Random rand = new Random();

byte[] data = new byte[512];
byte[] key = new byte[256];
byte[] keyBytes = new byte[256];

rand.nextBytes(data);
rand.nextBytes(key);

HashFunction hashFunc = Crypto.getHashFunction(ClassicAlgorithm.SHA256);
HashDigest dataHash = hashFunc.hash(data);
rand.nextBytes(keyBytes);
Bytes key = new Bytes(keyBytes);

long sn = 1024;
long version = 1;

DataNode node = encoderV1.create(ClassicAlgorithm.SHA256.code(), sn, new Bytes(key), version, data);
doTestV1(sn, version, key, data);
sn = 0;
version = 10088;
doTestV1(sn, version, key, data);
sn = (1 << 56) -1;
version = 1000;
doTestV1(sn, version, key, data);
}
private void doTestV1(long sn, long version, Bytes key, byte[] data) {
HashFunction hashFunc = Crypto.getHashFunction(ClassicAlgorithm.SHA256);
HashDigest dataHash = hashFunc.hash(data);
MerkleDataNodeEncoder encoderV1 = new MerkleDataNodeEncoder_V1();
DataNode node = encoderV1.create(ClassicAlgorithm.SHA256.code(), sn, key, version, data);

assertEquals(dataHash, node.getValueHash());

assertEquals(sn, node.getSN());
assertEquals(version, node.getVersion());
assertEquals(new Bytes(key), node.getKey());
assertEquals(key, node.getKey());

byte[] nodeBytes = node.toBytes();

@@ -89,8 +112,42 @@ public class MerkleDataNodeEncoderTest {

assertEquals(sn, node_reversed.getSN());
assertEquals(version, node_reversed.getVersion());
assertEquals(new Bytes(key), node_reversed.getKey());

assertEquals(key, node_reversed.getKey());
}

@Test
public void testCompatibility() {
Random rand = new Random();

byte[] data = new byte[512];
byte[] keyBytes = new byte[256];

rand.nextBytes(data);
rand.nextBytes(keyBytes);

Bytes key = new Bytes(keyBytes);

long sn = 1024;
long version = 1;


PreviousDataNode pdataNode = PreviousDataNode.newDataNode(ClassicAlgorithm.SHA256.code(), sn, key, version,
data);
MerkleDataNodeEncoder encoderV0 = new MerkleDataNodeEncoder_V0();
DataNode dataNode = encoderV0.create(ClassicAlgorithm.SHA256.code(), sn, key, version, data);
assertEquals(pdataNode.getNodeHash(), dataNode.getNodeHash());
assertEquals(pdataNode.getSN(), dataNode.getSN());
assertEquals(pdataNode.getVersion(), dataNode.getVersion());
assertEquals(pdataNode.getKey(), dataNode.getKey());
DataNode dataNode_reversed = encoderV0.resolve(pdataNode.toBytes());
assertNull(dataNode_reversed.getValueHash());
assertEquals(pdataNode.getNodeHash(), dataNode_reversed.getNodeHash());
assertEquals(pdataNode.getSN(), dataNode_reversed.getSN());
assertEquals(pdataNode.getVersion(), dataNode_reversed.getVersion());
assertEquals(pdataNode.getKey(), dataNode_reversed.getKey());
}
}

+ 191
- 0
source/ledger/ledger-core/src/test/java/com/jd/blockchain/ledger/core/PreviousDataNode.java View File

@@ -0,0 +1,191 @@
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.utils.Bytes;
import com.jd.blockchain.utils.io.BytesUtils;
import com.jd.blockchain.utils.io.NumberMask;



/**
* A copy of previous version of com.jd.blockchain.ledger.core.MerkleTree.DataNode;
*
* @author huanghaiquan
*
*/
public class PreviousDataNode {

private HashDigest nodeHash;

private long sn;

private Bytes key;

private long version;

private byte[] dataNodeBytes;

private PreviousDataNode(long sn, Bytes key, long version, HashDigest dataHash, byte[] dataBytes) {
this.sn = sn;
this.key = key;
this.version = version;
this.nodeHash = dataHash;
this.dataNodeBytes = dataBytes;
}

static PreviousDataNode newDataNode(CryptoAlgorithm hashAlgorithm, long sn, Bytes key, long version,
byte[] hashedData) {
return newDataNode(hashAlgorithm.code(), sn, key, version, hashedData);
}

static PreviousDataNode 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 PreviousDataNode(sn, key, version, dataHash, dataNodeBytes);
}

public HashDigest getNodeHash() {
return nodeHash;
}

protected long getStartingSN() {
return sn;
}

protected long getDataCount() {
return 1;
}

/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.core.MerkleDataNode#getLevel()
*/
public int getLevel() {
return 0;
}

/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.core.MerkleDataNode#getSN()
*/
public long getSN() {
return sn;
}

/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.core.MerkleDataNode#getKey()
*/
public Bytes getKey() {
return key;
}

/*
* (non-Javadoc)
*
* @see com.jd.blockchain.ledger.core.MerkleDataNode#getVersion()
*/
public long getVersion() {
return version;
}

public byte[] toBytes() {
return dataNodeBytes;
}

static PreviousDataNode 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 PreviousDataNode(sn, key, version, dataHash, bytes);
}

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

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj instanceof PreviousDataNode) {
PreviousDataNode node1 = (PreviousDataNode) obj;
return this.nodeHash.equals(node1.nodeHash);
}
return false;
}

}

Loading…
Cancel
Save