public async Task get_latest_block_number_should_return_null_if_head_is_null()
        {
            Block?result = await _ndmBridge.GetLatestBlockAsync();

            result.Should().BeNull();
        }
Esempio n. 2
0
        public Block?EnqueueJumpTarget(Address addrSrc, Address addrDest, Procedure proc, ProcessorState state)
        {
            Procedure procDest;
            Block?    block = FindExactBlock(addrDest);

            if (block == null)
            {
                // Target wasn't a block before. Make sure it exists.
                block = FindContainingBlock(addrDest);
                if (block != null)
                {
                    block = SplitBlock(block, addrDest);
                }
                else
                {
                    var label = Program.NamingPolicy.BlockName(addrDest);
                    block = AddBlock(addrDest, proc, label);
                }

                if (proc == block.Procedure)
                {
                    // Easy case: split a block in our own procedure.
                    var wi = CreateBlockWorkItem(addrDest, proc, state);
                    procQueue.Enqueue(PriorityJumpTarget, wi);
                }
                else if (IsBlockLinearProcedureExit(block))
                {
                    block = CloneBlockIntoOtherProcedure(block, proc);
                }
                else
                {
                    // We just created a block in a foreign procedure.
                    blocks.Remove(addrDest);
                    block.Procedure.RemoveBlock(block);
                    procDest = Program.EnsureProcedure(block.Procedure.Architecture, addrDest, null);
                    EnqueueProcedure(block.Procedure.Architecture, addrDest);
                    var blockThunk = CreateCallRetThunk(addrSrc, proc, procDest);
                    var wi         = CreatePromoteWorkItem(addrDest, block, procDest);
                    procQueue.Enqueue(PriorityBlockPromote, wi);
                    block = blockThunk;
                }
            }
            else if (block.Procedure != proc)
            {
                // Jumped to a block with a different procedure than the
                // current one. Was the jump to the entry of an existing procedure?
                if (Program.Procedures.TryGetValue(addrDest, out procDest))
                {
                    if (procDest == proc)
                    {
                        proc.Signature.StackDelta    = block.Procedure.Signature.StackDelta;
                        proc.Signature.FpuStackDelta = block.Procedure.Signature.FpuStackDelta;
                        var wi = CreatePromoteWorkItem(addrDest, block, procDest);
                        procQueue.Enqueue(PriorityBlockPromote, wi);
                    }
                    else
                    {
                        // We jumped to the entry of a different procedure.
                        block = CreateCallRetThunk(addrSrc, proc, procDest);
                    }
                }
                else
                {
                    // Jumped into the middle of another procedure. Is it worth
                    // promoting the destination block to a new procedure?
                    if (IsBlockLinearProcedureExit(block))
                    {
                        // No, just clone the block into the new procedure.
                        block = CloneBlockIntoOtherProcedure(block, proc);
                    }
                    else
                    {
                        // We jumped into a pre-existing block of another
                        // procedure which was hairy enough that we need to
                        // promote the block to a new procedure.
                        procDest = Program.EnsureProcedure(proc.Architecture, addrDest, null);
                        var blockNew = CreateCallRetThunk(addrSrc, proc, procDest);
                        EstablishInitialState(addrDest, Program.Architecture.CreateProcessorState(), procDest);
                        procDest.ControlGraph.AddEdge(procDest.EntryBlock, block);
                        InjectProcedureEntryInstructions(addrDest, procDest);
                        var wi = CreatePromoteWorkItem(addrDest, block, procDest);
                        procQueue.Enqueue(PriorityBlockPromote, wi);
                        return(blockNew);
                    }
                }
            }
            return(block);
        }
Esempio n. 3
0
 public static bool IsPoS(this Block?block) => block?.Header.IsPoS() == true;
Esempio n. 4
0
 public SelectorEntityProvider(Block?blockType, bool isGroup, Variable selector)
 {
     this.blockType = blockType;
     this.isGroup   = isGroup;
     this.selector  = selector;
 }
Esempio n. 5
0
 public Program(Block?body)
 {
     Body = body;
 }
Esempio n. 6
0
 private bool MoveNextRare()
 {
     index   = block.Count + 1;
     current = null;
     return(false);
 }
Esempio n. 7
0
        public async Task <RefundClaimStatus> TryClaimEarlyRefundAsync(DepositDetails deposit, Address refundTo)
        {
            ulong now = _timestamper.EpochSeconds;

            if (!deposit.CanClaimEarlyRefund(now))
            {
                return(RefundClaimStatus.Empty);
            }

            Block?latestBlock = await _blockchainBridge.GetLatestBlockAsync();

            if (latestBlock == null)
            {
                return(RefundClaimStatus.Empty);
            }

            now = (ulong)latestBlock.Timestamp;
            if (!deposit.CanClaimEarlyRefund(now))
            {
                return(RefundClaimStatus.Empty);
            }

            Keccak depositId       = deposit.Deposit.Id;
            Keccak?transactionHash = deposit.ClaimedRefundTransaction?.Hash;

            if (transactionHash is null)
            {
                Address provider = deposit.DataAsset.Provider.Address;
                if (deposit.EarlyRefundTicket == null)
                {
                    throw new InvalidDataException($"Early refund ticket is null on a claimable deposit {depositId}");
                }

                EarlyRefundTicket ticket           = deposit.EarlyRefundTicket;
                EarlyRefundClaim  earlyRefundClaim = new EarlyRefundClaim(ticket.DepositId, deposit.DataAsset.Id,
                                                                          deposit.Deposit.Units, deposit.Deposit.Value, deposit.Deposit.ExpiryTime, deposit.Pepper, provider,
                                                                          ticket.ClaimableAfter, ticket.Signature, refundTo);
                UInt256 gasPrice = await _gasPriceService.GetCurrentAsync();

                transactionHash = await _refundService.ClaimEarlyRefundAsync(refundTo, earlyRefundClaim, gasPrice);

                if (transactionHash is null)
                {
                    if (_logger.IsError)
                    {
                        _logger.Error("There was an error when trying to claim early refund (no transaction hash returned).");
                    }
                    return(RefundClaimStatus.Empty);
                }

                deposit.AddClaimedRefundTransaction(TransactionInfo.Default(transactionHash, 0, gasPrice,
                                                                            _refundService.GasLimit, _timestamper.EpochSeconds));
                await _depositRepository.UpdateAsync(deposit);

                if (_logger.IsInfo)
                {
                    _logger.Info($"Claimed an early refund for deposit: '{depositId}', gas price: {gasPrice} wei, transaction hash: '{transactionHash}' (awaits a confirmation).");
                }
            }

            bool confirmed = await TryConfirmClaimAsync(deposit, "early ");

            return(confirmed
                ? RefundClaimStatus.Confirmed(transactionHash)
                : RefundClaimStatus.Unconfirmed(transactionHash));
        }
Esempio n. 8
0
        private List <TransactionResult> GetTransactions(bool descending)
        {
            Client client = Rpc();

            int minTxsCount = 15;
            List <TransactionResult> result = new();
            int blockNumber = descending ? FromBlock : ToBlock;

            bool condition()
            {
                if (descending)
                {
                    return(blockNumber >= 0);
                }
                return(blockNumber <= (int)TipBlockNumber);
            }

            void stepper()
            {
                if (descending)
                {
                    ToBlock      = blockNumber;
                    blockNumber -= 1;
                }
                else
                {
                    FromBlock    = blockNumber;
                    blockNumber += 1;
                }
            }

            while (condition())
            {
                Block?block = client.GetBlockByNumber((UInt64)blockNumber);
                stepper();
                if (block == null || (block.Transactions.Length <= 1 && blockNumber > 0)) // Filter out cellbase tx
                {
                    continue;
                }

                var txs = block.Transactions.Skip(0).Select(tx =>
                {
                    UInt64 capacityInvolved = GetInputsCapacities(client, tx);

                    return(new TransactionResult()
                    {
                        TransactionHash = tx.Hash ?? "0x",
                        BlockNumber = Hex.HexToUInt64(block.Header.Number).ToString(),
                        BlockTimestamp = Hex.HexToUInt64(block.Header.Timestamp).ToString(),
                        CapacityInvolved = capacityInvolved.ToString(),
                        LiveCellChanges = (tx.Outputs.Length - tx.Inputs.Length).ToString()
                    });
                }).ToList();
                if (descending)
                {
                    result.AddRange(txs);
                }
                else
                {
                    result.InsertRange(0, txs);
                }
                if (result.Count >= minTxsCount)
                {
                    break;
                }
            }
            return(result);
        }
Esempio n. 9
0
        public Task <ResultWrapper <ForkchoiceUpdatedV1Result> > Handle(ForkchoiceStateV1 forkchoiceState, PayloadAttributes?payloadAttributes)
        {
            string requestStr = $"{forkchoiceState} {payloadAttributes}";

            if (_logger.IsInfo)
            {
                _logger.Info($"Received: {requestStr}");
            }

            if (_invalidChainTracker.IsOnKnownInvalidChain(forkchoiceState.HeadBlockHash, out Keccak? lastValidHash))
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($" FCU - Invalid - {requestStr} {forkchoiceState.HeadBlockHash} is known to be a part of an invalid chain.");
                }
                return(ForkchoiceUpdatedV1Result.Invalid(lastValidHash));
            }

            Block?newHeadBlock = GetBlock(forkchoiceState.HeadBlockHash);

            if (newHeadBlock is null) // if a head is unknown we are syncing
            {
                if (_blockCacheService.BlockCache.TryGetValue(forkchoiceState.HeadBlockHash, out Block? block))
                {
                    StartNewBeaconHeaderSync(forkchoiceState, block, requestStr);

                    return(ForkchoiceUpdatedV1Result.Syncing);
                }

                if (_logger.IsInfo)
                {
                    _logger.Info($"Syncing... Unknown forkchoiceState head hash... Request: {requestStr}.");
                }
                return(ForkchoiceUpdatedV1Result.Syncing);
            }

            BlockInfo blockInfo = _blockTree.GetInfo(newHeadBlock.Number, newHeadBlock.GetOrCalculateHash()).Info;

            if (!blockInfo.WasProcessed)
            {
                BlockHeader?blockParent = _blockTree.FindHeader(newHeadBlock.ParentHash !);
                if (blockParent == null)
                {
                    if (_logger.IsDebug)
                    {
                        _logger.Debug($"Parent of block not available. Starting new beacon header. sync.");
                    }

                    StartNewBeaconHeaderSync(forkchoiceState, newHeadBlock !, requestStr);

                    return(ForkchoiceUpdatedV1Result.Syncing);
                }

                if (!blockInfo.IsBeaconMainChain && blockInfo.IsBeaconInfo)
                {
                    ReorgBeaconChainDuringSync(newHeadBlock !, blockInfo);
                }

                int processingQueueCount = _processingQueue.Count;
                if (processingQueueCount == 0)
                {
                    _peerRefresher.RefreshPeers(newHeadBlock !.Hash !, newHeadBlock.ParentHash !, forkchoiceState.FinalizedBlockHash);
                    _blockCacheService.FinalizedHash = forkchoiceState.FinalizedBlockHash;
                    _mergeSyncController.StopBeaconModeControl();

                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Syncing beacon headers... Request: {requestStr}.");
                    }
                }
                else
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Processing {_processingQueue.Count} blocks... Request: {requestStr}.");
                    }
                }

                _beaconPivot.ProcessDestination ??= newHeadBlock !.Header;
                return(ForkchoiceUpdatedV1Result.Syncing);
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"FCU - block {newHeadBlock} was processed.");
            }

            BlockHeader?finalizedHeader = ValidateBlockHash(forkchoiceState.FinalizedBlockHash, out string?finalizationErrorMsg);

            if (finalizationErrorMsg is not null)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid finalized block hash {finalizationErrorMsg}. Request: {requestStr}.");
                }
                return(ForkchoiceUpdatedV1Result.Error(finalizationErrorMsg, MergeErrorCodes.InvalidForkchoiceState));
            }

            ValidateBlockHash(forkchoiceState.SafeBlockHash, out string?safeBlockErrorMsg);
            if (safeBlockErrorMsg is not null)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid safe block hash {finalizationErrorMsg}. Request: {requestStr}.");
                }
                return(ForkchoiceUpdatedV1Result.Error(safeBlockErrorMsg, MergeErrorCodes.InvalidForkchoiceState));
            }

            if ((newHeadBlock.TotalDifficulty ?? 0) != 0 && (_poSSwitcher.MisconfiguredTerminalTotalDifficulty() || _poSSwitcher.BlockBeforeTerminalTotalDifficulty(newHeadBlock.Header)))
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid terminal block. Nethermind TTD {_poSSwitcher.TerminalTotalDifficulty}, NewHeadBlock TD: {newHeadBlock.Header.TotalDifficulty}. Request: {requestStr}.");
                }

                // https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#specification
                // {status: INVALID, latestValidHash: 0x0000000000000000000000000000000000000000000000000000000000000000, validationError: errorMessage | null} if terminal block conditions are not satisfied
                return(ForkchoiceUpdatedV1Result.Invalid(Keccak.Zero));
            }

            Block[]? blocks = EnsureNewHead(newHeadBlock, out string?setHeadErrorMsg);
            if (setHeadErrorMsg is not null)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid new head block {setHeadErrorMsg}. Request: {requestStr}.");
                }
                return(ForkchoiceUpdatedV1Result.Error(setHeadErrorMsg, ErrorCodes.InvalidParams));
            }

            if (_blockTree.IsOnMainChainBehindHead(newHeadBlock))
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Valid. ForkchoiceUpdated ignored - already in canonical chain. Request: {requestStr}.");
                }
                return(ForkchoiceUpdatedV1Result.Valid(null, forkchoiceState.HeadBlockHash));
            }

            EnsureTerminalBlock(forkchoiceState, blocks);

            bool newHeadTheSameAsCurrentHead = _blockTree.Head !.Hash == newHeadBlock.Hash;
            bool shouldUpdateHead            = !newHeadTheSameAsCurrentHead && blocks is not null;

            if (shouldUpdateHead)
            {
                _blockTree.UpdateMainChain(blocks !, true, true);
            }

            if (IsInconsistent(forkchoiceState.FinalizedBlockHash))
            {
                string errorMsg = $"Inconsistent forkchoiceState - finalized block hash. Request: {requestStr}";
                if (_logger.IsWarn)
                {
                    _logger.Warn(errorMsg);
                }
                return(ForkchoiceUpdatedV1Result.Error(errorMsg, MergeErrorCodes.InvalidForkchoiceState));
            }

            if (IsInconsistent(forkchoiceState.SafeBlockHash))
            {
                string errorMsg = $"Inconsistent forkchoiceState - safe block hash. Request: {requestStr}";
                if (_logger.IsWarn)
                {
                    _logger.Warn(errorMsg);
                }
                return(ForkchoiceUpdatedV1Result.Error(errorMsg, MergeErrorCodes.InvalidForkchoiceState));
            }

            bool nonZeroFinalizedBlockHash = forkchoiceState.FinalizedBlockHash != Keccak.Zero;

            // bool nonZeroSafeBlockHash = forkchoiceState.SafeBlockHash != Keccak.Zero;
            if (nonZeroFinalizedBlockHash)
            {
                _manualBlockFinalizationManager.MarkFinalized(newHeadBlock.Header, finalizedHeader !);
            }

            if (shouldUpdateHead)
            {
                _poSSwitcher.ForkchoiceUpdated(newHeadBlock.Header, forkchoiceState.FinalizedBlockHash);
                if (_logger.IsInfo)
                {
                    _logger.Info($"Block {forkchoiceState.HeadBlockHash} was set as head.");
                }
            }

            string?payloadId = null;

            if (payloadAttributes is not null)
            {
                payloadAttributes.GasLimit = null;
                if (newHeadBlock.Timestamp >= payloadAttributes.Timestamp)
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn($"Invalid payload attributes timestamp {payloadAttributes.Timestamp}, block timestamp {newHeadBlock.Timestamp}. Request: {requestStr}.");
                    }

                    return(ForkchoiceUpdatedV1Result.Error(
                               $"Invalid payload attributes timestamp {payloadAttributes.Timestamp}, block timestamp {newHeadBlock.Timestamp}. Request: {requestStr}",
                               MergeErrorCodes.InvalidPayloadAttributes));
                }
                else
                {
                    payloadId = _payloadPreparationService.StartPreparingPayload(newHeadBlock.Header, payloadAttributes);
                }
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"Valid. Request: {requestStr}.");
            }

            _blockTree.ForkChoiceUpdated(forkchoiceState.FinalizedBlockHash, forkchoiceState.SafeBlockHash);
            return(ForkchoiceUpdatedV1Result.Valid(payloadId, forkchoiceState.HeadBlockHash));
        }
Esempio n. 10
0
        public ApplicationEngine?Create(TriggerType trigger, IVerifiable container, DataCache snapshot, Block?persistingBlock, ProtocolSettings settings, long gas)
        {
            if (trigger == TriggerType.Application &&
                container is Transaction tx &&
                tx.Witnesses != null &&
                tx.Witnesses.Length > 0 &&
                EnumerateContractCalls(tx.Script).Any())
            {
                var path = SysIO.Path.Combine(Environment.CurrentDirectory, $"{tx.Hash}.neo-trace");
                var sink = new TraceDebugSink(SysIO.File.OpenWrite(path));
                return(new ExpressApplicationEngine(sink, trigger, container, snapshot, persistingBlock, settings, gas));
            }

            return(null);
        }
Esempio n. 11
0
        public IActionResult OnGet(string?txhash)
        {
            if (txhash == null)
            {
                return(NotFound());
            }

            if (ActiveProject == null)
            {
                return(NotFound());
            }

            Client client = Rpc();

            TransactionWithStatus?transactionWithStatus = client.GetTransaction(txhash);

            if (transactionWithStatus == null)
            {
                return(NotFound());
            }

            Transaction tx = transactionWithStatus.Transaction;

            OutputsData = tx.Outputs.Select((o, i) =>
            {
                o.Data = tx.OutputsData[i];
                try
                {
                    LiveCell?cell = client.GetLiveCell(txhash, (ulong)i);
                    if (cell != null && cell.cell != null)
                    {
                        OutputsDataHash.Add(cell.cell.data.hash);
                    }
                    else
                    {
                        OutputsDataHash.Add("");
                    }
                }
                catch (Exception ex)
                {
                    OutputsDataHash.Add("");
                }
                return(tx.OutputsData[i]);
            }).ToList();


            OutputLockScripts = tx.Outputs.Select((o) => o.Lock).ToList();
            OutputTypeScripts = tx.Outputs.Select <Output, Script?>((o) => o.Type).ToList();

            bool   isCellbase = tx.Inputs[0].PreviousOutput.TxHash == EmptyHash;
            string prefix     = IsMainnet() ? "ckb" : "ckt";

            TransactionDetailResult detail = new()
            {
                IsCellbase = isCellbase,
                Witnesses  = tx.Witnesses,
                CellDeps   = tx.CellDeps.Select(dep =>
                {
                    return(new ApiData.CellDep()
                    {
                        DepType = dep.DepType,
                        OutPoint = new ApiData.OutPoint()
                        {
                            TxHash = dep.OutPoint.TxHash,
                            Index = Hex.HexToUInt32(dep.OutPoint.Index),
                        }
                    });
                }).ToArray(),
                HeaderDeps      = tx.HeaderDeps,
                TxStatus        = transactionWithStatus.TxStatus.Status,
                TransactionHash = txhash,
                TransactionFee  = "0", // "0" for cellbase
                BlockNumber     = "",
                Version         = "",
                BlockTimestamp  = "",
            };

            if (transactionWithStatus.TxStatus.BlockHash != null)
            {
                Block?block = client.GetBlock(transactionWithStatus.TxStatus.BlockHash);
                if (block != null)
                {
                    Header header      = block.Header;
                    UInt64 blockNumber = Hex.HexToUInt64(header.Number);

                    detail.BlockNumber    = blockNumber.ToString();
                    detail.Version        = Hex.HexToUInt32(header.Version).ToString();
                    detail.BlockTimestamp = Hex.HexToUInt64(header.Timestamp).ToString();

                    var(displayInputs, displayOutputs) = GenerateCellbaseDisplayInfos(client, txhash, tx.Outputs, blockNumber, prefix);

                    detail.DisplayInputs  = displayInputs;
                    detail.DisplayOutputs = displayOutputs;
                }
            }

            if (!isCellbase)
            {
                var previousOutputs = GetPreviousOutputs(client, tx.Inputs);

                UInt64 transactionFee = previousOutputs.Select(p => Hex.HexToUInt64(p.Capacity)).Aggregate((sum, cur) => sum + cur) -
                                        tx.Outputs.Select(o => Hex.HexToUInt64(o.Capacity)).Aggregate((sum, cur) => sum + cur);
                detail.TransactionFee = transactionFee.ToString();

                var(displayInputs, displayOutputs) = GenerateNotCellbaseDisplayInfos(tx.Inputs, tx.Outputs, previousOutputs, prefix, txhash, Tokens);
                detail.DisplayInputs  = displayInputs;
                detail.DisplayOutputs = displayOutputs;
            }

            Transaction       = tx;
            TransactionDetail = detail;

            return(Page());
        }
        public TerrainRaycastResult Raycast(Ray ray, bool ignoreNonColliders, float maxDist = float.MaxValue)
        {
            IndexPosition?blockIntersection = null;
            CubeSide?     side          = null;
            float?        intersectDist = null;
            Block?        interBlock    = null;

            bool rayInTheVoidOfSpace = true;
            int  chunkMisses         = 0;

            IndexPosition?lastChunkIndex = null;
            IndexPosition?lastBlockIndex = null;
            Chunk         lastChunk      = null;

            for (int i = 0; i < MAX_TERRAIN_RAY_CHECKS && i < maxDist; i++)
            {
                // Calculate the world position to check
                Vector3       tryWorldPos = ray.Origin + (ray.Direction * i) + Block.HALF_CUBE_3D_SIZE;
                IndexPosition chunkIndex  = Terrain.WorldToChunkCoords(tryWorldPos);

                Chunk inChunk;

                // Check the chunk the ray is in.
                // Only try to get the chunk if the rays chunkIndex moved, or its the first pass
                if (!lastChunkIndex.HasValue || (lastChunk != null && chunkIndex != lastChunkIndex))
                {
                    lastBlockIndex = null;
                    Terrain.IsChunkShaped(Terrain.WorldToChunkCoords(tryWorldPos), out inChunk);
                }
                else
                {
                    inChunk = lastChunk;
                }

                // If we can check this chunk
                if (inChunk != null)
                {
                    rayInTheVoidOfSpace = false;

                    // Calculate the block coordinate to try
                    IndexPosition blockPos = inChunk.BlockToChunkBlockCoords(Chunk.WorldToBlockCoords(tryWorldPos));

                    // If this is the first block checked for this chunk, or the index changed, continue
                    if (!lastBlockIndex.HasValue || blockPos != lastBlockIndex)
                    {
                        bool  blockFound  = false;
                        float closestDist = float.MaxValue;

                        // For a 1 block radius around the block found, see if any
                        // surrounding blocks are intersecting the ray, and are closer
                        // to the ray origin. This prevents the mild error in getting the first
                        // intersecting block, since we are just using block coordinates.
                        for (int x = -1; x <= 1; x++)
                        {
                            for (int y = -1; y <= 1; y++)
                            {
                                for (int z = -1; z <= 1; z++)
                                {
                                    IndexPosition cpos;
                                    Block         type = inChunk.GetBlockSafeFull(blockPos.X + x, blockPos.Y + y, blockPos.Z + z,
                                                                                  out cpos);

                                    if (cpos != inChunk.IndexPosition)
                                    {
                                        continue;
                                    }

                                    if (type != Block.AIR && !ignoreNonColliders ||
                                        type.HasCollision())
                                    {
                                        // Calculate the new blocks positions
                                        IndexPosition newIndexPos  = blockPos + new IndexPosition(x, y, z);
                                        Vector3       cubeWorldPos = inChunk.Position
                                                                     + (newIndexPos * Block.CUBE_3D_SIZE) - Block.HALF_CUBE_3D_SIZE;

                                        // If this blocks distance is smaller than the current, continue
                                        float dist = Maths.DistanceSquared(cubeWorldPos, ray.Origin);
                                        if (dist < closestDist)
                                        {
                                            AxisAlignedBoundingBox aabb =
                                                new AxisAlignedBoundingBox(cubeWorldPos, cubeWorldPos + Block.CUBE_3D_SIZE);

                                            // If this block intersects the ray,
                                            // it is the newly intersected block.
                                            float?   interDist;
                                            CubeSide interSide;
                                            if (ray.Intersects(aabb, out interDist, out interSide))
                                            {
                                                closestDist       = dist;
                                                side              = interSide;
                                                blockFound        = true;
                                                blockIntersection = newIndexPos;
                                                intersectDist     = interDist;
                                                interBlock        = type;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        // If any block was found to actually intersect the ray
                        // by here, the closest block was set so just set the chunk
                        // and return.
                        if (blockFound)
                        {
                            Vector3 interPosition = ray.Origin + ray.Direction * intersectDist.Value;
                            return(new TerrainRaycastResult(ray, true, interPosition, intersectDist,
                                                            inChunk, blockIntersection, interBlock, side));
                        }
                    }

                    lastBlockIndex = blockPos;
                }
                // If the ray missed to many chunks then stop checking because this means the rest of the ray
                // is shooting out into empty space
                else if (!rayInTheVoidOfSpace && chunkMisses++ > MAX_TERRAIN_CHUNK_MISSES)
                {
                    break;
                }

                lastChunk = inChunk;
                if (lastChunk != null)
                {
                    lastChunkIndex = chunkIndex;
                }
                else
                {
                    lastChunkIndex = null;
                }
            }

            // No intersection at this point
            return(new TerrainRaycastResult(ray));
        }
Esempio n. 13
0
 private TryStatement(TryStatementType tryStatementType, Block tryBlock, bool isStrictMode, Block?catchBlock, Block?finallyBlock, Identifier?catchParameter = null) : base(isStrictMode)
 {
     this.tryStatementType = tryStatementType;
     this.tryBlock         = tryBlock;
     this.catchBlock       = catchBlock;
     this.finallyBlock     = finallyBlock;
     this.catchParameter   = catchParameter;
     hasCatchParameter     = catchParameter != null;
 }
Esempio n. 14
0
        protected override void Update(GameTime gameTime)
        {
            KeyboardState currentState = Keyboard.GetState();

            debugInformation.Visible = showDebugInformation;

            Vector2 mpos = camera.GetMousePositionInWorld();

            Block?underMouse = world.GetBlockAtPosition((int)Math.Floor(mpos.X), (int)Math.Floor(mpos.Y));

            debugInformation.Show();
            debugInformation.Text
                = "Loaded chunks: " + world.LoadedChunks.GetLoadedChunkNumber()
                  + "\nVisible chunks: " + world.LoadedChunks.GetVisibleChunkNumber()
                  + "\nLoaded Megachunks: " + world.GetNumberOfLoadedMegachunks()
                  + "\nMemory usage: " + Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024 + "MB"
                  + "\nMouse position (World space): " + mpos.X + ", " + mpos.Y
                  + "\nMouse position (Block): " + Math.Floor(mpos.X) + ", " + Math.Floor(mpos.Y)
                  + "\nMouse position (Chunk): " + Math.Floor(mpos.X / Chunk.SIZE) + ", " + Math.Floor(mpos.Y / Chunk.SIZE)
                  + "\nMouse position (Megachunk): " + Math.Floor(mpos.X / Chunk.SIZE / Megachunk.SIZE) + ", " + Math.Floor(mpos.Y / Chunk.SIZE / Megachunk.SIZE)
                  + "\nCamera zoom: " + camera.zoom
                  + "\nCamera position (Center): " + camera.center.X + ", " + camera.center.Y
                  + "\nBlock under mouse: " + underMouse;

            if (currentState.IsKeyDown(Keys.LeftAlt))
            {
                world.SetBlockAtPosition((int)Math.Floor(mpos.X), (int)Math.Floor(mpos.Y), BlockType.Stone, 0);
            }

            if (!lastState.IsKeyDown(Keys.L) && currentState.IsKeyDown(Keys.L))
            {
                enableLighting = !enableLighting;
            }

            if (!lastState.IsKeyDown(Keys.P) && currentState.IsKeyDown(Keys.P))
            {
                Mob human = (Mob)EntityManager.Spawn(EntityType.Human);
                human.Position.Y = -10;
                human.Position.X = 10;
                world.AddEntity(human);
                player = new Player(human);
            }


            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || currentState.IsKeyDown(Keys.Escape))
            {
                Exit();
            }

            if (currentState.IsKeyDown(Keys.S))
            {
                camera.zoom -= 0.01f;
            }
            if (currentState.IsKeyDown(Keys.W))
            {
                camera.zoom += 0.01f;
            }

            player?.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
            if (player != null)
            {
                camera.Update(player.Position);
            }

            RectF rect = camera.GetRect();

            world.Update(gameTime, rect.X, rect.Y, rect.Width, rect.Height);

            if (player != null)
            {
                camera.Update(player.Position);
            }

            lastState = currentState;

            base.Update(gameTime);
        }
Esempio n. 15
0
 public int Compare(Block?x, Block?y)
 {
     return(comparison(x !, y !));
 }
Esempio n. 16
0
        public async Task <RefundClaimStatus> TryClaimRefundAsync(DepositDetails deposit, Address refundTo)
        {
            ulong now = _timestamper.UnixTime.Seconds;

            if (!deposit.CanClaimRefund(now))
            {
                DisplayRefundInfo(deposit, now);
                return(RefundClaimStatus.Empty);
            }

            Block?latestBlock = await _blockchainBridge.GetLatestBlockAsync();

            if (latestBlock == null)
            {
                return(RefundClaimStatus.Empty);
            }

            now = (ulong)latestBlock.Timestamp;
            if (!deposit.CanClaimRefund(now))
            {
                DisplayRefundInfo(deposit, now);
                return(RefundClaimStatus.Empty);
            }

            Keccak depositId       = deposit.Deposit.Id;
            Keccak?transactionHash = deposit.ClaimedRefundTransaction?.Hash;

            if (transactionHash is null)
            {
                Address     provider    = deposit.DataAsset.Provider.Address;
                RefundClaim refundClaim = new RefundClaim(depositId, deposit.DataAsset.Id, deposit.Deposit.Units,
                                                          deposit.Deposit.Value, deposit.Deposit.ExpiryTime, deposit.Pepper, provider, refundTo);
                UInt256 gasPrice = await _gasPriceService.GetCurrentRefundGasPriceAsync();

                transactionHash = await _refundService.ClaimRefundAsync(refundTo, refundClaim, gasPrice);

                if (transactionHash is null)
                {
                    if (_logger.IsError)
                    {
                        _logger.Error("There was an error when trying to claim refund (no transaction hash returned).");
                    }
                    return(RefundClaimStatus.Empty);
                }

                deposit.AddClaimedRefundTransaction(TransactionInfo.Default(transactionHash, 0, gasPrice,
                                                                            _refundService.GasLimit, _timestamper.UnixTime.Seconds));
                await _depositRepository.UpdateAsync(deposit);

                if (_logger.IsInfo)
                {
                    _logger.Info($"Claimed a refund for deposit: '{depositId}', gas price: {gasPrice} wei, transaction hash: '{transactionHash}' (awaits a confirmation).");
                }
            }

            bool confirmed = await TryConfirmClaimAsync(deposit, string.Empty);

            return(confirmed
                ? RefundClaimStatus.Confirmed(transactionHash)
                : RefundClaimStatus.Unconfirmed(transactionHash));
        }
Esempio n. 17
0
 internal Enumerator(ContainerBlock block)
 {
     this.block = block;
     index      = 0;
     current    = null;
 }
Esempio n. 18
0
        public void GenTrees(World world, Vector3i gridPosition)
        {
            const int treeHeight = 5;

            var airId    = (byte)BlockType.GetIdByName("air");
            var woodId   = (byte)BlockType.GetIdByName("wood");
            var leavesId = (byte)BlockType.GetIdByName("leaves");

            var grid = world.GetGridAt(gridPosition);

            if (grid == null)
            {
                return;
            }

            for (int i = 0; i < grid.Width; ++i)
            {
                for (int k = 0; k < grid.Length; ++k)
                {
                    int x = GRID_SIZE * gridPosition.X + i;
                    int z = GRID_SIZE * gridPosition.Z + k;

                    var position = new Vector2i(x, z);
                    int height   = GetHeightAt(position);
                    if (height < GRID_SIZE * gridPosition.Y || height > GRID_SIZE * (gridPosition.Y + 1) || height <= SEA_LEVEL)
                    {
                        continue;
                    }

                    float probability = GetTreeAt(position);
                    bool  placeTree   = probability > GetTreeAt(position - Vector2i.UnitX) && probability > GetTreeAt(position + Vector2i.UnitX) &&
                                        probability > GetTreeAt(position - Vector2i.UnitY) && probability > GetTreeAt(position + Vector2i.UnitY) &&
                                        probability > GetTreeAt(position - Vector2i.One) && probability > GetTreeAt(position + Vector2i.One);

                    if (placeTree)
                    {
                        for (int j = 0; j < treeHeight; ++j)
                        {
                            Vector3i blockPosition = new Vector3i(x, height + j, z);
                            Block?   block         = world.GetBlockAt(blockPosition);
                            if (!block.HasValue || block.Value.BlockTypeId == airId)
                            {
                                world.SetBlockAt(blockPosition, new Block(woodId));
                            }
                        }

                        for (int ii = -2; ii <= 2; ++ii)
                        {
                            for (int kk = -2; kk <= 2; ++kk)
                            {
                                int leavesMinHeight = ii == 0 && kk == 0 ? treeHeight : 3;
                                int leavesMaxHeight = Math.Abs(ii) == 2 || Math.Abs(kk) == 2
                                    ? treeHeight
                                    : Math.Abs(ii) == 0 || Math.Abs(kk) == 0
                                        ? treeHeight + 2
                                        : treeHeight + 1;

                                for (int j = leavesMinHeight; j < leavesMaxHeight; ++j)
                                {
                                    Vector3i blockPosition = new Vector3i(x + ii, height + j, z + kk);
                                    Block?   block         = world.GetBlockAt(blockPosition);
                                    if (!block.HasValue || block.Value.BlockTypeId == airId)
                                    {
                                        world.SetBlockAt(blockPosition, new Block(leavesId));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 19
0
 void IEnumerator.Reset()
 {
     index   = 0;
     current = null;
 }
Esempio n. 20
0
        public GethLikeTxTrace[] TraceBlock(long blockNumber, GethTraceOptions options, CancellationToken cancellationToken)
        {
            Block?block = _blockTree.FindBlock(blockNumber, BlockTreeLookupOptions.RequireCanonical);

            return(TraceBlock(block, options, cancellationToken));
        }
 public BlockReplacementEventArgs(Block block, Block?previousBlock = null) : base(block)
 {
     PreviousBlock = previousBlock;
 }
        public HandshakeTerrainData(Terrain terrain, int maxSectionSize)
        {
            byte[] finalData;
            byte[] uncompressed;

            using (MemoryStream ms = new MemoryStream())
                using (BinaryWriter writer = new BinaryWriter(ms))
                {
                    writer.Write((ushort)terrain.Chunks.Count);
                    foreach (Chunk chunk in terrain.Chunks.Values)
                    {
                        writer.Write((byte)0);
                        writer.Write((short)chunk.IndexPosition.X);
                        writer.Write((short)chunk.IndexPosition.Y);
                        writer.Write((short)chunk.IndexPosition.Z);

                        Block?lastBlock = null;
                        int   numRead   = 0;

                        for (int x = 0; x < chunk.Width; x++)
                        {
                            for (int y = 0; y < chunk.Height; y++)
                            {
                                for (int z = 0; z < chunk.Depth; z++)
                                {
                                    Block block      = chunk.Blocks[z, y, x];
                                    bool  blocksDiff = lastBlock.HasValue ? BlocksDifferent(block, lastBlock.Value) : true;

                                    if (blocksDiff)
                                    {
                                        Block b = lastBlock ?? block;
                                        WriteBlocks(writer, b, numRead);
                                        numRead = 0;
                                    }

                                    numRead++;
                                    lastBlock = block;
                                }
                            }
                        }

                        if (numRead > 0)
                        {
                            WriteBlocks(writer, lastBlock.Value, numRead);
                        }
                    }

                    uncompressed = ms.ToArray();
                }

            using (MemoryStream finalStream = new MemoryStream())
            {
                using (GZipStream zip = new GZipStream(finalStream, CompressionMode.Compress))
                    using (MemoryStream ms = new MemoryStream(uncompressed))
                        ms.CopyTo(zip);

                finalData = finalStream.ToArray();
            }

            int numSections = (int)Math.Ceiling(finalData.Length / (float)maxSectionSize);

            Sections = new byte[numSections][];

            UncompressedSize = uncompressed.Length;
            TotalPacketSize  = finalData.Length;
            int bytesLeft = finalData.Length;
            int pos       = 0;

            for (int i = 0; i < numSections; i++)
            {
                int sectionSize = Math.Min(bytesLeft, maxSectionSize);
                Sections[i] = new byte[sectionSize];
                Buffer.BlockCopy(finalData, pos, Sections[i], 0, sectionSize);
                bytesLeft -= sectionSize;
                pos       += sectionSize;
            }
        }
Esempio n. 23
0
 public Block(Token token, Block?parent)
 {
     Parent = parent;
 }
Esempio n. 24
0
        private void TimerOnElapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                if (_blockTree.Head == null)
                {
                    _timer.Enabled = true;
                    return;
                }

                Block?scheduledBlock = _scheduledBlock;
                if (scheduledBlock == null)
                {
                    if (_blockTree.Head.Timestamp + _config.BlockPeriod < _timestamper.EpochSeconds)
                    {
                        _signalsQueue.Add(_blockTree.FindBlock(_blockTree.Head.Hash, BlockTreeLookupOptions.None));
                    }

                    _timer.Enabled = true;
                    return;
                }

                string turnDescription = scheduledBlock.IsInTurn() ? "IN TURN" : "OUT OF TURN";

                int wiggle = _wiggle.WiggleFor(scheduledBlock.Header);
                if (scheduledBlock.Timestamp * 1000 + (UInt256)wiggle < _timestamper.EpochMilliseconds)
                {
                    if (scheduledBlock.TotalDifficulty > _blockTree.Head.TotalDifficulty)
                    {
                        if (ReferenceEquals(scheduledBlock, _scheduledBlock))
                        {
                            BlockHeader parent       = _blockTree.FindParentHeader(scheduledBlock.Header, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
                            Address     parentSigner = _snapshotManager.GetBlockSealer(parent);

                            string parentTurnDescription = parent.IsInTurn() ? "IN TURN" : "OUT OF TURN";
                            string parentDetails         = $"{parentTurnDescription} {parent.TimestampDate:HH:mm:ss} {parent.ToString(BlockHeader.Format.Short)} sealed by {KnownAddresses.GetDescription(parentSigner)}";

                            if (_logger.IsInfo)
                            {
                                _logger.Info($"Suggesting own {turnDescription} {_scheduledBlock.TimestampDate:HH:mm:ss} {scheduledBlock.ToString(Block.Format.HashNumberDiffAndTx)} based on {parentDetails} after the delay of {wiggle}");
                            }
                            _blockTree.SuggestBlock(scheduledBlock);
                        }
                    }
                    else
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Dropping a losing block {scheduledBlock.ToString(Block.Format.HashNumberDiffAndTx)}");
                        }
                    }

                    if (ReferenceEquals(scheduledBlock, _scheduledBlock))
                    {
                        _scheduledBlock = null;
                    }
                }
                else
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Not yet {scheduledBlock.ToString(Block.Format.HashNumberDiffAndTx)}");
                    }
                }

                _timer.Enabled = true;
            }
            catch (Exception exception)
            {
                if (_logger.IsError)
                {
                    _logger.Error("Clique block producer failure", exception);
                }
            }
        }
        private void BeamProcess(Block block)
        {
            if (block.TotalDifficulty == null)
            {
                throw new InvalidDataException(
                          $"Received a block with null {nameof(block.TotalDifficulty)} for beam processing");
            }

            CancellationTokenSource cancellationToken;

            lock (_tokens)
            {
                cancellationToken = _tokens.GetOrAdd(block.Number, t => new CancellationTokenSource());
                if (_isDisposed)
                {
                    return;
                }
            }

            Task beamProcessingTask = Task.CompletedTask;
            Task prefetchTasks      = Task.CompletedTask;

            try
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Beam processing block {block}");
                }
                _recoveryStep.RecoverData(block);
                (IBlockchainProcessor beamProcessor, IStateReader stateReader) = CreateProcessor(block, new ReadOnlyDbProvider(_readOnlyDbProvider, true), _specProvider, _logManager);

                BlockHeader parentHeader = _readOnlyBlockTree.FindHeader(block.ParentHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
                if (parentHeader != null)
                {
                    // TODO: is author / beneficiary always resolved here
                    prefetchTasks = PrefetchNew(stateReader, block, parentHeader.StateRoot !, parentHeader.Author ?? parentHeader.Beneficiary !);
                }

                Stopwatch stopwatch      = Stopwatch.StartNew();
                Block?    processedBlock = null;
                beamProcessingTask = Task.Run(() =>
                {
                    BeamSyncContext.MinimumDifficulty.Value = block.TotalDifficulty.Value;
                    BeamSyncContext.Description.Value       = $"[preProcess of {block.Hash!.ToShortString()}]";
                    BeamSyncContext.LastFetchUtc.Value      = DateTime.UtcNow;
                    BeamSyncContext.Cancelled.Value         = cancellationToken.Token;
                    processedBlock = beamProcessor.Process(block, ProcessingOptions.Beam, NullBlockTracer.Instance);
                    stopwatch.Stop();
                    if (processedBlock == null)
                    {
                        if (_logger.IsDebug)
                        {
                            _logger.Debug($"Block {block.ToString(Block.Format.Short)} skipped in beam sync");
                        }
                    }
                    else
                    {
                        Interlocked.Increment(ref Metrics.BeamedBlocks);
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Successfully beam processed block {processedBlock.ToString(Block.Format.Short)} in {stopwatch.ElapsedMilliseconds}ms");
                        }
                    }
                }).ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Stopped processing block {block} | {t.Exception?.Flatten().InnerException?.Message}");
                        }
                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"Details of beam sync failure {block} | {t.Exception}");
                        }
                        return;
                    }

                    if (processedBlock != null)
                    {
                        // if (_logger.IsDebug) _logger.Debug($"Running standard processor after beam sync for {block}");
                        // at this stage we are sure to have all the state available
                        CancelPreviousBeamSyncingBlocks(processedBlock.Number);

                        // do I even need this?
                        // do I even need to process any of these blocks or just leave the RPC available
                        // (based on user expectations they may need to trace or just query balance)

                        // soo - there should be a separate beam queue that we can wait for to finish?
                        // then we can ensure that it finishes before the normal queue fires
                        // and so they never hit the wrong databases?
                        // but, yeah, we do not even need to process it twice
                        // we can just announce that we have finished beam processing here...
                        // _standardProcessorQueue.Enqueue(block, ProcessingOptions.Beam);
                        // I only needed it in the past when I wanted to actually store the beam data
                        // now I can generate the witness on the fly and transfer the witness to the right place...
                        // OK, seems fine
                    }

                    beamProcessor.Dispose();
                });
            }
            catch (Exception e)
            {
                if (_logger.IsError)
                {
                    _logger.Error($"Block {block.ToString(Block.Format.Short)} failed processing and it will be skipped from beam sync", e);
                }
            }

            _beamProcessTasks.Add(Task.WhenAll(beamProcessingTask, prefetchTasks));

            long number = block.Number;

            CancelOldBeamTasks(number);
        }
Esempio n. 26
0
        private void ConsumeSignal()
        {
            foreach (Block signal in _signalsQueue.GetConsumingEnumerable(_cancellationTokenSource.Token))
            {
                Block parentBlock = signal;
                while (_signalsQueue.TryTake(out Block? nextSignal))
                {
                    if (parentBlock.Number <= nextSignal.Number)
                    {
                        parentBlock = nextSignal;
                    }
                }

                try
                {
                    Block?block = PrepareBlock(parentBlock);
                    if (block is null)
                    {
                        if (_logger.IsTrace)
                        {
                            _logger.Trace("Skipping block production or block production failed");
                        }
                        continue;
                    }

                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Processing prepared block {block.Number}");
                    }
                    Block processedBlock = _processor.Process(block, ProcessingOptions.NoValidation | ProcessingOptions.ReadOnlyChain | ProcessingOptions.WithRollback, NullBlockTracer.Instance);
                    if (processedBlock == null)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Prepared block has lost the race");
                        }
                        continue;
                    }

                    if (_logger.IsDebug)
                    {
                        _logger.Debug($"Sealing prepared block {processedBlock.Number}");
                    }

                    _sealer.SealBlock(processedBlock, _cancellationTokenSource.Token).ContinueWith(t =>
                    {
                        if (t.IsCompletedSuccessfully)
                        {
                            if (t.Result != null)
                            {
                                if (_logger.IsInfo)
                                {
                                    _logger.Info($"Sealed block {t.Result.ToString(Block.Format.HashNumberDiffAndTx)}");
                                }
                                _scheduledBlock = t.Result;
                            }
                            else
                            {
                                if (_logger.IsInfo)
                                {
                                    _logger.Info($"Failed to seal block {processedBlock.ToString(Block.Format.HashNumberDiffAndTx)} (null seal)");
                                }
                            }
                        }
                        else if (t.IsFaulted)
                        {
                            if (_logger.IsError)
                            {
                                _logger.Error("Mining failed", t.Exception);
                            }
                        }
                        else if (t.IsCanceled)
                        {
                            if (_logger.IsInfo)
                            {
                                _logger.Info($"Sealing block {processedBlock.Number} cancelled");
                            }
                        }
                    }, _cancellationTokenSource.Token);
                }
                catch (Exception e)
                {
                    if (_logger.IsError)
                    {
                        _logger.Error($"Block producer could not produce block on top of {parentBlock.ToString(Block.Format.Short)}", e);
                    }
                }
            }
        }
Esempio n. 27
0
 public void StartNewBlockTrace(Block block)
 {
     _block = block;
 }
Esempio n. 28
0
        private async Task <(uint confirmations, bool rejected)> VerifyDepositConfirmationsAsync(DepositDetails deposit,
                                                                                                 NdmTransaction transaction, long headNumber)
        {
            if (headNumber <= transaction.BlockNumber)
            {
                return(0, false);
            }

            Keccak?transactionHash = deposit.Transaction?.Hash;
            uint   confirmations   = 0u;
            Block? block           = await _blockchainBridge.FindBlockAsync(headNumber);

            do
            {
                if (block is null)
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn("Block was not found.");
                    }
                    return(0, false);
                }

                uint confirmationTimestamp = await _depositService.VerifyDepositAsync(deposit.Consumer, deposit.Id, block.Header.Number);

                if (confirmationTimestamp > 0)
                {
                    confirmations++;
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Deposit: '{deposit.Id}' has been confirmed in block number: {block.Number}, hash: '{block.Hash}', transaction hash: '{transactionHash}', timestamp: {confirmationTimestamp}.");
                    }
                    if (deposit.ConfirmationTimestamp == 0)
                    {
                        deposit.SetConfirmationTimestamp(confirmationTimestamp);
                        await _depositRepository.UpdateAsync(deposit);
                    }
                }
                else
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Deposit with id: '{deposit.Id}' has not returned confirmation timestamp from the contract call yet.'");
                    }
                    return(0, false);
                }

                if (confirmations == _requiredBlockConfirmations)
                {
                    break;
                }

                if (transaction.BlockHash == block.Hash || block.Number <= transaction.BlockNumber)
                {
                    break;
                }

                block = await _blockchainBridge.FindBlockAsync(block.ParentHash);
            } while (confirmations < _requiredBlockConfirmations);

            long latestBlockNumber = await _blockchainBridge.GetLatestBlockNumberAsync();

            long?blocksDifference = latestBlockNumber - transaction.BlockNumber;

            if (blocksDifference >= _requiredBlockConfirmations && confirmations < _requiredBlockConfirmations)
            {
                if (_logger.IsError)
                {
                    _logger.Error($"Deposit: '{deposit.Id}' has been rejected - missing confirmation in block number: {block!.Number}, hash: {block!.Hash}' (transaction hash: '{transactionHash}').");
                }
                return(confirmations, true);
            }

            return(confirmations, false);
        }
Esempio n. 29
0
        public bool MatchBranch(Block?targetBlock)
        {
            var inst = this as Branch;

            return(inst != null && inst.TargetBlock == targetBlock);
        }
Esempio n. 30
0
 /// <summary>
 /// Renders the web block.
 /// </summary>
 /// <param name="block">The block data.</param>
 /// <returns>The rendered block.</returns>
 public Task <IViewComponentResult> InvokeAsync(Block block)
 {
     this.Block = block;
     return(this.Render());
 }