예제 #1
0
        public static async Task <Tuple <bool, string> > TryWriteMerkleNodeAsync(this ICampfireNetObjectStore store, string ns, MerkleNode node)
        {
            using (var ms = new MemoryStream()) {
                using (var writer = new BinaryWriter(ms, Encoding.UTF8, true)) {
                    writer.WriteMerkleNode(node);
                }

                var objectData     = ms.GetBuffer();
                var length         = (int)ms.Position;
                var hash           = CampfireNetHash.ComputeSha256Base64(objectData, 0, length);
                var isNewlyWritten = await store.TryWriteUniqueAsync(ns, hash, objectData).ConfigureAwait(false);

//            var copy = await ReadMerkleNodeAsync(store, ns, hash).ConfigureAwait(false);
//            if (copy.TypeTag != node.TypeTag || copy.LeftHash != node.LeftHash || copy.RightHash != node.RightHash || copy.Descendents != node.Descendents) {
//               throw new InvalidStateException();
//            }
                return(Tuple.Create(isNewlyWritten, hash));
            }
        }
예제 #2
0
        private async Task <string> InsertHelperAsyncUnderTreeLock(string replaceeHash, MerkleNode replaceeNode, string inserteeHash)
        {
            var rightHash = replaceeNode.RightHash;
            var rightNode = await objectStore.ReadMerkleNodeAsync(NetworkDataNamespace, rightHash).ConfigureAwait(false);

            var rightwardDescendents = rightNode == null ? 0 : (1 + rightNode.Descendents);

            var isReplaceePerfect = replaceeNode.Descendents == rightwardDescendents * 2;

            if (isReplaceePerfect)
            {
                var internalNode = new MerkleNode {
                    TypeTag     = MerkleNodeTypeTag.Node,
                    LeftHash    = replaceeHash,
                    RightHash   = inserteeHash,
                    Descendents = 2 + replaceeNode.Descendents
                };
                var internalNodeHash = (await objectStore.TryWriteMerkleNodeAsync(NetworkDataNamespace, internalNode).ConfigureAwait(false)).Item2;
                await objectStore.TryWriteUniqueAsync(TreeContainmentNamespace, internalNodeHash, new byte[0]).ConfigureAwait(false);

                return(internalNodeHash);
            }

            var rightReplacementHash = await InsertHelperAsyncUnderTreeLock(rightHash, rightNode, inserteeHash).ConfigureAwait(false);

            replaceeNode.Descendents += 2; // leaf and inner node
            replaceeNode.RightHash    = rightReplacementHash;

            var newReplaceeNodeHash = (await objectStore.TryWriteMerkleNodeAsync(NetworkDataNamespace, replaceeNode).ConfigureAwait(false)).Item2;
            await objectStore.TryWriteUniqueAsync(TreeContainmentNamespace, newReplaceeNodeHash, new byte[0]).ConfigureAwait(false);

            return(newReplaceeNodeHash);
        }