예제 #1
0
        private void CreateAndDistributeCombinedBlock(RegistryFullBlock transactionsFullBlockMostConfident)
        {
            lock (_synchronizationContext)
            {
                SynchronizationRegistryCombinedBlock lastCombinedBlock = (SynchronizationRegistryCombinedBlock)_synchronizationChainDataService.GetAllLastBlocksByType(BlockTypes.Synchronization_RegistryCombinationBlock).Single();
                byte[] prevHash = lastCombinedBlock != null?_defaultTransactionHashCalculation.CalculateHash(lastCombinedBlock.RawData) : new byte[Globals.DEFAULT_HASH_SIZE];

                byte[] fullBlockHash = _defaultTransactionHashCalculation.CalculateHash(transactionsFullBlockMostConfident?.RawData ?? new byte[Globals.DEFAULT_HASH_SIZE]);
                //TODO: For initial POC there will be only one participant at Synchronization Layer, thus combination of FullBlocks won't be implemented fully
                SynchronizationRegistryCombinedBlock synchronizationRegistryCombinedBlock = new SynchronizationRegistryCombinedBlock
                {
                    SyncBlockHeight = _synchronizationContext.LastBlockDescriptor?.BlockHeight ?? 0,
                    PowHash         = _powCalculation.CalculateHash(_synchronizationContext.LastBlockDescriptor?.Hash ?? new byte[Globals.DEFAULT_HASH_SIZE]),
                    BlockHeight     = ++_synchronizationContext.LastRegistrationCombinedBlockHeight,
                    HashPrev        = prevHash,
                    ReportedTime    = DateTime.Now,
                    BlockHashes     = new byte[][] { fullBlockHash }
                };

                ISerializer combinedBlockSerializer = _signatureSupportSerializersFactory.Create(synchronizationRegistryCombinedBlock);
                combinedBlockSerializer.FillBodyAndRowBytes();

                IEnumerable <IKey> storageLayerKeys = _nodesResolutionService.GetStorageNodeKeys(combinedBlockSerializer);
                _communicationService.PostMessage(storageLayerKeys, combinedBlockSerializer);

                _synchronizationChainDataService.Add(synchronizationRegistryCombinedBlock);
            }
        }
예제 #2
0
        private void RecalculateProductionTimer()
        {
            _registryGroupState.Round = 0;

            if (_syncCycleDescriptor != null)
            {
                _syncCycleDescriptor.CancellationTokenSource.Cancel();
                _syncCycleDescriptor.CancellationRequested = true;
            }

            _syncCycleDescriptor = new SyncCycleDescriptor(_synchronizationContext.LastBlockDescriptor);

            PeriodicTaskFactory.Start(o =>
            {
                SyncCycleDescriptor syncCycleDescriptor = (SyncCycleDescriptor)o;
                SortedList <ushort, RegistryRegisterBlock> transactionStateWitnesses           = _registryMemPool.DequeueStateWitnessBulk();
                SortedList <ushort, RegistryRegisterUtxoConfidential> transactionUtxoWitnesses = _registryMemPool.DequeueUtxoWitnessBulk();

                RegistryFullBlock registryFullBlock   = ProduceTransactionsFullBlock(transactionStateWitnesses, transactionUtxoWitnesses, syncCycleDescriptor.SynchronizationDescriptor, syncCycleDescriptor.Round);
                RegistryShortBlock registryShortBlock = ProduceTransactionsShortBlock(registryFullBlock);

                SendTransactionsBlocks(registryFullBlock, registryShortBlock);

                syncCycleDescriptor.Round++;

                if (syncCycleDescriptor.CancellationRequested)
                {
                    syncCycleDescriptor.CancellationTokenSource.Cancel();
                }
            }, _syncCycleDescriptor, _registrationPeriodMsec * _registryConfiguration.TotalNodes, _registryConfiguration.Position * _registrationPeriodMsec, cancelToken: _syncCycleDescriptor.CancellationTokenSource.Token, periodicTaskCreationOptions: TaskCreationOptions.LongRunning);
        }
예제 #3
0
        private async Task UpdateTransactionsByFullRegistryBlock(SynchronizationRegistryCombinedBlock combinedBlock, byte[] fullRegistryBlockHash)
        {
            TransactionInfo registryFullBlockInfo = _syncLayerSyncManagerClient.GetFullRegistryBlock(new HeightHashRequest {
                Height = combinedBlock.SyncBlockHeight, Hash = ByteString.CopyFrom(fullRegistryBlockHash)
            });

            if (registryFullBlockInfo.IsEmpty)
            {
                return;
            }

            IBlockParsersRepository registryFullBlockParserRepo = _blockParsersRepositoriesRepository.GetBlockParsersRepository((PacketType)registryFullBlockInfo.PacketType);
            IBlockParser            registryFullBlockParser     = registryFullBlockParserRepo.GetInstance((ushort)registryFullBlockInfo.BlockType);

            RegistryFullBlock registryFullBlock = (RegistryFullBlock)registryFullBlockParser.Parse(registryFullBlockInfo.Content.ToByteArray());

            AsyncServerStreamingCall <TransactionInfo> asyncTransactionInfosStream = _storageLayerSyncManagerClient.GetTransactionInfos(new FullBlockRequest {
                SyncBlockHeight = registryFullBlock.SyncBlockHeight, Round = registryFullBlock.BlockHeight
            });

            while (await asyncTransactionInfosStream.ResponseStream.MoveNext(_cancellationToken))
            {
                TransactionInfo         transactionInfo            = asyncTransactionInfosStream.ResponseStream.Current;
                IBlockParsersRepository transactionBlockParserRepo = _blockParsersRepositoriesRepository.GetBlockParsersRepository((PacketType)transactionInfo.PacketType);
                IBlockParser            transactionBlockParser     = transactionBlockParserRepo.GetInstance((ushort)transactionInfo.BlockType);
                BlockBase transactionBlockBase = transactionBlockParser.Parse(transactionInfo.Content.ToByteArray());

                UpdateTransaction(transactionBlockBase, combinedBlock.BlockHeight);
            }
        }
예제 #4
0
        public override async Task GetCombinedRegistryBlocksInfoSinceHeight(ByHeightRequest request, IServerStreamWriter <CombinedRegistryBlockInfo> responseStream, ServerCallContext context)
        {
            IEnumerable <BlockBase> blocks = _syncChainDataService.GetAll(new BlockTypeLowHeightKey(BlockTypes.Synchronization_RegistryCombinationBlock, request.Height));

            foreach (BlockBase blockBase in blocks)
            {
                SynchronizationRegistryCombinedBlock registryCombinedBlock     = blockBase as SynchronizationRegistryCombinedBlock;
                CombinedRegistryBlockInfo            combinedRegistryBlockInfo = new CombinedRegistryBlockInfo
                {
                    SyncBlockHeight             = registryCombinedBlock.SyncBlockHeight,
                    Height                      = registryCombinedBlock.BlockHeight,
                    CombinedRegistryBlocksCount = (uint)registryCombinedBlock.BlockHashes.Length,
                };

                foreach (byte[] hash in registryCombinedBlock.BlockHashes)
                {
                    RegistryFullBlock registryFullBlock = (RegistryFullBlock)_registryChainDataService.Get(new SyncHashKey(registryCombinedBlock.SyncBlockHeight, hash));

                    if (registryFullBlock != null)
                    {
                        combinedRegistryBlockInfo.BlockDescriptors.Add(
                            new FullBlockDescriptor
                        {
                            SyncBlockHeight   = registryCombinedBlock.SyncBlockHeight,
                            Round             = registryFullBlock.BlockHeight,
                            TransactionsCount = (uint)registryFullBlock.TransactionHeaders.Count,
                            BlockHash         = ByteString.CopyFrom(hash)
                        });
                    }
                }

                await responseStream.WriteAsync(combinedRegistryBlockInfo);
            }
        }
예제 #5
0
        public void AddFullBlock(RegistryFullBlock registryFullBlock)
        {
            IKey key = _identityKeyProvider.GetKey(registryFullBlock.ShortBlockHash);

            if (!CandidateBlocks.ContainsKey(key))
            {
                CandidateBlocks.Add(key, registryFullBlock);
                CandidateVotes.Add(key, 0);
            }
        }
예제 #6
0
        private void DistributeAndSaveFullBlock(RegistryFullBlock transactionsFullBlockMostConfident)
        {
            IRawPacketProvider fullBlockSerializer = _rawPacketProvidersFactory.Create(transactionsFullBlockMostConfident);

            IEnumerable <IKey> storageLayerKeys = _nodesResolutionService.GetStorageNodeKeys(fullBlockSerializer);

            _communicationService.PostMessage(storageLayerKeys, fullBlockSerializer);

            _registryChainDataService.Add(transactionsFullBlockMostConfident);
        }
예제 #7
0
        private void DoVotingCycles(CancellationToken votingCycleCt)
        {
            Thread.Sleep(3000); // Shift voting cycles
            ulong round = 1;

            ulong syncHeight = _synchronizationContext.LastBlockDescriptor.BlockHeight;

            while (!_cancellationToken.IsCancellationRequested && !votingCycleCt.IsCancellationRequested)
            {
                // 1. check participation as leader
                try
                {
                    VerifyRoundSwitchExist(round);

                    _logger.Debug($"Voting - waiting for any block of current round {round}");
                    _roundSwitches[round].Wait(votingCycleCt);
                    _logger.Debug($"Voting - block of current round {round} obtained. Wait for another 3 seconds");

                    if (votingCycleCt.IsCancellationRequested || _cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    Thread.Sleep(3000);

                    RegistryFullBlock transactionsFullBlockMostConfident = null;

                    lock (_syncRegistryMemPool)
                    {
                        transactionsFullBlockMostConfident = _syncRegistryMemPool.GetMostConfidentFullBlock(round);
                        _syncRegistryMemPool.ResetRound(round++);
                        VerifyRoundSwitchExist(round);
                        _roundSwitches[round].Reset();
                    }

                    if (transactionsFullBlockMostConfident != null)
                    {
                        CreateAndDistributeConfirmationBlock(transactionsFullBlockMostConfident);

                        DistributeAndSaveFullBlock(transactionsFullBlockMostConfident);
                    }

                    CreateAndDistributeCombinedBlock(transactionsFullBlockMostConfident);
                }
                catch (OperationCanceledException)
                {
                    _logger.Info($"Round {round} was canceled");
                }
                catch (Exception ex)
                {
                    _logger.Error("Failed to complete Round due to error", ex);
                }
            }
            _syncRegistryMemPool.SetLastCompletedSyncHeight(syncHeight);
        }
예제 #8
0
        public override Task GetTransactionInfos(FullBlockRequest request, IServerStreamWriter <TransactionInfo> responseStream, ServerCallContext context)
        {
            return(Task.Run(async() =>
            {
                RegistryFullBlock registryFullBlock = (RegistryFullBlock)_registryChainDataService.Get(new DoubleHeightKey(request.SyncBlockHeight, request.Round));
                foreach (RegistryRegisterBlock transactionWitness in registryFullBlock.StateWitnesses)
                {
                    try
                    {
                        PacketBase blockBase = _transactionalDataService.Get(new SyncHashKey(transactionWitness.SyncBlockHeight, transactionWitness.ReferencedBodyHash));

                        if (blockBase != null)
                        {
                            await responseStream.WriteAsync(
                                new TransactionInfo
                            {
                                SyncBlockHeight = transactionWitness.SyncBlockHeight,
                                PacketType = (uint)transactionWitness.ReferencedPacketType,
                                BlockType = transactionWitness.ReferencedBlockType,
                                Content = ByteString.CopyFrom(blockBase.RawData.ToArray())
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"Failed to retrieve block for SyncBlockHeight {request.SyncBlockHeight} and Round {request.Round}", ex);
                    }
                }

                foreach (RegistryRegisterUtxoConfidential transactionWitness in registryFullBlock.UtxoWitnesses)
                {
                    try
                    {
                        PacketBase blockBase = _utxoConfidentialDataService.Get(new SyncHashKey(transactionWitness.SyncBlockHeight, transactionWitness.ReferencedBodyHash));

                        if (blockBase != null)
                        {
                            await responseStream.WriteAsync(
                                new TransactionInfo
                            {
                                SyncBlockHeight = transactionWitness.SyncBlockHeight,
                                PacketType = (uint)transactionWitness.ReferencedPacketType,
                                BlockType = transactionWitness.ReferencedBlockType,
                                Content = ByteString.CopyFrom(blockBase.RawData.ToArray())
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"Failed to retrieve block for SyncBlockHeight {request.SyncBlockHeight} and Round {request.Round}", ex);
                    }
                }
            }, context.CancellationToken));
        }
예제 #9
0
        public override PacketBase Translate(TransactionsRegistryBlock obj)
        {
            if (obj == null)
            {
                return(null);
            }

            IBlockParser blockParser = _blockParsersRepository.GetInstance(BlockTypes.Registry_FullBlock);

            RegistryFullBlock registryFullBlock = (RegistryFullBlock)blockParser.Parse(obj.Content);

            return(registryFullBlock);
        }
예제 #10
0
        private void CreateAndDistributeConfirmationBlock(RegistryFullBlock transactionsFullBlockMostConfident)
        {
            RegistryConfirmationBlock registryConfirmationBlock = new RegistryConfirmationBlock
            {
                SyncBlockHeight     = transactionsFullBlockMostConfident.SyncBlockHeight,
                Nonce               = transactionsFullBlockMostConfident.Nonce,
                PowHash             = transactionsFullBlockMostConfident.PowHash,
                BlockHeight         = transactionsFullBlockMostConfident.BlockHeight,
                ReferencedBlockHash = transactionsFullBlockMostConfident.ShortBlockHash
            };

            ShardDescriptor shardDescriptor = _syncShardsManager.GetShardDescriptorByRound((int)transactionsFullBlockMostConfident.BlockHeight);
            ISerializer     registryConfirmationBlockSerializer = _signatureSupportSerializersFactory.Create(registryConfirmationBlock);

            _communicationService.PostMessage(_syncRegistryNeighborhoodState.GetAllNeighbors(), registryConfirmationBlockSerializer);
        }
예제 #11
0
        private void SendTransactionsBlocks(Tuple <RegistryFullBlock, RegistryShortBlock> tuple)
        {
            RegistryFullBlock  transactionsFullBlock  = tuple.Item1;
            RegistryShortBlock transactionsShortBlock = tuple.Item2;

            ISerializer fullBlockSerializer  = _signatureSupportSerializersFactory.Create(transactionsFullBlock);
            ISerializer shortBlockSerializer = _signatureSupportSerializersFactory.Create(transactionsShortBlock);

            shortBlockSerializer.FillBodyAndRowBytes();
            transactionsFullBlock.ShortBlockHash = _hashCalculation.CalculateHash(transactionsShortBlock.RawData);

            _logger.Debug($"Sending FullBlock with {transactionsFullBlock.TransactionHeaders.Count} transactions and ShortBlock with {transactionsShortBlock.TransactionHeaderHashes.Count} hashes at round {transactionsFullBlock.BlockHeight}");

            _tcpCommunicationService.PostMessage(_registryGroupState.SyncLayerNode, fullBlockSerializer);
            _tcpCommunicationService.PostMessage(_registryGroupState.GetAllNeighbors(), shortBlockSerializer);
        }
예제 #12
0
        private RegistryShortBlock ProduceTransactionsShortBlock(RegistryFullBlock transactionsFullBlock)
        {
            RegistryShortBlock transactionsShortBlock = new RegistryShortBlock
            {
                SyncBlockHeight  = transactionsFullBlock.SyncBlockHeight,
                Nonce            = transactionsFullBlock.Nonce,
                PowHash          = transactionsFullBlock.PowHash,
                BlockHeight      = transactionsFullBlock.BlockHeight,
                WitnessStateKeys = transactionsFullBlock.StateWitnesses.Select(w => new WitnessStateKey {
                    PublicKey = w.Signer, Height = w.BlockHeight
                }).ToArray(),
                WitnessUtxoKeys = transactionsFullBlock.UtxoWitnesses.Select(w => new WitnessUtxoKey {
                    KeyImage = w.KeyImage
                }).ToArray()
            };

            return(transactionsShortBlock);
        }
예제 #13
0
        protected override Memory <byte> ParseSigned(ushort version, Memory <byte> spanBody, out SignedPacketBase syncedBlockBase)
        {
            if (version == 1)
            {
                int readBytes = 0;

                RegistryFullBlock transactionsFullBlock = new RegistryFullBlock();
                ushort            stateWitnessesCount   = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span.Slice(readBytes));
                readBytes += sizeof(ushort);

                ushort utxoWitnessesCount = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span.Slice(readBytes));
                readBytes += sizeof(ushort);

                transactionsFullBlock.StateWitnesses = new RegistryRegisterBlock[stateWitnessesCount];
                transactionsFullBlock.UtxoWitnesses  = new RegistryRegisterUtxoConfidential[utxoWitnessesCount];

                for (int i = 0; i < stateWitnessesCount; i++)
                {
                    RegistryRegisterBlock block = (RegistryRegisterBlock)_registryRegisterBlockParser.Parse(spanBody.Slice(readBytes));

                    readBytes += block?.RawData.Length ?? 0;

                    transactionsFullBlock.StateWitnesses[i] = block;
                }

                for (int i = 0; i < utxoWitnessesCount; i++)
                {
                    RegistryRegisterUtxoConfidential block = (RegistryRegisterUtxoConfidential)_registryRegisterUtxoConfidentialBlockParser.Parse(spanBody.Slice(readBytes));

                    readBytes += block?.RawData.Length ?? 0;

                    transactionsFullBlock.UtxoWitnesses[i] = block;
                }

                transactionsFullBlock.ShortBlockHash = spanBody.Slice(readBytes, Globals.DEFAULT_HASH_SIZE).ToArray();
                readBytes += Globals.DEFAULT_HASH_SIZE;

                syncedBlockBase = transactionsFullBlock;

                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #14
0
        private void SendTransactionsBlocks(RegistryFullBlock transactionsFullBlock, RegistryShortBlock transactionsShortBlock)
        {
            ISerializer fullBlockSerializer  = _serializersFactory.Create(transactionsFullBlock);
            ISerializer shortBlockSerializer = _serializersFactory.Create(transactionsShortBlock);

            shortBlockSerializer.SerializeBody();
            _nodeContext.SigningService.Sign(transactionsShortBlock);

            shortBlockSerializer.SerializeFully();
            transactionsFullBlock.ShortBlockHash = _hashCalculation.CalculateHash(transactionsShortBlock.RawData);

            fullBlockSerializer.SerializeBody();
            _nodeContext.SigningService.Sign(transactionsFullBlock);

            _logger.Debug($"Sending FullBlock with {transactionsFullBlock.StateWitnesses.Length + transactionsFullBlock.UtxoWitnesses.Length} transactions and ShortBlock with {transactionsShortBlock.WitnessStateKeys.Length + transactionsShortBlock.WitnessUtxoKeys.Length} keys at round {transactionsFullBlock.BlockHeight}");

            _tcpCommunicationService.PostMessage(_registryGroupState.SyncLayerNode, fullBlockSerializer);
            _tcpCommunicationService.PostMessage(_registryGroupState.GetAllNeighbors(), shortBlockSerializer);
        }
예제 #15
0
        private RegistryFullBlock ProduceTransactionsFullBlock(SortedList <ushort, RegistryRegisterBlock> transactionStateWitnesses, SortedList <ushort, RegistryRegisterUtxoConfidential> transactionUtxoWitnesses, SynchronizationDescriptor synchronizationDescriptor, int round)
        {
            ulong syncBlockHeight = synchronizationDescriptor?.BlockHeight ?? 0;

            byte[] hash = synchronizationDescriptor?.Hash ?? new byte[Globals.DEFAULT_HASH_SIZE];
            byte[] pow  = _powCalculation.CalculateHash(hash);

            _logger.Debug($"ProduceTransactionsFullBlock synchronizationDescriptor[{syncBlockHeight}].Hash = {hash.ToHexString()}; POW = {pow.ToHexString()}");

            RegistryFullBlock transactionsFullBlock = new RegistryFullBlock
            {
                SyncBlockHeight = syncBlockHeight,
                PowHash         = pow,
                BlockHeight     = (ulong)(round * _registryConfiguration.TotalNodes + _registryConfiguration.Position + 1),
                StateWitnesses  = transactionStateWitnesses.Select(t => t.Value).ToArray(),
                UtxoWitnesses   = transactionUtxoWitnesses.Select(t => t.Value).ToArray()
            };

            return(transactionsFullBlock);
        }
예제 #16
0
        protected override Memory <byte> ParseSynced(ushort version, Memory <byte> spanBody, out SyncedBlockBase syncedBlockBase)
        {
            if (version == 1)
            {
                RegistryFullBlock transactionsFullBlock = new RegistryFullBlock();
                ushort            itemsCount            = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span);

                transactionsFullBlock.TransactionHeaders = new SortedList <ushort, ITransactionRegistryBlock>(itemsCount);
                int readBytes = 2;

                if (itemsCount > 0)
                {
                    for (int i = 0; i < itemsCount; i++)
                    {
                        ushort order = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span.Slice(readBytes));
                        readBytes += 2;

                        BlockParserBase.GetPacketAndBlockTypes(spanBody.Slice(readBytes), out PacketType packetType, out ushort blockType);
                        IBlockParsersRepository blockParsersRepository = _blockParsersRepositoriesRepository.Value.GetBlockParsersRepository(packetType);
                        IBlockParser            blockParser            = blockParsersRepository.GetInstance(blockType);
                        BlockBase block = blockParser.Parse(spanBody.Slice(readBytes));

                        readBytes += block?.RawData.Length ?? 0;

                        if (block is ITransactionRegistryBlock transactionRegistryBlock)
                        {
                            transactionsFullBlock.TransactionHeaders.Add(order, transactionRegistryBlock);
                        }
                    }
                }

                transactionsFullBlock.ShortBlockHash = spanBody.Slice(readBytes, Globals.DEFAULT_HASH_SIZE).ToArray();
                readBytes += Globals.DEFAULT_HASH_SIZE;

                syncedBlockBase = transactionsFullBlock;

                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #17
0
        public override Task <TransactionInfo> GetFullRegistryBlock(HeightHashRequest request, ServerCallContext context)
        {
            RegistryFullBlock block = (RegistryFullBlock)_registryChainDataService.Get(new SyncHashKey(request.Height, request.Hash.ToByteArray()));

            if (block != null)
            {
                TransactionInfo transactionInfo = new TransactionInfo
                {
                    BlockType       = block.BlockType,
                    PacketType      = (uint)block.PacketType,
                    SyncBlockHeight = block.SyncBlockHeight,
                    Content         = ByteString.CopyFrom(block.RawData.ToArray())
                };

                return(Task.FromResult(transactionInfo));
            }

            return(Task.FromResult(new TransactionInfo {
                IsEmpty = true
            }));
        }
예제 #18
0
        public void AddCandidateBlock(RegistryFullBlock transactionsFullBlock)
        {
            if (transactionsFullBlock == null)
            {
                throw new ArgumentNullException(nameof(transactionsFullBlock));
            }

            _logger.Debug($"Adding candidate block of round {transactionsFullBlock.BlockHeight} with {transactionsFullBlock.StateWitnesses.Length + transactionsFullBlock.UtxoWitnesses.Length} transactions");

            byte[] hash = _defaultTransactionHashCalculation.CalculateHash(transactionsFullBlock.RawData);

            if (_registryCombinedBlocks.Any(b => b.BlockHashes.Any(h => h.Equals32(hash))))
            {
                return;
            }

            lock (_registryBlocks)
            {
                _registryBlocks.Add(transactionsFullBlock);
            }
        }
예제 #19
0
        public override Task GetTransactionRegistryBlockInfos(FullBlockRequest request, IServerStreamWriter <TransactionRegistryBlockInfo> responseStream, ServerCallContext context)
        {
            return(Task.Run(async() =>
            {
                RegistryFullBlock registryFullBlock = (RegistryFullBlock)_registryChainDataService.Get(new DoubleHeightKey(request.SyncBlockHeight, request.Round));

                foreach (RegistryRegisterBlock transactionWitness in registryFullBlock.StateWitnesses)
                {
                    TransactionRegistryBlockInfo blockInfo = new TransactionRegistryBlockInfo();

                    blockInfo.AccountedHeader = new AccountedTransactionHeaderDescriptor
                    {
                        SyncBlockHeight = transactionWitness.SyncBlockHeight,
                        ReferencedBlockType = transactionWitness.ReferencedBlockType,
                        ReferencedPacketType = (uint)transactionWitness.ReferencedPacketType,
                        ReferencedTarget = ByteString.CopyFrom(transactionWitness.ReferencedTarget),
                        ReferencedHeight = transactionWitness.BlockHeight
                    };

                    await responseStream.WriteAsync(blockInfo);
                }

                foreach (RegistryRegisterUtxoConfidential transactionWitness in registryFullBlock.UtxoWitnesses)
                {
                    TransactionRegistryBlockInfo blockInfo = new TransactionRegistryBlockInfo();

                    blockInfo.UtxoHeader = new UtxoTransactionHeaderDescriptor
                    {
                        SyncBlockHeight = transactionWitness.SyncBlockHeight,
                        ReferencedBlockType = transactionWitness.ReferencedBlockType,
                        ReferencedPacketType = (uint)transactionWitness.ReferencedPacketType,
                        ReferencedTarget = ByteString.CopyFrom(transactionWitness.DestinationKey),
                        ReferencedTransactionKey = ByteString.CopyFrom(transactionWitness.TransactionPublicKey),
                        KeyImage = ByteString.CopyFrom(transactionWitness.KeyImage.Value.ToArray())
                    };

                    await responseStream.WriteAsync(blockInfo);
                }
            }));
        }
예제 #20
0
        public RegistryFullBlock GetMostConfidentFullBlock(ulong round)
        {
            if (!_roundDescriptors.ContainsKey(round))
            {
                _logger.Error($"No RoundDescriptor with index {round}");
                return(null);
            }

            RoundDescriptor roundDescriptor = _roundDescriptors[round];

            foreach (var confidenceBlock in roundDescriptor.VotingBlocks)
            {
                IKey key = _transactionHashKey.GetKey(confidenceBlock.ReferencedBlockHash);
                if (roundDescriptor.CandidateVotes.ContainsKey(key))
                {
                    long sum = GetConfidence(confidenceBlock.BitMask);
                    roundDescriptor.CandidateVotes[key] += (int)sum;
                }
            }

            RegistryFullBlock transactionsFullBlockMostConfident = roundDescriptor.CandidateBlocks?.Values?.FirstOrDefault();

            //if (roundDescriptor.CandidateVotes?.Count > 0 )
            //{
            //    IKey mostConfidentKey = roundDescriptor.CandidateVotes.OrderByDescending(kv => (double)kv.Value / (double)roundDescriptor.CandidateBlocks[kv.Key].TransactionHeaders.Count).First().Key;
            //    transactionsFullBlockMostConfident = roundDescriptor.CandidateBlocks[mostConfidentKey];
            //}

            if (transactionsFullBlockMostConfident == null)
            {
                _logger.Error($"No candidates found for round {round}");
            }
            else
            {
                _logger.Debug($"Most confident RegistryFullBlock contains {transactionsFullBlockMostConfident.TransactionHeaders.Count} transactions");
            }

            return(transactionsFullBlockMostConfident);
        }
예제 #21
0
        private RegistryFullBlock ProduceTransactionsFullBlock(SortedList <ushort, ITransactionRegistryBlock> transactionRegisterBlocks)
        {
            SynchronizationDescriptor synchronizationDescriptor = _synchronizationContext.LastBlockDescriptor;
            ulong syncBlockHeight = synchronizationDescriptor?.BlockHeight ?? 0;

            byte[] hash = synchronizationDescriptor?.Hash ?? new byte[Globals.DEFAULT_HASH_SIZE];
            byte[] pow  = _powCalculation.CalculateHash(hash);

            _logger.Debug($"ProduceTransactionsFullBlock synchronizationDescriptor[{syncBlockHeight}].Hash = {hash.ToHexString()}; POW = {pow.ToHexString()}");

            RegistryFullBlock transactionsFullBlock = new RegistryFullBlock
            {
                SyncBlockHeight    = syncBlockHeight,
                PowHash            = pow,
                BlockHeight        = (ulong)_registryGroupState.Round,
                TransactionHeaders = transactionRegisterBlocks
            };

            //_nodeCountersService.RegistryBlockLastSize.RawValue = transactionRegisterBlocks.Count;
            //_nodeCountersService.RegistryBlockLastSize.NextSample();

            return(transactionsFullBlock);
        }
예제 #22
0
        public void AddCandidateBlock(RegistryFullBlock transactionsFullBlock)
        {
            if (transactionsFullBlock == null)
            {
                throw new ArgumentNullException(nameof(transactionsFullBlock));
            }

            _logger.Debug($"Adding candidate block of round {transactionsFullBlock.BlockHeight} with {transactionsFullBlock.TransactionHeaders.Count} transactions");
            _logger.Debug($"{nameof(SyncRegistryMemPool)} - adding candidate block {transactionsFullBlock.RawData.ToHexString()}");

            if (_lastCompletedRound > 1 && transactionsFullBlock.BlockHeight <= _lastCompletedRound && transactionsFullBlock.BlockHeight != 1 || _lastCompletedRound == 1 && transactionsFullBlock.BlockHeight == 1)
            {
                _logger.Error($"Received FullBlock with Round {transactionsFullBlock.BlockHeight} violates last completed Round {_lastCompletedRound}. Number of transactions: {transactionsFullBlock.TransactionHeaders.Count}");
                return;
            }
            else
            {
                _logger.Debug($"Received FullBlock with Round {transactionsFullBlock.BlockHeight} matches completed Round {_lastCompletedRound}");
            }

            lock (_syncRound)
            {
                if (!_roundDescriptors.ContainsKey(transactionsFullBlock.BlockHeight))
                {
                    RoundDescriptor roundDescriptor = new RoundDescriptor(_transactionHashKey);
                    roundDescriptor.AddFullBlock(transactionsFullBlock);
                    _roundDescriptors.Add(transactionsFullBlock.BlockHeight, roundDescriptor);
                }
                else
                {
                    _roundDescriptors[transactionsFullBlock.BlockHeight].AddFullBlock(transactionsFullBlock);
                }

                _logger.Debug($"AddCandidateBlock - Number of candidate blocks for round {transactionsFullBlock.BlockHeight} = {_roundDescriptors[transactionsFullBlock.BlockHeight].CandidateBlocks.Count}");
            }
        }
예제 #23
0
        public void RegistryFullBlockSerializerTest()
        {
            ulong syncBlockHeight = 1;
            uint  nonce           = 4;

            byte[] powHash     = BinaryHelper.GetPowHash(1234);
            ushort version     = 1;
            ulong  blockHeight = 9;

            byte[] prevHash = null;

            PacketType expectedReferencedPacketType = PacketType.Transactional;
            ushort     expectedReferencedBlockType  = BlockTypes.Transaction_TransferFunds;

            byte[] expectedReferencedBodyHash = BinaryHelper.GetDefaultHash(473826643);
            byte[] expectedTarget             = BinaryHelper.GetDefaultHash(BinaryHelper.GetRandomPublicKey());

            byte[] body;

            ushort expectedCount = 1000;

            RegistryRegisterBlock[]            stateWitnesses = new RegistryRegisterBlock[expectedCount];
            RegistryRegisterUtxoConfidential[] utxoWitnesses  = new RegistryRegisterUtxoConfidential[expectedCount];
            for (ushort i = 0; i < expectedCount; i++)
            {
                RegistryRegisterBlock registryRegisterBlock = new RegistryRegisterBlock
                {
                    SyncBlockHeight      = syncBlockHeight,
                    Nonce                = nonce + i,
                    PowHash              = BinaryHelper.GetPowHash(1234 + i),
                    BlockHeight          = blockHeight,
                    ReferencedPacketType = expectedReferencedPacketType,
                    ReferencedBlockType  = expectedReferencedBlockType,
                    ReferencedBodyHash   = BinaryHelper.GetDefaultHash(473826643 + i),
                    ReferencedTarget     = BinaryHelper.GetDefaultHash(BinaryHelper.GetRandomPublicKey())
                };

                RegistryRegisterBlockSerializer serializer1 = new RegistryRegisterBlockSerializer();
                serializer1.Initialize(registryRegisterBlock);
                serializer1.SerializeBody();
                _signingService.Sign(registryRegisterBlock);
                serializer1.SerializeFully();

                stateWitnesses[i] = registryRegisterBlock;

                RegistryRegisterUtxoConfidential registryRegisterUtxoConfidentialBlock = new RegistryRegisterUtxoConfidential
                {
                    SyncBlockHeight      = syncBlockHeight,
                    Nonce                = nonce + i,
                    PowHash              = BinaryHelper.GetPowHash(1234 + i),
                    DestinationKey       = ConfidentialAssetsHelper.GetRandomSeed(),
                    ReferencedPacketType = expectedReferencedPacketType,
                    ReferencedBlockType  = expectedReferencedBlockType,
                    DestinationKey2      = ConfidentialAssetsHelper.GetRandomSeed(),
                    ReferencedBodyHash   = BinaryHelper.GetDefaultHash(473826643 + i),
                    KeyImage             = new Key32(ConfidentialAssetsHelper.GetRandomSeed()),
                    TransactionPublicKey = ConfidentialAssetsHelper.GetRandomSeed(),
                    PublicKeys           = new IKey[] { new Key32(ConfidentialAssetsHelper.GetRandomSeed()), new Key32(ConfidentialAssetsHelper.GetRandomSeed()), new Key32(ConfidentialAssetsHelper.GetRandomSeed()) },
                    Signatures           = new RingSignature[]
                    {
                        new RingSignature {
                            C = ConfidentialAssetsHelper.GetRandomSeed(), R = ConfidentialAssetsHelper.GetRandomSeed()
                        },
                        new RingSignature {
                            C = ConfidentialAssetsHelper.GetRandomSeed(), R = ConfidentialAssetsHelper.GetRandomSeed()
                        },
                        new RingSignature {
                            C = ConfidentialAssetsHelper.GetRandomSeed(), R = ConfidentialAssetsHelper.GetRandomSeed()
                        }
                    }
                };

                RegistryRegisterUtxoConfidentialBlockSerializer serializer2 = new RegistryRegisterUtxoConfidentialBlockSerializer();
                serializer2.Initialize(registryRegisterUtxoConfidentialBlock);
                serializer2.SerializeFully();

                utxoWitnesses[i] = registryRegisterUtxoConfidentialBlock;
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write((ushort)stateWitnesses.Length);
                    bw.Write((ushort)utxoWitnesses.Length);

                    foreach (RegistryRegisterBlock witness in stateWitnesses)
                    {
                        bw.Write(witness.RawData.ToArray());
                    }

                    foreach (RegistryRegisterUtxoConfidential witness in utxoWitnesses)
                    {
                        bw.Write(witness.RawData.ToArray());
                    }

                    bw.Write(BinaryHelper.GetDefaultHash(1111));
                }

                body = ms.ToArray();
            }

            byte[] expectedPacket = BinaryHelper.GetSignedPacket(
                PacketType.Registry,
                syncBlockHeight,
                nonce, powHash, version,
                BlockTypes.Registry_FullBlock, blockHeight, prevHash, body, _privateKey, out byte[] expectedSignature);

            RegistryFullBlock block = new RegistryFullBlock
            {
                SyncBlockHeight = syncBlockHeight,
                Nonce           = nonce,
                PowHash         = powHash,
                BlockHeight     = blockHeight,
                StateWitnesses  = stateWitnesses,
                UtxoWitnesses   = utxoWitnesses,
                ShortBlockHash  = BinaryHelper.GetDefaultHash(1111)
            };

            RegistryFullBlockSerializer serializer = new RegistryFullBlockSerializer();

            serializer.Initialize(block);
            serializer.SerializeBody();
            _signingService.Sign(block);

            byte[] actualPacket = serializer.GetBytes();

            Trace.WriteLine(expectedPacket.ToHexString());
            Trace.WriteLine(actualPacket.ToHexString());

            Assert.Equal(expectedPacket, actualPacket);
        }
예제 #24
0
        public void RegistryFullBlockParserTest()
        {
            IBlockParser blockParser = new RegistryRegisterBlockParser(_identityKeyProvidersRegistry);

            _blockParsersRepository.GetInstance(0).ReturnsForAnyArgs(blockParser);

            ulong syncBlockHeight = 1;
            uint  nonce           = 4;

            byte[] powHash     = BinaryHelper.GetPowHash(1234);
            ushort version     = 1;
            ulong  blockHeight = 9;

            byte[] prevHash = null;

            PacketType expectedReferencedPacketType = PacketType.Transactional;
            ushort     expectedReferencedBlockType  = BlockTypes.Transaction_TransferFunds;

            byte[] body;

            ushort expectedCount = 1;

            byte[] expectedShortBlockHash;

            RegistryRegisterBlock[]            stateWitnesses = new RegistryRegisterBlock[expectedCount];
            RegistryRegisterUtxoConfidential[] utxoWitnesses  = new RegistryRegisterUtxoConfidential[expectedCount];

            for (ushort i = 0; i < expectedCount; i++)
            {
                RegistryRegisterBlock registryRegisterBlock = new RegistryRegisterBlock
                {
                    SyncBlockHeight      = syncBlockHeight,
                    Nonce                = nonce + i,
                    PowHash              = BinaryHelper.GetPowHash(1234 + i),
                    BlockHeight          = blockHeight,
                    ReferencedPacketType = expectedReferencedPacketType,
                    ReferencedBlockType  = expectedReferencedBlockType,
                    ReferencedBodyHash   = BinaryHelper.GetDefaultHash(473826643 + i),
                    ReferencedTarget     = BinaryHelper.GetDefaultHash(BinaryHelper.GetRandomPublicKey())
                };

                RegistryRegisterBlockSerializer serializer1 = new RegistryRegisterBlockSerializer();
                serializer1.Initialize(registryRegisterBlock);
                serializer1.SerializeBody();
                _signingService.Sign(registryRegisterBlock);
                serializer1.SerializeFully();

                stateWitnesses[i] = registryRegisterBlock;

                RegistryRegisterUtxoConfidential registryRegisterUtxoConfidentialBlock = new RegistryRegisterUtxoConfidential
                {
                    SyncBlockHeight      = syncBlockHeight,
                    Nonce                = nonce + i,
                    PowHash              = BinaryHelper.GetPowHash(1234 + i),
                    KeyImage             = new Key32(ConfidentialAssetsHelper.GetRandomSeed()),
                    ReferencedPacketType = expectedReferencedPacketType,
                    ReferencedBlockType  = expectedReferencedBlockType,
                    ReferencedBodyHash   = BinaryHelper.GetDefaultHash(473826643 + i),
                    DestinationKey       = ConfidentialAssetsHelper.GetRandomSeed(),
                    DestinationKey2      = ConfidentialAssetsHelper.GetRandomSeed(),
                    TransactionPublicKey = ConfidentialAssetsHelper.GetRandomSeed(),
                    PublicKeys           = new Key32[] { new Key32(ConfidentialAssetsHelper.GetRandomSeed()), new Key32(ConfidentialAssetsHelper.GetRandomSeed()), new Key32(ConfidentialAssetsHelper.GetRandomSeed()) },
                    Signatures           = new RingSignature[]
                    {
                        new RingSignature {
                            R = ConfidentialAssetsHelper.GetRandomSeed(), C = ConfidentialAssetsHelper.GetRandomSeed()
                        },
                        new RingSignature {
                            R = ConfidentialAssetsHelper.GetRandomSeed(), C = ConfidentialAssetsHelper.GetRandomSeed()
                        },
                        new RingSignature {
                            R = ConfidentialAssetsHelper.GetRandomSeed(), C = ConfidentialAssetsHelper.GetRandomSeed()
                        }
                    }
                };

                RegistryRegisterUtxoConfidentialBlockSerializer serializer2 = new RegistryRegisterUtxoConfidentialBlockSerializer();
                serializer2.Initialize(registryRegisterUtxoConfidentialBlock);
                serializer2.SerializeFully();

                utxoWitnesses[i] = registryRegisterUtxoConfidentialBlock;
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write((ushort)stateWitnesses.Length);
                    bw.Write((ushort)utxoWitnesses.Length);

                    foreach (RegistryRegisterBlock witness in stateWitnesses)
                    {
                        bw.Write(witness.RawData.ToArray());
                    }

                    foreach (RegistryRegisterUtxoConfidential witness in utxoWitnesses)
                    {
                        bw.Write(witness.RawData.ToArray());
                    }

                    expectedShortBlockHash = BinaryHelper.GetDefaultHash(1111);
                    bw.Write(expectedShortBlockHash);
                }

                body = ms.ToArray();
            }

            byte[] packet = BinaryHelper.GetSignedPacket(
                PacketType.Registry,
                syncBlockHeight,
                nonce, powHash, version,
                BlockTypes.Registry_FullBlock, blockHeight, prevHash, body, _privateKey, out byte[] expectedSignature);

            RegistryFullBlockParser registryFullBlockParser = new RegistryFullBlockParser(_identityKeyProvidersRegistry);
            RegistryFullBlock       block = (RegistryFullBlock)registryFullBlockParser.Parse(packet);

            Assert.Equal(syncBlockHeight, block.SyncBlockHeight);
            Assert.Equal(nonce, block.Nonce);
            Assert.Equal(powHash, block.PowHash);
            Assert.Equal(version, block.Version);
            Assert.Equal(blockHeight, block.BlockHeight);

            for (int i = 0; i < expectedCount; i++)
            {
                RegistryRegisterBlock registryRegisterBlock = block.StateWitnesses[i];
                Assert.Equal(stateWitnesses[i].PacketType, registryRegisterBlock.PacketType);
                Assert.Equal(stateWitnesses[i].SyncBlockHeight, registryRegisterBlock.SyncBlockHeight);
                Assert.Equal(stateWitnesses[i].Nonce, registryRegisterBlock.Nonce);
                Assert.Equal(stateWitnesses[i].PowHash, registryRegisterBlock.PowHash);
                Assert.Equal(stateWitnesses[i].BlockHeight, registryRegisterBlock.BlockHeight);
                Assert.Equal(stateWitnesses[i].BlockType, registryRegisterBlock.BlockType);
                Assert.Equal(stateWitnesses[i].ReferencedPacketType, registryRegisterBlock.ReferencedPacketType);
                Assert.Equal(stateWitnesses[i].ReferencedBlockType, registryRegisterBlock.ReferencedBlockType);
                Assert.Equal(stateWitnesses[i].ReferencedBodyHash, registryRegisterBlock.ReferencedBodyHash);
                Assert.Equal(stateWitnesses[i].ReferencedTarget, registryRegisterBlock.ReferencedTarget);
                Assert.Equal(stateWitnesses[i].Signature.ToArray(), registryRegisterBlock.Signature.ToArray());
                Assert.Equal(stateWitnesses[i].Signer, registryRegisterBlock.Signer);

                RegistryRegisterUtxoConfidential registryRegisterUtxoConfidentialBlock = block.UtxoWitnesses[i];
                Assert.Equal(utxoWitnesses[i].PacketType, registryRegisterUtxoConfidentialBlock.PacketType);
                Assert.Equal(utxoWitnesses[i].SyncBlockHeight, registryRegisterUtxoConfidentialBlock.SyncBlockHeight);
                Assert.Equal(utxoWitnesses[i].Nonce, registryRegisterUtxoConfidentialBlock.Nonce);
                Assert.Equal(utxoWitnesses[i].PowHash, registryRegisterUtxoConfidentialBlock.PowHash);
                Assert.Equal(utxoWitnesses[i].KeyImage, registryRegisterUtxoConfidentialBlock.KeyImage);
                Assert.Equal(utxoWitnesses[i].BlockType, registryRegisterUtxoConfidentialBlock.BlockType);
                Assert.Equal(utxoWitnesses[i].ReferencedPacketType, registryRegisterUtxoConfidentialBlock.ReferencedPacketType);
                Assert.Equal(utxoWitnesses[i].ReferencedBlockType, registryRegisterUtxoConfidentialBlock.ReferencedBlockType);
                Assert.Equal(utxoWitnesses[i].DestinationKey2, registryRegisterUtxoConfidentialBlock.DestinationKey2);
                Assert.Equal(utxoWitnesses[i].ReferencedBodyHash, registryRegisterUtxoConfidentialBlock.ReferencedBodyHash);
                Assert.Equal(utxoWitnesses[i].DestinationKey, registryRegisterUtxoConfidentialBlock.DestinationKey);
            }

            Assert.Equal(expectedShortBlockHash, block.ShortBlockHash);

            Assert.Equal(_publicKey, block.Signer.Value.ToArray());
            Assert.Equal(expectedSignature, block.Signature.ToArray());
        }
예제 #25
0
        public void GetMostConfidentFullBlockTest()
        {
            List <RegistryFullBlock>  registryFullBlocks    = new List <RegistryFullBlock>();
            List <RegistryShortBlock> registryShortBlocks   = new List <RegistryShortBlock>();
            Dictionary <IKey, int>    votesPerShortBlockKey = new Dictionary <IKey, int>();

            int   fullBlockCount  = 10;
            int   votersCount     = 100;
            ulong syncBlockHeight = 1;
            ulong blockHeight     = 12;
            uint  nonce           = 0;

            byte[]           powHash = BinaryHelper.GetPowHash(1234);
            IHashCalculation hashCalculationTransactionKey = new MurMurHashCalculation();

            IHashCalculation              hashCalculationDefault            = new Keccak256HashCalculation();
            IHashCalculation              hashCalculationMurMur             = new MurMurHashCalculation();
            ISerializersFactory           serializersFactory                = Substitute.For <ISerializersFactory>();
            IHashCalculationsRepository   hashCalculationsRepository        = Substitute.For <IHashCalculationsRepository>();
            IIdentityKeyProvider          identityKeyProviderTransactionKey = Substitute.For <IIdentityKeyProvider>();
            IIdentityKeyProvidersRegistry identityKeyProvidersRegistry      = Substitute.For <IIdentityKeyProvidersRegistry>();
            ISigningService         signingService         = GetRandomCryptoService();
            ILoggerService          loggerService          = Substitute.For <ILoggerService>();
            IStatesRepository       statesRepository       = Substitute.For <IStatesRepository>();
            ISynchronizationContext synchronizationContext = new Wist.Core.Synchronization.SynchronizationContext(loggerService);

            statesRepository.GetInstance <ISynchronizationContext>().ReturnsForAnyArgs(synchronizationContext);

            identityKeyProviderTransactionKey.GetKey(null).ReturnsForAnyArgs(c => new Key16(c.ArgAt <Memory <byte> >(0)));

            identityKeyProvidersRegistry.GetInstance("DefaultHash").Returns(new DefaultHashKeyProvider());
            identityKeyProvidersRegistry.GetTransactionsIdenityKeyProvider().Returns(identityKeyProviderTransactionKey);

            hashCalculationsRepository.Create(HashType.Keccak256).Returns(hashCalculationDefault);
            hashCalculationsRepository.Create(HashType.MurMur).Returns(hashCalculationMurMur);

            serializersFactory.Create(null).ReturnsForAnyArgs(c =>
            {
                RegistryShortBlockSerializer registryShortBlockSerializer = new RegistryShortBlockSerializer();
                registryShortBlockSerializer.Initialize(c.Arg <SignedPacketBase>());
                return(registryShortBlockSerializer);
            });

            SyncRegistryMemPool syncRegistryMemPool = new SyncRegistryMemPool(loggerService, hashCalculationsRepository);

            for (int i = 0; i < fullBlockCount; i++)
            {
                ISigningService signingService1 = GetRandomCryptoService();
                ushort          expectedCount   = 1000;

                SortedList <ushort, RegistryRegisterBlock> transactionHeaders = GetTransactionHeaders(syncBlockHeight, blockHeight, nonce, expectedCount);
                WitnessStateKey[] transactionHeaderKeys = GetTransactionHeaderKeys(transactionHeaders);

                RegistryShortBlock registryShortBlock = new RegistryShortBlock
                {
                    SyncBlockHeight  = syncBlockHeight,
                    BlockHeight      = blockHeight,
                    Nonce            = nonce,
                    PowHash          = powHash,
                    WitnessStateKeys = transactionHeaderKeys
                };

                RegistryShortBlockSerializer registryShortBlockSerializer = new RegistryShortBlockSerializer();
                registryShortBlockSerializer.Initialize(registryShortBlock);
                registryShortBlockSerializer.SerializeBody();
                signingService1.Sign(registryShortBlock);
                registryShortBlockSerializer.SerializeFully();

                RegistryFullBlock registryFullBlock = new RegistryFullBlock
                {
                    SyncBlockHeight = syncBlockHeight,
                    BlockHeight     = blockHeight,
                    Nonce           = nonce,
                    PowHash         = powHash,
                    StateWitnesses  = transactionHeaders.Values.ToArray(),
                    ShortBlockHash  = hashCalculationDefault.CalculateHash(registryShortBlock.RawData)
                };

                RegistryFullBlockSerializer serializer = new RegistryFullBlockSerializer();
                serializer.Initialize(registryFullBlock);
                serializer.SerializeBody();
                signingService.Sign(registryFullBlock);
                serializer.SerializeFully();

                registryFullBlocks.Add(registryFullBlock);
                registryShortBlocks.Add(registryShortBlock);
            }

            foreach (RegistryFullBlock fullBlock in registryFullBlocks)
            {
                syncRegistryMemPool.AddCandidateBlock(fullBlock);
            }

            IKey expectedMostConfidentKey = votesPerShortBlockKey.OrderByDescending(kv => kv.Value).Select(kv => kv.Key).First();

            IEnumerable <RegistryFullBlock> actualFullBlocks = syncRegistryMemPool.GetRegistryBlocks();
        }
예제 #26
0
        public void RegistryFullBlockParserTest()
        {
            IBlockParser blockParser = new RegistryRegisterBlockParser(_identityKeyProvidersRegistry, _hashCalculationRepository);

            _blockParsersRepository.GetInstance(0).ReturnsForAnyArgs(blockParser);

            ulong syncBlockHeight = 1;
            uint  nonce           = 4;

            byte[] powHash     = BinaryBuilder.GetPowHash(1234);
            ushort version     = 1;
            ulong  blockHeight = 9;

            byte[] prevHash = null;

            PacketType expectedReferencedPacketType = PacketType.Transactional;
            ushort     expectedReferencedBlockType  = BlockTypes.Transaction_TransferFunds;

            byte[] body;

            ushort expectedCount = 1000;

            byte[] expectedShortBlockHash;

            SortedList <ushort, RegistryRegisterBlock> transactionHeaders = new SortedList <ushort, RegistryRegisterBlock>();

            for (ushort i = 0; i < expectedCount; i++)
            {
                RegistryRegisterBlock registryRegisterBlock = new RegistryRegisterBlock
                {
                    SyncBlockHeight      = syncBlockHeight,
                    Nonce                = nonce + i,
                    PowHash              = BinaryBuilder.GetPowHash(1234 + i),
                    BlockHeight          = blockHeight,
                    ReferencedPacketType = expectedReferencedPacketType,
                    ReferencedBlockType  = expectedReferencedBlockType,
                    ReferencedBodyHash   = BinaryBuilder.GetDefaultHash(473826643 + i),
                    ReferencedTarget     = BinaryBuilder.GetDefaultHash(BinaryBuilder.GetRandomPublicKey())
                };

                RegistryRegisterBlockSerializer serializer1 = new RegistryRegisterBlockSerializer(_cryptoService, _identityKeyProvidersRegistry, _hashCalculationRepository);
                serializer1.Initialize(registryRegisterBlock);
                serializer1.FillBodyAndRowBytes();

                transactionHeaders.Add(i, registryRegisterBlock);
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write((ushort)transactionHeaders.Count);

                    foreach (ushort order in transactionHeaders.Keys)
                    {
                        bw.Write(order);
                        bw.Write(transactionHeaders[order].RawData.ToArray());
                    }

                    expectedShortBlockHash = BinaryBuilder.GetDefaultHash(1111);
                    bw.Write(expectedShortBlockHash);
                }

                body = ms.ToArray();
            }

            byte[] packet = BinaryBuilder.GetSignedPacket(
                PacketType.Registry,
                syncBlockHeight,
                nonce, powHash, version,
                BlockTypes.Registry_FullBlock, blockHeight, prevHash, body, _privateKey, out byte[] expectedSignature);

            RegistryFullBlockParser registryFullBlockParser = new RegistryFullBlockParser(_identityKeyProvidersRegistry, _hashCalculationRepository);
            RegistryFullBlock       block = (RegistryFullBlock)registryFullBlockParser.Parse(packet);

            Assert.Equal(syncBlockHeight, block.SyncBlockHeight);
            Assert.Equal(nonce, block.Nonce);
            Assert.Equal(powHash, block.PowHash);
            Assert.Equal(version, block.Version);
            Assert.Equal(blockHeight, block.BlockHeight);

            foreach (var item in transactionHeaders)
            {
                RegistryRegisterBlock registryRegisterBlock = (RegistryRegisterBlock)block.TransactionHeaders[item.Key];
                Assert.True(block.TransactionHeaders.ContainsKey(item.Key));
                Assert.Equal(item.Value.PacketType, registryRegisterBlock.PacketType);
                Assert.Equal(item.Value.SyncBlockHeight, registryRegisterBlock.SyncBlockHeight);
                Assert.Equal(item.Value.Nonce, registryRegisterBlock.Nonce);
                Assert.Equal(item.Value.PowHash, registryRegisterBlock.PowHash);
                Assert.Equal(item.Value.BlockHeight, registryRegisterBlock.BlockHeight);
                Assert.Equal(item.Value.BlockType, registryRegisterBlock.BlockType);
                Assert.Equal(item.Value.ReferencedPacketType, registryRegisterBlock.ReferencedPacketType);
                Assert.Equal(item.Value.ReferencedBlockType, registryRegisterBlock.ReferencedBlockType);
                Assert.Equal(item.Value.ReferencedBodyHash, registryRegisterBlock.ReferencedBodyHash);
                Assert.Equal(item.Value.ReferencedTarget, registryRegisterBlock.ReferencedTarget);
                Assert.Equal(item.Value.Signature.ToArray(), registryRegisterBlock.Signature.ToArray());
                Assert.Equal(item.Value.Signer, registryRegisterBlock.Signer);
            }

            Assert.Equal(expectedShortBlockHash, block.ShortBlockHash);

            Assert.Equal(_publicKey, block.Signer.Value.ToArray());
            Assert.Equal(expectedSignature, block.Signature.ToArray());
        }
예제 #27
0
        public void GetMostConfidentFullBlockTest()
        {
            List <RegistryFullBlock>  registryFullBlocks    = new List <RegistryFullBlock>();
            List <RegistryShortBlock> registryShortBlocks   = new List <RegistryShortBlock>();
            Dictionary <IKey, int>    votesPerShortBlockKey = new Dictionary <IKey, int>();

            int   fullBlockCount  = 10;
            int   votersCount     = 100;
            ulong syncBlockHeight = 1;
            ulong blockHeight     = 12;
            uint  nonce           = 0;

            byte[]           powHash = BinaryBuilder.GetPowHash(1234);
            IHashCalculation hashCalculationTransactionKey = new MurMurHashCalculation();

            IHashCalculation              hashCalculationDefault             = new Keccak256HashCalculation();
            IHashCalculation              hashCalculationMurMur              = new MurMurHashCalculation();
            ISerializersFactory           signatureSupportSerializersFactory = Substitute.For <ISerializersFactory>();
            IHashCalculationsRepository   hashCalculationsRepository         = Substitute.For <IHashCalculationsRepository>();
            IIdentityKeyProvider          identityKeyProviderTransactionKey  = Substitute.For <IIdentityKeyProvider>();
            IIdentityKeyProvidersRegistry identityKeyProvidersRegistry       = Substitute.For <IIdentityKeyProvidersRegistry>();
            ICryptoService          cryptoService          = GetRandomCryptoService();
            ILoggerService          loggerService          = Substitute.For <ILoggerService>();
            IStatesRepository       statesRepository       = Substitute.For <IStatesRepository>();
            ISynchronizationContext synchronizationContext = new Wist.Core.Synchronization.SynchronizationContext(loggerService);

            statesRepository.GetInstance <ISynchronizationContext>().ReturnsForAnyArgs(synchronizationContext);

            identityKeyProviderTransactionKey.GetKey(null).ReturnsForAnyArgs(c => new Key16(c.ArgAt <Memory <byte> >(0)));

            identityKeyProvidersRegistry.GetInstance("DefaultHash").Returns(new DefaultHashKeyProvider());
            identityKeyProvidersRegistry.GetTransactionsIdenityKeyProvider().Returns(identityKeyProviderTransactionKey);

            hashCalculationsRepository.Create(HashType.Keccak256).Returns(hashCalculationDefault);
            hashCalculationsRepository.Create(HashType.MurMur).Returns(hashCalculationMurMur);

            signatureSupportSerializersFactory.Create(null).ReturnsForAnyArgs(c =>
            {
                RegistryShortBlockSerializer registryShortBlockSerializer = new RegistryShortBlockSerializer(cryptoService, identityKeyProvidersRegistry, hashCalculationsRepository);
                registryShortBlockSerializer.Initialize(c.Arg <SignedBlockBase>());
                return(registryShortBlockSerializer);
            });

            SyncRegistryMemPool syncRegistryMemPool = new SyncRegistryMemPool(signatureSupportSerializersFactory, hashCalculationsRepository, identityKeyProvidersRegistry, cryptoService, statesRepository, loggerService);

            for (int i = 0; i < fullBlockCount; i++)
            {
                ICryptoService cryptoService1 = GetRandomCryptoService();
                ushort         expectedCount  = 1000;

                SortedList <ushort, ITransactionRegistryBlock> transactionHeaders = GetTransactionHeaders(syncBlockHeight, blockHeight, nonce, expectedCount);
                SortedList <ushort, IKey> transactionHeaderKeys = GetTransactionHeaderKeys(hashCalculationTransactionKey, transactionHeaders);

                RegistryShortBlock registryShortBlock = new RegistryShortBlock
                {
                    SyncBlockHeight         = syncBlockHeight,
                    BlockHeight             = blockHeight,
                    Nonce                   = nonce,
                    PowHash                 = powHash,
                    TransactionHeaderHashes = transactionHeaderKeys
                };

                RegistryShortBlockSerializer registryShortBlockSerializer = new RegistryShortBlockSerializer(cryptoService1, identityKeyProvidersRegistry, hashCalculationsRepository);
                registryShortBlockSerializer.Initialize(registryShortBlock);
                registryShortBlockSerializer.FillBodyAndRowBytes();

                RegistryFullBlock registryFullBlock = new RegistryFullBlock
                {
                    SyncBlockHeight    = syncBlockHeight,
                    BlockHeight        = blockHeight,
                    Nonce              = nonce,
                    PowHash            = powHash,
                    TransactionHeaders = transactionHeaders,
                    ShortBlockHash     = hashCalculationDefault.CalculateHash(registryShortBlock.RawData)
                };

                RegistryFullBlockSerializer serializer = new RegistryFullBlockSerializer(cryptoService1, identityKeyProvidersRegistry, hashCalculationsRepository);
                serializer.Initialize(registryFullBlock);
                serializer.FillBodyAndRowBytes();

                registryFullBlocks.Add(registryFullBlock);
                registryShortBlocks.Add(registryShortBlock);
            }

            foreach (RegistryFullBlock fullBlock in registryFullBlocks)
            {
                syncRegistryMemPool.AddCandidateBlock(fullBlock);
            }

            Random random = new Random();

            for (int i = 0; i < votersCount; i++)
            {
                ICryptoService cryptoService2 = GetRandomCryptoService();

                foreach (var registryShortBlock in registryShortBlocks)
                {
                    byte[] hashBytes     = hashCalculationDefault.CalculateHash(registryShortBlock.RawData);
                    Random randNum       = new Random();
                    byte[] bitMask       = Enumerable.Repeat(0, registryShortBlock.TransactionHeaderHashes.Count).Select(j => (byte)randNum.Next(0, 255)).ToArray();
                    byte[] expectedProof = Enumerable.Repeat(0, 16).Select(j => (byte)randNum.Next(0, 255)).ToArray();
                    IKey   shortBlockKey = new Key32(hashBytes);
                    long   vote          = GetConfidence(bitMask);
                    if (!votesPerShortBlockKey.ContainsKey(shortBlockKey))
                    {
                        votesPerShortBlockKey.Add(shortBlockKey, (ushort)vote);
                    }
                    else
                    {
                        votesPerShortBlockKey[shortBlockKey] += (ushort)vote;
                    }

                    RegistryConfidenceBlock registryConfidenceBlock = new RegistryConfidenceBlock
                    {
                        SyncBlockHeight     = syncBlockHeight,
                        BlockHeight         = blockHeight,
                        Nonce               = nonce,
                        PowHash             = powHash,
                        ReferencedBlockHash = hashBytes,
                        BitMask             = bitMask,
                        ConfidenceProof     = expectedProof
                    };

                    RegistryConfidenceBlockSerializer registryConfidenceBlockSerializer = new RegistryConfidenceBlockSerializer(cryptoService2, identityKeyProvidersRegistry, hashCalculationsRepository);
                    registryConfidenceBlockSerializer.Initialize(registryConfidenceBlock);
                    registryConfidenceBlockSerializer.FillBodyAndRowBytes();

                    syncRegistryMemPool.AddVotingBlock(registryConfidenceBlock);
                }
            }

            IKey expectedMostConfidentKey = votesPerShortBlockKey.OrderByDescending(kv => kv.Value).Select(kv => kv.Key).First();

            RegistryFullBlock actualFullBlock = syncRegistryMemPool.GetMostConfidentFullBlock(blockHeight);
            IKey actualMostConfidentKey       = new Key32(actualFullBlock.ShortBlockHash);

            Assert.Equal(expectedMostConfidentKey, actualMostConfidentKey);
        }
예제 #28
0
        private Tuple <RegistryFullBlock, RegistryShortBlock> ProduceTransactionsShortBlock(RegistryFullBlock transactionsFullBlock)
        {
            RegistryShortBlock transactionsShortBlock = new RegistryShortBlock
            {
                SyncBlockHeight         = transactionsFullBlock.SyncBlockHeight,
                Nonce                   = transactionsFullBlock.Nonce,
                PowHash                 = transactionsFullBlock.PowHash, // _powCalculation.CalculateHash(_synchronizationContext.LastBlockDescriptor?.Hash ?? new byte[Globals.DEFAULT_HASH_SIZE]),
                BlockHeight             = transactionsFullBlock.BlockHeight,
                TransactionHeaderHashes = new SortedList <ushort, IKey>(transactionsFullBlock.TransactionHeaders.ToDictionary(i => i.Key, i => _transactionsRegistryHelper.GetTransactionRegistryTwiceHashedKey(i.Value)))
            };

            Tuple <RegistryFullBlock, RegistryShortBlock> tuple = new Tuple <RegistryFullBlock, RegistryShortBlock>(transactionsFullBlock, transactionsShortBlock);

            return(tuple);
        }
예제 #29
0
        public void RegistryFullBlockSerializerTest()
        {
            ulong syncBlockHeight = 1;
            uint  nonce           = 4;

            byte[] powHash     = BinaryBuilder.GetPowHash(1234);
            ushort version     = 1;
            ulong  blockHeight = 9;

            byte[] prevHash = null;

            PacketType expectedReferencedPacketType = PacketType.Transactional;
            ushort     expectedReferencedBlockType  = BlockTypes.Transaction_TransferFunds;

            byte[] expectedReferencedBodyHash = BinaryBuilder.GetDefaultHash(473826643);
            byte[] expectedTarget             = BinaryBuilder.GetDefaultHash(BinaryBuilder.GetRandomPublicKey());

            byte[] body;

            ushort expectedCount = 1000;

            SortedList <ushort, ITransactionRegistryBlock> transactionHeaders = new SortedList <ushort, ITransactionRegistryBlock>();

            for (ushort i = 0; i < expectedCount; i++)
            {
                RegistryRegisterBlock registryRegisterBlock = new RegistryRegisterBlock
                {
                    SyncBlockHeight      = syncBlockHeight,
                    Nonce                = nonce + i,
                    PowHash              = BinaryBuilder.GetPowHash(1234 + i),
                    BlockHeight          = blockHeight,
                    ReferencedPacketType = expectedReferencedPacketType,
                    ReferencedBlockType  = expectedReferencedBlockType,
                    ReferencedBodyHash   = BinaryBuilder.GetDefaultHash(473826643 + i),
                    ReferencedTarget     = BinaryBuilder.GetDefaultHash(BinaryBuilder.GetRandomPublicKey())
                };

                RegistryRegisterBlockSerializer serializer1 = new RegistryRegisterBlockSerializer(_cryptoService, _identityKeyProvidersRegistry, _hashCalculationRepository);
                serializer1.Initialize(registryRegisterBlock);
                serializer1.FillBodyAndRowBytes();

                transactionHeaders.Add(i, registryRegisterBlock);
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write((ushort)transactionHeaders.Count);

                    foreach (ushort order in transactionHeaders.Keys)
                    {
                        bw.Write(order);
                        bw.Write(transactionHeaders[order].RawData.ToArray());
                    }

                    bw.Write(BinaryBuilder.GetDefaultHash(1111));
                }

                body = ms.ToArray();
            }

            byte[] expectedPacket = BinaryBuilder.GetSignedPacket(
                PacketType.Registry,
                syncBlockHeight,
                nonce, powHash, version,
                BlockTypes.Registry_FullBlock, blockHeight, prevHash, body, _privateKey, out byte[] expectedSignature);

            RegistryFullBlock block = new RegistryFullBlock
            {
                SyncBlockHeight    = syncBlockHeight,
                Nonce              = nonce,
                PowHash            = powHash,
                BlockHeight        = blockHeight,
                TransactionHeaders = transactionHeaders,
                ShortBlockHash     = BinaryBuilder.GetDefaultHash(1111)
            };

            RegistryFullBlockSerializer serializer = new RegistryFullBlockSerializer(_cryptoService, _identityKeyProvidersRegistry, _hashCalculationRepository);

            serializer.Initialize(block);

            byte[] actualPacket = serializer.GetBytes();

            Trace.WriteLine(expectedPacket.ToHexString());
            Trace.WriteLine(actualPacket.ToHexString());

            Assert.Equal(expectedPacket, actualPacket);
        }