From 5567ecc13776e43a88071ec30bb26548814b414e Mon Sep 17 00:00:00 2001 From: Maksim Strebkov <257byte@gmail.com> Date: Sat, 29 Jun 2024 15:14:17 +0300 Subject: [PATCH] Add allocation fee to drain delegate operations --- .../Operations/DrainDelegateOperation.cs | 5 + .../Repositories/BalanceHistoryRepository.cs | 4 +- .../OperationRepository.DrainDelegate.cs | 13 + Tzkt.Api/Repositories/ReportRepository.cs | 2 +- Tzkt.Api/Services/Home/HomeService.cs | 4 +- ...0240629103331_DrainDelegateExt.Designer.cs | 6933 +++++++++++++++++ .../20240629103331_DrainDelegateExt.cs | 29 + .../Migrations/TzktContextModelSnapshot.cs | 5 +- .../Operations/DrainDelegateOperation.cs | 1 + Tzkt.Sync.Tests/Database/StatisticsTests.cs | 1 + .../Commits/Operations/DrainDelegateCommit.cs | 51 +- .../Handlers/Proto19/Validation/Validator.cs | 1027 +-- 12 files changed, 7034 insertions(+), 1041 deletions(-) create mode 100644 Tzkt.Data/Migrations/20240629103331_DrainDelegateExt.Designer.cs create mode 100644 Tzkt.Data/Migrations/20240629103331_DrainDelegateExt.cs diff --git a/Tzkt.Api/Models/Operations/DrainDelegateOperation.cs b/Tzkt.Api/Models/Operations/DrainDelegateOperation.cs index 9c7d56429..27e348d48 100644 --- a/Tzkt.Api/Models/Operations/DrainDelegateOperation.cs +++ b/Tzkt.Api/Models/Operations/DrainDelegateOperation.cs @@ -52,6 +52,11 @@ public class DrainDelegateOperation : Operation /// public long Fee { get; set; } + /// + /// The amount of funds burned from the drained baker for account creation (micro tez) + /// + public long AllocationFee { get; set; } + #region injecting /// /// Injected historical quote at the time of operation diff --git a/Tzkt.Api/Repositories/BalanceHistoryRepository.cs b/Tzkt.Api/Repositories/BalanceHistoryRepository.cs index 8b6ec6532..9264eced0 100644 --- a/Tzkt.Api/Repositories/BalanceHistoryRepository.cs +++ b/Tzkt.Api/Repositories/BalanceHistoryRepository.cs @@ -915,7 +915,7 @@ void SumDrainDelegateOps(StringBuilder sql, int from, int to) sql.Append(sql.Length == 0 ? "SELECT " : "UNION ALL SELECT "); #region delegate - sql.Append(@"SUM(-""Amount"" - ""Fee"") as ""Change"" "); + sql.Append(@"SUM(-""Amount"" - ""Fee"" - ""AllocationFee"") as ""Change"" "); sql.Append(@"FROM ""DrainDelegateOps"" "); sql.Append(@"WHERE ""DelegateId"" = @account "); @@ -1782,7 +1782,7 @@ void UnionDrainDelegateOps(StringBuilder sql) #region delegate sql.Append(@"""Level"" as ""Level"", "); - sql.Append(@"(-""Amount"" - ""Fee"") as ""Change"" "); + sql.Append(@"(-""Amount"" - ""Fee"" - ""AllocationFee"") as ""Change"" "); sql.Append(@"FROM ""DrainDelegateOps"" "); sql.Append(@"WHERE ""DelegateId"" = @account "); diff --git a/Tzkt.Api/Repositories/OperationRepository.DrainDelegate.cs b/Tzkt.Api/Repositories/OperationRepository.DrainDelegate.cs index e78dd86b7..e1e9018ac 100644 --- a/Tzkt.Api/Repositories/OperationRepository.DrainDelegate.cs +++ b/Tzkt.Api/Repositories/OperationRepository.DrainDelegate.cs @@ -41,6 +41,7 @@ INNER JOIN ""Blocks"" as b Target = Accounts.GetAlias(row.TargetId), Amount = row.Amount, Fee = row.Fee, + AllocationFee = row.AllocationFee, Quote = Quotes.Get(quote, row.Level) }); } @@ -67,6 +68,7 @@ public async Task> GetDrainDelegates(Block b Target = Accounts.GetAlias(row.TargetId), Amount = row.Amount, Fee = row.Fee, + AllocationFee = row.AllocationFee, Quote = Quotes.Get(quote, block.Level) }); } @@ -108,6 +110,7 @@ public async Task> GetDrainDelegates( Target = Accounts.GetAlias(row.TargetId), Amount = row.Amount, Fee = row.Fee, + AllocationFee = row.AllocationFee, Quote = Quotes.Get(quote, row.Level) }); } @@ -139,6 +142,7 @@ public async Task GetDrainDelegates( case "target": columns.Add(@"o.""TargetId"""); break; case "amount": columns.Add(@"o.""Amount"""); break; case "fee": columns.Add(@"o.""Fee"""); break; + case "allocationFee": columns.Add(@"o.""AllocationFee"""); break; case "block": columns.Add(@"b.""Hash"""); joins.Add(@"INNER JOIN ""Blocks"" as b ON b.""Level"" = o.""Level"""); @@ -209,6 +213,10 @@ public async Task GetDrainDelegates( foreach (var row in rows) result[j++][i] = row.Fee; break; + case "allocationFee": + foreach (var row in rows) + result[j++][i] = row.AllocationFee; + break; case "quote": foreach (var row in rows) result[j++][i] = Quotes.Get(quote, row.Level); @@ -244,6 +252,7 @@ public async Task GetDrainDelegates( case "target": columns.Add(@"o.""TargetId"""); break; case "amount": columns.Add(@"o.""Amount"""); break; case "fee": columns.Add(@"o.""Fee"""); break; + case "allocationFee": columns.Add(@"o.""AllocationFee"""); break; case "block": columns.Add(@"b.""Hash"""); joins.Add(@"INNER JOIN ""Blocks"" as b ON b.""Level"" = o.""Level"""); @@ -311,6 +320,10 @@ public async Task GetDrainDelegates( foreach (var row in rows) result[j++] = row.Fee; break; + case "allocationFee": + foreach (var row in rows) + result[j++] = row.AllocationFee; + break; case "quote": foreach (var row in rows) result[j++] = Quotes.Get(quote, row.Level); diff --git a/Tzkt.Api/Repositories/ReportRepository.cs b/Tzkt.Api/Repositories/ReportRepository.cs index 1a36cd5a2..6351e0ef8 100644 --- a/Tzkt.Api/Repositories/ReportRepository.cs +++ b/Tzkt.Api/Repositories/ReportRepository.cs @@ -1520,7 +1520,7 @@ void UnionDrainDelegateOps(StringBuilder sql) sql.Append(@"null::integer as ""Received"", "); sql.Append(@"null::integer as ""From"", "); sql.Append(@"""Amount"" as ""Sent"", "); - sql.Append(@"""Fee"" as ""Fee"", "); + sql.Append(@"(""Fee"" + ""AllocationFee"") as ""Fee"", "); sql.Append(@"""TargetId"" as ""To"" "); sql.Append(@"FROM ""DrainDelegateOps"" "); diff --git a/Tzkt.Api/Services/Home/HomeService.cs b/Tzkt.Api/Services/Home/HomeService.cs index 7eb46fff0..566f61cf8 100644 --- a/Tzkt.Api/Services/Home/HomeService.cs +++ b/Tzkt.Api/Services/Home/HomeService.cs @@ -353,7 +353,7 @@ SELECT SUM(""BakerFee"")::bigint AS fee, 0::bigint AS burn FROM ""DalPublishComm UNION ALL SELECT SUM(""BakerFee"")::bigint AS fee, 0::bigint AS burn FROM ""DelegationOps"" WHERE ""Level"" >= {currPeriod} UNION ALL - SELECT SUM(""Fee"")::bigint AS fee, 0::bigint AS burn FROM ""DrainDelegateOps"" WHERE ""Level"" >= {currPeriod} + SELECT SUM(""Fee"")::bigint AS fee, SUM(""AllocationFee"")::bigint AS burn FROM ""DrainDelegateOps"" WHERE ""Level"" >= {currPeriod} UNION ALL SELECT SUM(""BakerFee"")::bigint AS fee, SUM(COALESCE(""StorageFee"", 0))::bigint AS burn FROM ""IncreasePaidStorageOps"" WHERE ""Level"" >= {currPeriod} UNION ALL @@ -431,7 +431,7 @@ SELECT SUM(""BakerFee"")::bigint AS fee, 0::bigint AS burn FROM ""DalPublishComm UNION ALL SELECT SUM(""BakerFee"")::bigint AS fee, 0::bigint AS burn FROM ""DelegationOps"" WHERE ""Level"" >= {prevPeriod} AND ""Level"" < {currPeriod} UNION ALL - SELECT SUM(""Fee"")::bigint AS fee, 0::bigint AS burn FROM ""DrainDelegateOps"" WHERE ""Level"" >= {prevPeriod} AND ""Level"" < {currPeriod} + SELECT SUM(""Fee"")::bigint AS fee, SUM(""AllocationFee"")::bigint AS burn FROM ""DrainDelegateOps"" WHERE ""Level"" >= {prevPeriod} AND ""Level"" < {currPeriod} UNION ALL SELECT SUM(""BakerFee"")::bigint AS fee, SUM(COALESCE(""StorageFee"", 0))::bigint AS burn FROM ""IncreasePaidStorageOps"" WHERE ""Level"" >= {prevPeriod} AND ""Level"" < {currPeriod} UNION ALL diff --git a/Tzkt.Data/Migrations/20240629103331_DrainDelegateExt.Designer.cs b/Tzkt.Data/Migrations/20240629103331_DrainDelegateExt.Designer.cs new file mode 100644 index 000000000..58f865c25 --- /dev/null +++ b/Tzkt.Data/Migrations/20240629103331_DrainDelegateExt.Designer.cs @@ -0,0 +1,6933 @@ +// +using System; +using System.Numerics; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Tzkt.Data; + +#nullable disable + +namespace Tzkt.Data.Migrations +{ + [DbContext(typeof(TzktContext))] + [Migration("20240629103331_DrainDelegateExt")] + partial class DrainDelegateExt + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.18") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Tzkt.Data.Models.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActiveRefutationGamesCount") + .HasColumnType("integer"); + + b.Property("ActiveTicketsCount") + .HasColumnType("integer"); + + b.Property("ActiveTokensCount") + .HasColumnType("integer"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(37) + .HasColumnType("character varying(37)"); + + b.Property("Balance") + .HasColumnType("bigint"); + + b.Property("ContractsCount") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("DelegateId") + .HasColumnType("integer"); + + b.Property("DelegationLevel") + .HasColumnType("integer"); + + b.Property("DelegationsCount") + .HasColumnType("integer"); + + b.Property("DrainDelegateCount") + .HasColumnType("integer"); + + b.Property("Extras") + .HasColumnType("jsonb"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("IncreasePaidStorageCount") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("Metadata") + .HasColumnType("jsonb"); + + b.Property("MigrationsCount") + .HasColumnType("integer"); + + b.Property("OriginationsCount") + .HasColumnType("integer"); + + b.Property("RefutationGamesCount") + .HasColumnType("integer"); + + b.Property("RevealsCount") + .HasColumnType("integer"); + + b.Property("RollupBonds") + .HasColumnType("bigint"); + + b.Property("RollupsCount") + .HasColumnType("integer"); + + b.Property("SmartRollupAddMessagesCount") + .HasColumnType("integer"); + + b.Property("SmartRollupBonds") + .HasColumnType("bigint"); + + b.Property("SmartRollupCementCount") + .HasColumnType("integer"); + + b.Property("SmartRollupExecuteCount") + .HasColumnType("integer"); + + b.Property("SmartRollupOriginateCount") + .HasColumnType("integer"); + + b.Property("SmartRollupPublishCount") + .HasColumnType("integer"); + + b.Property("SmartRollupRecoverBondCount") + .HasColumnType("integer"); + + b.Property("SmartRollupRefuteCount") + .HasColumnType("integer"); + + b.Property("SmartRollupsCount") + .HasColumnType("integer"); + + b.Property("Staked") + .HasColumnType("boolean"); + + b.Property("TicketBalancesCount") + .HasColumnType("integer"); + + b.Property("TicketTransfersCount") + .HasColumnType("integer"); + + b.Property("TokenBalancesCount") + .HasColumnType("integer"); + + b.Property("TokenTransfersCount") + .HasColumnType("integer"); + + b.Property("TransactionsCount") + .HasColumnType("integer"); + + b.Property("TransferTicketCount") + .HasColumnType("integer"); + + b.Property("TxRollupCommitCount") + .HasColumnType("integer"); + + b.Property("TxRollupDispatchTicketsCount") + .HasColumnType("integer"); + + b.Property("TxRollupFinalizeCommitmentCount") + .HasColumnType("integer"); + + b.Property("TxRollupOriginationCount") + .HasColumnType("integer"); + + b.Property("TxRollupRejectionCount") + .HasColumnType("integer"); + + b.Property("TxRollupRemoveCommitmentCount") + .HasColumnType("integer"); + + b.Property("TxRollupReturnBondCount") + .HasColumnType("integer"); + + b.Property("TxRollupSubmitBatchCount") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("UpdateConsensusKeyCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Address") + .IsUnique(); + + b.HasIndex("DelegateId"); + + b.HasIndex("Extras"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Extras"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("Extras"), new[] { "jsonb_path_ops" }); + + b.HasIndex("FirstLevel"); + + b.HasIndex("Metadata"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Metadata"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("Metadata"), new[] { "jsonb_path_ops" }); + + b.HasIndex("Type"); + + b.HasIndex("Staked", "Type") + .HasFilter("\"Staked\" = true"); + + b.ToTable("Accounts"); + + b.HasDiscriminator("Type").HasValue((byte)3); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Tzkt.Data.Models.ActivationOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer"); + + b.Property("Balance") + .HasColumnType("bigint"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AccountId") + .IsUnique(); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.ToTable("ActivationOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.AppState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountCounter") + .HasColumnType("integer"); + + b.Property("ActivationOpsCount") + .HasColumnType("integer"); + + b.Property("AutostakingOpsCount") + .HasColumnType("integer"); + + b.Property("BallotOpsCount") + .HasColumnType("integer"); + + b.Property("BigMapCounter") + .HasColumnType("integer"); + + b.Property("BigMapKeyCounter") + .HasColumnType("integer"); + + b.Property("BigMapUpdateCounter") + .HasColumnType("integer"); + + b.Property("BlocksCount") + .HasColumnType("integer"); + + b.Property("Chain") + .HasColumnType("text"); + + b.Property("ChainId") + .HasColumnType("text"); + + b.Property("CommitmentsCount") + .HasColumnType("integer"); + + b.Property("ConstantsCount") + .HasColumnType("integer"); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("CyclesCount") + .HasColumnType("integer"); + + b.Property("DalPublishCommitmentOpsCount") + .HasColumnType("integer"); + + b.Property("DelegationOpsCount") + .HasColumnType("integer"); + + b.Property("DomainsLevel") + .HasColumnType("integer"); + + b.Property("DomainsNameRegistry") + .HasColumnType("text"); + + b.Property("DoubleBakingOpsCount") + .HasColumnType("integer"); + + b.Property("DoubleEndorsingOpsCount") + .HasColumnType("integer"); + + b.Property("DoublePreendorsingOpsCount") + .HasColumnType("integer"); + + b.Property("DrainDelegateOpsCount") + .HasColumnType("integer"); + + b.Property("EndorsementOpsCount") + .HasColumnType("integer"); + + b.Property("EndorsingRewardOpsCount") + .HasColumnType("integer"); + + b.Property("EventCounter") + .HasColumnType("integer"); + + b.Property("EventsCount") + .HasColumnType("integer"); + + b.Property("Extras") + .HasColumnType("jsonb"); + + b.Property("Hash") + .HasColumnType("text"); + + b.Property("InboxMessageCounter") + .HasColumnType("integer"); + + b.Property("IncreasePaidStorageOpsCount") + .HasColumnType("integer"); + + b.Property("KnownHead") + .HasColumnType("integer"); + + b.Property("LastSync") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("ManagerCounter") + .HasColumnType("integer"); + + b.Property("MigrationOpsCount") + .HasColumnType("integer"); + + b.Property("NextProtocol") + .HasColumnType("text"); + + b.Property("NonceRevelationOpsCount") + .HasColumnType("integer"); + + b.Property("OperationCounter") + .HasColumnType("bigint"); + + b.Property("OriginationOpsCount") + .HasColumnType("integer"); + + b.Property("PendingDelegateParameters") + .HasColumnType("integer"); + + b.Property("PreendorsementOpsCount") + .HasColumnType("integer"); + + b.Property("ProposalOpsCount") + .HasColumnType("integer"); + + b.Property("ProposalsCount") + .HasColumnType("integer"); + + b.Property("Protocol") + .HasColumnType("text"); + + b.Property("ProtocolsCount") + .HasColumnType("integer"); + + b.Property("QuoteBtc") + .HasColumnType("double precision"); + + b.Property("QuoteCny") + .HasColumnType("double precision"); + + b.Property("QuoteEth") + .HasColumnType("double precision"); + + b.Property("QuoteEur") + .HasColumnType("double precision"); + + b.Property("QuoteGbp") + .HasColumnType("double precision"); + + b.Property("QuoteJpy") + .HasColumnType("double precision"); + + b.Property("QuoteKrw") + .HasColumnType("double precision"); + + b.Property("QuoteLevel") + .HasColumnType("integer"); + + b.Property("QuoteUsd") + .HasColumnType("double precision"); + + b.Property("RefutationGameCounter") + .HasColumnType("integer"); + + b.Property("RegisterConstantOpsCount") + .HasColumnType("integer"); + + b.Property("RevealOpsCount") + .HasColumnType("integer"); + + b.Property("RevelationPenaltyOpsCount") + .HasColumnType("integer"); + + b.Property("ScriptCounter") + .HasColumnType("integer"); + + b.Property("SetDelegateParametersOpsCount") + .HasColumnType("integer"); + + b.Property("SetDepositsLimitOpsCount") + .HasColumnType("integer"); + + b.Property("SmartRollupAddMessagesOpsCount") + .HasColumnType("integer"); + + b.Property("SmartRollupCementOpsCount") + .HasColumnType("integer"); + + b.Property("SmartRollupCommitmentCounter") + .HasColumnType("integer"); + + b.Property("SmartRollupExecuteOpsCount") + .HasColumnType("integer"); + + b.Property("SmartRollupOriginateOpsCount") + .HasColumnType("integer"); + + b.Property("SmartRollupPublishOpsCount") + .HasColumnType("integer"); + + b.Property("SmartRollupRecoverBondOpsCount") + .HasColumnType("integer"); + + b.Property("SmartRollupRefuteOpsCount") + .HasColumnType("integer"); + + b.Property("StakingOpsCount") + .HasColumnType("integer"); + + b.Property("StakingUpdatesCount") + .HasColumnType("integer"); + + b.Property("StorageCounter") + .HasColumnType("integer"); + + b.Property("TicketBalancesCount") + .HasColumnType("integer"); + + b.Property("TicketTransfersCount") + .HasColumnType("integer"); + + b.Property("TicketsCount") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("TokenBalancesCount") + .HasColumnType("integer"); + + b.Property("TokenTransfersCount") + .HasColumnType("integer"); + + b.Property("TokensCount") + .HasColumnType("integer"); + + b.Property("TransactionOpsCount") + .HasColumnType("integer"); + + b.Property("TransferTicketOpsCount") + .HasColumnType("integer"); + + b.Property("TxRollupCommitOpsCount") + .HasColumnType("integer"); + + b.Property("TxRollupDispatchTicketsOpsCount") + .HasColumnType("integer"); + + b.Property("TxRollupFinalizeCommitmentOpsCount") + .HasColumnType("integer"); + + b.Property("TxRollupOriginationOpsCount") + .HasColumnType("integer"); + + b.Property("TxRollupRejectionOpsCount") + .HasColumnType("integer"); + + b.Property("TxRollupRemoveCommitmentOpsCount") + .HasColumnType("integer"); + + b.Property("TxRollupReturnBondOpsCount") + .HasColumnType("integer"); + + b.Property("TxRollupSubmitBatchOpsCount") + .HasColumnType("integer"); + + b.Property("UnstakeRequestsCount") + .HasColumnType("integer"); + + b.Property("UpdateConsensusKeyOpsCount") + .HasColumnType("integer"); + + b.Property("VdfRevelationOpsCount") + .HasColumnType("integer"); + + b.Property("VotingEpoch") + .HasColumnType("integer"); + + b.Property("VotingPeriod") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("AppState"); + + b.HasData( + new + { + Id = -1, + AccountCounter = 0, + ActivationOpsCount = 0, + AutostakingOpsCount = 0, + BallotOpsCount = 0, + BigMapCounter = 0, + BigMapKeyCounter = 0, + BigMapUpdateCounter = 0, + BlocksCount = 0, + CommitmentsCount = 0, + ConstantsCount = 0, + Cycle = -1, + CyclesCount = 0, + DalPublishCommitmentOpsCount = 0, + DelegationOpsCount = 0, + DomainsLevel = 0, + DoubleBakingOpsCount = 0, + DoubleEndorsingOpsCount = 0, + DoublePreendorsingOpsCount = 0, + DrainDelegateOpsCount = 0, + EndorsementOpsCount = 0, + EndorsingRewardOpsCount = 0, + EventCounter = 0, + EventsCount = 0, + Hash = "", + InboxMessageCounter = 0, + IncreasePaidStorageOpsCount = 0, + KnownHead = 0, + LastSync = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + Level = -1, + ManagerCounter = 0, + MigrationOpsCount = 0, + NextProtocol = "", + NonceRevelationOpsCount = 0, + OperationCounter = 0L, + OriginationOpsCount = 0, + PendingDelegateParameters = 0, + PreendorsementOpsCount = 0, + ProposalOpsCount = 0, + ProposalsCount = 0, + Protocol = "", + ProtocolsCount = 0, + QuoteBtc = 0.0, + QuoteCny = 0.0, + QuoteEth = 0.0, + QuoteEur = 0.0, + QuoteGbp = 0.0, + QuoteJpy = 0.0, + QuoteKrw = 0.0, + QuoteLevel = -1, + QuoteUsd = 0.0, + RefutationGameCounter = 0, + RegisterConstantOpsCount = 0, + RevealOpsCount = 0, + RevelationPenaltyOpsCount = 0, + ScriptCounter = 0, + SetDelegateParametersOpsCount = 0, + SetDepositsLimitOpsCount = 0, + SmartRollupAddMessagesOpsCount = 0, + SmartRollupCementOpsCount = 0, + SmartRollupCommitmentCounter = 0, + SmartRollupExecuteOpsCount = 0, + SmartRollupOriginateOpsCount = 0, + SmartRollupPublishOpsCount = 0, + SmartRollupRecoverBondOpsCount = 0, + SmartRollupRefuteOpsCount = 0, + StakingOpsCount = 0, + StakingUpdatesCount = 0, + StorageCounter = 0, + TicketBalancesCount = 0, + TicketTransfersCount = 0, + TicketsCount = 0, + Timestamp = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + TokenBalancesCount = 0, + TokenTransfersCount = 0, + TokensCount = 0, + TransactionOpsCount = 0, + TransferTicketOpsCount = 0, + TxRollupCommitOpsCount = 0, + TxRollupDispatchTicketsOpsCount = 0, + TxRollupFinalizeCommitmentOpsCount = 0, + TxRollupOriginationOpsCount = 0, + TxRollupRejectionOpsCount = 0, + TxRollupRemoveCommitmentOpsCount = 0, + TxRollupReturnBondOpsCount = 0, + TxRollupSubmitBatchOpsCount = 0, + UnstakeRequestsCount = 0, + UpdateConsensusKeyOpsCount = 0, + VdfRevelationOpsCount = 0, + VotingEpoch = -1, + VotingPeriod = -1 + }); + }); + + modelBuilder.Entity("Tzkt.Data.Models.AutostakingOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("StakingUpdatesCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("BakerId"); + + b.HasIndex("Level"); + + b.ToTable("AutostakingOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.BakerCycle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("BakingPower") + .HasColumnType("bigint"); + + b.Property("BlockFees") + .HasColumnType("bigint"); + + b.Property("BlockRewardsDelegated") + .HasColumnType("bigint"); + + b.Property("BlockRewardsStakedEdge") + .HasColumnType("bigint"); + + b.Property("BlockRewardsStakedOwn") + .HasColumnType("bigint"); + + b.Property("BlockRewardsStakedShared") + .HasColumnType("bigint"); + + b.Property("Blocks") + .HasColumnType("integer"); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("DelegatorsCount") + .HasColumnType("integer"); + + b.Property("DoubleBakingLostExternalStaked") + .HasColumnType("bigint"); + + b.Property("DoubleBakingLostExternalUnstaked") + .HasColumnType("bigint"); + + b.Property("DoubleBakingLostStaked") + .HasColumnType("bigint"); + + b.Property("DoubleBakingLostUnstaked") + .HasColumnType("bigint"); + + b.Property("DoubleBakingRewards") + .HasColumnType("bigint"); + + b.Property("DoubleEndorsingLostExternalStaked") + .HasColumnType("bigint"); + + b.Property("DoubleEndorsingLostExternalUnstaked") + .HasColumnType("bigint"); + + b.Property("DoubleEndorsingLostStaked") + .HasColumnType("bigint"); + + b.Property("DoubleEndorsingLostUnstaked") + .HasColumnType("bigint"); + + b.Property("DoubleEndorsingRewards") + .HasColumnType("bigint"); + + b.Property("DoublePreendorsingLostExternalStaked") + .HasColumnType("bigint"); + + b.Property("DoublePreendorsingLostExternalUnstaked") + .HasColumnType("bigint"); + + b.Property("DoublePreendorsingLostStaked") + .HasColumnType("bigint"); + + b.Property("DoublePreendorsingLostUnstaked") + .HasColumnType("bigint"); + + b.Property("DoublePreendorsingRewards") + .HasColumnType("bigint"); + + b.Property("EndorsementRewardsDelegated") + .HasColumnType("bigint"); + + b.Property("EndorsementRewardsStakedEdge") + .HasColumnType("bigint"); + + b.Property("EndorsementRewardsStakedOwn") + .HasColumnType("bigint"); + + b.Property("EndorsementRewardsStakedShared") + .HasColumnType("bigint"); + + b.Property("Endorsements") + .HasColumnType("integer"); + + b.Property("ExpectedBlocks") + .HasColumnType("double precision"); + + b.Property("ExpectedEndorsements") + .HasColumnType("double precision"); + + b.Property("ExternalDelegatedBalance") + .HasColumnType("bigint"); + + b.Property("ExternalStakedBalance") + .HasColumnType("bigint"); + + b.Property("FutureBlockRewards") + .HasColumnType("bigint"); + + b.Property("FutureBlocks") + .HasColumnType("integer"); + + b.Property("FutureEndorsementRewards") + .HasColumnType("bigint"); + + b.Property("FutureEndorsements") + .HasColumnType("integer"); + + b.Property("MissedBlockFees") + .HasColumnType("bigint"); + + b.Property("MissedBlockRewards") + .HasColumnType("bigint"); + + b.Property("MissedBlocks") + .HasColumnType("integer"); + + b.Property("MissedEndorsementRewards") + .HasColumnType("bigint"); + + b.Property("MissedEndorsements") + .HasColumnType("integer"); + + b.Property("NonceRevelationLosses") + .HasColumnType("bigint"); + + b.Property("NonceRevelationRewardsDelegated") + .HasColumnType("bigint"); + + b.Property("NonceRevelationRewardsStakedEdge") + .HasColumnType("bigint"); + + b.Property("NonceRevelationRewardsStakedOwn") + .HasColumnType("bigint"); + + b.Property("NonceRevelationRewardsStakedShared") + .HasColumnType("bigint"); + + b.Property("OwnDelegatedBalance") + .HasColumnType("bigint"); + + b.Property("OwnStakedBalance") + .HasColumnType("bigint"); + + b.Property("StakersCount") + .HasColumnType("integer"); + + b.Property("TotalBakingPower") + .HasColumnType("bigint"); + + b.Property("VdfRevelationRewardsDelegated") + .HasColumnType("bigint"); + + b.Property("VdfRevelationRewardsStakedEdge") + .HasColumnType("bigint"); + + b.Property("VdfRevelationRewardsStakedOwn") + .HasColumnType("bigint"); + + b.Property("VdfRevelationRewardsStakedShared") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("BakerId"); + + b.HasIndex("Cycle", "BakerId"); + + b.ToTable("BakerCycles"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.BakingRight", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Round") + .HasColumnType("integer"); + + b.Property("Slots") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("Cycle", "BakerId"); + + b.ToTable("BakingRights"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.BallotOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Epoch") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Period") + .HasColumnType("integer"); + + b.Property("ProposalId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Vote") + .HasColumnType("integer"); + + b.Property("VotingPower") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Epoch"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("Period"); + + b.HasIndex("ProposalId"); + + b.HasIndex("SenderId"); + + b.ToTable("BallotOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.BigMap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ActiveKeys") + .HasColumnType("integer"); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("KeyType") + .HasColumnType("bytea"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("Ptr") + .HasColumnType("integer"); + + b.Property("StoragePath") + .HasColumnType("text"); + + b.Property("Tags") + .HasColumnType("integer"); + + b.Property("TotalKeys") + .HasColumnType("integer"); + + b.Property("Updates") + .HasColumnType("integer"); + + b.Property("ValueType") + .HasColumnType("bytea"); + + b.HasKey("Id"); + + b.HasIndex("ContractId"); + + b.HasIndex("Ptr") + .IsUnique(); + + b.ToTable("BigMaps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.BigMapKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("BigMapPtr") + .HasColumnType("integer"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("JsonKey") + .HasColumnType("jsonb"); + + b.Property("JsonValue") + .HasColumnType("jsonb"); + + b.Property("KeyHash") + .HasMaxLength(54) + .HasColumnType("character(54)") + .IsFixedLength(); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("RawKey") + .HasColumnType("bytea"); + + b.Property("RawValue") + .HasColumnType("bytea"); + + b.Property("Updates") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("JsonKey"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("JsonKey"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("JsonKey"), new[] { "jsonb_path_ops" }); + + b.HasIndex("JsonValue"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("JsonValue"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("JsonValue"), new[] { "jsonb_path_ops" }); + + b.HasIndex("LastLevel"); + + b.HasIndex("BigMapPtr", "KeyHash"); + + b.HasIndex(new[] { "BigMapPtr" }, "IX_BigMapKeys_BigMapPtr_Partial") + .HasFilter("\"Active\" = true"); + + b.ToTable("BigMapKeys"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.BigMapUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("BigMapKeyId") + .HasColumnType("integer"); + + b.Property("BigMapPtr") + .HasColumnType("integer"); + + b.Property("JsonValue") + .HasColumnType("jsonb"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("MigrationId") + .HasColumnType("bigint"); + + b.Property("OriginationId") + .HasColumnType("bigint"); + + b.Property("RawValue") + .HasColumnType("bytea"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("MigrationId") + .HasFilter("\"MigrationId\" IS NOT NULL"); + + b.HasIndex("OriginationId") + .HasFilter("\"OriginationId\" IS NOT NULL"); + + b.HasIndex("TransactionId") + .HasFilter("\"TransactionId\" IS NOT NULL"); + + b.HasIndex("BigMapKeyId", "Id") + .HasFilter("\"BigMapKeyId\" IS NOT NULL"); + + b.HasIndex("BigMapPtr", "Id"); + + b.ToTable("BigMapUpdates"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Block", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AIToggle") + .HasColumnType("boolean"); + + b.Property("AIToggleEma") + .HasColumnType("integer"); + + b.Property("BlockRound") + .HasColumnType("integer"); + + b.Property("BonusDelegated") + .HasColumnType("bigint"); + + b.Property("BonusStakedEdge") + .HasColumnType("bigint"); + + b.Property("BonusStakedOwn") + .HasColumnType("bigint"); + + b.Property("BonusStakedShared") + .HasColumnType("bigint"); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("Deposit") + .HasColumnType("bigint"); + + b.Property("Events") + .HasColumnType("integer"); + + b.Property("Extras") + .HasColumnType("jsonb"); + + b.Property("Fees") + .HasColumnType("bigint"); + + b.Property("Hash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("LBToggle") + .HasColumnType("boolean"); + + b.Property("LBToggleEma") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Operations") + .HasColumnType("bigint"); + + b.Property("PayloadRound") + .HasColumnType("integer"); + + b.Property("ProducerId") + .HasColumnType("integer"); + + b.Property("ProposerId") + .HasColumnType("integer"); + + b.Property("ProtoCode") + .HasColumnType("integer"); + + b.Property("ResetBakerDeactivation") + .HasColumnType("integer"); + + b.Property("ResetProposerDeactivation") + .HasColumnType("integer"); + + b.Property("RevelationId") + .HasColumnType("bigint"); + + b.Property("RewardDelegated") + .HasColumnType("bigint"); + + b.Property("RewardStakedEdge") + .HasColumnType("bigint"); + + b.Property("RewardStakedOwn") + .HasColumnType("bigint"); + + b.Property("RewardStakedShared") + .HasColumnType("bigint"); + + b.Property("SoftwareId") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Validations") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("Level") + .IsUnique(); + + b.HasIndex("ProducerId"); + + b.HasIndex("ProposerId"); + + b.HasIndex("ProtoCode"); + + b.HasIndex("RevelationId") + .IsUnique(); + + b.HasIndex("SoftwareId"); + + b.ToTable("Blocks"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Commitment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(37) + .HasColumnType("character(37)") + .IsFixedLength(); + + b.Property("Balance") + .HasColumnType("bigint"); + + b.Property("Level") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Address") + .IsUnique(); + + b.ToTable("Commitments"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.ContractEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ContractCodeHash") + .HasColumnType("integer"); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("JsonPayload") + .HasColumnType("jsonb"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("RawPayload") + .HasColumnType("bytea"); + + b.Property("Tag") + .HasColumnType("text"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.Property("Type") + .HasColumnType("bytea"); + + b.HasKey("Id"); + + b.HasIndex("JsonPayload"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("JsonPayload"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("JsonPayload"), new[] { "jsonb_path_ops" }); + + b.HasIndex("Level"); + + b.HasIndex("Tag"); + + b.HasIndex("TransactionId"); + + b.HasIndex("ContractCodeHash", "Tag"); + + b.HasIndex("ContractId", "Tag"); + + b.ToTable("Events"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Cycle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BlockBonusPerSlot") + .HasColumnType("bigint"); + + b.Property("BlockReward") + .HasColumnType("bigint"); + + b.Property("EndorsementRewardPerSlot") + .HasColumnType("bigint"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("Index") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("MaxBlockReward") + .HasColumnType("bigint"); + + b.Property("NonceRevelationReward") + .HasColumnType("bigint"); + + b.Property("Seed") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("bytea") + .IsFixedLength(); + + b.Property("SnapshotLevel") + .HasColumnType("integer"); + + b.Property("TotalBakers") + .HasColumnType("integer"); + + b.Property("TotalBakingPower") + .HasColumnType("bigint"); + + b.Property("VdfRevelationReward") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Index") + .IsUnique(); + + b.ToTable("Cycles"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DalPublishCommitmentOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Commitment") + .HasColumnType("text"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Slot") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.ToTable("DalPublishCommitmentOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DelegationOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("DelegateId") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("InitiatorId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Nonce") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("PrevDelegateId") + .HasColumnType("integer"); + + b.Property("ResetDeactivation") + .HasColumnType("integer"); + + b.Property("SenderCodeHash") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("StakingUpdatesCount") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("DelegateId"); + + b.HasIndex("InitiatorId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("PrevDelegateId"); + + b.HasIndex("SenderCodeHash") + .HasFilter("\"SenderCodeHash\" IS NOT NULL"); + + b.HasIndex("SenderId", "Id"); + + b.ToTable("DelegationOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DelegatorCycle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("DelegatedBalance") + .HasColumnType("bigint"); + + b.Property("DelegatorId") + .HasColumnType("integer"); + + b.Property("StakedBalance") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("DelegatorId"); + + b.HasIndex("Cycle", "BakerId"); + + b.HasIndex("Cycle", "DelegatorId"); + + b.ToTable("DelegatorCycles"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Domain", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Address") + .HasColumnType("text"); + + b.Property("Data") + .HasColumnType("jsonb"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Owner") + .HasColumnType("text"); + + b.Property("Reverse") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("Address"); + + b.HasIndex("FirstLevel"); + + b.HasIndex("LastLevel"); + + b.HasIndex("Level"); + + b.HasIndex("Name"); + + b.HasIndex("Owner"); + + b.ToTable("Domains"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DoubleBakingOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccusedLevel") + .HasColumnType("integer"); + + b.Property("AccuserId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("LostExternalStaked") + .HasColumnType("bigint"); + + b.Property("LostExternalUnstaked") + .HasColumnType("bigint"); + + b.Property("LostStaked") + .HasColumnType("bigint"); + + b.Property("LostUnstaked") + .HasColumnType("bigint"); + + b.Property("OffenderId") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Reward") + .HasColumnType("bigint"); + + b.Property("SlashedLevel") + .HasColumnType("integer"); + + b.Property("StakingUpdatesCount") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AccuserId"); + + b.HasIndex("Level"); + + b.HasIndex("OffenderId"); + + b.HasIndex("OpHash"); + + b.ToTable("DoubleBakingOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DoubleEndorsingOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccusedLevel") + .HasColumnType("integer"); + + b.Property("AccuserId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("LostExternalStaked") + .HasColumnType("bigint"); + + b.Property("LostExternalUnstaked") + .HasColumnType("bigint"); + + b.Property("LostStaked") + .HasColumnType("bigint"); + + b.Property("LostUnstaked") + .HasColumnType("bigint"); + + b.Property("OffenderId") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Reward") + .HasColumnType("bigint"); + + b.Property("SlashedLevel") + .HasColumnType("integer"); + + b.Property("StakingUpdatesCount") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AccuserId"); + + b.HasIndex("Level"); + + b.HasIndex("OffenderId"); + + b.HasIndex("OpHash"); + + b.ToTable("DoubleEndorsingOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DoublePreendorsingOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccusedLevel") + .HasColumnType("integer"); + + b.Property("AccuserId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("LostExternalStaked") + .HasColumnType("bigint"); + + b.Property("LostExternalUnstaked") + .HasColumnType("bigint"); + + b.Property("LostStaked") + .HasColumnType("bigint"); + + b.Property("LostUnstaked") + .HasColumnType("bigint"); + + b.Property("OffenderId") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Reward") + .HasColumnType("bigint"); + + b.Property("SlashedLevel") + .HasColumnType("integer"); + + b.Property("StakingUpdatesCount") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AccuserId"); + + b.HasIndex("Level"); + + b.HasIndex("OffenderId"); + + b.HasIndex("OpHash"); + + b.ToTable("DoublePreendorsingOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DrainDelegateOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("DelegateId") + .HasColumnType("integer"); + + b.Property("Fee") + .HasColumnType("bigint"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("TargetId") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("DelegateId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("TargetId"); + + b.ToTable("DrainDelegateOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.EndorsementOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DelegateId") + .HasColumnType("integer"); + + b.Property("Deposit") + .HasColumnType("bigint"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("ResetDeactivation") + .HasColumnType("integer"); + + b.Property("Reward") + .HasColumnType("bigint"); + + b.Property("Slots") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("DelegateId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.ToTable("EndorsementOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.EndorsingRewardOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Expected") + .HasColumnType("bigint"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("RewardDelegated") + .HasColumnType("bigint"); + + b.Property("RewardStakedEdge") + .HasColumnType("bigint"); + + b.Property("RewardStakedOwn") + .HasColumnType("bigint"); + + b.Property("RewardStakedShared") + .HasColumnType("bigint"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("BakerId"); + + b.HasIndex("Level"); + + b.ToTable("EndorsingRewardOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.InboxMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Index") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OperationId") + .HasColumnType("bigint"); + + b.Property("Payload") + .HasColumnType("bytea"); + + b.Property("PredecessorLevel") + .HasColumnType("integer"); + + b.Property("Protocol") + .HasColumnType("text"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OperationId"); + + b.HasIndex("Type", "Id"); + + b.ToTable("InboxMessages"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.IncreasePaidStorageOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ContractId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.ToTable("IncreasePaidStorageOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.MigrationOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer"); + + b.Property("BalanceChange") + .HasColumnType("bigint"); + + b.Property("BigMapUpdates") + .HasColumnType("integer"); + + b.Property("Kind") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("ScriptId") + .HasColumnType("integer"); + + b.Property("StorageId") + .HasColumnType("integer"); + + b.Property("SubIds") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("TokenTransfers") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Level"); + + b.HasIndex("ScriptId"); + + b.HasIndex("StorageId"); + + b.ToTable("MigrationOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.NonceRevelationOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Nonce") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("bytea") + .IsFixedLength(); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RevealedCycle") + .HasColumnType("integer"); + + b.Property("RevealedLevel") + .HasColumnType("integer"); + + b.Property("RewardDelegated") + .HasColumnType("bigint"); + + b.Property("RewardStakedEdge") + .HasColumnType("bigint"); + + b.Property("RewardStakedOwn") + .HasColumnType("bigint"); + + b.Property("RewardStakedShared") + .HasColumnType("bigint"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("BakerId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RevealedCycle"); + + b.HasIndex("SenderId"); + + b.ToTable("NonceRevelationOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.OriginationOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Balance") + .HasColumnType("bigint"); + + b.Property("BigMapUpdates") + .HasColumnType("integer"); + + b.Property("ContractCodeHash") + .HasColumnType("integer"); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("DelegateId") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("InitiatorId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("ManagerId") + .HasColumnType("integer"); + + b.Property("Nonce") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("ScriptId") + .HasColumnType("integer"); + + b.Property("SenderCodeHash") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageId") + .HasColumnType("integer"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("SubIds") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("TokenTransfers") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ContractCodeHash") + .HasFilter("\"ContractCodeHash\" IS NOT NULL"); + + b.HasIndex("ContractId"); + + b.HasIndex("DelegateId"); + + b.HasIndex("InitiatorId"); + + b.HasIndex("Level"); + + b.HasIndex("ManagerId"); + + b.HasIndex("OpHash"); + + b.HasIndex("ScriptId"); + + b.HasIndex("SenderCodeHash") + .HasFilter("\"SenderCodeHash\" IS NOT NULL"); + + b.HasIndex("SenderId"); + + b.HasIndex("StorageId"); + + b.ToTable("OriginationOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.PreendorsementOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DelegateId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("ResetDeactivation") + .HasColumnType("integer"); + + b.Property("Slots") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("DelegateId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.ToTable("PreendorsementOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Proposal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Epoch") + .HasColumnType("integer"); + + b.Property("Extras") + .HasColumnType("jsonb"); + + b.Property("FirstPeriod") + .HasColumnType("integer"); + + b.Property("Hash") + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("InitiatorId") + .HasColumnType("integer"); + + b.Property("LastPeriod") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Upvotes") + .HasColumnType("integer"); + + b.Property("VotingPower") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Epoch"); + + b.HasIndex("FirstPeriod"); + + b.HasIndex("Hash"); + + b.HasIndex("LastPeriod"); + + b.HasIndex(new[] { "Status" }, "IX_Proposals_Status_Partial") + .HasFilter("\"Status\" = 0"); + + b.ToTable("Proposals"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.ProposalOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Duplicated") + .HasColumnType("boolean"); + + b.Property("Epoch") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Period") + .HasColumnType("integer"); + + b.Property("ProposalId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("VotingPower") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Epoch"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("Period"); + + b.HasIndex("ProposalId"); + + b.HasIndex("SenderId"); + + b.ToTable("ProposalOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Protocol", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BallotQuorumMax") + .HasColumnType("integer"); + + b.Property("BallotQuorumMin") + .HasColumnType("integer"); + + b.Property("BlockDeposit") + .HasColumnType("bigint"); + + b.Property("BlockReward0") + .HasColumnType("bigint"); + + b.Property("BlockReward1") + .HasColumnType("bigint"); + + b.Property("BlocksPerCommitment") + .HasColumnType("integer"); + + b.Property("BlocksPerCycle") + .HasColumnType("integer"); + + b.Property("BlocksPerSnapshot") + .HasColumnType("integer"); + + b.Property("BlocksPerVoting") + .HasColumnType("integer"); + + b.Property("ByteCost") + .HasColumnType("integer"); + + b.Property("Code") + .HasColumnType("integer"); + + b.Property("ConsensusRightsDelay") + .HasColumnType("integer"); + + b.Property("ConsensusThreshold") + .HasColumnType("integer"); + + b.Property("DelegateParametersActivationDelay") + .HasColumnType("integer"); + + b.Property("Dictator") + .HasColumnType("text"); + + b.Property("DoubleBakingSlashedPercentage") + .HasColumnType("integer"); + + b.Property("DoubleEndorsingSlashedPercentage") + .HasColumnType("integer"); + + b.Property("EndorsementDeposit") + .HasColumnType("bigint"); + + b.Property("EndorsementReward0") + .HasColumnType("bigint"); + + b.Property("EndorsementReward1") + .HasColumnType("bigint"); + + b.Property("EndorsersPerBlock") + .HasColumnType("integer"); + + b.Property("Extras") + .HasColumnType("jsonb"); + + b.Property("FirstCycle") + .HasColumnType("integer"); + + b.Property("FirstCycleLevel") + .HasColumnType("integer"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("HardBlockGasLimit") + .HasColumnType("integer"); + + b.Property("HardOperationGasLimit") + .HasColumnType("integer"); + + b.Property("HardOperationStorageLimit") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("LBToggleThreshold") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("MaxBakingReward") + .HasColumnType("bigint"); + + b.Property("MaxDelegatedOverFrozenRatio") + .HasColumnType("integer"); + + b.Property("MaxEndorsingReward") + .HasColumnType("bigint"); + + b.Property("MaxExternalOverOwnStakeRatio") + .HasColumnType("integer"); + + b.Property("MaxSlashingPeriod") + .HasColumnType("integer"); + + b.Property("MinParticipationDenominator") + .HasColumnType("integer"); + + b.Property("MinParticipationNumerator") + .HasColumnType("integer"); + + b.Property("MinimalFrozenStake") + .HasColumnType("bigint"); + + b.Property("MinimalStake") + .HasColumnType("bigint"); + + b.Property("NoRewardCycles") + .HasColumnType("integer"); + + b.Property("OriginationSize") + .HasColumnType("integer"); + + b.Property("ProposalQuorum") + .HasColumnType("integer"); + + b.Property("RampUpCycles") + .HasColumnType("integer"); + + b.Property("SmartRollupChallengeWindow") + .HasColumnType("integer"); + + b.Property("SmartRollupCommitmentPeriod") + .HasColumnType("integer"); + + b.Property("SmartRollupOriginationSize") + .HasColumnType("integer"); + + b.Property("SmartRollupStakeAmount") + .HasColumnType("bigint"); + + b.Property("SmartRollupTimeoutPeriod") + .HasColumnType("integer"); + + b.Property("StakePowerMultiplier") + .HasColumnType("integer"); + + b.Property("TimeBetweenBlocks") + .HasColumnType("integer"); + + b.Property("Version") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Code") + .IsUnique(); + + b.HasIndex("Hash") + .IsUnique(); + + b.ToTable("Protocols"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Btc") + .HasColumnType("double precision"); + + b.Property("Cny") + .HasColumnType("double precision"); + + b.Property("Eth") + .HasColumnType("double precision"); + + b.Property("Eur") + .HasColumnType("double precision"); + + b.Property("Gbp") + .HasColumnType("double precision"); + + b.Property("Jpy") + .HasColumnType("double precision"); + + b.Property("Krw") + .HasColumnType("double precision"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Usd") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("Level") + .IsUnique(); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.RefutationGame", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("InitiatorCommitmentId") + .HasColumnType("integer"); + + b.Property("InitiatorId") + .HasColumnType("integer"); + + b.Property("InitiatorLoss") + .HasColumnType("bigint"); + + b.Property("InitiatorReward") + .HasColumnType("bigint"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("LastMoveId") + .HasColumnType("bigint"); + + b.Property("OpponentCommitmentId") + .HasColumnType("integer"); + + b.Property("OpponentId") + .HasColumnType("integer"); + + b.Property("OpponentLoss") + .HasColumnType("bigint"); + + b.Property("OpponentReward") + .HasColumnType("bigint"); + + b.Property("SmartRollupId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FirstLevel"); + + b.HasIndex("InitiatorCommitmentId"); + + b.HasIndex("InitiatorId"); + + b.HasIndex("LastLevel"); + + b.HasIndex("OpponentCommitmentId"); + + b.HasIndex("OpponentId"); + + b.HasIndex("SmartRollupId", "Id"); + + b.ToTable("RefutationGames"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.RegisterConstantOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Address") + .HasMaxLength(54) + .HasColumnType("character varying(54)"); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("Extras") + .HasColumnType("jsonb"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Refs") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .HasColumnType("bytea"); + + b.HasKey("Id"); + + b.HasIndex("Address") + .HasFilter("\"Address\" IS NOT NULL"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.ToTable("RegisterConstantOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.RevealOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.ToTable("RevealOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.RevelationPenaltyOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Loss") + .HasColumnType("bigint"); + + b.Property("MissedLevel") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("BakerId"); + + b.HasIndex("Level"); + + b.ToTable("RevelationPenaltyOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Script", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CodeHash") + .HasColumnType("integer"); + + b.Property("CodeSchema") + .HasColumnType("bytea"); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("Current") + .HasColumnType("boolean"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("MigrationId") + .HasColumnType("bigint"); + + b.Property("OriginationId") + .HasColumnType("bigint"); + + b.Property("ParameterSchema") + .HasColumnType("bytea"); + + b.Property("StorageSchema") + .HasColumnType("bytea"); + + b.Property("TypeHash") + .HasColumnType("integer"); + + b.Property("Views") + .HasColumnType("bytea[]"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "ContractId" }, "IX_Scripts_ContractId_Partial") + .HasFilter("\"Current\" = true"); + + b.ToTable("Scripts"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SetDelegateParametersOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActivationCycle") + .HasColumnType("integer"); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("EdgeOfBakingOverStaking") + .HasColumnType("bigint"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("LimitOfStakingOverBaking") + .HasColumnType("bigint"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ActivationCycle"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId", "Id"); + + b.ToTable("SetDelegateParametersOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SetDepositsLimitOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Limit") + .HasColumnType("numeric"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId", "Id"); + + b.ToTable("SetDepositsLimitOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupAddMessagesOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("MessagesCount") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.ToTable("SmartRollupAddMessagesOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupCementOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("CommitmentId") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("SmartRollupId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CommitmentId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.HasIndex("SmartRollupId", "Id"); + + b.ToTable("SmartRollupCementOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupCommitment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActiveStakers") + .HasColumnType("integer"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("Hash") + .HasColumnType("text"); + + b.Property("InboxLevel") + .HasColumnType("integer"); + + b.Property("InitiatorId") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("PredecessorId") + .HasColumnType("integer"); + + b.Property("SmartRollupId") + .HasColumnType("integer"); + + b.Property("Stakers") + .HasColumnType("integer"); + + b.Property("State") + .HasColumnType("text"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Successors") + .HasColumnType("integer"); + + b.Property("Ticks") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InboxLevel"); + + b.HasIndex("LastLevel"); + + b.HasIndex("PredecessorId"); + + b.HasIndex("SmartRollupId"); + + b.HasIndex("Hash", "SmartRollupId"); + + b.ToTable("SmartRollupCommitments"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupExecuteOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("CommitmentId") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("SmartRollupId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("SubIds") + .HasColumnType("integer"); + + b.Property("TicketTransfers") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.HasIndex("SmartRollupId"); + + b.HasIndex("CommitmentId", "Id"); + + b.ToTable("SmartRollupExecuteOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupOriginateOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("GenesisCommitment") + .HasColumnType("text"); + + b.Property("Kernel") + .HasColumnType("bytea"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("ParameterType") + .HasColumnType("bytea"); + + b.Property("PvmKind") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("SmartRollupId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.HasIndex("SmartRollupId"); + + b.ToTable("SmartRollupOriginateOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupPublishOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Bond") + .HasColumnType("bigint"); + + b.Property("BondStatus") + .HasColumnType("integer"); + + b.Property("CommitmentId") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("Flags") + .HasColumnType("integer"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("SmartRollupId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CommitmentId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.HasIndex("SmartRollupId", "BondStatus", "SenderId") + .HasFilter("\"BondStatus\" IS NOT NULL"); + + b.HasIndex("SmartRollupId", "SenderId", "Id"); + + b.ToTable("SmartRollupPublishOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupRecoverBondOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Bond") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("SmartRollupId") + .HasColumnType("integer"); + + b.Property("StakerId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.HasIndex("SmartRollupId"); + + b.HasIndex("StakerId"); + + b.ToTable("SmartRollupRecoverBondOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupRefuteOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("DissectionEnd") + .HasColumnType("bigint"); + + b.Property("DissectionStart") + .HasColumnType("bigint"); + + b.Property("DissectionSteps") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GameId") + .HasColumnType("integer"); + + b.Property("GameStatus") + .HasColumnType("integer"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Move") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("SmartRollupId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.HasIndex("SmartRollupId"); + + b.HasIndex("GameId", "Id"); + + b.ToTable("SmartRollupRefuteOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SnapshotBalance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer"); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("DelegatorsCount") + .HasColumnType("integer"); + + b.Property("ExternalDelegatedBalance") + .HasColumnType("bigint"); + + b.Property("ExternalStakedBalance") + .HasColumnType("bigint"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OwnDelegatedBalance") + .HasColumnType("bigint"); + + b.Property("OwnStakedBalance") + .HasColumnType("bigint"); + + b.Property("StakersCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Level", "AccountId", "BakerId"); + + b.HasIndex(new[] { "Level" }, "IX_SnapshotBalances_Level_Partial") + .HasFilter("\"AccountId\" = \"BakerId\""); + + b.ToTable("SnapshotBalances"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Software", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BlocksCount") + .HasColumnType("integer"); + + b.Property("Extras") + .HasColumnType("jsonb"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("ShortHash") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("character(8)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.ToTable("Software"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.StakingOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RequestedAmount") + .HasColumnType("bigint"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("StakingUpdatesCount") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("BakerId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.ToTable("StakingOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.StakingUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("AutostakingOpId") + .HasColumnType("bigint"); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("DelegationOpId") + .HasColumnType("bigint"); + + b.Property("DoubleBakingOpId") + .HasColumnType("bigint"); + + b.Property("DoubleEndorsingOpId") + .HasColumnType("bigint"); + + b.Property("DoublePreendorsingOpId") + .HasColumnType("bigint"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Pseudotokens") + .HasColumnType("numeric"); + + b.Property("RoundingError") + .HasColumnType("bigint"); + + b.Property("StakerId") + .HasColumnType("integer"); + + b.Property("StakingOpId") + .HasColumnType("bigint"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AutostakingOpId") + .HasFilter("\"AutostakingOpId\" IS NOT NULL"); + + b.HasIndex("DelegationOpId") + .HasFilter("\"DelegationOpId\" IS NOT NULL"); + + b.HasIndex("DoubleBakingOpId") + .HasFilter("\"DoubleBakingOpId\" IS NOT NULL"); + + b.HasIndex("DoubleEndorsingOpId") + .HasFilter("\"DoubleEndorsingOpId\" IS NOT NULL"); + + b.HasIndex("DoublePreendorsingOpId") + .HasFilter("\"DoublePreendorsingOpId\" IS NOT NULL"); + + b.HasIndex("StakingOpId") + .HasFilter("\"StakingOpId\" IS NOT NULL"); + + b.HasIndex("Level", "Id"); + + b.HasIndex("BakerId", "Cycle", "Id"); + + b.HasIndex("StakerId", "Cycle", "Id"); + + b.ToTable("StakingUpdates"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Statistics", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("Date") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("TotalActivated") + .HasColumnType("bigint"); + + b.Property("TotalBanished") + .HasColumnType("bigint"); + + b.Property("TotalBootstrapped") + .HasColumnType("bigint"); + + b.Property("TotalBurned") + .HasColumnType("bigint"); + + b.Property("TotalCommitments") + .HasColumnType("bigint"); + + b.Property("TotalCreated") + .HasColumnType("bigint"); + + b.Property("TotalFrozen") + .HasColumnType("bigint"); + + b.Property("TotalLost") + .HasColumnType("bigint"); + + b.Property("TotalRollupBonds") + .HasColumnType("bigint"); + + b.Property("TotalSmartRollupBonds") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Cycle") + .IsUnique() + .HasFilter("\"Cycle\" IS NOT NULL"); + + b.HasIndex("Date") + .IsUnique() + .HasFilter("\"Date\" IS NOT NULL"); + + b.HasIndex("Level") + .IsUnique(); + + b.ToTable("Statistics"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Storage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("Current") + .HasColumnType("boolean"); + + b.Property("JsonValue") + .HasColumnType("jsonb"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("MigrationId") + .HasColumnType("bigint"); + + b.Property("OriginationId") + .HasColumnType("bigint"); + + b.Property("RawValue") + .HasColumnType("bytea"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("ContractId", "Id"); + + b.HasIndex(new[] { "ContractId" }, "IX_Storages_ContractId_Partial") + .HasFilter("\"Current\" = true"); + + b.ToTable("Storages"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BalancesCount") + .HasColumnType("integer"); + + b.Property("ContentHash") + .HasColumnType("integer"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("FirstMinterId") + .HasColumnType("integer"); + + b.Property("HoldersCount") + .HasColumnType("integer"); + + b.Property("JsonContent") + .HasColumnType("jsonb"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("RawContent") + .HasColumnType("bytea"); + + b.Property("RawType") + .HasColumnType("bytea"); + + b.Property("TicketerId") + .HasColumnType("integer"); + + b.Property("TotalBurned") + .HasColumnType("numeric"); + + b.Property("TotalMinted") + .HasColumnType("numeric"); + + b.Property("TotalSupply") + .HasColumnType("numeric"); + + b.Property("TransfersCount") + .HasColumnType("integer"); + + b.Property("TypeHash") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ContentHash"); + + b.HasIndex("FirstLevel"); + + b.HasIndex("FirstMinterId"); + + b.HasIndex("JsonContent"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("JsonContent"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("JsonContent"), new[] { "jsonb_path_ops" }); + + b.HasIndex("LastLevel"); + + b.HasIndex("TypeHash"); + + b.HasIndex("TicketerId", "TypeHash", "ContentHash"); + + b.ToTable("Tickets"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TicketBalance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer"); + + b.Property("Balance") + .HasColumnType("numeric"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("TicketId") + .HasColumnType("bigint"); + + b.Property("TicketerId") + .HasColumnType("integer"); + + b.Property("TransfersCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FirstLevel"); + + b.HasIndex("LastLevel"); + + b.HasIndex("TicketId"); + + b.HasIndex("TicketerId"); + + b.HasIndex("AccountId", "TicketId") + .IsUnique(); + + b.HasIndex("AccountId", "TicketerId"); + + b.ToTable("TicketBalances"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TicketTransfer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("FromId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("SmartRollupExecuteId") + .HasColumnType("bigint"); + + b.Property("TicketId") + .HasColumnType("bigint"); + + b.Property("TicketerId") + .HasColumnType("integer"); + + b.Property("ToId") + .HasColumnType("integer"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.Property("TransferTicketId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("FromId"); + + b.HasIndex("SmartRollupExecuteId") + .HasFilter("\"SmartRollupExecuteId\" IS NOT NULL"); + + b.HasIndex("TicketId"); + + b.HasIndex("TicketerId"); + + b.HasIndex("ToId"); + + b.HasIndex("TransactionId") + .HasFilter("\"TransactionId\" IS NOT NULL"); + + b.HasIndex("TransferTicketId") + .HasFilter("\"TransferTicketId\" IS NOT NULL"); + + b.HasIndex("Level", "Id"); + + b.ToTable("TicketTransfers"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Token", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BalancesCount") + .HasColumnType("integer"); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("FirstMinterId") + .HasColumnType("integer"); + + b.Property("HoldersCount") + .HasColumnType("integer"); + + b.Property("IndexedAt") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("Metadata") + .HasColumnType("jsonb"); + + b.Property("OwnerId") + .HasColumnType("integer"); + + b.Property("Tags") + .HasColumnType("integer"); + + b.Property("TokenId") + .HasColumnType("numeric"); + + b.Property("TotalBurned") + .HasColumnType("numeric"); + + b.Property("TotalMinted") + .HasColumnType("numeric"); + + b.Property("TotalSupply") + .HasColumnType("numeric"); + + b.Property("TransfersCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FirstMinterId"); + + b.HasIndex("IndexedAt") + .HasFilter("\"IndexedAt\" IS NOT NULL"); + + b.HasIndex("LastLevel"); + + b.HasIndex("Metadata"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Metadata"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("Metadata"), new[] { "jsonb_path_ops" }); + + b.HasIndex("ContractId", "TokenId") + .IsUnique(); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TokenBalance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer"); + + b.Property("Balance") + .HasColumnType("numeric"); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("IndexedAt") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("TokenId") + .HasColumnType("bigint"); + + b.Property("TransfersCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ContractId"); + + b.HasIndex("IndexedAt") + .HasFilter("\"IndexedAt\" IS NOT NULL"); + + b.HasIndex("LastLevel"); + + b.HasIndex("TokenId"); + + b.HasIndex("AccountId", "ContractId"); + + b.HasIndex("AccountId", "TokenId") + .IsUnique(); + + b.HasIndex(new[] { "AccountId" }, "IX_TokenBalances_AccountId_Partial") + .HasFilter("\"Balance\" != '0'"); + + b.HasIndex(new[] { "ContractId" }, "IX_TokenBalances_ContractId_Partial") + .HasFilter("\"Balance\" != '0'"); + + b.HasIndex(new[] { "TokenId" }, "IX_TokenBalances_TokenId_Partial") + .HasFilter("\"Balance\" != '0'"); + + b.ToTable("TokenBalances"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TokenTransfer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("ContractId") + .HasColumnType("integer"); + + b.Property("FromId") + .HasColumnType("integer"); + + b.Property("IndexedAt") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("MigrationId") + .HasColumnType("bigint"); + + b.Property("OriginationId") + .HasColumnType("bigint"); + + b.Property("ToId") + .HasColumnType("integer"); + + b.Property("TokenId") + .HasColumnType("bigint"); + + b.Property("TransactionId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ContractId"); + + b.HasIndex("FromId") + .HasFilter("\"FromId\" IS NOT NULL"); + + b.HasIndex("IndexedAt") + .HasFilter("\"IndexedAt\" IS NOT NULL"); + + b.HasIndex("MigrationId") + .HasFilter("\"MigrationId\" IS NOT NULL"); + + b.HasIndex("OriginationId") + .HasFilter("\"OriginationId\" IS NOT NULL"); + + b.HasIndex("ToId") + .HasFilter("\"ToId\" IS NOT NULL"); + + b.HasIndex("TokenId"); + + b.HasIndex("TransactionId") + .HasFilter("\"TransactionId\" IS NOT NULL"); + + b.HasIndex("Level", "Id"); + + b.ToTable("TokenTransfers"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TransactionOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("Amount") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("BigMapUpdates") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Entrypoint") + .HasColumnType("text"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("EventsCount") + .HasColumnType("integer"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("InitiatorId") + .HasColumnType("integer"); + + b.Property("InternalDelegations") + .HasColumnType("smallint"); + + b.Property("InternalOperations") + .HasColumnType("smallint"); + + b.Property("InternalOriginations") + .HasColumnType("smallint"); + + b.Property("InternalTransactions") + .HasColumnType("smallint"); + + b.Property("JsonParameters") + .HasColumnType("jsonb"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Nonce") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RawParameters") + .HasColumnType("bytea"); + + b.Property("ResetDeactivation") + .HasColumnType("integer"); + + b.Property("SenderCodeHash") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageId") + .HasColumnType("integer"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("SubIds") + .HasColumnType("integer"); + + b.Property("TargetCodeHash") + .HasColumnType("integer"); + + b.Property("TargetId") + .HasColumnType("integer"); + + b.Property("TicketTransfers") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("TokenTransfers") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("InitiatorId"); + + b.HasIndex("JsonParameters"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("JsonParameters"), "gin"); + NpgsqlIndexBuilderExtensions.HasOperators(b.HasIndex("JsonParameters"), new[] { "jsonb_path_ops" }); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderCodeHash") + .HasFilter("\"SenderCodeHash\" IS NOT NULL"); + + b.HasIndex("SenderId"); + + b.HasIndex("StorageId"); + + b.HasIndex("TargetCodeHash") + .HasFilter("\"TargetCodeHash\" IS NOT NULL"); + + b.HasIndex("TargetId"); + + b.HasIndex(new[] { "TargetId" }, "IX_TransactionOps_TargetId_Partial") + .HasFilter("\"Entrypoint\" = 'transfer'\r\nAND \"TokenTransfers\" IS NULL\r\nAND \"Status\" = 1"); + + b.ToTable("TransactionOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TransferTicketOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Entrypoint") + .HasColumnType("text"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("JsonContent") + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RawContent") + .HasColumnType("bytea"); + + b.Property("RawType") + .HasColumnType("bytea"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("SubIds") + .HasColumnType("integer"); + + b.Property("TargetId") + .HasColumnType("integer"); + + b.Property("TicketTransfers") + .HasColumnType("integer"); + + b.Property("TicketerId") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.HasIndex("TargetId"); + + b.HasIndex("TicketerId"); + + b.ToTable("TransferTicketOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupCommitOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Bond") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RollupId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RollupId"); + + b.HasIndex("SenderId"); + + b.ToTable("TxRollupCommitOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupDispatchTicketsOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RollupId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RollupId"); + + b.HasIndex("SenderId"); + + b.ToTable("TxRollupDispatchTicketsOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupFinalizeCommitmentOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RollupId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RollupId"); + + b.HasIndex("SenderId"); + + b.ToTable("TxRollupFinalizeCommitmentOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupOriginationOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RollupId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RollupId"); + + b.HasIndex("SenderId"); + + b.ToTable("TxRollupOriginationOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupRejectionOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("CommitterId") + .HasColumnType("integer"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Loss") + .HasColumnType("bigint"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Reward") + .HasColumnType("bigint"); + + b.Property("RollupId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CommitterId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RollupId"); + + b.HasIndex("SenderId"); + + b.ToTable("TxRollupRejectionOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupRemoveCommitmentOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RollupId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RollupId"); + + b.HasIndex("SenderId"); + + b.ToTable("TxRollupRemoveCommitmentOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupReturnBondOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Bond") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RollupId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RollupId"); + + b.HasIndex("SenderId"); + + b.ToTable("TxRollupReturnBondOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupSubmitBatchOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("RollupId") + .HasColumnType("integer"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("RollupId"); + + b.HasIndex("SenderId"); + + b.ToTable("TxRollupSubmitBatchOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.UnstakeRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("FinalizedAmount") + .HasColumnType("bigint"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("RequestedAmount") + .HasColumnType("bigint"); + + b.Property("RestakedAmount") + .HasColumnType("bigint"); + + b.Property("RoundingError") + .HasColumnType("bigint"); + + b.Property("SlashedAmount") + .HasColumnType("bigint"); + + b.Property("StakerId") + .HasColumnType("integer"); + + b.Property("UpdatesCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("BakerId", "Cycle"); + + b.HasIndex("StakerId", "Cycle"); + + b.ToTable("UnstakeRequests"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.UpdateConsensusKeyOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActivationCycle") + .HasColumnType("integer"); + + b.Property("AllocationFee") + .HasColumnType("bigint"); + + b.Property("BakerFee") + .HasColumnType("bigint"); + + b.Property("Counter") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("text"); + + b.Property("GasLimit") + .HasColumnType("integer"); + + b.Property("GasUsed") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("PublicKey") + .HasColumnType("text"); + + b.Property("PublicKeyHash") + .HasColumnType("text"); + + b.Property("SenderId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("StorageFee") + .HasColumnType("bigint"); + + b.Property("StorageLimit") + .HasColumnType("integer"); + + b.Property("StorageUsed") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("SenderId"); + + b.ToTable("UpdateConsensusKeyOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.VdfRevelationOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Cycle") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("OpHash") + .IsRequired() + .HasMaxLength(51) + .HasColumnType("character(51)") + .IsFixedLength(); + + b.Property("Proof") + .HasColumnType("bytea"); + + b.Property("RewardDelegated") + .HasColumnType("bigint"); + + b.Property("RewardStakedEdge") + .HasColumnType("bigint"); + + b.Property("RewardStakedOwn") + .HasColumnType("bigint"); + + b.Property("RewardStakedShared") + .HasColumnType("bigint"); + + b.Property("Solution") + .HasColumnType("bytea"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("BakerId"); + + b.HasIndex("Level"); + + b.HasIndex("OpHash"); + + b.HasIndex("Cycle", "Id"); + + b.ToTable("VdfRevelationOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.VotingPeriod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BallotsQuorum") + .HasColumnType("integer"); + + b.Property("Dictator") + .HasColumnType("integer"); + + b.Property("Epoch") + .HasColumnType("integer"); + + b.Property("FirstLevel") + .HasColumnType("integer"); + + b.Property("Index") + .HasColumnType("integer"); + + b.Property("Kind") + .HasColumnType("integer"); + + b.Property("LastLevel") + .HasColumnType("integer"); + + b.Property("NayBallots") + .HasColumnType("integer"); + + b.Property("NayVotingPower") + .HasColumnType("bigint"); + + b.Property("ParticipationEma") + .HasColumnType("integer"); + + b.Property("PassBallots") + .HasColumnType("integer"); + + b.Property("PassVotingPower") + .HasColumnType("bigint"); + + b.Property("ProposalsCount") + .HasColumnType("integer"); + + b.Property("SingleWinner") + .HasColumnType("boolean"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Supermajority") + .HasColumnType("integer"); + + b.Property("TopUpvotes") + .HasColumnType("integer"); + + b.Property("TopVotingPower") + .HasColumnType("bigint"); + + b.Property("TotalBakers") + .HasColumnType("integer"); + + b.Property("TotalVotingPower") + .HasColumnType("bigint"); + + b.Property("UpvotesQuorum") + .HasColumnType("integer"); + + b.Property("YayBallots") + .HasColumnType("integer"); + + b.Property("YayVotingPower") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Epoch"); + + b.HasIndex("Index") + .IsUnique(); + + b.ToTable("VotingPeriods"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.VotingSnapshot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BakerId") + .HasColumnType("integer"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Period") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("VotingPower") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Period", "BakerId") + .IsUnique(); + + b.ToTable("VotingSnapshots"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Contract", b => + { + b.HasBaseType("Tzkt.Data.Models.Account"); + + b.Property("CodeHash") + .HasColumnType("integer"); + + b.Property("CreatorId") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("CreatorId"); + + b.Property("EventsCount") + .HasColumnType("integer"); + + b.Property("Kind") + .HasColumnType("smallint"); + + b.Property("ManagerId") + .HasColumnType("integer"); + + b.Property("Spendable") + .HasColumnType("boolean"); + + b.Property("Tags") + .HasColumnType("integer"); + + b.Property("TicketsCount") + .HasColumnType("integer"); + + b.Property("TokensCount") + .HasColumnType("integer"); + + b.Property("TypeHash") + .HasColumnType("integer"); + + b.Property("WeirdDelegateId") + .HasColumnType("integer"); + + b.HasIndex("CodeHash"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ManagerId"); + + b.HasIndex("TypeHash"); + + b.HasIndex("WeirdDelegateId") + .HasFilter("\"WeirdDelegateId\" IS NOT NULL"); + + b.HasIndex(new[] { "Kind" }, "IX_Accounts_Kind_Partial") + .HasFilter("\"Type\" = 2"); + + b.HasDiscriminator().HasValue((byte)2); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Rollup", b => + { + b.HasBaseType("Tzkt.Data.Models.Account"); + + b.Property("CreatorId") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("CreatorId"); + + b.HasIndex("CreatorId"); + + b.HasDiscriminator().HasValue((byte)4); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollup", b => + { + b.HasBaseType("Tzkt.Data.Models.Account"); + + b.Property("ActiveStakers") + .HasColumnType("integer"); + + b.Property("CementedCommitments") + .HasColumnType("integer"); + + b.Property("CreatorId") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("CreatorId"); + + b.Property("ExecutedCommitments") + .HasColumnType("integer"); + + b.Property("GenesisCommitment") + .HasColumnType("text"); + + b.Property("InboxLevel") + .HasColumnType("integer"); + + b.Property("LastCommitment") + .HasColumnType("text"); + + b.Property("OrphanCommitments") + .HasColumnType("integer"); + + b.Property("ParameterSchema") + .HasColumnType("bytea"); + + b.Property("PendingCommitments") + .HasColumnType("integer"); + + b.Property("PvmKind") + .HasColumnType("integer"); + + b.Property("RefutedCommitments") + .HasColumnType("integer"); + + b.Property("TotalStakers") + .HasColumnType("integer"); + + b.HasIndex("CreatorId"); + + b.HasDiscriminator().HasValue((byte)5); + }); + + modelBuilder.Entity("Tzkt.Data.Models.User", b => + { + b.HasBaseType("Tzkt.Data.Models.Account"); + + b.Property("ActivationsCount") + .HasColumnType("integer"); + + b.Property("DalPublishCommitmentOpsCount") + .HasColumnType("integer"); + + b.Property("PublicKey") + .HasColumnType("text"); + + b.Property("RegisterConstantsCount") + .HasColumnType("integer"); + + b.Property("Revealed") + .HasColumnType("boolean"); + + b.Property("SetDelegateParametersOpsCount") + .HasColumnType("integer"); + + b.Property("SetDepositsLimitsCount") + .HasColumnType("integer"); + + b.Property("StakedPseudotokens") + .HasColumnType("numeric"); + + b.Property("StakingOpsCount") + .HasColumnType("integer"); + + b.Property("StakingUpdatesCount") + .HasColumnType("integer"); + + b.Property("UnstakedBakerId") + .HasColumnType("integer"); + + b.Property("UnstakedBalance") + .HasColumnType("bigint"); + + b.HasIndex("UnstakedBakerId") + .HasFilter("\"UnstakedBakerId\" IS NOT NULL"); + + b.HasDiscriminator().HasValue((byte)0); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Delegate", b => + { + b.HasBaseType("Tzkt.Data.Models.User"); + + b.Property("ActivationLevel") + .HasColumnType("integer"); + + b.Property("AutostakingOpsCount") + .HasColumnType("integer"); + + b.Property("BallotsCount") + .HasColumnType("integer"); + + b.Property("BlocksCount") + .HasColumnType("integer"); + + b.Property("DeactivationLevel") + .HasColumnType("integer"); + + b.Property("DelegatedBalance") + .HasColumnType("bigint"); + + b.Property("DelegatorsCount") + .HasColumnType("integer"); + + b.Property("DoubleBakingCount") + .HasColumnType("integer"); + + b.Property("DoubleEndorsingCount") + .HasColumnType("integer"); + + b.Property("DoublePreendorsingCount") + .HasColumnType("integer"); + + b.Property("EdgeOfBakingOverStaking") + .HasColumnType("bigint"); + + b.Property("EndorsementsCount") + .HasColumnType("integer"); + + b.Property("EndorsingRewardsCount") + .HasColumnType("integer"); + + b.Property("ExternalStakedBalance") + .HasColumnType("bigint"); + + b.Property("ExternalUnstakedBalance") + .HasColumnType("bigint"); + + b.Property("FrozenDepositLimit") + .HasColumnType("bigint"); + + b.Property("IssuedPseudotokens") + .HasColumnType("numeric"); + + b.Property("LimitOfStakingOverBaking") + .HasColumnType("bigint"); + + b.Property("NonceRevelationsCount") + .HasColumnType("integer"); + + b.Property("OwnStakedBalance") + .HasColumnType("bigint"); + + b.Property("PreendorsementsCount") + .HasColumnType("integer"); + + b.Property("ProposalsCount") + .HasColumnType("integer"); + + b.Property("RevelationPenaltiesCount") + .HasColumnType("integer"); + + b.Property("RoundingError") + .HasColumnType("bigint"); + + b.Property("SoftwareId") + .HasColumnType("integer"); + + b.Property("StakersCount") + .HasColumnType("integer"); + + b.Property("StakingBalance") + .HasColumnType("bigint"); + + b.Property("VdfRevelationsCount") + .HasColumnType("integer"); + + b.HasIndex("SoftwareId"); + + b.HasIndex(new[] { "DeactivationLevel" }, "IX_Accounts_DeactivationLevel_Partial") + .HasFilter("\"Type\" = 1"); + + b.HasIndex(new[] { "Staked" }, "IX_Accounts_Staked_Partial") + .HasFilter("\"Type\" = 1"); + + b.HasDiscriminator().HasValue((byte)1); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Account", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Delegate") + .WithMany("DelegatedAccounts") + .HasForeignKey("DelegateId"); + + b.HasOne("Tzkt.Data.Models.Block", "FirstBlock") + .WithMany("CreatedAccounts") + .HasForeignKey("FirstLevel") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Delegate"); + + b.Navigation("FirstBlock"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.ActivationOperation", b => + { + b.HasOne("Tzkt.Data.Models.User", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Activations") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Block"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.BallotOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Ballots") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Proposal", "Proposal") + .WithMany() + .HasForeignKey("ProposalId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Delegate", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Proposal"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Block", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Proposer") + .WithMany() + .HasForeignKey("ProposerId"); + + b.HasOne("Tzkt.Data.Models.Protocol", "Protocol") + .WithMany() + .HasForeignKey("ProtoCode") + .HasPrincipalKey("Code") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.NonceRevelationOperation", "Revelation") + .WithOne("RevealedBlock") + .HasForeignKey("Tzkt.Data.Models.Block", "RevelationId"); + + b.HasOne("Tzkt.Data.Models.Software", "Software") + .WithMany() + .HasForeignKey("SoftwareId"); + + b.Navigation("Proposer"); + + b.Navigation("Protocol"); + + b.Navigation("Revelation"); + + b.Navigation("Software"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DalPublishCommitmentOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("DalPublishCommitmentOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DelegationOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Delegate") + .WithMany() + .HasForeignKey("DelegateId"); + + b.HasOne("Tzkt.Data.Models.Account", "Initiator") + .WithMany() + .HasForeignKey("InitiatorId"); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Delegations") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Delegate", "PrevDelegate") + .WithMany() + .HasForeignKey("PrevDelegateId"); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Delegate"); + + b.Navigation("Initiator"); + + b.Navigation("PrevDelegate"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DoubleBakingOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Accuser") + .WithMany() + .HasForeignKey("AccuserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("DoubleBakings") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Delegate", "Offender") + .WithMany() + .HasForeignKey("OffenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Accuser"); + + b.Navigation("Block"); + + b.Navigation("Offender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DoubleEndorsingOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Accuser") + .WithMany() + .HasForeignKey("AccuserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("DoubleEndorsings") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Delegate", "Offender") + .WithMany() + .HasForeignKey("OffenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Accuser"); + + b.Navigation("Block"); + + b.Navigation("Offender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DoublePreendorsingOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Accuser") + .WithMany() + .HasForeignKey("AccuserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("DoublePreendorsings") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Delegate", "Offender") + .WithMany() + .HasForeignKey("OffenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Accuser"); + + b.Navigation("Block"); + + b.Navigation("Offender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.DrainDelegateOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("DrainDelegateOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.EndorsementOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Delegate") + .WithMany() + .HasForeignKey("DelegateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Endorsements") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Delegate"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.IncreasePaidStorageOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("IncreasePaidStorageOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.MigrationOperation", b => + { + b.HasOne("Tzkt.Data.Models.Account", "Account") + .WithMany() + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Migrations") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Script", "Script") + .WithMany() + .HasForeignKey("ScriptId"); + + b.HasOne("Tzkt.Data.Models.Storage", "Storage") + .WithMany() + .HasForeignKey("StorageId"); + + b.Navigation("Account"); + + b.Navigation("Block"); + + b.Navigation("Script"); + + b.Navigation("Storage"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.NonceRevelationOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Baker") + .WithMany() + .HasForeignKey("BakerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Revelations") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Delegate", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Baker"); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.OriginationOperation", b => + { + b.HasOne("Tzkt.Data.Models.Contract", "Contract") + .WithMany() + .HasForeignKey("ContractId"); + + b.HasOne("Tzkt.Data.Models.Delegate", "Delegate") + .WithMany() + .HasForeignKey("DelegateId"); + + b.HasOne("Tzkt.Data.Models.Account", "Initiator") + .WithMany() + .HasForeignKey("InitiatorId"); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Originations") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.User", "Manager") + .WithMany() + .HasForeignKey("ManagerId"); + + b.HasOne("Tzkt.Data.Models.Script", "Script") + .WithMany() + .HasForeignKey("ScriptId"); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Storage", "Storage") + .WithMany() + .HasForeignKey("StorageId"); + + b.Navigation("Block"); + + b.Navigation("Contract"); + + b.Navigation("Delegate"); + + b.Navigation("Initiator"); + + b.Navigation("Manager"); + + b.Navigation("Script"); + + b.Navigation("Sender"); + + b.Navigation("Storage"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.PreendorsementOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Delegate") + .WithMany() + .HasForeignKey("DelegateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Preendorsements") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Delegate"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.ProposalOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Proposals") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Proposal", "Proposal") + .WithMany() + .HasForeignKey("ProposalId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Delegate", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Proposal"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.RegisterConstantOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("RegisterConstants") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.RevealOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Reveals") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.RevelationPenaltyOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Baker") + .WithMany() + .HasForeignKey("BakerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("RevelationPenalties") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Baker"); + + b.Navigation("Block"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SetDelegateParametersOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SetDelegateParametersOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SetDepositsLimitOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SetDepositsLimits") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupAddMessagesOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SmartRollupAddMessagesOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupCementOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SmartRollupCementOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupExecuteOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SmartRollupExecuteOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupOriginateOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SmartRollupOriginateOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupPublishOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SmartRollupPublishOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupRecoverBondOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SmartRollupRecoverBondOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.SmartRollupRefuteOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("SmartRollupRefuteOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.StakingOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("StakingOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TransactionOperation", b => + { + b.HasOne("Tzkt.Data.Models.Account", "Initiator") + .WithMany() + .HasForeignKey("InitiatorId"); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("Transactions") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Storage", "Storage") + .WithMany() + .HasForeignKey("StorageId"); + + b.HasOne("Tzkt.Data.Models.Account", "Target") + .WithMany() + .HasForeignKey("TargetId"); + + b.Navigation("Block"); + + b.Navigation("Initiator"); + + b.Navigation("Sender"); + + b.Navigation("Storage"); + + b.Navigation("Target"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TransferTicketOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TransferTicketOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupCommitOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TxRollupCommitOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupDispatchTicketsOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TxRollupDispatchTicketsOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupFinalizeCommitmentOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TxRollupFinalizeCommitmentOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupOriginationOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TxRollupOriginationOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupRejectionOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TxRollupRejectionOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupRemoveCommitmentOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TxRollupRemoveCommitmentOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupReturnBondOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TxRollupReturnBondOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.TxRollupSubmitBatchOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("TxRollupSubmitBatchOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.UpdateConsensusKeyOperation", b => + { + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("UpdateConsensusKeyOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Account", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.VdfRevelationOperation", b => + { + b.HasOne("Tzkt.Data.Models.Delegate", "Baker") + .WithMany() + .HasForeignKey("BakerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tzkt.Data.Models.Block", "Block") + .WithMany("VdfRevelationOps") + .HasForeignKey("Level") + .HasPrincipalKey("Level") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Baker"); + + b.Navigation("Block"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Contract", b => + { + b.HasOne("Tzkt.Data.Models.Account", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.HasOne("Tzkt.Data.Models.User", "Manager") + .WithMany() + .HasForeignKey("ManagerId"); + + b.HasOne("Tzkt.Data.Models.User", "WeirdDelegate") + .WithMany() + .HasForeignKey("WeirdDelegateId"); + + b.Navigation("Creator"); + + b.Navigation("Manager"); + + b.Navigation("WeirdDelegate"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Delegate", b => + { + b.HasOne("Tzkt.Data.Models.Software", "Software") + .WithMany() + .HasForeignKey("SoftwareId"); + + b.Navigation("Software"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Block", b => + { + b.Navigation("Activations"); + + b.Navigation("Ballots"); + + b.Navigation("CreatedAccounts"); + + b.Navigation("DalPublishCommitmentOps"); + + b.Navigation("Delegations"); + + b.Navigation("DoubleBakings"); + + b.Navigation("DoubleEndorsings"); + + b.Navigation("DoublePreendorsings"); + + b.Navigation("DrainDelegateOps"); + + b.Navigation("Endorsements"); + + b.Navigation("IncreasePaidStorageOps"); + + b.Navigation("Migrations"); + + b.Navigation("Originations"); + + b.Navigation("Preendorsements"); + + b.Navigation("Proposals"); + + b.Navigation("RegisterConstants"); + + b.Navigation("Reveals"); + + b.Navigation("RevelationPenalties"); + + b.Navigation("Revelations"); + + b.Navigation("SetDelegateParametersOps"); + + b.Navigation("SetDepositsLimits"); + + b.Navigation("SmartRollupAddMessagesOps"); + + b.Navigation("SmartRollupCementOps"); + + b.Navigation("SmartRollupExecuteOps"); + + b.Navigation("SmartRollupOriginateOps"); + + b.Navigation("SmartRollupPublishOps"); + + b.Navigation("SmartRollupRecoverBondOps"); + + b.Navigation("SmartRollupRefuteOps"); + + b.Navigation("StakingOps"); + + b.Navigation("Transactions"); + + b.Navigation("TransferTicketOps"); + + b.Navigation("TxRollupCommitOps"); + + b.Navigation("TxRollupDispatchTicketsOps"); + + b.Navigation("TxRollupFinalizeCommitmentOps"); + + b.Navigation("TxRollupOriginationOps"); + + b.Navigation("TxRollupRejectionOps"); + + b.Navigation("TxRollupRemoveCommitmentOps"); + + b.Navigation("TxRollupReturnBondOps"); + + b.Navigation("TxRollupSubmitBatchOps"); + + b.Navigation("UpdateConsensusKeyOps"); + + b.Navigation("VdfRevelationOps"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.NonceRevelationOperation", b => + { + b.Navigation("RevealedBlock"); + }); + + modelBuilder.Entity("Tzkt.Data.Models.Delegate", b => + { + b.Navigation("DelegatedAccounts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Tzkt.Data/Migrations/20240629103331_DrainDelegateExt.cs b/Tzkt.Data/Migrations/20240629103331_DrainDelegateExt.cs new file mode 100644 index 000000000..0108ae746 --- /dev/null +++ b/Tzkt.Data/Migrations/20240629103331_DrainDelegateExt.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Tzkt.Data.Migrations +{ + /// + public partial class DrainDelegateExt : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "AllocationFee", + table: "DrainDelegateOps", + type: "bigint", + nullable: false, + defaultValue: 0L); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "AllocationFee", + table: "DrainDelegateOps"); + } + } +} diff --git a/Tzkt.Data/Migrations/TzktContextModelSnapshot.cs b/Tzkt.Data/Migrations/TzktContextModelSnapshot.cs index 72147edc7..fff48fca0 100644 --- a/Tzkt.Data/Migrations/TzktContextModelSnapshot.cs +++ b/Tzkt.Data/Migrations/TzktContextModelSnapshot.cs @@ -19,7 +19,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("ProductVersion", "7.0.18") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); @@ -1839,6 +1839,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + b.Property("AllocationFee") + .HasColumnType("bigint"); + b.Property("Amount") .HasColumnType("bigint"); diff --git a/Tzkt.Data/Models/Operations/DrainDelegateOperation.cs b/Tzkt.Data/Models/Operations/DrainDelegateOperation.cs index de73060fe..c7a3f64fb 100644 --- a/Tzkt.Data/Models/Operations/DrainDelegateOperation.cs +++ b/Tzkt.Data/Models/Operations/DrainDelegateOperation.cs @@ -9,6 +9,7 @@ public class DrainDelegateOperation : BaseOperation public int TargetId { get; set; } public long Amount { get; set; } public long Fee { get; set; } + public long AllocationFee { get; set; } } public static class DrainDelegateOperationModel diff --git a/Tzkt.Sync.Tests/Database/StatisticsTests.cs b/Tzkt.Sync.Tests/Database/StatisticsTests.cs index 0282aa238..cb082dd23 100644 --- a/Tzkt.Sync.Tests/Database/StatisticsTests.cs +++ b/Tzkt.Sync.Tests/Database/StatisticsTests.cs @@ -35,6 +35,7 @@ public static async Task RunAsync(TzktContext db) totalBurned += await db.DoubleEndorsingOps.SumAsync(x => x.LostStaked + x.LostExternalStaked + x.LostUnstaked + x.LostExternalUnstaked - x.Reward); totalBurned += await db.DoublePreendorsingOps.SumAsync(x => x.LostStaked + x.LostExternalStaked + x.LostUnstaked + x.LostExternalUnstaked - x.Reward); totalBurned += await db.RevelationPenaltyOps.SumAsync(x => x.Loss); + totalBurned += await db.DrainDelegateOps.SumAsync(x => x.AllocationFee); totalBurned += await db.RefutationGames.Where(x => x.InitiatorLoss != null || x.OpponentLoss != null).SumAsync(x => (x.InitiatorLoss ?? 0) + (x.OpponentLoss ?? 0) - (x.InitiatorReward ?? 0) - (x.OpponentReward ?? 0)); totalBurned += await db.DalPublishCommitmentOps.Where(x => x.Status == OperationStatus.Applied).SumAsync(x => (x.StorageFee ?? 0) + (x.AllocationFee ?? 0)); totalBurned += await db.DelegationOps.Where(x => x.Status == OperationStatus.Applied).SumAsync(x => (x.StorageFee ?? 0) + (x.AllocationFee ?? 0)); diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DrainDelegateCommit.cs index 9c8109565..0348f6b54 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DrainDelegateCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DrainDelegateCommit.cs @@ -1,6 +1,4 @@ -using System.Linq; -using System.Text.Json; -using System.Threading.Tasks; +using System.Text.Json; using Tzkt.Data.Models; namespace Tzkt.Sync.Protocols.Proto15 @@ -17,15 +15,37 @@ public virtual async Task Apply(Block block, JsonElement op, JsonElement content var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - var amountUpdate = balanceUpdates.FirstOrDefault(x => x.RequiredString("contract") == target.Address); - var amount = amountUpdate.ValueKind != JsonValueKind.Undefined - ? amountUpdate.RequiredInt64("change") + var allocationFeeUpdate = balanceUpdates.SingleOrDefault(x => x.RequiredString("kind") == "burned"); + var allocationFee = allocationFeeUpdate.ValueKind != JsonValueKind.Undefined + ? allocationFeeUpdate.RequiredInt64("change") : 0; - var feeUpdate = balanceUpdates.FirstOrDefault(x => x.RequiredString("contract") == block.Proposer.Address); - var fee = feeUpdate.ValueKind != JsonValueKind.Undefined - ? feeUpdate.RequiredInt64("change") - : 0; + var deposits = balanceUpdates + .Where(x => x.RequiredString("kind") == "contract" && x.RequiredInt64("change") > 0) + .OrderByDescending(x => x.RequiredInt64("change")) + .ToList(); + + var amount = 0L; + var fee = 0L; + + if (deposits.Count == 2) + { + amount = deposits.First(x => x.RequiredString("contract") == target.Address).RequiredInt64("change"); + fee = deposits.Last(x => x.RequiredString("contract") == block.Proposer.Address).RequiredInt64("change"); + } + else if (deposits.Count == 1) + { + if (deposits[0].RequiredString("contract") == target.Address) + amount = deposits[0].RequiredInt64("change"); + else if (deposits[0].RequiredString("contract") == block.Proposer.Address) + fee = deposits[0].RequiredInt64("change"); + else + throw new Exception("Unexpected balance updates behavior"); + } + else if (deposits.Count != 0) + { + throw new Exception("Unexpected balance updates behavior"); + } var operation = new DrainDelegateOperation { @@ -37,7 +57,8 @@ public virtual async Task Apply(Block block, JsonElement op, JsonElement content DelegateId = delegat.Id, TargetId = target.Id, Amount = amount, - Fee = fee + Fee = fee, + AllocationFee = allocationFee }; #endregion @@ -58,6 +79,9 @@ public virtual async Task Apply(Block block, JsonElement op, JsonElement content delegat.Balance -= operation.Fee; delegat.StakingBalance -= operation.Fee; + delegat.Balance -= operation.AllocationFee; + delegat.StakingBalance -= operation.AllocationFee; + target.Balance += operation.Amount; if (targetDelegate != null) { @@ -76,6 +100,8 @@ public virtual async Task Apply(Block block, JsonElement op, JsonElement content block.Fees += operation.Fee; Cache.AppState.Get().DrainDelegateOpsCount++; + + Cache.Statistics.Current.TotalBurned += operation.AllocationFee; #endregion Db.DrainDelegateOps.Add(operation); @@ -104,6 +130,9 @@ public virtual async Task Revert(Block block, DrainDelegateOperation operation) delegat.Balance += operation.Fee; delegat.StakingBalance += operation.Fee; + delegat.Balance += operation.AllocationFee; + delegat.StakingBalance += operation.AllocationFee; + target.Balance -= operation.Amount; if (targetDelegate != null) { diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Validation/Validator.cs index 33cc160b0..9ff9084b0 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Validation/Validator.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto19/Validation/Validator.cs @@ -1,1028 +1,7 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto19 +namespace Tzkt.Sync.Protocols.Proto19 { - class Validator : IValidator + class Validator : Proto1.Validator { - readonly CacheService Cache; - Protocol Protocol; - string Proposer; - string Producer; - int Level; - int Cycle; - - public Validator(ProtocolHandler protocol) => Cache = protocol.Cache; - - public virtual async Task ValidateBlock(JsonElement block) - { - Protocol = await Cache.Protocols.GetAsync(Cache.AppState.GetNextProtocol()); - - if (block.RequiredString("chain_id") != Cache.AppState.GetChainId()) - throw new ValidationException("invalid chain"); - - if (block.RequiredString("protocol") != Cache.AppState.GetNextProtocol()) - throw new ValidationException("invalid block protocol", true); - - ValidateBlockHeader(block.Required("header")); - await ValidateBlockMetadata(block.Required("metadata")); - await ValidateOperations(block.RequiredArray("operations", 4)); - } - - void ValidateBlockHeader(JsonElement header) - { - Level = header.RequiredInt32("level"); - if (Level != Cache.AppState.GetNextLevel()) - throw new ValidationException($"invalid block level", true); - - if (header.RequiredString("predecessor") != Cache.AppState.GetHead()) - throw new ValidationException($"invalid block predecessor", true); - } - - async Task ValidateBlockMetadata(JsonElement metadata) - { - #region baking - Proposer = metadata.RequiredString("proposer"); - if (!Cache.Accounts.DelegateExists(Proposer)) - throw new ValidationException($"non-existent block proposer"); - - Producer = metadata.RequiredString("baker"); - if (!Cache.Accounts.DelegateExists(Producer)) - throw new ValidationException($"non-existent block baker"); - #endregion - - #region level info - Cycle = metadata.Required("level_info").RequiredInt32("cycle"); - if (Cycle != Protocol.GetCycle(Level)) - throw new ValidationException($"invalid block cycle", true); - #endregion - - #region voting info - var periodInfo = metadata.Required("voting_period_info").Required("voting_period"); - var periodIndex = periodInfo.RequiredInt32("index"); - var periodKind = periodInfo.RequiredString("kind") switch - { - "proposal" => PeriodKind.Proposal, - "exploration" => PeriodKind.Exploration, - "cooldown" => PeriodKind.Testing, - "promotion" => PeriodKind.Promotion, - "adoption" => PeriodKind.Adoption, - _ => throw new ValidationException("invalid voting period kind") - }; - - var period = await Cache.Periods.GetAsync(Cache.AppState.Get().VotingPeriod); - if (Level > period.FirstLevel && Level < period.LastLevel) - { - if (periodIndex != period.Index) - throw new ValidationException("invalid voting period index"); - - if (!Protocol.HasDictator && periodKind != period.Kind) - throw new ValidationException("unexpected voting period"); - } - #endregion - - #region deactivation - foreach (var baker in metadata.RequiredArray("deactivated").EnumerateArray()) - if (!Cache.Accounts.DelegateExists(baker.GetString())) - throw new ValidationException($"non-existent deactivated baker {baker}"); - #endregion - - #region balance updates - var balanceUpdates = metadata.RequiredArray("balance_updates").EnumerateArray(); - if (balanceUpdates.Any(x => x.RequiredString("kind") == "contract" && x.RequiredString("origin") == "block" && !Cache.Accounts.DelegateExists(x.RequiredString("contract")))) - throw new ValidationException("non-existent delegate in block balance updates"); - - if (Cycle < Protocol.NoRewardCycles) - { - if (balanceUpdates.Any(x => x.RequiredString("kind") == "minted" && x.RequiredString("category") == "baking rewards")) - throw new ValidationException("unexpected block reward"); - - if (balanceUpdates.Any(x => x.RequiredString("kind") == "minted" && x.RequiredString("category") == "baking bonuses")) - throw new ValidationException("unexpected block bonus"); - } - else - { - if (balanceUpdates.Count(x => x.RequiredString("kind") == "minted" && x.RequiredString("category") == "baking rewards") > 4) - throw new ValidationException("invalid block reward"); - - if (balanceUpdates.Count(x => x.RequiredString("kind") == "minted" && x.RequiredString("category") == "baking bonuses") > 4) - throw new ValidationException("invalid block bonus"); - } - #endregion - - #region implicit operations - foreach (var op in metadata.RequiredArray("implicit_operations_results").EnumerateArray()) - { - var kind = op.RequiredString("kind"); - if (kind == "transaction") - { - var subsidy = op.RequiredArray("balance_updates", 2).EnumerateArray() - .Where(x => x.RequiredString("kind") == "contract"); - - if (subsidy.Count() > 1) - throw new ValidationException("invalid subsidy"); - - if (subsidy.Any(x => x.RequiredString("origin") != "subsidy")) - throw new ValidationException("invalid subsidy origin"); - - if (subsidy.Any(x => x.RequiredString("contract") != Proto10.ProtoActivator.CpmmContract)) - throw new ValidationException("invalid subsidy recepient"); - } - else if (kind == "origination" && Level == Protocol.FirstLevel) - { - var contract = op.RequiredArray("originated_contracts", 1)[0].RequiredString(); - if (!await Cache.Accounts.ExistsAsync(contract, AccountType.Contract)) - throw new ValidationException("unexpected implicit origination"); - } - else - { - throw new ValidationException("unexpected implicit operation kind"); - } - } - #endregion - } - - protected virtual async Task ValidateOperations(JsonElement operations) - { - foreach (var opg in operations.EnumerateArray()) - { - foreach (var op in opg.RequiredArray().EnumerateArray()) - { - foreach (var content in op.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "attestation": ValidateAttestation(content); break; - case "attestation_with_dal": ValidateAttestation(content); break; - case "preattestation": ValidatePreattestation(content); break; - case "preattestation_with_dal": ValidatePreattestation(content); break; - case "ballot": await ValidateBallot(content); break; - case "proposals": ValidateProposal(content); break; - case "activate_account": await ValidateActivation(content); break; - case "double_baking_evidence": ValidateDoubleBaking(content); break; - case "double_attestation_evidence": ValidateDoubleBaking(content); break; - case "double_preattestation_evidence": ValidateDoubleBaking(content); break; - case "seed_nonce_revelation": await ValidateSeedNonceRevelation(content); break; - case "vdf_revelation": ValidateVdfRevelation(content); break; - case "drain_delegate": ValidateDrainDelegate(content); break; - case "delegation": await ValidateDelegation(content); break; - case "origination": await ValidateOrigination(content); break; - case "transaction": await ValidateTransaction(content); break; - case "reveal": await ValidateReveal(content); break; - case "register_global_constant": await ValidateRegisterConstant(content); break; - case "set_deposits_limit": await ValidateSetDepositsLimit(content); break; - case "increase_paid_storage": await ValidateIncreasePaidStorage(content); break; - case "update_consensus_key": await ValidateUpdateConsensusKey(content); break; - case "tx_rollup_origination": await ValidateTxRollupOrigination(content); break; - case "tx_rollup_submit_batch": await ValidateTxRollupSubmitBatch(content); break; - case "tx_rollup_commit": await ValidateTxRollupCommit(content); break; - case "tx_rollup_finalize_commitment": await ValidateTxRollupFinalizeCommitment(content); break; - case "tx_rollup_remove_commitment": await ValidateTxRollupRemoveCommitment(content); break; - case "tx_rollup_return_bond": await ValidateTxRollupReturnBond(content); break; - case "tx_rollup_rejection": await ValidateTxRollupRejection(content); break; - case "tx_rollup_dispatch_tickets": await ValidateTxRollupDispatchTickets(content); break; - case "transfer_ticket": await ValidateTransferTicket(content); break; - case "smart_rollup_add_messages": await ValidateSmartRollupAddMessages(content); break; - case "smart_rollup_cement": await ValidateSmartRollupCement(content); break; - case "smart_rollup_execute_outbox_message": await ValidateSmartRollupExecute(content); break; - case "smart_rollup_originate": await ValidateSmartRollupOriginate(content); break; - case "smart_rollup_publish": await ValidateSmartRollupPublish(content); break; - case "smart_rollup_recover_bond": await ValidateSmartRollupRecoverBond(content); break; - case "smart_rollup_refute": await ValidateSmartRollupRefute(content); break; - case "smart_rollup_timeout": await ValidateSmartRollupTimeout(content); break; - case "dal_publish_commitment": await ValidateDalPublishCommitment(content); break; - default: - throw new ValidationException("invalid operation content kind"); - } - } - } - } - } - - protected virtual void ValidateAttestation(JsonElement content) - { - if (content.RequiredInt32("level") != Cache.AppState.GetLevel()) - throw new ValidationException("invalid attestation level"); - - if (!Cache.Accounts.DelegateExists(content.Required("metadata").RequiredString("delegate"))) - throw new ValidationException("unknown attestation delegate"); - } - - protected virtual void ValidatePreattestation(JsonElement content) - { - if (content.RequiredInt32("level") != Cache.AppState.GetLevel() + 1) - throw new ValidationException("invalid preattestation level"); - - if (!Cache.Accounts.DelegateExists(content.Required("metadata").RequiredString("delegate"))) - throw new ValidationException("unknown preattestation delegate"); - } - - protected virtual async Task ValidateBallot(JsonElement content) - { - var periodIndex = content.RequiredInt32("period"); - - if (Cache.AppState.Get().VotingPeriod != periodIndex) - throw new ValidationException("invalid ballot voting period"); - - var proposal = await Cache.Proposals.GetOrDefaultAsync(Cache.AppState.Get().VotingEpoch, content.RequiredString("proposal")); - if (proposal?.Status != ProposalStatus.Active) - throw new ValidationException("invalid ballot proposal"); - - if (!Cache.Accounts.DelegateExists(content.RequiredString("source"))) - throw new ValidationException("invalid ballot sender"); - } - - protected virtual void ValidateProposal(JsonElement content) - { - var periodIndex = content.RequiredInt32("period"); - - if (Cache.AppState.Get().VotingPeriod != periodIndex) - throw new ValidationException("invalid proposal voting period"); - - var source = content.RequiredString("source"); - if (Protocol.Dictator != source && !Cache.Accounts.DelegateExists(source)) - throw new ValidationException("invalid proposal sender"); - } - - protected virtual async Task ValidateActivation(JsonElement content) - { - var account = content.RequiredString("pkh"); - - if (await Cache.Accounts.ExistsAsync(account, AccountType.User) && - ((await Cache.Accounts.GetAsync(account)) as User).ActivationsCount > 0) - throw new ValidationException("account is already activated"); - - if (content.Required("metadata").RequiredArray("balance_updates", 2)[1].RequiredString("contract") != account) - throw new ValidationException("invalid activation balance updates"); - } - - protected virtual void ValidateDoubleBaking(JsonElement content) - { - } - - protected virtual async Task ValidateSeedNonceRevelation(JsonElement content) - { - var level = content.RequiredInt32("level"); - var proto = await Cache.Protocols.FindByLevelAsync(level); - - if ((level - Cache.Protocols.GetCycleStart(proto.GetCycle(level)) + 1) % proto.BlocksPerCommitment != 0) - throw new ValidationException("invalid seed nonce revelation level"); - - var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - - if (balanceUpdates.Count() % 2 != 0) - throw new ValidationException("invalid seed nonce revelation balance updates count"); - - if (balanceUpdates.Any(x => - x.RequiredString("kind") == "contract" && Proposer != x.RequiredString("contract") || - x.RequiredString("kind") == "freezer" && Proposer != ( - x.Required("staker").Optional("baker_own_stake")?.GetString() - ?? x.Required("staker").Optional("baker_edge")?.GetString() - ?? x.Required("staker").Required("delegate").GetString() - ))) - throw new ValidationException("invalid seed nonce revelation baker"); - } - - protected virtual void ValidateVdfRevelation(JsonElement content) - { - var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - - if (balanceUpdates.Count() % 2 != 0) - throw new ValidationException("invalid vdf revelation balance updates count"); - - if (balanceUpdates.Any(x => - x.RequiredString("kind") == "contract" && Proposer != x.RequiredString("contract") || - x.RequiredString("kind") == "freezer" && Proposer != ( - x.Required("staker").Optional("baker_own_stake")?.GetString() - ?? x.Required("staker").Optional("baker_edge")?.GetString() - ?? x.Required("staker").Required("delegate").GetString() - ))) - throw new ValidationException("invalid vdf revelation baker"); - } - - protected virtual void ValidateDrainDelegate(JsonElement content) - { - var drainedBaker = content.RequiredString("delegate"); - var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - - if (!Cache.Accounts.DelegateExists(drainedBaker)) - throw new ValidationException("unknown drained delegate"); - - if (balanceUpdates.Count() % 2 != 0) - throw new ValidationException("invalid drain balance updates count"); - - if (balanceUpdates.Where(x => x.RequiredInt64("change") < 0).Any(x => x.RequiredString("contract") != drainedBaker)) - throw new ValidationException("invalid drain balance updates"); - } - - protected virtual async Task ValidateDelegation(JsonElement content) - { - var source = content.RequiredString("source"); - var delegat = content.OptionalString("delegate"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - if (content.Required("metadata").Required("operation_result").RequiredString("status") == "applied" && delegat != null) - if (source != delegat && !Cache.Accounts.DelegateExists(delegat)) - throw new ValidationException("unknown delegate account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual void ValidateInternalDelegation(JsonElement content, string initiator) - { - //var delegat = content.OptionalString("delegate"); - - //if (content.Required("result").RequiredString("status") == "applied" && delegat != null) - // if (!Cache.Accounts.DelegateExists(delegat)) - // throw new ValidationException("unknown delegate account"); - } - - protected virtual async Task ValidateOrigination(JsonElement content) - { - var source = content.RequiredString("source"); - var delegat = content.OptionalString("delegate"); - var metadata = content.Required("metadata"); - var result = metadata.Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - if (applied && delegat != null) - if (!Cache.Accounts.DelegateExists(delegat)) - throw new ValidationException("unknown delegate account"); - - ValidateFeeBalanceUpdates( - metadata.OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - if (applied && result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.EnumerateArray(), - source, - result.RequiredArray("originated_contracts", 1)[0].RequiredString(), - content.RequiredInt64("balance"), - (result.OptionalInt32("paid_storage_size_diff") ?? 0) * Protocol.ByteCost, - Protocol.OriginationSize * Protocol.ByteCost); - } - - protected virtual void ValidateInternalOrigination(JsonElement content, string initiator) - { - //var delegat = content.OptionalString("delegate"); - var result = content.Required("result"); - var applied = result.RequiredString("status") == "applied"; - - //if (applied && delegat != null) - // if (!Cache.Accounts.DelegateExists(delegat)) - // throw new ValidationException("unknown delegate account"); - - if (applied && result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.RequiredArray().EnumerateArray(), - content.RequiredString("source"), - result.RequiredArray("originated_contracts", 1)[0].RequiredString(), - content.RequiredInt64("balance"), - (result.OptionalInt32("paid_storage_size_diff") ?? 0) * Protocol.ByteCost, - Protocol.OriginationSize * Protocol.ByteCost, - initiator); - } - - protected virtual async Task ValidateTransaction(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - var metadata = content.Required("metadata"); - - ValidateFeeBalanceUpdates( - metadata.OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = metadata.Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied) - { - var target = content.RequiredString("destination"); - - if (source == target && source.StartsWith("tz") && content.Optional("parameters")?.RequiredString("entrypoint") is string entrypoint) - { - switch (entrypoint) - { - case "stake": - case "unstake": - case "finalize_unstake": - case "set_delegate_parameters": - return; - default: - throw new ValidationException("unsupported staking operation"); - } - } - - if (result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.RequiredArray().EnumerateArray(), - source, - target, - content.RequiredInt64("amount"), - (result.OptionalInt32("paid_storage_size_diff") ?? 0) * Protocol.ByteCost, - (result.OptionalBool("allocated_destination_contract") ?? false) ? Protocol.OriginationSize * Protocol.ByteCost : 0); - } - - if (metadata.TryGetProperty("internal_operation_results", out var internalResults)) - { - foreach (var internalContent in internalResults.RequiredArray().EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": ValidateInternalDelegation(internalContent, source); break; - case "origination": ValidateInternalOrigination(internalContent, source); break; - case "transaction": ValidateInternalTransaction(internalContent, source); break; - case "event": break; - default: - throw new ValidationException("invalid internal operation kind"); - } - } - } - } - - protected virtual void ValidateInternalTransaction(JsonElement content, string initiator) - { - var result = content.Required("result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied && result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.RequiredArray().EnumerateArray(), - content.RequiredString("source"), - content.RequiredString("destination"), - content.RequiredInt64("amount"), - (result.OptionalInt32("paid_storage_size_diff") ?? 0) * Protocol.ByteCost, - (result.OptionalBool("allocated_destination_contract") ?? false) ? Protocol.OriginationSize * Protocol.ByteCost : 0, - initiator); - } - - protected virtual async Task ValidateReveal(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateDalPublishCommitment(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateRegisterConstant(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateSetDepositsLimit(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateIncreasePaidStorage(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateUpdateConsensusKey(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateTxRollupOrigination(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied && result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.EnumerateArray(), - source, - null, - 0, - 0, - 4_000 * Protocol.ByteCost); - } - - protected virtual async Task ValidateTxRollupSubmitBatch(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied && result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.EnumerateArray(), - source, - null, - 0, - (result.OptionalInt32("paid_storage_size_diff") ?? 0) * Protocol.ByteCost, - 0); - } - - protected virtual async Task ValidateTxRollupCommit(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - if (result.TryGetProperty("balance_updates", out var updates) && updates.Count() != 0) - { - if (updates.Count() != 2) - throw new ValidationException("unexpected number of rollup bonds balance updates"); - - if (!updates.EnumerateArray().Any(x => - x.RequiredString("kind") == "contract" && - x.RequiredString("contract") == source)) - throw new ValidationException("invalid transfer balance updates"); - - if (!updates.EnumerateArray().Any(x => - x.RequiredString("kind") == "freezer" && - x.RequiredString("category") == "bonds" && - x.RequiredString("contract") == source)) - throw new ValidationException("invalid transfer balance updates"); - - if (updates[0].RequiredInt64("change") != -updates[1].RequiredInt64("change")) - throw new ValidationException("inconsistent change of rollup bonds balance updates"); - } - } - - protected virtual async Task ValidateTxRollupFinalizeCommitment(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - if (result.TryGetProperty("balance_updates", out var updates) && updates.Count() != 0) - throw new ValidationException("unexpected balance updates"); - } - - protected virtual async Task ValidateTxRollupRemoveCommitment(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - if (result.TryGetProperty("balance_updates", out var updates) && updates.Count() != 0) - throw new ValidationException("unexpected balance updates"); - } - - protected virtual async Task ValidateTxRollupReturnBond(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - if (result.TryGetProperty("balance_updates", out var updates) && updates.Count() != 0) - { - if (updates.Count() != 2) - throw new ValidationException("unexpected number of rollup bonds balance updates"); - - if (!updates.EnumerateArray().Any(x => - x.RequiredString("kind") == "contract" && - x.RequiredString("contract") == source)) - throw new ValidationException("invalid transfer balance updates"); - - if (!updates.EnumerateArray().Any(x => - x.RequiredString("kind") == "freezer" && - x.RequiredString("category") == "bonds" && - x.RequiredString("contract") == source)) - throw new ValidationException("invalid transfer balance updates"); - - if (updates[0].RequiredInt64("change") != -updates[1].RequiredInt64("change")) - throw new ValidationException("inconsistent change of rollup bonds balance updates"); - } - } - - protected virtual async Task ValidateTxRollupRejection(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateTxRollupDispatchTickets(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateTransferTicket(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateSmartRollupAddMessages(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied && result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.EnumerateArray(), - source, - null, - 0, - 0, - 0); - } - - protected virtual async Task ValidateSmartRollupCement(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - if (result.RequiredString("status") == "applied" && - result.TryGetProperty("balance_updates", out var updates) && updates.Count() > 0) - throw new ValidationException("unexpected balnce updates"); - } - - protected virtual async Task ValidateSmartRollupExecute(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - var metadata = content.Required("metadata"); - - ValidateFeeBalanceUpdates( - metadata.OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = metadata.Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied && result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.RequiredArray().EnumerateArray(), - source, - null, - 0, - (result.OptionalInt32("paid_storage_size_diff") ?? 0) * Protocol.ByteCost, - 0); - - if (metadata.TryGetProperty("internal_operation_results", out var internalResults)) - { - foreach (var internalContent in internalResults.RequiredArray().EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": ValidateInternalDelegation(internalContent, source); break; - case "origination": ValidateInternalOrigination(internalContent, source); break; - case "transaction": ValidateInternalTransaction(internalContent, source); break; - case "event": break; - default: - throw new ValidationException("invalid internal operation kind"); - } - } - } - } - - protected virtual async Task ValidateSmartRollupOriginate(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied && result.TryGetProperty("balance_updates", out var resultUpdates)) - ValidateTransferBalanceUpdates( - resultUpdates.EnumerateArray(), - source, - null, - 0, - (result.OptionalInt32("size") ?? 0) * Protocol.ByteCost, - 0); - } - - protected virtual async Task ValidateSmartRollupPublish(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - if (result.TryGetProperty("balance_updates", out var updates) && updates.Count() != 0) - { - if (updates.Count() != 2) - throw new ValidationException("unexpected number of smart rollup bonds balance updates"); - - if (!updates.EnumerateArray().Any(x => - x.RequiredString("kind") == "contract" && - x.RequiredString("contract") == source)) - throw new ValidationException("invalid smart rollup bonds balance updates"); - - if (!updates.EnumerateArray().Any(x => - x.RequiredString("kind") == "freezer" && - x.RequiredString("category") == "bonds" && - x.RequiredString("contract") == source)) - throw new ValidationException("invalid smart rollup bonds balance updates"); - - if (updates[0].RequiredInt64("change") != -updates[1].RequiredInt64("change")) - throw new ValidationException("inconsistent change of smart rollup bonds balance updates"); - } - } - - protected virtual async Task ValidateSmartRollupRecoverBond(JsonElement content) - { - var source = content.RequiredString("source"); - var staker = content.RequiredString("staker"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - - var result = content.Required("metadata").Required("operation_result"); - if (result.TryGetProperty("balance_updates", out var updates) && updates.Count() != 0) - { - if (updates.Count() != 2) - throw new ValidationException("unexpected number of smart rollup bonds balance updates"); - - if (!updates.EnumerateArray().Any(x => - x.RequiredString("kind") == "contract" && - x.RequiredString("contract") == staker)) - throw new ValidationException("invalid smart rollup bonds balance updates"); - - if (!updates.EnumerateArray().Any(x => - x.RequiredString("kind") == "freezer" && - x.RequiredString("category") == "bonds" && - x.RequiredString("contract") == staker)) - throw new ValidationException("invalid smart rollup bonds balance updates"); - - if (updates[0].RequiredInt64("change") != -updates[1].RequiredInt64("change")) - throw new ValidationException("inconsistent change of smart rollup bonds balance updates"); - } - } - - protected virtual async Task ValidateSmartRollupRefute(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateSmartRollupTimeout(JsonElement content) - { - var source = content.RequiredString("source"); - - if (!await Cache.Accounts.ExistsAsync(source)) - throw new ValidationException("unknown source account"); - - ValidateFeeBalanceUpdates( - content.Required("metadata").OptionalArray("balance_updates")?.EnumerateArray() ?? Enumerable.Empty(), - source, - content.RequiredInt64("fee")); - } - - protected virtual void ValidateFeeBalanceUpdates(IEnumerable balanceUpdates, string sender, long fee) - { - if (fee != 0) - { - if (balanceUpdates.Count() != 2) - throw new ValidationException("invalid fee balance updates count"); - - var first = balanceUpdates.First(); - var last = balanceUpdates.Last(); - - if (first.RequiredString("kind") != "contract" || - first.RequiredString("contract") != sender || - first.RequiredInt64("change") != -fee) - throw new ValidationException("invalid fee contract update"); - - if (last.RequiredString("kind") != "accumulator" || - last.RequiredString("category") != "block fees" || - last.RequiredInt64("change") != fee) - throw new ValidationException("invalid fee accumulator update"); - } - else - { - if (balanceUpdates.Any()) - throw new ValidationException("invalid fee balance updates count"); - } - } - - protected virtual void ValidateTransferBalanceUpdates(IEnumerable balanceUpdates, string sender, string target, long amount, long storageFee, long allocationFee, string initiator = null) - { - if (balanceUpdates.Count() != (amount != 0 ? 2 : 0) + (storageFee != 0 ? 2 : 0) + (allocationFee != 0 ? 2 : 0)) - throw new ValidationException("invalid transfer balance updates count"); - - if (amount > 0) - { - if (!balanceUpdates.Any(x => - x.RequiredString("kind") == "contract" && - x.RequiredInt64("change") == -amount && - x.RequiredString("contract") == sender)) - throw new ValidationException("invalid transfer balance updates"); - - if (!balanceUpdates.Any(x => - x.RequiredString("kind") == "contract" && - x.RequiredInt64("change") == amount && - x.RequiredString("contract") == target)) - throw new ValidationException("invalid transfer balance updates"); - } - - if (storageFee > 0) - { - if (!balanceUpdates.Any(x => - x.RequiredString("kind") == "contract" && - x.RequiredInt64("change") == -storageFee && - x.RequiredString("contract") == (initiator ?? sender))) - throw new ValidationException("invalid storage fee balance updates"); - - if (!balanceUpdates.Any(x => - x.RequiredString("kind") == "burned" && - x.RequiredString("category") == "storage fees" && - x.RequiredInt64("change") == storageFee)) - throw new ValidationException("invalid storage fee balance updates"); - } - - if (allocationFee > 0) - { - if (!balanceUpdates.Any(x => - x.RequiredString("kind") == "contract" && - x.RequiredInt64("change") == -allocationFee && - x.RequiredString("contract") == (initiator ?? sender))) - throw new ValidationException("invalid allocation fee balance updates"); - - if (!balanceUpdates.Any(x => - x.RequiredString("kind") == "burned" && - x.RequiredString("category") == "storage fees" && - x.RequiredInt64("change") == allocationFee)) - throw new ValidationException("invalid allocation fee balance updates"); - } - } + public Validator(ProtocolHandler protocol) : base(protocol) { } } }