Ejemplo n.º 1
0
        private void OnFillMemoryPool(IEnumerable <Transaction> transactions)
        {
            // Invalidate all the transactions in the memory pool, to avoid any failures when adding new transactions.
            MemPool.InvalidateAllTransactions();

            // Add the transactions to the memory pool
            foreach (var tx in transactions)
            {
                if (tx.Type == TransactionType.MinerTransaction)
                {
                    continue;
                }
                if (Store.ContainsTransaction(tx.Hash))
                {
                    continue;
                }
                if (!Plugin.CheckPolicy(tx))
                {
                    continue;
                }
                // First remove the tx if it is unverified in the pool.
                MemPool.TryRemoveUnVerified(tx.Hash, out _);
                // Verify the the transaction
                if (!tx.Verify(currentSnapshot, MemPool.GetVerifiedTransactions()))
                {
                    continue;
                }
                // Add to the memory pool
                MemPool.TryAdd(tx.Hash, tx);
            }
            // Transactions originally in the pool will automatically be reverified based on their priority.

            Sender.Tell(new FillCompleted());
        }
Ejemplo n.º 2
0
        private RelayResultReason OnNewTransaction(Transaction transaction)
        {
            if (transaction.Type == TransactionType.MinerTransaction)
            {
                return(RelayResultReason.Invalid);
            }
            if (ContainsTransaction(transaction.Hash))
            {
                return(RelayResultReason.AlreadyExists);
            }
            if (!MemPool.CanTransactionFitInPool(transaction))
            {
                return(RelayResultReason.OutOfMemory);
            }
            if (!transaction.Verify(currentSnapshot, MemPool.GetVerifiedTransactions()))
            {
                return(RelayResultReason.Invalid);
            }
            if (!Plugin.CheckPolicy(transaction))
            {
                return(RelayResultReason.PolicyFail);
            }

            if (!MemPool.TryAdd(transaction.Hash, transaction))
            {
                return(RelayResultReason.OutOfMemory);
            }

            system.LocalNode.Tell(new LocalNode.RelayDirectly {
                Inventory = transaction
            });
            return(RelayResultReason.Succeed);
        }
Ejemplo n.º 3
0
        private void OnFillMemoryPool(IEnumerable <Transaction> transactions)
        {
            // Invalidate all the transactions in the memory pool, to avoid any failures when adding new transactions.
            MemPool.InvalidateAllTransactions();

            // Add the transactions to the memory pool
            foreach (var tx in transactions)
            {
                if (View.ContainsTransaction(tx.Hash))
                {
                    continue;
                }
                if (!NativeContract.Policy.CheckPolicy(tx, currentSnapshot))
                {
                    continue;
                }
                // First remove the tx if it is unverified in the pool.
                MemPool.TryRemoveUnVerified(tx.Hash, out _);
                // Verify the the transaction
                if (tx.Verify(currentSnapshot, MemPool.SendersFeeMonitor.GetSenderFee(tx.Sender)) != VerifyResult.Succeed)
                {
                    continue;
                }
                // Add to the memory pool
                MemPool.TryAdd(tx.Hash, tx);
            }
            // Transactions originally in the pool will automatically be reverified based on their priority.

            Sender.Tell(new FillCompleted());
        }
Ejemplo n.º 4
0
 private VerifyResult OnNewTransaction(Transaction transaction)
 {
     if (ContainsTransaction(transaction.Hash))
     {
         return(VerifyResult.AlreadyExists);
     }
     return(MemPool.TryAdd(transaction, currentSnapshot));
 }
Ejemplo n.º 5
0
 public bool ContainsTransaction(UInt256 hash)
 {
     if (MemPool.ContainsKey(hash))
     {
         return(true);
     }
     return(NativeContract.Ledger.ContainsTransaction(StoreView, hash));
 }
Ejemplo n.º 6
0
 private void OnPersistCompleted(Block block)
 {
     block_cache.Remove(block.Hash);
     MemPool.UpdatePoolForBlockPersisted(block, currentSnapshot);
     Context.System.EventStream.Publish(new PersistCompleted {
         Block = block
     });
 }
Ejemplo n.º 7
0
 public bool ContainsTransaction(UInt256 hash)
 {
     if (MemPool.ContainsKey(hash))
     {
         return(true);
     }
     return(View.ContainsTransaction(hash));
 }
Ejemplo n.º 8
0
 public Transaction GetTransaction(UInt256 hash)
 {
     if (MemPool.TryGetValue(hash, out Transaction transaction))
     {
         return(transaction);
     }
     return(View.GetTransaction(hash));
 }
Ejemplo n.º 9
0
 public void Release(MemPool pool)
 {
     if (null != recivedata)
     {
         pool.Recycle(ref recivedata);
         recivedata = null;
     }
     sendData = null;
 }
Ejemplo n.º 10
0
 private void OnPersistCompleted(Block block)
 {
     Debugger.Log(nameof(Blockchain), $"block persist completed=>{block.Index}/{block.Hash}", 2);
     block_cache.Remove(block.Hash);
     MemPool.UpdatePoolForBlockPersisted(block, currentSnapshot);
     Context.System.EventStream.Publish(new PersistCompleted {
         Block = block
     });
 }
Ejemplo n.º 11
0
 public bool HasTransactionInMemPool(string transactionId)
 {
     if (MemPool.ToList().FindAll(r => r.Body.TransactionId == transactionId)
         .Count > 0)
     {
         return(true);
     }
     return(false);
 }
Ejemplo n.º 12
0
        private void OnPersistCompleted(Block block)
        {
            block_cache.Remove(block.Hash);
            MemPool.UpdatePoolForBlockPersisted(block, currentSnapshot);
            PersistCompleted completed = new PersistCompleted {
                Block = block
            };

            system.Consensus?.Tell(completed);
            Distribute(completed);
        }
Ejemplo n.º 13
0
 private List <Transaction> ChooseTxs()
 {
     if (MemPool.Count < 4200)
     {
         return(MemPool.ToList());
     }
     else
     {
         var newPool = MemPool.OrderBy(CalculateFee).Take(4000);
         return(newPool.ToList());
     }
 }
Ejemplo n.º 14
0
        protected override void OnReceive(object message)
        {
            switch (message)
            {
            case Import import:
                OnImport(import.Blocks, import.Verify);
                break;

            case FillMemoryPool fill:
                OnFillMemoryPool(fill.Transactions);
                break;

            case Header[] headers:
                OnNewHeaders(headers);
                break;

            case Block block:
                Sender.Tell(OnNewBlock(block));
                break;

            case Transaction[] transactions:
            {
                // This message comes from a mempool's revalidation, already relayed
                foreach (var tx in transactions)
                {
                    OnNewTransaction(tx, false);
                }
                break;
            }

            case Transaction transaction:
                OnNewTransaction(transaction, true);
                break;

            case ParallelVerified parallelVerified:
                OnParallelVerified(parallelVerified);
                break;

            case ConsensusPayload payload:
                Sender.Tell(OnNewConsensus(payload));
                break;

            case Idle _:
                if (MemPool.ReVerifyTopUnverifiedTransactionsIfNeeded(MaxTxToReverifyPerIdle, currentSnapshot))
                {
                    Self.Tell(Idle.Instance, ActorRefs.NoSender);
                }
                break;
            }
        }
Ejemplo n.º 15
0
        protected override void OnReceive(object message)
        {
            switch (message)
            {
            case Import import:
                OnImport(import.Blocks);
                break;

            case ImportRoots importRoots:
                OnImportRoots(importRoots.Roots);
                break;

            case FillMemoryPool fill:
                OnFillMemoryPool(fill.Transactions);
                break;

            case Header[] headers:
                OnNewHeaders(headers);
                break;

            case Block block:
                Sender.Tell(OnNewBlock(block));
                break;

            case Transaction transaction:
                Sender.Tell(OnNewTransaction(transaction));
                break;

            case StateRoot stateRoot:
                OnNewStateRoot(stateRoot);
                break;

            case StateRoot[] stateRoots:
                OnStateRoots(stateRoots);
                break;

            case ConsensusPayload payload:
                Sender.Tell(OnNewConsensus(payload));
                break;

            case Idle _:
                if (MemPool.ReVerifyTopUnverifiedTransactionsIfNeeded(MaxTxToReverifyPerIdle, currentSnapshot))
                {
                    Self.Tell(Idle.Instance, ActorRefs.NoSender);
                }
                break;
            }
        }
Ejemplo n.º 16
0
 public Blockchain(NeoSystem system, IStore store)
 {
     this.system  = system;
     this.MemPool = new MemoryPool(system, ProtocolSettings.Default.MemoryPoolMaxTransactions);
     this.Store   = store;
     this.View    = new ReadOnlyView(store);
     lock (lockObj)
     {
         if (singleton != null)
         {
             throw new InvalidOperationException();
         }
         header_index.AddRange(View.HeaderHashList.Find().OrderBy(p => (uint)p.Key).SelectMany(p => p.Value.Hashes));
         stored_header_count += (uint)header_index.Count;
         if (stored_header_count == 0)
         {
             header_index.AddRange(View.Blocks.Find().OrderBy(p => p.Value.Index).Select(p => p.Key));
         }
         else
         {
             HashIndexState hashIndex = View.HeaderHashIndex.Get();
             if (hashIndex.Index >= stored_header_count)
             {
                 DataCache <UInt256, TrimmedBlock> cache = View.Blocks;
                 for (UInt256 hash = hashIndex.Hash; hash != header_index[(int)stored_header_count - 1];)
                 {
                     header_index.Insert((int)stored_header_count, hash);
                     hash = cache[hash].PrevHash;
                 }
             }
         }
         if (header_index.Count == 0)
         {
             Persist(GenesisBlock);
         }
         else
         {
             UpdateCurrentSnapshot();
             MemPool.LoadPolicy(currentSnapshot);
         }
         singleton = this;
     }
 }
Ejemplo n.º 17
0
        //解包数据(data内容,写在对象里面)
        public bool Unpack(byte[] buffer, int offset, int bufferLen, MemPool pool)
        {
            int nPose = offset;

            serverID = buffer[nPose];
            ++nPose;
            msgID  = BitConverter.ToUInt16(buffer, nPose);
            nPose += 2;
            try
            {
                int nLen = bufferLen - MESSAGE_HEAD_LEN;
                recivedata = pool.Aloc(nLen);//new byte[nLen];
                Array.Copy(buffer, offset + MESSAGE_HEAD_LEN, recivedata.item.data, 0, nLen);
                recivedata.item.nLen = nLen;
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }
            return(true);
        }
Ejemplo n.º 18
0
        private void OnFillMemoryPool(IEnumerable <Transaction> transactions)
        {
            // Invalidate all the transactions in the memory pool, to avoid any failures when adding new transactions.
            MemPool.InvalidateAllTransactions();

            // Add the transactions to the memory pool
            foreach (var tx in transactions)
            {
                if (View.ContainsTransaction(tx.Hash))
                {
                    continue;
                }
                // First remove the tx if it is unverified in the pool.
                MemPool.TryRemoveUnVerified(tx.Hash, out _);
                // Add to the memory pool
                MemPool.TryAdd(tx, currentSnapshot);
            }
            // Transactions originally in the pool will automatically be reverified based on their priority.

            Sender.Tell(new FillCompleted());
        }
Ejemplo n.º 19
0
        protected override void OnReceive(object message)
        {
            switch (message)
            {
            case Register _:
                OnRegister();
                break;

            case Import import:
                OnImport(import.Blocks);
                break;

            case Header[] headers:
                OnNewHeaders(headers);
                break;

            case Block block:
                Sender.Tell(OnNewBlock(block));
                break;

            case Transaction transaction:
                Sender.Tell(OnNewTransaction(transaction));
                break;

            case ConsensusPayload payload:
                Sender.Tell(OnNewConsensus(payload));
                break;

            case Idle _:
                if (MemPool.ReVerifyTopUnverifiedTransactionsIfNeeded(MaxTxToReverifyPerIdle, currentSnapshot))
                {
                    Self.Tell(Idle.Instance, ActorRefs.NoSender);
                }
                break;

            case Terminated terminated:
                subscribers.Remove(terminated.ActorRef);
                break;
            }
        }
Ejemplo n.º 20
0
        private VerifyResult OnNewTransaction(Transaction transaction)
        {
            if (ContainsTransaction(transaction.Hash))
            {
                return(VerifyResult.AlreadyExists);
            }
            if (!MemPool.CanTransactionFitInPool(transaction))
            {
                return(VerifyResult.OutOfMemory);
            }
            VerifyResult reason = transaction.Verify(currentSnapshot, MemPool.SendersFeeMonitor.GetSenderFee(transaction.Sender));

            if (reason != VerifyResult.Succeed)
            {
                return(reason);
            }
            if (!MemPool.TryAdd(transaction.Hash, transaction))
            {
                return(VerifyResult.OutOfMemory);
            }
            return(VerifyResult.Succeed);
        }
Ejemplo n.º 21
0
        protected override void OnReceive(object message)
        {
            switch (message)
            {
            case Import import:
                OnImport(import.Blocks, import.Verify);
                break;

            case FillMemoryPool fill:
                OnFillMemoryPool(fill.Transactions);
                break;

            case Block block:
                OnInventory(block, false);
                break;

            case Transaction[] transactions:
            {
                // This message comes from a mempool's revalidation, already relayed
                foreach (var tx in transactions)
                {
                    OnInventory(tx, false);
                }
                break;
            }

            case IInventory inventory:
                OnInventory(inventory);
                break;

            case Idle _:
                if (MemPool.ReVerifyTopUnverifiedTransactionsIfNeeded(MaxTxToReverifyPerIdle, currentSnapshot))
                {
                    Self.Tell(Idle.Instance, ActorRefs.NoSender);
                }
                break;
            }
        }
Ejemplo n.º 22
0
        private void OnParallelVerified(ParallelVerified parallelVerified)
        {
            RelayResultReason reason = parallelVerified.VerifyResult;

            if (reason == RelayResultReason.Succeed)
            {
                if (!MemPool.CanTransactionFitInPool(parallelVerified.Transaction))
                {
                    reason = RelayResultReason.OutOfMemory;
                }
                else if (!MemPool.TryAdd(parallelVerified.Transaction.Hash, parallelVerified.Transaction))
                {
                    reason = RelayResultReason.OutOfMemory;
                }
                else if (parallelVerified.ShouldRelay)
                {
                    system.LocalNode.Tell(new LocalNode.RelayDirectly {
                        Inventory = parallelVerified.Transaction
                    });
                }
            }
            Sender.Tell(reason);
        }
Ejemplo n.º 23
0
        private void Persist(Block block)
        {
            using (SnapshotView snapshot = GetSnapshot())
            {
                if (block.Index == header_index.Count)
                {
                    header_index.Add(block.Hash);
                    snapshot.HeaderHashIndex.GetAndChange().Set(block);
                }
                List <ApplicationExecuted> all_application_executed = new List <ApplicationExecuted>();
                snapshot.PersistingBlock = block;
                if (block.Index > 0)
                {
                    using (ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true))
                    {
                        engine.LoadScript(onPersistNativeContractScript);
                        if (engine.Execute() != VMState.HALT)
                        {
                            throw new InvalidOperationException();
                        }
                        ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                        Context.System.EventStream.Publish(application_executed);
                        all_application_executed.Add(application_executed);
                    }
                }
                snapshot.Blocks.Add(block.Hash, block.Trim());
                StoreView clonedSnapshot = snapshot.Clone();
                // Warning: Do not write into variable snapshot directly. Write into variable clonedSnapshot and commit instead.
                foreach (Transaction tx in block.Transactions)
                {
                    var state = new TransactionState
                    {
                        BlockIndex  = block.Index,
                        Transaction = tx
                    };

                    clonedSnapshot.Transactions.Add(tx.Hash, state);
                    clonedSnapshot.Transactions.Commit();

                    using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee))
                    {
                        engine.LoadScript(tx.Script);
                        state.VMState = engine.Execute();
                        if (state.VMState == VMState.HALT)
                        {
                            clonedSnapshot.Commit();
                        }
                        else
                        {
                            clonedSnapshot = snapshot.Clone();
                        }
                        ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                        Context.System.EventStream.Publish(application_executed);
                        all_application_executed.Add(application_executed);
                    }
                }
                snapshot.BlockHashIndex.GetAndChange().Set(block);
                foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
                {
                    plugin.OnPersist(snapshot, all_application_executed);
                }
                snapshot.Commit();
                List <Exception> commitExceptions = null;
                foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
                {
                    try
                    {
                        plugin.OnCommit(snapshot);
                    }
                    catch (Exception ex)
                    {
                        if (plugin.ShouldThrowExceptionFromCommit(ex))
                        {
                            if (commitExceptions == null)
                            {
                                commitExceptions = new List <Exception>();
                            }

                            commitExceptions.Add(ex);
                        }
                    }
                }
                if (commitExceptions != null)
                {
                    throw new AggregateException(commitExceptions);
                }
            }
            UpdateCurrentSnapshot();
            block_cache.Remove(block.PrevHash);
            MemPool.UpdatePoolForBlockPersisted(block, currentSnapshot);
            Context.System.EventStream.Publish(new PersistCompleted {
                Block = block
            });
        }
Ejemplo n.º 24
0
 private Task Peer_OnMemPool(BitcoinPeer s, MemPool mp)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 25
0
        private async Task ReadStream()
        {
            while (!Closing)
            {
                try
                {
                    //try to read a header
                    var hdata = new byte[24];
                    await Stream.ReadAsyncExact(hdata, 0, hdata.Length);

                    var h = new MessageHeader();
                    h.ReadFromPayload(hdata, 0);
                    if (h != null)
                    {
                        //read the payload
                        var pl = new byte[h.PayloadSize];
                        await Stream.ReadAsyncExact(pl, 0, pl.Length);

                        bool checksumOk = false;

                        //verify hash
                        using (var sha = SHA256.Create())
                        {
                            var h1 = sha.ComputeHash(pl);
                            var h2 = sha.ComputeHash(h1);

                            checksumOk = h2[0] == h.Checksum[0] && h2[1] == h.Checksum[1] && h2[2] == h.Checksum[2] && h2[3] == h.Checksum[3];
                        }

                        if (checksumOk)
                        {
                            switch (h.Command)
                            {
                            case "addr\0\0\0\0\0\0\0\0":
                            {
                                if (OnAddr != null)
                                {
                                    var a = new Addr();
                                    a.ReadFromPayload(pl, 0);

                                    await OnAddr?.Invoke(this, a);
                                }
                                break;
                            }

                            case "alert\0\0\0\0\0\0\0":
                            {
                                if (OnAlert != null)
                                {
                                    var a = new Alert();
                                    a.ReadFromPayload(pl, 0);

                                    await OnAlert?.Invoke(this, a);
                                }
                                break;
                            }

                            case "feefilter\0\0\0":
                            {
                                if (OnFeeFilter != null)
                                {
                                    var f = new FeeFilter();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFeeFilter?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filteradd\0\0\0":
                            {
                                if (OnFilterAdd != null)
                                {
                                    var f = new FilterAdd();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterAdd?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filterclear\0":
                            {
                                if (OnFilterClear != null)
                                {
                                    var f = new FilterClear();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterClear?.Invoke(this, f);
                                }
                                break;
                            }

                            case "filterload\0\0":
                            {
                                if (OnFilterLoad != null)
                                {
                                    var f = new FilterLoad();
                                    f.ReadFromPayload(pl, 0);

                                    await OnFilterLoad?.Invoke(this, f);
                                }
                                break;
                            }

                            case "getaddr\0\0\0\0\0":
                            {
                                if (OnGetAddr != null)
                                {
                                    var ga = new GetAddr();
                                    ga.ReadFromPayload(pl, 0);

                                    await OnGetAddr?.Invoke(this, ga);
                                }
                                break;
                            }

                            case "getblocks\0\0\0":
                            {
                                if (OnGetBlocks != null)
                                {
                                    var gb = new GetBlocks();
                                    gb.ReadFromPayload(pl, 0);

                                    await OnGetBlocks?.Invoke(this, gb);
                                }
                                break;
                            }

                            case "getdata\0\0\0\0\0":
                            {
                                if (OnGetData != null)
                                {
                                    var gd = new GetData();
                                    gd.ReadFromPayload(pl, 0);

                                    await OnGetData?.Invoke(this, gd);
                                }
                                break;
                            }

                            case "getheaders\0\0":
                            {
                                if (OnGetHeaders != null)
                                {
                                    var gh = new GetHeaders();
                                    gh.ReadFromPayload(pl, 0);

                                    await OnGetHeaders?.Invoke(this, gh);
                                }
                                break;
                            }

                            case "headers\0\0\0\0\0":
                            {
                                if (OnHeaders != null)
                                {
                                    var hd = new Headers();
                                    hd.ReadFromPayload(pl, 0);

                                    await OnHeaders?.Invoke(this, hd);
                                }
                                break;
                            }

                            case "inv\0\0\0\0\0\0\0\0\0":
                            {
                                if (OnInv != null)
                                {
                                    var iv = new Inv();
                                    iv.ReadFromPayload(pl, 0);

                                    await OnInv?.Invoke(this, iv);
                                }
                                break;
                            }

                            case "mempool\0\0\0\0\0":
                            {
                                if (OnMemPool != null)
                                {
                                    var mp = new MemPool();
                                    mp.ReadFromPayload(pl, 0);

                                    await OnMemPool?.Invoke(this, mp);
                                }
                                break;
                            }

                            case "notfound\0\0\0\0":
                            {
                                if (OnNotFound != null)
                                {
                                    var nf = new NotFound();
                                    nf.ReadFromPayload(pl, 0);

                                    await OnNotFound?.Invoke(this, nf);
                                }
                                break;
                            }

                            case "ping\0\0\0\0\0\0\0\0":
                            {
                                if (OnPing != null)
                                {
                                    var ping = new Ping();
                                    ping.ReadFromPayload(pl, 0);

                                    await OnPing?.Invoke(this, ping);
                                }
                                break;
                            }

                            case "pong\0\0\0\0\0\0\0\0":
                            {
                                if (OnPong != null)
                                {
                                    var pong = new Pong();
                                    pong.ReadFromPayload(pl, 0);

                                    await OnPong?.Invoke(this, pong);
                                }
                                break;
                            }

                            case "reject\0\0\0\0\0\0":
                            {
                                if (OnReject != null)
                                {
                                    var re = new Reject();
                                    re.ReadFromPayload(pl, 0);

                                    await OnReject?.Invoke(this, re);
                                }
                                break;
                            }

                            case "sendheaders\0":
                            {
                                if (OnSendHeaders != null)
                                {
                                    var sh = new SendHeaders();
                                    sh.ReadFromPayload(pl, 0);

                                    await OnSendHeaders?.Invoke(this, sh);
                                }
                                break;
                            }

                            case "verack\0\0\0\0\0\0":
                            {
                                if (OnVerAck != null)
                                {
                                    var va = new VerAck();
                                    va.ReadFromPayload(pl, 0);

                                    await OnVerAck.Invoke(this, va);
                                }
                                break;
                            }

                            case "version\0\0\0\0\0":
                            {
                                if (OnVersion != null)
                                {
                                    var v = new bitcoin_lib.P2P.Version("");
                                    v.ReadFromPayload(pl, 0);

                                    await OnVersion?.Invoke(this, v);
                                }
                                break;
                            }

                            default:
                            {
                                //Console.WriteLine($"Got cmd: {h.Command}");
                                break;
                            }
                            }
                        }
                        else
                        {
                            Closing = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Closing = true;
                }
            }
        }
Ejemplo n.º 26
0
        public void ClearAllTask()
        {
            Task                Task;
            CPUContext          CPUContext;
            MemoryPool          MemPool;
            MemoryPoolFixedsize MemPoolFx;
            Mailbox             Mailbox;
            Semaphore           Semaphore;
            CyclicHandler       CyclicHandler;
            UdpCep              UdpCep;
            Udp6Cep             Udp6Cep;
            TcpCep              TcpCep;

            while (m_CyclicHandlerTable.Count != 0)
            {
                CyclicHandler = m_CyclicHandlerTable[0];
                m_CyclicHandlerTable.RemoveAt(0);
                //if(CyclicHandler != null)
                //	delete CyclicHandler;
            }

            do
            {
                LockTaskTable();
                try {
                    for (int i = 0; i < m_TaskTable.Count; i++)
                    {
                        Task       = m_TaskTable[i];
                        CPUContext = (CPUContext)(Task.GetCPUContext());
                        if ((CPUContext == null) || CPUContext.IsFinished())
                        {
                            m_TaskTable.RemoveAt(i);
                            i--;
                            continue;
                        }
                        try {
                            CPUContext.Terminate();
                        }
                        catch (System.Threading.ThreadAbortException) {
                        }
                        catch (Exception e) {
                            System.Diagnostics.Debug.WriteLine(e.Message);
                        }
                    }
                }
                finally {
                    UnlockTaskTable();
                }
                System.Threading.Thread.Yield();
            } while (m_TaskTable.Count != 0);

            while (m_MemPoolTable.Count != 0)
            {
                MemPool = m_MemPoolTable[0];
                MemPool.EnumMemoryBlock(this, EnumBlockCallBack);
                m_MemPoolTable.RemoveAt(0);
                //delete MemPool;
            }

            while (m_MemPoolFxTable.Count != 0)
            {
                MemPoolFx = m_MemPoolFxTable[0];
                m_MemPoolFxTable.RemoveAt(0);
                //delete MemPoolFx;
            }

            while (m_MailboxTable.Count != 0)
            {
                Mailbox = m_MailboxTable[0];
                m_MailboxTable.RemoveAt(0);
                //delete Mailbox;
            }

            while (m_SemaphoreTable.Count != 0)
            {
                Semaphore = m_SemaphoreTable[0];
                m_SemaphoreTable.RemoveAt(0);
                //delete Semaphore;
            }

            while (m_UdpCepTable.Count != 0)
            {
                UdpCep = m_UdpCepTable[0];
                m_UdpCepTable.RemoveAt(0);
                //delete UdpCep;
            }

            while (m_Udp6CepTable.Count != 0)
            {
                Udp6Cep = m_Udp6CepTable[0];
                m_Udp6CepTable.RemoveAt(0);
                //delete Udp6Cep;
            }

            while (m_TcpCepTable.Count != 0)
            {
                TcpCep = m_TcpCepTable[0];
                m_TcpCepTable.RemoveAt(0);
                //delete TcpCep;
            }
        }
Ejemplo n.º 27
0
        private async Task Peer_OnMessage(BitcoinPeer s, IStreamable msg)
        {
            switch (msg)
            {
            case bitcoin_lib.P2P.Version a:
            {
                PeerVersion = a;

                if (Peer.IsInbound)
                {
                    await SendVersion();
                }

                var va = new VerAck();
                await s.WriteMessage(va);

                if (Peer.IsInbound && PeerVersion.HighestVersion >= 70014)
                {
                    //send cmpct (i only want my version, i dont care about another version)
                    //no version 1 msg will be sent if version 2 is supported
                    var nVersion = (Peer.ChainParams.Services & (ulong)Services.NODE_WITNESS) != 0 ? 2ul : 1ul;

                    var cmp = new SendCMPCT();
                    cmp.Version = nVersion;
                    cmp.Enabled = true;

                    await s.WriteMessage(cmp);
                }

                if (BlockChain.Mempool.Count == 0)
                {
                    //ask for mempool
                    var mp = new MemPool();
                    await s.WriteMessage(mp);
                }

                var ph = ((IPEndPoint)Peer.RemoteEndpoint).AsHash();
                if (BlockChain.Peers.ContainsKey(ph))
                {
                    //update peer info
                    BlockChain.Peers[ph].LastSeen    = DateTime.Now;
                    BlockChain.Peers[ph].LastVersion = a;
                }
                else
                {
                    //ask the peer for addr info if this is the first time we seen them
                    var ga = new GetAddr();
                    await s.WriteMessage(ga);
                }
                break;
            }

            case Inv a:
            {
                var gd     = new GetData();
                var to_get = new List <Inventory>();

                var sw = new Stopwatch();
                sw.Start();

                to_get.AddRange(a.Inventory.Where(b => b.Type == InventoryType.MSG_TX && !BlockChain.Mempool.ContainsKey(b.Hash)));
                if ((PeerVersion.Services & (ulong)Services.NODE_WITNESS) == 1)
                {
                    to_get.ForEach(b => b.Type = InventoryType.MSG_WITNESS_TX);
                }
                gd.Inventory = to_get.ToArray();

                if (gd.Inventory.Length > 0)
                {
                    //Console.WriteLine($"Asking for {gd.Count} tnxs, {sw.Elapsed.TotalMilliseconds.ToString("0.00")}ms");
                    await s.WriteMessage(gd);
                }
                break;
            }

            case Tx a:
            {
                if (!BlockChain.Mempool.ContainsKey(a.Hash))
                {
                    BlockChain.Mempool.Add(a.Hash, a);
                }
                break;
            }

            case VerAck a:
            {
                if (Peer.IsInbound)
                {
                    await SendAddr();
                }

                await s.WriteMessage(new Ping());

                break;
            }

            case Addr a:
            {
                foreach (var ip in a.Ips)
                {
                    var ph = new IPEndPoint(ip.Ip, ip.Port).AsHash();
                    if (!BlockChain.Peers.ContainsKey(ph))
                    {
                        BlockChain.Peers.Add(ph, new PeerInfo()
                            {
                                Ip          = Peer.RemoteEndpoint,
                                LastSeen    = DateTime.Now,
                                LastVersion = new bitcoin_lib.P2P.Version()     //add empty version
                            });
                    }
                }
                break;
            }

            case Pong a:
            {
                if (PingTimer.IsRunning)
                {
                    PingTimer.Stop();
                }

                //Console.WriteLine($"[{RemoteEndpoint}]{PeerVersion.UserAgent} ping is: {LastPing.TotalMilliseconds.ToString("0.00")}ms");
                break;
            }

            case Ping a:
            {
                var pong = new Pong();
                pong.Nonce = a.Nonce;

                await s.WriteMessage(pong);

                break;
            }

            case MemPool a:
            {
                var inv = new Inv();
                inv.Inventory = BlockChain.Mempool.Keys.Select(b => new Inventory()
                    {
                        Type = InventoryType.MSG_TX,
                        Hash = b
                    }).ToArray();

                if (inv.Inventory.Length > 0)
                {
                    await s.WriteMessage(inv);
                }
                break;
            }

            case SendCMPCT a:
            {
                if (CMPCTBlockVersion == 0 && a.Enabled && a.Version <= 2)
                {
                    if (Peer.IsInbound)
                    {
                        //lock in cmpct
                        var nVersion = (Peer.ChainParams.Services & (ulong)Services.NODE_WITNESS) != 0 ? 2ul : 1ul;
                        if (a.Version == nVersion)
                        {
                            CMPCTBlockVersion = a.Version;
                            Console.WriteLine($"Locking version {a.Version} cmpct block");
                        }
                    }
                    else
                    {
                        //reply to cmpct negotiation, if the node advertises witness use version 2
                        var nVersion = (PeerVersion.Services & (ulong)Services.NODE_WITNESS) != 0 ? 2ul : 1ul;
                        if (a.Version == nVersion)
                        {
                            CMPCTBlockVersion = a.Version;
                        }
                        else if (nVersion != a.Version && CMPCTBlockVersion == 0)         //if they only sent version 1 & they advertise NODE_WITNESS, use this version
                        {
                            CMPCTBlockVersion = a.Version;
                        }

                        var rsp = new SendCMPCT();
                        rsp.Version = CMPCTBlockVersion;
                        rsp.Enabled = true;

                        Console.WriteLine($"Sending version {rsp.Version} cmpct block");
                        await s.WriteMessage(rsp);
                    }
                    Console.WriteLine($"Peer is asking for version {a.Version} cmpct block");
                }
                break;
            }
            }
        }