private async Task <Tuple <bool, string> > InsertAsyncInternal(MerkleNode itemNode) { // ignore whether we're writing a new object to the store (item1) var writeMerkleNodeResult = await objectStore.TryWriteMerkleNodeAsync(NetworkDataNamespace, itemNode).ConfigureAwait(false); var itemHash = writeMerkleNodeResult.Item2; // if the tree does not contain the merkle node, insert. var isNodeContained = (await objectStore.TryReadAsync(TreeContainmentNamespace, itemHash).ConfigureAwait(false)).Item1; if (!isNodeContained) { // Persist pointer to object in merkle structure. using (await treeSync.LockAsync().ConfigureAwait(false)) { isNodeContained = (await objectStore.TryReadAsync(TreeContainmentNamespace, itemHash).ConfigureAwait(false)).Item1; if (!isNodeContained) { var nextRootHash = itemHash; var rootHash = await GetRootHashAsyncUnderLock().ConfigureAwait(false); if (rootHash != null) { var rootNode = await GetNodeAsync(rootHash).ConfigureAwait(false); if (rootNode == null) { throw new InvalidStateException(); } nextRootHash = await InsertHelperAsyncUnderTreeLock(rootHash, rootNode, itemHash).ConfigureAwait(false); } await SetRootHashAsyncUnderLock(nextRootHash).ConfigureAwait(false); await objectStore.TryWriteUniqueAsync(TreeContainmentNamespace, itemHash, new byte[0]).ConfigureAwait(false); // Console.WriteLine($"LOC UPD ROOT {rootHash:n} => {nextRootHash:n}"); } } } return(Tuple.Create(!isNodeContained, itemHash)); }
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)); } }