protected virtual void DataRecieved(object sender, string data)
        {
            Data.Add(data);

            if (!Processing && LookForBlock())
            {
                Processing = true;
                NewBlock?.Invoke(this, ProcessBlock());
                Processing = false;
            }
        }
Пример #2
0
        public async Task NewBlockHandle(NewBlock msg, IPEndPoint endPoint, int localPort)
        {
            var block = msg.Block;

            if (!ValidCheck(block))
            {
                return;
            }
            var lastBlock = _blockchain.Chain.Last();

            if (!lastBlock.Id.Equals(block.PreviousBlockHash))
            {
                var req = new Message()
                {
                    Type    = MessageType.RequestFullChain,
                    Payload = new byte[] { 0 }
                }.SendAsync(endPoint, localPort);
            }
            _blockchain.BlockVerify(block);
        }
Пример #3
0
        public void Synchronize()
        {
            Interlocked.Exchange(ref _running, 1);

            Task.Run(async() =>
            {
                try
                {
                    var blockCount = await RpcClient.GetBlockCountAsync();
                    var isIIB      = true;                // Initial Index Building phase

                    while (IsRunning)
                    {
                        try
                        {
                            // If stop was requested return.
                            if (IsRunning == false)
                            {
                                return;
                            }

                            Height height    = StartingHeight;
                            uint256 prevHash = null;
                            using (await IndexLock.LockAsync())
                            {
                                if (Index.Count != 0)
                                {
                                    var lastIndex = Index.Last();
                                    height        = lastIndex.BlockHeight + 1;
                                    prevHash      = lastIndex.BlockHash;
                                }
                            }

                            if (blockCount - height <= 100)
                            {
                                isIIB = false;
                            }

                            Block block = null;
                            try
                            {
                                block = await RpcClient.GetBlockAsync(height);
                            }
                            catch (RPCException)                             // if the block didn't come yet
                            {
                                await Task.Delay(1000);
                                continue;
                            }

                            if (blockCount - height <= 2)
                            {
                                NewBlock?.Invoke(this, block);
                            }

                            if (!(prevHash is null))
                            {
                                // In case of reorg:
                                if (prevHash != block.Header.HashPrevBlock && !isIIB)                                 // There is no reorg in IIB
                                {
                                    Logger.LogInfo <IndexBuilderService>($"REORG Invalid Block: {prevHash}");
                                    // 1. Rollback index
                                    using (await IndexLock.LockAsync())
                                    {
                                        Index.RemoveLast();
                                    }

                                    // 2. Serialize Index. (Remove last line.)
                                    var lines = File.ReadAllLines(IndexFilePath);
                                    File.WriteAllLines(IndexFilePath, lines.Take(lines.Length - 1).ToArray());

                                    // 3. Rollback Bech32UtxoSet
                                    if (Bech32UtxoSetHistory.Count != 0)
                                    {
                                        Bech32UtxoSetHistory.Last().Rollback(Bech32UtxoSet);                                         // The Bech32UtxoSet MUST be recovered to its previous state.
                                        Bech32UtxoSetHistory.RemoveLast();

                                        // 4. Serialize Bech32UtxoSet.
                                        await File.WriteAllLinesAsync(Bech32UtxoSetFilePath, Bech32UtxoSet
                                                                      .Select(entry => entry.Key.Hash + ":" + entry.Key.N + ":" + ByteHelpers.ToHex(entry.Value.ToCompressedBytes())));
                                    }

                                    // 5. Skip the current block.
                                    continue;
                                }
                            }

                            if (!isIIB)
                            {
                                if (Bech32UtxoSetHistory.Count >= 100)
                                {
                                    Bech32UtxoSetHistory.RemoveFirst();
                                }
                                Bech32UtxoSetHistory.Add(new ActionHistoryHelper());
                            }

                            var scripts = new HashSet <Script>();

                            foreach (var tx in block.Transactions)
                            {
                                // If stop was requested return.
                                // Because this tx iteration can take even minutes
                                // It doesn't need to be accessed with a thread safe fasion with Interlocked through IsRunning, this may have some performance benefit
                                if (_running != 1)
                                {
                                    return;
                                }

                                for (int i = 0; i < tx.Outputs.Count; i++)
                                {
                                    var output = tx.Outputs[i];
                                    if (!output.ScriptPubKey.IsPayToScriptHash && output.ScriptPubKey.IsWitness)
                                    {
                                        var outpoint = new OutPoint(tx.GetHash(), i);
                                        Bech32UtxoSet.Add(outpoint, output.ScriptPubKey);
                                        if (!isIIB)
                                        {
                                            Bech32UtxoSetHistory.Last().StoreAction(ActionHistoryHelper.Operation.Add, outpoint, output.ScriptPubKey);
                                        }
                                        scripts.Add(output.ScriptPubKey);
                                    }
                                }

                                foreach (var input in tx.Inputs)
                                {
                                    OutPoint prevOut = input.PrevOut;
                                    if (Bech32UtxoSet.TryGetValue(prevOut, out Script foundScript))
                                    {
                                        Bech32UtxoSet.Remove(prevOut);
                                        if (!isIIB)
                                        {
                                            Bech32UtxoSetHistory.Last().StoreAction(ActionHistoryHelper.Operation.Remove, prevOut, foundScript);
                                        }
                                        scripts.Add(foundScript);
                                    }
                                }
                            }

                            GolombRiceFilter filter = null;
                            if (scripts.Count != 0)
                            {
                                filter = new GolombRiceFilterBuilder()
                                         .SetKey(block.GetHash())
                                         .SetP(20)
                                         .SetM(1 << 20)
                                         .AddEntries(scripts.Select(x => x.ToCompressedBytes()))
                                         .Build();
                            }

                            var filterModel = new FilterModel
                            {
                                BlockHash   = block.GetHash(),
                                BlockHeight = height,
                                Filter      = filter
                            };

                            await File.AppendAllLinesAsync(IndexFilePath, new[] { filterModel.ToLine() });
                            using (await IndexLock.LockAsync())
                            {
                                Index.Add(filterModel);
                            }
                            if (File.Exists(Bech32UtxoSetFilePath))
                            {
                                File.Delete(Bech32UtxoSetFilePath);
                            }
                            await File.WriteAllLinesAsync(Bech32UtxoSetFilePath, Bech32UtxoSet
                                                          .Select(entry => entry.Key.Hash + ":" + entry.Key.N + ":" + ByteHelpers.ToHex(entry.Value.ToCompressedBytes())));

                            // If not close to the tip, just log debug.
                            // Use height.Value instead of simply height, because it cannot be negative height.
                            if (blockCount - height.Value <= 3 || height % 100 == 0)
                            {
                                Logger.LogInfo <IndexBuilderService>($"Created filter for block: {height}.");
                            }
                            else
                            {
                                Logger.LogDebug <IndexBuilderService>($"Created filter for block: {height}.");
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.LogDebug <IndexBuilderService>(ex);
                        }
                    }
                }
                finally
                {
                    if (IsStopping)
                    {
                        Interlocked.Exchange(ref _running, 3);
                    }
                }
            });
        }
        public bool CheckBlock(Block block, EndPoint peerAddress = null)
        {
            if (db.GetBlock(block.Hash) != null)
            {
                return(false);
            }

            var prevBlock = db.GetBlock(block.PreviousHash);
            var creator   = db.GetUserCreation(block.CreatorHash);

            bool needWait = false;


            //проверка существования предыдущего блока
            if (prevBlock == null)
            {
                //если ее нет и в ожидающих - запрашиваем от пиров
                if (!pendingBlocks.Keys.Any(bl => bl.Hash == block.PreviousHash))
                {
                    RequestBlock(block.PreviousHash, peerAddress);
                }
                needWait = true;
            }


            //проверка существования создателя блока
            if (creator == null)
            {
                if (!pendingTransactions.Keys.Any(tr => tr.RecieverHash == block.CreatorHash))
                {
                    RequestTransaction(block.CreatorHash, peerAddress);
                }
                needWait = true;
            }

            if (block.Transactions == null)
            {
                return(false);
            }

            //проверка существования транзакций
            foreach (var itemHash in block.Transactions)
            {
                if (db.GetTransaction(itemHash) == null)
                {
                    if (!pendingTransactions.Keys.Any(tr => tr.Hash == itemHash))
                    {
                        RequestTransaction(itemHash, peerAddress);
                    }
                    needWait = true;
                }
            }


            //если блок не в списке ожидающих и запросили инфу, то отправляем ее в список ожидающих
            if (needWait == true)
            {
                if (!pendingBlocks.ContainsKey(block))
                {
                    pendingBlocks.Add(block, CommonHelpers.GetTime());
                }
                return(false);
            }


            ////если все данные есть, начинаем проверку блока

            //удаляем его из ожидающих
            pendingBlocks.Remove(block);


            //проверка хеша и подписи
            if (!(block.CheckHash() && block.CheckSignature()))
            {
                return(false);
            }


            //проверка даты
            if (!(block.Date0 >= prevBlock.Date0 && block.Date0 <= CommonHelpers.GetTime()))
            {
                return(false);
            }


            //проверка создателя блока
            //var senderCreation = db.GetUserCreation(block.CreatorHash);
            var senderBan = db.GetUserBan(block.CreatorHash);

            if (!(creator.Date0 <= block.Date0 &&
                  (senderBan == null || senderBan.Date0 > block.Date0)))
            {
                return(false);
            }



            //сравнение длины цепочки этого блока с длиной цепочки в базе
            var blockCopyInDB = db.GetBlock(block.Number);

            if (blockCopyInDB != null)
            {
                var lastBlockInChain = GetLastBlockFromPending(block);
                var lastBlockInDB    = db.GetLastBlock();

                //если цепочка нового блока длиннее или цепочки равны, но дата нового блока раньше
                if ((lastBlockInChain.Number > lastBlockInDB.Number) ||
                    (lastBlockInChain.Number == lastBlockInDB.Number && block.Date0 < blockCopyInDB.Date0))
                {
                    //удаляем из базы все блоки начиная с этого
                    for (int i = blockCopyInDB.Number; i <= lastBlockInDB.Number; i++)
                    {
                        var blockToRemove = db.GetBlock(i);
                        db.DeleteBlock(blockToRemove);

                        //СПОРНЫЙ МОМЕНТ
                        //отмечаем транзакции из блока как свободные
                        db.MarkAsFreePendingTransactions(true, blockToRemove.Transactions);
                    }

                    //добавляем блок обратно в ожидающие
                    pendingBlocks.Add(block, CommonHelpers.GetTime());
                    //запускаем проверку последнего ожидающего блока из цепочки (он снова загрузит нужные транзакции)
                    CheckBlock(lastBlockInChain);
                }
                else
                {
                    //СПОРНЫЙ МОМЕНТ
                    //если не приняли новый блок, то освобождаем полученные для него транзакции
                    db.MarkAsFreePendingTransactions(false, block.Transactions);
                }


                NewTransaction?.Invoke(this, new IntEventArgs(db.TransactionsCount()));
                NewBlock?.Invoke(this, new IntEventArgs(db.BlocksCount()));

                return(false);
            }


            //проверка транзакций
            foreach (var itemHash in block.Transactions)
            {
                var tr = db.GetTransaction(itemHash);
                if (tr.Status == TransactionStatus.InBlock || tr.Date0 > block.Date0)
                {
                    return(false);
                }
            }



            ////если все хорошо, добавляем блок в базу
            db.PutBlock(block);

            NetworkComms.Logger.Warn("Added block " + block.Hash);

            NewBlock?.Invoke(this, new IntEventArgs(db.BlocksCount()));

            //помечаем транзакции, что они в блоке
            foreach (var itemHash in block.Transactions)
            {
                var tr = db.GetTransaction(itemHash);
                db.MarkTransaction(tr, TransactionStatus.InBlock);
            }

            //ищем в ожидающих блоках связанные с этим и проверяем их
            var pending = pendingBlocks.Keys.Where(bl => bl.PreviousHash == block.Hash).ToList();

            foreach (var item in pending)
            {
                CheckBlock(item);
            }


            return(true);
        }
Пример #5
0
 protected virtual void OnNewBlock(NewBlockRequest newBlockRequest)
 {
     NewBlock?.Invoke(this, new NewBlockEventArgs(newBlockRequest.Block));
 }
Пример #6
0
    public void merge(GameObject other)
    {
        if (((this.color == Color.Orange || this.color == Color.Green || this.color == Color.Purple) && !ScoreManager.ComplementaryCanMerge()))
        {
            return;
        }
        if (other.name.Equals(name))
        {
            stacks += other.gameObject.GetComponent <CheckForMerge>().stacks;
            Destroy(other);
            if (stacks >= StacksForPoints)
            {
                if (this.color == Color.Blue || this.color == Color.Red || this.color == Color.Yellow)
                {
                    ScoreManager.GrantPoints(ScoreManager.BlockScoreType.Primary, StacksForPoints);
                }
                else
                {
                    ScoreManager.GrantPoints(ScoreManager.BlockScoreType.Complementary, StacksForPoints);
                }
                ParticleSystem p = ((GameObject)Instantiate(Resources.Load("Sparkles"), transform.position + new Vector3(0f, 0f, -1f), Quaternion.identity)).GetComponent <ParticleSystem> ();
                p.startColor = GetColor(color);
                Destroy(this.gameObject);
                Destroy(other.gameObject);
            }
            else
            {
                return;
            }
        }
        //At this point, only complementary merges possible, want to make sure we can do that
        if (!ScoreManager.ComplementaryCanMerge())
        {
            return;
        }
        GameObject NewBlock;

        switch (name)
        {
        case "BlueBlock(Clone)":
            if (other.gameObject.name.Contains("Yellow"))
            {
                NewBlock = (GameObject)Instantiate(Resources.Load("GreenBlock"), transform.position, Quaternion.identity);
                ((GameObject)Instantiate(Resources.Load("Cloud"), transform.position + new Vector3(0f, 0f, -1f), Quaternion.identity)).GetComponent <ParticleSystem> ().startColor = GetColor(Color.Green);
            }
            else if (other.gameObject.name.Contains("Red"))
            {
                NewBlock = (GameObject)Instantiate(Resources.Load("PurpleBlock"), transform.position, Quaternion.identity);
                ((GameObject)Instantiate(Resources.Load("Cloud"), transform.position + new Vector3(0f, 0f, -1f), Quaternion.identity)).GetComponent <ParticleSystem> ().startColor = GetColor(Color.Purple);
            }
            else
            {
                return;
            }
            break;

        case "YellowBlock(Clone)":
            if (other.gameObject.name.Contains("Blue"))
            {
                NewBlock = (GameObject)Instantiate(Resources.Load("GreenBlock"), transform.position, Quaternion.identity);
                ((GameObject)Instantiate(Resources.Load("Cloud"), transform.position + new Vector3(0f, 0f, -1f), Quaternion.identity)).GetComponent <ParticleSystem> ().startColor = GetColor(Color.Green);
            }
            else if (other.gameObject.name.Contains("Red"))
            {
                NewBlock = (GameObject)Instantiate(Resources.Load("OrangeBlock"), transform.position, Quaternion.identity);
                ((GameObject)Instantiate(Resources.Load("Cloud"), transform.position + new Vector3(0f, 0f, -1f), Quaternion.identity)).GetComponent <ParticleSystem> ().startColor = GetColor(Color.Orange);
            }
            else
            {
                return;
            }
            break;

        case "RedBlock(Clone)":
            if (other.gameObject.name.Contains("Blue"))
            {
                NewBlock = (GameObject)Instantiate(Resources.Load("PurpleBlock"), transform.position, Quaternion.identity);
                ((GameObject)Instantiate(Resources.Load("Cloud"), transform.position + new Vector3(0f, 0f, -1f), Quaternion.identity)).GetComponent <ParticleSystem> ().startColor = GetColor(Color.Purple);
            }
            else if (other.gameObject.name.Contains("Yellow"))
            {
                NewBlock = (GameObject)Instantiate(Resources.Load("OrangeBlock"), transform.position, Quaternion.identity);
                ((GameObject)Instantiate(Resources.Load("Cloud"), transform.position + new Vector3(0f, 0f, -1f), Quaternion.identity)).GetComponent <ParticleSystem> ().startColor = GetColor(Color.Orange);
            }
            else
            {
                return;
            }

            break;

        default:
            return;
        }
        if (this.stacks < other.gameObject.GetComponent <CheckForMerge> ().stacks)
        {
            NewBlock.GetComponent <CheckForMerge> ().setStacks(this.stacks);
        }
        else
        {
            NewBlock.GetComponent <CheckForMerge> ().setStacks(other.gameObject.GetComponent <CheckForMerge> ().stacks);
        }
        Destroy(this.gameObject);
        Destroy(other.gameObject);
    }
Пример #7
0
 public BlockchainMessage(NewBlock message)
 {
     this.type     = new CryptoNote.BlockchainMessage.Type.NewBlock;
     this.newBlock = std::move(message);
 }
 private void OnNewBlock(Block block) => NewBlock?.Invoke(this, block);
Пример #9
0
    public void GenerateBlock(string name)
    {
        GameObject NewBlock;
        GameObject TargetBlock = CheckBlock(name);

        NewBlock = (GameObject)Instantiate(TargetBlock);
        NewBlock.transform.name         += (count++);
        NewBlock.transform.parent        = GameObject.Find("WorkSpace").transform;
        NewBlock.transform.localPosition = new Vector3(-550, 350, 0);
        NewBlock.transform.localRotation = Quaternion.Euler(0, 180, 0);

        switch (name)
        {
        case "StartHere":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.STARTHERE);
            break;

        case "Reserved_For":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.FOR);
            break;

        case "Reserved_If":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.IF);
            break;

        case "Reserved_ElseIf":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.ELIF);
            break;

        case "Reserved_Else":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.ELSE);
            break;

        case "Operator_Equal":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.EQ);
            break;

        case "Operator_NotEqual":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.NEQ);
            break;

        case "Operator_GT":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.GT);
            break;

        case "Operator_LT":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.LT);
            break;

        case "Operator_GE":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.GE);
            break;

        case "Operator_LE":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.LE);
            break;

        case "Operator_Plus":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.PLUS);
            break;

        case "Operator_Minus":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.MINUS);
            break;

        case "Operator_Mul":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.MUL);
            break;

        case "Operator_Div":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.DIV);
            break;

        case "Operator_Mod":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.MOD);
            break;

        case "Operator_Neg":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.NEG);
            break;

        case "Operator_And":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.AND);
            break;

        case "Operator_Or":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.OR);
            break;

        case "Operator_Not":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.NOT);
            break;

        case "Operator_Bop":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.BOP);
            break;

        case "Operator_Bcl":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.BCL);
            break;

        case "Operator_Ass":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.ASS);
            break;

        case "Operator_Comma":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.COMMA);
            break;

        case "Const_1":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_1);
            break;

        case "Const_2":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_2);
            break;

        case "Const_3":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_3);
            break;

        case "Const_4":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_4);
            break;

        case "Const_5":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_5);
            break;

        case "Const_6":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_6);
            break;

        case "Const_7":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_7);
            break;

        case "Const_8":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_8);
            break;

        case "Const_9":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_9);
            break;

        case "Const_0":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTI_0);
            break;

        case "Bool_True":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTB_TRUE);
            break;

        case "Bool_False":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.CONSTB_FALSE);
            break;

        case "Var_a":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARI_a);
            break;

        case "Var_b":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARI_b);
            break;

        case "Var_c":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARI_c);
            break;

        case "Var_i":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARI_i);
            break;

        case "Var_j":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARI_j);
            break;

        case "Var_k":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARI_k);
            break;

        case "Var_w":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARB_w);
            break;

        case "Var_x":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARB_x);
            break;

        case "Var_y":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARB_y);
            break;

        case "Var_z":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.VARB_z);
            break;

        case "Func_AttackMelee":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.FUNC_MELEEATTACK);
            break;

        case "Func_AttackRange":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.FUNC_RANGEATTACK);
            break;

        case "Func_Observe":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.FUNC_OBSERVE);
            break;

        case "Func_Defence":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.FUNC_DEFENCE);
            break;

        case "Func_EnergyCharge":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.FUNC_ENERGYCHARGE);
            break;

        case "Func_BreakShield":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.FUNC_BREAKSHIELD);
            break;

        case "Func_GolemEnergy":
            NewBlock.GetComponent <Block>().initBlock(Block.BlockKind.FUNC_GOLEMENERGY);
            break;
        }
    }