Skip to content

Commit

Permalink
Support node api v7
Browse files Browse the repository at this point in the history
  • Loading branch information
limemloh committed Sep 11, 2024
1 parent d60ea69 commit cc8d986
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 17 deletions.
53 changes: 48 additions & 5 deletions src/Types/AccountInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
/// </param>
/// <param name="Schedule">
/// Release schedule for any locked up amount. This could be an empty
/// release schedule.
/// </param>
/// <param name="Cooldowns">
/// 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.
/// </param>
/// <param name="AvailableBalance">
/// 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).
/// </param>
public sealed record AccountInfo(
AccountSequenceNumber AccountNonce,
CcdAmount AccountAmount,
AccountIndex AccountIndex,
AccountAddress AccountAddress,
IAccountStakingInfo? AccountStakingInfo)
IAccountStakingInfo? AccountStakingInfo,
ReleaseSchedule Schedule,
IList<Cooldown> 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
);
}
}
17 changes: 16 additions & 1 deletion src/Types/AccountStakingInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ namespace Concordium.Sdk.Types;
/// <summary>
/// Information related to staking for a specific account.
/// </summary>
public interface IAccountStakingInfo { }
public interface IAccountStakingInfo
{
/// <summary>
/// Get the amount of CCD being staked.
/// </summary>
public CcdAmount GetStakedAmount();
}

internal static class AccountStakingInfo
{
Expand Down Expand Up @@ -48,6 +54,11 @@ internal static AccountBaker From(Grpc.V2.AccountStakingInfo.Types.Baker stakeBa
StakedAmount: CcdAmount.From(stakeBaker.StakedAmount),
BakerPoolInfo: BakerPoolInfo.From(stakeBaker.PoolInfo)
);

/// <summary>
/// Get the amount of CCD being staked.
/// </summary>
public CcdAmount GetStakedAmount() => this.StakedAmount;
}

/// <summary>
Expand All @@ -67,4 +78,8 @@ internal static AccountDelegation From(Grpc.V2.AccountStakingInfo.Types.Delegato
DelegationTarget: DelegationTarget.From(stakeDelegator.Target),
PendingChange: AccountDelegationPendingChangeFactory.From(stakeDelegator.PendingChange)
);
/// <summary>
/// Get the amount of CCD being staked.
/// </summary>
public CcdAmount GetStakedAmount() => this.StakedAmount;
}
8 changes: 7 additions & 1 deletion src/Types/BakerEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.EventOneofCase>(bakerEvent.EventCase),
BakerEvent.EventOneofCase.DelegationRemoved => throw new NotImplementedException(),
_ => throw new MissingEnumException<BakerEvent.EventOneofCase>(bakerEvent.EventCase)
};
}
Expand Down Expand Up @@ -136,3 +136,9 @@ public sealed record BakerSetBakingRewardCommissionEvent(BakerId BakerId, Amount
/// <param name="BakerId">Baker's id</param>
/// <param name="FinalizationRewardCommission">The finalization reward commission</param>
public sealed record BakerSetFinalizationRewardCommissionEvent(BakerId BakerId, AmountFraction FinalizationRewardCommission) : IBakerEvent;

/// <summary>
/// An existing delegator was removed.
/// </summary>
/// <param name="DelegatorId">Delegator's id</param>
public sealed record DelegationRemovedEvent(DelegatorId DelegatorId) : IBakerEvent;
26 changes: 16 additions & 10 deletions src/Types/BakerPoolStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
/// </summary>
/// <remarks>
/// From protocol version 7, pool removal has immediate effect, however, the
/// pool may still be present for the current (and possibly next) reward period.
/// </remarks>
/// <param name="BakerId">The 'BakerId' of the pool owner.</param>
/// <param name="BakerAddress">The account address of the pool owner.</param>
/// <param name="BakerEquityCapital">The equity capital provided by the pool owner.</param>
/// <param name="DelegatedCapital">The capital delegated to the pool by other accounts.</param>
/// <param name="BakerEquityCapital">The equity capital provided by the pool owner. Absent if the pool is removed.</param>
/// <param name="DelegatedCapital">The capital delegated to the pool by other accounts. Absent if the pool is removed.</param>
/// <param name="DelegatedCapitalCap">
/// The maximum amount that may be delegated to the pool, accounting for
/// leverage and stake limits.
/// Absent if the pool is removed.
/// </param>
/// <param name="PoolInfo">
/// The pool info associated with the pool: open status, metadata URL
/// and commission rates.
/// Absent if the pool is removed.
/// </param>
/// <param name="CurrentPaydayStatus">
/// Status of the pool in the current reward period. This will be null
Expand All @@ -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)
Expand All @@ -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)
Expand Down
22 changes: 22 additions & 0 deletions src/Types/Cooldown.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Concordium.Sdk.Helpers;

namespace Concordium.Sdk.Types;

/// <summary>
/// The stake on the account that is in cooldown.
/// </summary>
/// <param name="EndTime">The time when the cooldown period ends.</param>
/// <param name="Amount">The amount that is in cooldown and set to be released at the end of the cooldown period.</param>
/// <param name="Status">The status of the cooldown.</param>
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()
);
}
48 changes: 48 additions & 0 deletions src/Types/CooldownStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Concordium.Sdk.Exceptions;

namespace Concordium.Sdk.Types;

/// <summary>
/// The status of a cooldown.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
public enum CooldownStatus
{
/// <summary>
/// The amount is in cooldown and will expire at the specified time, becoming available
/// at the subsequent pay day.
/// </summary>
Cooldown,
/// <summary>
/// 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.
/// </summary>
PreCooldown,
/// <summary>
/// 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.
/// </summary>
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<Grpc.V2.Cooldown.Types.CooldownStatus>(status)
};
}
13 changes: 13 additions & 0 deletions src/Types/DelegationEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal static IDelegationEvent From(DelegationEvent delegationEvent) =>
DelegationAdded.From(delegationEvent.DelegationAdded),
DelegationEvent.EventOneofCase.DelegationRemoved =>
DelegationRemoved.From(delegationEvent.DelegationRemoved),
DelegationEvent.EventOneofCase.BakerRemoved => DelegationEventBakerRemoved.From(delegationEvent.BakerRemoved),
DelegationEvent.EventOneofCase.None =>
throw new MissingEnumException<DelegationEvent.EventOneofCase>(delegationEvent.EventCase),
_ => throw new MissingEnumException<DelegationEvent.EventOneofCase>(delegationEvent.EventCase)
Expand Down Expand Up @@ -113,3 +114,15 @@ internal static DelegationRemoved From(Grpc.V2.DelegatorId id) =>
DelegatorId.From(id)
);
}

/// <summary>
/// A baker was removed.
/// </summary>
/// <param name="BakerId">Baker's id</param>
public sealed record DelegationEventBakerRemoved(BakerId BakerId) : IDelegationEvent
{
internal static DelegationEventBakerRemoved From(DelegationEvent.Types.BakerRemoved removed) =>
new(
BakerId.From(removed.BakerId)
);
}
22 changes: 22 additions & 0 deletions src/Types/Release.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Concordium.Sdk.Helpers;

namespace Concordium.Sdk.Types;

/// <summary>
/// An individual release of a locked balance.
/// </summary>
/// <param name="Timestamp">Effective time of the release.</param>
/// <param name="Amount">Amount to be released.</param>
/// <param name="Transactions">List of transaction hashes that contribute a balance to this release.</param>
public sealed record Release(
DateTimeOffset Timestamp,
CcdAmount Amount,
IList<TransactionHash> Transactions
)
{
internal static Release From(Grpc.V2.Release release) => new(
release.Timestamp.ToDateTimeOffset(),
CcdAmount.From(release.Amount),
release.Transactions.Select(TransactionHash.From).ToList()
);
}
18 changes: 18 additions & 0 deletions src/Types/ReleaseSchedule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Concordium.Sdk.Types;

/// <summary>
/// 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.
/// </summary>
/// <param name="Total">Total amount locked in the release schedule.</param>
/// <param name="Schedules">A list of releases, ordered by increasing timestamp.</param>
public sealed record ReleaseSchedule(
CcdAmount Total,
IList<Release> Schedules
)
{
internal static ReleaseSchedule From(Grpc.V2.ReleaseSchedule schedule) => new(
CcdAmount.From(schedule.Total),
schedule.Schedules.Select(Release.From).ToList()
);
}

0 comments on commit cc8d986

Please sign in to comment.