コード例 #1
0
        private Task TryPrefetchAsync(ConsensusFlags flags)
        {
            Task prefetching = Task.FromResult <bool>(true);

            if (UTXOSet is CachedCoinView)
            {
                var nextBlock = this.Puller.TryGetLookahead(0);
                if (nextBlock != null)
                {
                    prefetching = UTXOSet.FetchCoinsAsync(GetIdsToFetch(nextBlock, flags.EnforceBIP30));
                }
            }
            return(prefetching);
        }
コード例 #2
0
        public void Initialize()
        {
            var utxoHash = UTXOSet.GetBlockHashAsync().GetAwaiter().GetResult();

            while (true)
            {
                Tip = Chain.GetBlock(utxoHash);
                if (Tip != null)
                {
                    break;
                }
                utxoHash = UTXOSet.Rewind().GetAwaiter().GetResult();
            }
            Puller.SetLocation(Tip);
            BIP9 = new ThresholdConditionCache(Validator.ConsensusParams);
        }
コード例 #3
0
        public void AcceptBlock(BlockResult result)
        {
            ContextInformation context;
            ConsensusFlags     flags;

            using (watch.Start(o => Validator.PerformanceCounter.AddBlockProcessingTime(o)))
            {
                Validator.CheckBlockHeader(result.Block.Header);
                if (result.Block.Header.HashPrevBlock != Tip.HashBlock)
                {
                    return;                     // reorg
                }
                result.ChainedBlock = new ChainedBlock(result.Block.Header, result.Block.Header.GetHash(), Tip);
                result.ChainedBlock = Chain.GetBlock(result.ChainedBlock.HashBlock) ?? result.ChainedBlock;
                //Liberate from memory the block created above if possible
                context = new ContextInformation(result.ChainedBlock, Validator.ConsensusParams);
                Validator.ContextualCheckBlockHeader(result.Block.Header, context);
                flags = GetFlags(result.ChainedBlock);
                Validator.ContextualCheckBlock(result.Block, flags, context);
                Validator.CheckBlock(result.Block);
            }

            var set = new UnspentOutputSet();

            using (watch.Start(o => Validator.PerformanceCounter.AddUTXOFetchingTime(o)))
            {
                var ids   = GetIdsToFetch(result.Block, flags.EnforceBIP30);
                var coins = UTXOSet.FetchCoinsAsync(ids).GetAwaiter().GetResult();
                set.SetCoins(coins);
            }

            TryPrefetchAsync(flags);
            using (watch.Start(o => Validator.PerformanceCounter.AddBlockProcessingTime(o)))
            {
                Validator.ExecuteBlock(result.Block, result.ChainedBlock, flags, set, null);
            }

            UTXOSet.SaveChangesAsync(set.GetCoins(UTXOSet), null, Tip.HashBlock, result.ChainedBlock.HashBlock);

            _Tip = result.ChainedBlock;
        }
コード例 #4
0
        public BlockResult ExecuteNextBlock(CancellationToken cancellationToken)
        {
            BlockResult result = new BlockResult();

            try
            {
                using (watch.Start(o => Validator.PerformanceCounter.AddBlockFetchingTime(o)))
                {
                    while (true)
                    {
                        result.Block = Puller.NextBlock(cancellationToken);
                        if (result.Block != null)
                        {
                            break;
                        }
                        else
                        {
                            while (true)
                            {
                                var hash     = UTXOSet.Rewind().GetAwaiter().GetResult();
                                var rewinded = Chain.GetBlock(hash);
                                if (rewinded == null)
                                {
                                    continue;
                                }
                                _Tip = rewinded;
                                Puller.SetLocation(rewinded);
                                break;
                            }
                        }
                    }
                }

                this.AcceptBlock(result);
            }
            catch (ConsensusErrorException ex)
            {
                result.Error = ex.ConsensusError;
            }
            return(result);
        }
コード例 #5
0
        private void MineTransactions()
        {
            miningInProgress = true;
            logger.Debug("Mining started");
            var startTime = DateTime.Now;

            var txList     = new List <Transaction>();
            var coinBaseTx = Transaction.CoinBaseTx(_loggedUser.Address, ""); //add later

            coinBaseTx.Inputs[0].MagicValue = chain.GetBestHeight() + 1;
            coinBaseTx.MagicVK = chain.GetBestHeight() + 1;
            coinBaseTx.Id      = coinBaseTx.CalculateHash();

            txList.Add(coinBaseTx);
            //fill txList from TransactionPool
            foreach (var txPair in TransactionPool)
            {
                var tx = txPair.Value;
                if (chain.VerifyTransaction(tx))
                {
                    txList.Add(tx);
                }
            }

            if (txList.Count == 0)
            {
                logger.Debug("All txs invalid");
                miningInProgress = false;
                return;
            }


            chain.HashDiscovered += HashDiscovered;
            NotifyGUIisMining(true);
            var newBlock = chain.MineBlock(txList);

            if (newBlock != null)
            {
                //skew for synch
                if (handlingNewBlock || (DateTime.Now - timeSkewBetweenHandlingBlock).Milliseconds < 200)
                {
                    // mined same time as block came
                    logger.Debug($"!New block mined, mining duration: {DateTime.Now - startTime} But discard it, cause handling newRemoteBlock");
                    miningInProgress = false;
                    return;
                }
                NotifyGUIisMining(false);
                handlingNewBlock = true;
                logger.Debug($"New block mined, mining duration: {DateTime.Now - startTime}");
                chain.AddBlock(newBlock);
                //30.4
                var utxoSet = new UTXOSet(chain);
                utxoSet.Update(newBlock);
                //


                //7.4.19
                if (InMemoryBlockChains.Count > 0)
                {
                    logger.Debug("Find best chain");
                    InMemoryBlockChain bestChain = null;
                    var count     = 1;
                    var bestIndex = chain.GetBestHeight();

                    foreach (var chain in InMemoryBlockChains)
                    {
                        var currentIndex = chain.GetLastIndex();

                        if (currentIndex > bestIndex)
                        {
                            bestIndex = currentIndex;
                            count     = 1;
                            bestChain = chain;
                        }
                        else if (currentIndex == bestIndex)
                        {
                            count++;
                        }
                    }
                    if (count == 1)
                    {
                        logger.Debug("Best chain found");
                        BreakMining();//redundant

                        if (bestChain != null)
                        {
                            logger.Debug("Best chain found in subchains, restructualize chain");
                            //if not restruct to new one
                            chain.RestructualizeSubchain(bestChain);
                            InMemoryBlockChains.Clear(); //clear InMemoryChains
                        }
                        else
                        {
                            //if bestChain is null, chain stays local
                            logger.Debug("Best chain found in localchain, do nothing");
                        }
                    }
                    else
                    {
                        logger.Debug("Best chain not found");
                    }
                }

                handlingNewBlock = false;
                if (IncomingMinedNewBlocksMessages.Count > 0)
                {
                    ProcessMessage(IncomingMinedNewBlocksMessages.Dequeue());
                }
                //7.4.19

                //this means pow was broke
                chain.ReindexUTXO();

                chain.HashDiscovered -= HashDiscovered;
                WholeChainDownloaded?.Invoke(this, EventArgs.Empty);
                SendNewBlockMined(newBlock);
                //remove txs from Transaction pool

                RemoveTransactionsFromPool(txList);
            }
            else
            {
                logger.Debug("block added by remote client");
                //I delete txs from txpool in NewBlockMined
                //chain.ReindexUTXO();
            }

            miningInProgress = false;

            if (TransactionPool.Count > 0)
            {
                MineTransactions();
            }
        }
コード例 #6
0
        public void Send(string from, string to, int amount)
        {
            var utxoSet = new UTXOSet(chain);

            var tx = Transaction.NewTransaction(from, to, amount, utxoSet);

            if (tx == null)
            {
                logger.Debug("Couldn't create new TX to send");
                InsufficientFund?.Invoke(this, EventArgs.Empty);
                return;
            }
            //old ver
            //var block = chain.MineBlock(new List<Transaction>() { tx });
            //utxoSet.Update(block);
            //WholeChainDownloaded?.Invoke(this, EventArgs.Empty);
            //chain.ReindexUTXO();


            //check if not referencing same output, TODO BUG FIX
            //var referencingSameOutput = false;
            //foreach (var transaction in TransactionPool)
            //{
            //    var txOutputs = tx.Outputs;
            //    var poolOutputs = transaction.Value.Outputs;

            //    foreach (var outp in poolOutputs)
            //    {
            //        foreach (var txOutp in txOutputs)
            //        {
            //            if (outp.Equals(txOutp))
            //            {
            //                referencingSameOutput = true;
            //                break;
            //            }
            //        }
            //        if (referencingSameOutput) break;
            //    }
            //    if (referencingSameOutput) break;
            //}

            //if (referencingSameOutput)
            //{
            //    logger.Debug("Referencing same output in tx. Tx not added to TPool");
            //    return;
            //}

            //add to pool
            TransactionPool.Add(HexadecimalEncoding.ToHexString(tx.Id), tx);
            TransactionPoolChanged?.Invoke(this, new TransactionPoolEventArgs(new List <string>(TransactionPool.Keys)));

            //send to all except me and the one who send the tx
            var addressesToExclude = new string[] { _blockchainPeer.ClientDetails().ToString() };
            var msg = new CommandMessage();

            msg.Command = CommandType.Transaction;
            msg.Client  = _blockchainPeer.ClientDetails();
            msg.Data    = tx.Serialize();

            _blockchainPeer.BroadcastMessageAsyncExceptAddress(addressesToExclude, msg);
            logger.Debug("Sending tx over nettwork");

            if (!miningInProgress)
            {
                if (TransactionPool.Count >= numberOfTransactionsToStartMining)
                {
                    var thread = new Thread(MineTransactions);
                    thread.Start();
                }
            }
        }
コード例 #7
0
        private void HandleNewBlockMined(CommandMessage rxMsg)
        {
            try
            {
                handlingNewBlock = true;
                PauseMining(); //pause mining if mining

                Block minedBlock   = new Block().DeSerialize(rxMsg.Data);
                var   transactions = minedBlock.Transactions;
                logger.Debug("Recieved block, somebody mined: " + Convert.ToBase64String(minedBlock.Hash));

                var isValid = IsPreviousHashValid(minedBlock.PreviousHash);

                if (!isValid)
                {
                    logger.Debug("Previous hash invalid, try add to fork subchain");
                    if (!VerifyTransactions(transactions))
                    {
                        logger.Debug("Transactions  not valid");
                        ResumeMining();
                        handlingNewBlock = false;
                        return;
                    }

                    //try to add to fork chains
                    var added = false;
                    foreach (var memChain in InMemoryBlockChains)
                    {
                        if (memChain.BelongsToThisChain(minedBlock))
                        {
                            added = memChain.AddBlock(minedBlock);
                            RemoveTransactionsFromPool(minedBlock.Transactions);
                            logger.Debug("Added to subchain");
                        }
                    }

                    if (!added)
                    {
                        var newForkChain = new InMemoryBlockChain();
                        newForkChain.AddBlock(minedBlock);
                        InMemoryBlockChains.Add(newForkChain);
                        logger.Debug("Created new subchain");
                    }
                    PrintCurrentForkChains(InMemoryBlockChains);
                }
                else
                {
                    logger.Debug("Previous hash VALID, add to local chain");

                    if (!VerifyTransactions(transactions))
                    {
                        ResumeMining();
                        handlingNewBlock             = false;
                        timeSkewBetweenHandlingBlock = DateTime.Now;
                        return;
                    }

                    BreakMining();
                    RemoveTransactionsFromPool(minedBlock.Transactions); //remove new block transactions from pool
                    chain.AddBlock(minedBlock);
                    //30.4
                    var utxoSet = new UTXOSet(chain);
                    utxoSet.Update(minedBlock);
                    //
                }

                if (InMemoryBlockChains.Count > 0)
                {
                    logger.Debug("Find best chain");
                    InMemoryBlockChain bestChain = null;
                    var count     = 1;
                    var bestIndex = chain.GetBestHeight();     //local blockchain

                    foreach (var chain in InMemoryBlockChains) //subchains
                    {
                        var currentIndex = chain.GetLastIndex();

                        if (currentIndex > bestIndex)
                        {
                            bestIndex = currentIndex;
                            count     = 1;
                            bestChain = chain;
                        }
                        else if (currentIndex == bestIndex)
                        {
                            count++;
                        }
                    }
                    if (count == 1)
                    {
                        logger.Debug("Best chain found");
                        BreakMining();

                        if (bestChain != null)
                        {
                            logger.Debug("Best chain found in subchains, restructualize chain");
                            //if not restruct to new one
                            chain.RestructualizeSubchain(bestChain);
                            InMemoryBlockChains.Clear(); //clear InMemoryChains
                        }
                        else
                        {
                            //if bestChain is null, chain stays local
                            logger.Debug("Best chain found in localchain, do nothing");
                        }
                    }
                    else
                    {
                        logger.Debug("Best chain not found");
                    }
                }

                WholeChainDownloaded?.Invoke(this, EventArgs.Empty);
                chain.ReindexUTXO(); // asynch
                handlingNewBlock = false;
                if (IncomingMinedNewBlocksMessages.Count > 0)
                {
                    ProcessMessage(IncomingMinedNewBlocksMessages.Dequeue());
                }
            }
            catch (Exception e)
            {
                logger.Error(e.Message);
                logger.Error(e.StackTrace);
            }
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: dntichy/Fricoin_sharp
        static void Main(string[] args)
        {
            var startTime = DateTime.Now;

            //var wBank = new WalletBank();

            //for (var i = 0; i < 100; i++) wBank.CreateWallet();


            //foreach (var wallet in wBank)
            //{
            //    var isOk = wallet.VerifyAddress(wallet.Address);
            //    Console.WriteLine(isOk);
            //}


            //var blockChain = new BlockChain();
            //blockChain.Print();


            //var txList = new List<Transaction>();
            //for(var i = 0; i<10000; i++) {
            //Transaction tx1 = new Transaction()
            //{
            //   Id = null,
            //   Inputs = new List<TxInput>()
            //   {
            //       new TxInput() {
            //           Id = new byte[] {},
            //           PubKey = new byte[]{0x01},
            //           Out = i
            //       }
            //   } ,
            //   Outputs = new List<TxOutput>() { new TxOutput()
            //   {
            //       Value = i,
            //   } }
            //};
            //tx1.CalculateHash();

            //    txList.Add(tx1);
            //}

            //var  merkleTree = new MerkleTree(txList);
            //merkleTree.LevelOrder();

            var list = new List <Transaction>();

            var bank = new WalletBank();
            var _loggedUserWallet = bank.FindWallet("112H2TcYAvxWGPSWXz4bzGvm5RXEdFDCms");
            var _friChain         = new BlockChain("x");
            var utxoSet           = new UTXOSet(_friChain);

            for (int i = 0; i < 20; i++)
            {
                var tx = Transaction.NewTransaction("112H2TcYAvxWGPSWXz4bzGvm5RXEdFDCms", "1fp9JwtnMMnYVLaABMEQuKGtpXUnJm7Cz", 2, utxoSet);
                if (tx == null)
                {
                    return;
                }
                list.Add(tx);
            }

            var block = _friChain.MineBlock(list);

            utxoSet.Update(block);
            _friChain.GetBalance("112H2TcYAvxWGPSWXz4bzGvm5RXEdFDCms");

            var endTime = DateTime.Now;

            Console.WriteLine($"Duration: {endTime - startTime}");
            Console.Read();
        }