/// <summary> /// Creates a database anchor for the current state of the database. /// </summary> /// <returns>The task object representing the asynchronous operation.</returns> public async Task<LedgerAnchor> CreateAnchor() { IEnumerable<LedgerAnchor> anchors = await ExecuteAsync(@" SELECT Position, FullLedgerHash, TransactionCount FROM Anchors ORDER BY Id DESC LIMIT 1", reader => new LedgerAnchor( new ByteString((byte[])reader.GetValue(0)), new ByteString((byte[])reader.GetValue(1)), reader.GetInt64(2)), new Dictionary<string, object>()); LedgerAnchor lastAnchor = anchors.FirstOrDefault(); IReadOnlyList<ByteString> newTransactions; byte[] currentHash; if (lastAnchor != null) { newTransactions = await ExecuteAsync(@" SELECT Hash FROM Transactions WHERE Id > (SELECT Id FROM Transactions WHERE Hash = @hash) ORDER BY Id", reader => new ByteString((byte[])reader.GetValue(0)), new Dictionary<string, object>() { ["@hash"] = lastAnchor.Position.ToByteArray() }); currentHash = lastAnchor.FullStoreHash.ToByteArray(); } else { newTransactions = await ExecuteAsync(@" SELECT Hash FROM Transactions ORDER BY Id", reader => new ByteString((byte[])reader.GetValue(0)), new Dictionary<string, object>()); currentHash = new byte[32]; } if (newTransactions.Count == 0) return null; byte[] buffer = new byte[64]; using (SHA256 sha = SHA256.Create()) { foreach (ByteString transactionHash in newTransactions) { currentHash.CopyTo(buffer, 0); transactionHash.CopyTo(buffer, 32); currentHash = sha.ComputeHash(sha.ComputeHash(buffer)); } } LedgerAnchor result = new LedgerAnchor( newTransactions[newTransactions.Count - 1], new ByteString(currentHash), newTransactions.Count + (lastAnchor != null ? lastAnchor.TransactionCount : 0)); return result; }
/// <summary> /// Marks the anchor as successfully recorded in the anchoring medium. /// </summary> /// <param name="anchor">The anchor to commit.</param> /// <returns>The task object representing the asynchronous operation.</returns> public async Task CommitAnchor(LedgerAnchor anchor) { await ExecuteAsync(@" INSERT INTO Anchors (Position, FullLedgerHash, TransactionCount) VALUES (@position, @fullLedgerHash, @transactionCount)", new Dictionary<string, object>() { ["@position"] = anchor.Position.ToByteArray(), ["@fullLedgerHash"] = anchor.FullStoreHash.ToByteArray(), ["@transactionCount"] = anchor.TransactionCount }); }