示例#1
0
		public bool TrySetTip(BlockHeader header, out ChainedBlock chainedHeader)
		{
			if (header == null) throw new ArgumentNullException("header");
			chainedHeader = null;
			var prev = GetBlock(header.HashPrevBlock);
			if(prev == null)
				return false;
			chainedHeader = new ChainedBlock(header, header.GetHash(), GetBlock(header.HashPrevBlock));
			SetTip(chainedHeader);
			return true;
		}
示例#2
0
        public bool TrySetTip(BlockHeader header, out ChainedBlock chainedHeader)
        {
            if (header == null)
            {
                throw new ArgumentNullException("header");
            }
            chainedHeader = null;
            var prev = GetBlock(header.HashPrevBlock);

            if (prev == null)
            {
                return(false);
            }
            chainedHeader = new ChainedBlock(header, header.GetHash(), GetBlock(header.HashPrevBlock));
            SetTip(chainedHeader);
            return(true);
        }
示例#3
0
        public ChainedBlock CreateChainedBlock(BlockHeader header)
        {
            AssertInitialized();
            var hash   = header.GetHash();
            var result = GetBlock(hash, true);

            if (result == null)
            {
                var previous = GetBlock(header.HashPrevBlock, true);
                if (previous == null)
                {
                    throw new InvalidOperationException("Previous block is missing");
                }
                return(new ChainedBlock(header, hash, previous));
            }
            return(result);
        }
        /// <summary>
        /// Attempts to set the tip of this chain based upon another block header.
        /// </summary>
        /// <param name="header">The block header to set to tip.</param>
        /// <param name="chainedHeader">The newly chained block header for the tip.</param>
        /// <returns>Whether the tip was set successfully. The method fails (and returns <c>false</c>)
        /// if the <paramref name="header"/>'s link to a previous header does not point to any block
        /// in the current chain.</returns>
        public bool TrySetTip(BlockHeader header, out ChainedBlock chainedHeader)
        {
            if (header == null)
            {
                throw new ArgumentNullException("header");
            }

            chainedHeader = null;
            ChainedBlock prev = this.GetBlock(header.HashPrevBlock);

            if (prev == null)
            {
                return(false);
            }

            chainedHeader = new ChainedBlock(header, header.GetHash(this.Network.NetworkOptions), this.GetBlock(header.HashPrevBlock));
            this.SetTip(chainedHeader);
            return(true);
        }
示例#5
0
        // (memory only) Sequencial id assigned to distinguish order in which blocks are received.
        //uint nSequenceId;
        public ChainedBlock(BlockHeader header,uint256 headerHash, ChainedBlock previous)
        {
            if(previous != null)
            {
                nHeight = previous.Height + 1;
            }
            this.pprev = previous;
            //this.nDataPos = pos;
            this.header = header;
            this.phashBlock = headerHash ?? header.GetHash();

            if(previous == null)
            {
                if(header.HashPrevBlock != 0)
                    throw new ArgumentException("Only the genesis block can have no previous block");
            }
            else
            {
                if(previous.HashBlock != header.HashPrevBlock)
                    throw new ArgumentException("The previous block has not the expected hash");
            }
        }
        public void Load(BitcoinStream stream)
        {
            stream.ConsensusFactory = this.network.Consensus.ConsensusFactory;

            using (this.lockObject.LockWrite())
            {
                try
                {
                    int height = 0;
                    while (true)
                    {
                        uint256.MutableUint256 id = null;
                        stream.ReadWrite <uint256.MutableUint256>(ref id);
                        BlockHeader header = null;
                        stream.ReadWrite(ref header);
                        if (height == 0)
                        {
                            this.blocksByHeight.Clear();
                            this.blocksById.Clear();
                            this.tip = null;
                            this.SetTipLocked(new ChainedHeader(header, header.GetHash(), 0));
                        }
                        else if (this.tip.HashBlock == header.HashPrevBlock && !(header.IsNull && header.Nonce == 0))
                        {
                            this.SetTipLocked(new ChainedHeader(header, id.Value, this.Tip));
                        }
                        else
                        {
                            break;
                        }

                        height++;
                    }
                }
                catch (EndOfStreamException)
                {
                }
            }
        }
示例#7
0
		public ChainedBlock(BlockHeader header, int height)
		{
			if(header == null)
				throw new ArgumentNullException("header");
			nHeight = height;
			//this.nDataPos = pos;
			this.header = header;
			this.phashBlock = header.GetHash();
		}
示例#8
0
 public ChainedBlock(BlockHeader header, int height)
 {
     nHeight = height;
     //this.nDataPos = pos;
     this.header = header;
     this.phashBlock = header.GetHash();
 }
 public ConcurrentChain(BlockHeader genesisHeader, Network network = null) // TODO: Remove the null default
 {
     this.network = network ?? Network.Main;
     this.SetTip(new ChainedHeader(genesisHeader, genesisHeader.GetHash(), 0));
 }
示例#10
0
 public bool PutHeader(BlockHeader blockHeader)
 {
     return(this.headers.TryAdd(blockHeader.GetHash(), blockHeader));
 }
示例#11
0
 public Chain(BlockHeader blockHeader, int height, ObjectStream<ChainChange> changes)
 {
     if(changes == null)
         changes = new StreamObjectStream<ChainChange>();
     _Changes = changes;
     changes.Rewind();
     if(changes.EOF)
     {
         Initialize(blockHeader, height);
     }
     else
     {
         var first = changes.ReadNext();
         if(first.BlockHeader.GetHash() != blockHeader.GetHash())
         {
             throw new InvalidOperationException("The first block of this stream is different than the expected one at height " + height);
         }
         if(first.HeightOrBackstep != height)
         {
             throw new InvalidOperationException("The first block of this stream has height " + first.HeightOrBackstep + " but expected is " + height);
         }
         changes.Rewind();
         Process();
     }
 }
示例#12
0
 public ConcurrentChain(BlockHeader genesisHeader, Network network = null) // TODO: Remove the null default
 {
     this.network = network ?? Network.PurpleMain;
     this.SetTip(new ChainedBlock(genesisHeader, genesisHeader.GetHash(this.network.NetworkOptions), 0));
 }
示例#13
0
 public void Initialize(BlockHeader header, int height)
 {
     if(Initialized)
         throw new InvalidOperationException("Already initialized");
     var change = new ChainChange()
     {
         Add = true,
         BlockHeader = header,
         HeightOrBackstep = (uint)height
     };
     ProcessAndRecord(change, header.GetHash());
 }
示例#14
0
        public ChainedBlock GetOrAdd(BlockHeader header)
        {
            AssertInitialized();
            var headerHash = header.GetHash();
            ChainedBlock pindex = GetBlock(headerHash, true);
            if(pindex != null)
                return pindex;
            ChainedBlock previous = GetBlock(header.HashPrevBlock, true);
            if(previous == null)
            {
                return null;
            }

            pindex = new ChainedBlock(header, headerHash, previous);
            if(previous.HashBlock == Tip.HashBlock)
            {
                var change = new ChainChange()
                {
                    Add = true,
                    BlockHeader = pindex.Header,
                    HeightOrBackstep = (uint)pindex.Height
                };
                ProcessAndRecord(change, pindex.HashBlock);
            }
            else
            {
                if(pindex.Height <= Tip.Height)
                {
                    offchainIndex.Add(pindex.HashBlock, pindex);
                }
                else
                {
                    var fork = FindFork(pindex.EnumerateToGenesis().Select(c => c.HashBlock));
                    var change = new ChainChange()
                    {
                        Add = false,
                        HeightOrBackstep = (uint)(Tip.Height - fork.Height)
                    };
                    ProcessAndRecord(change, null);

                    foreach(var block in pindex.EnumerateToGenesis().TakeWhile(s => s != fork).Reverse())
                    {
                        change = new ChainChange()
                        {
                            Add = true,
                            BlockHeader = block.Header,
                            HeightOrBackstep = (uint)block.Height
                        };
                        ProcessAndRecord(change, block.HashBlock);
                    }
                }
            }
            return pindex;
        }
示例#15
0
文件: Block.cs 项目: long20p/CoinBag
 public uint256 GetHash()
 {
     //Block's hash is his header's hash
     return(header.GetHash());
 }
示例#16
0
 public Target GetNextWorkRequired(BlockHeader block, Consensus consensus)
 {
     return(new ChainedBlock(block, block.GetHash(), this).GetWorkRequired(consensus));
 }
 private ChainBlockHeader CreateChainChange(int height, BlockHeader block)
 {
     return new ChainBlockHeader()
                {
                    Height = height,
                    Header = block,
                    BlockId = block.GetHash()
                };
 }