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(); }
public BranchedChain(PendingBlock first) { PendingBlocks.Add(first); PendingBlocks.SortByBlockIndex(); EndHeight = PendingBlocks.Last().Block.Header.Index; }
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); } }
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; }
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; }
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); }
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."); } } }
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); }
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); }
/// <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}"); }
public static void Despawn(PendingBlock tile) { tile.StopAllCoroutines(); tile.gameObject.SetActive(false); }
/// <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); }
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); }