protected override Memory <byte> FillBlockBaseHeader(BlockBase blockBase, Memory <byte> spanHeader) { SyncedBlockBase syncedBlockBase = (SyncedBlockBase)blockBase; spanHeader = base.FillBlockBaseHeader(blockBase, spanHeader); syncedBlockBase.SyncBlockHeight = BinaryPrimitives.ReadUInt64LittleEndian(spanHeader.Span); syncedBlockBase.Nonce = BinaryPrimitives.ReadUInt32LittleEndian(spanHeader.Slice(8).Span); syncedBlockBase.PowHash = spanHeader.Slice(12, Globals.POW_HASH_SIZE).ToArray(); return(spanHeader.Slice(12 + Globals.POW_HASH_SIZE)); }
public bool VerifyBlock(BlockBase blockBase) { SyncedBlockBase syncedBlockBase = (SyncedBlockBase)blockBase; ulong syncBlockHeight = syncedBlockBase.SyncBlockHeight; if (!((_synchronizationContext.LastBlockDescriptor?.BlockHeight.Equals(syncBlockHeight) ?? true) || (_synchronizationContext.PrevBlockDescriptor?.BlockHeight.Equals(syncBlockHeight) ?? true))) { _log.Error($"Synchronization block height is outdated: {blockBase.RawData.ToArray().ToHexString()}"); return(false); } return(CheckSyncPOW(syncedBlockBase)); }
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); }
protected abstract Memory <byte> ParseSynced(ushort version, Memory <byte> spanBody, out SyncedBlockBase syncedBlockBase);
private bool CheckSyncPOW(SyncedBlockBase syncedBlockBase) { ulong syncBlockHeight = syncedBlockBase.SyncBlockHeight; uint nonce = syncedBlockBase.Nonce; byte[] powHash = syncedBlockBase.PowHash; byte[] baseHash; byte[] baseSyncHash; if (syncedBlockBase.PacketType != PacketType.Synchronization) { //TODO: make difficulty check dynamic //if (powHash[0] != 0 || powHash[1] != 0) //{ // return false; //} BigInteger bigInteger; baseSyncHash = new byte[Globals.DEFAULT_HASH_SIZE + 1]; // Adding extra 0 byte for avoiding negative values of BigInteger lock (_synchronizationContext) { byte[] buf; if (_synchronizationContext.LastBlockDescriptor != null || _synchronizationContext.PrevBlockDescriptor != null) { buf = (syncBlockHeight == _synchronizationContext.LastBlockDescriptor?.BlockHeight) ? _synchronizationContext.LastBlockDescriptor.Hash : _synchronizationContext.PrevBlockDescriptor.Hash; } else { _log.Warning("CheckSyncPOW - BOTH LastBlockDescriptor and PrevBlockDescriptor are NULL"); buf = new byte[Globals.DEFAULT_HASH_SIZE]; } Array.Copy(buf, 0, baseSyncHash, 0, buf.Length); } bigInteger = new BigInteger(baseSyncHash); bigInteger += nonce; baseHash = bigInteger.ToByteArray().Take(Globals.DEFAULT_HASH_SIZE).ToArray(); } else { lock (_synchronizationContext) { if (_synchronizationContext.LastBlockDescriptor == null) { baseSyncHash = new byte[Globals.DEFAULT_HASH_SIZE]; } else { baseSyncHash = (syncBlockHeight == _synchronizationContext.LastBlockDescriptor.BlockHeight) ? _synchronizationContext.LastBlockDescriptor.Hash : _synchronizationContext.PrevBlockDescriptor.Hash; } } baseHash = baseSyncHash; } byte[] computedHash = _proofOfWorkCalculation.CalculateHash(baseHash); if (!computedHash.Equals24(powHash)) { _log.Error($"Computed HASH differs from obtained one. PacketType is {syncedBlockBase.PacketType}, BlockType is {syncedBlockBase.BlockType}. Reported SyncBlockHeight is {syncedBlockBase.SyncBlockHeight}, Nonce is {syncedBlockBase.Nonce}, POW is {syncedBlockBase.PowHash.ToHexString()}. Hash of SyncBlock is {baseSyncHash.ToHexString()}, after adding Nonce is {baseHash.ToHexString()}, computed POW Hash is {computedHash.ToHexString()}"); return(false); } return(true); }
protected override Memory <byte> ParseSynced(ushort version, Memory <byte> spanBody, out SyncedBlockBase signedBlockBase) { byte[] prevHash = spanBody.Slice(0, Globals.DEFAULT_HASH_SIZE).ToArray(); Memory <byte> spanPostBody = ParseSyncLinked(version, spanBody.Slice(Globals.DEFAULT_HASH_SIZE), out SyncedLinkedBlockBase syncedBlockBase); syncedBlockBase.HashPrev = prevHash; signedBlockBase = syncedBlockBase; return(spanPostBody); }
protected override Memory <byte> ParseSynced(ushort version, Memory <byte> spanBody, out SyncedBlockBase syncedBlockBase) { if (version == 1) { PacketType referencedPacketType = (PacketType)BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span); ushort referencedBlockType = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span.Slice(2)); byte[] referencedBlockHash = spanBody.Slice(4, Globals.DEFAULT_HASH_SIZE).ToArray(); byte[] referencedTargetHash = spanBody.Slice(4 + Globals.DEFAULT_HASH_SIZE, Globals.DEFAULT_HASH_SIZE).ToArray(); RegistryRegisterBlock transactionRegisterBlock = new RegistryRegisterBlock { ReferencedPacketType = referencedPacketType, ReferencedBlockType = referencedBlockType, ReferencedBodyHash = referencedBlockHash, ReferencedTarget = referencedTargetHash }; syncedBlockBase = transactionRegisterBlock; return(spanBody.Slice(4 + Globals.DEFAULT_HASH_SIZE + Globals.DEFAULT_HASH_SIZE)); } throw new BlockVersionNotSupportedException(version, BlockType); }
protected override Memory <byte> ParseSynced(ushort version, Memory <byte> spanBody, out SyncedBlockBase syncedBlockBase) { if (version == 1) { RegistryConfidenceBlock registryConfidenceBlock = new RegistryConfidenceBlock(); ushort bitMaskLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span); registryConfidenceBlock.BitMask = spanBody.Slice(2, bitMaskLength).ToArray(); registryConfidenceBlock.ConfidenceProof = spanBody.Slice(2 + bitMaskLength, Globals.TRANSACTION_KEY_HASH_SIZE).ToArray(); registryConfidenceBlock.ReferencedBlockHash = spanBody.Slice(2 + bitMaskLength + Globals.TRANSACTION_KEY_HASH_SIZE, Globals.DEFAULT_HASH_SIZE).ToArray(); syncedBlockBase = registryConfidenceBlock; return(spanBody.Slice(2 + bitMaskLength + Globals.TRANSACTION_KEY_HASH_SIZE + Globals.DEFAULT_HASH_SIZE)); } throw new BlockVersionNotSupportedException(version, BlockType); }
private void FillSyncData(SyncedBlockBase block) { Proto.Model.SyncBlockDescriptor lastSyncBlock = _networkAdapter.GetLastSyncBlock(); block.SyncBlockHeight = lastSyncBlock.Height; block.PowHash = GetPowHash(lastSyncBlock.Hash.ToByteArray(), 0); }
public AccountSourceKey(SyncedBlockBase blockBase) { _blockBase = blockBase; }
protected override Memory <byte> ParseSynced(ushort version, Memory <byte> spanBody, out SyncedBlockBase syncedBlockBase) { if (version == 1) { RegistryConfirmationBlock block = new RegistryConfirmationBlock { ReferencedBlockHash = spanBody.Slice(0, Globals.DEFAULT_HASH_SIZE).ToArray() }; syncedBlockBase = block; return(spanBody.Slice(Globals.DEFAULT_HASH_SIZE)); } throw new BlockVersionNotSupportedException(version, BlockType); }
protected override Memory <byte> ParseSynced(ushort version, Memory <byte> spanBody, out SyncedBlockBase syncedBlockBase) { if (version == 1) { RegistryShortBlock transactionsShortBlock = new RegistryShortBlock(); ushort itemsCount = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span); transactionsShortBlock.TransactionHeaderHashes = new SortedList <ushort, IKey>(itemsCount); for (int i = 0; i < itemsCount; i++) { ushort order = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span.Slice(2 + i * (Globals.TRANSACTION_KEY_HASH_SIZE + 2))); byte[] hashKey = spanBody.Slice(2 + i * (Globals.TRANSACTION_KEY_HASH_SIZE + 2) + 2, Globals.TRANSACTION_KEY_HASH_SIZE).ToArray(); IKey key = _transactionHashKeyProvider.GetKey(hashKey); transactionsShortBlock.TransactionHeaderHashes.Add(order, key); } syncedBlockBase = transactionsShortBlock; return(spanBody.Slice(2 + itemsCount * (Globals.TRANSACTION_KEY_HASH_SIZE + 2))); } throw new BlockVersionNotSupportedException(version, BlockType); }