public async Task Execute(CancellationToken _) { _initConfig = _api.Config <IInitConfig>(); Keccak?expectedGenesisHash = string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash); if (_api.BlockTree == null) { throw new StepDependencyException(); } // if we already have a database with blocks then we do not need to load genesis from spec if (_api.BlockTree.Genesis == null) { Load(); } ValidateGenesisHash(expectedGenesisHash); if (!_initConfig.ProcessingEnabled) { if (_logger.IsWarn) { _logger.Warn($"Shutting down the blockchain processor due to {nameof(InitConfig)}.{nameof(InitConfig.ProcessingEnabled)} set to false"); } await(_api.BlockchainProcessor?.StopAsync() ?? Task.CompletedTask); } }
public static ResultWrapper <ForkchoiceUpdatedV1Result> Invalid(Keccak?latestValidHash, string?validationError = null) => ResultWrapper <ForkchoiceUpdatedV1Result> .Success(new ForkchoiceUpdatedV1Result { PayloadStatus = new PayloadStatusV1 { Status = Data.V1.PayloadStatus.Invalid, LatestValidHash = latestValidHash, ValidationError = validationError } });
public async Task <PaymentsValueSummary> GetPaymentsSummary(Keccak?depositId = null, Keccak?assetId = null, Address?consumer = null) { var values = await Query(depositId, assetId, consumer) .Select(c => new { c.ClaimedValue, c.Income, c.Status }) .ToListAsync(); if (values.Count == 0) { return(PaymentsValueSummary.Empty); } var claimed = UInt256.Zero; var pending = UInt256.Zero; var income = UInt256.Zero; foreach (var value in values) { if (value.Status == PaymentClaimStatus.Claimed) { claimed += value.ClaimedValue; income += value.Income; } else { pending += value.ClaimedValue; } } return(new PaymentsValueSummary(claimed, pending, income)); }
public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak?stateRoot = null) { Success = false; Error = error; Output = output; }
private IMongoQueryable <PaymentClaim> Query(Keccak?depositId = null, Keccak?assetId = null, Address?consumer = null, bool onlyUnclaimed = false, bool onlyPending = false) { var paymentClaims = PaymentClaims.AsQueryable(); if (!(depositId is null)) { paymentClaims = paymentClaims.Where(c => c.DepositId == depositId); } if (!(assetId is null)) { paymentClaims = paymentClaims.Where(c => c.AssetId == assetId); } if (!(consumer is null)) { paymentClaims = paymentClaims.Where(c => c.Consumer == consumer); } if (onlyUnclaimed) { paymentClaims = paymentClaims.Where(c => c.Status != PaymentClaimStatus.Claimed && c.Status != PaymentClaimStatus.ClaimedWithLoss); } if (onlyPending) { paymentClaims = paymentClaims.Where(c => c.Transaction != null && c.Transaction.State == TransactionState.Pending && c.Status == PaymentClaimStatus.Sent); } return(paymentClaims.OrderByDescending(c => c.Timestamp)); }
public TransactionForRpc(Keccak?blockHash, long?blockNumber, int?txIndex, Transaction transaction) { Hash = transaction.Hash; Nonce = transaction.Nonce; BlockHash = blockHash; BlockNumber = blockNumber; TransactionIndex = txIndex; From = transaction.SenderAddress; To = transaction.To; Value = transaction.Value; GasPrice = transaction.GasPrice; Gas = transaction.GasLimit; Input = Data = transaction.Data; Type = transaction.Type; AccessList = transaction.AccessList is null ? null : AccessListItemForRpc.FromAccessList(transaction.AccessList); Signature?signature = transaction.Signature; if (signature != null) { R = new UInt256(signature.R, true); S = new UInt256(signature.S, true); V = (UInt256?)signature.V; } }
private List <Keccak> MakeChain(int n, bool connectInReverse = false) { Keccak? prev = null; List <Keccak> hashList = new(); for (int i = 0; i < n; i++) { Keccak newHash = Keccak.Compute(Random.Shared.NextInt64().ToString()); hashList.Add(newHash); } if (connectInReverse) { for (int i = hashList.Count - 2; i >= 0; i--) { _tracker.SetChildParent(hashList[i + 1], hashList[i]); } } else { for (int i = 0; i < hashList.Count - 1; i++) { _tracker.SetChildParent(hashList[i + 1], hashList[i]); } } return(hashList); }
public Task <PaymentsValueSummary> GetPaymentsSummary(Keccak?depositId = null, Keccak?assetId = null, Address?consumer = null) { var paymentClaims = GetAll(); if (paymentClaims.Length == 0) { return(Task.FromResult(PaymentsValueSummary.Empty)); } var values = Query(paymentClaims.AsEnumerable(), depositId, assetId, consumer) .Select(c => new { c.ClaimedValue, c.Income, c.Status }); var claimed = UInt256.Zero; var pending = UInt256.Zero; var income = UInt256.Zero; foreach (var value in values) { if (value.Status == PaymentClaimStatus.Claimed) { claimed += value.ClaimedValue; income += value.Income; } else { pending += value.ClaimedValue; } } return(Task.FromResult(new PaymentsValueSummary(claimed, pending, income))); }
public bool TryUpdateTerminalBlock(BlockHeader header) { if (_terminalBlockExplicitSpecified || TransitionFinished || !header.IsTerminalBlock(_specProvider)) { return(false); } _terminalBlockNumber = header.Number; _terminalBlockHash = header.Hash; _metadataDb.Set(MetadataDbKeys.TerminalPoWNumber, Rlp.Encode(_terminalBlockNumber.Value).Bytes); _metadataDb.Set(MetadataDbKeys.TerminalPoWHash, Rlp.Encode(_terminalBlockHash).Bytes); _firstPoSBlockNumber = header.Number + 1; _specProvider.UpdateMergeTransitionInfo(_firstPoSBlockNumber.Value); if (_hasEverReachedTerminalDifficulty == false) { TerminalBlockReached?.Invoke(this, EventArgs.Empty); _hasEverReachedTerminalDifficulty = true; if (_logger.IsInfo) { _logger.Info($"Reached terminal block {header}"); } } else { if (_logger.IsInfo) { _logger.Info($"Updated terminal block {header}"); } } return(true); }
private ConsumerSession[] Filter( Keccak?depositId = null, Keccak?dataAssetId = null, PublicKey?consumerNodeId = null, Address?consumerAddress = null, PublicKey?providerNodeId = null, Address?providerAddress = null) { byte[][] sessionsBytes = _database.GetAllValues().ToArray(); if (sessionsBytes.Length == 0) { return(Array.Empty <ConsumerSession>()); } ConsumerSession[] sessions = new ConsumerSession[sessionsBytes.Length]; for (int i = 0; i < sessionsBytes.Length; i++) { sessions[i] = Decode(sessionsBytes[i]); } if (depositId is null && dataAssetId is null && consumerNodeId is null && consumerAddress is null && providerNodeId is null && providerAddress is null) { return(sessions); } IEnumerable <ConsumerSession> filteredSessions = sessions.AsEnumerable(); if (!(depositId is null)) { filteredSessions = filteredSessions.Where(s => s.DepositId == depositId); } if (!(dataAssetId is null)) { filteredSessions = filteredSessions.Where(s => s.DataAssetId == dataAssetId); } if (!(consumerNodeId is null)) { filteredSessions = filteredSessions.Where(s => s.ConsumerNodeId == consumerNodeId); } if (!(consumerAddress is null)) { filteredSessions = filteredSessions.Where(s => s.ConsumerAddress == consumerAddress); } if (!(providerNodeId is null)) { filteredSessions = filteredSessions.Where(s => s.ProviderNodeId == providerNodeId); } if (!(providerAddress is null)) { filteredSessions = filteredSessions.Where(s => s.ProviderAddress == providerAddress); } return(filteredSessions.OrderByDescending(s => s.StartTimestamp).ToArray()); }
public static ResultWrapper <PayloadStatusV1> Valid(Keccak?latestValidHash) { return(ResultWrapper <PayloadStatusV1> .Success(new PayloadStatusV1() { Status = PayloadStatus.Valid, LatestValidHash = latestValidHash })); }
public static ResultWrapper <PayloadStatusV1> Invalid(Keccak?latestValidHash, string?validationError = null) { return(ResultWrapper <PayloadStatusV1> .Success(new PayloadStatusV1() { Status = PayloadStatus.Invalid, LatestValidHash = latestValidHash, ValidationError = validationError })); }
public async Task payment_claim_should_not_be_sent_while_units_are_less_than_units_range_to() { var unitsRange = new UnitsRange(0, 5); var paymentClaim = new PaymentClaim(id: Keccak.Zero, depositId: Keccak.Zero, assetId: Keccak.Zero, assetName: "test", units: 3, claimedUnits: 3, unitsRange: unitsRange, value: 10, claimedValue: 30, expiryTime: 10, pepper: Array.Empty <byte>(), provider: TestItem.AddressA, consumer: TestItem.AddressB, signature: new Signature(1, 2, 37), timestamp: 12, transactions: Array.Empty <TransactionInfo>(), status: PaymentClaimStatus.Unknown ); Keccak?transactionHash = await _processor.SendTransactionAsync(paymentClaim, 10); Assert.IsNull(transactionHash); Assert.IsTrue(paymentClaim.Status != PaymentClaimStatus.Sent); }
public async Task <RefundClaimStatus> TryClaimRefundAsync(DepositDetails deposit, Address refundTo) { ulong now = _timestamper.EpochSeconds; if (!deposit.CanClaimRefund(now)) { return(RefundClaimStatus.Empty); } Block?latestBlock = await _blockchainBridge.GetLatestBlockAsync(); if (latestBlock == null) { return(RefundClaimStatus.Empty); } now = (ulong)latestBlock.Timestamp; if (!deposit.CanClaimRefund(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.GetCurrentAsync(); 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.EpochSeconds)); 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)); }
public FaucetRequestDetailsForRpc(string?host, Address?address, UInt256?value, DateTime?date, Keccak?transactionHash) { Host = host; Address = address; Value = value; Date = date; TransactionHash = transactionHash; }
public NdmTransaction(Transaction transaction, bool isPending, long?blockNumber, Keccak?blockHash, long?gasUsed) { Transaction = transaction; IsPending = isPending; BlockNumber = blockNumber; BlockHash = blockHash; GasUsed = gasUsed; }
public async Task <UpdatedTransactionInfo> CancelPaymentClaimAsync(Keccak paymentClaimId) { (UpdatedTransactionStatus status, PaymentClaim? paymentClaim) = await TryGetPaymentClaimAsync(paymentClaimId, "cancel"); if (status != UpdatedTransactionStatus.Ok) { return(new UpdatedTransactionInfo(status)); } TransactionInfo?currentTransaction = paymentClaim !.Transaction; if (currentTransaction == null) { if (_logger.IsError) { _logger.Error($"Cannot cancel missing transaction for payment claim with id: '{paymentClaim!.Id}'."); } return(new UpdatedTransactionInfo(UpdatedTransactionStatus.MissingTransaction)); } Keccak?hash = currentTransaction.Hash; if (hash == null) { if (_logger.IsError) { _logger.Error($"Cannot cancel missing transaction for payment claim with id: '{paymentClaim!.Id}'."); } return(new UpdatedTransactionInfo(UpdatedTransactionStatus.MissingTransaction)); } if (currentTransaction.State != TransactionState.Pending) { if (_logger.IsError) { _logger.Error($"Cannot cancel transaction with hash: '{hash}' for payment claim with id: '{paymentClaim!.Id}' (state: '{currentTransaction.State}')."); } return(new UpdatedTransactionInfo(UpdatedTransactionStatus.AlreadyIncluded)); } if (_logger.IsWarn) { _logger.Warn($"Canceling transaction for payment claim with id: '{paymentClaimId}'."); } CanceledTransactionInfo transaction = await _transactionService.CancelAsync(hash); if (_logger.IsWarn) { _logger.Warn($"Canceled transaction for payment claim with id: '{paymentClaimId}', transaction hash: '{transaction.Hash}'."); } TransactionInfo cancellingTransaction = TransactionInfo.Cancellation(transaction.Hash, transaction.GasPrice, transaction.GasLimit, _timestamper.UnixTime.Seconds); paymentClaim !.AddTransaction(cancellingTransaction); await _paymentClaimRepository.UpdateAsync(paymentClaim !); return(new UpdatedTransactionInfo(UpdatedTransactionStatus.Ok, transaction.Hash)); }
public FaucetRequestDetails(string host, Address address, UInt256 value, DateTime date, Keccak transactionHash) { Host = host; Address = address; Value = value; Date = date; TransactionHash = transactionHash; Value = value; }
public bool Equals(Keccak?other) { if (ReferenceEquals(other, null)) { return(false); } return(Core.Extensions.Bytes.AreEqual(other.Bytes, Bytes)); }
public async Task forkChoiceUpdatedV1_unknown_block_initiates_syncing() { using MergeTestBlockchain chain = await CreateBlockChain(); IEngineRpcModule rpc = CreateEngineModule(chain); Keccak? startingHead = chain.BlockTree.HeadHash; BlockHeader parent = Build.A.BlockHeader .WithNumber(1) .WithHash(TestItem.KeccakA) .WithNonce(0) .WithDifficulty(0) .TestObject; Block block = Build.A.Block .WithNumber(2) .WithParent(parent) .WithNonce(0) .WithDifficulty(0) .WithAuthor(Address.Zero) .WithPostMergeFlag(true) .TestObject; await rpc.engine_newPayloadV1(new ExecutionPayloadV1(block)); // sync has not started yet chain.BeaconSync.IsBeaconSyncHeadersFinished().Should().BeTrue(); chain.BeaconSync.IsBeaconSyncFinished(block.Header).Should().BeTrue(); chain.BeaconSync.ShouldBeInBeaconHeaders().Should().BeFalse(); chain.BeaconPivot.BeaconPivotExists().Should().BeFalse(); BlockTreePointers pointers = new() { BestKnownNumber = 0, BestSuggestedHeader = chain.BlockTree.Genesis !, BestSuggestedBody = chain.BlockTree.FindBlock(0) !, BestKnownBeaconBlock = 0, LowestInsertedHeader = null, LowestInsertedBeaconHeader = null }; AssertBlockTreePointers(chain.BlockTree, pointers); ForkchoiceStateV1 forkchoiceStateV1 = new(block.Hash !, startingHead, startingHead); ResultWrapper <ForkchoiceUpdatedV1Result> forkchoiceUpdatedResult = await rpc.engine_forkchoiceUpdatedV1(forkchoiceStateV1); forkchoiceUpdatedResult.Data.PayloadStatus.Status.Should() .Be(nameof(PayloadStatusV1.Syncing).ToUpper()); chain.BeaconSync.ShouldBeInBeaconHeaders().Should().BeTrue(); chain.BeaconSync.IsBeaconSyncHeadersFinished().Should().BeFalse(); chain.BeaconSync.IsBeaconSyncFinished(chain.BlockTree.FindBlock(block.Hash)?.Header).Should().BeFalse(); AssertBeaconPivotValues(chain.BeaconPivot, block.Header); pointers.LowestInsertedBeaconHeader = block.Header; pointers.BestKnownBeaconBlock = block.Number; pointers.LowestInsertedHeader = block.Header; AssertBlockTreePointers(chain.BlockTree, pointers); AssertExecutionStatusNotChangedV1(rpc, block.Hash !, startingHead, startingHead); }
public DataStreamDisabledMessage Deserialize(byte[] bytes) { RlpStream context = bytes.AsRlpStream(); context.ReadSequenceLength(); Keccak?depositId = context.DecodeKeccak(); string client = context.DecodeString(); return(new DataStreamDisabledMessage(depositId, client)); }
public Account?Get(Address address, Keccak?rootHash = null) { byte[]? bytes = Get(ValueKeccak.Compute(address.Bytes).BytesAsSpan, rootHash); if (bytes is null) { return(null); } return(_decoder.Decode(bytes.AsRlpStream())); }
public DataAssetStateChangedMessage Deserialize(byte[] bytes) { RlpStream context = bytes.AsRlpStream(); context.ReadSequenceLength(); Keccak? dataAssetId = context.DecodeKeccak(); DataAssetState state = (DataAssetState)context.DecodeInt(); return(new DataAssetStateChangedMessage(dataAssetId, state)); }
public DataAvailabilityMessage Deserialize(byte[] bytes) { RlpStream context = bytes.AsRlpStream(); context.ReadSequenceLength(); Keccak? depositId = context.DecodeKeccak(); DataAvailability reason = (DataAvailability)context.DecodeInt(); return(new DataAvailabilityMessage(depositId, reason)); }
private void AssertInvalid(Keccak hash, Keccak?expectedLsatValidHash = null) { Keccak?lastValidHash; _tracker.IsOnKnownInvalidChain(hash, out lastValidHash).Should().BeTrue(); if (expectedLsatValidHash != null) { lastValidHash.Should().BeEquivalentTo(expectedLsatValidHash); } }
public DepositApprovalRejectedMessage Deserialize(byte[] bytes) { RlpStream?context = bytes.AsRlpStream(); context.ReadSequenceLength(); Keccak? dataAssetId = context.DecodeKeccak(); Address?consumer = context.DecodeAddress(); return(new DepositApprovalRejectedMessage(dataAssetId, consumer)); }
public async Task <UpdatedTransactionInfo> UpdatePaymentClaimGasPriceAsync(Keccak paymentClaimId, UInt256 gasPrice) { if (gasPrice == 0) { if (_logger.IsError) { _logger.Error("Gas price cannot be 0."); } return(new UpdatedTransactionInfo(UpdatedTransactionStatus.InvalidGasPrice)); } (UpdatedTransactionStatus status, PaymentClaim? paymentClaim) = await TryGetPaymentClaimAsync(paymentClaimId, "update gas price"); if (status != UpdatedTransactionStatus.Ok) { return(new UpdatedTransactionInfo(status)); } TransactionInfo?currentTransaction = paymentClaim !.Transaction; if (currentTransaction == null) { return(new UpdatedTransactionInfo(UpdatedTransactionStatus.MissingTransaction)); } Keccak?currentHash = currentTransaction.Hash; if (currentHash == null) { return(new UpdatedTransactionInfo(UpdatedTransactionStatus.MissingTransaction)); } ulong gasLimit = currentTransaction.GasLimit; if (_logger.IsInfo) { _logger.Info($"Updating gas price for payment claim with id: '{paymentClaim!.Id}', current transaction hash: '{currentHash}'."); } Keccak transactionHash = await _transactionService.UpdateGasPriceAsync(currentHash, gasPrice); if (_logger.IsInfo) { _logger.Info($"Received transaction hash: '{transactionHash}' for payment claim with id: '{paymentClaim.Id}' after updating gas price."); } paymentClaim !.AddTransaction(TransactionInfo.SpeedUp(transactionHash, 0, gasPrice, gasLimit, _timestamper.UnixTime.Seconds)); await _paymentClaimRepository.UpdateAsync(paymentClaim !); if (_logger.IsInfo) { _logger.Info($"Updated gas price for payment claim with id: '{paymentClaim!.Id}', transaction hash: '{transactionHash}'."); } return(new UpdatedTransactionInfo(UpdatedTransactionStatus.Ok, transactionHash)); }
internal TransactionInfo(Keccak?hash, UInt256 value, UInt256 gasPrice, ulong gasLimit, ulong timestamp, TransactionType type = TransactionType.Default, TransactionState state = TransactionState.Pending) { Hash = hash; Value = value; GasPrice = gasPrice; GasLimit = gasLimit; Timestamp = timestamp; Type = type; State = state; }
public TransactionInfoForRpc(Keccak? hash, UInt256 value, UInt256 gasPrice, ulong gasLimit, ulong timestamp, string type, string state) { Hash = hash; Value = value; GasPrice = gasPrice; GasLimit = gasLimit; Timestamp = timestamp; Type = type; State = state; }
public RequestDepositApprovalMessage Deserialize(byte[] bytes) { RlpStream context = bytes.AsRlpStream(); context.ReadSequenceLength(); Keccak? dataAssetId = context.DecodeKeccak(); Address?consumer = context.DecodeAddress(); string kyc = context.DecodeString(); return(new RequestDepositApprovalMessage(dataAssetId, consumer, kyc)); }