public void CommitChildOfUncommittedParent() { _chain = new SimpleBlockchain(); _chain.OpenFirstBlock(); var id = _chain.OpenBlock(_1).Alias; Assert.Throws <ArgumentException>(() => _chain.CommitBlock(id, _hash1)); }
public void AddBlockToCommittedParent() { _chain = new SimpleBlockchain(); var id = _chain.OpenFirstBlock().Alias; _chain.CommitBlock(id, BlockId.Genesis); _chain.OpenBlock(_1); }
public void AddValidBlocksWithFork() { _chain = new SimpleBlockchain(); var id = _chain.OpenFirstBlock().Alias; Assert.Equal(0, _chain.BlockchainHeight); _chain.CommitBlock(id, BlockId.Genesis); Assert.Equal(0, _chain.BlockchainHeight); id = _chain.OpenBlock(_1).Alias; Assert.Equal(1, _chain.BlockchainHeight); _chain.CommitBlock(id, _hash1); Assert.Equal(1, _chain.BlockchainHeight); id = _chain.OpenBlock(_2).Alias; Assert.Equal(2, _chain.BlockchainHeight); _chain.CommitBlock(id, _hash2); Assert.Equal(2, _chain.BlockchainHeight); // Second child for second block id = _chain.OpenBlock(_2).Alias; Assert.Equal(2, _chain.BlockchainHeight); _chain.CommitBlock(id, _hash3); Assert.Equal(2, _chain.BlockchainHeight); }
public void Setup() { var id = _chain.OpenFirstBlock().Alias; _chain.CommitBlock(id, BlockId.Genesis); id = _chain.OpenBlock(_1).Alias; _chain.CommitBlock(id, new BlockId(new Hash256(0x11111111UL, 0x22222222UL, 0x33333333UL, 0x44444444UL))); id = _chain.OpenBlock(_2).Alias; _chain.CommitBlock(id, new BlockId(new Hash256(0xFFFFFFFFUL, 0xEEEEEEEEUL, 0xDDDDDDDDUL, 0xCCCCCCCCUL))); // Second child for block 2 id = _chain.OpenBlock(_2).Alias; _chain.CommitBlock(id, new BlockId(new Hash256(0x1111111122UL, 0x2222222233UL, 0x3333333344UL, 0x4444444455UL))); // main chain prolonged id = _chain.OpenBlock(_3).Alias; _chain.CommitBlock(id, new BlockId(new Hash256(0x1111111122UL, 0x2222222233UL, 0x3333333344UL, 0x4444444455UL))); // side chain prolonged id = _chain.OpenBlock(_4).Alias; _chain.CommitBlock(id, new BlockId(new Hash256(0x1111111122UL, 0x2222222233UL, 0x3333333344UL, 0x4444444455UL))); // fork on end of main chain id = _chain.OpenBlock(_5).Alias; _chain.CommitBlock(id, new BlockId(new Hash256(0x1111111122UL, 0x2222222233UL, 0x3333333344UL, 0x4444444455UL))); id = _chain.OpenBlock(_5).Alias; _chain.CommitBlock(id, new BlockId(new Hash256(0x1111111122UL, 0x2222222233UL, 0x3333333344UL, 0x4444444455UL))); var chainStrategy = new BlockchainStrategies(); var opti = new OptimizedLineage(chainStrategy.GetQuasiOrphans(_chain), _2); _controller = new ControllerThread(_chain, opti, _inbox = BoundedInbox.Create(), _outbox = BoundedInbox.Create()); }
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); }
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. } }