Esempio n. 1
0
        private async Task <LedgerAnchor> ComputeNewAnchor(LedgerAnchor lastAnchor)
        {
            IReadOnlyList <ByteString> newTransactions;

            byte[] currentHash;
            if (lastAnchor != null)
            {
                newTransactions = await storageEngine.GetTransactions(lastAnchor.Position);

                currentHash = lastAnchor.FullStoreHash.ToByteArray();
            }
            else
            {
                newTransactions = await storageEngine.GetTransactions(null);

                currentHash = new byte[32];
            }

            if (newTransactions.Count == 0)
            {
                return(null);
            }

            byte[] position = currentHash;
            byte[] buffer   = new byte[64];
            using (SHA256 sha = SHA256.Create())
            {
                foreach (ByteString rawTransaction in newTransactions)
                {
                    currentHash.CopyTo(buffer, 0);
                    position = MessageSerializer.ComputeHash(rawTransaction.ToByteArray());
                    position.CopyTo(buffer, 32);

                    currentHash = sha.ComputeHash(sha.ComputeHash(buffer));
                }
            }

            LedgerAnchor result = new LedgerAnchor(
                new ByteString(position),
                new ByteString(currentHash),
                newTransactions.Count + (lastAnchor != null ? lastAnchor.TransactionCount : 0));

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Determines whether a new anchor should be calculated and recorded,
        /// and does it if it is the case.
        /// </summary>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public async Task <LedgerAnchor> RecordAnchor()
        {
            if (await anchorRecorder.CanRecordAnchor())
            {
                LedgerAnchor anchor = await anchorState.GetLastAnchor();

                LedgerAnchor latestAnchor = await ComputeNewAnchor(anchor);

                if (latestAnchor != null)
                {
                    // Record the anchor
                    await anchorRecorder.RecordAnchor(latestAnchor);

                    // Commit the anchor if it has been recorded successfully
                    await anchorState.CommitAnchor(latestAnchor);

                    return(latestAnchor);
                }
            }

            return(null);
        }