public void CommitBlock(BlockHandle handle, CommittedBlockId blockId) { var returnCode = PInvokes.terab_utxo_commit_block(_connection, handle, ref blockId); if (returnCode != ReturnCode.SUCCESS) { throw new TerabException("CommitBlock failed.", returnCode); } }
private static unsafe CommittedBlockId GetMockBlockId(byte filler) { var blockId = new CommittedBlockId(); for (var i = 0; i < CommittedBlockId.SizeInBytes; i++) { blockId.Data[i] = filler; } return(blockId); }
public BlockHandle GetCommittedBlock(CommittedBlockId blockId) { var returnCode = PInvokes.terab_utxo_get_committed_block( _connection, ref blockId, out BlockHandle handle); if (returnCode != ReturnCode.SUCCESS) { throw new TerabException("GetCommittedBlock failed.", returnCode); } return(handle); }
private static unsafe CommittedBlockId GetBlockId() { var buffer = new byte[32]; RandomNumberGenerator.Fill(buffer); var blockId = new CommittedBlockId(); for (var i = 0; i < 32; i++) { blockId.Data[i] = buffer[i]; } return(blockId); }
public unsafe void DeepChain() { var store = new ChainStore(new MemoryMappedFileSlim(MemoryMappedFile.CreateNew(null, BlockHeight * 120 + 4096 - (BlockHeight * 120) % 4096))); store.Initialize(); var watch = new Stopwatch(); watch.Start(); store.TryOpenBlock(CommittedBlockId.GenesisParent, out var ub); for (var i = 0; i < BlockHeight; i++) { var blockId = new CommittedBlockId(); for (var j = 0; j < 4; j++) { blockId.Data[j] = (byte)(j >> (i * 8)); } blockId.Data[5] = 1; // ensure non-zero store.TryCommitBlock(ub.Alias, blockId, out var cb); // Filtering to improve speed. // Only ~1ms, but we can have a million calls. if (i <= 1000) { var lineage2 = store.GetLineage(); Assert.False(lineage2.IsUncommitted(cb.Alias)); } store.TryOpenBlock(blockId, out ub); } // ~0.013ms to open & commit a new block against 500k blocks. _log.Log(LogSeverity.Info, $"{(double)watch.ElapsedMilliseconds / BlockHeight} ms per block (pure I/O)."); watch.Reset(); watch.Start(); // ~70ms against 500k blocks with orphan at zero height (when disabling 'OldestOrphanHeight'). var lastLineage = store.GetLineage(); Assert.True(lastLineage.IsUncommitted(ub.Alias)); _log.Log(LogSeverity.Info, $"{(double)watch.ElapsedMilliseconds } ms on GetLineage last block (at {BlockHeight} height)."); }
private static void CommitBlock(BlockHandle handle, CommittedBlockId blockId, ISocketLike socket) { var request = CommitBlockRequest.From( RequestId.MinRequestId, ClientId.MinClientId, handle, blockId); socket.Send(request.Span); var response = new CommitBlockResponse(new byte[CommitBlockResponse.SizeInBytes]); socket.Receive(response.Span); if (response.Status != CommitBlockStatus.Success) { throw new InvalidOperationException("Failed to commit block."); } }
/// <summary> /// Allocate an array. Intended for testing purposes only. /// </summary> internal static OpenBlockRequest From( RequestId requestId, ClientId clientId, CommittedBlockId parentId) { var request = new OpenBlockRequest { _buffer = new Span <byte>(new byte[sizeof(Header)]) }; request.MessageHeader.MessageSizeInBytes = Header.SizeInBytes; request.MessageHeader.RequestId = requestId; request.MessageHeader.ClientId = clientId; request.MessageHeader.MessageKind = MessageKind.OpenBlock; request.AsHeader.ParentId = parentId; return(request); }
/// <summary> /// Allocate an array. Intended for testing purposes only. /// </summary> internal static CommitBlockRequest From( RequestId requestId, ClientId clientId, BlockHandle handle, CommittedBlockId blockId) { var request = new CommitBlockRequest { _buffer = new Span <byte>(new byte[sizeof(Header)]) }; request.MessageHeader.MessageSizeInBytes = Header.SizeInBytes; request.MessageHeader.RequestId = requestId; request.MessageHeader.ClientId = clientId; request.MessageHeader.MessageKind = MessageKind.CommitBlock; request.AsHeader.Handle = handle; request.AsHeader.BlockId = blockId; return(request); }
public BlockHandle OpenBlock(CommittedBlockId parent, out UncommittedBlockId ucid) { ucid = default; var returnCode = PInvokes.terab_utxo_open_block( _connection, ref parent, out BlockHandle handle, ref ucid); if (returnCode != ReturnCode.SUCCESS) { throw new TerabException("OpenBlock failed.", returnCode); } return(handle); }
private static BlockHandle OpenBlock(CommittedBlockId parentId, ISocketLike socket, ILog log) { var openBlockRequest = OpenBlockRequest.From( RequestId.MinRequestId, ClientId.MinClientId, parentId); socket.Send(openBlockRequest.Span); var openBlockResponse = new OpenBlockResponse(new byte[OpenBlockResponse.SizeInBytes]); socket.Receive(openBlockResponse.Span); if (openBlockResponse.Status != OpenBlockStatus.Success) { throw new InvalidOperationException("Failed to open block."); } log.Log(LogSeverity.Info, "Block opened, writing coins..."); return(openBlockResponse.Handle); }
public void TryAddConsumptionInPastTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); // Create a real lineage var cBlocks = new List <CommittedBlock>(); cBlocks.Add(new CommittedBlock(CommittedBlockId.Genesis, BlockAlias.Genesis, BlockAlias.GenesisParent)); var firstBlockAlias = new BlockAlias(1, 0); cBlocks.Add(new CommittedBlock( CommittedBlockId.ReadFromHex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD"), firstBlockAlias, BlockAlias.Genesis)); var futureBlockAlias = new BlockAlias(2, 0); cBlocks.Add(new CommittedBlock( CommittedBlockId.ReadFromHex("AAAABBBBBBBBCCCCCCCCDDDDDDDDAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDAAAA"), futureBlockAlias, firstBlockAlias)); var realLineage = new Lineage(cBlocks, new List <UncommittedBlock>(), 100); var sozu = GetSozuTable(volatileStore, hash); var coin1 = GetCoin(rand); // The next two commands will work because the fact that a block is uncommitted is not verified anymore. // If this test is moved into the ICoinStore at any point, adding a previous consumption should fail // already because a 'previous' block always has to be committed. var ret = sozu.AddProduction(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, false, coin1.Payload, futureBlockAlias, realLineage); Assert.Equal(CoinChangeStatus.Success, ret); var cons = sozu.AddConsumption(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, firstBlockAlias, realLineage); Assert.Equal(CoinChangeStatus.InvalidContext, cons); }
public GetBlockInfoResponse( ref MessageHeader requestHeader, CommittedBlockId committedBlockId, BlockAlias alias, BlockAlias parent, int blockHeight, BlockHandleMask mask, SpanPool <byte> pool) { _buffer = pool.GetSpan(Header.SizeInBytes); AsHeader.ResponseHeader = requestHeader; AsHeader.ResponseHeader.MessageKind = MessageKind.BlockInfoResponse; AsHeader.ResponseHeader.MessageSizeInBytes = Header.SizeInBytes; AsHeader.CommittedBlockId = committedBlockId; AsHeader.Handle = alias.ConvertToBlockHandle(mask); AsHeader.Parent = parent.ConvertToBlockHandle(mask); AsHeader.BlockHeight = blockHeight; AsHeader.IsCommitted = true; }
public void TryGetCoinInFutureTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); // Create a real lineage. It doesn't matter if all blocks are committed because we are just reading. var cBlocks = new List <CommittedBlock>(); cBlocks.Add(new CommittedBlock(CommittedBlockId.Genesis, BlockAlias.Genesis, BlockAlias.GenesisParent)); var firstBlockAlias = new BlockAlias(1, 0); cBlocks.Add(new CommittedBlock( CommittedBlockId.ReadFromHex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD"), firstBlockAlias, BlockAlias.Genesis)); var futureBlockAlias = new BlockAlias(2, 0); cBlocks.Add(new CommittedBlock( CommittedBlockId.ReadFromHex("AAAABBBBBBBBCCCCCCCCDDDDDDDDAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDAAAA"), futureBlockAlias, firstBlockAlias)); var realLineage = new Lineage(cBlocks, new List <UncommittedBlock>(), 100); var sozu = GetSozuTable(volatileStore, hash); var coin1 = GetCoin(rand); var ret = sozu.AddProduction(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, false, coin1.Payload, futureBlockAlias, realLineage); Assert.Equal(CoinChangeStatus.Success, ret); var read = sozu.TryGet(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, firstBlockAlias, realLineage, out var coin, out var prod, out var cons); Assert.False(read); }
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)); }
public OpenBlockStatus TryOpenBlock(CommittedBlockId parent, out UncommittedBlock freshBlock) { var blocks = GetBlocks(); var blockCount = AsHeader.BlockCount; var lowerIndex = Math.Max(0, blockCount - BlockScanLimit); freshBlock = default; if (blockCount == 0 && !parent.Equals(CommittedBlockId.GenesisParent)) { return(OpenBlockStatus.ParentNotFound); } // Find the parent, and assess the block height int parentBlockHeight = -1; var parentAlias = BlockAlias.Undefined; for (var i = blockCount - 1; i >= lowerIndex; i--) { ref var candidate = ref blocks[i]; if (candidate.IsDeleted) { continue; } if (candidate.BlockId.Equals(parent)) { parentBlockHeight = candidate.BlockHeight; parentAlias = candidate.Alias; break; } if (i == 0) { return(OpenBlockStatus.ParentNotFound); } }
public unsafe void OpenCommit() { var instance = GetInstance(); instance.Start(); var localEndpoint = new IPEndPoint(IPAddress.Loopback, instance.Port); var rawSocket = new Socket(localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); rawSocket.Connect(localEndpoint); var socket = new SocketLikeAdapter(rawSocket); try { // Open block var openBlockRequest = OpenBlockRequest.ForGenesis(RequestId.MinRequestId); socket.Send(openBlockRequest.Span); var openBlockResponse = new OpenBlockResponse(new byte[OpenBlockResponse.SizeInBytes]); socket.Receive(openBlockResponse.Span); Assert.Equal(OpenBlockStatus.Success, openBlockResponse.Status); // Commit block var blockId = new CommittedBlockId(); for (var i = 0; i < CommittedBlockId.SizeInBytes; i++) { blockId.Data[i] = (byte)i; } var commitBlockRequest = CommitBlockRequest.From( RequestId.MinRequestId, ClientId.MinClientId, openBlockResponse.Handle, blockId); socket.Send(commitBlockRequest.Span); var commitBlockResponse = new CommitBlockResponse(new byte[CommitBlockResponse.SizeInBytes]); socket.Receive(commitBlockResponse.Span); Assert.Equal(CommitBlockStatus.Success, commitBlockResponse.Status); // Get block info var getBlockInfoRequest = GetBlockInfoRequest.From( RequestId.MinRequestId, ClientId.MinClientId, openBlockResponse.Handle); socket.Send(getBlockInfoRequest.Span); var getBlockInfoResponse = new GetBlockInfoResponse(new byte[GetBlockInfoResponse.SizeInBytes]); socket.Receive(getBlockInfoResponse.Span); Assert.True(getBlockInfoResponse.CommittedBlockId.Equals(blockId)); } finally { socket.Close(); instance.Stop(); } }
internal static extern ReturnCode terab_utxo_open_block( SafeConnectionHandle connection, ref CommittedBlockId parentId, out BlockHandle handle, ref UncommittedBlockId ucid);
internal static extern ReturnCode terab_utxo_commit_block( SafeConnectionHandle connection, BlockHandle handle, ref CommittedBlockId blockId);
internal static extern ReturnCode terab_utxo_get_committed_block( SafeConnectionHandle connection, ref CommittedBlockId blockId, out BlockHandle handle);
/// <summary> /// Allocate an array. Intended for testing purposes only. /// </summary> internal static GetBlockHandleRequest From(RequestId requestId, ClientId clientId, CommittedBlockId blockId) { var request = new GetBlockHandleRequest { _buffer = new Span <byte>(new byte[Header.SizeInBytes]) }; request.MessageHeader.MessageSizeInBytes = Header.SizeInBytes; request.MessageHeader.RequestId = requestId; request.MessageHeader.ClientId = clientId; request.MessageHeader.MessageKind = MessageKind.GetBlockHandle; request.AsHeader.CommittedBlockId = blockId; request.AsHeader.IsCommitted = true; return(request); }
public CommittedBlock(CommittedBlockId blockId, BlockAlias alias, BlockAlias parent) { BlockId = blockId; Alias = alias; Parent = parent; }