From 1c55b358d7052be9945756d7998d1cce9061e885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pawelec?= Date: Wed, 12 Jul 2023 14:47:39 +0200 Subject: [PATCH] include pending_xrd_withdraw_vault, locked_owner_stake_unit_vault, pending_owner_stake_unit_unlock_vault, stake_vault in /state/validators/list endpoint. --- CHANGELOG.md | 1 + .../gateway-api-schema.yaml | 30 ++- .../Model/ValidatorCollectionItem.cs | 114 +++++++-- .../generated/Model/ValidatorVaultItem.cs | 232 ++++++++++++++++++ .../Services/EntityStateQuerier.cs | 70 +++++- 5 files changed, 417 insertions(+), 30 deletions(-) create mode 100644 src/RadixDlt.NetworkGateway.GatewayApiSdk/generated/Model/ValidatorVaultItem.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ebd27e97..7c38b57b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ _Release Date: Unreleased_ - Added `affected_global_entities` to `/transaction/committed-details` and `/stream/transactions` endpoints. To include them in response make sure to include `affected_global_entities` optin. - New `affected_global_entities_filter` filter in `/stream/transactions`. - Use strongly-typed metadata models. +- return `pending_xrd_withdraw_vault`, `locked_owner_stake_unit_vault`, `pending_owner_stake_unit_unlock_vault`, `stake_vault` from `/state/validators/list` endpoint. - Changed `access_rule_chain` to partially strongly typed `access_rules`. - Added package details to `/satus/entity/details` endpoint. diff --git a/src/RadixDlt.NetworkGateway.GatewayApi/gateway-api-schema.yaml b/src/RadixDlt.NetworkGateway.GatewayApi/gateway-api-schema.yaml index 03a04a295..8308d87b0 100644 --- a/src/RadixDlt.NetworkGateway.GatewayApi/gateway-api-schema.yaml +++ b/src/RadixDlt.NetworkGateway.GatewayApi/gateway-api-schema.yaml @@ -716,6 +716,21 @@ components: # Common Response Types # + ValidatorVaultItem: + type: object + required: + - balance + - last_changed_at_state_version + - address + properties: + balance: + $ref: "#/components/schemas/BigDecimal" + last_changed_at_state_version: + type: integer + format: int64 + address: + $ref: "#/components/schemas/Address" + LedgerStateMixin: type: object required: @@ -1134,15 +1149,24 @@ components: required: - address - metadata - - current_stake + - stake_vault + - pending_xrd_withdraw_vault + - locked_owner_stake_unit_vault + - pending_owner_stake_unit_unlock_vault properties: address: $ref: "#/components/schemas/Address" + stake_vault: + $ref: "#/components/schemas/ValidatorVaultItem" + pending_xrd_withdraw_vault: + $ref: "#/components/schemas/ValidatorVaultItem" + locked_owner_stake_unit_vault: + $ref: "#/components/schemas/ValidatorVaultItem" + pending_owner_stake_unit_unlock_vault: + $ref: "#/components/schemas/ValidatorVaultItem" state: type: object nullable: true - current_stake: - $ref: "#/components/schemas/BigDecimal" active_in_epoch: $ref: "#/components/schemas/ValidatorCollectionItemActiveInEpoch" metadata: diff --git a/src/RadixDlt.NetworkGateway.GatewayApiSdk/generated/Model/ValidatorCollectionItem.cs b/src/RadixDlt.NetworkGateway.GatewayApiSdk/generated/Model/ValidatorCollectionItem.cs index 645920c72..1cdf3e1c7 100644 --- a/src/RadixDlt.NetworkGateway.GatewayApiSdk/generated/Model/ValidatorCollectionItem.cs +++ b/src/RadixDlt.NetworkGateway.GatewayApiSdk/generated/Model/ValidatorCollectionItem.cs @@ -104,11 +104,14 @@ protected ValidatorCollectionItem() { } /// Initializes a new instance of the class. /// /// Bech32m-encoded human readable version of the address. (required). + /// stakeVault (required). + /// pendingXrdWithdrawVault (required). + /// lockedOwnerStakeUnitVault (required). + /// pendingOwnerStakeUnitUnlockVault (required). /// state. - /// String-encoded decimal representing the amount of a related fungible resource. (required). /// activeInEpoch. /// metadata (required). - public ValidatorCollectionItem(string address = default(string), Object state = default(Object), string currentStake = default(string), ValidatorCollectionItemActiveInEpoch activeInEpoch = default(ValidatorCollectionItemActiveInEpoch), EntityMetadataCollection metadata = default(EntityMetadataCollection)) + public ValidatorCollectionItem(string address = default(string), ValidatorVaultItem stakeVault = default(ValidatorVaultItem), ValidatorVaultItem pendingXrdWithdrawVault = default(ValidatorVaultItem), ValidatorVaultItem lockedOwnerStakeUnitVault = default(ValidatorVaultItem), ValidatorVaultItem pendingOwnerStakeUnitUnlockVault = default(ValidatorVaultItem), Object state = default(Object), ValidatorCollectionItemActiveInEpoch activeInEpoch = default(ValidatorCollectionItemActiveInEpoch), EntityMetadataCollection metadata = default(EntityMetadataCollection)) { // to ensure "address" is required (not null) if (address == null) @@ -116,12 +119,30 @@ protected ValidatorCollectionItem() { } throw new ArgumentNullException("address is a required property for ValidatorCollectionItem and cannot be null"); } this.Address = address; - // to ensure "currentStake" is required (not null) - if (currentStake == null) + // to ensure "stakeVault" is required (not null) + if (stakeVault == null) { - throw new ArgumentNullException("currentStake is a required property for ValidatorCollectionItem and cannot be null"); + throw new ArgumentNullException("stakeVault is a required property for ValidatorCollectionItem and cannot be null"); } - this.CurrentStake = currentStake; + this.StakeVault = stakeVault; + // to ensure "pendingXrdWithdrawVault" is required (not null) + if (pendingXrdWithdrawVault == null) + { + throw new ArgumentNullException("pendingXrdWithdrawVault is a required property for ValidatorCollectionItem and cannot be null"); + } + this.PendingXrdWithdrawVault = pendingXrdWithdrawVault; + // to ensure "lockedOwnerStakeUnitVault" is required (not null) + if (lockedOwnerStakeUnitVault == null) + { + throw new ArgumentNullException("lockedOwnerStakeUnitVault is a required property for ValidatorCollectionItem and cannot be null"); + } + this.LockedOwnerStakeUnitVault = lockedOwnerStakeUnitVault; + // to ensure "pendingOwnerStakeUnitUnlockVault" is required (not null) + if (pendingOwnerStakeUnitUnlockVault == null) + { + throw new ArgumentNullException("pendingOwnerStakeUnitUnlockVault is a required property for ValidatorCollectionItem and cannot be null"); + } + this.PendingOwnerStakeUnitUnlockVault = pendingOwnerStakeUnitUnlockVault; // to ensure "metadata" is required (not null) if (metadata == null) { @@ -140,17 +161,34 @@ protected ValidatorCollectionItem() { } public string Address { get; set; } /// - /// Gets or Sets State + /// Gets or Sets StakeVault /// - [DataMember(Name = "state", EmitDefaultValue = true)] - public Object State { get; set; } + [DataMember(Name = "stake_vault", IsRequired = true, EmitDefaultValue = true)] + public ValidatorVaultItem StakeVault { get; set; } /// - /// String-encoded decimal representing the amount of a related fungible resource. + /// Gets or Sets PendingXrdWithdrawVault /// - /// String-encoded decimal representing the amount of a related fungible resource. - [DataMember(Name = "current_stake", IsRequired = true, EmitDefaultValue = true)] - public string CurrentStake { get; set; } + [DataMember(Name = "pending_xrd_withdraw_vault", IsRequired = true, EmitDefaultValue = true)] + public ValidatorVaultItem PendingXrdWithdrawVault { get; set; } + + /// + /// Gets or Sets LockedOwnerStakeUnitVault + /// + [DataMember(Name = "locked_owner_stake_unit_vault", IsRequired = true, EmitDefaultValue = true)] + public ValidatorVaultItem LockedOwnerStakeUnitVault { get; set; } + + /// + /// Gets or Sets PendingOwnerStakeUnitUnlockVault + /// + [DataMember(Name = "pending_owner_stake_unit_unlock_vault", IsRequired = true, EmitDefaultValue = true)] + public ValidatorVaultItem PendingOwnerStakeUnitUnlockVault { get; set; } + + /// + /// Gets or Sets State + /// + [DataMember(Name = "state", EmitDefaultValue = true)] + public Object State { get; set; } /// /// Gets or Sets ActiveInEpoch @@ -173,8 +211,11 @@ public override string ToString() StringBuilder sb = new StringBuilder(); sb.Append("class ValidatorCollectionItem {\n"); sb.Append(" Address: ").Append(Address).Append("\n"); + sb.Append(" StakeVault: ").Append(StakeVault).Append("\n"); + sb.Append(" PendingXrdWithdrawVault: ").Append(PendingXrdWithdrawVault).Append("\n"); + sb.Append(" LockedOwnerStakeUnitVault: ").Append(LockedOwnerStakeUnitVault).Append("\n"); + sb.Append(" PendingOwnerStakeUnitUnlockVault: ").Append(PendingOwnerStakeUnitUnlockVault).Append("\n"); sb.Append(" State: ").Append(State).Append("\n"); - sb.Append(" CurrentStake: ").Append(CurrentStake).Append("\n"); sb.Append(" ActiveInEpoch: ").Append(ActiveInEpoch).Append("\n"); sb.Append(" Metadata: ").Append(Metadata).Append("\n"); sb.Append("}\n"); @@ -217,16 +258,31 @@ public bool Equals(ValidatorCollectionItem input) (this.Address != null && this.Address.Equals(input.Address)) ) && + ( + this.StakeVault == input.StakeVault || + (this.StakeVault != null && + this.StakeVault.Equals(input.StakeVault)) + ) && + ( + this.PendingXrdWithdrawVault == input.PendingXrdWithdrawVault || + (this.PendingXrdWithdrawVault != null && + this.PendingXrdWithdrawVault.Equals(input.PendingXrdWithdrawVault)) + ) && + ( + this.LockedOwnerStakeUnitVault == input.LockedOwnerStakeUnitVault || + (this.LockedOwnerStakeUnitVault != null && + this.LockedOwnerStakeUnitVault.Equals(input.LockedOwnerStakeUnitVault)) + ) && + ( + this.PendingOwnerStakeUnitUnlockVault == input.PendingOwnerStakeUnitUnlockVault || + (this.PendingOwnerStakeUnitUnlockVault != null && + this.PendingOwnerStakeUnitUnlockVault.Equals(input.PendingOwnerStakeUnitUnlockVault)) + ) && ( this.State == input.State || (this.State != null && this.State.Equals(input.State)) ) && - ( - this.CurrentStake == input.CurrentStake || - (this.CurrentStake != null && - this.CurrentStake.Equals(input.CurrentStake)) - ) && ( this.ActiveInEpoch == input.ActiveInEpoch || (this.ActiveInEpoch != null && @@ -252,13 +308,25 @@ public override int GetHashCode() { hashCode = (hashCode * 59) + this.Address.GetHashCode(); } - if (this.State != null) + if (this.StakeVault != null) { - hashCode = (hashCode * 59) + this.State.GetHashCode(); + hashCode = (hashCode * 59) + this.StakeVault.GetHashCode(); + } + if (this.PendingXrdWithdrawVault != null) + { + hashCode = (hashCode * 59) + this.PendingXrdWithdrawVault.GetHashCode(); + } + if (this.LockedOwnerStakeUnitVault != null) + { + hashCode = (hashCode * 59) + this.LockedOwnerStakeUnitVault.GetHashCode(); } - if (this.CurrentStake != null) + if (this.PendingOwnerStakeUnitUnlockVault != null) { - hashCode = (hashCode * 59) + this.CurrentStake.GetHashCode(); + hashCode = (hashCode * 59) + this.PendingOwnerStakeUnitUnlockVault.GetHashCode(); + } + if (this.State != null) + { + hashCode = (hashCode * 59) + this.State.GetHashCode(); } if (this.ActiveInEpoch != null) { diff --git a/src/RadixDlt.NetworkGateway.GatewayApiSdk/generated/Model/ValidatorVaultItem.cs b/src/RadixDlt.NetworkGateway.GatewayApiSdk/generated/Model/ValidatorVaultItem.cs new file mode 100644 index 000000000..5abe78927 --- /dev/null +++ b/src/RadixDlt.NetworkGateway.GatewayApiSdk/generated/Model/ValidatorVaultItem.cs @@ -0,0 +1,232 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +/* + * Babylon Gateway API - RCnet V2 + * + * This API is exposed by the Babylon Radix Gateway to enable clients to efficiently query current and historic state on the RadixDLT ledger, and intelligently handle transaction submission. It is designed for use by wallets and explorers. For simple use cases, you can typically use the Core API on a Node. A Gateway is only needed for reading historic snapshots of ledger states or a more robust set-up. The Gateway API is implemented by the [Network Gateway](https://github.com/radixdlt/babylon-gateway), which is configured to read from [full node(s)](https://github.com/radixdlt/babylon-node) to extract and index data from the network. This document is an API reference documentation, visit [User Guide](https://docs-babylon.radixdlt.com/) to learn more about how to run a Gateway of your own. ## Integration and forward compatibility guarantees We give no guarantees that other endpoints will not change before Babylon mainnet launch, although changes are expected to be minimal. + * + * The version of the OpenAPI document: 0.4.0 + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using FileParameter = RadixDlt.NetworkGateway.GatewayApiSdk.Client.FileParameter; +using OpenAPIDateConverter = RadixDlt.NetworkGateway.GatewayApiSdk.Client.OpenAPIDateConverter; + +namespace RadixDlt.NetworkGateway.GatewayApiSdk.Model +{ + /// + /// ValidatorVaultItem + /// + [DataContract(Name = "ValidatorVaultItem")] + public partial class ValidatorVaultItem : IEquatable + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + protected ValidatorVaultItem() { } + /// + /// Initializes a new instance of the class. + /// + /// String-encoded decimal representing the amount of a related fungible resource. (required). + /// lastChangedAtStateVersion (required). + /// Bech32m-encoded human readable version of the address. (required). + public ValidatorVaultItem(string balance = default(string), long lastChangedAtStateVersion = default(long), string address = default(string)) + { + // to ensure "balance" is required (not null) + if (balance == null) + { + throw new ArgumentNullException("balance is a required property for ValidatorVaultItem and cannot be null"); + } + this.Balance = balance; + this.LastChangedAtStateVersion = lastChangedAtStateVersion; + // to ensure "address" is required (not null) + if (address == null) + { + throw new ArgumentNullException("address is a required property for ValidatorVaultItem and cannot be null"); + } + this.Address = address; + } + + /// + /// String-encoded decimal representing the amount of a related fungible resource. + /// + /// String-encoded decimal representing the amount of a related fungible resource. + [DataMember(Name = "balance", IsRequired = true, EmitDefaultValue = true)] + public string Balance { get; set; } + + /// + /// Gets or Sets LastChangedAtStateVersion + /// + [DataMember(Name = "last_changed_at_state_version", IsRequired = true, EmitDefaultValue = true)] + public long LastChangedAtStateVersion { get; set; } + + /// + /// Bech32m-encoded human readable version of the address. + /// + /// Bech32m-encoded human readable version of the address. + [DataMember(Name = "address", IsRequired = true, EmitDefaultValue = true)] + public string Address { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class ValidatorVaultItem {\n"); + sb.Append(" Balance: ").Append(Balance).Append("\n"); + sb.Append(" LastChangedAtStateVersion: ").Append(LastChangedAtStateVersion).Append("\n"); + sb.Append(" Address: ").Append(Address).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as ValidatorVaultItem); + } + + /// + /// Returns true if ValidatorVaultItem instances are equal + /// + /// Instance of ValidatorVaultItem to be compared + /// Boolean + public bool Equals(ValidatorVaultItem input) + { + if (input == null) + { + return false; + } + return + ( + this.Balance == input.Balance || + (this.Balance != null && + this.Balance.Equals(input.Balance)) + ) && + ( + this.LastChangedAtStateVersion == input.LastChangedAtStateVersion || + this.LastChangedAtStateVersion.Equals(input.LastChangedAtStateVersion) + ) && + ( + this.Address == input.Address || + (this.Address != null && + this.Address.Equals(input.Address)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Balance != null) + { + hashCode = (hashCode * 59) + this.Balance.GetHashCode(); + } + hashCode = (hashCode * 59) + this.LastChangedAtStateVersion.GetHashCode(); + if (this.Address != null) + { + hashCode = (hashCode * 59) + this.Address.GetHashCode(); + } + return hashCode; + } + } + + } + +} diff --git a/src/RadixDlt.NetworkGateway.PostgresIntegration/Services/EntityStateQuerier.cs b/src/RadixDlt.NetworkGateway.PostgresIntegration/Services/EntityStateQuerier.cs index 689891da7..004a1b24f 100644 --- a/src/RadixDlt.NetworkGateway.PostgresIntegration/Services/EntityStateQuerier.cs +++ b/src/RadixDlt.NetworkGateway.PostgresIntegration/Services/EntityStateQuerier.cs @@ -91,7 +91,7 @@ internal class EntityStateQuerier : IEntityStateQuerier { private record MetadataViewModel(long FromStateVersion, long EntityId, string Key, byte[] Value, bool IsLocked, int TotalCount); - private record ValidatorCurrentStakeViewModel(long ValidatorId, string Balance, string State, long BalanceLastUpdatedAtStateVersion, long StateLastUpdatedAtStateVersion); + private record ValidatorCurrentStakeViewModel(long ValidatorId, string State, long StateLastUpdatedAtStateVersion, string StakeVaultBalance, long StakeVaultLastUpdatedAtStateVersion, string PendingXrdWithdrawVaultBalance, long PendingXrdWithdrawVaultLastUpdatedAtStateVersion, string LockedOwnerStakeUnitVaultBalance, long LockedOwnerStakeUnitVaultLastUpdatedAtStateVersion, string PendingOwnerStakeUnitUnlockVaultBalance, long PendingOwnerStakeUnitUnlockVaultLastUpdatedAtStateVersion); private record FungibleViewModel(EntityAddress ResourceEntityAddress, string Balance, int ResourcesTotalCount, long LastUpdatedAtStateVersion); @@ -605,7 +605,8 @@ ORDER BY nfid.from_state_version DESC var fromStateVersion = cursor?.StateVersionBoundary ?? 0; var validatorsAndOneMore = await _dbContext.Entities - .Where(e => e.FromStateVersion <= ledgerState.StateVersion && e.GetType() == typeof(GlobalValidatorEntity)) + .OfType() + .Where(e => e.FromStateVersion <= ledgerState.StateVersion) .Where(e => e.FromStateVersion > fromStateVersion) .OrderBy(e => e.FromStateVersion) .ThenBy(e => e.Id) @@ -629,11 +630,32 @@ ORDER BY nfid.from_state_version DESC .Aggregate(TokenAmount.Zero, (current, x) => current + x); var validatorIds = validatorsAndOneMore.Take(validatorsPageSize).Select(e => e.Id).ToArray(); + var validatorVaultIds = validatorsAndOneMore.Take(validatorsPageSize).Aggregate(new List(), (aggregated, validator) => + { + aggregated.Add(validator.StakeVaultEntityId); + aggregated.Add(validator.PendingXrdWithdrawVault); + aggregated.Add(validator.LockedOwnerStakeUnitVault); + aggregated.Add(validator.PendingOwnerStakeUnitUnlockVault); + + return aggregated; + }) + .ToList(); var cd = new CommandDefinition( commandText: @" WITH variables (validator_entity_id) AS (SELECT UNNEST(@validatorIds)) -SELECT e.id AS ValidatorId, CAST(evh.balance AS text) AS Balance, esh.state AS State, evh.from_state_version AS BalanceLastUpdatedAtStateVersion, esh.from_state_version AS StateLastUpdatedAtStateVersion +SELECT + e.id AS ValidatorId, + esh.state AS State, + esh.from_state_version AS StateLastUpdatedAtStateVersion, + CAST(evh.balance AS text) AS StakeVaultBalance, + evh.from_state_version AS StakeVaultLastUpdatedAtStateVersion, + CAST(pxrwv.balance AS text) AS PendingXrdWithdrawVaultBalance, + pxrwv.from_state_version AS PendingXrdWithdrawVaultLastUpdatedAtStateVersion, + CAST(losuv.balance AS text) AS LockedOwnerStakeUnitVaultBalance, + losuv.from_state_version AS LockedOwnerStakeUnitVaultLastUpdatedAtStateVersion, + CAST(posuuv.balance AS text) AS PendingOwnerStakeUnitUnlockVaultBalance, + posuuv.from_state_version AS PendingOwnerStakeUnitUnlockVaultLastUpdatedAtStateVersion FROM variables INNER JOIN entities e ON e.id = variables.validator_entity_id AND from_state_version <= @stateVersion INNER JOIN LATERAL ( @@ -650,6 +672,27 @@ FROM entity_state_history ORDER BY from_state_version DESC LIMIT 1 ) esh ON true +INNER JOIN LATERAL ( + SELECT balance, from_state_version + FROM entity_vault_history + WHERE vault_entity_id = e.pending_xrd_withdraw_vault_entity_id AND from_state_version <= @stateVersion + ORDER BY from_state_version DESC + LIMIT 1 +) pxrwv ON true +INNER JOIN LATERAL ( + SELECT balance, from_state_version + FROM entity_vault_history + WHERE vault_entity_id = e.locked_owner_stake_unit_vault_entity_id AND from_state_version <= @stateVersion + ORDER BY from_state_version DESC + LIMIT 1 +) losuv ON true +INNER JOIN LATERAL ( + SELECT balance, from_state_version + FROM entity_vault_history + WHERE vault_entity_id = e.pending_owner_stake_unit_unlock_vault_entity_id AND from_state_version <= @stateVersion + ORDER BY from_state_version DESC + LIMIT 1 +) posuuv ON true ;", parameters: new { @@ -658,6 +701,10 @@ LIMIT 1 cancellationToken: token); var validatorsDetails = (await _dbContext.Database.GetDbConnection().QueryAsync(cd)).ToList(); + var vaultAddresses = await _dbContext.Entities + .Where(e => validatorVaultIds.Contains(e.Id)) + .Select(e => new { e.Id, GlobalAddress = e.Address }) + .ToDictionaryAsync(e => e.Id, e => e.GlobalAddress, token); var metadataById = await GetMetadataSlices(validatorIds, 0, _endpointConfiguration.Value.DefaultPageSize, ledgerState, token); @@ -679,8 +726,23 @@ LIMIT 1 return new GatewayModel.ValidatorCollectionItem( v.Address, + new GatewayModel.ValidatorVaultItem( + TokenAmount.FromSubUnitsString(details.StakeVaultBalance).ToString(), + details.StakeVaultLastUpdatedAtStateVersion, + vaultAddresses[v.StakeVaultEntityId]), + new GatewayModel.ValidatorVaultItem( + TokenAmount.FromSubUnitsString(details.PendingXrdWithdrawVaultBalance).ToString(), + details.PendingXrdWithdrawVaultLastUpdatedAtStateVersion, + vaultAddresses[v.PendingXrdWithdrawVault]), + new GatewayModel.ValidatorVaultItem( + TokenAmount.FromSubUnitsString(details.LockedOwnerStakeUnitVaultBalance).ToString(), + details.LockedOwnerStakeUnitVaultLastUpdatedAtStateVersion, + vaultAddresses[v.LockedOwnerStakeUnitVault]), + new GatewayModel.ValidatorVaultItem( + TokenAmount.FromSubUnitsString(details.PendingOwnerStakeUnitUnlockVaultBalance).ToString(), + details.PendingOwnerStakeUnitUnlockVaultLastUpdatedAtStateVersion, + vaultAddresses[v.PendingXrdWithdrawVault]), new JRaw(details.State), - TokenAmount.FromSubUnitsString(details.Balance).ToString(), activeInEpoch, metadataById[v.Id]); })