Skip to content

Commit

Permalink
Add Quebec protocol support (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmirgaleev authored Jan 12, 2025
1 parent ee761f9 commit f4f552a
Show file tree
Hide file tree
Showing 62 changed files with 2,422 additions and 1,128 deletions.
6 changes: 5 additions & 1 deletion Tzkt.Sync/Protocols/Handlers/Initiator/Rpc/Rpc.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using Tzkt.Sync.Services;
using System.Text.Json;
using Tzkt.Sync.Services;

namespace Tzkt.Sync.Protocols.Initiator
{
sealed class Rpc : Proto1.Rpc
{
public Rpc(TezosNode node) : base(node) { }

public override Task<JsonElement> GetBlockAsync(int level)
=> Node.GetAsync($"chains/main/blocks/{level}");
}
}
207 changes: 108 additions & 99 deletions Tzkt.Sync/Protocols/Handlers/Proto12/Diagnostics/Diagnostics.cs
Original file line number Diff line number Diff line change
@@ -1,99 +1,108 @@
using System.Text.Json;
using Tzkt.Data.Models;
using Tzkt.Sync.Utils;

namespace Tzkt.Sync.Protocols.Proto12
{
class Diagnostics : Proto5.Diagnostics
{
public Diagnostics(ProtocolHandler handler) : base(handler) { }

protected override async Task TestDelegate(int level, Data.Models.Delegate delegat, Protocol proto)
{
var remote = await Rpc.GetDelegateAsync(level, delegat.Address);

if (remote.RequiredInt64("full_balance") != delegat.Balance)
throw new Exception($"Diagnostics failed: wrong balance {delegat.Address}");

if (remote.RequiredInt64("staking_balance") != delegat.StakingBalance)
throw new Exception($"Diagnostics failed: wrong staking balance {delegat.Address}");

if (!CheckDelegatedBalance(remote, delegat))
throw new Exception($"Diagnostics failed: wrong delegated balance {delegat.Address}");

if (remote.RequiredBool("deactivated") != !delegat.Staked)
throw new Exception($"Diagnostics failed: wrong deactivation state {delegat.Address}");

var deactivationCycle = (delegat.DeactivationLevel - 1) >= proto.FirstLevel
? proto.GetCycle(delegat.DeactivationLevel - 1)
: (await Cache.Blocks.GetAsync(delegat.DeactivationLevel - 1)).Cycle;

if (remote.RequiredInt32("grace_period") != deactivationCycle)
throw new Exception($"Diagnostics failed: wrong grace period {delegat.Address}");

if (remote.OptionalInt64("frozen_deposits_limit") != delegat.FrozenDepositLimit)
throw new Exception($"Diagnostics failed: wrong frozen deposits limit {delegat.Address}");

TestDelegatorsCount(remote, delegat);
}

protected override async Task TestParticipation(AppState state)
{
var bakers = Cache.Accounts.GetDelegates().ToList();
var bakerCycles = Db.ChangeTracker.Entries()
.Where(x => x.Entity is BakerCycle bc && bc.Cycle == state.Cycle)
.Select(x => x.Entity as BakerCycle)
.ToDictionary(x => x.BakerId);

foreach (var baker in bakers)
{
var remote = await Rpc.GetDelegateParticipationAsync(state.Level, baker.Address);

if (bakerCycles.TryGetValue(baker.Id, out var bakerCycle))
{
if ((long)bakerCycle.ExpectedEndorsements != remote.RequiredInt64("expected_cycle_activity"))
throw new Exception($"Invalid baker ExpectedEndorsements {baker.Address}");

if (bakerCycle.FutureEndorsementRewards != remote.RequiredInt64("expected_endorsing_rewards"))
throw new Exception($"Invalid baker FutureEndorsementRewards {baker.Address}");

if (bakerCycle.MissedEndorsements != remote.RequiredInt64("missed_slots"))
{
var proto = await Cache.Protocols.GetAsync(state.Protocol);
if (bakerCycle.Cycle != proto.FirstCycle)
throw new Exception($"Invalid baker MissedEndorsements {baker.Address}");
}
}
else
{
if (remote.RequiredInt64("expected_cycle_activity") != 0)
throw new Exception($"Invalid baker ExpectedEndorsements {baker.Address}");

if (remote.RequiredInt64("expected_endorsing_rewards") != 0)
throw new Exception($"Invalid baker FutureEndorsementRewards {baker.Address}");

if (remote.RequiredInt64("missed_slots") != 0)
throw new Exception($"Invalid baker MissedEndorsements {baker.Address}");
}
}
}

protected override async Task TestCycle(AppState state, Cycle cycle)
{
var level = Math.Min(state.Level, cycle.FirstLevel);
var remote = await Rpc.GetCycleAsync(level, cycle.Index);

if (remote.RequiredString("random_seed") != Hex.Convert(cycle.Seed))
throw new Exception($"Invalid cycle {cycle.Index} seed {Hex.Convert(cycle.Seed)}");

if (remote.RequiredInt64("total_active_stake") != cycle.TotalBakingPower)
throw new Exception($"Invalid cycle {cycle.Index} selected stake {cycle.TotalBakingPower}");

if (remote.RequiredArray("selected_stake_distribution").Count() != cycle.TotalBakers)
throw new Exception($"Invalid cycle {cycle.Index} selected bakers {cycle.TotalBakers}");
}

protected virtual bool CheckDelegatedBalance(JsonElement remote, Data.Models.Delegate delegat) =>
remote.RequiredInt64("delegated_balance") == delegat.DelegatedBalance + delegat.RollupBonds;
}
}
using System.Text.Json;
using Tzkt.Data.Models;
using Tzkt.Sync.Utils;

namespace Tzkt.Sync.Protocols.Proto12
{
class Diagnostics : Proto5.Diagnostics
{
public Diagnostics(ProtocolHandler handler) : base(handler) { }

protected override async Task TestDelegate(int level, Data.Models.Delegate delegat, Protocol proto)
{
var remote = await Rpc.GetDelegateAsync(level, delegat.Address);

if (!CheckFullBalance(remote, delegat))
throw new Exception($"Diagnostics failed: wrong balance {delegat.Address}");

if (!CheckStakingBalance(remote, delegat))
throw new Exception($"Diagnostics failed: wrong staking balance {delegat.Address}");

if (!CheckDelegatedBalance(remote, delegat))
throw new Exception($"Diagnostics failed: wrong delegated balance {delegat.Address}");

if (remote.RequiredBool("deactivated") != !delegat.Staked)
throw new Exception($"Diagnostics failed: wrong deactivation state {delegat.Address}");

var deactivationCycle = (delegat.DeactivationLevel - 1) >= proto.FirstLevel
? proto.GetCycle(delegat.DeactivationLevel - 1)
: (await Cache.Blocks.GetAsync(delegat.DeactivationLevel - 1)).Cycle;

if (remote.RequiredInt32("grace_period") != deactivationCycle)
throw new Exception($"Diagnostics failed: wrong grace period {delegat.Address}");

if (!CheckFrozenDepositLimit(remote, delegat))
throw new Exception($"Diagnostics failed: wrong frozen deposits limit {delegat.Address}");

TestDelegatorsCount(remote, delegat);
}

protected override async Task TestParticipation(AppState state)
{
var bakers = Cache.Accounts.GetDelegates().ToList();
var bakerCycles = Db.ChangeTracker.Entries()
.Where(x => x.Entity is BakerCycle bc && bc.Cycle == state.Cycle)
.Select(x => x.Entity as BakerCycle)
.ToDictionary(x => x.BakerId);

foreach (var baker in bakers)
{
var remote = await Rpc.GetDelegateParticipationAsync(state.Level, baker.Address);

if (bakerCycles.TryGetValue(baker.Id, out var bakerCycle))
{
if ((long)bakerCycle.ExpectedEndorsements != remote.RequiredInt64("expected_cycle_activity"))
throw new Exception($"Invalid baker ExpectedEndorsements {baker.Address}");

if (bakerCycle.FutureEndorsementRewards != remote.RequiredInt64("expected_endorsing_rewards"))
throw new Exception($"Invalid baker FutureEndorsementRewards {baker.Address}");

if (bakerCycle.MissedEndorsements != remote.RequiredInt64("missed_slots"))
{
var proto = await Cache.Protocols.GetAsync(state.Protocol);
if (bakerCycle.Cycle != proto.FirstCycle)
throw new Exception($"Invalid baker MissedEndorsements {baker.Address}");
}
}
else
{
if (remote.RequiredInt64("expected_cycle_activity") != 0)
throw new Exception($"Invalid baker ExpectedEndorsements {baker.Address}");

if (remote.RequiredInt64("expected_endorsing_rewards") != 0)
throw new Exception($"Invalid baker FutureEndorsementRewards {baker.Address}");

if (remote.RequiredInt64("missed_slots") != 0)
throw new Exception($"Invalid baker MissedEndorsements {baker.Address}");
}
}
}

protected override async Task TestCycle(AppState state, Cycle cycle)
{
var level = Math.Min(state.Level, cycle.FirstLevel);
var remote = await Rpc.GetCycleAsync(level, cycle.Index);

if (remote.RequiredString("random_seed") != Hex.Convert(cycle.Seed))
throw new Exception($"Invalid cycle {cycle.Index} seed {Hex.Convert(cycle.Seed)}");

if (remote.RequiredInt64("total_active_stake") != cycle.TotalBakingPower)
throw new Exception($"Invalid cycle {cycle.Index} selected stake {cycle.TotalBakingPower}");

if (remote.RequiredArray("selected_stake_distribution").Count() != cycle.TotalBakers)
throw new Exception($"Invalid cycle {cycle.Index} selected bakers {cycle.TotalBakers}");
}

protected virtual bool CheckFullBalance(JsonElement remote, Data.Models.Delegate delegat) =>
remote.RequiredInt64("full_balance") == delegat.Balance;

protected virtual bool CheckStakingBalance(JsonElement remote, Data.Models.Delegate delegat) =>
remote.RequiredInt64("staking_balance") == delegat.StakingBalance;

protected virtual bool CheckDelegatedBalance(JsonElement remote, Data.Models.Delegate delegat) =>
remote.RequiredInt64("delegated_balance") == delegat.DelegatedBalance + delegat.RollupBonds;

protected virtual bool CheckFrozenDepositLimit(JsonElement remote, Data.Models.Delegate delegat) =>
remote.RequiredInt64("frozen_deposits_limit") == delegat.FrozenDepositLimit;
}
}
Loading

0 comments on commit f4f552a

Please sign in to comment.