Example #1
0
        public void ReadAndWriteStreamAllUncommitted()
        {
            AddValidBlocksWithForkAllUncommitted();
            var stream = new MemoryStream();
            var writer = new BinaryWriter(stream);
            var reader = new BinaryReader(stream);

            BlockchainSerializer.WriteTo(writer, _chain);
            stream.Seek(0, 0);
            SimpleBlockchain newChain = BlockchainSerializer.ReadFrom(reader);

            Assert.Equal(_1, newChain.RetrieveAlias(_tmpId1));
            Assert.Equal(_2, newChain.RetrieveAlias(_tmpId2));
            Assert.Equal(_3, newChain.RetrieveAlias(_tmpId3));
            Assert.Equal(_4, newChain.RetrieveAlias(_tmpId4));

            Assert.True(newChain.RetrieveUncommittedBlock(_1, out var oneBlock));
            Assert.True(newChain.RetrieveUncommittedBlock(_2, out var twoBlock));
            Assert.True(newChain.RetrieveUncommittedBlock(_3, out var threeBlock));
            Assert.True(newChain.RetrieveUncommittedBlock(_4, out var fourBlock));

            Assert.Equal(_tmpId1, oneBlock.BlockId);
            Assert.Equal(_tmpId2, twoBlock.BlockId);
            Assert.Equal(_tmpId3, threeBlock.BlockId);
            Assert.Equal(_tmpId4, fourBlock.BlockId);

            Assert.Equal(2, _chain.BlockchainHeight);
        }
Example #2
0
        public void RetrieveBlock()
        {
            AddValidBlocksWithForkAllUncommitted();

            Assert.True(_chain.RetrieveUncommittedBlock(_1, out var genesisBlockU));
            Assert.True(_chain.RetrieveUncommittedBlock(_2, out var firstBlockU));
            Assert.True(_chain.RetrieveUncommittedBlock(_3, out var secondBlockU));
            Assert.True(_chain.RetrieveUncommittedBlock(_4, out var forkU));

            Assert.Equal(_tmpId1, genesisBlockU.BlockId);
            Assert.Equal(_tmpId2, firstBlockU.BlockId);
            Assert.Equal(_tmpId3, secondBlockU.BlockId);
            Assert.Equal(_tmpId4, forkU.BlockId);
            Assert.Equal(_1, firstBlockU.Parent);
            Assert.Equal(_2, secondBlockU.Parent);
            Assert.Equal(_2, forkU.Parent);
            Assert.Equal(0, genesisBlockU.BlockHeight);
            Assert.Equal(1, firstBlockU.BlockHeight);
            Assert.Equal(2, secondBlockU.BlockHeight);
            Assert.Equal(2, forkU.BlockHeight);

            _chain.CommitBlock(_1, BlockId.Genesis);
            _chain.CommitBlock(_2, _hash1);
            _chain.CommitBlock(_3, _hash2);
            _chain.CommitBlock(_4, _hash3);

            Assert.True(_chain.RetrieveCommittedBlock(_1, out var genesisBlock));
            Assert.True(_chain.RetrieveCommittedBlock(_2, out var firstBlock));
            Assert.True(_chain.RetrieveCommittedBlock(_3, out var secondBlock));
            Assert.True(_chain.RetrieveCommittedBlock(_4, out var fork));

            Assert.Equal(BlockId.Genesis, genesisBlock.BlockId);
            Assert.Equal(_hash1, firstBlock.BlockId);
            Assert.Equal(_hash2, secondBlock.BlockId);
            Assert.Equal(_hash3, fork.BlockId);
            Assert.Equal(_1, firstBlock.Parent);
            Assert.Equal(_2, secondBlock.Parent);
            Assert.Equal(_2, fork.Parent);
            Assert.Equal(0, genesisBlock.BlockHeight);
            Assert.Equal(1, firstBlock.BlockHeight);
            Assert.Equal(2, secondBlock.BlockHeight);
            Assert.Equal(2, fork.BlockHeight);
        }
Example #3
0
        public void DoWork()
        // TODO: [vermorel] method should return 'true' if any work has been done
        {
            var nextMessage = _inbox.Peek();

            if (nextMessage.Length != 0)
            {
                // get message type and deserialize accordingly
                var reqType = ClientServerMessage.GetMessageType(nextMessage);
                switch (reqType)
                {
// TODO: [vermorel] I don't like to too much the code below, it's highly repetitive, factorization is needed.

                case MessageType.OpenBlock:
                    var openBlock = MessageSerializers.DeserializeOpenBlock(nextMessage);
                    UncommittedBlock block;
                    if (openBlock.ParentHandle == BlockAlias.GenesisParent && _chain.BlockchainLength == 0)
                    {
                        block = _chain.OpenFirstBlock();
                    }
                    else
                    {
                        block = _chain.OpenBlock(openBlock.ParentHandle);
                    }
                    var blockHandle =
                        new OpenedBlock(openBlock.RequestId, openBlock.ClientId, block.BlockId, block.Alias);
                    MessageSerializers.SerializeOpenedBlock(blockHandle, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, OpenedBlock.SizeInBytes));
                    break;

                case MessageType.GetBlockHandle:
                    var getBlockHandle  = MessageSerializers.DeserializeGetBlockHandle(nextMessage);
                    var retrievedHandle = _chain.RetrieveAlias(getBlockHandle.BlockId);
                    var returnMessage   = new BlockHandleResponse(getBlockHandle.RequestId, getBlockHandle.ClientId,
                                                                  retrievedHandle);
                    MessageSerializers.SerializeBlockHandleResponse(returnMessage, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, BlockHandleResponse.SizeInBytes));
                    break;

                case MessageType.GetUncommittedBlockHandle:
                    var getUBlockHandle  = MessageSerializers.DeserializeGetUncommittedBlockHandle(nextMessage);
                    var retrievedUHandle = _chain.RetrieveAlias(getUBlockHandle.UncommittedBlockId);
                    var returnMes        = new BlockHandleResponse(getUBlockHandle.RequestId, getUBlockHandle.ClientId,
                                                                   retrievedUHandle);
                    MessageSerializers.SerializeBlockHandleResponse(returnMes, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, BlockHandleResponse.SizeInBytes));
                    break;

                case MessageType.CommitBlock:
                    var commitBlock = MessageSerializers.DeserializeCommitBlock(nextMessage);
                    _chain.CommitBlock(commitBlock.BlockHandle, commitBlock.BlockId);
                    var committedMessage =
                        new EverythingOkResponse(commitBlock.RequestId, commitBlock.ClientId);
                    MessageSerializers.SerializeEverythingOk(committedMessage, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, EverythingOkResponse.SizeInBytes));
                    break;

                case MessageType.IsAncestor:
                    var isAncestor        = MessageSerializers.DeserializeIsAncestor(nextMessage);
                    var res               = _opti.IsAncestor(isAncestor.BlockHandle, isAncestor.MaybeAncestorHandle);
                    var isAncestorMessage = new AncestorResponse(isAncestor.RequestId, isAncestor.ClientId, res);
                    MessageSerializers.SerializeAncestorResponse(isAncestorMessage, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, AncestorResponse.SizeInBytes));
                    break;

                case MessageType.IsPruneable:
                    var isPruneable        = MessageSerializers.DeserializeIsPruneable(nextMessage);
                    var result             = _opti.IsPruneable(isPruneable.BlockHandle);
                    var isPruneableMessage = new PruneableResponse(isPruneable.RequestId, isPruneable.ClientId, result);
                    MessageSerializers.SerializePruneableResponse(isPruneableMessage, _responseBuffer);
                    _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, PruneableResponse.SizeInBytes));
                    break;

                case MessageType.GetBlockInfo:
                    var blockInfoReq = MessageSerializers.DeserializeGetBlockInfo(nextMessage);

                    // TODO: [vermorel] clarify the purpose of this test, unclear
                    if (_chain.RetrieveCommittedBlock(blockInfoReq.BlockHandle, out var blockInfoC))
                    {
                        var blockInfo =
                            new CommittedBlockInformation(blockInfoReq.RequestId, blockInfoReq.ClientId,
                                                          blockInfoC.BlockId, blockInfoC.Alias, blockInfoC.BlockHeight, blockInfoC.Parent);
                        MessageSerializers.SerializeCommittedBlockInfo(blockInfo, _responseBuffer);
                        _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, CommittedBlockInformation.SizeInBytes));
                        break;
                    }
                    else
                    {
                        _chain.RetrieveUncommittedBlock(blockInfoReq.BlockHandle, out var blockInfoU);
                        var blockInfo =
                            new UncommittedBlockInformation(blockInfoReq.RequestId, blockInfoReq.ClientId,
                                                            blockInfoU.BlockId, blockInfoU.Alias, blockInfoU.BlockHeight, blockInfoU.Parent);
                        MessageSerializers.SerializeUncommittedBlockInfo(blockInfo, _responseBuffer);
                        _outbox.TryWrite(new Span <byte>(_responseBuffer, 0, UncommittedBlockInformation.SizeInBytes));
                        break;
                    }

// TODO: [vermorel] the 'default:' case should be covered with an NotSupportedException.
                }
                _inbox.Next();
                // TODO: errors are not yet handled.
            }
        }