Esempio n. 1
0
        private ILineage MakeLineage()
        {
            var blockId1   = CommittedBlockId.ReadFromHex("0000000000000000000000000000000000000000000000000000000000AAA333");
            var commBlock1 = new CommittedBlock(blockId1, BlockAlias.Genesis, BlockAlias.GenesisParent);
            var blockId2   = CommittedBlockId.ReadFromHex("0000000000000000000000000000000000000000000000000000000000BBB444");
            var commBlock2 = new CommittedBlock(blockId2, new BlockAlias(2), BlockAlias.Genesis);
            var blockId3   = CommittedBlockId.ReadFromHex("0000000000000000000000000000000000000000000000000000000000CCC555");
            var commBlock3 = new CommittedBlock(blockId3, new BlockAlias(3), new BlockAlias(2));

            var uncommBlock = new UncommittedBlock(UncommittedBlockId.Create(), new BlockAlias(4), new BlockAlias(3));

            var committedBlocks = new List <CommittedBlock>();

            committedBlocks.Add(commBlock1);
            committedBlocks.Add(commBlock2);
            committedBlocks.Add(commBlock3);

            var uncommittedBlocks = new List <UncommittedBlock>();

            uncommittedBlocks.Add(uncommBlock);

            return(new Lineage(committedBlocks, uncommittedBlocks, 100));
        }
Esempio n. 2
0
        /// <summary>
        /// Reads blockchain information from a stream in the following order:
        ///  - number of blocks to read
        ///  - blocks with Hash256 representing the blockId first, then int
        ///         representing the parentAlias
        /// The blockHeight is calculated for each block based on the
        /// blockHeight of its parent, so it should not be stored.
        /// The corresponding Serialization method is <see cref="WriteTo"/>.
        /// </summary>
        /// <returns>A new list representing the blockchain.</returns>
        public static SimpleBlockchain ReadFrom(BinaryReader reader)
        {
            var committedBlocks   = new List <CommittedBlock>();
            var uncommittedBlocks = new List <UncommittedBlock>();
            var maxBlockHeight    = 0; // track the blockHeight so that it doesn't have to be recalculated afterward

            // Read blocks
            var committedBlockCount = reader.ReadInt32();

            for (var i = 0; i < committedBlockCount; i++)
            {
                var blockId     = new BlockId(reader.ReadHash256());
                var blockAlias  = new BlockAlias(reader.ReadUInt32());
                var parentAlias = new BlockAlias(reader.ReadUInt32());

                // Only the first block can have parentAlias 0.
                if (parentAlias == BlockAlias.GenesisParent && !blockId.Equals(BlockId.Genesis) ||
                    blockAlias.IsPrior(parentAlias))
                {
                    throw new FormatException(
                              $"Parent alias {parentAlias} is an invalid parent for block {blockAlias}.");
                }

                if (!TryFindCommitted(parentAlias, committedBlocks, out var parentBlock) &&
                    !blockId.Equals(BlockId.Genesis))
                {
                    throw new ArgumentNullException($"No parent {parentAlias} found.");
                }

                // The first block, which is the only one to have parent 0, has block height 0.
                var blockHeight = parentAlias == BlockAlias.GenesisParent
                    ? 0
                    : parentBlock.BlockHeight + 1;
                var newBlock = new CommittedBlock(blockHeight, blockId, blockAlias, parentAlias);

                if (blockHeight > maxBlockHeight)
                {
                    maxBlockHeight = blockHeight;
                }

                committedBlocks.Add(newBlock);
            }

            var numUncommmittedBlocks = reader.ReadInt32();

            for (var i = 0; i < numUncommmittedBlocks; i++)
            {
                var blockId     = new TempBlockId(reader.ReadHash128());
                var blockAlias  = new BlockAlias(reader.ReadUInt32());
                var parentAlias = new BlockAlias(reader.ReadUInt32());

                // Only the first block can have parentAlias 0.
                if ((uncommittedBlocks.Count != 0 || committedBlocks.Count != 0) &&
                    parentAlias == BlockAlias.GenesisParent || blockAlias.IsPrior(parentAlias))
                {
                    throw new FormatException(
                              $"Parent alias {parentAlias} is an invalid parent for block {blockAlias}.");
                }

                int blockHeight;
                if (TryFindCommitted(parentAlias, committedBlocks, out var parentBlock))
                {
                    blockHeight = parentBlock.BlockHeight + 1;
                }
                else
                {
                    if (uncommittedBlocks.Count == 0 && committedBlocks.Count == 0 &&
                        parentAlias == BlockAlias.GenesisParent) // we're adding the first block
                    {
                        blockHeight = 1;
                    }
                    else
                    {
                        if (!TryFindUncommitted(parentAlias, uncommittedBlocks, out var uParentBlock))
                        {
                            throw new ArgumentNullException($"No parent {parentAlias} found.");
                        }
                        blockHeight = uParentBlock.BlockHeight + 1;
                    }
                }

                var newBlock = new UncommittedBlock(blockHeight, blockId, blockAlias, parentAlias);

                if (blockHeight > maxBlockHeight)
                {
                    maxBlockHeight = blockHeight;
                }

                uncommittedBlocks.Add(newBlock);
            }

            return(new SimpleBlockchain(committedBlocks, uncommittedBlocks, maxBlockHeight));
        }
Esempio n. 3
0
 /// <summary>
 /// Find a given committed block in a chain of committed blocks that is
 /// enumerated from the end.
 /// </summary>
 /// <remarks>
 /// The enumerator of the blockchain cannot be used as the blockchain
 /// has not been created yet.
 /// </remarks>
 private static bool TryFindCommitted(BlockAlias alias, List <CommittedBlock> blocks,
                                      out CommittedBlock foundCommittedBlock)
 {
     foundCommittedBlock = blocks.FindLast(b => b.Alias == alias);
     return(!foundCommittedBlock.Equals(default));