Пример #1
0
        private static List <HeadCandidate> AssembleBlockchain(Database db, HeadSelector selector)
        {
            var blocks = BuildBlocks(db);

            var ret = new List <HeadCandidate>(blocks.Blocks.Count);

            if (blocks.Blocks.Count == 0)
            {
                return(ret);
            }

            for (var current = SelectHead(db, blocks, selector); current != null; current = current.Previous)
            {
                ret.Add(current);
                var back = ret[ret.Count - 1];
                if (current.Previous != null)
                {
                    back.PreviousBlockId = current.Previous.DbId;
                }
                else
                {
                    back.PreviousBlockId = long.MaxValue;
                }
            }
            ret.Reverse();
            return(ret);
        }
Пример #2
0
        private static HeadCandidate SelectHead(Database db, BlocksTemp blocks, HeadSelector selector)
        {
            var heads = blocks.Blocks.Where(block => !block.HasChildren).ToList();

            if (heads.Count == 0)
            {
                throw new Exception("Invalid blockchain. Circular topologies are invalid.");
            }

            if (heads.Count == 1)
            {
                return(heads[0]);
            }

            var hash = db.BlockchainHead;

            if (hash == null)
            {
                if (selector == null)
                {
                    throw new Exception("Can't read blockchain head from DB.");
                }
                hash = selector(heads).Hash;
            }

            HeadCandidate ret;

            if (!blocks.BlockMap.TryGetValue(hash, out ret))
            {
                throw new Exception(
                          $"DB states that the blockchain head is {hash}, but no such block exists in the DB.");
            }
            return(ret);
        }
Пример #3
0
        public Blockchain(Database db, HeadSelector selector = null) : base(db, Configuration.Get().Network)
        {
            var blocks = AssembleBlockchain(db, selector);

            _blockchain = new List <Block>(blocks.Count);
            foreach (var block in blocks)
            {
                var height = _blockchain.Count;
                var block2 = new Block
                {
                    Hash            = block.Hash,
                    PreviousHash    = block.PreviousHash,
                    Height          = height,
                    DbId            = block.DbId,
                    PreviousBlockId = block.PreviousBlockId
                };
                _blockMap[block2.Hash] = height;
                _blockchain.Add(block2);
            }
            UpdateDb();
        }