示例#1
0
        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));
        }
示例#2
0
        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));
        }
示例#3
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);
        }
示例#4
0
 protected abstract Memory <byte> ParseSynced(ushort version, Memory <byte> spanBody, out SyncedBlockBase syncedBlockBase);
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }
示例#9
0
 private void FillSyncData(SyncedBlockBase block)
 {
     Proto.Model.SyncBlockDescriptor lastSyncBlock = _networkAdapter.GetLastSyncBlock();
     block.SyncBlockHeight = lastSyncBlock.Height;
     block.PowHash         = GetPowHash(lastSyncBlock.Hash.ToByteArray(), 0);
 }
示例#10
0
 public AccountSourceKey(SyncedBlockBase blockBase)
 {
     _blockBase = blockBase;
 }
示例#11
0
        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);
        }
示例#12
0
        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);
        }