summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <me@fwei.tk>2019-08-08 22:03:57 -0400
committerFranklin Wei <me@fwei.tk>2019-08-08 22:06:52 -0400
commit3f00bd392b466bbc959ff8e1541792060cbd049c (patch)
treeb561b55cd911464a52e7157e6a7e198ef7b59398
parente857918f4872f0a15276c1f6a31a1048b98b98bc (diff)
downloaddcr-3f00bd392b466bbc959ff8e1541792060cbd049c.zip
dcr-3f00bd392b466bbc959ff8e1541792060cbd049c.tar.gz
dcr-3f00bd392b466bbc959ff8e1541792060cbd049c.tar.bz2
dcr-3f00bd392b466bbc959ff8e1541792060cbd049c.tar.xz
Work on application functionalityHEADmaster
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/DCRChaincode.java234
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/FabricIOMT.java2
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMT.java6
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTLeaf.java2
-rw-r--r--java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTNode.java11
5 files changed, 253 insertions, 2 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 261c083..c5b17b9 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
@@ -42,6 +42,12 @@ public class DCRChaincode extends ChaincodeBase {
public static final String GET_HEADER_FUNCTION = "getHeader"; // get header only
+ public static final String CREATE_IMAGE_FUNCTION = "createImage";
+ public static final String QUERY_IMAGE_FUNCTION = "queryImage";
+ public static final String QUERY_VERSION_FUNCTION = "queryVersion";
+ public static final String UPDATE_IMAGE_FUNCTION = "updateImage";
+ public static final String UPDATE_ACL_FUNCTION = "updateACL";
+
@Override
public Response init(ChaincodeStub chaincodeStub) {
return newSuccessResponse();
@@ -101,10 +107,238 @@ public class DCRChaincode extends ChaincodeBase {
{
return performEncloserLookupOperation(chaincodeStub, paramList);
}
+ else if (CREATE_IMAGE_FUNCTION.equalsIgnoreCase(functionName))
+ {
+ return performCreateImageOperation(chaincodeStub, paramList);
+ }
else
return newErrorResponse(functionName + " function is currently supported");
}
+ /* creator[] is a unique byte array to each client. We don't care too much
+ * about its exact contents, just that it's unique. */
+ private String getUserId(byte [] creator) {
+ return DigestUtils.sha256Hex(creator);
+ }
+
+ /* h(user | imageName) */
+ private String computeImageKey(String userId, String name) {
+ String cat = userId + name;
+ return DigestUtils.sha256Hex(cat);
+ }
+
+ private String getTrustedRoot(ChaincodeStub chaincodeStub) {
+ return chaincodeStub.getStringState("root");
+ }
+
+ private class LeafLookupResult {
+ public boolean exists;
+
+ /* No pointer semantics here. Updates will not be reflected in the
+ * in-state tree.
+ */
+ public IOMTLeaf leaf;
+ public int physIdx;
+
+ /*
+ * Complementary nodes to `leaf', ordered by nearest first.
+ */
+ public IOMTNode [] compNodes;
+ }
+
+ /**
+ * Take the first 4 bytes of a hash and convert it to a 32-bit int.
+ * Definitely a hack because we now lose collision resistance in the
+ * namespace. However, this is good enough for a proof-of-concept.
+ */
+ private static int intFromHash(String hash) {
+ return 0; // TODO
+ }
+
+ String merkleCompute(String leafNode, IOMTNode [] comp) {
+ return ""; // TODO
+ }
+
+ /**
+ * Prove that some leaf with index `key' exists in IOMT `tree' (whose
+ * root must match the trusted root `root'.
+ */
+ private LeafLookupResult proveExists(String root, FabricIOMT tree,
+ int virtIdx) throws RuntimeException {
+ ImmutablePair<IOMTLeaf, Integer> pair;
+ LeafLookupResult result = new LeafLookupResult();
+ result.exists = false;
+
+ try {
+ pair = tree.getLeafAndPhysIdxVirtual(virtIdx);
+
+ IOMTLeaf leaf = pair.getLeft();
+ int physIdx = pair.getRight();
+
+ IOMTNode [] compnodes = tree.getComplementary(physIdx);
+
+ String supposedRoot = merkleCompute(leaf.hash(), compnodes);
+
+ if(!supposedRoot.equalsIgnoreCase(root)) {
+ // we're being lied to by the StateDB... bail out!
+ throw new RuntimeException("trusted root inconsistent");
+ }
+
+ // success
+ result.exists = true;
+ result.leaf = leaf;
+ result.physIdx = physIdx;
+ result.compNodes = compnodes;
+
+ return result;
+ } catch (IndexOutOfBoundsException e) {
+ // will be empty
+ return result;
+ }
+ }
+
+ /**
+ * Prove whether `virtIdx' is enclosed in the tree with root `root', and
+ * if so, return some useful data.
+ *
+ * @param root Trusted root. All values must be consistent with this.
+ * @param tree Handle to Fabric-backed IOMTs
+ * @param virtIdx Enclosed index
+ * @return exist = true if some leaf encloses virtIdx
+ * @throws RuntimeException
+ */
+ private LeafLookupResult proveEncloser(String root, FabricIOMT tree,
+ int virtIdx) throws
+ RuntimeException {
+ ImmutablePair<IOMTLeaf, Integer> pair;
+ LeafLookupResult result = new LeafLookupResult();
+ result.exists = false;
+
+ try {
+ pair = tree.getEncloser(virtIdx);
+
+ IOMTLeaf leaf = pair.getLeft();
+ int physIdx = pair.getRight();
+
+ IOMTNode [] compnodes = tree.getComplementary(physIdx);
+
+ String supposedRoot = merkleCompute(leaf.hash(), compnodes);
+
+ if(!supposedRoot.equalsIgnoreCase(root)) {
+ // we're being lied to by the StateDB... bail out!
+ throw new RuntimeException("trusted root inconsistent");
+ }
+
+ // success
+ result.exists = true;
+ result.leaf = leaf;
+ result.physIdx = physIdx;
+ result.compNodes = compnodes;
+
+ return result;
+ } catch (IndexOutOfBoundsException e) {
+ // will be empty
+ return result;
+ }
+ }
+
+ /**
+ * Compute the ancestor values of a Merkle tree node given its value and
+ * those of its complements. [0] is just `node' itself. [1] is the value
+ * of `node's immediate parent, and so on.
+ *
+ *
+ */
+ private IOMTNode [] merkleComputeParents(String node, IOMTNode [] comp) {
+
+ }
+
+ private void updateChangedNodes(IOMTNode [] dest, IOMTNode [] updated) {
+
+ }
+
+ /**
+ * Insert (key -> value) into IOMT `tree' with a trusted `root'.
+ * Nodes/leaves must be consistent with this root, or else this function
+ * will fail.
+ */
+ private String trustedInsert(String root, FabricIOMT tree, int key,
+ String value) {
+ LeafLookupResult result;
+
+ result = proveEncloser(root, tree, key);
+
+ if(!result.exists) {
+ throw new RuntimeException("key to insert already exists");
+ }
+
+ assert(merkleCompute(result.leaf.hash(),result.compNodes).equalsIgnoreCase(root));
+
+ IOMTLeaf encloser = result.leaf;
+
+ int oldNextIdx = encloser.getNextIdx();
+
+ encloser.setNextIdx(key);
+
+ /* root with idx' changed to key */
+ IOMTNode [] parentsOfEncloser = merkleComputeParents(encloser.hash(),
+ result.compNodes);
+
+ /* We now compute the resulting tree from the new key->value pair */
+ int newPhysIdx = tree.getEmptyLeafSlot();
+ IOMTNode [] newLeafComp = tree.getComplementary(newPhysIdx);
+
+ /* Cause any changes caused by E -> E' which are in L_comp to be
+ * reflected. */
+ updateChangedNodes(newLeafComp, parentsOfEncloser);
+
+ tree.updateLeafPhysicalFull(result.physIdx, encloser);
+
+ assert(tree.getNode(0)
+ .equalsIgnoreCase(merkleCompute(encloser.hash(),
+ result.compNodes)));
+ }
+
+ private Response performCreateImageOperation(ChaincodeStub chaincodeStub,
+ List<String> paramList) {
+ //return newSuccessResponse(chaincodeStub.getCreator());
+ //return newErrorResponse("not implemented");
+
+ if(listHasDifferentSizeThen(paramList,1)) {
+ return newErrorResponse("incorrect number of arguments");
+ }
+
+ String imageName = paramList.get(0);
+
+ String userId = getUserId(chaincodeStub.getCreator());
+
+ String K = computeImageKey(userId, imageName);
+
+ LOG.info("userId: " + userId + " K: " + K);
+
+ String root = getTrustedRoot(chaincodeStub);
+
+ FabricIOMT base;
+ try {
+ base = new FabricIOMT(chaincodeStub, "base");
+
+ LeafLookupResult result = proveExists(root, base, intFromHash(K));
+ if(result.exists) {
+ return newErrorResponse("already exists");
+ }
+
+ // Doesn't exist and IOMT appears consistent. We can proceed.
+ LeafLookupResult =
+
+ } catch (JSONException e) {
+ return newErrorResponse("no base IOMT");
+ } catch (RuntimeException e) {
+ return newErrorResponse("Hyperledger lies!!!");
+ }
+
+ return newErrorResponse("not implemented");
+ }
+
private Response performQueryByHistoryFunction(ChaincodeStub chaincodeStub, List<String> paramList) {
if (listHasDifferentSizeThen(paramList, 1)) {
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 4cb1cb0..8cf0448 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
@@ -390,4 +390,4 @@ public class FabricIOMT extends IOMT {
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 cd003ad..7c6e521 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
@@ -310,4 +310,10 @@ public abstract class IOMT {
updateLeafPhysicalFull(physIdx, old);
}
+
+ // list of nodes complementary to a leaf
+ public IOMTNode [] getComplementary(int physLeafIdx) {
+ // TODO
+ return null;
+ }
}
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 a31c6d9..952acac 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
@@ -40,7 +40,7 @@ public class IOMTLeaf {
/* append and hash */
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
-
+
ByteBuffer buf1, buf2;
buf1 = ByteBuffer.allocate(4).putInt(getIdx());
buf2 = ByteBuffer.allocate(4).putInt(getNextIdx());
diff --git a/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTNode.java b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTNode.java
new file mode 100644
index 0000000..b56d720
--- /dev/null
+++ b/java-chaincode/dcrchaincode/src/main/java/tk/fwei/dcr/IOMTNode.java
@@ -0,0 +1,11 @@
+package tk.fwei.dcr;
+
+/**
+ * This class is used mostly for holding arrays of complementary nodes.
+ * Internally, we use hex Strings as nodes, so there is no need for this
+ * class unless ordering information (i.e. left/right ordering) is needed.
+ */
+public class IOMTNode {
+ public String val;
+ public boolean isLeftOrder;
+}