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); } }
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); } }
public override Task GetAllCombinedRegistryBlocksPerSync(ByHeightRequest request, IServerStreamWriter <CombinedRegistryBlockInfo> responseStream, ServerCallContext context) { return(Task.Run(() => { IEnumerable <PacketBase> blocks = _syncChainDataService.GetAllLastBlocksByType(BlockTypes.Synchronization_RegistryCombinationBlock).Where(b => ((SynchronizationRegistryCombinedBlock)b).SyncBlockHeight == request.Height); foreach (PacketBase 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[] item in registryCombinedBlock.BlockHashes) { combinedRegistryBlockInfo.BlockDescriptors.Add(new FullBlockDescriptor { BlockHash = ByteString.CopyFrom(item) }); } responseStream.WriteAsync(combinedRegistryBlockInfo); } })); }
public void SynchronizationRegistryCombinedBlockSerializerTest() { ulong syncBlockHeight = 1; uint nonce = 4; byte[] powHash = BinaryHelper.GetPowHash(1234); ushort version = 1; ulong blockHeight = 9; byte[] prevHash = BinaryHelper.GetDefaultHash(1234); byte[] body; DateTime expectedDateTime = DateTime.Now; byte[][] expectedHashes = new byte[2][] { ConfidentialAssetsHelper.GetRandomSeed(), ConfidentialAssetsHelper.GetRandomSeed() }; using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(expectedDateTime.ToBinary()); bw.Write((ushort)2); bw.Write(expectedHashes[0]); bw.Write(expectedHashes[1]); } body = ms.ToArray(); } byte[] expectedPacket = BinaryHelper.GetSignedPacket( PacketType.Synchronization, syncBlockHeight, nonce, powHash, version, BlockTypes.Synchronization_RegistryCombinationBlock, blockHeight, prevHash, body, _privateKey, out byte[] expectedSignature); SynchronizationRegistryCombinedBlock block = new SynchronizationRegistryCombinedBlock { SyncBlockHeight = syncBlockHeight, Nonce = nonce, PowHash = powHash, BlockHeight = blockHeight, HashPrev = prevHash, ReportedTime = expectedDateTime, BlockHashes = expectedHashes }; SynchronizationRegistryCombinedBlockSerializer serializer = new SynchronizationRegistryCombinedBlockSerializer(); serializer.Initialize(block); serializer.SerializeBody(); _signingService.Sign(block); byte[] actualPacket = serializer.GetBytes(); Trace.WriteLine(expectedPacket.ToHexString()); Trace.WriteLine(actualPacket.ToHexString()); Assert.Equal(expectedPacket, actualPacket); }
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); } }
public void SynchronizationRegistryCombinedBlockParserTest() { ulong syncBlockHeight = 1; uint nonce = 4; byte[] powHash = BinaryHelper.GetPowHash(1234); ushort version = 1; ulong blockHeight = 9; byte[] prevHash = BinaryHelper.GetDefaultHash(1234); byte[] body; DateTime expectedDateTime = DateTime.Now; byte[][] expectedHashes = new byte[2][] { ConfidentialAssetsHelper.GetRandomSeed(), ConfidentialAssetsHelper.GetRandomSeed() }; using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(expectedDateTime.ToBinary()); bw.Write((ushort)2); bw.Write(expectedHashes[0]); bw.Write(expectedHashes[1]); } body = ms.ToArray(); } byte[] packet = BinaryHelper.GetSignedPacket( PacketType.Synchronization, syncBlockHeight, nonce, powHash, version, BlockTypes.Synchronization_RegistryCombinationBlock, blockHeight, prevHash, body, _privateKey, out byte[] expectedSignature); SynchronizationRegistryCombinedBlockParser parser = new SynchronizationRegistryCombinedBlockParser(_identityKeyProvidersRegistry); SynchronizationRegistryCombinedBlock block = (SynchronizationRegistryCombinedBlock)parser.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); Assert.Equal(expectedHashes.Length, block.BlockHashes.Length); for (int i = 0; i < expectedHashes.Length; i++) { Assert.Equal(expectedHashes[i], block.BlockHashes[i]); } Assert.Equal(_publicKey, block.Signer.Value.ToArray()); Assert.Equal(expectedSignature, block.Signature.ToArray()); }
public void RegisterCombinedBlock(SynchronizationRegistryCombinedBlock combinedBlock) { List <SynchronizationRegistryCombinedBlock> toRemove = _registryCombinedBlocks.Where(b => (int)(combinedBlock.BlockHeight - b.BlockHeight) > _maxCombinedBlocks).ToList(); foreach (var item in toRemove) { _registryCombinedBlocks.Remove(item); } _registryCombinedBlocks.Add(combinedBlock); RemoveRange(combinedBlock.BlockHashes); }
public override BlockBase Translate(RegistryCombinedBlock registryCombinedBlock) { if (registryCombinedBlock == null) { return(null); } SynchronizationRegistryCombinedBlock block = null; IBlockParser blockParser = _blockParsersRepository.GetInstance(BlockTypes.Synchronization_RegistryCombinationBlock); block = blockParser.Parse(registryCombinedBlock.Content) as SynchronizationRegistryCombinedBlock; block.SyncBlockHeight = registryCombinedBlock.SyncBlockHeight; return(block); }
public override async Task GetCombinedRegistryBlocksContentSinceHeight(ByHeightRequest request, IServerStreamWriter <TransactionInfo> responseStream, ServerCallContext context) { IEnumerable <PacketBase> blocks = _syncChainDataService.GetAll(new BlockTypeLowHeightKey(BlockTypes.Synchronization_RegistryCombinationBlock, request.Height)); foreach (PacketBase blockBase in blocks) { SynchronizationRegistryCombinedBlock registryCombinedBlock = blockBase as SynchronizationRegistryCombinedBlock; TransactionInfo blockInfo = new TransactionInfo { SyncBlockHeight = registryCombinedBlock.SyncBlockHeight, BlockType = registryCombinedBlock.BlockType, PacketType = (uint)registryCombinedBlock.PacketType, Content = ByteString.CopyFrom(registryCombinedBlock.RawData.ToArray()) }; await responseStream.WriteAsync(blockInfo); } }
protected override Memory <byte> ParseSynchronization(ushort version, Memory <byte> spanBody, out SynchronizationBlockBase synchronizationBlockBase) { SynchronizationRegistryCombinedBlock block = new SynchronizationRegistryCombinedBlock(); if (version == 1) { ushort blockHashesCount = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span); block.BlockHashes = new byte[blockHashesCount][]; for (int i = 0; i < blockHashesCount; i++) { block.BlockHashes[i] = spanBody.Slice(2 + i * Globals.DEFAULT_HASH_SIZE, Globals.DEFAULT_HASH_SIZE).ToArray(); } synchronizationBlockBase = block; return(spanBody.Slice(2 + blockHashesCount * Globals.DEFAULT_HASH_SIZE)); } throw new BlockVersionNotSupportedException(version, BlockType); }
protected override void InitializeInner() { _logger.Info("Starting Synchronization Initializer"); try { SynchronizationConfirmedBlock synchronizationConfirmedBlock = (SynchronizationConfirmedBlock)_chainDataService.GetAllLastBlocksByType(BlockTypes.Synchronization_ConfirmedBlock).Single(); if (synchronizationConfirmedBlock != null) { _synchronizationContext.UpdateLastSyncBlockDescriptor(new SynchronizationDescriptor(synchronizationConfirmedBlock.BlockHeight, _hashCalculation.CalculateHash(synchronizationConfirmedBlock.RawData), synchronizationConfirmedBlock.ReportedTime, DateTime.Now, synchronizationConfirmedBlock.Round)); } SynchronizationRegistryCombinedBlock combinedBlock = (SynchronizationRegistryCombinedBlock)_chainDataService.GetAllLastBlocksByType(BlockTypes.Synchronization_RegistryCombinationBlock).Single(); if (combinedBlock != null) { _synchronizationContext.LastRegistrationCombinedBlockHeight = combinedBlock.BlockHeight; } } finally { _logger.Info("Synchronization Initializer completed"); } }
public void Start() { _logger.Info("Started"); _communicationService.Start(); PeriodicTaskFactory.Start(async() => { if (_isProcessing) { return; } lock (_sync) { if (_isProcessing) { return; } _isProcessing = true; } try { Proto.Model.SyncBlockDescriptor syncBlockDescriptor = _syncLayerSyncManagerClient.GetLastSyncBlock(new Empty()); if (_lastSyncDescriptor.Height < syncBlockDescriptor.Height) { _lastSyncDescriptor = new Entities.SyncBlockDescriptor(syncBlockDescriptor.Height, syncBlockDescriptor.Hash.ToByteArray()); _dataAccessService.UpdateLastSyncBlock(syncBlockDescriptor.Height, syncBlockDescriptor.Hash.ToByteArray()); } ulong lastCombinedBlockHeight = _lastCombinedBlockDescriptor.Height; SynchronizationRegistryCombinedBlock lastCombinedBlock = null; AsyncServerStreamingCall <TransactionInfo> asyncCall = _syncLayerSyncManagerClient.GetCombinedRegistryBlocksContentSinceHeight(new ByHeightRequest { Height = _lastCombinedBlockDescriptor.Height }); while (await asyncCall.ResponseStream.MoveNext(_cancellationToken)) { SynchronizationRegistryCombinedBlock combinedBlock = GetRegistryCombinedBlock(asyncCall.ResponseStream.Current); if (combinedBlock == null) { continue; } try { _dataAccessService.UpdateLastRegistryCombinedBlock(combinedBlock.BlockHeight, combinedBlock.RawData.ToArray()); if (lastCombinedBlockHeight < combinedBlock.BlockHeight) { lastCombinedBlockHeight = combinedBlock.BlockHeight; lastCombinedBlock = combinedBlock; } foreach (byte[] fullRegistryBlockHash in combinedBlock.BlockHashes) { await UpdateTransactionsByFullRegistryBlock(combinedBlock, fullRegistryBlockHash); } } catch (Exception ex) { _logger.Error($"Failure during obtaining transactions at Registry Combined Block with height {combinedBlock.BlockHeight}", ex); } } if (lastCombinedBlock != null) { _lastCombinedBlockDescriptor = new RegistryCombinedBlockDescriptor(lastCombinedBlock.BlockHeight, lastCombinedBlock.RawData.ToArray(), _defaultHashCalculation.CalculateHash(lastCombinedBlock.RawData)); _dataAccessService.UpdateLastRegistryCombinedBlock(_lastCombinedBlockDescriptor.Height, _lastCombinedBlockDescriptor.Hash); } } catch (Exception ex) { _logger.Error("Failure during updating blockchain", ex); } finally { _isProcessing = false; } }, 5000, cancelToken: _cancellationToken); }