summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <me@fwei.tk>2019-07-11 23:47:08 -0400
committerFranklin Wei <me@fwei.tk>2019-07-11 23:47:08 -0400
commitca2f7d7fdb9ea3321c122bbb6e05d03c35a0b063 (patch)
tree2035e6ab25b86706d0aff76808494a92229b22c4
parent083d69046f1176d3548bb413298298adb3667957 (diff)
downloaddcr-ca2f7d7fdb9ea3321c122bbb6e05d03c35a0b063.zip
dcr-ca2f7d7fdb9ea3321c122bbb6e05d03c35a0b063.tar.gz
dcr-ca2f7d7fdb9ea3321c122bbb6e05d03c35a0b063.tar.bz2
dcr-ca2f7d7fdb9ea3321c122bbb6e05d03c35a0b063.tar.xz
Add leaf lookup by virtual index
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/DCRChaincode.java118
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/FabricIOMT.java33
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMT.java63
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTLeaf.java4
-rwxr-xr-xjava-chaincode/deploy.sh4
5 files changed, 166 insertions, 56 deletions
diff --git a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/DCRChaincode.java b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/DCRChaincode.java
index 51b151c..6590da5 100644
--- a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/DCRChaincode.java
+++ b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/DCRChaincode.java
@@ -32,8 +32,8 @@ public class DCRChaincode extends ChaincodeBase {
// Testing use only. Will be disabled for production.
public static final String GET_NODE_FUNCTION = "getNode";
public static final String SET_NODE_FUNCTION = "setNode";
- public static final String GET_LEAF_FUNCTION = "getLeaf";
- public static final String SET_LEAF_FUNCTION = "setLeaf";
+ public static final String GET_VIRTLEAF_FUNCTION = "getLeafVirtual";
+ public static final String SET_PHYSLEAF_FUNCTION = "setLeafPhysical";
public static final String GET_HEADER_FUNCTION = "getHeader"; // get header only
@Override
@@ -51,23 +51,44 @@ public class DCRChaincode extends ChaincodeBase {
List<String> paramList = chaincodeStub.getParameters();
IntStream.range(0,paramList.size()).forEach(idx -> LOG.info("value of param: " + idx + " is: "+paramList.get(idx)));
- if (INIT_FUNCTION.equalsIgnoreCase(functionName)) {
+ if (INIT_FUNCTION.equalsIgnoreCase(functionName))
+ {
return performInitOperation(chaincodeStub, paramList);
- } else if (INVOKE_FUNCTION.equalsIgnoreCase(functionName)) {
+ }
+ else if (INVOKE_FUNCTION.equalsIgnoreCase(functionName))
+ {
return performInvokeOperation(chaincodeStub, paramList);
- } else if (QUERY_FUNCTION.equalsIgnoreCase(functionName)) {
+ }
+ else if (QUERY_FUNCTION.equalsIgnoreCase(functionName))
+ {
return performQueryOperation(chaincodeStub, paramList);
- } else if( GET_NODE_FUNCTION.equalsIgnoreCase(functionName)) {
- return performQueryNodeFunction(chaincodeStub, paramList);
- } else if (QUERY_HISTORY_FUNCTION.equalsIgnoreCase(functionName)){
+ }
+ else if (QUERY_HISTORY_FUNCTION.equalsIgnoreCase(functionName))
+ {
return performQueryByHistoryFunction(chaincodeStub, paramList);
- } else if (SET_NODE_FUNCTION.equalsIgnoreCase(functionName)) {
+ }
+ else if( GET_NODE_FUNCTION.equalsIgnoreCase(functionName))
+ {
+ return performQueryNodeFunction(chaincodeStub, paramList);
+ }
+ else if (SET_NODE_FUNCTION.equalsIgnoreCase(functionName))
+ {
return performSetNodeOperation(chaincodeStub, paramList);
- } else if (GET_HEADER_FUNCTION.equalsIgnoreCase(functionName)) {
+ }
+ else if( GET_VIRTLEAF_FUNCTION.equalsIgnoreCase(functionName))
+ {
+ return performQueryLeafFunction(chaincodeStub, paramList);
+ }
+ else if (SET_PHYSLEAF_FUNCTION.equalsIgnoreCase(functionName))
+ {
+ return performSetLeafOperation(chaincodeStub, paramList);
+ }
+ else if (GET_HEADER_FUNCTION.equalsIgnoreCase(functionName))
+ {
return performGetHeaderOperation(chaincodeStub, paramList);
}
- else return newErrorResponse(functionName + " function is currently " +
- "not supported blah blah" + GET_NODE_FUNCTION);
+ else
+ return newErrorResponse(functionName + " function is currently supported");
}
private Response performQueryByHistoryFunction(ChaincodeStub chaincodeStub, List<String> paramList) {
@@ -195,6 +216,79 @@ public class DCRChaincode extends ChaincodeBase {
}
}
+ private Response performQueryLeafFunction(ChaincodeStub chaincodeStub, List<String> paramList) {
+ if (listHasDifferentSizeThen(paramList, 2)) {
+ return newErrorResponse("incorrect number of arguments");
+ }
+
+ String iomt_name = paramList.get(0);
+
+ if(!FabricIOMT.treeExists(chaincodeStub, iomt_name)) {
+ return newErrorResponse("IOMT does not exist");
+ }
+
+ try {
+ FabricIOMT iomt = new FabricIOMT(chaincodeStub, iomt_name);
+
+ String id_s = paramList.get(1);
+ if(!StringUtils.isNumeric(id_s)) {
+ return newErrorResponse("leaf id must be numeric");
+ }
+
+ int id = Integer.valueOf(id_s);
+
+ IOMTLeaf leaf = iomt.getLeafVirtual(id);
+
+ return newSuccessResponse(leaf.toString());
+ } catch (IndexOutOfBoundsException e) {
+ return newErrorResponse(e.getMessage());
+ } catch (JSONException e) {
+ return newErrorResponse("corrupt JSON");
+ }
+ }
+
+ private Response performSetLeafOperation(ChaincodeStub chaincodeStub,
+ List<String> paramList) {
+ if (listHasDifferentSizeThen(paramList, 5)) {
+ return newErrorResponse("incorrect number of arguments");
+ }
+
+ String iomt_name = paramList.get(0);
+
+ try {
+ FabricIOMT iomt = new FabricIOMT(chaincodeStub, iomt_name);
+
+ String physIdx_str, idx_str, nextIdx_str, val;
+
+ physIdx_str = paramList.get(1);
+ idx_str = paramList.get(2);
+ nextIdx_str = paramList.get(3);
+ val = paramList.get(4);
+
+ if(!StringUtils.isNumeric(physIdx_str) || !StringUtils.isNumeric(idx_str) ||
+ !StringUtils.isNumeric(nextIdx_str) || !IOMT.isValidHash(val)) {
+ return newErrorResponse("invalid arguments");
+ }
+
+ int physIdx = Integer.valueOf(idx_str);
+ int idx = Integer.valueOf(idx_str);
+ int nextIdx = Integer.valueOf(nextIdx_str);
+
+ if(!iomt.isValidLeafPhysIdx(physIdx) || !iomt.isValidLeafVirtIdx(idx) ||
+ !iomt.isValidLeafVirtIdx(nextIdx)) {
+ return newErrorResponse("invalid index(es)");
+ }
+
+ IOMTLeaf newLeaf = new IOMTLeaf(idx, nextIdx, val);
+
+ iomt.setLeafPhysical(physIdx, newLeaf);
+
+ return newSuccessResponse(newLeaf.toString());
+ } catch (Exception e) {
+ return newErrorResponse(e.getMessage());
+ }
+ }
+
private Response performInitOperation(ChaincodeStub chaincodeStub, List<String> paramList) {
if(listHasDifferentSizeThen(paramList, 2)) {
return newErrorResponse("incorrect number of arguments");
diff --git a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/FabricIOMT.java b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/FabricIOMT.java
index 3bdc63f..9e31068 100644
--- a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/FabricIOMT.java
+++ b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/FabricIOMT.java
@@ -1,12 +1,12 @@
package tk.fwei.dcr;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import org.hyperledger.fabric.shim.ChaincodeStub;
import org.hyperledger.fabric.shim.ledger.CompositeKey;
import org.hyperledger.fabric.shim.ledger.KeyValue;
import org.hyperledger.fabric.shim.ledger.QueryResultsIterator;
import org.json.JSONException;
import org.json.JSONObject;
-
import java.util.Iterator;
/**
@@ -133,7 +133,7 @@ public class FabricIOMT extends IOMT {
*/
public JSONObject toJSON() throws JSONException {
JSONObject obj = new JSONObject();
-
+4
try {
obj.put("height", Integer.toString(height));
obj.put("name", name);
@@ -152,7 +152,7 @@ public class FabricIOMT extends IOMT {
* @throws IndexOutOfBoundsException
*/
public String getNode(int node_id) throws IndexOutOfBoundsException {
- if (invalidNodeId(node_id)) {
+ if (!isValidNodeIdx(node_id)) {
throw new IndexOutOfBoundsException("out of bounds" + getMaxNodeId() + " " + height + (1 << height));
}
@@ -189,12 +189,13 @@ public class FabricIOMT extends IOMT {
public void setNode(int nodeId, String val) {
if (!isValidHash(val))
throw new RuntimeException("invalid hash");
- if (invalidNodeId(nodeId))
+ if (!isValidNodeIdx(nodeId))
throw new RuntimeException("out of bounds");
JSONObject node = new JSONObject();
try {
node.put("docType", "iomtnode");
+ node.put("parentIOMT", this.name);
node.put("val", val);
} catch (JSONException e) {
throw new RuntimeException("err");
@@ -228,7 +229,7 @@ public class FabricIOMT extends IOMT {
}
public IOMTLeaf getLeafPhysical(int leafId) {
- if (!isValidLeafId(leafId)) {
+ if (!isValidLeafPhysIdx(leafId)) {
throw new IndexOutOfBoundsException("out of bounds");
}
@@ -243,6 +244,7 @@ public class FabricIOMT extends IOMT {
JSONObject leaf = new JSONObject();
try {
leaf.put("docType", "iomtleaf");
+ leaf.put("parentIOMT", this.name);
leaf.put("idx", val.getIdx());
leaf.put("nextIdx", val.getNextIdx());
leaf.put("val", val.getVal());
@@ -254,7 +256,7 @@ public class FabricIOMT extends IOMT {
leaf.toString());
}
- public Pair<IOMTLeaf, Integer> getLeafVirtual(int virtIdx) {
+ public ImmutablePair<IOMTLeaf, Integer> getLeafAndPhysIdxVirtual(int virtIdx) {
// TODO: couchdb query
// build query string (see CouchDB docs)
@@ -264,38 +266,41 @@ public class FabricIOMT extends IOMT {
QueryResultsIterator results;
try {
selector.put("docType", "iomtleaf");
+ selector.put("parentIOMT", this.name);
selector.put("idx", virtIdx);
jsonQuery.put("selector", selector);
results = chaincodeStub.getQueryResult(jsonQuery.toString());
- } catch(JSONException e) {
+ } catch (JSONException e) {
throw new RuntimeException("json error");
}
Iterator<KeyValue> iterator = results.iterator();
- if(!iterator.hasNext())
+ if (!iterator.hasNext())
throw new IndexOutOfBoundsException("no leaf found with given index");
KeyValue pair = iterator.next();
String keyString = pair.getKey();
CompositeKey key = chaincodeStub.splitCompositeKey(keyString);
+ assert(key.getAttributes().get(0).equals(this.name));
+
// get physical index
- int physIdx = Integer.parseInt(key.getAttributes().get(0));
+ int physIdx = Integer.parseInt(key.getAttributes().get(1));
// get leaf fields
IOMTLeaf leaf = parseLeaf(pair.getStringValue());
- return new Pair<IOMTLeaf, Integer>(leaf, physIdx);
+ return new ImmutablePair<IOMTLeaf, Integer>(leaf, physIdx);
}
- public Pair<IOMTLeaf, Integer> getEncloser(int virtIdx) {
- return new IOMTLeaf();
+ public ImmutablePair<IOMTLeaf, Integer> getEncloser(int virtIdx) {
+ return new ImmutablePair(new IOMTLeaf(), 0);
}
- public Pair<IOMTLeaf, Integer> getLeafOrEncloser(int virtIdx) {
- return new IOMTLeaf();
+ public ImmutablePair<IOMTLeaf, Integer> getLeafOrEncloser(int virtIdx) {
+ return new ImmutablePair(new IOMTLeaf(), 0);
}
} \ No newline at end of file
diff --git a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMT.java b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMT.java
index 7322b0d..cb55e48 100644
--- a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMT.java
+++ b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMT.java
@@ -1,7 +1,7 @@
package tk.fwei.dcr;
import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import java.security.MessageDigest;
@@ -106,7 +106,7 @@ public abstract class IOMT {
}
}
- private boolean charIsHex(char c) {
+ private static boolean charIsHex(char c) {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@@ -119,7 +119,7 @@ public abstract class IOMT {
}
}
- private boolean isAllHex(String str) {
+ private static boolean isAllHex(String str) {
for(int i = 0; i < str.length(); i++) {
if(!charIsHex(str.charAt(i)))
return false;
@@ -127,7 +127,7 @@ public abstract class IOMT {
return true;
}
- public boolean isValidHash(String hash) {
+ public static boolean isValidHash(String hash) {
return hash.length() == HASH_LEN && isAllHex(hash);
}
@@ -136,8 +136,8 @@ public abstract class IOMT {
return (1 << (height + 1)) - 1;
}
- public boolean invalidNodeId(int node_id) {
- return node_id < 0 || node_id > getMaxNodeId();
+ public boolean isValidNodeIdx(int node_id) {
+ return !(node_id < 0 || node_id > getMaxNodeId());
}
public int getMaxLeafId() {
@@ -145,10 +145,19 @@ public abstract class IOMT {
return (1 << height) - 1;
}
- public boolean isValidLeafId(int leafId) {
+ public boolean isValidLeafPhysIdx(int leafId) {
return !(leafId < 0 || leafId > getMaxLeafId());
}
+ public boolean isValidLeafVirtIdx(int virtIdx) {
+ return virtIdx > 0;
+ }
+
+ static private int bintreeParent(int idx)
+ {
+ return (idx - 1) / 2;
+ }
+
/* Implementations must implement the following */
abstract public String getNode(int node_id);
@@ -156,7 +165,7 @@ public abstract class IOMT {
/**
* Look up a leaf's value (a 3-tuple of index, nextIndex, and value) by its PHYSICAL
- * index--not its virtual index. Use getLeafVirtual if you want that.
+ * index--not its virtual index. Use getLeafAndPhysIdxVirtual if you want that.
* @param leaf_id
* @return
*/
@@ -172,11 +181,15 @@ public abstract class IOMT {
* @param virtIdx virtual index of leaf
* @return a pair containing the leaf's contents and its physical index in the tree
*/
- abstract public Pair<IOMTLeaf, Integer> getLeafVirtual(int virtIdx);
+ abstract public ImmutablePair<IOMTLeaf, Integer> getLeafAndPhysIdxVirtual(int virtIdx);
- abstract public Pair<IOMTLeaf, Integer> getEncloser(int virtIdx);
+ abstract public ImmutablePair<IOMTLeaf, Integer> getEncloser(int virtIdx);
- abstract public Pair<IOMTLeaf, Integer> getLeafOrEncloser(int virtIdx);
+ abstract public ImmutablePair<IOMTLeaf, Integer> getLeafOrEncloser(int virtIdx);
+
+ public IOMTLeaf getLeafVirtual(int virtIdx) {
+ return getLeafAndPhysIdxVirtual(virtIdx).getLeft();
+ }
/**
* Change the value of a level-0 NODE in the tree--NOT a leaf. Update will propagate
@@ -240,18 +253,12 @@ public abstract class IOMT {
updateLeafPhysicalFull(physIdx, old);
}
- static private int bintreeParent(int idx)
- {
- return (idx - 1) / 2;
- }
-
/**
/* Convenience functions. */
public void updateLeafVirtualFull(int virtIdx, IOMTLeaf newLeaf) {
- Integer physIdx = -1;
-
- getLeafVirtual(virtIdx, physIdx);
+ ImmutablePair<IOMTLeaf, Integer> leafPair = getLeafAndPhysIdxVirtual(virtIdx);
+ int physIdx = leafPair.getRight();
if(physIdx < 0)
throw new RuntimeException("leaf not found");
@@ -260,9 +267,9 @@ public abstract class IOMT {
}
public void updateLeafVirtualIdx(int virtIdx, int newIdx) {
- Integer physIdx = -1;
-
- IOMTLeaf old = getLeafVirtual(virtIdx, physIdx);
+ ImmutablePair<IOMTLeaf, Integer> leafPair = getLeafAndPhysIdxVirtual(virtIdx);
+ IOMTLeaf old = leafPair.getLeft();
+ int physIdx = leafPair.getRight();
if(physIdx < 0)
throw new RuntimeException("leaf not found");
@@ -273,9 +280,9 @@ public abstract class IOMT {
}
public void updateLeafVirtualNextIdx(int virtIdx, int newNextIdx) {
- Integer physIdx = -1;
-
- IOMTLeaf old = getLeafVirtual(virtIdx, physIdx);
+ ImmutablePair<IOMTLeaf, Integer> leafPair = getLeafAndPhysIdxVirtual(virtIdx);
+ IOMTLeaf old = leafPair.getLeft();
+ int physIdx = leafPair.getRight();
if(physIdx < 0)
throw new RuntimeException("leaf not found");
@@ -286,9 +293,9 @@ public abstract class IOMT {
}
public void updateLeafVirtualVal(int virtIdx, String hash) {
- Integer physIdx = -1;
-
- IOMTLeaf old = getLeafVirtual(virtIdx, physIdx);
+ ImmutablePair<IOMTLeaf, Integer> leafPair = getLeafAndPhysIdxVirtual(virtIdx);
+ IOMTLeaf old = leafPair.getLeft();
+ int physIdx = leafPair.getRight();
if(physIdx < 0)
throw new RuntimeException("leaf not found");
diff --git a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTLeaf.java b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTLeaf.java
index 6214486..4822027 100644
--- a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTLeaf.java
+++ b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTLeaf.java
@@ -37,6 +37,10 @@ public class IOMTLeaf {
//return IOMT.ZERO_HASH;
}
+ public String toString() {
+ return "(" + getIdx() + ", " + getNextIdx() + ", " + getVal() + ")";
+ }
+
public IOMTLeaf(int idx, int nextIdx, String val) {
setIdx(idx);
setNextIdx(nextIdx);
diff --git a/java-chaincode/deploy.sh b/java-chaincode/deploy.sh
index b9aa221..19ac6e6 100755
--- a/java-chaincode/deploy.sh
+++ b/java-chaincode/deploy.sh
@@ -2,10 +2,10 @@
export ID=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 10)
-docker images | grep dev-peer | awk '{print $1}' | xargs docker rmi
+docker images | grep dev-peer | awk '{print $1}' | xargs docker rmi -f
docker exec cli peer chaincode install -l java -n $ID -v v1 -p /opt/gopath/src/github.com/chaincode/
sleep 5
docker exec cli peer chaincode instantiate -o orderer.mydomain.com:7050 -C mychannel -n $ID -v v1 -c '{"Args":[]}' -P 'OR ("Org1MSP.member")'
echo $ID | tee .ccid
-echo "Name written to .ccid" \ No newline at end of file
+echo "Name written to .ccid"