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 AddValidBlocksWithForkAllUncommitted() { _chain = new SimpleBlockchain(); _tmpId1 = _chain.OpenFirstBlock().BlockId; _tmpId2 = _chain.OpenBlock(_1).BlockId; _tmpId3 = _chain.OpenBlock(_2).BlockId; // Second child for second block _tmpId4 = _chain.OpenBlock(_2).BlockId; }
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 AddBlockToUncommittedParent() { _chain = new SimpleBlockchain(); _chain.OpenFirstBlock(); _chain.OpenBlock(_1); }
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. } }