예제 #1
0
        public void TestCommitBlock()
        {
            var(_, inbox, outbox, chainController, c5, _) = TestOpenBlock();

            // C(0) -> C(1) -> C(2)   -> C(3) -> C(4)
            //             |                 \-> C(4-1)
            //             |                 \-> U(4-2)
            //             \-> C(2-1) -> C(3-1)

            var request = CommitBlockRequest.From(
                _r1, c5, _4_2.ConvertToBlockHandle(c5.Mask), GetMockBlockId(42));

            inbox.TryWrite(request.Span);

            chainController.HandleRequest();

            outbox.Next();
            var result = new CommitBlockResponse(outbox.Peek().Span);

            Assert.Equal(MessageKind.CommitBlockResponse, result.MessageHeader.MessageKind);

            Assert.Equal(_r1, result.MessageHeader.RequestId);
            Assert.Equal(c5, result.MessageHeader.ClientId);

            // TODO: [vermorel] persistence unit tests should be isolated
            //var persister = new BlockchainPersister(TerabConfiguration.CommittedBlocksPersistencePath,
            //    TerabConfiguration.UncommittedBlocksPersistencePath);
            //var newChain = persister.ReadBlockchain();
            //Assert.True(chain.GetLastCommitted().BlockId.Equals(newChain.GetLastCommitted().BlockId));
        }
예제 #2
0
        /// <summary>
        /// Allocate an array. Intended for testing purposes only.
        /// </summary>
        internal static ProduceCoinRequest From(
            RequestId requestId,
            ClientId clientId,
            Outpoint outpoint,
            OutpointFlags flags,
            BlockAlias context,
            ulong satoshis,
            uint nLockTime,
            Span <byte> script,
            BlockHandleMask mask)
        {
            var request = new ProduceCoinRequest
            {
                _buffer = new Span <byte>(new byte[Header.SizeInBytes + script.Length])
            };

            request.MessageHeader.MessageSizeInBytes = Header.SizeInBytes + script.Length;
            request.MessageHeader.RequestId          = requestId;
            request.MessageHeader.ClientId           = clientId;
            request.MessageHeader.MessageKind        = MessageKind.ProduceCoin;

            request.AsHeader.Outpoint  = outpoint;
            request.AsHeader.Flags     = flags;
            request.AsHeader.Context   = context.ConvertToBlockHandle(mask);
            request.AsHeader.Satoshis  = satoshis;
            request.AsHeader.NLockTime = nLockTime;

            script.CopyTo(request._buffer.Slice(Header.SizeInBytes));

            return(request);
        }
예제 #3
0
        public GetCoinResponse(
            RequestId requestId,
            ClientId clientId,
            GetCoinStatus status,
            ref Outpoint outpoint,
            OutpointFlags flags,
            BlockAlias context,
            BlockAlias production,
            BlockAlias consumption,
            ulong satoshis,
            uint nLockTime,
            Span <byte> script,
            BlockHandleMask mask,
            SpanPool <byte> pool)
        {
            var messageSizeInBytes = Header.SizeInBytes + script.Length;

            _buffer = pool.GetSpan(messageSizeInBytes);

            AsHeader.ResponseHeader.MessageSizeInBytes = messageSizeInBytes;
            AsHeader.ResponseHeader.RequestId          = requestId;
            AsHeader.ResponseHeader.ClientId           = clientId;
            AsHeader.ResponseHeader.MessageKind        = MessageKind.GetCoinResponse;

            AsHeader.Status      = status;
            AsHeader.Outpoint    = outpoint;
            AsHeader.Flags       = flags;
            AsHeader.Context     = context.ConvertToBlockHandle(mask);
            AsHeader.Production  = production.ConvertToBlockHandle(mask);
            AsHeader.Consumption = consumption.ConvertToBlockHandle(mask);
            AsHeader.Satoshis    = satoshis;
            AsHeader.NLockTime   = nLockTime;

            script.CopyTo(_buffer.Slice(Header.SizeInBytes));
        }
예제 #4
0
        public void AliasHandleRoundTrip()
        {
            var rand = new Random(42);

            for (var i = 0; i < 70000; i++)
            {
                for (var j = 0; j < 64; j++)
                {
                    var alias = new BlockAlias(i, j);

                    Assert.True(alias.IsDefined);
                    Assert.Equal(i, alias.BlockHeight);
                    Assert.Equal(j, alias.SubIndex);

                    var mask = new ClientId((uint)rand.Next()).Mask;

                    var handle = alias.ConvertToBlockHandle(mask);

                    Assert.True(handle.IsDefined);

                    var aliasBis = handle.ConvertToBlockAlias(mask);

                    Assert.Equal(alias, aliasBis);
                }
            }
        }
예제 #5
0
 /// <summary>
 /// Allocate an array. Intended for testing purposes only.
 /// </summary>
 internal static ConsumeCoinRequest From(RequestId requestId,
                                         ref Outpoint outpoint,
                                         BlockAlias context,
                                         BlockHandleMask mask)
 {
     return(new ConsumeCoinRequest(requestId, ref outpoint,
                                   context.ConvertToBlockHandle(mask), new SpanPool <byte>(Header.SizeInBytes)));
 }
예제 #6
0
        public void ConvertToBlockAlias()
        {
            var alias           = new BlockAlias(100, 1);
            var handle          = alias.ConvertToBlockHandle(new BlockHandleMask(0x5678abcd));
            var aliasFromHandle = handle.ConvertToBlockAlias(new BlockHandleMask(0x5678abcd));

            Assert.Equal(alias, aliasFromHandle);
        }
예제 #7
0
        public GetBlockHandleResponse(
            ref MessageHeader requestHeader, BlockHandleMask mask, BlockAlias alias, SpanPool <byte> pool)
        {
            _buffer = pool.GetSpan(Header.SizeInBytes);

            AsHeader.ResponseHeader = requestHeader;

            AsHeader.ResponseHeader.MessageKind        = MessageKind.BlockHandleResponse;
            AsHeader.ResponseHeader.MessageSizeInBytes = Header.SizeInBytes;

            AsHeader.Status = GetBlockHandleStatus.Success;
            AsHeader.Handle = alias.ConvertToBlockHandle(mask);
        }
예제 #8
0
        public OpenBlockResponse(
            ref MessageHeader requestHeader, BlockHandleMask mask, BlockAlias alias, UncommittedBlockId uncommittedBlockId, SpanPool <byte> pool)
        {
            _buffer = pool.GetSpan(Header.SizeInBytes);

            AsHeader.ResponseHeader = requestHeader;

            AsHeader.ResponseHeader.MessageKind        = MessageKind.OpenBlockResponse;
            AsHeader.ResponseHeader.MessageSizeInBytes = Header.SizeInBytes;

            AsHeader.Status             = OpenBlockStatus.Success;
            AsHeader.Handle             = alias.ConvertToBlockHandle(mask);
            AsHeader.UncommittedBlockId = uncommittedBlockId;
        }
예제 #9
0
        /// <summary>
        /// Allocate an array. Intended for testing purposes only.
        /// </summary>
        internal static GetCoinRequest From(
            RequestId requestId,
            ClientId clientId,
            Outpoint outpoint,
            BlockAlias context,
            BlockHandleMask mask)
        {
            var request = new GetCoinRequest {
                _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.GetCoin;

            request.AsHeader.Outpoint = outpoint;
            request.AsHeader.Context  = context.ConvertToBlockHandle(mask);

            return(request);
        }
예제 #10
0
        public GetBlockInfoResponse(
            ref MessageHeader requestHeader,
            UncommittedBlockId uncommittedBlockId,
            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.UncommittedBlockId = uncommittedBlockId;
            AsHeader.Handle             = alias.ConvertToBlockHandle(mask);
            AsHeader.Parent             = parent.ConvertToBlockHandle(mask);
            AsHeader.BlockHeight        = blockHeight;
            AsHeader.IsCommitted        = false;
        }
예제 #11
0
        public void TestGetCommittedBlockInfo()
        {
            var(_, inbox, outbox, chainController, c5) = Setup();

            var request = GetBlockInfoRequest.From(_r1, c5, _1.ConvertToBlockHandle(c5.Mask));

            inbox.TryWrite(request.Span);

            chainController.HandleRequest();

            var response = new GetBlockInfoResponse(outbox.Peek().Span);

            Assert.Equal(MessageKind.BlockInfoResponse, response.MessageHeader.MessageKind);
            Assert.True(response.IsCommitted);

            Assert.Equal(_r1, response.MessageHeader.RequestId);
            Assert.Equal(c5, response.MessageHeader.ClientId);

            Assert.Equal(_id_1, response.CommittedBlockId);
            Assert.Equal(_1, response.Handle.ConvertToBlockAlias(c5.Mask));
            Assert.Equal(new BlockAlias(0, 0), response.Parent.ConvertToBlockAlias(c5.Mask));
            Assert.Equal(1, response.BlockHeight);
        }