Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Constructor
 /// </summary>
 public SpanPool()
 {
     next  = null;
     items = Helper.CreateArray(Recast.RC_SPANS_PER_POOL, () =>
     {
         return(new Span());
     });
 }
Ejemplo n.º 3
0
        public void GetSpans()
        {
            var pool       = new SpanPool <RequestId>(20);
            var firstPart  = pool.GetSpan(3);
            var secondPart = pool.GetSpan(17);

            firstPart[0] = new RequestId();
            firstPart[2] = new RequestId();

            Assert.Equal(default, secondPart[0]);
Ejemplo n.º 4
0
        public GetBlockHandleResponse(
            ref MessageHeader requestHeader, GetBlockHandleStatus status, SpanPool <byte> pool)
        {
            _buffer = pool.GetSpan(Header.SizeInBytes);

            AsHeader.ResponseHeader = requestHeader;

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

            AsHeader.Status = status;
            AsHeader.Handle = default;
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
0
        public ProtocolErrorResponse(
            RequestId requestId,
            ClientId clientId,
            ProtocolErrorStatus status,
            SpanPool <byte> pool)
        {
            _buffer = pool.GetSpan(Header.SizeInBytes);

            AsHeader.ResponseHeader.MessageSizeInBytes = Header.SizeInBytes;
            AsHeader.ResponseHeader.RequestId          = requestId;
            AsHeader.ResponseHeader.ClientId           = clientId;
            AsHeader.ResponseHeader.MessageKind        = MessageKind.ProtocolErrorResponse;

            AsHeader.Status = status;
        }
Ejemplo n.º 7
0
        public ConsumeCoinResponse(
            RequestId requestId,
            ClientId clientId,
            ChangeCoinStatus status,
            SpanPool <byte> pool)
        {
            _buffer = pool.GetSpan(Header.SizeInBytes);

            AsHeader.ResponseHeader.MessageSizeInBytes = Header.SizeInBytes;
            AsHeader.ResponseHeader.RequestId          = requestId;
            AsHeader.ResponseHeader.ClientId           = clientId;
            AsHeader.ResponseHeader.MessageKind        = MessageKind.ConsumeCoinResponse;

            AsHeader.Status = status;
        }
Ejemplo n.º 8
0
        /// <summary> Client-side perspective. </summary>
        public GetCoinRequest(
            RequestId requestId,
            ref Outpoint outpoint,
            BlockHandle context,
            SpanPool <byte> pool)
        {
            _buffer = pool.GetSpan(Header.SizeInBytes);
            _mask   = default;

            AsHeader.RequestHeader.MessageSizeInBytes = Header.SizeInBytes;
            AsHeader.RequestHeader.RequestId          = requestId;
            AsHeader.RequestHeader.MessageKind        = MessageKind.GetCoin;

            Outpoint      = outpoint;
            HandleContext = context;
        }
Ejemplo n.º 9
0
        public void WriteCoinCons()
        {
            var sozu = new VolatileCoinStore();

            var inbox      = new BoundedInbox();
            var outbox     = new BoundedInbox();
            var controller = new CoinController(inbox, outbox, sozu, _hash);

            controller.Lineage = new MockLineage();

            var clientId = new ClientId();
            var reqId    = new RequestId(1);

            var coin = GetCoin(_rand);

            sozu.AddProduction(
                _hash.Hash(ref coin.Outpoint),
                ref coin.Outpoint,
                false, coin.Payload,
                new BlockAlias(2),
                null);

            var pool             = new SpanPool <byte>(4096);
            var buffer           = new byte[ConsumeCoinRequest.SizeInBytes];
            var writeCoinRequest = new ConsumeCoinRequest(
                reqId, ref coin.Outpoint, new BlockAlias(2).ConvertToBlockHandle(clientId.Mask), pool);

            inbox.TryWrite(writeCoinRequest.Span);
            controller.HandleRequest();

            var raw = outbox.Peek();

            Assert.Equal(ConsumeCoinResponse.SizeInBytes, raw.Length);
            var response = new ConsumeCoinResponse(raw.Span);

            // verify response contents
            Assert.Equal(reqId, response.MessageHeader.RequestId);
            Assert.Equal(clientId, response.MessageHeader.ClientId);
            Assert.Equal(MessageKind.ConsumeCoinResponse, response.MessageHeader.MessageKind);
            Assert.Equal(ChangeCoinStatus.Success, response.Status);
        }
Ejemplo n.º 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;
        }
Ejemplo n.º 11
0
        /// <summary> Coin production. Client-side perspective. </summary>
        public ProduceCoinRequest(
            RequestId requestId,
            ref Outpoint outpoint,
            OutpointFlags flags,
            BlockHandle context,
            ulong satoshis,
            uint nLockTime,
            int scriptSizeInBytes,
            SpanPool <byte> pool)
        {
            _buffer = pool.GetSpan(Header.SizeInBytes + scriptSizeInBytes);
            _mask   = default;

            AsHeader.RequestHeader.MessageSizeInBytes = Header.SizeInBytes + scriptSizeInBytes;
            AsHeader.RequestHeader.RequestId          = requestId;
            AsHeader.RequestHeader.MessageKind        = MessageKind.ProduceCoin;

            Outpoint      = outpoint;
            HandleContext = context;
            Flags         = flags;
            Satoshis      = satoshis;
            NLockTime     = nLockTime;
        }
Ejemplo n.º 12
0
 public SozuTable(IPackStore store, IOutpointHash hash)
 {
     _store = store;
     _hash  = hash;
     _pool  = new SpanPool <byte>(SpanPoolCapacity);
 }
Ejemplo n.º 13
0
 public VolatileCoinStore()
 {
     _pool  = new SpanPool <byte>(65536);
     _coins = new Dictionary <Outpoint, FatCoin>(new OutpointComparer());
 }
Ejemplo n.º 14
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;
        }
Ejemplo n.º 15
0
        private static void DoBenchmark(IPEndPoint endpoint, ILog log)
        {
            var rand = new Random(); // non-deterministic on purpose

            var genWatch = new Stopwatch();

            genWatch.Start();

            var generator = new CoinGenerator(rand);

            generator.GenerateSketches(CoinIoCount);

            log.Log(LogSeverity.Info,
                    $"{CoinIoCount} coin I/Os generated in " + (genWatch.ElapsedMilliseconds / 1000f) + " seconds");

            var rawSocket = new Socket(endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            rawSocket.Connect(endpoint);
            var socket = new SocketLikeAdapter(rawSocket);

            EnsureGenesisExists(socket);

            var handle = OpenBlock(CommittedBlockId.Genesis, socket, log);

            // Process coins
            var requestPool    = new SpanPool <byte>(1024 * 1024);
            var responseBuffer = new Span <byte>(new byte[4096]);

            var watch        = new Stopwatch();
            var commitWatch  = new Stopwatch();
            var outpointSeed = generator.Random.Next();

            for (var i = 0; i < generator.CoinSketches.Length; i++)
            {
                if (i % EpochSize == 0)
                {
                    watch.Reset();
                    watch.Start();
                }

                var sketch   = generator.CoinSketches[i];
                var outpoint = GetOutpoint(sketch, outpointSeed);

                if (sketch.IsProduction)
                {
                    // intended side effect on 'requestPool'
                    var writeCoinRequest = new ProduceCoinRequest(
                        new RequestId((uint)i),
                        ref outpoint,
                        OutpointFlags.None,
                        handle,
                        satoshis: 123,
                        nLockTime: 42,
                        scriptSizeInBytes: 100,
                        requestPool);

                    var script = writeCoinRequest.Script;
                    script[0] = (byte)i;
                }

                if (sketch.IsRead)
                {
                    // intended side effect on 'requestPool'
                    var readCoinRequest =
                        new GetCoinRequest(new RequestId((uint)i), ref outpoint, handle, requestPool);
                }

                if (sketch.IsConsumption)
                {
                    // intended side effect on 'requestPool'
                    var writeCoinRequest = new ConsumeCoinRequest(
                        new RequestId((uint)i), ref outpoint, handle, requestPool);
                }

                if (i % BatchSize == BatchSize - 1)
                {
                    // send all the requests as a batch
                    socket.Send(requestPool.Allocated());
                    requestPool.Reset();

                    for (var j = 0; j < BatchSize; j++)
                    {
                        socket.Receive(responseBuffer.Slice(0, 4));
                        var responseSize = responseBuffer[0];
                        socket.Receive(responseBuffer.Slice(4, responseSize - 4));
                    }
                }

                if (i % EpochSize == EpochSize - 1)
                {
                    watch.Stop();

                    var nextBlockId = GetBlockId();

                    commitWatch.Reset();
                    commitWatch.Start();
                    CommitBlock(handle, nextBlockId, socket);
                    commitWatch.Stop();

                    handle = OpenBlock(nextBlockId, socket, log);

                    var elapsed = watch.ElapsedMilliseconds / 1000.0; // seconds

                    var iops = (int)(EpochSize / elapsed);

                    log.Log(LogSeverity.Info,
                            $"Epoch {i / EpochSize} at {iops} IOps. Commit in {commitWatch.Elapsed.TotalMilliseconds} ms.");
                }
            }
        }
Ejemplo n.º 16
0
 public VolatileKeyValueStore()
 {
     _map  = new Dictionary <T, byte[]>();
     _pool = new SpanPool <byte>(PoolSizeInBytes);
 }
Ejemplo n.º 17
0
        public OpenBlockResponse(ref MessageHeader requestHeader, OpenBlockStatus status, SpanPool <byte> pool)
        {
            _buffer = pool.GetSpan(Header.SizeInBytes);

            AsHeader.ResponseHeader = requestHeader;

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

            AsHeader.Status             = status;
            AsHeader.Handle             = default;
            AsHeader.UncommittedBlockId = default;
        }