Пример #1
0
 public async Task <Block> GetBlock(string id)
 {
     return(await _blockProvider.GetBlock(id));
 }
Пример #2
0
        public void Process(Chain mainChain, IBlockProvider blockProvider)
        {
            bool newChain = false;
            if(!Chain.Initialized)
            {
                newChain = true;

                var firstBlock = mainChain.GetBlock(StartHeight);
                Chain.Initialize(firstBlock.Header, StartHeight);
            }
            var forkBlock = mainChain.FindFork(Chain);
            if(forkBlock.HashBlock != Chain.Tip.HashBlock)
            {
                Chain.SetTip(Chain.GetBlock(forkBlock.Height));
                foreach(var e in Account.GetInChain(Chain, false)
                                            .Where(e => e.Reason != AccountEntryReason.ChainBlockChanged))
                {
                    var neutralized = e.Neutralize();
                    Account.PushAccountEntry(neutralized);
                }
            }

            var unprocessedBlocks = mainChain.ToEnumerable(true)
                                       .TakeWhile(block => block != forkBlock)
                                       .Concat(newChain ? new ChainedBlock[] { forkBlock } : new ChainedBlock[0])
                                       .Reverse().ToArray();
            foreach(var block in unprocessedBlocks)
            {
                List<byte[]> searchedData = new List<byte[]>();
                Scanner.GetScannedPushData(searchedData);
                foreach(var unspent in Account.Unspent)
                {
                    searchedData.Add(unspent.OutPoint.ToBytes());
                }

                var fullBlock = blockProvider.GetBlock(block.HashBlock, searchedData);
                if(fullBlock != null)
                {
                    foreach(var spent in Scanner.FindSpent(fullBlock, Account.Unspent))
                    {
                        var entry = new AccountEntry(AccountEntryReason.Outcome,
                                                    block.HashBlock,
                                                    spent, -spent.TxOut.Value);
                        Account.PushAccountEntry(entry);
                    }
                    foreach(var coins in Scanner.ScanCoins(fullBlock, (int)block.Height))
                    {
                        int i = 0;
                        foreach(var output in coins.Coins.Outputs)
                        {
                            if(!output.IsNull)
                            {
                                var entry = new AccountEntry(AccountEntryReason.Income, block.HashBlock,
                                                    new Spendable(new OutPoint(coins.TxId, i), output), output.Value);
                                Account.PushAccountEntry(entry);
                            }
                            i++;
                        }
                    }
                }
                Chain.GetOrAdd(block.Header);
            }
        }
Пример #3
0
        public void Process(Chain mainChain, IBlockProvider blockProvider)
        {
            bool newChain = false;

            if (!Chain.Initialized)
            {
                newChain = true;

                var firstBlock = mainChain.GetBlock(StartHeight);
                Chain.Initialize(firstBlock.Header, StartHeight);
            }
            var forkBlock = mainChain.FindFork(Chain);

            if (forkBlock.HashBlock != Chain.Tip.HashBlock)
            {
                Chain.SetTip(Chain.GetBlock(forkBlock.Height));
                foreach (var e in Account.GetInChain(Chain, false)
                         .Where(e => e.Reason != AccountEntryReason.ChainBlockChanged))
                {
                    var neutralized = e.Neutralize();
                    Account.PushAccountEntry(neutralized);
                }
            }

            var unprocessedBlocks = mainChain.ToEnumerable(true)
                                    .TakeWhile(block => block != forkBlock)
                                    .Concat(newChain ? new ChainedBlock[] { forkBlock } : new ChainedBlock[0])
                                    .Reverse().ToArray();

            foreach (var block in unprocessedBlocks)
            {
                List <byte[]> searchedData = new List <byte[]>();
                Scanner.GetScannedPushData(searchedData);
                foreach (var unspent in Account.Unspent)
                {
                    searchedData.Add(unspent.OutPoint.ToBytes());
                }

                var fullBlock = blockProvider.GetBlock(block.HashBlock, searchedData);
                if (fullBlock != null)
                {
                    foreach (var spent in Scanner.FindSpent(fullBlock, Account.Unspent))
                    {
                        var entry = new AccountEntry(AccountEntryReason.Outcome,
                                                     block.HashBlock,
                                                     spent, -spent.TxOut.Value);
                        Account.PushAccountEntry(entry);
                    }
                    foreach (var coins in Scanner.ScanCoins(fullBlock, (int)block.Height))
                    {
                        int i = 0;
                        foreach (var output in coins.Coins.Outputs)
                        {
                            if (!output.IsNull)
                            {
                                var entry = new AccountEntry(AccountEntryReason.Income, block.HashBlock,
                                                             new Spendable(new OutPoint(coins.TxId, i), output), output.Value);
                                Account.PushAccountEntry(entry);
                            }
                            i++;
                        }
                    }
                }
                Chain.GetOrAdd(block.Header);
            }
        }
Пример #4
0
        public bool Process(ChainBase mainChain, IBlockProvider blockProvider)
        {
            var chainCopy       = Chain.Clone();
            var chainPosition   = chainCopy.Changes.Position;
            var accountCopy     = Account.Clone();
            var accountPosition = accountCopy.Entries.Position;

            bool newChain = false;

            if (!chainCopy.Initialized)
            {
                newChain = true;

                var firstBlock = mainChain.GetBlock(StartHeight);
                chainCopy.Initialize(firstBlock.Header, StartHeight);
            }
            var forkBlock = mainChain.FindFork(chainCopy);

            if (forkBlock.HashBlock != chainCopy.Tip.HashBlock)
            {
                var subChain = chainCopy.CreateSubChain(forkBlock, false, chainCopy.Tip, true);
                chainCopy.SetTip(chainCopy.GetBlock(forkBlock.Height));
                foreach (var e in accountCopy.GetInChain(subChain, true)
                         .Where(c => c.Reason != AccountEntryReason.Lock && c.Reason != AccountEntryReason.Unlock)
                         .Reverse())
                {
                    var neutralized = e.Neutralize();
                    accountCopy.PushAccountEntry(neutralized);
                }
            }

            var unprocessedBlocks = mainChain.ToEnumerable(true)
                                    .TakeWhile(block => block != forkBlock)
                                    .Concat(newChain ? new ChainedBlock[] { forkBlock } : new ChainedBlock[0])
                                    .Reverse().ToArray();

            foreach (var block in unprocessedBlocks)
            {
                List <byte[]> searchedData = new List <byte[]>();
                Scanner.GetScannedPushData(searchedData);
                foreach (var unspent in accountCopy.Unspent)
                {
                    searchedData.Add(unspent.OutPoint.ToBytes());
                }

                var fullBlock = blockProvider.GetBlock(block.HashBlock, searchedData);
                if (fullBlock == null)
                {
                    continue;
                }

                List <Tuple <OutPoint, AccountEntry> > spents = new List <Tuple <OutPoint, AccountEntry> >();
                foreach (var spent in FindSpent(fullBlock, accountCopy.Unspent))
                {
                    var entry = new AccountEntry(AccountEntryReason.Outcome,
                                                 block.HashBlock,
                                                 spent.Spendable, -spent.Spendable.TxOut.Value, spent.TxId);
                    spents.Add(Tuple.Create(entry.Spendable.OutPoint, entry));
                }

                if (CheckDoubleSpend)
                {
                    var spentsDico = spents.ToDictionary(t => t.Item1, t => t.Item2);
                    foreach (var spent in Scanner.FindSpent(fullBlock))
                    {
                        if (!spentsDico.ContainsKey(spent.PrevOut))
                        {
                            return(false);
                        }
                    }
                }

                foreach (var spent in spents)
                {
                    if (accountCopy.PushAccountEntry(spent.Item2) == null)
                    {
                        return(false);
                    }
                }

                foreach (var coins in Scanner.ScanCoins(fullBlock, (int)block.Height))
                {
                    int i = 0;
                    foreach (var output in coins.Coins.Outputs)
                    {
                        if (!output.IsNull)
                        {
                            var entry = new AccountEntry(AccountEntryReason.Income, block.HashBlock,
                                                         new Spendable(new OutPoint(coins.TxId, i), output), output.Value, null);
                            if (accountCopy.PushAccountEntry(entry) == null)
                            {
                                return(false);
                            }
                        }
                        i++;
                    }
                }

                chainCopy.SetTip(block);
            }

            accountCopy.Entries.GoTo(accountPosition);
            Account.PushAccountEntries(accountCopy.Entries);

            chainCopy.Changes.GoTo(chainPosition);
            Chain.PushChanges(chainCopy.Changes);
            return(true);
        }
Пример #5
0
        public bool Process(Chain mainChain, IBlockProvider blockProvider)
        {
            var chain = Chain.Clone();
            var chainPosition = chain.Changes.Position;
            var account = Account.Clone();
            var accountPosition = account.Entries.Position;

            bool newChain = false;
            if(!chain.Initialized)
            {
                newChain = true;

                var firstBlock = mainChain.GetBlock(StartHeight);
                chain.Initialize(firstBlock.Header, StartHeight);
            }
            var forkBlock = mainChain.FindFork(chain);
            if(forkBlock.HashBlock != chain.Tip.HashBlock)
            {
                var subChain = chain.CreateSubChain(forkBlock, false, chain.Tip, true);
                chain.SetTip(chain.GetBlock(forkBlock.Height));
                foreach(var e in account.GetInChain(subChain, true)
                                        .Where(c => c.Reason != AccountEntryReason.Lock && c.Reason != AccountEntryReason.Unlock)
                                        .Reverse())
                {
                    var neutralized = e.Neutralize();
                    account.PushAccountEntry(neutralized);
                }
            }

            var unprocessedBlocks = mainChain.ToEnumerable(true)
                                       .TakeWhile(block => block != forkBlock)
                                       .Concat(newChain ? new ChainedBlock[] { forkBlock } : new ChainedBlock[0])
                                       .Reverse().ToArray();
            foreach(var block in unprocessedBlocks)
            {
                List<byte[]> searchedData = new List<byte[]>();
                Scanner.GetScannedPushData(searchedData);
                foreach(var unspent in account.Unspent)
                {
                    searchedData.Add(unspent.OutPoint.ToBytes());
                }

                var fullBlock = blockProvider.GetBlock(block.HashBlock, searchedData);
                if(fullBlock == null)
                    continue;

                List<Tuple<OutPoint, AccountEntry>> spents = new List<Tuple<OutPoint, AccountEntry>>();
                foreach(var spent in FindSpent(fullBlock, account.Unspent))
                {
                    var entry = new AccountEntry(AccountEntryReason.Outcome,
                                                block.HashBlock,
                                                spent, -spent.TxOut.Value);
                    spents.Add(Tuple.Create(entry.Spendable.OutPoint, entry));
                }

                if(CheckDoubleSpend)
                {
                    var spentsDico = spents.ToDictionary(t => t.Item1, t => t.Item2);
                    foreach(var spent in Scanner.FindSpent(fullBlock))
                    {
                        if(!spentsDico.ContainsKey(spent.PrevOut))
                            return false;
                    }
                }

                foreach(var spent in spents)
                {
                    if(account.PushAccountEntry(spent.Item2) == null)
                        return false;
                }

                foreach(var coins in Scanner.ScanCoins(fullBlock, (int)block.Height))
                {
                    int i = 0;
                    foreach(var output in coins.Coins.Outputs)
                    {
                        if(!output.IsNull)
                        {
                            var entry = new AccountEntry(AccountEntryReason.Income, block.HashBlock,
                                                new Spendable(new OutPoint(coins.TxId, i), output), output.Value);
                            if(account.PushAccountEntry(entry) == null)
                                return false;
                        }
                        i++;
                    }
                }

                chain.GetOrAdd(block.Header);
            }

            account.Entries.GoTo(accountPosition);
            Account.Entries.WriteNext(account.Entries);
            Account.Process();

            chain.Changes.GoTo(chainPosition);
            Chain.Changes.WriteNext(chain.Changes);
            Chain.Process();
            return true;
        }