Ejemplo n.º 1
0
        /// <summary>
        /// Saves index and current blocks to file.
        /// </summary>
        /// <returns>True if succeeds.</returns>
        public bool Save()
        {
            DbFile.Write(Config.GetBlockIndexFilePath(), _indexFile);

            foreach (var p in _blockFileByIndex)
            {
                var blockFile = p.Value;
                if (blockFile.IsDirty())
                {
                    BlockFile.Write(blockFile);
                    blockFile.MarkBlocksSaved();
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Loads block index from file into memory.
        /// </summary>
        /// <returns>True if succeeds.</returns>
        public bool Load()
        {
            _indexFile = DbFile.Read <IndexFile>(Config.GetBlockIndexFilePath());
            if (_indexFile == null)
            {
                _indexFile = new IndexFile
                {
                    BlockIndices = new List <BlockIndex>()
                };
                DbFile.Write(Config.GetBlockIndexFilePath(), _indexFile);
            }

            _blockIndices = _indexFile.BlockIndices;

            for (int i = 0, c = _blockIndices.Count; i < c; ++i)
            {
                var idx = _blockIndices[i].Index;
                if (idx != i)
                {
                    return(false);
                }

                var hash = Utils.HexUtils.ByteArrayFromHex(_blockIndices[i].Hash);
                if (!Pow.IsValidHash(hash, Pow.CalculateDifficulty(idx)))
                {
                    return(false);
                }
            }

            _blockFileByIndex = new Dictionary <int, BlockFile>();
            _blocks           = new Dictionary <int, Block>();

            if (_blockIndices.Count == 0)
            {
                AddBlock(Config.GetGenesisBlock());
            }

            IsReady = true;

            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Loads transaction database from persistent storage into memory.
        /// </summary>
        /// <returns>True if succeeds.</returns>
        public bool Load()
        {
            _indexFile = DbFile.Read <IndexFile>(Config.GetTransactionIndexFilePath());
            if (_indexFile == null)
            {
                _indexFile = new IndexFile
                {
                    TransactionIndices  = new Dictionary <string, TransactionIndex>(),
                    UnspentTxOuts       = new List <UnspentTxOut>(),
                    PendingTransactions = new List <PendingTransaction>(),
                };
                DbFile.Write(Config.GetTransactionIndexFilePath(), _indexFile);
            }

            _transactionIndices  = _indexFile.TransactionIndices;
            _unspentTxOuts       = _indexFile.UnspentTxOuts;
            _pendingTransactions = _indexFile.PendingTransactions;

            _transactions = new Dictionary <string, Transaction>();

            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Adds a new block to the chain.
        /// </summary>
        /// <param name="block">The block to add.</param>
        /// <param name="needSave">If true, the index file and block file will be saved immediately.</param>
        /// <returns>Index to the new block.</returns>
        /// <remarks>
        /// In scenarios when there are multiple calls to this method,
        /// passing false to <paramref name="needSave"/> and then calling
        /// <see cref="Save"/> in the end would be a more efficient approach.
        /// </remarks>
        public BlockIndex AddBlock(Block block, bool needSave = true)
        {
            if (_blockIndices.Count > 0 && block.Index != LatestBlock.Index + 1)
            {
                throw new System.ArgumentException("Given block is not right after latest block.");
            }

            int fileIndex = block.Index / BlockFile.BlocksPerFile;

            if (_blockFileByIndex.ContainsKey(fileIndex))
            {
                var blockFile = _blockFileByIndex[fileIndex];
                blockFile.AddBlock(block);

                if (needSave)
                {
                    BlockFile.Write(blockFile);
                }
            }
            else
            {
                var blockFile = BlockFile.Read(block.Index);

                if (blockFile != null)
                {
                    blockFile.AddBlock(block);
                }
                else
                {
                    blockFile = new BlockFile(block);
                }

                _blockFileByIndex.Add(fileIndex, blockFile);

                if (needSave)
                {
                    BlockFile.Write(blockFile);
                }
            }

            if (needSave)
            {
                block.IsSaved = true;
            }

            var blockIndex = new BlockIndex
            {
                Index = block.Index,
                Hash  = block.Hash,
            };

            _blockIndices.Add(blockIndex);
            _blocks.Add(block.Index, block);

            if (needSave)
            {
                DbFile.Write(Config.GetBlockIndexFilePath(), _indexFile);
            }

            return(blockIndex);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Writes transaction database into persistent storage.
 /// </summary>
 /// <returns>True if succeeds.</returns>
 public bool Save()
 {
     DbFile.Write(Config.GetTransactionIndexFilePath(), _indexFile);
     return(true);
 }