Ejemplo n.º 1
0
        /// <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;
        }
Ejemplo n.º 2
0
 /// <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
         });
 }