From 45addfc2a9a87fead760cc37d0b87b2c17f38c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Wed, 11 Sep 2024 13:34:15 +0200 Subject: [PATCH 1/9] Support node api v7 --- examples/GetPoolInfo/Program.cs | 3 +- src/Types/AccountInfo.cs | 53 +++++++++++++++++++++++++++++---- src/Types/AccountStakingInfo.cs | 17 ++++++++++- src/Types/BakerEvent.cs | 8 ++++- src/Types/BakerPoolStatus.cs | 26 +++++++++------- src/Types/Cooldown.cs | 22 ++++++++++++++ src/Types/CooldownStatus.cs | 48 +++++++++++++++++++++++++++++ src/Types/DelegationEvent.cs | 14 ++++++++- src/Types/Release.cs | 22 ++++++++++++++ src/Types/ReleaseSchedule.cs | 18 +++++++++++ 10 files changed, 212 insertions(+), 19 deletions(-) create mode 100644 src/Types/Cooldown.cs create mode 100644 src/Types/CooldownStatus.cs create mode 100644 src/Types/Release.cs create mode 100644 src/Types/ReleaseSchedule.cs diff --git a/examples/GetPoolInfo/Program.cs b/examples/GetPoolInfo/Program.cs index 9be61918..d1723959 100644 --- a/examples/GetPoolInfo/Program.cs +++ b/examples/GetPoolInfo/Program.cs @@ -52,6 +52,7 @@ private static async Task Run(GetPoolInfoOptions options) Console.WriteLine($"BlockHash: {response.BlockHash}"); - Console.WriteLine($"Baker {bakerId} has baker equity capital {response.Response.BakerEquityCapital.GetFormattedCcd()}"); + var capital = response.Response.BakerEquityCapital ?? CcdAmount.Zero; + Console.WriteLine($"Baker {bakerId} has baker equity capital {capital.GetFormattedCcd()}"); } } diff --git a/src/Types/AccountInfo.cs b/src/Types/AccountInfo.cs index 50b99302..a7ad691c 100644 --- a/src/Types/AccountInfo.cs +++ b/src/Types/AccountInfo.cs @@ -18,19 +18,62 @@ namespace Concordium.Sdk.Types; /// Not null if and only if the account is a baker or delegator. In that case /// it is the information about the baker or delegator. /// +/// +/// Release schedule for any locked up amount. This could be an empty +/// release schedule. +/// +/// +/// The stake on the account that is in cooldown. +/// There can be multiple amounts in cooldown that expire at different times. +/// This was introduced in protocol version 7, and so is not present in +/// earlier protocol versions. +/// +/// +/// The available (unencrypted) balance of the account (i.e. that can be transferred +/// or used to pay for transactions). This is the balance minus the locked amount. +/// The locked amount is the maximum of the amount in the release schedule and +/// the total amount that is actively staked or in cooldown (inactive stake). +/// public sealed record AccountInfo( AccountSequenceNumber AccountNonce, CcdAmount AccountAmount, AccountIndex AccountIndex, AccountAddress AccountAddress, - IAccountStakingInfo? AccountStakingInfo) + IAccountStakingInfo? AccountStakingInfo, + ReleaseSchedule Schedule, + IList Cooldowns, + CcdAmount AvailableBalance +) { - internal static AccountInfo From(Grpc.V2.AccountInfo accountInfo) => - new( + internal static AccountInfo From(Grpc.V2.AccountInfo accountInfo) + { + var accountAmount = CcdAmount.From(accountInfo.Amount); + var schedule = ReleaseSchedule.From(accountInfo.Schedule); + var stakingInfo = Types.AccountStakingInfo.From(accountInfo.Stake); + + // `accountInfo.availableBalance` was introduce in the Concordium Node API v7, + // so to remain backwards compatible with node versions prior to this, we + // compute the available balance if this is not present. + CcdAmount availableBalance; + if (accountInfo.AvailableBalance == null) + { + var staked = stakingInfo?.GetStakedAmount() ?? CcdAmount.Zero; + availableBalance = accountAmount - CcdAmount.Max(staked, schedule.Total); + } + else + { + availableBalance = CcdAmount.From(accountInfo.AvailableBalance); + } + + return new( AccountNonce: AccountSequenceNumber.From(accountInfo.SequenceNumber), - AccountAmount: CcdAmount.From(accountInfo.Amount), + AccountAmount: accountAmount, AccountIndex: new AccountIndex(accountInfo.Index.Value), AccountAddress: AccountAddress.From(accountInfo.Address), - AccountStakingInfo: Types.AccountStakingInfo.From(accountInfo.Stake) + AccountStakingInfo: stakingInfo, + Schedule: schedule, + Cooldowns: accountInfo.Cooldowns.Select(Cooldown.From).ToList(), + AvailableBalance: availableBalance ); + } } diff --git a/src/Types/AccountStakingInfo.cs b/src/Types/AccountStakingInfo.cs index 85931f74..97d8db72 100644 --- a/src/Types/AccountStakingInfo.cs +++ b/src/Types/AccountStakingInfo.cs @@ -5,7 +5,13 @@ namespace Concordium.Sdk.Types; /// /// Information related to staking for a specific account. /// -public interface IAccountStakingInfo { } +public interface IAccountStakingInfo +{ + /// + /// Get the amount of CCD being staked. + /// + public CcdAmount GetStakedAmount(); +} internal static class AccountStakingInfo { @@ -48,6 +54,11 @@ internal static AccountBaker From(Grpc.V2.AccountStakingInfo.Types.Baker stakeBa StakedAmount: CcdAmount.From(stakeBaker.StakedAmount), BakerPoolInfo: BakerPoolInfo.From(stakeBaker.PoolInfo) ); + + /// + /// Get the amount of CCD being staked. + /// + public CcdAmount GetStakedAmount() => this.StakedAmount; } /// @@ -67,4 +78,8 @@ internal static AccountDelegation From(Grpc.V2.AccountStakingInfo.Types.Delegato DelegationTarget: DelegationTarget.From(stakeDelegator.Target), PendingChange: AccountDelegationPendingChangeFactory.From(stakeDelegator.PendingChange) ); + /// + /// Get the amount of CCD being staked. + /// + public CcdAmount GetStakedAmount() => this.StakedAmount; } diff --git a/src/Types/BakerEvent.cs b/src/Types/BakerEvent.cs index cd4a819f..b4566c6b 100644 --- a/src/Types/BakerEvent.cs +++ b/src/Types/BakerEvent.cs @@ -49,9 +49,9 @@ internal static IBakerEvent From(BakerEvent bakerEvent) => BakerId.From(bakerEvent.BakerSetFinalizationRewardCommission.BakerId), AmountFraction.From(bakerEvent.BakerSetFinalizationRewardCommission.FinalizationRewardCommission) ), + BakerEvent.EventOneofCase.DelegationRemoved => new DelegationRemovedEvent(DelegatorId.From(bakerEvent.DelegationRemoved.DelegatorId)), BakerEvent.EventOneofCase.None => throw new MissingEnumException(bakerEvent.EventCase), - BakerEvent.EventOneofCase.DelegationRemoved => throw new NotImplementedException(), _ => throw new MissingEnumException(bakerEvent.EventCase) }; } @@ -136,3 +136,9 @@ public sealed record BakerSetBakingRewardCommissionEvent(BakerId BakerId, Amount /// Baker's id /// The finalization reward commission public sealed record BakerSetFinalizationRewardCommissionEvent(BakerId BakerId, AmountFraction FinalizationRewardCommission) : IBakerEvent; + +/// +/// An existing delegator was removed. +/// +/// Delegator's id +public sealed record DelegationRemovedEvent(DelegatorId DelegatorId) : IBakerEvent; diff --git a/src/Types/BakerPoolStatus.cs b/src/Types/BakerPoolStatus.cs index e74e6cea..a9a9c585 100644 --- a/src/Types/BakerPoolStatus.cs +++ b/src/Types/BakerPoolStatus.cs @@ -6,17 +6,23 @@ namespace Concordium.Sdk.Types; /// by transactions (and rewards). This is in contrast to "epoch baker" which is /// the state of the baker that is currently eligible for baking. /// +/// +/// From protocol version 7, pool removal has immediate effect, however, the +/// pool may still be present for the current (and possibly next) reward period. +/// /// The 'BakerId' of the pool owner. /// The account address of the pool owner. -/// The equity capital provided by the pool owner. -/// The capital delegated to the pool by other accounts. +/// The equity capital provided by the pool owner. Absent if the pool is removed. +/// The capital delegated to the pool by other accounts. Absent if the pool is removed. /// /// The maximum amount that may be delegated to the pool, accounting for /// leverage and stake limits. +/// Absent if the pool is removed. /// /// /// The pool info associated with the pool: open status, metadata URL /// and commission rates. +/// Absent if the pool is removed. /// /// /// Status of the pool in the current reward period. This will be null @@ -28,10 +34,10 @@ namespace Concordium.Sdk.Types; public sealed record BakerPoolStatus( BakerId BakerId, AccountAddress BakerAddress, - CcdAmount BakerEquityCapital, - CcdAmount DelegatedCapital, - CcdAmount DelegatedCapitalCap, - BakerPoolInfo PoolInfo, + CcdAmount? BakerEquityCapital, + CcdAmount? DelegatedCapital, + CcdAmount? DelegatedCapitalCap, + BakerPoolInfo? PoolInfo, CurrentPaydayBakerPoolStatus? CurrentPaydayStatus, CcdAmount AllPoolTotalCapital, BakerPoolPendingChange? BakerStakePendingChange) @@ -40,10 +46,10 @@ internal static BakerPoolStatus From(Grpc.V2.PoolInfoResponse poolInfoResponse) new( BakerId.From(poolInfoResponse.Baker), AccountAddress.From(poolInfoResponse.Address), - CcdAmount.From(poolInfoResponse.EquityCapital), - CcdAmount.From(poolInfoResponse.DelegatedCapital), - CcdAmount.From(poolInfoResponse.DelegatedCapitalCap), - BakerPoolInfo.From(poolInfoResponse.PoolInfo)!, + poolInfoResponse.EquityCapital != null ? CcdAmount.From(poolInfoResponse.EquityCapital) : null, + poolInfoResponse.DelegatedCapital != null ? CcdAmount.From(poolInfoResponse.DelegatedCapital) : null, + poolInfoResponse.DelegatedCapitalCap != null ? CcdAmount.From(poolInfoResponse.DelegatedCapitalCap) : null, + poolInfoResponse.PoolInfo != null ? BakerPoolInfo.From(poolInfoResponse.PoolInfo) : null, CurrentPaydayBakerPoolStatus.From(poolInfoResponse.CurrentPaydayInfo), CcdAmount.From(poolInfoResponse.AllPoolTotalCapital), BakerPoolPendingChange.From(poolInfoResponse.EquityPendingChange) diff --git a/src/Types/Cooldown.cs b/src/Types/Cooldown.cs new file mode 100644 index 00000000..9fea410c --- /dev/null +++ b/src/Types/Cooldown.cs @@ -0,0 +1,22 @@ +using Concordium.Sdk.Helpers; + +namespace Concordium.Sdk.Types; + +/// +/// The stake on the account that is in cooldown. +/// +/// The time when the cooldown period ends. +/// The amount that is in cooldown and set to be released at the end of the cooldown period. +/// The status of the cooldown. +public sealed record Cooldown( + DateTimeOffset EndTime, + CcdAmount Amount, + CooldownStatus Status +) +{ + internal static Cooldown From(Grpc.V2.Cooldown cooldown) => new( + cooldown.EndTime.ToDateTimeOffset(), + CcdAmount.From(cooldown.Amount), + cooldown.Status.Into() + ); +} diff --git a/src/Types/CooldownStatus.cs b/src/Types/CooldownStatus.cs new file mode 100644 index 00000000..c677f9f0 --- /dev/null +++ b/src/Types/CooldownStatus.cs @@ -0,0 +1,48 @@ +using Concordium.Sdk.Exceptions; + +namespace Concordium.Sdk.Types; + +/// +/// The status of a cooldown. +/// +/// +/// When stake is removed from a baker or delegator +/// (from protocol version 7) it first enters the pre-pre-cooldown state. +/// The next time the stake snaphot is taken (at the epoch transition before +/// a payday) it enters the pre-cooldown state. At the subsequent payday, it +/// enters the cooldown state. At the payday after the end of the cooldown +/// period, the stake is finally released. +/// +public enum CooldownStatus +{ + /// + /// The amount is in cooldown and will expire at the specified time, becoming available + /// at the subsequent pay day. + /// + Cooldown, + /// + /// The amount will enter cooldown at the next pay day. The specified end time is + /// projected to be the end of the cooldown period, but the actual end time will be + /// determined at the payday, and may be different if the global cooldown period + /// changes. + /// + PreCooldown, + /// + /// The amount will enter pre-cooldown at the next snapshot epoch (i.e. the epoch + /// transition before a pay day transition). As with pre-cooldown, the specified + /// end time is projected, but the actual end time will be determined later. + /// + PrePreCooldown +} + +internal static class CooldownStatusFactory +{ + internal static CooldownStatus Into(this Grpc.V2.Cooldown.Types.CooldownStatus status) => + status switch + { + Grpc.V2.Cooldown.Types.CooldownStatus.Cooldown => CooldownStatus.Cooldown, + Grpc.V2.Cooldown.Types.CooldownStatus.PreCooldown => CooldownStatus.PreCooldown, + Grpc.V2.Cooldown.Types.CooldownStatus.PrePreCooldown => CooldownStatus.PrePreCooldown, + _ => throw new MissingEnumException(status) + }; +} diff --git a/src/Types/DelegationEvent.cs b/src/Types/DelegationEvent.cs index 923e8983..f9b82f5e 100644 --- a/src/Types/DelegationEvent.cs +++ b/src/Types/DelegationEvent.cs @@ -27,7 +27,7 @@ internal static IDelegationEvent From(DelegationEvent delegationEvent) => DelegationAdded.From(delegationEvent.DelegationAdded), DelegationEvent.EventOneofCase.DelegationRemoved => DelegationRemoved.From(delegationEvent.DelegationRemoved), - DelegationEvent.EventOneofCase.BakerRemoved => throw new NotImplementedException(), + DelegationEvent.EventOneofCase.BakerRemoved => DelegationEventBakerRemoved.From(delegationEvent.BakerRemoved), DelegationEvent.EventOneofCase.None => throw new MissingEnumException(delegationEvent.EventCase), _ => throw new MissingEnumException(delegationEvent.EventCase) @@ -114,3 +114,15 @@ internal static DelegationRemoved From(Grpc.V2.DelegatorId id) => DelegatorId.From(id) ); } + +/// +/// A baker was removed. +/// +/// Baker's id +public sealed record DelegationEventBakerRemoved(BakerId BakerId) : IDelegationEvent +{ + internal static DelegationEventBakerRemoved From(DelegationEvent.Types.BakerRemoved removed) => + new( + BakerId.From(removed.BakerId) + ); +} diff --git a/src/Types/Release.cs b/src/Types/Release.cs new file mode 100644 index 00000000..a3664b93 --- /dev/null +++ b/src/Types/Release.cs @@ -0,0 +1,22 @@ +using Concordium.Sdk.Helpers; + +namespace Concordium.Sdk.Types; + +/// +/// An individual release of a locked balance. +/// +/// Effective time of the release. +/// Amount to be released. +/// List of transaction hashes that contribute a balance to this release. +public sealed record Release( + DateTimeOffset Timestamp, + CcdAmount Amount, + IList Transactions +) +{ + internal static Release From(Grpc.V2.Release release) => new( + release.Timestamp.ToDateTimeOffset(), + CcdAmount.From(release.Amount), + release.Transactions.Select(TransactionHash.From).ToList() + ); +} diff --git a/src/Types/ReleaseSchedule.cs b/src/Types/ReleaseSchedule.cs new file mode 100644 index 00000000..ccfd692a --- /dev/null +++ b/src/Types/ReleaseSchedule.cs @@ -0,0 +1,18 @@ +namespace Concordium.Sdk.Types; + +/// +/// State of the account's release schedule. This is the balance of the account +/// that is owned by the account, but cannot be used until the release point. +/// +/// Total amount locked in the release schedule. +/// A list of releases, ordered by increasing timestamp. +public sealed record ReleaseSchedule( + CcdAmount Total, + IList Schedules +) +{ + internal static ReleaseSchedule From(Grpc.V2.ReleaseSchedule schedule) => new( + CcdAmount.From(schedule.Total), + schedule.Schedules.Select(Release.From).ToList() + ); +} From 612716ed4b2e9d4828a90bfdcb007433efb71b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Wed, 11 Sep 2024 13:53:23 +0200 Subject: [PATCH 2/9] Prepare for release of 5.0.0 --- CHANGELOG.md | 15 +++++++++++++++ src/Concordium.Sdk.csproj | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2c261f6..f1fd1ec7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ ## Unreleased changes +## 5.0.0 + +- Added + - More documentation comments on various types. + - `AccountInfo` now includes the `Schedule` field, which are the locked CCD amounts scheduled for release. + - Method `GetStakedAmount` for `IAccountStakingInfo` method, which provide the staked amount. +- Support Concordium Node version 7 API changes: + - `AccountInfo` now have fields `Cooldowns` and `AvailableBalance`, which are respectively describing the stake currently in cooldown and the (unencrypted) balance of an account, which can be transfered. + - New baker event `DelegationRemovedEvent` signaling a delegator is removed, right before becoming a baker/validator. + - New delegation event `DelegationEventBakerRemoved` signaling a baker/validator is removed, right before becoming a deligator. + - Some fields of type `BakerPoolStatus` are now nullable, more specifically `BakerEquityCapital`, `DelegatedCapital`, `DelegatedCapitalCap` and `PoolInfo`. + Prior to Protocol Version 7, these will always be present. + From protocol version 7, pool removal has immediate effect, however, the pool may still be present for the current (and possibly next) reward period. + + ## 4.4.0 - Added - New transaction `InitContract` diff --git a/src/Concordium.Sdk.csproj b/src/Concordium.Sdk.csproj index e22bfbbc..3c933262 100644 --- a/src/Concordium.Sdk.csproj +++ b/src/Concordium.Sdk.csproj @@ -15,7 +15,7 @@ concordium;concordium-net-sdk;blockchain;sdk; Concordium ConcordiumNetSdk - 4.4.0 + 5.0.0 icon.png README.md MPL-2.0 From 5c1b12e4e11024100ba980d2705584dd0f4dc8f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Wed, 11 Sep 2024 14:21:07 +0200 Subject: [PATCH 3/9] Update base --- concordium-base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concordium-base b/concordium-base index 66eef319..31a168d0 160000 --- a/concordium-base +++ b/concordium-base @@ -1 +1 @@ -Subproject commit 66eef31986a3475ab68f2546c297857e9d9b7125 +Subproject commit 31a168d0af2c568e8e6dd7931a404601b2cee090 From 5755d0cef13aabeca4f100243afecc73ac6bcd2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Wed, 11 Sep 2024 15:48:57 +0200 Subject: [PATCH 4/9] Update rust version in release workflow --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 2a201c8c..0dc332fd 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -4,7 +4,7 @@ on: workflow_dispatch: env: - RUST_VERSION: 1.68 + RUST_VERSION: 1.73 jobs: build-native-ubuntu: From d3d25dff007d38ccbbfa897a5e32f15b665c3752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Wed, 11 Sep 2024 15:55:09 +0200 Subject: [PATCH 5/9] Trigger CI checks in more cases --- .github/workflows/build-test-format.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-test-format.yml b/.github/workflows/build-test-format.yml index b73d195b..0b6e696d 100644 --- a/.github/workflows/build-test-format.yml +++ b/.github/workflows/build-test-format.yml @@ -5,6 +5,7 @@ on: branches: [ "main" ] pull_request: branches: [ "main" ] + types: [ opened, reopened, synchronize, ready_for_review, edited ] workflow_dispatch: env: From 4ce1293381b618bbdf02841135cd94f79750a011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Wed, 11 Sep 2024 20:46:25 +0200 Subject: [PATCH 6/9] Fixed missing null checks --- src/Types/AccountTransactionEffects.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Types/AccountTransactionEffects.cs b/src/Types/AccountTransactionEffects.cs index c989f51b..a73f8e74 100644 --- a/src/Types/AccountTransactionEffects.cs +++ b/src/Types/AccountTransactionEffects.cs @@ -27,7 +27,7 @@ internal static IAccountTransactionEffects From(Grpc.V2.AccountTransactionEffect new AccountTransfer( CcdAmount.From(effects.AccountTransfer.Amount), AccountAddress.From(effects.AccountTransfer.Receiver), - OnChainData.From(effects.AccountTransfer.Memo)), + effects.AccountTransfer.Memo == null ? null : OnChainData.From(effects.AccountTransfer.Memo)), Grpc.V2.AccountTransactionEffects.EffectOneofCase.BakerAdded => new BakerAdded(BakerKeysEvent.From( effects.BakerAdded.KeysEvent), @@ -45,7 +45,7 @@ internal static IAccountTransactionEffects From(Grpc.V2.AccountTransactionEffect new EncryptedAmountTransferred( EncryptedAmountRemovedEvent.From(effects.EncryptedAmountTransferred.Removed), NewEncryptedAmountEvent.From(effects.EncryptedAmountTransferred.Added), - OnChainData.From(effects.EncryptedAmountTransferred.Memo) + effects.EncryptedAmountTransferred.Memo == null ? null : OnChainData.From(effects.EncryptedAmountTransferred.Memo) ), Grpc.V2.AccountTransactionEffects.EffectOneofCase.TransferredToEncrypted => new TransferredToEncrypted( @@ -57,7 +57,7 @@ internal static IAccountTransactionEffects From(Grpc.V2.AccountTransactionEffect new TransferredWithSchedule( AccountAddress.From(effects.TransferredWithSchedule.Receiver), effects.TransferredWithSchedule.Amount.Select(a => (a.Timestamp.ToDateTimeOffset(), a.Amount.ToCcd())).ToList(), - OnChainData.From(effects.TransferredWithSchedule.Memo) + effects.TransferredWithSchedule.Memo == null ? null : OnChainData.From(effects.TransferredWithSchedule.Memo) ), Grpc.V2.AccountTransactionEffects.EffectOneofCase.CredentialKeysUpdated => CredentialKeysUpdated.From(effects.CredentialKeysUpdated), From 3ff2e0a0889c8f30ebd650e206096b0452459fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Fri, 13 Sep 2024 11:27:42 +0200 Subject: [PATCH 7/9] Address review comments --- CHANGELOG.md | 11 ++++++----- src/Types/BakerEvent.cs | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1fd1ec7..be895d7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,13 +5,14 @@ - Added - More documentation comments on various types. - `AccountInfo` now includes the `Schedule` field, which are the locked CCD amounts scheduled for release. - - Method `GetStakedAmount` for `IAccountStakingInfo` method, which provide the staked amount. + - Method `GetStakedAmount` to interface `IAccountStakingInfo` , which provides the staked amount. + - Support Concordium Node version 7 API changes: - - `AccountInfo` now have fields `Cooldowns` and `AvailableBalance`, which are respectively describing the stake currently in cooldown and the (unencrypted) balance of an account, which can be transfered. - - New baker event `DelegationRemovedEvent` signaling a delegator is removed, right before becoming a baker/validator. - - New delegation event `DelegationEventBakerRemoved` signaling a baker/validator is removed, right before becoming a deligator. + - `AccountInfo` now have fields `Cooldowns` and `AvailableBalance`, which are respectively describing the stake currently in cooldown and the (unencrypted) balance of an account, which can be transferred. + - New baker event `BakerEventDelegationRemoved` signaling a delegator is removed, right before becoming a baker/validator. + - New delegation event `DelegationEventBakerRemoved` signaling a baker/validator is removed, right before becoming a delegator. - Some fields of type `BakerPoolStatus` are now nullable, more specifically `BakerEquityCapital`, `DelegatedCapital`, `DelegatedCapitalCap` and `PoolInfo`. - Prior to Protocol Version 7, these will always be present. + Querying blocks prior to Protocol Version 7, these fields will always be present. From protocol version 7, pool removal has immediate effect, however, the pool may still be present for the current (and possibly next) reward period. diff --git a/src/Types/BakerEvent.cs b/src/Types/BakerEvent.cs index b4566c6b..94649254 100644 --- a/src/Types/BakerEvent.cs +++ b/src/Types/BakerEvent.cs @@ -49,7 +49,7 @@ internal static IBakerEvent From(BakerEvent bakerEvent) => BakerId.From(bakerEvent.BakerSetFinalizationRewardCommission.BakerId), AmountFraction.From(bakerEvent.BakerSetFinalizationRewardCommission.FinalizationRewardCommission) ), - BakerEvent.EventOneofCase.DelegationRemoved => new DelegationRemovedEvent(DelegatorId.From(bakerEvent.DelegationRemoved.DelegatorId)), + BakerEvent.EventOneofCase.DelegationRemoved => new BakerEventDelegationRemoved(DelegatorId.From(bakerEvent.DelegationRemoved.DelegatorId)), BakerEvent.EventOneofCase.None => throw new MissingEnumException(bakerEvent.EventCase), _ => throw new MissingEnumException(bakerEvent.EventCase) @@ -141,4 +141,4 @@ public sealed record BakerSetFinalizationRewardCommissionEvent(BakerId BakerId, /// An existing delegator was removed. /// /// Delegator's id -public sealed record DelegationRemovedEvent(DelegatorId DelegatorId) : IBakerEvent; +public sealed record BakerEventDelegationRemoved(DelegatorId DelegatorId) : IBakerEvent; From b8a1eb3f2a8a8bf418442f056d7bdf10b3d70e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Fri, 13 Sep 2024 11:28:03 +0200 Subject: [PATCH 8/9] Add missing IBakerEvent case in GetBakerIds method --- src/Types/AccountTransactionEffects.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Types/AccountTransactionEffects.cs b/src/Types/AccountTransactionEffects.cs index a73f8e74..0eec678d 100644 --- a/src/Types/AccountTransactionEffects.cs +++ b/src/Types/AccountTransactionEffects.cs @@ -377,6 +377,8 @@ public IEnumerable GetBakerIds() case BakerStakeIncreasedEvent bakerStakeIncreasedEvent: yield return bakerStakeIncreasedEvent.BakerId; break; + case BakerEventDelegationRemoved delegatorId: + break; default: throw new MissingTypeException(bakerEvent); } From 34fe6f311899253d2b063c20ec1892b2536d1848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Holm=20Gj=C3=B8rup?= Date: Mon, 23 Sep 2024 10:01:51 +0200 Subject: [PATCH 9/9] Add helper function for creating an empty release schedule --- src/Types/ReleaseSchedule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Types/ReleaseSchedule.cs b/src/Types/ReleaseSchedule.cs index ccfd692a..bd32cd11 100644 --- a/src/Types/ReleaseSchedule.cs +++ b/src/Types/ReleaseSchedule.cs @@ -15,4 +15,10 @@ IList Schedules CcdAmount.From(schedule.Total), schedule.Schedules.Select(Release.From).ToList() ); + + /// + /// Construct an empty . + /// Useful for writing test cases. + /// + public static ReleaseSchedule Empty() => new(CcdAmount.Zero, new List()); }