示例#1
0
    public void SpawnBlock()
    {
        while (true)
        {
            int x = Mathf.Clamp(Random.Range(0, Cols), 0, Cols - 1);
            int y = Mathf.Clamp(Random.Range(0, Rows), 0, Rows - 1);

            if (Board[y, x] != null)
            {
                // Prevent the possibility of an infinite loop
                TestForFailure();
                if (CurrentState == GameState.GameOver)
                {
                    return;
                }
                continue;
            }

            tmpBlock = GenerateBlock(x, y, true);
            PendingBlock.Spawn(BlockSprites[tmpBlock.BlockType],
                               tmpBlock,
                               GetLocalPosition(x, y), UICanvas, _t, x, y);

            break;
        }
        ShowAndHideArrows();
    }
示例#2
0
        public BranchedChain(PendingBlock first)
        {
            PendingBlocks.Add(first);

            PendingBlocks.SortByBlockIndex();
            EndHeight = PendingBlocks.Last().Block.Header.Index;
        }
示例#3
0
        private bool AbleToAdd(PendingBlock pendingBlock)
        {
            switch (pendingBlock.MsgType)
            {
            case AElfProtocolMsgType.Block:
                _logger.Trace(AElfProtocolMsgType.Block);
                return(false);

            case AElfProtocolMsgType.NewBlock:
                if (PendingBlocks.IsEmpty())
                {
                    return(SyncedHeight + 1 == pendingBlock.Block.Header.Index &&
                           pendingBlock.Block.Header.PreviousBlockHash ==
                           BlockChain.GetCurrentBlockHashAsync().Result);
                }

                var lastPendingBlock = PendingBlocks.Last().Block;
                if (pendingBlock.Block.Header.Index != lastPendingBlock.Header.Index + 1)
                {
                    _logger.Trace($"Wrong Index {pendingBlock.Block.Header.Index} != {lastPendingBlock.Header.Index + 1}");
                }
                if (pendingBlock.Block.Header.PreviousBlockHash != lastPendingBlock.Header.GetHash())
                {
                    _logger.Trace($"Wrong previousBlockHash {pendingBlock.Block.Header.PreviousBlockHash.DumpHex()} != {lastPendingBlock.Header.GetHash().DumpHex()}");
                }
                return(pendingBlock.Block.Header.Index == lastPendingBlock.Header.Index + 1 &&
                       pendingBlock.Block.Header.PreviousBlockHash == lastPendingBlock.Header.GetHash());

            default:
                _logger.Trace("Unknown reason");
                return(false);
            }
        }
示例#4
0
        public BranchedChain(IEnumerable <PendingBlock> list, PendingBlock last)
        {
            foreach (var pendingBlock in list)
            {
                PendingBlocks.Add(pendingBlock);
            }

            PendingBlocks.Add(last);

            PendingBlocks.SortByBlockIndex();
            EndHeight = PendingBlocks.Last().Block.Header.Index;
        }
示例#5
0
        public BranchedChain(PendingBlock first, IReadOnlyCollection <PendingBlock> list)
        {
            PendingBlocks.Add(first);

            foreach (var pendingBlock in list)
            {
                PendingBlocks.Add(pendingBlock);
            }

            PendingBlocks.SortByBlockIndex();
            EndHeight = PendingBlocks.Last().Block.Header.Index;
        }
示例#6
0
        private static int Compare(PendingBlock block1, PendingBlock block2)
        {
            if (block1.Block.Header.Index > block2.Block.Header.Index)
            {
                return(1);
            }

            if (block1.Block.Header.Index < block2.Block.Header.Index)
            {
                return(-1);
            }

            return(0);
        }
示例#7
0
        private void AddToPendingBlocks(PendingBlock pendingBlock)
        {
            PendingBlockHeight = Math.Max(PendingBlockHeight, pendingBlock.Block.Header.Index);
            _logger?.Trace("Adding to pending blocks: " + pendingBlock.Block.GetHash().DumpHex());
            PrintPendingBlocks(PendingBlocks);
            PendingBlocks.Add(pendingBlock);
            PendingBlocks.SortByBlockIndex();

            if (_branchedChains.Count > 0)
            {
                var num = _branchedChains.RemoveWhere(bc => bc.StartHeight < SyncedHeight);
                if (num > 0)
                {
                    _logger?.Trace($"Removed {num} redundant branched chain.");
                }
            }
        }
示例#8
0
        private static int ComparePendingBlockIndex(PendingBlock block1, PendingBlock block2)
        {
            if (block1 != null)
            {
                if (block2 == null)
                {
                    return(1);
                }

                return(Compare(block1, block2));
            }

            if (block2 == null)
            {
                return(0);
            }

            return(-1);
        }
示例#9
0
    public static PendingBlock Spawn(Sprite sprite, GameBlock realBlock, Vector3 localPosition, Canvas canvas, Transform parent, int x, int y)
    {
        // Attempt to use a pooled block
        tmp = null;
        for (int i = 0; i < Pool.Count; i++)
        {
            if (Pool[i] != null && !Pool[i].gameObject.activeSelf)
            {
                tmp = Pool[i];
                tmp.gameObject.SetActive(true);
                tmp.InitializeFromPool(sprite, realBlock, localPosition, canvas, parent);
                return(tmp);
            }
        }

        // Create a new block
        tmp = (PendingBlock)Instantiate(prefab);
        tmp.InitializeFromPool(sprite, realBlock, localPosition, canvas, parent);
        Pool.Add(tmp);
        return(tmp);
    }
示例#10
0
        /// <summary>
        /// Add the pending block to branched chain after removing.
        /// </summary>
        /// <param name="pendingBlock"></param>
        public void RemovePendingBlock(PendingBlock pendingBlock)
        {
            _logger.Trace($"Removing pending Block at {pendingBlock.Block.Header.Index}, hash {pendingBlock.Block.Header.GetHash()}");
            if (pendingBlock.BlockValidationResult == BlockValidationResult.Success)
            {
                PendingBlocks.Remove(pendingBlock);
                _logger.Trace($"Removed pending Block at {pendingBlock.Block.Header.Index}, hash {pendingBlock.Block.Header.GetHash()}");
            }
            else
            {
                _logger?.Trace("ValidationError: " + pendingBlock.BlockValidationResult);
                PendingBlocks.Remove(pendingBlock);
                AddBlockToBranchedChains(pendingBlock);
            }

            if (!PendingBlocks.IsEmpty() || BranchedChainsCount <= 0)
            {
                return;
            }
            var longest = _branchedChains.Where(c =>
            {
                if (c.CanCheckout(SyncedHeight))
                {
                    _logger?.Trace($"CanCheckOut: EndHeight = {c.EndHeight}, SyncedHeight = {SyncedHeight}");
                }
                return(c.CanCheckout(SyncedHeight));
            }).Max();

            if (longest == null)
            {
                return;
            }
            _branchedChains.Remove(longest);
            PendingBlocks = longest.GetPendingBlocks();
            _logger?.Trace($"Branch switched! pending count {PendingBlocks?.Count}");
        }
示例#11
0
 public static void Despawn(PendingBlock tile)
 {
     tile.StopAllCoroutines();
     tile.gameObject.SetActive(false);
 }
示例#12
0
        /// <summary>
        /// Basically add the pending block if the block is supposed to be on local chain.
        /// Otherwise add the pending block to branched chains.
        /// </summary>
        /// <param name="pendingBlock"></param>
        public List <Transaction> AddPendingBlock(PendingBlock pendingBlock)
        {
            // No need to handle an already exists pending block again.
            if (!PendingBlocks.IsNullOrEmpty() &&
                PendingBlocks.Any(b => new Hash(b.Block.GetHash()) == new Hash(pendingBlock.Block.GetHash())))
            {
                return(null);
            }

            if (GlobalConfig.IsConsensusGenerator)
            {
                _isInitialSync = false;
            }

            if (_isInitialSync)
            {
                switch (pendingBlock.MsgType)
                {
                case AElfProtocolMsgType.NewBlock:
                    if (_targetHeight == ulong.MaxValue)
                    {
                        _targetHeight = pendingBlock.Block.Header.Index;
                        if (_targetHeight == _heightBefore + 1)
                        {
                            _isInitialSync = false;
                        }

                        if (DPoS.ConsensusDisposable != null)
                        {
                            DPoS.ConsensusDisposable.Dispose();
                            _logger?.Trace("Disposed previous consensus observables list.");
                        }

                        AddToPendingBlocks(pendingBlock);
                        PendingBlocks.SortByBlockIndex();
                        _initialSyncBlocksIndexes.Add(_targetHeight);
                        return(null);
                    }
                    else
                    {
                        _logger?.Trace("Receive a new block while do initial sync.");
                        return(AddBlockToBranchedChains(pendingBlock));
                    }

                case AElfProtocolMsgType.Block:
                    if (!_initialSyncBlocksIndexes.Contains(pendingBlock.Block.Header.Index) &&
                        !ReceivedAllTheBlocksBeforeTargetBlock)
                    {
                        AddToPendingBlocks(pendingBlock);
                        _initialSyncBlocksIndexes.Add(pendingBlock.Block.Header.Index);
                        if (ReceivedAllTheBlocksBeforeTargetBlock)
                        {
                            _isInitialSync = false;
                        }

                        return(null);
                    }
                    else
                    {
                        _logger?.Trace("Receive a forked block while do initial sync.");
                        return(AddBlockToBranchedChains(pendingBlock));
                    }
                }

                return(null);
            }

            if (!AbleToAdd(pendingBlock))
            {
                _logger?.Trace("Receive an orphan block.");
                return(AddBlockToBranchedChains(pendingBlock));
            }

            AddToPendingBlocks(pendingBlock);
            return(null);
        }
示例#13
0
        private List <Transaction> AddBlockToBranchedChains(PendingBlock pendingBlock)
        {
            PrintPendingBlocks(PendingBlocks);

            _logger?.Trace(
                $"Ready to add branched pending block height: {pendingBlock.Block.Header.Index}\nBlock number of each round: {GlobalConfig.BlockNumberOfEachRound}\nPending block height or Synced height: {(PendingBlockHeight == 0 ? SyncedHeight : PendingBlockHeight)}");
            if (pendingBlock.Block.Header.Index + (ulong)GlobalConfig.BlockNumberOfEachRound <
                (PendingBlockHeight == 0 ? SyncedHeight : PendingBlockHeight))
            {
                return(null);
            }

            _logger?.Trace(
                $"Adding to branched chain: {pendingBlock.Block.GetHash().DumpHex()} : {pendingBlock.Block.Header.Index}");

            if (_branchedChains.Count == 0)
            {
                _logger?.Trace($"Adding branched chain for block {pendingBlock.Block.Header.Index}.");
                _branchedChains.Add(new BranchedChain(pendingBlock));
                return(null);
            }

            var preBlockHash = pendingBlock.Block.Header.PreviousBlockHash;
            var blockHash    = pendingBlock.Block.Header.GetHash();

            var toRemove = new List <BranchedChain>();
            var toAdd    = new List <BranchedChain>();

            foreach (var branchedChain in _branchedChains)
            {
                if (branchedChain.GetPendingBlocks().First().Block.Header.PreviousBlockHash == blockHash)
                {
                    var newBranchedChain = new BranchedChain(pendingBlock, branchedChain.GetPendingBlocks());
                    toAdd.Add(newBranchedChain);
                    toRemove.Add(branchedChain);
                }
                else if (branchedChain.GetPendingBlocks().Last().Block.GetHash() == preBlockHash)
                {
                    var newBranchedChain = new BranchedChain(branchedChain.GetPendingBlocks(), pendingBlock);
                    toAdd.Add(newBranchedChain);
                    toRemove.Add(branchedChain);
                }
                else
                {
                    if (toAdd.Any(c => c.GetPendingBlocks().Any(pd => pd.Block.GetHash() == blockHash)) ||
                        _branchedChains.Any(bc => bc.LastBlockHash == blockHash) ||
                        _branchedChains.Any(bc => bc.GetPendingBlocks().Any(pb => pb.Block.GetHash() == blockHash)))
                    {
                        continue;
                    }

                    toAdd.Add(new BranchedChain(pendingBlock));
                }
            }

            foreach (var branchedChain in toRemove)
            {
                _branchedChains.Remove(branchedChain);
            }

            foreach (var branchedChain in toAdd)
            {
                _logger?.Trace($"Adding branched chain for block {pendingBlock.Block.Header.Index}.");
                _branchedChains.Add(branchedChain);
            }

            _logger?.Trace("Branched chains count: " + BranchedChainsCount);

            var flag = 1;

            foreach (var branchedChain in _branchedChains)
            {
                _logger?.Trace(flag++ + ":");
                PrintPendingBlocks(branchedChain.GetPendingBlocks());
            }

            var result = AdjustBranchedChains();

            if (result == null)
            {
                return(null);
            }

            if (DPoS.ConsensusDisposable != null)
            {
                DPoS.ConsensusDisposable.Dispose();
                _logger?.Trace("Disposed previous consensus observables list.");
            }

            if (SyncedHeight < result.StartHeight)
            {
                var oldBlocks = new List <PendingBlock>();
                // Replace the pending blocks with the result
                foreach (var branchedBlock in result.GetPendingBlocks())
                {
                    if (PendingBlockHeight >= branchedBlock.Block.Header.Index)
                    {
                        var corresponding =
                            PendingBlocks.First(pb => pb.Block.Header.Index == branchedBlock.Block.Header.Index);
                        PendingBlocks.Remove(corresponding);
                        oldBlocks.Add(corresponding);
                    }

                    PendingBlocks.Add(branchedBlock);
                }

                if (!oldBlocks.IsEmpty())
                {
                    //TODO: Move back.
                    //_branchedChains.Add(new BranchedChain(oldBlocks));
                }
            }
            else
            {
                PendingBlocks = result.GetPendingBlocks();
            }

            //_isInitialSync = true;
            //_targetHeight = result.EndHeight;
            PendingBlockHeight = result.EndHeight;
            _branchedChains.Remove(result);

            // State rollback.
            _logger?.Trace("Rollback to height: " + (result.StartHeight - 1));
            var txs = BlockChain.RollbackToHeight(result.StartHeight - 1).Result;

            return(txs);
        }