diff --git a/Tzkt.Api/Controllers/AccountsController.cs b/Tzkt.Api/Controllers/AccountsController.cs index 3aef0af33..9656dcebb 100644 --- a/Tzkt.Api/Controllers/AccountsController.cs +++ b/Tzkt.Api/Controllers/AccountsController.cs @@ -541,7 +541,7 @@ public async Task GetBalanceReport( [Required][Address] string address, DateTimeOffset? from, DateTimeOffset? to, - string currency, + string? currency, bool historical = false, string delimiter = "comma", string separator = "point") diff --git a/Tzkt.Api/Models/Accounts/Ghost.cs b/Tzkt.Api/Models/Accounts/Ghost.cs index ad811fa98..7b5b7daea 100644 --- a/Tzkt.Api/Models/Accounts/Ghost.cs +++ b/Tzkt.Api/Models/Accounts/Ghost.cs @@ -24,6 +24,21 @@ public class Ghost : Account /// public string? Alias { get; set; } + /// + /// Number of all transaction (tez transfer) operations, related to the account + /// + public int NumTransactions { get; set; } + + /// + /// Number of transfer ticket operations sent by the account + /// + public int TransferTicketCount { get; set; } + + /// + /// Number of `increase_paid_storage` operations sent by the account + /// + public int IncreasePaidStorageCount { get; set; } + /// /// Number of account tokens with non-zero balances /// diff --git a/Tzkt.Api/Models/Operations/IncreasePaidStorageOperation.cs b/Tzkt.Api/Models/Operations/IncreasePaidStorageOperation.cs index df7fb9cb6..3c0c6afdd 100644 --- a/Tzkt.Api/Models/Operations/IncreasePaidStorageOperation.cs +++ b/Tzkt.Api/Models/Operations/IncreasePaidStorageOperation.cs @@ -86,7 +86,7 @@ public class IncreasePaidStorageOperation : Operation /// /// Information about the contract for which paid storage was increased /// - public Alias? Contract { get; set; } + public required Alias Contract { get; set; } /// /// Amount of storage in bytes prepaid. diff --git a/Tzkt.Api/Models/Operations/TransactionOperation.cs b/Tzkt.Api/Models/Operations/TransactionOperation.cs index 716b9f247..a94b5e81e 100644 --- a/Tzkt.Api/Models/Operations/TransactionOperation.cs +++ b/Tzkt.Api/Models/Operations/TransactionOperation.cs @@ -95,7 +95,7 @@ public class TransactionOperation : Operation /// /// Information about the target of the transaction /// - public Alias? Target { get; set; } + public required Alias Target { get; set; } /// /// Hash of the target contract code, or `null` is the target is not a contract diff --git a/Tzkt.Api/Models/Operations/TransferTicketOperation.cs b/Tzkt.Api/Models/Operations/TransferTicketOperation.cs index 0c76443a9..b9c268a52 100644 --- a/Tzkt.Api/Models/Operations/TransferTicketOperation.cs +++ b/Tzkt.Api/Models/Operations/TransferTicketOperation.cs @@ -78,12 +78,12 @@ public class TransferTicketOperation : Operation /// /// Information about the target to which the operation was sent /// - public Alias? Target { get; set; } + public required Alias Target { get; set; } /// /// Information about the ticketer /// - public Alias? Ticketer { get; set; } + public required Alias Ticketer { get; set; } /// /// Amount sent diff --git a/Tzkt.Api/Program.cs b/Tzkt.Api/Program.cs index b67088631..9fe24ecab 100644 --- a/Tzkt.Api/Program.cs +++ b/Tzkt.Api/Program.cs @@ -230,7 +230,7 @@ } var state = db.AppState.Single(); - if (state.Level < 1) + if (state.BlocksCount < 2) { logger.LogWarning("No data in the database. Let's wait for the indexer to index at least two blocks, and try again."); Thread.Sleep(3000); diff --git a/Tzkt.Api/Repositories/AccountRepository.cs b/Tzkt.Api/Repositories/AccountRepository.cs index 8a7c2d8db..13ce3f4db 100644 --- a/Tzkt.Api/Repositories/AccountRepository.cs +++ b/Tzkt.Api/Repositories/AccountRepository.cs @@ -386,6 +386,9 @@ public async Task GetCounterAsync(string address) Id = rawAccount.Id, Alias = rawAccount.Alias, Address = rawAccount.Address, + NumTransactions = rawAccount.TransactionsCount, + TransferTicketCount = rawAccount.TransferTicketCount, + IncreasePaidStorageCount = rawAccount.IncreasePaidStorageCount, ActiveTokensCount = rawAccount.ActiveTokensCount, TokenBalancesCount = rawAccount.TokenBalancesCount, TokenTransfersCount = rawAccount.TokenTransfersCount, @@ -712,6 +715,9 @@ public async Task> Get( Id = row.Id, Alias = row.Alias, Address = row.Address, + NumTransactions = row.TransactionsCount, + TransferTicketCount = row.TransferTicketCount, + IncreasePaidStorageCount = row.IncreasePaidStorageCount, ActiveTokensCount = row.ActiveTokensCount, TokenBalancesCount = row.TokenBalancesCount, TokenTransfersCount = row.TokenTransfersCount, @@ -2965,6 +2971,31 @@ await Task.WhenAll( result.AddRange(smartRollupSrRecoverBondOps.Result); result.AddRange(smartRollupSrRefuteOps.Result); + break; + case RawAccount ghost: + var _ghost = new AccountParameter { Eq = ghost.Id }; + + var ghostTransactions = ghost.TransactionsCount > 0 && types.Contains(ActivityTypes.Transaction) + ? Operations.GetTransactions(null, new AnyOfParameter { Fields = ["initiator", "sender", "target"], Eq = ghost.Id }, initiator, sender, target, null, null, level, timestamp, null, null, null, entrypoint, parameter, hasInternals, status, sort, offset, limit, format, quote) + : Task.FromResult(Enumerable.Empty()); + + var ghostTransferTicketOps = ghost.TransferTicketCount > 0 && types.Contains(ActivityTypes.TransferTicket) + ? Operations.GetTransferTicketOps(null, null, _ghost, null, null, null, level, timestamp, status, sort, offset, limit, format, quote) + : Task.FromResult(Enumerable.Empty()); + + var ghostIncreasePaidStorageOps = ghost.IncreasePaidStorageCount > 0 && types.Contains(ActivityTypes.IncreasePaidStorage) + ? Operations.GetIncreasePaidStorageOps(null, _ghost, null, level, timestamp, status, sort, offset, limit, quote) + : Task.FromResult(Enumerable.Empty()); + + await Task.WhenAll( + ghostTransactions, + ghostTransferTicketOps, + ghostIncreasePaidStorageOps); + + result.AddRange(ghostTransactions.Result); + result.AddRange(ghostTransferTicketOps.Result); + result.AddRange(ghostIncreasePaidStorageOps.Result); + break; default: break; diff --git a/Tzkt.Api/Repositories/BalanceHistoryRepository.cs b/Tzkt.Api/Repositories/BalanceHistoryRepository.cs index 3daea5eeb..d2647df9b 100644 --- a/Tzkt.Api/Repositories/BalanceHistoryRepository.cs +++ b/Tzkt.Api/Repositories/BalanceHistoryRepository.cs @@ -289,19 +289,19 @@ string SumUnion(RawAccount account, int from, int to) if (user.StakingUpdatesCount > 0) SumStakingUpdates(union, from, to); } - if (account is RawDelegate delegat) - { - if (delegat.AttestationRewardsCount > 0) SumAttestationRewards(union, from, to); - if (delegat.DalAttestationRewardsCount > 0) SumDalAttestationRewards(union, from, to); - if (delegat.BlocksCount > 0) SumBaking(union, from, to); - if (delegat.AttestationsCount > 0) SumAttestations(union, from, to); - if (delegat.DoubleBakingCount > 0) SumDoubleBaking(union, from, to); - if (delegat.DoubleConsensusCount > 0) SumDoubleConsensus(union, from, to); - if (delegat.NonceRevelationsCount > 0) SumNonceRevelations(union, from, to); - if (delegat.VdfRevelationsCount > 0) SumVdfRevelations(union, from, to); - if (delegat.RevelationPenaltiesCount > 0) SumRevelationPenalties(union, from, to); - if (delegat.UpdateSecondaryKeyCount > 0) SumUpdateSecondaryKeyOps(union, from, to); - } + //if (account is RawDelegate delegat) + //{ + // if (delegat.AttestationRewardsCount > 0) SumAttestationRewards(union, from, to); + // if (delegat.DalAttestationRewardsCount > 0) SumDalAttestationRewards(union, from, to); + // if (delegat.BlocksCount > 0) SumBaking(union, from, to); + // if (delegat.AttestationsCount > 0) SumAttestations(union, from, to); + // if (delegat.DoubleBakingCount > 0) SumDoubleBaking(union, from, to); + // if (delegat.DoubleConsensusCount > 0) SumDoubleConsensus(union, from, to); + // if (delegat.NonceRevelationsCount > 0) SumNonceRevelations(union, from, to); + // if (delegat.VdfRevelationsCount > 0) SumVdfRevelations(union, from, to); + // if (delegat.RevelationPenaltiesCount > 0) SumRevelationPenalties(union, from, to); + // if (delegat.UpdateSecondaryKeyCount > 0) SumUpdateSecondaryKeyOps(union, from, to); + //} return union.ToString(); } @@ -1250,19 +1250,19 @@ string SelectUnion(RawAccount account) if (user.StakingUpdatesCount > 0) UnionStakingUpdates(union); } - if (account is RawDelegate delegat) - { - if (delegat.AttestationRewardsCount > 0) UnionAttestationRewards(union); - if (delegat.DalAttestationRewardsCount > 0) UnionDalAttestationRewards(union); - if (delegat.BlocksCount > 0) UnionBaking(union); - if (delegat.AttestationsCount > 0) UnionAttestations(union); - if (delegat.DoubleBakingCount > 0) UnionDoubleBaking(union); - if (delegat.DoubleConsensusCount > 0) UnionDoubleConsensus(union); - if (delegat.NonceRevelationsCount > 0) UnionNonceRevelations(union); - if (delegat.VdfRevelationsCount > 0) UnionVdfRevelations(union); - if (delegat.RevelationPenaltiesCount > 0) UnionRevelationPenalties(union); - if (delegat.UpdateSecondaryKeyCount > 0) UnionUpdateSecondaryKeyOps(union); - } + //if (account is RawDelegate delegat) + //{ + // if (delegat.AttestationRewardsCount > 0) UnionAttestationRewards(union); + // if (delegat.DalAttestationRewardsCount > 0) UnionDalAttestationRewards(union); + // if (delegat.BlocksCount > 0) UnionBaking(union); + // if (delegat.AttestationsCount > 0) UnionAttestations(union); + // if (delegat.DoubleBakingCount > 0) UnionDoubleBaking(union); + // if (delegat.DoubleConsensusCount > 0) UnionDoubleConsensus(union); + // if (delegat.NonceRevelationsCount > 0) UnionNonceRevelations(union); + // if (delegat.VdfRevelationsCount > 0) UnionVdfRevelations(union); + // if (delegat.RevelationPenaltiesCount > 0) UnionRevelationPenalties(union); + // if (delegat.UpdateSecondaryKeyCount > 0) UnionUpdateSecondaryKeyOps(union); + //} return union.ToString(); } diff --git a/Tzkt.Api/Repositories/OperationRepository.Baking.cs b/Tzkt.Api/Repositories/OperationRepository.Baking.cs index 5fb5bd22a..4cf13f5ca 100644 --- a/Tzkt.Api/Repositories/OperationRepository.Baking.cs +++ b/Tzkt.Api/Repositories/OperationRepository.Baking.cs @@ -50,7 +50,7 @@ public async Task GetBakingsCount( BonusStakedOwn = row.BonusStakedOwn, BonusStakedEdge = row.BonusStakedEdge, BonusStakedShared = row.BonusStakedShared, - Fees = row.Fees, + Fees = 0,//row.Fees, Quote = Quotes.Get(quote, row.Level) }; } @@ -139,7 +139,7 @@ public async Task> GetBakings( BonusStakedOwn = row.BonusStakedOwn, BonusStakedEdge = row.BonusStakedEdge, BonusStakedShared = row.BonusStakedShared, - Fees = row.Fees, + Fees = 0,//row.Fees, Quote = Quotes.Get(quote, row.Level) }); } @@ -278,7 +278,7 @@ public async Task> GetBakings( break; case "fees": foreach (var row in rows) - result[j++][i] = row.Fees; + result[j++][i] = 0;// row.Fees; break; case "quote": foreach (var row in rows) @@ -419,7 +419,7 @@ public async Task> GetBakings( break; case "fees": foreach (var row in rows) - result[j++] = row.Fees; + result[j++] = 0;// row.Fees; break; case "quote": foreach (var row in rows) diff --git a/Tzkt.Api/Repositories/OperationRepository.IncreasePaidStorage.cs b/Tzkt.Api/Repositories/OperationRepository.IncreasePaidStorage.cs index c1e71697a..f33a75e5a 100644 --- a/Tzkt.Api/Repositories/OperationRepository.IncreasePaidStorage.cs +++ b/Tzkt.Api/Repositories/OperationRepository.IncreasePaidStorage.cs @@ -47,7 +47,7 @@ INNER JOIN ""Blocks"" as b BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, Status = OpStatuses.ToString(row.Status), - Contract = row.ContractId == null ? null : Accounts.GetAlias(row.ContractId), + Contract = Accounts.GetAlias(row.ContractId), Amount = row.Amount, Errors = row.Errors != null ? OperationErrorSerializer.Deserialize(row.Errors) : null, Quote = Quotes.Get(quote, row.Level) @@ -83,7 +83,7 @@ INNER JOIN ""Blocks"" as b BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, Status = OpStatuses.ToString(row.Status), - Contract = row.ContractId == null ? null : Accounts.GetAlias(row.ContractId), + Contract = Accounts.GetAlias(row.ContractId), Amount = row.Amount, Errors = row.Errors != null ? OperationErrorSerializer.Deserialize(row.Errors) : null, Quote = Quotes.Get(quote, row.Level) @@ -117,7 +117,7 @@ SELECT o.* BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, Status = OpStatuses.ToString(row.Status), - Contract = row.ContractId == null ? null : Accounts.GetAlias(row.ContractId), + Contract = Accounts.GetAlias(row.ContractId), Amount = row.Amount, Errors = row.Errors != null ? OperationErrorSerializer.Deserialize(row.Errors) : null, Quote = Quotes.Get(quote, row.Level) @@ -221,7 +221,7 @@ INNER JOIN ""Blocks"" as b BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, Status = OpStatuses.ToString(row.Status), - Contract = row.ContractId == null ? null : Accounts.GetAlias(row.ContractId), + Contract = Accounts.GetAlias(row.ContractId), Amount = row.Amount, Errors = row.Errors != null ? OperationErrorSerializer.Deserialize(row.Errors) : null, Quote = Quotes.Get(quote, row.Level) @@ -359,7 +359,7 @@ INNER JOIN ""Blocks"" as b break; case "contract": foreach (var row in rows) - result[j++][i] = row.ContractId == null ? null : Accounts.GetAlias(row.ContractId); + result[j++][i] = Accounts.GetAlias(row.ContractId); break; case "amount": foreach (var row in rows) @@ -505,7 +505,7 @@ INNER JOIN ""Blocks"" as b break; case "contract": foreach (var row in rows) - result[j++] = row.ContractId == null ? null : Accounts.GetAlias(row.ContractId); + result[j++] = Accounts.GetAlias(row.ContractId); break; case "amount": foreach (var row in rows) diff --git a/Tzkt.Api/Repositories/OperationRepository.Transactions.cs b/Tzkt.Api/Repositories/OperationRepository.Transactions.cs index ea9f4b550..82881e8dd 100644 --- a/Tzkt.Api/Repositories/OperationRepository.Transactions.cs +++ b/Tzkt.Api/Repositories/OperationRepository.Transactions.cs @@ -91,7 +91,7 @@ INNER JOIN ""Blocks"" as b BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, AllocationFee = row.AllocationFee ?? 0, - Target = row.TargetId != null ? Accounts.GetAlias(row.TargetId) : null, + Target = Accounts.GetAlias(row.TargetId), TargetCodeHash = row.TargetCodeHash, Amount = row.Amount, Parameter = row.Entrypoint == null ? null : new TxParameter @@ -167,7 +167,7 @@ INNER JOIN ""Blocks"" as b BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, AllocationFee = row.AllocationFee ?? 0, - Target = row.TargetId != null ? Accounts.GetAlias(row.TargetId) : null, + Target = Accounts.GetAlias(row.TargetId), TargetCodeHash = row.TargetCodeHash, Amount = row.Amount, Parameter = row.Entrypoint == null ? null : new TxParameter @@ -242,7 +242,7 @@ INNER JOIN ""Blocks"" as b BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, AllocationFee = row.AllocationFee ?? 0, - Target = row.TargetId != null ? Accounts.GetAlias(row.TargetId) : null, + Target = Accounts.GetAlias(row.TargetId), TargetCodeHash = row.TargetCodeHash, Amount = row.Amount, Parameter = row.Entrypoint == null ? null : new TxParameter @@ -299,7 +299,7 @@ public async Task> GetTransactions(Block block BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, AllocationFee = row.AllocationFee ?? 0, - Target = row.TargetId != null ? Accounts.GetAlias(row.TargetId) : null, + Target = Accounts.GetAlias(row.TargetId), TargetCodeHash = row.TargetCodeHash, Amount = row.Amount, Parameter = row.Entrypoint == null ? null : new TxParameter @@ -501,7 +501,7 @@ INNER JOIN ""Blocks"" as b BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, AllocationFee = row.AllocationFee ?? 0, - Target = row.TargetId != null ? Accounts.GetAlias(row.TargetId) : null, + Target = Accounts.GetAlias(row.TargetId), TargetCodeHash = row.TargetCodeHash, Amount = row.Amount, Parameter = row.Entrypoint == null ? null : new TxParameter @@ -743,7 +743,7 @@ INNER JOIN ""Blocks"" as b break; case "target": foreach (var row in rows) - result[j++][i] = row.TargetId != null ? await Accounts.GetAliasAsync(row.TargetId) : null; + result[j++][i] = await Accounts.GetAliasAsync(row.TargetId); break; case "targetCodeHash": foreach (var row in rows) @@ -1038,7 +1038,7 @@ INNER JOIN ""Blocks"" as b break; case "target": foreach (var row in rows) - result[j++] = row.TargetId != null ? await Accounts.GetAliasAsync(row.TargetId) : null; + result[j++] = await Accounts.GetAliasAsync(row.TargetId); break; case "targetCodeHash": foreach (var row in rows) diff --git a/Tzkt.Api/Repositories/OperationRepository.TransferTicket.cs b/Tzkt.Api/Repositories/OperationRepository.TransferTicket.cs index a684cec44..01e616284 100644 --- a/Tzkt.Api/Repositories/OperationRepository.TransferTicket.cs +++ b/Tzkt.Api/Repositories/OperationRepository.TransferTicket.cs @@ -54,8 +54,8 @@ INNER JOIN ""Blocks"" as b StorageUsed = row.StorageUsed, BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, - Target = row.TargetId == null ? null : Accounts.GetAlias(row.TargetId) , - Ticketer = row.TicketerId == null ? null : Accounts.GetAlias(row.TicketerId), + Target = Accounts.GetAlias(row.TargetId), + Ticketer = Accounts.GetAlias(row.TicketerId), Amount = row.Amount, Entrypoint = row.Entrypoint, ContentType = (RawJson)Micheline.ToJson(row.RawType), @@ -102,8 +102,8 @@ INNER JOIN ""Blocks"" as b StorageUsed = row.StorageUsed, BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, - Target = row.TargetId == null ? null : Accounts.GetAlias(row.TargetId), - Ticketer = row.TicketerId == null ? null : Accounts.GetAlias(row.TicketerId), + Target = Accounts.GetAlias(row.TargetId), + Ticketer = Accounts.GetAlias(row.TicketerId), Amount = row.Amount, Entrypoint = row.Entrypoint, ContentType = (RawJson)Micheline.ToJson(row.RawType), @@ -148,8 +148,8 @@ SELECT o.* StorageUsed = row.StorageUsed, BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, - Target = row.TargetId == null ? null : Accounts.GetAlias(row.TargetId), - Ticketer = row.TicketerId == null ? null : Accounts.GetAlias(row.TicketerId), + Target = Accounts.GetAlias(row.TargetId), + Ticketer = Accounts.GetAlias(row.TicketerId), Amount = row.Amount, Entrypoint = row.Entrypoint, ContentType = (RawJson)Micheline.ToJson(row.RawType), @@ -285,8 +285,8 @@ INNER JOIN ""Blocks"" as b StorageUsed = row.StorageUsed, BakerFee = row.BakerFee, StorageFee = row.StorageFee ?? 0, - Target = row.TargetId == null ? null : Accounts.GetAlias(row.TargetId), - Ticketer = row.TicketerId == null ? null : Accounts.GetAlias(row.TicketerId), + Target = Accounts.GetAlias(row.TargetId), + Ticketer = Accounts.GetAlias(row.TicketerId), Amount = row.Amount, Entrypoint = row.Entrypoint, ContentType = (RawJson)Micheline.ToJson(row.RawType), @@ -456,11 +456,11 @@ INNER JOIN ""Blocks"" as b break; case "target": foreach (var row in rows) - result[j++][i] = row.TargetId == null ? null : await Accounts.GetAliasAsync(row.TargetId); + result[j++][i] = await Accounts.GetAliasAsync(row.TargetId); break; case "ticketer": foreach (var row in rows) - result[j++][i] = row.TicketerId == null ? null : await Accounts.GetAliasAsync(row.TicketerId); + result[j++][i] = await Accounts.GetAliasAsync(row.TicketerId); break; case "amount": foreach (var row in rows) @@ -657,11 +657,11 @@ INNER JOIN ""Blocks"" as b break; case "target": foreach (var row in rows) - result[j++] = row.TargetId == null ? null : await Accounts.GetAliasAsync(row.TargetId); + result[j++] = await Accounts.GetAliasAsync(row.TargetId); break; case "ticketer": foreach (var row in rows) - result[j++] = row.TicketerId == null ? null : await Accounts.GetAliasAsync(row.TicketerId); + result[j++] = await Accounts.GetAliasAsync(row.TicketerId); break; case "amount": foreach (var row in rows) diff --git a/Tzkt.Api/Repositories/ReportRepository.cs b/Tzkt.Api/Repositories/ReportRepository.cs index 4d51c4305..0141ed5af 100644 --- a/Tzkt.Api/Repositories/ReportRepository.cs +++ b/Tzkt.Api/Repositories/ReportRepository.cs @@ -70,19 +70,19 @@ public async Task Write(StreamWriter csv, string address, DateTime from, DateTim if (user.StakingUpdatesCount > 0) UnionStakingUpdates(sql); } - if (account is RawDelegate delegat) - { - if (delegat.AttestationRewardsCount > 0) UnionAttestationRewards(sql); - if (delegat.DalAttestationRewardsCount > 0) UnionDalAttestationRewards(sql); - if (delegat.BlocksCount > 0) UnionBaking(sql); - if (delegat.AttestationsCount > 0) UnionAttestations(sql); - if (delegat.DoubleBakingCount > 0) UnionDoubleBaking(sql); - if (delegat.DoubleConsensusCount > 0) UnionDoubleConsensus(sql); - if (delegat.NonceRevelationsCount > 0) UnionNonceRevelations(sql); - if (delegat.VdfRevelationsCount > 0) UnionVdfRevelations(sql); - if (delegat.RevelationPenaltiesCount > 0) UnionRevelationPenalties(sql); - if (delegat.UpdateSecondaryKeyCount > 0) UnionUpdateSecondaryKeyOps(sql); - } + //if (account is RawDelegate delegat) + //{ + // if (delegat.AttestationRewardsCount > 0) UnionAttestationRewards(sql); + // if (delegat.DalAttestationRewardsCount > 0) UnionDalAttestationRewards(sql); + // if (delegat.BlocksCount > 0) UnionBaking(sql); + // if (delegat.AttestationsCount > 0) UnionAttestations(sql); + // if (delegat.DoubleBakingCount > 0) UnionDoubleBaking(sql); + // if (delegat.DoubleConsensusCount > 0) UnionDoubleConsensus(sql); + // if (delegat.NonceRevelationsCount > 0) UnionNonceRevelations(sql); + // if (delegat.VdfRevelationsCount > 0) UnionVdfRevelations(sql); + // if (delegat.RevelationPenaltiesCount > 0) UnionRevelationPenalties(sql); + // if (delegat.UpdateSecondaryKeyCount > 0) UnionUpdateSecondaryKeyOps(sql); + //} if (sql.Length == 0) return; @@ -206,19 +206,19 @@ public async Task Write(StreamWriter csv, string address, DateTime from, DateTim if (user.StakingUpdatesCount > 0) UnionStakingUpdates(sql); } - if (account is RawDelegate delegat) - { - if (delegat.AttestationRewardsCount > 0) UnionAttestationRewards(sql); - if (delegat.DalAttestationRewardsCount > 0) UnionDalAttestationRewards(sql); - if (delegat.BlocksCount > 0) UnionBaking(sql); - if (delegat.AttestationsCount > 0) UnionAttestations(sql); - if (delegat.DoubleBakingCount > 0) UnionDoubleBaking(sql); - if (delegat.DoubleConsensusCount > 0) UnionDoubleConsensus(sql); - if (delegat.NonceRevelationsCount > 0) UnionNonceRevelations(sql); - if (delegat.VdfRevelationsCount > 0) UnionVdfRevelations(sql); - if (delegat.RevelationPenaltiesCount > 0) UnionRevelationPenalties(sql); - if (delegat.UpdateSecondaryKeyCount > 0) UnionUpdateSecondaryKeyOps(sql); - } + //if (account is RawDelegate delegat) + //{ + // if (delegat.AttestationRewardsCount > 0) UnionAttestationRewards(sql); + // if (delegat.DalAttestationRewardsCount > 0) UnionDalAttestationRewards(sql); + // if (delegat.BlocksCount > 0) UnionBaking(sql); + // if (delegat.AttestationsCount > 0) UnionAttestations(sql); + // if (delegat.DoubleBakingCount > 0) UnionDoubleBaking(sql); + // if (delegat.DoubleConsensusCount > 0) UnionDoubleConsensus(sql); + // if (delegat.NonceRevelationsCount > 0) UnionNonceRevelations(sql); + // if (delegat.VdfRevelationsCount > 0) UnionVdfRevelations(sql); + // if (delegat.RevelationPenaltiesCount > 0) UnionRevelationPenalties(sql); + // if (delegat.UpdateSecondaryKeyCount > 0) UnionUpdateSecondaryKeyOps(sql); + //} if (sql.Length == 0) return; @@ -376,19 +376,19 @@ public async Task WriteHistorical(StreamWriter csv, string address, DateTime fro if (user.StakingUpdatesCount > 0) UnionStakingUpdates(sql); } - if (account is RawDelegate delegat) - { - if (delegat.AttestationRewardsCount > 0) UnionAttestationRewards(sql); - if (delegat.DalAttestationRewardsCount > 0) UnionDalAttestationRewards(sql); - if (delegat.BlocksCount > 0) UnionBaking(sql); - if (delegat.AttestationsCount > 0) UnionAttestations(sql); - if (delegat.DoubleBakingCount > 0) UnionDoubleBaking(sql); - if (delegat.DoubleConsensusCount > 0) UnionDoubleConsensus(sql); - if (delegat.NonceRevelationsCount > 0) UnionNonceRevelations(sql); - if (delegat.VdfRevelationsCount > 0) UnionVdfRevelations(sql); - if (delegat.RevelationPenaltiesCount > 0) UnionRevelationPenalties(sql); - if (delegat.UpdateSecondaryKeyCount > 0) UnionUpdateSecondaryKeyOps(sql); - } + //if (account is RawDelegate delegat) + //{ + // if (delegat.AttestationRewardsCount > 0) UnionAttestationRewards(sql); + // if (delegat.DalAttestationRewardsCount > 0) UnionDalAttestationRewards(sql); + // if (delegat.BlocksCount > 0) UnionBaking(sql); + // if (delegat.AttestationsCount > 0) UnionAttestations(sql); + // if (delegat.DoubleBakingCount > 0) UnionDoubleBaking(sql); + // if (delegat.DoubleConsensusCount > 0) UnionDoubleConsensus(sql); + // if (delegat.NonceRevelationsCount > 0) UnionNonceRevelations(sql); + // if (delegat.VdfRevelationsCount > 0) UnionVdfRevelations(sql); + // if (delegat.RevelationPenaltiesCount > 0) UnionRevelationPenalties(sql); + // if (delegat.UpdateSecondaryKeyCount > 0) UnionUpdateSecondaryKeyOps(sql); + //} if (sql.Length == 0) return; diff --git a/Tzkt.Api/Services/Home/HomeService.cs b/Tzkt.Api/Services/Home/HomeService.cs index 49064e321..058f94dae 100644 --- a/Tzkt.Api/Services/Home/HomeService.cs +++ b/Tzkt.Api/Services/Home/HomeService.cs @@ -1,6 +1,5 @@ using System.Data; using Dapper; -using Dynamic.Json; using Npgsql; using Tzkt.Api.Models; using Tzkt.Api.Repositories; @@ -330,23 +329,16 @@ async Task GetDailyData(IDbConnection db) CycleData GetCycleData() { - var state = State.Current; - var cycle = state.Cycle; - var level = state.Level; - var cycleSize = Protocols.FindByCycle(cycle).BlocksPerCycle; - var firstLevel = Protocols.FindByCycle(cycle).GetCycleStart(cycle); - var lastLevel = Protocols.FindByCycle(cycle).GetCycleEnd(cycle); - return new CycleData { - Cycle = cycle, - Level = level, - Timestamp = state.Timestamp, - FirstLevel = firstLevel, - StartTime = Times[firstLevel], - LastLevel = lastLevel, - EndTime = Times[lastLevel], - Progress = Math.Round(100.0 * (level - firstLevel + 1) / cycleSize, 2) + Cycle = State.Current.Cycle, + Level = State.Current.Level, + Timestamp = State.Current.Timestamp, + FirstLevel = 0, + StartTime = DateTimeOffset.MinValue.UtcDateTime, + LastLevel = 0, + EndTime = DateTimeOffset.MinValue.UtcDateTime, + Progress = 0 }; } @@ -516,78 +508,30 @@ SELECT SUM(""BakerFee"")::bigint AS fee, 0::bigint AS burn FROM ""UpdateSecondar async Task GetStakingData(IDbConnection db, long totalSupply) { - var protocol = Protocols.Current; - - var total = await db.QueryFirstAsync($""" - SELECT COUNT(*)::integer as "ActiveBakers", - COALESCE(SUM("OwnStakedBalance"), 0)::bigint AS "OwnStaked", - COALESCE(SUM("ExternalStakedBalance"), 0)::bigint AS "ExternalStaked", - COALESCE(SUM("OwnDelegatedBalance"), 0)::bigint AS "OwnDelegated", - COALESCE(SUM("ExternalDelegatedBalance"), 0)::bigint AS "ExternalDelegated", - COALESCE(SUM("BakingPower"), 0)::bigint AS "BakingPower", - COALESCE(SUM("VotingPower"), 0)::bigint AS "VotingPower" - FROM "Accounts" - WHERE "Type" = 1 - AND "Staked" = true - """); - - var funded = await db.ExecuteScalarAsync(""" - SELECT COUNT(*) - FROM "Accounts" - WHERE "Type" = 1 - AND "Staked" = true - AND "BakingPower" != 0 - """); - - var futureCycle = await db.QueryFirstAsync(""" - SELECT * - FROM "Cycles" - ORDER BY "Index" DESC - LIMIT 1 - """); - - var lbSubsidyPerBlock = 5_000_000 * protocol.TimeBetweenBlocks / 60; - - var maxRewardsPerBlock = futureCycle.BlockReward - + futureCycle.BlockBonusPerBlock - + futureCycle.AttestationRewardPerBlock - + futureCycle.DalAttestationRewardPerShard * protocol.NumberOfShards - + futureCycle.NonceRevelationReward / protocol.BlocksPerCommitment - + futureCycle.VdfRevelationReward / protocol.BlocksPerCycle; - - var blocksPerYear = 365 * 24 * 60 * 60 / protocol.TimeBetweenBlocks; - var totalRewardsPerYear = maxRewardsPerBlock * blocksPerYear; - var totalCreatedPerYear = (maxRewardsPerBlock + lbSubsidyPerBlock) * blocksPerYear; - - var totalStaked = (long)total.OwnStaked + (long)total.ExternalStaked; - var totalDelegated = (long)total.OwnDelegated + (long)total.ExternalDelegated; - var totalBakingPower = totalStaked + totalDelegated / protocol.StakePowerMultiplier; - var totalStaking = totalStaked + totalDelegated; - return new StakingData { - TotalStaking = totalStaking, - StakingPercentage = Math.Round(100.0 * totalStaking / totalSupply, 2), - AvgRoi = Math.Round(100.0 * totalRewardsPerYear / totalStaking, 2), - Inflation = Math.Round(100.0 * totalCreatedPerYear / totalSupply, 2), - Bakers = total.ActiveBakers, - FundedBakers = funded, - OwnStaked = total.OwnStaked, - OwnStakedPercentage = Math.Round(100.0 * total.OwnStaked / totalSupply, 2), - ExternalStaked = total.ExternalStaked, - ExternalStakedPercentage = Math.Round(100.0 * total.ExternalStaked / totalSupply, 2), - TotalStaked = totalStaked, - TotalStakedPercentage = Math.Round(100.0 * totalStaked / totalSupply, 2), - OwnDelegated = total.OwnDelegated, - OwnDelegatedPercentage = Math.Round(100.0 * total.OwnDelegated / totalSupply, 2), - ExternalDelegated = total.ExternalDelegated, - ExternalDelegatedPercentage = Math.Round(100.0 * total.ExternalDelegated / totalSupply, 2), - TotalDelegated = totalDelegated, - TotalDelegatedPercentage = Math.Round(100.0 * totalDelegated / totalSupply, 2), - StakingApy = Math.Round(100.0 * totalRewardsPerYear / totalBakingPower, 2), - DelegationApy = Math.Round(100.0 * totalRewardsPerYear / totalBakingPower, 2) / protocol.StakePowerMultiplier, - TotalBakingPower = total.BakingPower, - TotalVotingPower = total.VotingPower + TotalStaking = 0, + StakingPercentage = 0, + AvgRoi = 0, + Inflation = 0, + Bakers = 0, + FundedBakers = 0, + OwnStaked = 0, + OwnStakedPercentage = 0, + ExternalStaked = 0, + ExternalStakedPercentage = 0, + TotalStaked = 0, + TotalStakedPercentage = 0, + OwnDelegated = 0, + OwnDelegatedPercentage = 0, + ExternalDelegated = 0, + ExternalDelegatedPercentage = 0, + TotalDelegated = 0, + TotalDelegatedPercentage = 0, + StakingApy = 0, + DelegationApy = 0, + TotalBakingPower = 0, + TotalVotingPower = 0 }; } @@ -629,62 +573,17 @@ SELECT COUNT(*)::integer async Task GetGovernanceData() { - var epoch = (await VotingRepo.GetEpoch(State.Current.VotingEpoch))!; - var period = epoch.Periods.Last(); - var proposals = epoch.Proposals.OrderByDescending(x => x.VotingPower).ToList(); - var proposal = proposals.FirstOrDefault(); - var proposalExtras = proposal?.Extras == null ? null : DJson.Parse(proposal.Extras); - - if (period.Kind == PeriodKinds.Proposal) + return new GovernanceData { - return new GovernanceData - { - Epoch = period.Epoch, - Period = period.Kind, - Protocol = proposals.Any() ? null : State.Current.Protocol, - Proposals = proposals.Select(x => new ProposalData - { - Hash = x.Hash, - Extras = x.Extras, - VotingPower = x.VotingPower, - VotingPowerPercentage = Math.Round(100.0 * x.VotingPower / period.TotalVotingPower, 2) - }).ToList(), - UpvotesQuorum = period.UpvotesQuorum, - PeriodEndTime = period.EndTime, - EpochStartTime = Times[epoch.FirstLevel], - EpochEndTime = Times[epoch.FirstLevel + (Protocols.Current.BlocksPerVoting * 5)], - }; - } - - var result = new GovernanceData - { - Epoch = period.Epoch, - Proposal = proposal!.Hash, - Protocol = proposalExtras?.alias, - Period = period.Kind, - PeriodEndTime = period.EndTime, - EpochStartTime = Times[epoch.FirstLevel], - EpochEndTime = Times[epoch.FirstLevel + (Protocols.Current.BlocksPerVoting * 5)], + Epoch = 0, + Period = "proposal", + Protocol = State.Current.Protocol, + Proposals = [], + UpvotesQuorum = 0, + PeriodEndTime = DateTimeOffset.MaxValue.UtcDateTime, + EpochStartTime = DateTimeOffset.MinValue.UtcDateTime, + EpochEndTime = DateTimeOffset.MaxValue.UtcDateTime, }; - - if (period.Kind is PeriodKinds.Exploration or PeriodKinds.Promotion) - { - var yayNaySum = (long)period.YayVotingPower! + (long)period.NayVotingPower!; - var totalVoted = yayNaySum + (long)period.PassVotingPower!; - - result.YayVotes = yayNaySum > 0 - ? Math.Round(100.0 * (long)period.YayVotingPower / yayNaySum, 2) - : 0; - - result.Participation = period.TotalVotingPower > 0 - ? Math.Round(100.0 * totalVoted / period.TotalVotingPower, 2) - : 0; - - result.BallotsQuorum = Math.Round((double)period.BallotsQuorum!, 2); - result.Supermajority = Math.Round((double)period.Supermajority!, 2); - } - - return result; } #endregion diff --git a/Tzkt.Api/Websocket/Processors/OperationsProcessor.cs b/Tzkt.Api/Websocket/Processors/OperationsProcessor.cs index 09f8c7993..5fdef095d 100644 --- a/Tzkt.Api/Websocket/Processors/OperationsProcessor.cs +++ b/Tzkt.Api/Websocket/Processors/OperationsProcessor.cs @@ -615,7 +615,7 @@ void AddByCodeHash(Dictionary> subs, Models.TransactionOper AddByCodeHash(senderSubs.CodeHashSubs, op); } - if (op.Target != null && transactionsSub.AddressSubs.TryGetValue(op.Target.Address, out var targetSubs)) + if (transactionsSub.AddressSubs.TryGetValue(op.Target.Address, out var targetSubs)) { if (targetSubs.Subs != null) Add(targetSubs.Subs, op); @@ -670,10 +670,10 @@ void AddByCodeHash(Dictionary> subs, Models.TransactionOper if (transferTicketSub.AddressSubs.TryGetValue(op.Sender.Address, out var senderSubs) && senderSubs.Subs != null) Add(senderSubs.Subs, op); - if (op.Target != null && transferTicketSub.AddressSubs.TryGetValue(op.Target.Address, out var targetSubs) && targetSubs.Subs != null) + if (transferTicketSub.AddressSubs.TryGetValue(op.Target.Address, out var targetSubs) && targetSubs.Subs != null) Add(targetSubs.Subs, op); - if (op.Ticketer != null && transferTicketSub.AddressSubs.TryGetValue(op.Ticketer.Address, out var ticketerSubs) && ticketerSubs.Subs != null) + if (transferTicketSub.AddressSubs.TryGetValue(op.Ticketer.Address, out var ticketerSubs) && ticketerSubs.Subs != null) Add(ticketerSubs.Subs, op); } } @@ -820,7 +820,7 @@ void AddByCodeHash(Dictionary> subs, Models.TransactionOper if (increasePaidStorageSubs.AddressSubs.TryGetValue(op.Sender.Address, out var senderSubs) && senderSubs.Subs != null) Add(senderSubs.Subs, op); - if (op.Contract != null && increasePaidStorageSubs.AddressSubs.TryGetValue(op.Contract.Address, out var contractSubs) && contractSubs.Subs != null) + if (increasePaidStorageSubs.AddressSubs.TryGetValue(op.Contract.Address, out var contractSubs) && contractSubs.Subs != null) Add(contractSubs.Subs, op); } } diff --git a/Tzkt.Data/Migrations/20251216213614_Initial.Designer.cs b/Tzkt.Data/Migrations/20260402141327_Initial.Designer.cs similarity index 99% rename from Tzkt.Data/Migrations/20251216213614_Initial.Designer.cs rename to Tzkt.Data/Migrations/20260402141327_Initial.Designer.cs index 893380a1a..08745e363 100644 --- a/Tzkt.Data/Migrations/20251216213614_Initial.Designer.cs +++ b/Tzkt.Data/Migrations/20260402141327_Initial.Designer.cs @@ -14,7 +14,7 @@ namespace Tzkt.Data.Migrations { [DbContext(typeof(TzktContext))] - [Migration("20251216213614_Initial")] + [Migration("20260402141327_Initial")] partial class Initial { /// @@ -2137,7 +2137,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("BakerFee") .HasColumnType("bigint"); - b.Property("ContractId") + b.Property("ContractId") .HasColumnType("integer"); b.Property("Counter") @@ -4744,7 +4744,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("TargetCodeHash") .HasColumnType("integer"); - b.Property("TargetId") + b.Property("TargetId") .HasColumnType("integer"); b.Property("TicketTransfers") @@ -4854,13 +4854,13 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("SubIds") .HasColumnType("integer"); - b.Property("TargetId") + b.Property("TargetId") .HasColumnType("integer"); b.Property("TicketTransfers") .HasColumnType("integer"); - b.Property("TicketerId") + b.Property("TicketerId") .HasColumnType("integer"); b.Property("Timestamp") diff --git a/Tzkt.Data/Migrations/20251216213614_Initial.cs b/Tzkt.Data/Migrations/20260402141327_Initial.cs similarity index 99% rename from Tzkt.Data/Migrations/20251216213614_Initial.cs rename to Tzkt.Data/Migrations/20260402141327_Initial.cs index ba3c6e0a7..4b60324b6 100644 --- a/Tzkt.Data/Migrations/20251216213614_Initial.cs +++ b/Tzkt.Data/Migrations/20260402141327_Initial.cs @@ -864,7 +864,7 @@ protected override void Up(MigrationBuilder migrationBuilder) { Id = table.Column(type: "bigint", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ContractId = table.Column(type: "integer", nullable: true), + ContractId = table.Column(type: "integer", nullable: false), Amount = table.Column(type: "numeric", nullable: false), Level = table.Column(type: "integer", nullable: false), Timestamp = table.Column(type: "timestamp with time zone", nullable: false), @@ -1840,7 +1840,7 @@ protected override void Up(MigrationBuilder migrationBuilder) Id = table.Column(type: "bigint", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), SenderCodeHash = table.Column(type: "integer", nullable: true), - TargetId = table.Column(type: "integer", nullable: true), + TargetId = table.Column(type: "integer", nullable: false), TargetCodeHash = table.Column(type: "integer", nullable: true), ResetDeactivation = table.Column(type: "integer", nullable: true), Amount = table.Column(type: "bigint", nullable: false), @@ -1886,8 +1886,8 @@ protected override void Up(MigrationBuilder migrationBuilder) { Id = table.Column(type: "bigint", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - TargetId = table.Column(type: "integer", nullable: true), - TicketerId = table.Column(type: "integer", nullable: true), + TargetId = table.Column(type: "integer", nullable: false), + TicketerId = table.Column(type: "integer", nullable: false), Amount = table.Column(type: "numeric", nullable: false), RawType = table.Column(type: "bytea", nullable: true), RawContent = table.Column(type: "bytea", nullable: true), diff --git a/Tzkt.Data/Migrations/20251216213633_Triggers.Designer.cs b/Tzkt.Data/Migrations/20260402141343_Triggers.Designer.cs similarity index 99% rename from Tzkt.Data/Migrations/20251216213633_Triggers.Designer.cs rename to Tzkt.Data/Migrations/20260402141343_Triggers.Designer.cs index 247206090..7a732cce0 100644 --- a/Tzkt.Data/Migrations/20251216213633_Triggers.Designer.cs +++ b/Tzkt.Data/Migrations/20260402141343_Triggers.Designer.cs @@ -14,7 +14,7 @@ namespace Tzkt.Data.Migrations { [DbContext(typeof(TzktContext))] - [Migration("20251216213633_Triggers")] + [Migration("20260402141343_Triggers")] partial class Triggers { /// @@ -2137,7 +2137,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("BakerFee") .HasColumnType("bigint"); - b.Property("ContractId") + b.Property("ContractId") .HasColumnType("integer"); b.Property("Counter") @@ -4744,7 +4744,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("TargetCodeHash") .HasColumnType("integer"); - b.Property("TargetId") + b.Property("TargetId") .HasColumnType("integer"); b.Property("TicketTransfers") @@ -4854,13 +4854,13 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("SubIds") .HasColumnType("integer"); - b.Property("TargetId") + b.Property("TargetId") .HasColumnType("integer"); b.Property("TicketTransfers") .HasColumnType("integer"); - b.Property("TicketerId") + b.Property("TicketerId") .HasColumnType("integer"); b.Property("Timestamp") diff --git a/Tzkt.Data/Migrations/20251216213633_Triggers.cs b/Tzkt.Data/Migrations/20260402141343_Triggers.cs similarity index 100% rename from Tzkt.Data/Migrations/20251216213633_Triggers.cs rename to Tzkt.Data/Migrations/20260402141343_Triggers.cs diff --git a/Tzkt.Data/Migrations/TzktContextModelSnapshot.cs b/Tzkt.Data/Migrations/TzktContextModelSnapshot.cs index c23bcade9..83a8404b7 100644 --- a/Tzkt.Data/Migrations/TzktContextModelSnapshot.cs +++ b/Tzkt.Data/Migrations/TzktContextModelSnapshot.cs @@ -210,7 +210,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Staked", "Type") .HasFilter("\"Staked\" = true"); - b.ToTable("Accounts", (string)null); + b.ToTable("Accounts"); b.HasDiscriminator("Type").HasValue((byte)3); @@ -252,7 +252,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("OpHash"); - b.ToTable("ActivationOps", (string)null); + b.ToTable("ActivationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.AppState", b => @@ -568,7 +568,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("AppState", (string)null); + b.ToTable("AppState"); b.HasData( new @@ -716,7 +716,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("OpHash"); - b.ToTable("AttestationOps", (string)null); + b.ToTable("AttestationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.AttestationRewardOperation", b => @@ -757,7 +757,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level"); - b.ToTable("AttestationRewardOps", (string)null); + b.ToTable("AttestationRewardOps"); }); modelBuilder.Entity("Tzkt.Data.Models.AutostakingOperation", b => @@ -792,7 +792,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level"); - b.ToTable("AutostakingOps", (string)null); + b.ToTable("AutostakingOps"); }); modelBuilder.Entity("Tzkt.Data.Models.BakerCycle", b => @@ -986,7 +986,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Cycle", "BakerId"); - b.ToTable("BakerCycles", (string)null); + b.ToTable("BakerCycles"); }); modelBuilder.Entity("Tzkt.Data.Models.BakingRight", b => @@ -1024,7 +1024,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Cycle", "BakerId"); - b.ToTable("BakingRights", (string)null); + b.ToTable("BakingRights"); }); modelBuilder.Entity("Tzkt.Data.Models.BallotOperation", b => @@ -1079,7 +1079,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("BallotOps", (string)null); + b.ToTable("BallotOps"); }); modelBuilder.Entity("Tzkt.Data.Models.BigMap", b => @@ -1136,7 +1136,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Ptr") .IsUnique(); - b.ToTable("BigMaps", (string)null); + b.ToTable("BigMaps"); }); modelBuilder.Entity("Tzkt.Data.Models.BigMapKey", b => @@ -1203,7 +1203,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "BigMapPtr" }, "IX_BigMapKeys_BigMapPtr_Partial") .HasFilter("\"Active\" = true"); - b.ToTable("BigMapKeys", (string)null); + b.ToTable("BigMapKeys"); }); modelBuilder.Entity("Tzkt.Data.Models.BigMapUpdate", b => @@ -1259,7 +1259,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("BigMapPtr", "Id"); - b.ToTable("BigMapUpdates", (string)null); + b.ToTable("BigMapUpdates"); }); modelBuilder.Entity("Tzkt.Data.Models.Block", b => @@ -1375,7 +1375,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ProposerId"); - b.ToTable("Blocks", (string)null); + b.ToTable("Blocks"); }); modelBuilder.Entity("Tzkt.Data.Models.Commitment", b => @@ -1408,7 +1408,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Address") .IsUnique(); - b.ToTable("Commitments", (string)null); + b.ToTable("Commitments"); }); modelBuilder.Entity("Tzkt.Data.Models.ContractEvent", b => @@ -1460,7 +1460,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ContractId", "Tag"); - b.ToTable("Events", (string)null); + b.ToTable("Events"); }); modelBuilder.Entity("Tzkt.Data.Models.Cycle", b => @@ -1518,7 +1518,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Index") .IsUnique(); - b.ToTable("Cycles", (string)null); + b.ToTable("Cycles"); }); modelBuilder.Entity("Tzkt.Data.Models.DalAttestationRewardOperation", b => @@ -1559,7 +1559,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level"); - b.ToTable("DalAttestationRewardOps", (string)null); + b.ToTable("DalAttestationRewardOps"); }); modelBuilder.Entity("Tzkt.Data.Models.DalEntrapmentEvidenceOperation", b => @@ -1604,7 +1604,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("OpHash"); - b.ToTable("DalEntrapmentEvidenceOps", (string)null); + b.ToTable("DalEntrapmentEvidenceOps"); }); modelBuilder.Entity("Tzkt.Data.Models.DalPublishCommitmentOperation", b => @@ -1675,7 +1675,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("DalPublishCommitmentOps", (string)null); + b.ToTable("DalPublishCommitmentOps"); }); modelBuilder.Entity("Tzkt.Data.Models.DelegationOperation", b => @@ -1775,7 +1775,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId", "Id"); - b.ToTable("DelegationOps", (string)null); + b.ToTable("DelegationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.DelegationSnapshot", b => @@ -1809,7 +1809,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "Level" }, "IX_DelegationSnapshots_Level_Partial") .HasFilter("\"BakerId\" = \"AccountId\""); - b.ToTable("DelegationSnapshots", (string)null); + b.ToTable("DelegationSnapshots"); }); modelBuilder.Entity("Tzkt.Data.Models.DelegatorCycle", b => @@ -1843,7 +1843,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Cycle", "DelegatorId"); - b.ToTable("DelegatorCycles", (string)null); + b.ToTable("DelegatorCycles"); }); modelBuilder.Entity("Tzkt.Data.Models.Domain", b => @@ -1897,7 +1897,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Owner"); - b.ToTable("Domains", (string)null); + b.ToTable("Domains"); }); modelBuilder.Entity("Tzkt.Data.Models.DoubleBakingOperation", b => @@ -1960,7 +1960,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("OpHash"); - b.ToTable("DoubleBakingOps", (string)null); + b.ToTable("DoubleBakingOps"); }); modelBuilder.Entity("Tzkt.Data.Models.DoubleConsensusOperation", b => @@ -2026,7 +2026,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("OpHash"); - b.ToTable("DoubleConsensusOps", (string)null); + b.ToTable("DoubleConsensusOps"); }); modelBuilder.Entity("Tzkt.Data.Models.DrainDelegateOperation", b => @@ -2074,7 +2074,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("TargetId"); - b.ToTable("DrainDelegateOps", (string)null); + b.ToTable("DrainDelegateOps"); }); modelBuilder.Entity("Tzkt.Data.Models.InboxMessage", b => @@ -2114,7 +2114,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Type", "Id"); - b.ToTable("InboxMessages", (string)null); + b.ToTable("InboxMessages"); }); modelBuilder.Entity("Tzkt.Data.Models.IncreasePaidStorageOperation", b => @@ -2134,7 +2134,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("BakerFee") .HasColumnType("bigint"); - b.Property("ContractId") + b.Property("ContractId") .HasColumnType("integer"); b.Property("Counter") @@ -2186,7 +2186,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("IncreasePaidStorageOps", (string)null); + b.ToTable("IncreasePaidStorageOps"); }); modelBuilder.Entity("Tzkt.Data.Models.MigrationOperation", b => @@ -2233,7 +2233,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level"); - b.ToTable("MigrationOps", (string)null); + b.ToTable("MigrationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.NonceRevelationOperation", b => @@ -2298,7 +2298,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("NonceRevelationOps", (string)null); + b.ToTable("NonceRevelationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.OriginationOperation", b => @@ -2410,7 +2410,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("OriginationOps", (string)null); + b.ToTable("OriginationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.PreattestationOperation", b => @@ -2447,7 +2447,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("OpHash"); - b.ToTable("PreattestationOps", (string)null); + b.ToTable("PreattestationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.Proposal", b => @@ -2501,7 +2501,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "Status" }, "IX_Proposals_Status_Partial") .HasFilter("\"Status\" = 0"); - b.ToTable("Proposals", (string)null); + b.ToTable("Proposals"); }); modelBuilder.Entity("Tzkt.Data.Models.ProposalOperation", b => @@ -2556,7 +2556,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("ProposalOps", (string)null); + b.ToTable("ProposalOps"); }); modelBuilder.Entity("Tzkt.Data.Models.Protocol", b => @@ -2743,7 +2743,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Hash") .IsUnique(); - b.ToTable("Protocols", (string)null); + b.ToTable("Protocols"); }); modelBuilder.Entity("Tzkt.Data.Models.Quote", b => @@ -2789,7 +2789,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level") .IsUnique(); - b.ToTable("Quotes", (string)null); + b.ToTable("Quotes"); }); modelBuilder.Entity("Tzkt.Data.Models.RefutationGame", b => @@ -2852,7 +2852,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SmartRollupId", "Id"); - b.ToTable("RefutationGames", (string)null); + b.ToTable("RefutationGames"); }); modelBuilder.Entity("Tzkt.Data.Models.RegisterConstantOperation", b => @@ -2932,7 +2932,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("RegisterConstantOps", (string)null); + b.ToTable("RegisterConstantOps"); }); modelBuilder.Entity("Tzkt.Data.Models.RevealOperation", b => @@ -2996,7 +2996,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("RevealOps", (string)null); + b.ToTable("RevealOps"); }); modelBuilder.Entity("Tzkt.Data.Models.RevelationPenaltyOperation", b => @@ -3028,7 +3028,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level"); - b.ToTable("RevelationPenaltyOps", (string)null); + b.ToTable("RevelationPenaltyOps"); }); modelBuilder.Entity("Tzkt.Data.Models.Script", b => @@ -3080,7 +3080,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "ContractId" }, "IX_Scripts_ContractId_Partial") .HasFilter("\"Current\" = true"); - b.ToTable("Scripts", (string)null); + b.ToTable("Scripts"); }); modelBuilder.Entity("Tzkt.Data.Models.SetDelegateParametersOperation", b => @@ -3155,7 +3155,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId", "Id"); - b.ToTable("SetDelegateParametersOps", (string)null); + b.ToTable("SetDelegateParametersOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SetDepositsLimitOperation", b => @@ -3222,7 +3222,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId", "Id"); - b.ToTable("SetDepositsLimitOps", (string)null); + b.ToTable("SetDepositsLimitOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SmartRollupAddMessagesOperation", b => @@ -3289,7 +3289,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("SmartRollupAddMessagesOps", (string)null); + b.ToTable("SmartRollupAddMessagesOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SmartRollupCementOperation", b => @@ -3363,7 +3363,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SmartRollupId", "Id"); - b.ToTable("SmartRollupCementOps", (string)null); + b.ToTable("SmartRollupCementOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SmartRollupCommitment", b => @@ -3427,7 +3427,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Hash", "SmartRollupId"); - b.ToTable("SmartRollupCommitments", (string)null); + b.ToTable("SmartRollupCommitments"); }); modelBuilder.Entity("Tzkt.Data.Models.SmartRollupExecuteOperation", b => @@ -3507,7 +3507,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("CommitmentId", "Id"); - b.ToTable("SmartRollupExecuteOps", (string)null); + b.ToTable("SmartRollupExecuteOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SmartRollupOriginateOperation", b => @@ -3589,7 +3589,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SmartRollupId"); - b.ToTable("SmartRollupOriginateOps", (string)null); + b.ToTable("SmartRollupOriginateOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SmartRollupPublishOperation", b => @@ -3675,7 +3675,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SmartRollupId", "SenderId", "Id"); - b.ToTable("SmartRollupPublishOps", (string)null); + b.ToTable("SmartRollupPublishOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SmartRollupRecoverBondOperation", b => @@ -3752,7 +3752,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("StakerId"); - b.ToTable("SmartRollupRecoverBondOps", (string)null); + b.ToTable("SmartRollupRecoverBondOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SmartRollupRefuteOperation", b => @@ -3841,7 +3841,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("GameId", "Id"); - b.ToTable("SmartRollupRefuteOps", (string)null); + b.ToTable("SmartRollupRefuteOps"); }); modelBuilder.Entity("Tzkt.Data.Models.SnapshotBalance", b => @@ -3881,7 +3881,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "Level" }, "IX_SnapshotBalances_Level_Partial") .HasFilter("\"BakerId\" = \"AccountId\""); - b.ToTable("SnapshotBalances", (string)null); + b.ToTable("SnapshotBalances"); }); modelBuilder.Entity("Tzkt.Data.Models.Software", b => @@ -3912,7 +3912,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("Software", (string)null); + b.ToTable("Software"); }); modelBuilder.Entity("Tzkt.Data.Models.StakerCycle", b => @@ -3953,7 +3953,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("StakerId", "Cycle"); - b.ToTable("StakerCycles", (string)null); + b.ToTable("StakerCycles"); }); modelBuilder.Entity("Tzkt.Data.Models.StakingOperation", b => @@ -4039,7 +4039,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("StakerId"); - b.ToTable("StakingOps", (string)null); + b.ToTable("StakingOps"); }); modelBuilder.Entity("Tzkt.Data.Models.StakingUpdate", b => @@ -4112,7 +4112,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("StakerId", "Cycle", "Id"); - b.ToTable("StakingUpdates", (string)null); + b.ToTable("StakingUpdates"); }); modelBuilder.Entity("Tzkt.Data.Models.Statistics", b => @@ -4202,7 +4202,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level") .IsUnique(); - b.ToTable("Statistics", (string)null); + b.ToTable("Statistics"); }); modelBuilder.Entity("Tzkt.Data.Models.Storage", b => @@ -4248,7 +4248,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "ContractId" }, "IX_Storages_ContractId_Partial") .HasFilter("\"Current\" = true"); - b.ToTable("Storages", (string)null); + b.ToTable("Storages"); }); modelBuilder.Entity("Tzkt.Data.Models.Ticket", b => @@ -4325,7 +4325,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("TicketerId", "TypeHash", "ContentHash"); - b.ToTable("Tickets", (string)null); + b.ToTable("Tickets"); }); modelBuilder.Entity("Tzkt.Data.Models.TicketBalance", b => @@ -4372,7 +4372,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("AccountId", "TicketerId"); - b.ToTable("TicketBalances", (string)null); + b.ToTable("TicketBalances"); }); modelBuilder.Entity("Tzkt.Data.Models.TicketTransfer", b => @@ -4431,7 +4431,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level", "Id"); - b.ToTable("TicketTransfers", (string)null); + b.ToTable("TicketTransfers"); }); modelBuilder.Entity("Tzkt.Data.Models.Token", b => @@ -4507,7 +4507,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ContractId", "TokenId") .IsUnique(); - b.ToTable("Tokens", (string)null); + b.ToTable("Tokens"); }); modelBuilder.Entity("Tzkt.Data.Models.TokenBalance", b => @@ -4567,7 +4567,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "TokenId" }, "IX_TokenBalances_TokenId_Partial") .HasFilter("\"Balance\" != '0'"); - b.ToTable("TokenBalances", (string)null); + b.ToTable("TokenBalances"); }); modelBuilder.Entity("Tzkt.Data.Models.TokenTransfer", b => @@ -4634,7 +4634,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Level", "Id"); - b.ToTable("TokenTransfers", (string)null); + b.ToTable("TokenTransfers"); }); modelBuilder.Entity("Tzkt.Data.Models.TransactionOperation", b => @@ -4741,7 +4741,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("TargetCodeHash") .HasColumnType("integer"); - b.Property("TargetId") + b.Property("TargetId") .HasColumnType("integer"); b.Property("TicketTransfers") @@ -4779,7 +4779,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "TargetId" }, "IX_TransactionOps_TargetId_Partial") .HasFilter("\"Entrypoint\" = 'transfer' AND \"TokenTransfers\" IS NULL AND \"Status\" = 1"); - b.ToTable("TransactionOps", (string)null); + b.ToTable("TransactionOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TransferTicketOperation", b => @@ -4851,13 +4851,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("SubIds") .HasColumnType("integer"); - b.Property("TargetId") + b.Property("TargetId") .HasColumnType("integer"); b.Property("TicketTransfers") .HasColumnType("integer"); - b.Property("TicketerId") + b.Property("TicketerId") .HasColumnType("integer"); b.Property("Timestamp") @@ -4875,7 +4875,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("TicketerId"); - b.ToTable("TransferTicketOps", (string)null); + b.ToTable("TransferTicketOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TxRollupCommitOperation", b => @@ -4947,7 +4947,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("TxRollupCommitOps", (string)null); + b.ToTable("TxRollupCommitOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TxRollupDispatchTicketsOperation", b => @@ -5016,7 +5016,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("TxRollupDispatchTicketsOps", (string)null); + b.ToTable("TxRollupDispatchTicketsOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TxRollupFinalizeCommitmentOperation", b => @@ -5085,7 +5085,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("TxRollupFinalizeCommitmentOps", (string)null); + b.ToTable("TxRollupFinalizeCommitmentOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TxRollupOriginationOperation", b => @@ -5154,7 +5154,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("TxRollupOriginationOps", (string)null); + b.ToTable("TxRollupOriginationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TxRollupRejectionOperation", b => @@ -5234,7 +5234,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("TxRollupRejectionOps", (string)null); + b.ToTable("TxRollupRejectionOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TxRollupRemoveCommitmentOperation", b => @@ -5303,7 +5303,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("TxRollupRemoveCommitmentOps", (string)null); + b.ToTable("TxRollupRemoveCommitmentOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TxRollupReturnBondOperation", b => @@ -5375,7 +5375,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("TxRollupReturnBondOps", (string)null); + b.ToTable("TxRollupReturnBondOps"); }); modelBuilder.Entity("Tzkt.Data.Models.TxRollupSubmitBatchOperation", b => @@ -5444,7 +5444,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId"); - b.ToTable("TxRollupSubmitBatchOps", (string)null); + b.ToTable("TxRollupSubmitBatchOps"); }); modelBuilder.Entity("Tzkt.Data.Models.UnstakeRequest", b => @@ -5494,7 +5494,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("StakerId", "Cycle"); - b.ToTable("UnstakeRequests", (string)null); + b.ToTable("UnstakeRequests"); }); modelBuilder.Entity("Tzkt.Data.Models.UpdateSecondaryKeyOperation", b => @@ -5574,7 +5574,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("SenderId", "Id"); - b.ToTable("UpdateSecondaryKeyOps", (string)null); + b.ToTable("UpdateSecondaryKeyOps"); }); modelBuilder.Entity("Tzkt.Data.Models.VdfRevelationOperation", b => @@ -5633,7 +5633,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Cycle", "Id"); - b.ToTable("VdfRevelationOps", (string)null); + b.ToTable("VdfRevelationOps"); }); modelBuilder.Entity("Tzkt.Data.Models.VotingPeriod", b => @@ -5720,7 +5720,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Index") .IsUnique(); - b.ToTable("VotingPeriods", (string)null); + b.ToTable("VotingPeriods"); }); modelBuilder.Entity("Tzkt.Data.Models.VotingSnapshot", b => @@ -5751,7 +5751,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Period", "BakerId") .IsUnique(); - b.ToTable("VotingSnapshots", (string)null); + b.ToTable("VotingSnapshots"); }); modelBuilder.Entity("Tzkt.Data.Models.Contract", b => diff --git a/Tzkt.Data/Models/Operations/IncreasePaidStorageOperation.cs b/Tzkt.Data/Models/Operations/IncreasePaidStorageOperation.cs index aa9ebb9a9..34fcc5f22 100644 --- a/Tzkt.Data/Models/Operations/IncreasePaidStorageOperation.cs +++ b/Tzkt.Data/Models/Operations/IncreasePaidStorageOperation.cs @@ -6,7 +6,7 @@ namespace Tzkt.Data.Models { public class IncreasePaidStorageOperation : ManagerOperation { - public int? ContractId { get; set; } + public int ContractId { get; set; } public BigInteger Amount { get; set; } } diff --git a/Tzkt.Data/Models/Operations/TransactionOperation.cs b/Tzkt.Data/Models/Operations/TransactionOperation.cs index d61ae26e0..02b37cc0b 100644 --- a/Tzkt.Data/Models/Operations/TransactionOperation.cs +++ b/Tzkt.Data/Models/Operations/TransactionOperation.cs @@ -8,7 +8,7 @@ namespace Tzkt.Data.Models public class TransactionOperation : ContractOperation { public int? SenderCodeHash { get; set; } - public int? TargetId { get; set; } + public int TargetId { get; set; } public int? TargetCodeHash { get; set; } public int? ResetDeactivation { get; set; } diff --git a/Tzkt.Data/Models/Operations/TransferTicketOperation.cs b/Tzkt.Data/Models/Operations/TransferTicketOperation.cs index ab0ca37d3..66795cee2 100644 --- a/Tzkt.Data/Models/Operations/TransferTicketOperation.cs +++ b/Tzkt.Data/Models/Operations/TransferTicketOperation.cs @@ -6,8 +6,8 @@ namespace Tzkt.Data.Models { public class TransferTicketOperation : ManagerOperation { - public int? TargetId { get; set; } - public int? TicketerId { get; set; } + public int TargetId { get; set; } + public int TicketerId { get; set; } public BigInteger Amount { get; set; } public byte[]? RawType { get; set; } diff --git a/Tzkt.Sync.Tests/Indexer/Indexer.cs b/Tzkt.Sync.Tests/Indexer/Indexer.cs index f93c02a02..7514bead8 100644 --- a/Tzkt.Sync.Tests/Indexer/Indexer.cs +++ b/Tzkt.Sync.Tests/Indexer/Indexer.cs @@ -23,7 +23,7 @@ public static async Task RunAsync(IHost app, CancellationToken ct) logger.LogInformation("Applying {level} of {total}", state.Level + 1, head); using var scope = app.Services.CreateScope(); - var protocol = scope.ServiceProvider.GetProtocolHandler(state.Level + 1, state.NextProtocol); + var protocol = scope.ServiceProvider.GetNextBlockHandler(state); state = await protocol.CommitNextBlock(); } diff --git a/Tzkt.Sync/Extensions/JsonElementExtension.cs b/Tzkt.Sync/Extensions/JsonElementExtension.cs index 56ff722bd..ed98e83b8 100644 --- a/Tzkt.Sync/Extensions/JsonElementExtension.cs +++ b/Tzkt.Sync/Extensions/JsonElementExtension.cs @@ -63,6 +63,15 @@ public static string RequiredString(this JsonElement el, string name) : throw new SerializationException($"Missed required string {name}"); } + public static string? OptionalString(this JsonElement el) + { + if (el.ValueKind == JsonValueKind.Null) + return null; + + return el.ValueKind == JsonValueKind.String ? el.GetString() + : throw new SerializationException($"Expected string but got {el.ValueKind}"); + } + public static string? OptionalString(this JsonElement el, string name) { if (!el.TryGetProperty(name, out var res) || res.ValueKind == JsonValueKind.Null) diff --git a/Tzkt.Sync/Program.cs b/Tzkt.Sync/Program.cs index acd28f359..cfe43ab0b 100644 --- a/Tzkt.Sync/Program.cs +++ b/Tzkt.Sync/Program.cs @@ -29,6 +29,7 @@ options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddCache(builder.Configuration); +builder.Services.AddEvmNode(); builder.Services.AddTezosNode(); builder.Services.AddTezosProtocols(); builder.Services.AddQuotes(builder.Configuration); @@ -111,6 +112,44 @@ } logger.LogInformation("Database initialized"); + + logger.LogInformation("Initialize state..."); + + var state = await db.AppState.AsNoTracking().SingleAsync(); + if (state.ChainId == string.Empty) + { + var evmNode = scope.ServiceProvider.GetRequiredService(); + var tezNode = scope.ServiceProvider.GetRequiredService(); + + var evmChainId = await evmNode.PostAsync("eth_chainId"); + var tezActivationLevel = 0; + try { + tezActivationLevel = evmChainId switch + { + "0x1f440" => 171555, // previewnet + _ => await evmNode.PostAsync("tez_getMichelsonActivationLevel"), + }; + } + catch { } + + try + { + var genesis = await tezNode.GetAsync($"chains/main/blocks/{tezActivationLevel}"); + + db.TryAttach(state); + state.ChainId = genesis.RequiredString("chain_id"); + state.NextProtocol = genesis.RequiredString("protocol"); + state.Level = genesis.Required("header").RequiredInt32("level") - 1; + state.QuoteLevel = genesis.Required("header").RequiredInt32("level") - 1; + await db.SaveChangesAsync(); + } + catch (Exception ex) + { + throw new Exception("Failed to init genesis", ex); + } + } + + logger.LogInformation("State initialized"); break; } catch (Exception ex) diff --git a/Tzkt.Sync/Protocols/Abstract/IActivator.cs b/Tzkt.Sync/Protocols/Abstract/IActivator.cs new file mode 100644 index 000000000..6856d46ac --- /dev/null +++ b/Tzkt.Sync/Protocols/Abstract/IActivator.cs @@ -0,0 +1,12 @@ +using System.Text.Json; +using Tzkt.Data.Models; + +namespace Tzkt.Sync.Protocols +{ + public interface IActivator + { + Task ActivateContext(AppState state, JsonElement block); + + Task DeactivateContext(AppState state); + } +} diff --git a/Tzkt.Sync/Protocols/Abstract/IDiagnostics.cs b/Tzkt.Sync/Protocols/Abstract/IDiagnostics.cs deleted file mode 100644 index 2d6c2bfd4..000000000 --- a/Tzkt.Sync/Protocols/Abstract/IDiagnostics.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols -{ - public interface IDiagnostics - { - void TrackChanges(); - Task Run(JsonElement block); - Task Run(int level); - } -} diff --git a/Tzkt.Sync/Protocols/Abstract/IHelpers.cs b/Tzkt.Sync/Protocols/Abstract/IHelpers.cs deleted file mode 100644 index 35f89de10..000000000 --- a/Tzkt.Sync/Protocols/Abstract/IHelpers.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Tzkt.Sync.Protocols -{ - public interface IHelpers - { - long BakingPower(Data.Models.Delegate baker); - long VotingPower(Data.Models.Delegate baker); - } -} diff --git a/Tzkt.Sync/Protocols/Abstract/IMigrator.cs b/Tzkt.Sync/Protocols/Abstract/IMigrator.cs new file mode 100644 index 000000000..7311576bb --- /dev/null +++ b/Tzkt.Sync/Protocols/Abstract/IMigrator.cs @@ -0,0 +1,11 @@ +using Tzkt.Data.Models; + +namespace Tzkt.Sync.Protocols +{ + public interface IMigrator + { + Task MigrateContext(AppState state); + + Task RevertContext(AppState state); + } +} diff --git a/Tzkt.Sync/Protocols/Abstract/IRpc.cs b/Tzkt.Sync/Protocols/Abstract/IRpc.cs index a284ef9aa..b51861e9d 100644 --- a/Tzkt.Sync/Protocols/Abstract/IRpc.cs +++ b/Tzkt.Sync/Protocols/Abstract/IRpc.cs @@ -6,28 +6,10 @@ public interface IRpc { #region indexer Task GetBlockAsync(int level); - Task GetBakingRightsAsync(int block, int cycle); - Task GetAttestationRightsAsync(int block, int cycle); - Task GetLevelBakingRightsAsync(int block, int level, int maxRound); - Task GetLevelAttestationRightsAsync(int block, int level); Task GetContractAsync(int level, string address); - Task GetDelegateAsync(int level, string address); - Task GetExpectedIssuance(int level); - Task GetSmartRollupGenesisInfo(int level, string address); - Task GetUnstakeRequests(int level, string address); - Task GetContractRawAsync(int level, string address); - #endregion - - #region diagnostics - Task GetGlobalCounterAsync(int level); - Task GetDelegatesAsync(int level); - Task GetActiveDelegatesAsync(int level); - Task GetDelegateParticipationAsync(int level, string address); - Task GetDelegateDalParticipationAsync(int level, string address); - Task GetCycleAsync(int level, int cycle); - Task GetTicketBalance(int level, string address, string ticket); - Task GetCurrentStakingBalance(int level, string address); - Task GetStakingParameters(int level, string address); + Task GetContractManagerKeyAsync(int level, string address); + Task GetConstantsAsync(int level); + Task GetContractsAsync(int level); #endregion } } diff --git a/Tzkt.Sync/Protocols/Handlers/Genesis/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Genesis/Diagnostics/Diagnostics.cs deleted file mode 100644 index 0c968e368..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Genesis/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Genesis -{ - class Diagnostics : IDiagnostics - { - public void TrackChanges() { } - public Task Run(JsonElement block) => Task.CompletedTask; - public Task Run(int level) => Task.CompletedTask; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Genesis/GenesisHandler.cs b/Tzkt.Sync/Protocols/Handlers/Genesis/GenesisHandler.cs deleted file mode 100644 index dc6fb9f00..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Genesis/GenesisHandler.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Genesis; - -namespace Tzkt.Sync.Protocols -{ - class GenesisHandler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "genesis"; - public override int VersionNumber => -1; - - public GenesisHandler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Diagnostics = new Diagnostics(); - Validator = new Validator(this); - Helpers = new Helpers(); - Rpc = new Rpc(node); - } - - public override Task WarmUpCache(JsonElement block) => Task.CompletedTask; - - public override Task Commit(JsonElement rawBlock) - { - #region add protocol - var protocol = new Protocol - { - Id = 0, - Hash = rawBlock.RequiredString("protocol"), - Code = -1, - Version = VersionNumber, - FirstLevel = 0, - LastLevel = 0, - FirstCycle = 0, - FirstCycleLevel = 1 - }; - Db.Protocols.Add(protocol); - Cache.Protocols.Add(protocol); - #endregion - - #region add block - var block = new Block - { - Id = Cache.AppState.NextOperationId(), - Hash = rawBlock.RequiredString("hash"), - Cycle = -1, - Level = rawBlock.Required("header").RequiredInt32("level"), - ProtoCode = protocol.Code, - Timestamp = rawBlock.Required("header").RequiredDateTime("timestamp"), - Events = BlockEvents.ProtocolBegin | BlockEvents.ProtocolEnd - }; - Db.Blocks.Add(block); - Cache.Blocks.Add(block); - #endregion - - #region add empty stats - var stats = new Statistics - { - Id = 0, - Level = block.Level - }; - Db.Statistics.Add(stats); - Cache.Statistics.SetCurrent(stats); - #endregion - - #region update state - var state = Cache.AppState.Get(); - state.ChainId = rawBlock.RequiredString("chain_id"); - state.Chain = Chains.GetName(state.ChainId); - state.Cycle = -1; - state.Level = block.Level; - state.Timestamp = block.Timestamp; - state.Protocol = protocol.Hash; - state.NextProtocol = rawBlock.Required("metadata").RequiredString("next_protocol"); - state.Hash = block.Hash; - state.BlocksCount++; - state.ProtocolsCount++; - #endregion - - return Task.CompletedTask; - } - - public override async Task Revert() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Statistics"; - DELETE FROM "Protocols"; - DELETE FROM "Blocks"; - """); - - await Cache.Statistics.ResetAsync(); - await Cache.Protocols.ResetAsync(); - Cache.Blocks.Reset(); - - #region update state - var state = Cache.AppState.Get(); - state.ChainId = string.Empty; - state.Chain = string.Empty; - state.Cycle = -1; - state.Level = -1; - state.Timestamp = DateTimeOffset.MinValue.UtcDateTime; - state.Protocol = string.Empty; - state.NextProtocol = string.Empty; - state.Hash = string.Empty; - state.BlocksCount--; - state.ProtocolsCount--; - - Cache.AppState.ReleaseOperationId(); - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Genesis/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Genesis/Helpers.cs deleted file mode 100644 index f9f47aeff..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Genesis/Helpers.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Tzkt.Sync.Protocols.Genesis -{ - public class Helpers() : IHelpers - { - public virtual long BakingPower(Data.Models.Delegate baker) - => throw new NotImplementedException(); - - public virtual long VotingPower(Data.Models.Delegate baker) - => throw new NotImplementedException(); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Genesis/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Genesis/Rpc/Rpc.cs deleted file mode 100644 index 1421f5630..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Genesis/Rpc/Rpc.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Genesis -{ - class Rpc(TezosNode node) : IRpc - { - readonly TezosNode Node = node; - - #region indexer - public Task GetBlockAsync(int level) - => Node.GetAsync($"chains/main/blocks/{level}"); - - public Task GetBakingRightsAsync(int block, int cycle) - => throw new InvalidOperationException(); - - public Task GetAttestationRightsAsync(int block, int cycle) - => throw new InvalidOperationException(); - - public Task GetLevelBakingRightsAsync(int block, int level, int maxRound) - => throw new InvalidOperationException(); - - public Task GetLevelAttestationRightsAsync(int block, int level) - => throw new InvalidOperationException(); - - public Task GetContractAsync(int level, string address) - => throw new InvalidOperationException(); - - public Task GetDelegateAsync(int level, string address) - => throw new InvalidOperationException(); - - public Task GetExpectedIssuance(int level) - => throw new InvalidOperationException(); - - public Task GetSmartRollupGenesisInfo(int level, string address) - => throw new InvalidOperationException(); - - public Task GetUnstakeRequests(int level, string address) - => throw new InvalidOperationException(); - - public Task GetContractRawAsync(int level, string address) - => throw new InvalidOperationException(); - #endregion - - #region diagnostics - public Task GetGlobalCounterAsync(int level) - => throw new InvalidOperationException(); - - public Task GetDelegatesAsync(int level) - => throw new InvalidOperationException(); - - public Task GetActiveDelegatesAsync(int level) - => throw new InvalidOperationException(); - - public Task GetCycleAsync(int level, int cycle) - => throw new InvalidOperationException(); - - public Task GetDelegateParticipationAsync(int level, string address) - => throw new InvalidOperationException(); - - public Task GetDelegateDalParticipationAsync(int level, string address) - => throw new InvalidOperationException(); - - public Task GetTicketBalance(int level, string address, string ticket) - => throw new InvalidOperationException(); - - public Task GetCurrentStakingBalance(int level, string address) - => throw new InvalidOperationException(); - - public Task GetStakingParameters(int level, string address) - => throw new InvalidOperationException(); - #endregion - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Genesis/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Genesis/Validation/Validator.cs deleted file mode 100644 index 2582b7195..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Genesis/Validation/Validator.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Genesis -{ - class Validator(ProtocolHandler protocol) : IValidator - { - readonly CacheService Cache = protocol.Cache; - - public Task ValidateBlock(JsonElement block) - { - if (block.Required("header").RequiredInt32("level") != Cache.AppState.GetNextLevel()) - throw new ValidationException("invalid block level", true); - - if (block.Required("header").RequiredInt32("level") != 0) - throw new ValidationException("genesis block is allowed only at level 0", true); - - return Task.CompletedTask; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Initiator/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Initiator/Diagnostics/Diagnostics.cs deleted file mode 100644 index 3f507ed07..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Initiator/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Initiator -{ - class Diagnostics : Genesis.Diagnostics { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Initiator/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Initiator/Helpers.cs deleted file mode 100644 index bcb9318f5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Initiator/Helpers.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Tzkt.Sync.Protocols.Initiator -{ - public class Helpers() : IHelpers - { - public virtual long BakingPower(Data.Models.Delegate baker) - => throw new NotImplementedException(); - - public virtual long VotingPower(Data.Models.Delegate baker) - => throw new NotImplementedException(); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Initiator/InitiatorHandler.cs b/Tzkt.Sync/Protocols/Handlers/Initiator/InitiatorHandler.cs deleted file mode 100644 index 22defee15..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Initiator/InitiatorHandler.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Initiator; - -namespace Tzkt.Sync.Protocols -{ - class InitiatorHandler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "genesis"; - public override int VersionNumber => 0; - - public InitiatorHandler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Diagnostics = new Diagnostics(); - Helpers = new Helpers(); - Validator = new Validator(this); - Rpc = new Rpc(node); - } - - public override Task Activate(AppState state, JsonElement block) => Task.CompletedTask; - public override Task Deactivate(AppState state) => Task.CompletedTask; - - public override Task WarmUpCache(JsonElement block) => Task.CompletedTask; - - public override Task Commit(JsonElement rawBlock) - { - #region add protocol - var protocol = new Protocol - { - Id = 0, - Hash = rawBlock.RequiredString("protocol"), - Code = 0, - Version = VersionNumber, - FirstLevel = 1, - LastLevel = 1, - FirstCycle = 0, - FirstCycleLevel = 1 - }; - Db.Protocols.Add(protocol); - Cache.Protocols.Add(protocol); - #endregion - - #region add block - var block = new Block - { - Id = Cache.AppState.NextOperationId(), - Hash = rawBlock.RequiredString("hash"), - Cycle = 0, - Level = rawBlock.Required("header").RequiredInt32("level"), - ProtoCode = protocol.Code, - Timestamp = rawBlock.Required("header").RequiredDateTime("timestamp"), - Events = BlockEvents.CycleBegin - | BlockEvents.ProtocolBegin - | BlockEvents.ProtocolEnd - | BlockEvents.BalanceSnapshot - }; - Db.Blocks.Add(block); - Cache.Blocks.Add(block); - #endregion - - #region add empty stats - var stats = new Statistics - { - Id = 0, - Level = block.Level - }; - Db.Statistics.Add(stats); - Cache.Statistics.SetCurrent(stats); - #endregion - - #region update state - var state = Cache.AppState.Get(); - state.Cycle = 0; - state.Level = block.Level; - state.Timestamp = block.Timestamp; - state.Protocol = protocol.Hash; - state.NextProtocol = rawBlock.Required("metadata").RequiredString("next_protocol"); - state.Hash = block.Hash; - state.BlocksCount++; - state.ProtocolsCount++; - state.VotingEpoch = 0; - state.VotingPeriod = 0; - #endregion - - return Task.CompletedTask; - } - - public override async Task Revert() - { - var curr = Cache.Blocks.Current(); - var currProtocol = await Cache.Protocols.GetAsync(curr.ProtoCode); - - var prev = await Cache.Blocks.PreviousAsync(); - var prevProtocol = await Cache.Protocols.GetAsync(prev.ProtoCode); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Statistics" WHERE "Level" = {0}; - DELETE FROM "Protocols" WHERE "FirstLevel" = {0}; - DELETE FROM "Blocks" WHERE "Level" = {0}; - """, curr.Level); - - await Cache.Statistics.ResetAsync(); - await Cache.Protocols.ResetAsync(); - Cache.Blocks.Reset(); - - #region update state - var state = Cache.AppState.Get(); - state.Cycle = -1; - state.Level = prev.Level; - state.Timestamp = prev.Timestamp; - state.Protocol = prevProtocol.Hash; - state.NextProtocol = currProtocol.Hash; - state.Hash = prev.Hash; - state.BlocksCount--; - state.ProtocolsCount--; - - Cache.AppState.ReleaseOperationId(); - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Initiator/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Initiator/Rpc/Rpc.cs deleted file mode 100644 index 64ab2b9c6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Initiator/Rpc/Rpc.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Initiator -{ - sealed class Rpc(TezosNode node) : Proto1.Rpc(node) - { - public override Task GetBlockAsync(int level) - => Node.GetAsync($"chains/main/blocks/{level}"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Initiator/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Initiator/Validation/Validator.cs deleted file mode 100644 index 3a8d71e1a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Initiator/Validation/Validator.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Initiator -{ - class Validator(ProtocolHandler protocol) : IValidator - { - readonly CacheService Cache = protocol.Cache; - - public Task ValidateBlock(JsonElement block) - { - if (block.RequiredString("chain_id") != Cache.AppState.GetChainId()) - throw new ValidationException("invalid chain"); - - if (block.Required("header").RequiredInt32("level") != Cache.AppState.GetNextLevel()) - throw new ValidationException("invalid block level", true); - - if (block.Required("header").RequiredString("predecessor") != Cache.AppState.GetHead()) - throw new ValidationException("invalid block predecessor", true); - - if (block.RequiredString("protocol") != Cache.AppState.GetNextProtocol()) - throw new ValidationException("invalid block protocol", true); - - if (block.Required("header").RequiredInt32("level") != 1) - throw new ValidationException("initiator block is allowed only at level 1", true); - - return Task.CompletedTask; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Accounts.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Accounts.cs deleted file mode 100644 index e2e2fc9e5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Accounts.cs +++ /dev/null @@ -1,360 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Netezos.Keys; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - protected virtual async Task> BootstrapAccounts(Protocol protocol, JToken parameters) - { - var bootstrapAccounts = parameters["bootstrap_accounts"]? - .Select(x => (x[0]!.Value()!, x[1]!.Value(), x.Count() > 2 ? x[2]!.Value()! : null)) - .ToList() ?? []; - - var bootstrapContracts = parameters["bootstrap_contracts"]? - .Select(x => - ( - x["amount"]!.Value(), - x["delegate"]?.Value(), - x["script"]!["code"]!.ToString(), - x["script"]!["storage"]!.ToString(), - x["hash"]?.Value() - )) - .ToList() ?? []; - - var bootstrapSmartRollups = parameters["bootstrap_smart_rollups"]? - .Select(x => - ( - x["address"]!.Value()!, - x["pvm_kind"]!.Value()!, - x["parameters_ty"]!.ToString() - )) - .ToList() ?? []; - - var accounts = new List(bootstrapAccounts.Count + bootstrapContracts.Count + bootstrapSmartRollups.Count); - - #region allocate null-address - var nullAddress = new User - { - Id = Cache.AppState.NextAccountId(), - Address = NullAddress.Address, - Type = AccountType.User, - FirstLevel = 1, - LastLevel = 1, - Index = 0 - }; - if (nullAddress.Id != NullAddress.Id) - throw new Exception("Failed to allocate null-address"); - Cache.Accounts.Add(nullAddress); - Db.Accounts.Add(nullAddress); - #endregion - - #region bootstrap bakers - foreach (var (pubKey, balance, _) in bootstrapAccounts.Where(x => x.Item1[0] != 't' && (x.Item3 == null || x.Item3[0] != 't'))) - { - var address = PubKey.FromBase58(pubKey).Address; - if (Cache.Accounts.TryGetCached(address, out var acc)) - { - Receive(acc, acc as Data.Models.Delegate, balance); - continue; - } - var baker = new Data.Models.Delegate - { - Id = Cache.AppState.NextAccountId(), - Address = address, - PublicKey = pubKey, - FirstLevel = 1, - LastLevel = 1, - ActivationLevel = 1, - DeactivationLevel = GracePeriod.Init(2, protocol), - Staked = true, - Revealed = true, - Type = AccountType.Delegate - }; - Receive(baker, baker, balance); - Cache.Accounts.Add(baker); - accounts.Add(baker); - - Cache.Statistics.Current.TotalBakers++; - } - #endregion - - #region bootstrap delegated users - foreach (var (pubKey, balance, delegateTo) in bootstrapAccounts.Where(x => x.Item1[0] != 't' && x.Item3 != null && x.Item3[0] == 't')) - { - var delegat = Cache.Accounts.GetExistingDelegate(delegateTo!); - - var address = PubKey.FromBase58(pubKey).Address; - if (Cache.Accounts.TryGetCached(address, out var acc)) - { - Receive(acc, delegat, balance); - continue; - } - - var user = new User - { - Id = Cache.AppState.NextAccountId(), - Address = address, - FirstLevel = 1, - LastLevel = 1, - Type = AccountType.User, - PublicKey = pubKey, - Revealed = true, - }; - Receive(user, null, balance); - - Delegate(user, delegat, 1); - - Cache.Accounts.Add(user); - accounts.Add(user); - } - #endregion - - #region bootstrap users - foreach (var (pkh, balance, _) in bootstrapAccounts.Where(x => x.Item1[0] == 't')) - { - if (Cache.Accounts.TryGetCached(pkh, out var acc)) - { - Receive(acc, null, balance); - continue; - } - var user = new User - { - Id = Cache.AppState.NextAccountId(), - Address = pkh, - FirstLevel = 1, - LastLevel = 1, - Type = AccountType.User - }; - Receive(user, null, balance); - - Cache.Accounts.Add(user); - accounts.Add(user); - } - #endregion - - #region bootstrap contracts - if (Proto.Config.Precompiles?.Count > 0) - { - foreach (var hash in Proto.Config.Precompiles) - { - var contract = await Proto.Rpc.GetContractAsync(1, hash); - var balance = contract.RequiredInt64("balance"); - var delegatePkh = contract.OptionalString("delegate"); - var script = contract.Required("script"); - var codeStr = script.Required("code").GetRawText(); - var storageStr = script.Required("storage").GetRawText(); - - bootstrapContracts.Add((balance, delegatePkh, codeStr, storageStr, hash)); - } - } - - var index = 0; - foreach (var (balance, delegatePkh, codeStr, storageStr, hash) in bootstrapContracts) - { - #region contract - var delegat = Cache.Accounts.GetDelegate(delegatePkh); - var creator = nullAddress; - - var contract = new Contract - { - Id = Cache.AppState.NextAccountId(), - Address = hash ?? OriginationNonce.GetContractAddress(index++), - FirstLevel = 1, - LastLevel = 1, - CreatorId = creator.Id, - Type = AccountType.Contract, - Kind = ContractKind.SmartContract, - }; - Receive(contract, null, balance); - - creator.ContractsCount++; - - if (delegat != null) - Delegate(contract, delegat, 1); - - Cache.Accounts.Add(contract); - accounts.Add(contract); - #endregion - - #region script - var code = (Micheline.FromJson(codeStr) as MichelineArray)!; - var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter); - var micheStorage = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage); - var micheCode = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code); - var micheViews = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view); - var script = new Script - { - Id = Cache.AppState.NextScriptId(), - Level = 1, - ContractId = contract.Id, - ParameterSchema = micheParameter.ToBytes(), - StorageSchema = micheStorage.ToBytes(), - CodeSchema = micheCode.ToBytes(), - Views = micheViews.Any() - ? [..micheViews.Select(x => x.ToBytes())] - : null, - Current = true - }; - - var viewsBytes = script.Views? - .OrderBy(x => x, new BytesComparer()) - .SelectMany(x => x) - .ToArray() - ?? []; - var typeSchema = script.ParameterSchema.Concat(script.StorageSchema).Concat(viewsBytes); - var fullSchema = typeSchema.Concat(script.CodeSchema); - contract.TypeHash = script.TypeHash = Script.GetHash(typeSchema); - contract.CodeHash = script.CodeHash = Script.GetHash(fullSchema); - - if (script.Schema.IsFA1()) - { - if (script.Schema.IsFA12()) - contract.Tags |= ContractTags.FA12; - - contract.Tags |= ContractTags.FA1; - contract.Kind = ContractKind.Asset; - } - if (script.Schema.IsFA2()) - { - contract.Tags |= ContractTags.FA2; - contract.Kind = ContractKind.Asset; - } - - Db.Scripts.Add(script); - Cache.Schemas.Add(contract, script.Schema); - #endregion - - #region storage - var storageValue = Micheline.FromJson(storageStr)!; - var storage = new Storage - { - Id = Cache.AppState.NextStorageId(), - Level = 1, - ContractId = contract.Id, - RawValue = script.Schema.OptimizeStorage(storageValue, false).ToBytes(), - JsonValue = script.Schema.HumanizeStorage(storageValue), - Current = true - }; - - Db.Storages.Add(storage); - Cache.Storages.Add(contract, storage); - #endregion - - } - #endregion - - #region bootstrap smart rollups - foreach (var (address, pvmKind, parameterType) in bootstrapSmartRollups) - { - var genesisInfo = await Proto.Rpc.GetSmartRollupGenesisInfo(1, address); - - var creator = nullAddress; - var rollup = new SmartRollup() - { - Id = Cache.AppState.NextAccountId(), - FirstLevel = 1, - LastLevel = 1, - Address = address, - CreatorId = creator.Id, - Type = AccountType.SmartRollup, - PvmKind = pvmKind switch - { - "arith" => PvmKind.Arith, - "wasm_2_0_0" => PvmKind.Wasm, - _ => throw new NotImplementedException() - }, - ParameterSchema = Micheline.FromJson(parameterType)!.ToBytes(), - GenesisCommitment = genesisInfo.RequiredString("commitment_hash"), - LastCommitment = genesisInfo.RequiredString("commitment_hash"), - InboxLevel = genesisInfo.RequiredInt32("level"), - TotalStakers = 0, - ActiveStakers = 0, - ExecutedCommitments = 0, - CementedCommitments = 0, - PendingCommitments = 0, - RefutedCommitments = 0, - OrphanCommitments = 0, - SmartRollupBonds = 0 - }; - Cache.Accounts.Add(rollup); - accounts.Add(rollup); - - creator.SmartRollupsCount++; - } - #endregion - - Db.Accounts.AddRange(accounts); - - #region migration ops - var block = Cache.Blocks.Current(); - - block.Operations |= Operations.Migrations; - - foreach (var account in accounts) - { - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = account.Id, - Kind = MigrationKind.Bootstrap, - BalanceChange = account.Balance, - }; - - if (account is Contract contract) - { - var script = (Db.ChangeTracker.Entries() - .First(x => x.Entity is Script s && s.ContractId == contract.Id).Entity as Script)!; - var storage = await Cache.Storages.GetAsync(contract); - - script.MigrationId = migration.Id; - storage.MigrationId = migration.Id; - - migration.ScriptId = script.Id; - migration.StorageId = storage.Id; - } - - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - account.MigrationsCount++; - } - - var state = Cache.AppState.Get(); - state.MigrationOpsCount += accounts.Count; - #endregion - - #region statistics - Cache.Statistics.Current.TotalBootstrapped = accounts.Sum(x => x.Balance); - #endregion - - return accounts; - } - - async Task ClearAccounts() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Accounts"; - DELETE FROM "MigrationOps"; - DELETE FROM "Scripts"; - DELETE FROM "Storages"; - """); - - await Cache.Accounts.ResetAsync(); - Cache.Schemas.Reset(); - Cache.Storages.Reset(); - - var state = Cache.AppState.Get(); - Cache.AppState.ReleaseOperationId(state.MigrationOpsCount); - state.AccountCounter = 0; - state.MigrationOpsCount = 0; - state.ScriptCounter = 0; - state.StorageCounter = 0; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.BakerCycles.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.BakerCycles.cs deleted file mode 100644 index 7b50f0b0d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.BakerCycles.cs +++ /dev/null @@ -1,103 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - public virtual void BootstrapBakerCycles( - Protocol protocol, - List accounts, - List cycles, - List> bakingRights, - List> attestationRights) - { - var bakers = accounts - .Where(x => x.Type == AccountType.Delegate) - .Select(x => (x as Data.Models.Delegate)!); - - foreach (var cycle in cycles) - { - var bakerCycles = bakers.ToDictionary(x => x.Id, x => - { - var share = (double)x.BakingPower / cycle.TotalBakingPower; - return new BakerCycle - { - Id = 0, - Cycle = cycle.Index, - BakerId = x.Id, - OwnDelegatedBalance = x.Balance, - ExternalDelegatedBalance = x.ExternalDelegatedBalance, - DelegatorsCount = x.DelegatorsCount, - OwnStakedBalance = x.OwnStakedBalance, - ExternalStakedBalance = x.ExternalStakedBalance, - StakersCount = x.StakersCount, - IssuedPseudotokens = x.IssuedPseudotokens, - BakingPower = x.BakingPower, - TotalBakingPower = cycle.TotalBakingPower, - ExpectedBlocks = protocol.BlocksPerCycle * share, - ExpectedAttestations = protocol.AttestersPerBlock * protocol.BlocksPerCycle * share - }; - }); - - #region future baking rights - foreach (var br in bakingRights[cycle.Index].SkipWhile(x => x.Level == 1)) // skip bootstrap block rights - { - if (br.Round > 0) - continue; - - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Unknown baking right recipient"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += GetFutureBlockReward(protocol, cycle.Index); - } - #endregion - - #region future attestation rights - var skipLevel = attestationRights[cycle.Index].Last().Level; // skip shifted rights - foreach (var ar in attestationRights[cycle.Index].TakeWhile(x => x.Level < skipLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Unknown attestation right recipient"); - - bakerCycle.FutureAttestations += ar.Slots; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(protocol, cycle.Index, ar.Slots); - } - #endregion - - #region shifted future endirsing rights - if (cycle.Index > 0) - { - foreach (var ar in attestationRights[cycle.Index - 1].Reverse().TakeWhile(x => x.Level == cycle.FirstLevel - 1)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Unknown attestation right recipient"); - - bakerCycle.FutureAttestations += ar.Slots; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(protocol, cycle.Index, ar.Slots); - } - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - } - } - - public async Task ClearBakerCycles() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakerCycles" - """); - Cache.BakerCycles.Reset(); - } - - #region helpers - protected virtual long GetFutureBlockReward(Protocol protocol, int cycle) - => cycle < protocol.NoRewardCycles ? 0 : protocol.BlockReward0; - - protected virtual long GetFutureAttestationReward(Protocol protocol, int cycle, int slots) - => cycle < protocol.NoRewardCycles ? 0 : (slots * protocol.AttestationReward0); - #endregion - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.BakingRights.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.BakingRights.cs deleted file mode 100644 index 5418d7da4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.BakingRights.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - public async Task<(List>, List>)> BootstrapBakingRights( - Protocol protocol, - List accounts, - List cycles) - { - var bakingRights = new List>(protocol.ConsensusRightsDelay + 1); - var attestationRights = new List>(protocol.ConsensusRightsDelay + 1); - - foreach (var cycle in cycles) - { - var (futureBakingRights, futureAttestationRights) = await GetRights(protocol, accounts, cycle); - - bakingRights.Add(futureBakingRights); - attestationRights.Add(futureAttestationRights); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@" - COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") - FROM STDIN (FORMAT BINARY)"); - - foreach (var ar in futureAttestationRights) - { - writer.StartRow(); - writer.Write(protocol.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); // level + 1 (shifted) - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); // level + 1 (shifted) - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in futureBakingRights.SkipWhile(x => x.Level == 1)) // skip bootstrap block rights - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - - return (bakingRights, attestationRights); - } - - public async Task ClearBakingRights() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - """); - Cache.BakingRights.Reset(); - } - - protected virtual async Task<(IEnumerable, IEnumerable)> GetRights(Protocol protocol, List accounts, Cycle cycle) - { - var bakingRights = (await Proto.Rpc.GetBakingRightsAsync(1, cycle.Index)) - .EnumerateArray() - .Select(x => new RightsGenerator.BR - { - Baker = Cache.Accounts.GetExistingDelegate(x.RequiredString("delegate")).Id, - Level = x.RequiredInt32("level"), - Round = x.RequiredInt32("priority") - }); - - var attestationRights = (await Proto.Rpc.GetAttestationRightsAsync(1, cycle.Index)) - .EnumerateArray() - .Select(x => new RightsGenerator.AR - { - Baker = Cache.Accounts.GetExistingDelegate(x.RequiredString("delegate")).Id, - Level = x.RequiredInt32("level"), - Slots = x.RequiredArray("slots").Count() - }); - - return (bakingRights, attestationRights); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Commitments.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Commitments.cs deleted file mode 100644 index 774c16b4b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Commitments.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - void BootstrapCommitments(JToken parameters) - { - var commitments = parameters["commitments"]?.Select(x => new Commitment - { - Id = 0, - Address = x[0]!.Value()!, - Balance = x[1]!.Value() - }); - - if (commitments != null) - { - var state = Cache.AppState.Get(); - var statistics = Cache.Statistics.Current; - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@"COPY ""Commitments"" (""Balance"", ""Address"") FROM STDIN (FORMAT BINARY)"); - - foreach (var commitment in commitments) - { - writer.StartRow(); - writer.Write(commitment.Balance); - writer.Write(commitment.Address); - - state.CommitmentsCount++; - statistics.TotalCommitments += commitment.Balance; - } - - writer.Complete(); - } - } - - async Task ClearCommitments() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Commitments" - """); - - var state = Cache.AppState.Get(); - state.CommitmentsCount = 0; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Cycles.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Cycles.cs deleted file mode 100644 index a5718fd67..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Cycles.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - public virtual List BootstrapCycles(Protocol protocol, List accounts, JToken parameters) - { - var cycles = new List(protocol.ConsensusRightsDelay + 1); - var delegates = accounts - .Where(x => x.Type == AccountType.Delegate) - .Select(x => (x as Data.Models.Delegate)!); - var selected = delegates.Where(x => x.BakingPower != 0); - var selectedBakers = selected.Count(); - var selectedPower = selected.Sum(x => x.BakingPower); - - var initialSeed = parameters["initial_seed"]?.Value() is string base58Seed && - Base58.TryParse(base58Seed, new byte[3], out var _initialSeed) && - _initialSeed.Length == 32 - ? _initialSeed - : []; - - var seeds = Seed.GetInitialSeeds(protocol.ConsensusRightsDelay + 1, initialSeed); - for (int index = 0; index <= protocol.ConsensusRightsDelay; index++) - { - var cycle = new Cycle - { - Id = 0, - Index = index, - FirstLevel = protocol.GetCycleStart(index), - LastLevel = protocol.GetCycleEnd(index), - SnapshotLevel = 1, - TotalBakers = selectedBakers, - TotalBakingPower = selectedPower, - Seed = seeds[index] - }; - Db.Cycles.Add(cycle); - cycles.Add(cycle); - } - - var state = Cache.AppState.Get(); - state.CyclesCount += protocol.ConsensusRightsDelay + 1; - - return cycles; - } - - public async Task ClearCycles() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Cycles" - """); - var state = Cache.AppState.Get(); - state.CyclesCount = 0; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.DelegationSnapshots.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.DelegationSnapshots.cs deleted file mode 100644 index b67599a69..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.DelegationSnapshots.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - public void BootstrapDelegationSnapshots(List accounts) - { - Db.DelegationSnapshots.AddRange(accounts - .Where(x => x.Staked) - .Select(x => new DelegationSnapshot - { - Level = 1, - BakerId = x.DelegateId ?? x.Id, - AccountId = x.Id, - - OwnDelegatedBalance = x.Balance - ((x as Data.Models.Delegate)?.OwnStakedBalance ?? 0), - ExternalDelegatedBalance = (x as Data.Models.Delegate)?.ExternalDelegatedBalance, - DelegatorsCount = (x as Data.Models.Delegate)?.DelegatorsCount, - - PrevMinTotalDelegatedLevel = (x as Data.Models.Delegate)?.MinTotalDelegatedLevel, - PrevMinTotalDelegated = (x as Data.Models.Delegate)?.MinTotalDelegated - })); - } - - public async Task ClearDelegationSnapshots() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "DelegationSnapshots" - """); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.DelegatorCycles.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.DelegatorCycles.cs deleted file mode 100644 index b66970d6c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.DelegatorCycles.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - public void BootstrapDelegatorCycles(Protocol protocol, List accounts) - { - for (int cycle = 0; cycle <= protocol.ConsensusRightsDelay; cycle++) - { - Db.DelegatorCycles.AddRange(accounts - .Where(x => x.DelegateId != null) - .Select(x => new DelegatorCycle - { - Id = 0, - Cycle = cycle, - DelegatorId = x.Id, - BakerId = x.DelegateId!.Value, - DelegatedBalance = x.Balance, - StakedPseudotokens = (x as User)?.StakedPseudotokens - })); - } - } - - public async Task ClearDelegatorCycles() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "DelegatorCycles" - """); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Protocol.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Protocol.cs deleted file mode 100644 index 9be03fc38..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Protocol.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; -using Tzkt.Sync.Utils; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - public (Protocol, JToken) BootstrapProtocol(JsonElement rawBlock) - { - var protocol = new Protocol - { - Id = 0, - Code = 1, - Version = Proto.VersionNumber, - Hash = rawBlock.Required("metadata").RequiredString("next_protocol"), - FirstLevel = 2, - LastLevel = -1, - FirstCycle = 0, - FirstCycleLevel = 1 - }; - Db.Protocols.Add(protocol); - Cache.Protocols.Add(protocol); - Context.Protocol = protocol; - - var parameters = Bson.Parse(rawBlock - .Required("header") - .Required("content") - .RequiredString("protocol_parameters") - [8..]); - - SetParameters(protocol, parameters); - return (protocol, parameters); - } - - public async Task ClearProtocol() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Protocols" - WHERE "Code" = 1 - """); - - await Cache.Protocols.ResetAsync(); - } - - protected virtual void SetParameters(Protocol protocol, JToken parameters) - { - protocol.RampUpCycles = parameters["security_deposit_ramp_up_cycles"]?.Value() ?? 0; - protocol.NoRewardCycles = parameters["no_reward_cycles"]?.Value() ?? 0; - protocol.BlockDeposit = parameters["block_security_deposit"]?.Value() ?? 512_000_000; - protocol.BlockReward0 = parameters["block_reward"]?.Value() ?? 16_000_000; - protocol.BlockReward1 = 0; - protocol.BlocksPerCommitment = parameters["blocks_per_commitment"]?.Value() ?? 32; - protocol.BlocksPerCycle = parameters["blocks_per_cycle"]?.Value() ?? 4096; - protocol.BlocksPerSnapshot = parameters["blocks_per_roll_snapshot"]?.Value() ?? 256; - protocol.BlocksPerVoting = parameters["blocks_per_voting_period"]?.Value() ?? 32_768; - protocol.ByteCost = parameters["cost_per_byte"]?.Value() ?? 1000; - protocol.AttestationDeposit = parameters["endorsement_security_deposit"]?.Value() ?? 64_000_000; - protocol.AttestationReward0 = parameters["endorsement_reward"]?.Value() ?? 2_000_000; - protocol.AttestationReward1 = 0; - protocol.AttestersPerBlock = parameters["endorsers_per_block"]?.Value() ?? 32; - protocol.HardBlockGasLimit = parameters["hard_gas_limit_per_block"]?.Value() ?? 4_000_000; - protocol.HardOperationGasLimit = parameters["hard_gas_limit_per_operation"]?.Value() ?? 400_000; - protocol.HardOperationStorageLimit = parameters["hard_storage_limit_per_operation"]?.Value() ?? 60_000; - protocol.OriginationSize = (parameters["origination_burn"]?.Value() ?? 257_000) / protocol.ByteCost; - protocol.ConsensusRightsDelay = parameters["preserved_cycles"]?.Value() ?? 5; - protocol.ToleratedInactivityPeriod = protocol.ConsensusRightsDelay + 1; - protocol.TimeBetweenBlocks = parameters["time_between_blocks"]?[0]!.Value() ?? 60; - protocol.MinimalStake = parameters["tokens_per_roll"]?.Value() ?? 10_000_000_000; - protocol.BallotQuorumMin = 0; - protocol.BallotQuorumMax = 10000; - protocol.ProposalQuorum = 0; - } - - public async Task UpgradeProtocol(AppState state) - { - var prev = await Cache.Protocols.GetAsync(state.Protocol); - Db.TryAttach(prev); - prev.LastLevel = state.Level; - - var protocol = new Protocol - { - Id = 0, - Code = prev.Code + 1, - Version = Proto.VersionNumber, - Hash = state.NextProtocol, - FirstLevel = state.Level + 1, - LastLevel = -1, - FirstCycle = state.Cycle + 1, - FirstCycleLevel = prev.GetCycleStart(state.Cycle + 1), - RampUpCycles = prev.RampUpCycles, - NoRewardCycles = prev.NoRewardCycles, - BlockDeposit = prev.BlockDeposit, - BlockReward0 = prev.BlockReward0, - BlockReward1 = prev.BlockReward1, - BlocksPerCommitment = prev.BlocksPerCommitment, - BlocksPerCycle = prev.BlocksPerCycle, - BlocksPerSnapshot = prev.BlocksPerSnapshot, - BlocksPerVoting = prev.BlocksPerVoting, - ByteCost = prev.ByteCost, - AttestationDeposit = prev.AttestationDeposit, - AttestationReward0 = prev.AttestationReward0, - AttestationReward1 = prev.AttestationReward1, - AttestersPerBlock = prev.AttestersPerBlock, - HardBlockGasLimit = prev.HardBlockGasLimit, - HardOperationGasLimit = prev.HardOperationGasLimit, - HardOperationStorageLimit = prev.HardOperationStorageLimit, - OriginationSize = prev.OriginationSize, - ConsensusRightsDelay = prev.ConsensusRightsDelay, - ToleratedInactivityPeriod = prev.ToleratedInactivityPeriod, - TimeBetweenBlocks = prev.TimeBetweenBlocks, - MinimalStake = prev.MinimalStake, - BallotQuorumMin = prev.BallotQuorumMin, - BallotQuorumMax = prev.BallotQuorumMax, - ProposalQuorum = prev.ProposalQuorum, - LBToggleThreshold = prev.LBToggleThreshold, - ConsensusThreshold = prev.ConsensusThreshold, - MaxDelegatedOverFrozenRatio = prev.MaxDelegatedOverFrozenRatio, - MaxExternalOverOwnStakeRatio = prev.MaxExternalOverOwnStakeRatio, - DoubleBakingSlashedPercentage = prev.DoubleBakingSlashedPercentage, - DoubleConsensusSlashedPercentage = prev.DoubleConsensusSlashedPercentage, - MinimalFrozenStake = prev.MinimalFrozenStake, - StakePowerMultiplier = prev.StakePowerMultiplier, - MaxBakingReward = prev.MaxBakingReward, - MaxAttestationReward = prev.MaxAttestationReward, - DenunciationPeriod = prev.DenunciationPeriod, - SlashingDelay = prev.SlashingDelay, - MinParticipationDenominator = prev.MinParticipationDenominator, - MinParticipationNumerator = prev.MinParticipationNumerator, - Dictator = prev.Dictator, - SmartRollupChallengeWindow = prev.SmartRollupChallengeWindow, - SmartRollupCommitmentPeriod = prev.SmartRollupCommitmentPeriod, - SmartRollupOriginationSize = prev.SmartRollupOriginationSize, - SmartRollupStakeAmount = prev.SmartRollupStakeAmount, - SmartRollupTimeoutPeriod = prev.SmartRollupTimeoutPeriod, - DelegateParametersActivationDelay = prev.DelegateParametersActivationDelay, - NumberOfShards = prev.NumberOfShards - }; - Db.Protocols.Add(protocol); - Cache.Protocols.Add(protocol); - Context.Protocol = protocol; - - UpgradeParameters(protocol, prev); - } - - public async Task DowngradeProtocol(AppState state) - { - var current = await Cache.Protocols.GetAsync(state.NextProtocol); - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Protocols" - WHERE "Code" = {0} - """, current.Code); - - - var prev = await Cache.Protocols.GetAsync(state.Protocol); - Db.TryAttach(prev); - prev.LastLevel = -1; - - await Cache.Protocols.ResetAsync(); - } - - protected virtual void UpgradeParameters(Protocol protocol, Protocol prev) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.SnapshotBalances.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.SnapshotBalances.cs deleted file mode 100644 index 21df4917a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.SnapshotBalances.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - public void BootstrapSnapshotBalances(List accounts) - { - Db.SnapshotBalances.AddRange(accounts - .Where(x => x.Staked) - .Select(x => new SnapshotBalance - { - Level = 1, - BakerId = x.DelegateId ?? x.Id, - AccountId = x.Id, - - OwnDelegatedBalance = x.Balance - ((x as Data.Models.Delegate)?.OwnStakedBalance ?? 0), - ExternalDelegatedBalance = (x as Data.Models.Delegate)?.ExternalDelegatedBalance, - DelegatorsCount = (x as Data.Models.Delegate)?.DelegatorsCount, - - OwnStakedBalance = (x as Data.Models.Delegate)?.OwnStakedBalance, - ExternalStakedBalance = (x as Data.Models.Delegate)?.ExternalStakedBalance, - StakersCount = (x as Data.Models.Delegate)?.StakersCount, - - Pseudotokens = (x as Data.Models.Delegate)?.IssuedPseudotokens ?? (x as User)?.StakedPseudotokens - })); - } - - public async Task ClearSnapshotBalances() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "SnapshotBalances" - """); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.StakerCycles.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.StakerCycles.cs deleted file mode 100644 index 22ae36964..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.StakerCycles.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - protected virtual void BootstrapStakerCycles(Protocol protocol, List accounts) - { - // staker cycles start from proto19 - } - - protected async Task ClearStakerCycles() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "StakerCycles" - """); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Voting.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Voting.cs deleted file mode 100644 index 909aa6545..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.Voting.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator : ProtocolCommit - { - public void BootstrapVoting(Protocol protocol, List accounts) - { - var snapshots = accounts - .Where(x => x.Type == AccountType.Delegate) - .Select(x => (x as Data.Models.Delegate)!) - .Select(x => new VotingSnapshot - { - Id = 0, - Level = 1, - Period = 0, - BakerId = x.Id, - VotingPower = x.VotingPower, - Status = VoterStatus.None - }); - - var period = new VotingPeriod - { - Id = 0, - Index = 0, - Epoch = 0, - FirstLevel = 1, - LastLevel = protocol.BlocksPerVoting, - Kind = PeriodKind.Proposal, - Status = PeriodStatus.Active, - TotalBakers = snapshots.Count(), - TotalVotingPower = snapshots.Sum(x => x.VotingPower), - UpvotesQuorum = protocol.ProposalQuorum, - ProposalsCount = 0, - TopUpvotes = 0, - TopVotingPower = 0, - SingleWinner = false - }; - - Db.VotingSnapshots.AddRange(snapshots); - Db.VotingPeriods.Add(period); - Cache.Periods.Add(period); - } - - public async Task ClearVoting() - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "VotingPeriods"; - DELETE FROM "VotingSnapshots"; - """); - Cache.Periods.Reset(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.cs deleted file mode 100644 index 3137f2684..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Activation/ProtoActivator.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - partial class ProtoActivator(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Activate(AppState state, JsonElement rawBlock) - { - if (state.Level == 1) // bootstrap - { - ActivateFeatures(); - var (protocol, parameters) = BootstrapProtocol(rawBlock); - var accounts = await BootstrapAccounts(protocol, parameters); - var cycles = BootstrapCycles(protocol, accounts, parameters); - var (bakingRights, attestationRights) = await BootstrapBakingRights(protocol, accounts, cycles); - BootstrapDelegationSnapshots(accounts); - BootstrapSnapshotBalances(accounts); - BootstrapBakerCycles(protocol, accounts, cycles, bakingRights, attestationRights); - BootstrapStakerCycles(protocol, accounts); - BootstrapDelegatorCycles(protocol, accounts); - BootstrapVoting(protocol, accounts); - BootstrapCommitments(parameters); - await ActivateContext(state); - } - else // upgrade - { - await UpgradeProtocol(state); - await MigrateContext(state); - } - } - - public async Task Deactivate(AppState state) - { - if (state.Level == 1) // clear - { - await DeactivateContext(state); - await ClearCommitments(); - await ClearVoting(); - await ClearSnapshotBalances(); - await ClearDelegationSnapshots(); - await ClearBakerCycles(); - await ClearStakerCycles(); - await ClearDelegatorCycles(); - await ClearCycles(); - await ClearBakingRights(); - await ClearAccounts(); - await ClearProtocol(); - DeactivateFeatures(); - } - else // downgrade - { - await RevertContext(state); - await DowngradeProtocol(state); - } - } - - protected virtual void ActivateFeatures() { } - protected virtual void DeactivateFeatures() { } - protected virtual Task ActivateContext(AppState state) => Task.CompletedTask; - protected virtual Task DeactivateContext(AppState state) => Task.CompletedTask; - protected virtual Task MigrateContext(AppState state) => Task.CompletedTask; - protected virtual Task RevertContext(AppState state) => Task.CompletedTask; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BakerCycleCommit.cs deleted file mode 100644 index 738e63dfb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,592 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class BakerCycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply( - Block block, - Cycle? futureCycle, - IEnumerable? futureBakingRights, - IEnumerable? futureAttestationRights, - List? snapshots, - List currentRights) - { - #region current rights - var prevBlock = await Cache.Blocks.CurrentAsync(); - var prevBakingRights = prevBlock.Level == 1 ? [] - : await Cache.BakingRights.GetAsync(prevBlock.Level); - - foreach (var rights in currentRights.GroupBy(x => x.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, rights.Key); - Db.TryAttach(bakerCycle); - - var bakingRights = rights - .Where(x => x.Type == BakingRightType.Baking) - .OrderBy(x => x.Round) - .ToList(); - - var attestationRight = rights - .FirstOrDefault(x => x.Type == BakingRightType.Attestation); - - #region rights and deposits - foreach (var br in bakingRights) - { - if (br.Round == 0 && bakerCycle.FutureBlocks != 0) // FutureBlocks is always 0 for weirds - { - bakerCycle.FutureBlocks--; - } - - if (br.Status == BakingRightStatus.Realized) - { - bakerCycle.Blocks++; - } - else if (br.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlocks++; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - - if (attestationRight != null) - { - if (bakerCycle.FutureAttestations != 0) // FutureAttestations is always 0 for weirds - { - bakerCycle.FutureAttestations -= attestationRight.Slots!.Value; - } - - if (attestationRight.Status == BakingRightStatus.Realized) - { - bakerCycle.Attestations += attestationRight.Slots!.Value; - } - else if (attestationRight.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedAttestations += attestationRight.Slots!.Value; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - - #region attestation rewards - if (attestationRight != null) - { - if (bakerCycle.FutureAttestationRewards != 0) // FutureAttestationRewards is always 0 for weirds - bakerCycle.FutureAttestationRewards -= GetFutureAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots!.Value); - - var successReward = GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots!.Value, prevBlock.BlockRound); - - var prevRights = prevBakingRights - .Where(x => x.Type == BakingRightType.Baking && x.BakerId == rights.Key) - .OrderBy(x => x.Round) - .ToList(); - - var maxReward = prevRights.FirstOrDefault()?.Status > BakingRightStatus.Realized - ? GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, prevRights[0].Round!.Value) - : successReward; - - if (attestationRight.Status == BakingRightStatus.Realized) - bakerCycle.AttestationRewardsDelegated += successReward; - else if (attestationRight.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestationRewards += successReward; - else - throw new Exception("Unexpected future rights"); - - if (maxReward != successReward) - { - var prevBakerCycle = await Cache.BakerCycles.GetAsync(prevBlock.Cycle, rights.Key); - Db.TryAttach(prevBakerCycle); - - prevBakerCycle.MissedBlockRewards += maxReward - successReward; - } - } - #endregion - - #region baking rewards - if (bakingRights.Count > 0) - { - if (bakingRights[0].Round == 0 && bakerCycle.FutureBlockRewards != 0) // FutureBlockRewards is always 0 for weirds - bakerCycle.FutureBlockRewards -= GetFutureBlockReward(Context.Protocol, block.Cycle); - - var successReward = GetBlockReward(Context.Protocol, block.Cycle); - - var actualReward = bakingRights[^1].Status == BakingRightStatus.Realized - ? GetBlockReward(Context.Protocol, block.Cycle) - : 0; - - //var maxReward = attestationRight?.Status > BakingRightStatus.Realized - // ? GetBlockReward(Context.Protocol, (int)bakingRights[0].Round, block.AttestationPower + attestationRight.Slots.Value) - // : successReward; - - if (actualReward > 0) - { - bakerCycle.BlockRewardsDelegated += actualReward; - } - - if (successReward != actualReward) - { - bakerCycle.MissedBlockRewards += successReward - actualReward; - } - - //if (maxReward != successReward) - //{ - // bakerCycle.MissedAttestationRewards += maxReward - successReward; - //} - } - #endregion - - #region fees - if (bakingRights.Count > 0) - { - if (bakingRights[^1].Status == BakingRightStatus.Realized) - { - bakerCycle.BlockFees += block.Fees; - } - else if (bakingRights[0].Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlockFees += block.Fees; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - } - - foreach (var op in Context.DoubleBakingOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleBakingLostStaked += op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleBakingRewards += op.Reward; - } - - foreach (var op in Context.DoubleConsensusOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleConsensusLostStaked += op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleConsensusRewards += op.Reward; - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.NonceRevelationRewardsDelegated += op.RewardDelegated; - } - - foreach (var op in Context.RevelationPenaltyOps) - { - var penaltyBlock = await Cache.Blocks.GetAsync(op.MissedLevel); - var penaltyCycle = await Cache.BakerCycles.GetAsync(penaltyBlock.Cycle, op.BakerId); - Db.TryAttach(penaltyCycle); - - penaltyCycle.NonceRevelationLosses += op.Loss; - } - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var bakerCycles = new Dictionary(snapshots!.Count); - foreach (var snapshot in snapshots) - { - var baker = await Cache.Accounts.GetAsync(snapshot.AccountId); // WTF: rights were given to non-baker accounts - - var bakingPower = snapshot.StakingBalance - snapshot.StakingBalance % Context.Protocol.MinimalStake; - var share = (double)bakingPower / futureCycle!.TotalBakingPower; - - var bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = snapshot.AccountId, - OwnDelegatedBalance = snapshot.OwnDelegatedBalance, - ExternalDelegatedBalance = snapshot.ExternalDelegatedBalance!.Value, - DelegatorsCount = snapshot.DelegatorsCount!.Value, - OwnStakedBalance = snapshot.OwnStakedBalance ?? 0, - ExternalStakedBalance = snapshot.ExternalStakedBalance ?? 0, - StakersCount = snapshot.StakersCount ?? 0, - IssuedPseudotokens = snapshot.Pseudotokens, - BakingPower = bakingPower, - TotalBakingPower = futureCycle.TotalBakingPower, - ExpectedBlocks = Context.Protocol.BlocksPerCycle * share, - ExpectedAttestations = Context.Protocol.AttestersPerBlock * Context.Protocol.BlocksPerCycle * share - }; - - bakerCycles.Add(baker.Address, bakerCycle); - } - - #region future baking rights - foreach (var br in futureBakingRights!) - { - if (br.RequiredInt32("priority") > 0) - continue; - - if (!bakerCycles.TryGetValue(br.RequiredString("delegate"), out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - if (!Cache.Accounts.DelegateExists(br.RequiredString("delegate"))) - continue; - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += GetFutureBlockReward(Context.Protocol, futureCycle!.Index); - } - #endregion - - #region future attestation rights - var skipLevel = futureAttestationRights!.Last().RequiredInt32("level"); - - foreach (var ar in futureAttestationRights!.TakeWhile(x => x.RequiredInt32("level") < skipLevel)) - { - if (!bakerCycles.TryGetValue(ar.RequiredString("delegate"), out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - if (!Cache.Accounts.DelegateExists(ar.RequiredString("delegate"))) - continue; - - var slots = ar.RequiredArray("slots").Count(); - - bakerCycle.FutureAttestations += slots; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, futureCycle!.Index, slots); - } - #endregion - - #region shifted future attestation rights - // TODO: cache shifted rights - var shiftedRights = await Db.BakingRights.AsNoTracking() - .Where(x => x.Level == futureCycle!.FirstLevel && x.Type == BakingRightType.Attestation) - .ToListAsync(); - - foreach (var ar in shiftedRights) - { - if (!Cache.Accounts.DelegateExists(ar.BakerId)) - continue; - - var baker = Cache.Accounts.GetDelegate(ar.BakerId); - if (!bakerCycles.TryGetValue(baker.Address, out var bakerCycle)) - { - #region shifting hack - //shifting is actually a bad idea, but this is the lesser of two evils while Tezos protocol has bugs in the freezer. - var snapshottedBaker = await Proto.Rpc.GetDelegateAsync(futureCycle!.SnapshotLevel, baker.Address); - var delegators = snapshottedBaker - .RequiredArray("delegated_contracts") - .EnumerateArray() - .Select(x => x.RequiredString()) - .Where(x => x != baker.Address); - - if (snapshottedBaker.RequiredInt32("grace_period") != block.Cycle - 3) - throw new Exception("Deactivated baker got baking rights"); - - var stakingBalance = snapshottedBaker.RequiredInt64("staking_balance"); - var delegatedBalance = snapshottedBaker.RequiredInt64("delegated_balance"); - - bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = baker.Id, - OwnDelegatedBalance = stakingBalance - delegatedBalance, - ExternalDelegatedBalance = delegatedBalance, - DelegatorsCount = delegators.Count(), - OwnStakedBalance = 0, - ExternalStakedBalance = 0, - StakersCount = 0, - IssuedPseudotokens = null, - BakingPower = 0, - TotalBakingPower = futureCycle.TotalBakingPower, - ExpectedBlocks = 0, - ExpectedAttestations = 0 - }; - bakerCycles.Add(baker.Address, bakerCycle); - - foreach (var delegatorAddress in delegators) - { - var snapshottedDelegator = await Proto.Rpc.GetContractAsync(futureCycle.SnapshotLevel, delegatorAddress); - Db.DelegatorCycles.Add(new DelegatorCycle - { - Id = 0, - Cycle = futureCycle.Index, - DelegatorId = (await Cache.Accounts.GetExistingAsync(delegatorAddress)).Id, - BakerId = baker.Id, - DelegatedBalance = snapshottedDelegator.RequiredInt64("balance"), - StakedPseudotokens = null - }); - } - #endregion - } - - bakerCycle.FutureAttestations += ar.Slots!.Value; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, futureCycle!.Index, (int)ar.Slots); - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - - #region weird bakers - if (block.Cycle > 0) - { - //one-way change... - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakerCycles" as bc - USING "Accounts" as acc - WHERE acc."Id" = bc."BakerId" - AND bc."Cycle" = {0} - AND acc."Type" != {1} - """, block.Cycle - 1, (int)AccountType.Delegate); - } - #endregion - } - #endregion - } - - public virtual async Task Revert(Block block) - { - #region current rights - var prevBlock = await Cache.Blocks.PreviousAsync(); - var prevBakingRights = prevBlock.Level == 1 ? [] - : await Cache.BakingRights.GetAsync(prevBlock.Level); - - var currentRights = await Cache.BakingRights.GetAsync(block.Level); - - foreach (var rights in currentRights.GroupBy(x => x.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, rights.Key); - if (bakerCycle == null) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin) || rights.Any(x => x.Status == BakingRightStatus.Realized)) - throw new Exception("Shifted rights hack doesn't work :("); - continue; - } - - Db.TryAttach(bakerCycle); - - var bakingRights = rights - .Where(x => x.Type == BakingRightType.Baking) - .OrderBy(x => x.Round) - .ToList(); - - var attestationRight = rights - .FirstOrDefault(x => x.Type == BakingRightType.Attestation); - - #region rights and deposits - foreach (var br in bakingRights) - { - if (br.Round == 0) - { - bakerCycle.FutureBlocks++; - } - - if (br.Status == BakingRightStatus.Realized) - { - bakerCycle.Blocks--; - } - else if (br.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlocks--; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - - if (attestationRight != null) - { - bakerCycle.FutureAttestations += attestationRight.Slots!.Value; - - if (attestationRight.Status == BakingRightStatus.Realized) - { - bakerCycle.Attestations -= attestationRight.Slots.Value; - } - else if (attestationRight.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedAttestations -= attestationRight.Slots.Value; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - - #region attestation rewards - if (attestationRight != null) - { - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots!.Value); - - var successReward = GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, prevBlock.BlockRound); - - var prevRights = prevBakingRights - .Where(x => x.Type == BakingRightType.Baking && x.BakerId == rights.Key) - .OrderBy(x => x.Round) - .ToList(); - - var maxReward = prevRights.FirstOrDefault()?.Status > BakingRightStatus.Realized - ? GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, prevRights[0].Round!.Value) - : successReward; - - if (attestationRight.Status == BakingRightStatus.Realized) - bakerCycle.AttestationRewardsDelegated -= successReward; - else if (attestationRight.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestationRewards -= successReward; - else - throw new Exception("Unexpected future rights"); - - if (maxReward != successReward) - { - var prevBakerCycle = await Cache.BakerCycles.GetAsync(prevBlock.Cycle, rights.Key); - Db.TryAttach(prevBakerCycle); - - prevBakerCycle.MissedBlockRewards -= maxReward - successReward; - } - } - #endregion - - #region baking rewards - if (bakingRights.Count > 0) - { - if (bakingRights[0].Round == 0) - bakerCycle.FutureBlockRewards += GetFutureBlockReward(Context.Protocol, block.Cycle); - - var successReward = GetBlockReward(Context.Protocol, block.Cycle); - - var actualReward = bakingRights[^1].Status == BakingRightStatus.Realized - ? GetBlockReward(Context.Protocol, block.Cycle) - : 0; - - //var maxReward = attestationRight?.Status > BakingRightStatus.Realized - // ? GetBlockReward(Context.Protocol, bakingRights[0].Round!.Value, block.AttestationPower + attestationRight.Slots.Value) - // : successReward; - - if (actualReward > 0) - { - bakerCycle.BlockRewardsDelegated -= actualReward; - } - - if (successReward != actualReward) - { - bakerCycle.MissedBlockRewards -= successReward - actualReward; - } - - //if (maxReward != successReward) - //{ - // bakerCycle.MissedAttestationRewards -= maxReward - successReward; - //} - } - #endregion - - #region fees - if (bakingRights.Count > 0) - { - if (bakingRights[^1].Status == BakingRightStatus.Realized) - { - bakerCycle.BlockFees -= block.Fees; - } - else if (bakingRights[0].Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlockFees -= block.Fees; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - } - - foreach (var op in Context.DoubleBakingOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleBakingLostStaked -= op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleBakingRewards -= op.Reward; - } - - foreach (var op in Context.DoubleConsensusOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleConsensusLostStaked -= op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleConsensusRewards -= op.Reward; - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.NonceRevelationRewardsDelegated -= op.RewardDelegated; - } - - foreach (var op in Context.RevelationPenaltyOps) - { - var penaltyBlock = await Cache.Blocks.GetAsync(op.MissedLevel); - var penaltyCycle = await Cache.BakerCycles.GetAsync(penaltyBlock.Cycle, op.BakerId); - Db.TryAttach(penaltyCycle); - - penaltyCycle.NonceRevelationLosses -= op.Loss; - } - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakerCycles" - WHERE "Cycle" = {0} - """, block.Cycle + Context.Protocol.ConsensusRightsDelay); - } - #endregion - } - - #region helpers - protected long GetFutureBlockReward(Protocol protocol, int cycle) - => cycle < protocol.NoRewardCycles ? 0 : protocol.BlockReward0; - - protected long GetFutureAttestationReward(Protocol protocol, int cycle, int slots) - => cycle < protocol.NoRewardCycles ? 0 : (slots * protocol.AttestationReward0); - - protected long GetBlockReward(Protocol protocol, int cycle) - => cycle < protocol.NoRewardCycles ? 0 : protocol.BlockReward0; - - protected long GetAttestationReward(Protocol protocol, int cycle, int slots, int prevPriority) - => cycle < protocol.NoRewardCycles ? 0 : (slots * (long)(protocol.AttestationReward0 / (prevPriority + 1.0))); - #endregion - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BakingRightsCommit.cs deleted file mode 100644 index 080262e42..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class BakingRightsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public List CurrentRights { get; protected set; } = null!; - public IEnumerable? FutureBakingRights { get; protected set; } - public IEnumerable? FutureAttestationRights { get; protected set; } - - public virtual async Task Apply(Block block) - { - #region current rights - CurrentRights = await Cache.BakingRights.GetAsync(block.Level); - var sql = string.Empty; - - if (block.BlockRound == 0 && block.AttestationPower == block.AttestationCommittee) - { - CurrentRights.RemoveAll(x => x.Type == BakingRightType.Baking && x.Round > 0); - CurrentRights.ForEach(x => x.Status = BakingRightStatus.Realized); - - sql = $@" - DELETE FROM ""BakingRights"" - WHERE ""Level"" = {block.Level} - AND ""Type"" = {(int)BakingRightType.Baking} - AND ""Round"" > 0; - - UPDATE ""BakingRights"" - SET ""Status"" = {(int)BakingRightStatus.Realized} - WHERE ""Level"" = {block.Level};"; - } - else - { - #region load missed rounds - var maxExistedRound = CurrentRights - .Where(x => x.Type == BakingRightType.Baking) - .Select(x => x.Round) - .Max(); - - if (maxExistedRound < block.BlockRound) - { - var bakingRights = await Proto.Rpc.GetLevelBakingRightsAsync(block.Level, block.Level, block.BlockRound); - //bakingRights = bakingRights.OrderBy(x => x.Round); - - var sqlInsert = @" - INSERT INTO ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") VALUES "; - - foreach (var bakingRight in bakingRights.EnumerateArray().SkipWhile(x => x.RequiredInt32("priority") <= maxExistedRound)) - { - var delegat = Cache.Accounts.GetDelegateOrDefault(bakingRight.RequiredString("delegate")); - if (delegat == null) continue; // WTF: [level:28680] - Baking rights were given to non-baker account - - sqlInsert += $@" - ({block.Cycle}, {block.Level}, {delegat.Id}, {(int)BakingRightType.Baking}, {(int)BakingRightStatus.Future}, {bakingRight.RequiredInt32("priority")}, null),"; - } - - await Db.Database.ExecuteSqlRawAsync(sqlInsert[..^1]); - - //TODO: execute sql with RETURNS to get identity - var addedRights = await Db.BakingRights - .Where(x => x.Level == block.Level && x.Type == BakingRightType.Baking && x.Round > maxExistedRound) - .ToListAsync(); - - CurrentRights.AddRange(addedRights); - } - #endregion - - #region remove excess - if (CurrentRights.RemoveAll(x => x.Type == BakingRightType.Baking && x.Round > block.BlockRound) > 0) - { - sql += $@" - DELETE FROM ""BakingRights"" - WHERE ""Level"" = {block.Level} - AND ""Type"" = {(int)BakingRightType.Baking} - AND ""Round"" > {block.BlockRound};"; - } - #endregion - - #region remove weird - var weirdRights = CurrentRights - .Where(x => !Cache.Accounts.DelegateExists(x.BakerId)) - .ToList(); - - if (weirdRights.Count > 0) - { - foreach (var wr in weirdRights) - CurrentRights.Remove(wr); - - sql += $@" - DELETE FROM ""BakingRights"" - WHERE ""Level"" = {block.Level} - AND ""Id"" = ANY(ARRAY[{string.Join(',', weirdRights.Select(x => x.Id))}]);"; - } - #endregion - - foreach (var cr in CurrentRights) - cr.Status = BakingRightStatus.Missed; - - CurrentRights.First(x => x.Round == block.BlockRound).Status = BakingRightStatus.Realized; - - if (Context.AttestationOps.Count != 0) - { - var attesters = new HashSet(Context.AttestationOps.Select(x => x.DelegateId)); - foreach (var ar in CurrentRights.Where(x => x.Type == BakingRightType.Attestation && attesters.Contains(x.BakerId))) - ar.Status = BakingRightStatus.Realized; - } - - var realized = CurrentRights.Where(x => x.Status == BakingRightStatus.Realized); - var missed = CurrentRights.Where(x => x.Status == BakingRightStatus.Missed); - - sql += $@" - UPDATE ""BakingRights"" - SET ""Status"" = {(int)BakingRightStatus.Realized} - WHERE ""Level"" = {block.Level} - AND ""Id"" = ANY(ARRAY[{string.Join(',', realized.Select(x => x.Id))}]);"; - - if (missed.Any()) - { - sql += $@" - UPDATE ""BakingRights"" - SET ""Status"" = {(int)BakingRightStatus.Missed} - WHERE ""Level"" = {block.Level} - AND ""Id"" = ANY(ARRAY[{string.Join(',', missed.Select(x => x.Id))}]);"; - } - } - - await Db.Database.ExecuteSqlRawAsync(sql); - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - FutureBakingRights = await GetBakingRights(block, Context.Protocol, futureCycle); - FutureAttestationRights = await GetAttestationRights(block, Context.Protocol, futureCycle); - - foreach (var ar in FutureAttestationRights) - if (!await Cache.Accounts.ExistsAsync(ar.RequiredString("delegate"))) - throw new Exception($"Account {ar.RequiredString("delegate")} doesn't exist"); - - foreach (var br in FutureBakingRights) - if (!await Cache.Accounts.ExistsAsync(br.RequiredString("delegate"))) - throw new Exception($"Account {br.RequiredString("delegate")} doesn't exist"); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@"COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") FROM STDIN (FORMAT BINARY)"); - - foreach (var ar in FutureAttestationRights) - { - // WTF: [level:28680] - Baking rights were given to non-baker account - var acc = await Cache.Accounts.GetExistingAsync(ar.RequiredString("delegate")); - - writer.StartRow(); - writer.Write(Context.Protocol.GetCycle(ar.RequiredInt32("level") + 1), NpgsqlTypes.NpgsqlDbType.Integer); // level + 1 (shifted) - writer.Write(ar.RequiredInt32("level") + 1, NpgsqlTypes.NpgsqlDbType.Integer); // level + 1 (shifted) - writer.Write(acc.Id, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.RequiredArray("slots").Count(), NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in FutureBakingRights) - { - // WTF: [level:28680] - Baking rights were given to non-baker account - var acc = await Cache.Accounts.GetExistingAsync(br.RequiredString("delegate")); - - writer.StartRow(); - writer.Write(futureCycle, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.RequiredInt32("level"), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(acc.Id, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.RequiredInt32("priority"), NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - } - - public virtual async Task Revert(Block block) - { - #region current rights - CurrentRights = await Cache.BakingRights.GetAsync(block.Level); - - foreach (var cr in CurrentRights) - cr.Status = BakingRightStatus.Future; - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "BakingRights" - SET "Status" = {0} - WHERE "Level" = {1} - """, (int)BakingRightStatus.Future, block.Level); - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" = {0} AND "Type" = {1} - OR "Level" > {2} - """, - block.Cycle + Context.Protocol.ConsensusRightsDelay, - (int)BakingRightType.Baking, - Context.Protocol.GetCycleStart(block.Cycle + Context.Protocol.ConsensusRightsDelay)); - } - #endregion - } - - protected virtual async Task> GetBakingRights(Block block, Protocol protocol, int cycle) - { - var rights = (await Proto.Rpc.GetBakingRightsAsync(block.Level, cycle)).RequiredArray().EnumerateArray(); - if (!rights.Any() || rights.Count(x => x.RequiredInt32("priority") == 0) != protocol.BlocksPerCycle) - throw new ValidationException("Rpc returned less baking rights (with priority 0) than it should be"); - - return rights; - } - - protected virtual async Task> GetAttestationRights(Block block, Protocol protocol, int cycle) - { - var rights = (await Proto.Rpc.GetAttestationRightsAsync(block.Level, cycle)).RequiredArray().EnumerateArray(); - if (!rights.Any() || rights.Sum(x => x.RequiredArray("slots").Count()) != protocol.BlocksPerCycle * protocol.AttestersPerBlock) - throw new ValidationException("Rpc returned less attestation rights (slots) than it should be"); - - return rights; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BigMapCommit.cs deleted file mode 100644 index 5b537a5a1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BigMapCommit.cs +++ /dev/null @@ -1,538 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Npgsql; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class BigMapCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public List<(BigMap, BigMapKey?, BigMapUpdate, ContractOperation)> Updates = []; - - readonly List<(ContractOperation op, Contract contract, BigMapDiff diff)> Diffs = []; - readonly Dictionary TempPtrs = new(7); - int TempPtr = 0; - - public virtual void Append(ContractOperation op, Contract contract, IEnumerable diffs) - { - foreach (var diff in diffs) - { - #region transform temp ptrs - if (diff.Ptr < 0) - { - if (diff.Action <= BigMapDiffAction.Copy) - { - TempPtrs[diff.Ptr] = --TempPtr; - diff.Ptr = TempPtr; - } - else - { - diff.Ptr = TempPtrs[diff.Ptr]; - } - } - if (diff is CopyDiff copy && copy.SourcePtr < 0) - { - copy.SourcePtr = TempPtrs[copy.SourcePtr]; - } - #endregion - Diffs.Add((op, contract, diff)); - } - } - - public virtual async Task Apply() - { - if (Diffs.Count == 0) return; - Context.Block.Events |= BlockEvents.Bigmaps; - - #region prefetch - var allocated = new HashSet(7); - var copiedFrom = new HashSet(7); - - foreach (var diff in Diffs.Where(x => x.diff.Ptr >= 0)) - { - if (diff.diff.Action == BigMapDiffAction.Alloc) - { - allocated.Add(diff.diff.Ptr); - } - else if (diff.diff is CopyDiff copy) - { - var origin = GetOrigin(copy); - if (origin < 0) - allocated.Add(diff.diff.Ptr); - else - copiedFrom.Add(origin); - } - } - - await Cache.BigMaps.Prefetch(Diffs - .Where(x => x.diff.Ptr >= 0 && !allocated.Contains(x.diff.Ptr)) - .Select(x => x.diff.Ptr)); - - await Cache.BigMapKeys.Prefetch(Diffs - .Where(x => x.diff.Ptr >= 0 && !allocated.Contains(x.diff.Ptr) && x.diff.Action == BigMapDiffAction.Update) - .Select(x => (x.diff.Ptr, (x.diff as UpdateDiff)!.KeyHash))); - - var copiedKeys = copiedFrom.Count == 0 ? [] : - await Db.BigMapKeys - .AsNoTracking() - .Where(x => copiedFrom.Contains(x.BigMapPtr)) - .ToListAsync(); - #endregion - - BigMapUpdate bigMapUpdate; - var bigMapUpdates = new List(Updates.Count); - var images = new Dictionary>(); - foreach (var diff in Diffs) - { - switch (diff.diff) - { - case AllocDiff alloc: - if (alloc.Ptr >= 0) - { - #region allocate new - var script = await Cache.Schemas.GetAsync(diff.contract); - var storage = await Cache.Storages.GetAsync(diff.contract); - var storageView = script.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); - var bigMapNode = storageView.Nodes() - .FirstOrDefault(x => x.Schema.Prim == PrimType.big_map && x.Value is MichelineInt v && v.Value == alloc.Ptr); - - if (bigMapNode == null) - { - storage = (Db.ChangeTracker.Entries() - .First(x => x.Entity is Storage s && (s.OriginationId == diff.op.Id || s.TransactionId == diff.op.Id)) - .Entity as Storage)!; - storageView = script.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); - bigMapNode = storageView.Nodes() - .FirstOrDefault(x => x.Schema.Prim == PrimType.big_map && x.Value is MichelineInt v && v.Value == alloc.Ptr) - ?? throw new Exception($"Allocated big_map {alloc.Ptr} missed in the storage"); - } - var bigMapSchema = (bigMapNode.Schema as BigMapSchema)!; - var allocatedBigMap = new BigMap - { - Id = Cache.AppState.NextBigMapId(), - Ptr = alloc.Ptr, - ContractId = diff.contract.Id, - StoragePath = bigMapNode.Path, - KeyType = bigMapSchema.Key.ToMicheline().ToBytes(), - ValueType = bigMapSchema.Value.ToMicheline().ToBytes(), - Active = true, - FirstLevel = diff.op.Level, - LastLevel = diff.op.Level, - ActiveKeys = 0, - TotalKeys = 0, - Updates = 1, - Tags = GetTags(diff.contract, bigMapNode) - }; - Db.BigMaps.Add(allocatedBigMap); - Cache.BigMaps.Add(allocatedBigMap); - - bigMapUpdate = new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.Allocate, - BigMapPtr = alloc.Ptr, - Level = diff.op.Level, - TransactionId = (diff.op as TransactionOperation)?.Id, - OriginationId = (diff.op as OriginationOperation)?.Id - }; - //Db.BigMapUpdates.Add(bigMapUpdate); - bigMapUpdates.Add(bigMapUpdate); - Updates.Add((allocatedBigMap, null, bigMapUpdate, diff.op)); - diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; - - images.Add(alloc.Ptr, []); - #endregion - } - else - { - #region alloc temp - images.Add(alloc.Ptr, []); - #endregion - } - break; - case CopyDiff copy: - if (copy.SourcePtr >= 0 && !copiedFrom.Contains(copy.SourcePtr)) - break; - if (!images.TryGetValue(copy.SourcePtr, out var src)) - { - src = copiedKeys - .Where(x => x.BigMapPtr == copy.SourcePtr) - .ToDictionary(x => x.KeyHash, x => (x.RawKey, x.RawValue)); - } - if (copy.Ptr >= 0) - { - #region copy to new - var script = await Cache.Schemas.GetAsync(diff.contract); - var storage = await Cache.Storages.GetAsync(diff.contract); - var storageView = script.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); - var bigMapNode = storageView.Nodes() - .FirstOrDefault(x => x.Schema.Prim == PrimType.big_map && x.Value is MichelineInt v && v.Value == copy.Ptr); - - if (bigMapNode == null) - { - storage = (Db.ChangeTracker.Entries() - .First(x => x.Entity is Storage s && (s.OriginationId == diff.op.Id || s.TransactionId == diff.op.Id)) - .Entity as Storage)!; - storageView = script.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); - bigMapNode = storageView.Nodes() - .FirstOrDefault(x => x.Schema.Prim == PrimType.big_map && x.Value is MichelineInt v && v.Value == copy.Ptr) - ?? throw new Exception($"Copied big_map {copy.Ptr} missed in the storage"); - } - - var bigMapSchema = (bigMapNode.Schema as BigMapSchema)!; - - var keys = src.Select(kv => - { - var rawKey = Micheline.FromBytes(kv.Value.RawKey); - var rawValue = Micheline.FromBytes(kv.Value.RawValue); - return new BigMapKey - { - Id = Cache.AppState.NextBigMapKeyId(), - BigMapPtr = copy.Ptr, - Active = true, - KeyHash = kv.Key, - JsonKey = bigMapSchema.Key.Humanize(rawKey), - JsonValue = bigMapSchema.Value.Humanize(rawValue), - RawKey = bigMapSchema.Key.Optimize(rawKey).ToBytes(), - RawValue = bigMapSchema.Value.Optimize(rawValue).ToBytes(), - FirstLevel = diff.op.Level, - LastLevel = diff.op.Level, - Updates = 1 - }; - }).ToList(); - - Db.BigMapKeys.AddRange(keys); - Cache.BigMapKeys.Add(keys); - - var copiedBigMap = new BigMap - { - Id = Cache.AppState.NextBigMapId(), - Ptr = copy.Ptr, - ContractId = diff.contract.Id, - StoragePath = bigMapNode.Path, - KeyType = bigMapSchema.Key.ToMicheline().ToBytes(), - ValueType = bigMapSchema.Value.ToMicheline().ToBytes(), - Active = true, - FirstLevel = diff.op.Level, - LastLevel = diff.op.Level, - ActiveKeys = keys.Count, - TotalKeys = keys.Count, - Updates = keys.Count + 1, - Tags = GetTags(diff.contract, bigMapNode) - }; - Db.BigMaps.Add(copiedBigMap); - Cache.BigMaps.Add(copiedBigMap); - - bigMapUpdate = new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.Allocate, - BigMapPtr = copy.Ptr, - Level = diff.op.Level, - TransactionId = (diff.op as TransactionOperation)?.Id, - OriginationId = (diff.op as OriginationOperation)?.Id - }; - //Db.BigMapUpdates.Add(bigMapUpdate); - bigMapUpdates.Add(bigMapUpdate); - Updates.Add((copiedBigMap, null, bigMapUpdate, diff.op)); - - foreach (var key in keys) - { - bigMapUpdate = new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.AddKey, - BigMapKeyId = key.Id, - BigMapPtr = key.BigMapPtr, - JsonValue = key.JsonValue, - RawValue = key.RawValue, - Level = key.FirstLevel, - TransactionId = (diff.op as TransactionOperation)?.Id, - OriginationId = (diff.op as OriginationOperation)?.Id - }; - //Db.BigMapUpdates.Add(bigMapUpdate); - bigMapUpdates.Add(bigMapUpdate); - Updates.Add((copiedBigMap, key, bigMapUpdate, diff.op)); - } - diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + keys.Count + 1; - - images.Add(copy.Ptr, keys.ToDictionary(x => x.KeyHash, x => (x.RawKey, x.RawValue))); - #endregion - } - else - { - #region copy to temp - images.Add(copy.Ptr, src.ToDictionary(x => x.Key, x => x.Value)); - #endregion - } - break; - case UpdateDiff update: - if (update.Ptr >= 0) - { - var bigMap = Cache.BigMaps.Get(update.Ptr); - - if (Cache.BigMapKeys.TryGet(update.Ptr, update.KeyHash, out var key)) - { - if (update.Value != null) - { - #region update key - Db.TryAttach(bigMap); - bigMap.LastLevel = diff.op.Level; - if (!key.Active) bigMap.ActiveKeys++; - bigMap.Updates++; - - Db.TryAttach(key); - key.Active = true; - key.JsonValue = bigMap.Schema.Value.Humanize(update.Value); - key.RawValue = bigMap.Schema.Value.Optimize(update.Value).ToBytes(); - key.LastLevel = diff.op.Level; - key.Updates++; - - bigMapUpdate = new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.UpdateKey, - BigMapKeyId = key.Id, - BigMapPtr = key.BigMapPtr, - JsonValue = key.JsonValue, - RawValue = key.RawValue, - Level = key.LastLevel, - TransactionId = (diff.op as TransactionOperation)?.Id, - OriginationId = (diff.op as OriginationOperation)?.Id - }; - //Db.BigMapUpdates.Add(bigMapUpdate); - bigMapUpdates.Add(bigMapUpdate); - Updates.Add((bigMap, key, bigMapUpdate, diff.op)); - diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; - #endregion - } - else if (key.Active) // WTF: edo2net:76611 - key was removed twice - { - #region remove key - Db.TryAttach(bigMap); - bigMap.LastLevel = diff.op.Level; - bigMap.ActiveKeys--; - bigMap.Updates++; - - Db.TryAttach(key); - key.Active = false; - key.LastLevel = diff.op.Level; - key.Updates++; - - bigMapUpdate = new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.RemoveKey, - BigMapKeyId = key.Id, - BigMapPtr = key.BigMapPtr, - JsonValue = key.JsonValue, - RawValue = key.RawValue, - Level = key.LastLevel, - TransactionId = (diff.op as TransactionOperation)?.Id, - OriginationId = (diff.op as OriginationOperation)?.Id - }; - //Db.BigMapUpdates.Add(bigMapUpdate); - bigMapUpdates.Add(bigMapUpdate); - Updates.Add((bigMap, key, bigMapUpdate, diff.op)); - diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; - #endregion - } - } - else if (update.Value != null) // WTF: edo2net:34839 - non-existent key was removed - { - #region add key - Db.TryAttach(bigMap); - bigMap.LastLevel = diff.op.Level; - bigMap.ActiveKeys++; - bigMap.TotalKeys++; - bigMap.Updates++; - - key = new BigMapKey - { - Id = Cache.AppState.NextBigMapKeyId(), - Active = true, - BigMapPtr = update.Ptr, - FirstLevel = diff.op.Level, - LastLevel = diff.op.Level, - JsonKey = bigMap.Schema.Key.Humanize(update.Key), - JsonValue = bigMap.Schema.Value.Humanize(update.Value), - RawKey = bigMap.Schema.Key.Optimize(update.Key).ToBytes(), - RawValue = bigMap.Schema.Value.Optimize(update.Value).ToBytes(), - KeyHash = update.KeyHash, - Updates = 1 - }; - - Db.BigMapKeys.Add(key); - Cache.BigMapKeys.Add(key); - - bigMapUpdate = new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.AddKey, - BigMapKeyId = key.Id, - BigMapPtr = key.BigMapPtr, - JsonValue = key.JsonValue, - RawValue = key.RawValue, - Level = key.LastLevel, - TransactionId = (diff.op as TransactionOperation)?.Id, - OriginationId = (diff.op as OriginationOperation)?.Id - }; - //Db.BigMapUpdates.Add(bigMapUpdate); - bigMapUpdates.Add(bigMapUpdate); - Updates.Add((bigMap, key, bigMapUpdate, diff.op)); - diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; - #endregion - } - } - else - { - #region update temp - if (!images.TryGetValue(update.Ptr, out var image)) - throw new Exception("Can't update non-existent temporary big_map"); - - if (image.TryGetValue(update.KeyHash, out var key)) - { - if (update.Value != null) - { - image[update.KeyHash] = (key.RawKey, update.Value.ToBytes()); - } - else - { - image.Remove(update.KeyHash); - } - } - else if (update.Value != null) // WTF: edo2net:34839 - non-existent key was removed - { - image.Add(update.KeyHash, (update.Key.ToBytes(), update.Value.ToBytes())); - } - #endregion - } - break; - case RemoveDiff remove: - if (remove.Ptr >= 0) - { - var removedBigMap = Cache.BigMaps.Get(remove.Ptr); - - Db.TryAttach(removedBigMap); - removedBigMap.Active = false; - removedBigMap.LastLevel = diff.op.Level; - removedBigMap.Updates++; - - bigMapUpdate = new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.Remove, - BigMapPtr = remove.Ptr, - Level = diff.op.Level, - TransactionId = (diff.op as TransactionOperation)?.Id, - OriginationId = (diff.op as OriginationOperation)?.Id - }; - //Db.BigMapUpdates.Add(bigMapUpdate); - bigMapUpdates.Add(bigMapUpdate); - Updates.Add((removedBigMap, null, bigMapUpdate, diff.op)); - diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; - } - break; - default: - break; - } - } - if (bigMapUpdates.Count != 0) - BigMapUpdate.Write((Db.Database.GetDbConnection() as NpgsqlConnection)!, bigMapUpdates); - } - - int GetOrigin(CopyDiff copy) - { - return Diffs - .FirstOrDefault(x => x.diff.Action == BigMapDiffAction.Copy && x.diff.Ptr == copy.SourcePtr).diff is CopyDiff prevCopy - ? GetOrigin(prevCopy) - : copy.SourcePtr; - } - - protected virtual BigMapTag GetTags(Contract contract, TreeView node) => BigMaps.GetTags(contract, node); - - public virtual async Task Revert(Block block) - { - if (block.Events.HasFlag(BlockEvents.Bigmaps)) - { - var bigmaps = await Db.BigMaps.Where(x => x.LastLevel == block.Level).ToListAsync(); - var keys = await Db.BigMapKeys.Where(x => x.LastLevel == block.Level).ToListAsync(); - var updates = await Db.BigMapUpdates - .AsNoTracking() - .Where(x => x.Level == block.Level) - .Select(x => new - { - Ptr = x.BigMapPtr, - KeyId = x.BigMapKeyId - }) - .ToListAsync(); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BigMapUpdates" - WHERE "Level" = {0} - """, block.Level); - Cache.AppState.ReleaseBigMapUpdateId(updates.Count); - - foreach (var key in keys) - { - var bigmap = bigmaps.First(x => x.Ptr == key.BigMapPtr); - Cache.BigMaps.Add(bigmap); - Cache.BigMapKeys.Add(key); - - if (key.FirstLevel == block.Level) - { - if (key.Active) bigmap.ActiveKeys--; - bigmap.TotalKeys--; - Db.BigMapKeys.Remove(key); - Cache.BigMapKeys.Remove(key); - Cache.AppState.ReleaseBigMapKeyId(); - } - else - { - var prevUpdate = await Db.BigMapUpdates - .Where(x => x.BigMapKeyId == key.Id) - .OrderByDescending(x => x.Id) - .FirstAsync(); - - var prevActive = prevUpdate.Action != BigMapAction.RemoveKey; - if (key.Active && !prevActive) - bigmap.ActiveKeys--; - else if (!key.Active && prevActive) - bigmap.ActiveKeys++; - - key.Active = prevActive; - key.JsonValue = prevUpdate.JsonValue!; - key.RawValue = prevUpdate.RawValue!; - key.LastLevel = prevUpdate.Level; - key.Updates -= updates.Count(x => x.KeyId == key.Id); - } - } - - foreach (var bigmap in bigmaps) - { - Cache.BigMaps.Add(bigmap); - if (bigmap.FirstLevel == block.Level) - { - Db.BigMaps.Remove(bigmap); - Cache.BigMaps.Remove(bigmap); - Cache.AppState.ReleaseBigMapId(); - } - else - { - bigmap.Active = true; - bigmap.Updates -= updates.Count(x => x.Ptr == bigmap.Ptr); - bigmap.LastLevel = bigmap.Updates > 1 - ? (await Db.BigMapUpdates - .Where(x => x.BigMapPtr == bigmap.Ptr) - .OrderByDescending(x => x.Id) - .FirstAsync()) - .Level - : bigmap.FirstLevel; - } - } - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BlockCommit.cs deleted file mode 100644 index 2be46cf7a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/BlockCommit.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class BlockCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Block Block { get; private set; } = null!; - - public virtual async Task Apply(JsonElement rawBlock) - { - var level = rawBlock.Required("header").RequiredInt32("level"); - var protocol = await Cache.Protocols.GetAsync(rawBlock.RequiredString("protocol")); - var events = BlockEvents.None; - - var metadata = rawBlock.Required("metadata"); - var (deposit, reward) = ParseBalanceUpdates(metadata.RequiredArray("balance_updates")); - - if (protocol.IsCycleStart(level)) - events |= BlockEvents.CycleBegin; - else if (protocol.IsCycleEnd(level)) - events |= BlockEvents.CycleEnd; - - if (protocol.FirstLevel == level) - events |= BlockEvents.ProtocolBegin; - else if (metadata.RequiredString("protocol") != metadata.RequiredString("next_protocol")) - events |= BlockEvents.ProtocolEnd; - - if (metadata.RequiredArray("deactivated").Count() > 0) - events |= BlockEvents.Deactivations; - - if (level % protocol.BlocksPerSnapshot == 0) - events |= BlockEvents.BalanceSnapshot; - - var round = rawBlock.Required("header").RequiredInt32("priority"); - var baker = Cache.Accounts.GetExistingDelegate(rawBlock.Required("metadata").RequiredString("baker")); - Block = new Block - { - Id = Cache.AppState.NextOperationId(), - Hash = rawBlock.RequiredString("hash"), - Cycle = protocol.GetCycle(level), - Level = level, - ProtoCode = protocol.Code, - Timestamp = rawBlock.Required("header").RequiredDateTime("timestamp"), - AttestationCommittee = protocol.AttestersPerBlock, - PayloadRound = round, - BlockRound = round, - ProposerId = baker.Id, - ProducerId = baker.Id, - Events = events, - RewardDelegated = reward, - Deposit = deposit, - LBToggle = GetLBToggleVote(rawBlock), - LBToggleEma = GetLBToggleEma(rawBlock) - }; - - Context.Block = Block; - Context.Proposer = baker; - Context.Protocol = protocol; - - #region entities - Db.TryAttach(protocol); - Db.TryAttach(baker); - #endregion - - ReceiveLockedRewards(baker, Block.RewardDelegated); - baker.BlocksCount++; - - var newDeactivationLevel = baker.Staked ? GracePeriod.Reset(Block.Level, protocol) : GracePeriod.Init(Block.Level, protocol); - if (baker.DeactivationLevel < newDeactivationLevel) - { - if (baker.DeactivationLevel <= Block.Level) - await ActivateBaker(baker); - - Block.ResetBakerDeactivation = baker.DeactivationLevel; - baker.DeactivationLevel = newDeactivationLevel; - } - - if (Block.Events.HasFlag(BlockEvents.ProtocolEnd)) - protocol.LastLevel = Block.Level; - - Cache.AppState.Get().BlocksCount++; - Cache.Statistics.Current.TotalCreated += Block.RewardDelegated; - Cache.Statistics.Current.TotalFrozen += Block.RewardDelegated + Block.Deposit + Block.Fees; - - Db.Blocks.Add(Block); - Cache.Blocks.Add(Block); - } - - public virtual async Task Revert(Block block) - { - Block = block; - - #region entities - var baker = Context.Proposer; - Db.TryAttach(baker); - #endregion - - RevertReceiveLockedRewards(baker, Block.RewardDelegated); - baker.BlocksCount--; - - if (Block.ResetBakerDeactivation != null) - { - if (Block.ResetBakerDeactivation <= Block.Level) - await DeactivateBaker(baker); - - baker.DeactivationLevel = (int)Block.ResetBakerDeactivation; - } - - Cache.AppState.Get().BlocksCount--; - - Db.Blocks.Remove(Block); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual (long, long) ParseBalanceUpdates(JsonElement balanceUpdates) - { - var deposit = 0L; - var reward = 0L; - foreach (var bu in balanceUpdates.EnumerateArray().Take(3)) - { - if (bu.RequiredString("kind")[0] == 'f') - { - var change = bu.RequiredInt64("change"); - if (change > 0) - { - if (bu.RequiredString("category")[0] == 'd') - deposit = change; - else - reward = change; - } - - } - } - return (deposit, reward); - } - - protected virtual bool? GetLBToggleVote(JsonElement block) => null; - - protected virtual int GetLBToggleEma(JsonElement block) => 0; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/CycleCommit.cs deleted file mode 100644 index 8b4348657..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/CycleCommit.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class CycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Cycle? FutureCycle { get; protected set; } - public List? BakerSnapshots { get; protected set; } - - public virtual async Task Apply(Block block) - { - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - var lastSeed = await Db.Cycles - .AsNoTracking() - .Where(x => x.Index == futureCycle - 1) - .Select(x => x.Seed) - .FirstOrDefaultAsync() - ?? throw new Exception($"Seed for cycle {futureCycle - 1} is missed"); - - var nonces = block.Cycle < 2 ? [] : await Db.NonceRevelationOps - .AsNoTracking() - .Where(x => x.RevealedCycle == block.Cycle - 2) - .OrderByDescending(x => x.RevealedLevel) - .Select(x => x.Nonce) - .ToListAsync(); - - var futureSeed = Seed.GetNextSeed(lastSeed, nonces, null); - var snapshotIndex = 0; - var snapshotLevel = 1; - var snapshotProto = await Cache.Protocols.FindByCycleAsync(Math.Max(block.Cycle - 2, 0)); - - if (block.Cycle >= 2) - { - snapshotIndex = Seed.GetSnapshotIndex(futureSeed, snapshotProto.SnapshotsPerCycle); - snapshotLevel = snapshotProto.GetCycleStart(block.Cycle - 2) - 1 + (snapshotIndex + 1) * snapshotProto.BlocksPerSnapshot; - } - - BakerSnapshots = await Db.SnapshotBalances - .AsNoTracking() - .Where(x => x.Level == snapshotLevel && x.BakerId == x.AccountId) - .ToListAsync(); - - FutureCycle = new Cycle - { - Id = 0, - Index = futureCycle, - FirstLevel = Context.Protocol.GetCycleStart(futureCycle), - LastLevel = Context.Protocol.GetCycleEnd(futureCycle), - SnapshotLevel = snapshotLevel, - TotalBakers = BakerSnapshots.Count(x => x.StakingBalance >= snapshotProto.MinimalStake), - TotalBakingPower = BakerSnapshots.Sum(x => x.StakingBalance - x.StakingBalance % snapshotProto.MinimalStake), - Seed = futureSeed - }; - - Db.Cycles.Add(FutureCycle); - } - } - - public virtual async Task Revert(Block block) - { - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Cycles" - WHERE "Index" = {0} - """, futureCycle); - } - } - - public class DelegateSnapshot - { - public long StakingBalance { get; set; } - public long DelegatedBalance { get; set; } - public int DelegatorsCount { get; set; } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 423eab9aa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class DelegatorCycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, Cycle? futureCycle) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - await CreateFromSnapshots(futureCycle!); - - #region weird delegators - if (block.Cycle > 0) - { - //one-way change... - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "DelegatorCycles" as dc - USING "Accounts" as acc - WHERE acc."Id" = dc."BakerId" - AND dc."Cycle" = {0} - AND acc."Type" != {1} - """, block.Cycle - 1, (int)AccountType.Delegate); - } - #endregion - } - - public virtual async Task Revert(Block block) - { - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "DelegatorCycles" - WHERE "Cycle" = {0} - """, futureCycle); - } - } - - protected virtual Task CreateFromSnapshots(Cycle futureCycle) - { - return Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "DelegatorCycles" ( - "Cycle", - "DelegatorId", - "BakerId", - "DelegatedBalance", - "StakedPseudotokens" - ) - SELECT - {0}, - "AccountId", - "BakerId", - "OwnDelegatedBalance", - "Pseudotokens" - FROM "SnapshotBalances" - WHERE "Level" = {1} - AND "BakerId" != "AccountId" - """, futureCycle.Index, futureCycle.SnapshotLevel); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/FreezerCommit.cs deleted file mode 100644 index 2357fa16c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/FreezerCommit.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class FreezerCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public void Apply(Block block, JsonElement rawBlock) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - foreach (var update in GetFreezerUpdates(block, Context.Protocol, rawBlock)) - { - var change = update.RequiredInt64("change"); - switch (update.RequiredString("category")[0]) - { - case 'd': - break; - case 'r': - var delegat = Cache.Accounts.GetExistingDelegate(update.RequiredString("delegate")); - Db.TryAttach(delegat); - UnlockRewards(delegat, -change); - break; - case 'f': - break; - default: - throw new Exception("unexpected freezer balance update type"); - } - - Cache.Statistics.Current.TotalFrozen += change; - } - - return; - } - - public async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - var rawBlock = await Proto.Rpc.GetBlockAsync(block.Level); - - foreach (var update in GetFreezerUpdates(block, Context.Protocol, rawBlock)) - { - var change = update.RequiredInt64("change"); - switch (update.RequiredString("category")[0]) - { - case 'd': - break; - case 'r': - var delegat = Cache.Accounts.GetExistingDelegate(update.RequiredString("delegate")); - Db.TryAttach(delegat); - RevertUnlockRewards(delegat, -change); - break; - case 'f': - break; - default: - throw new Exception("unexpected freezer balance update type"); - } - } - } - - protected virtual int GetFreezerCycle(JsonElement el) => el.RequiredInt32("level"); - - protected virtual IEnumerable GetFreezerUpdates(Block block, Protocol protocol, JsonElement rawBlock) - { - return rawBlock - .Required("metadata") - .Required("balance_updates") - .EnumerateArray() - .Where(x => x.RequiredString("kind")[0] == 'f' && - x.RequiredInt64("change") < 0 && - GetFreezerCycle(x) == block.Cycle - protocol.ConsensusRightsDelay); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 5aabaf3ef..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class ActivationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = (User)await Cache.Accounts.GetOrCreateAsync(content.RequiredString("pkh")); - - var activatedBalance = content - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .Single(x => x.RequiredString("kind") == "contract" && x.RequiredString("contract") == sender.Address) - .RequiredInt64("change"); - - var activation = new ActivationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - AccountId = sender.Id, - Balance = activatedBalance - }; - - var btz = Blind.GetBlindedAddress(content.RequiredString("pkh"), content.RequiredString("secret")); - var commitment = await Db.Commitments.FirstAsync(x => x.Address == btz); - #endregion - - #region apply operation - Db.TryAttach(sender); - Receive(sender, activation.Balance); - sender.ActivationsCount++; - - block.Operations |= Operations.Activations; - - commitment.AccountId = sender.Id; - commitment.Level = block.Level; - - Cache.AppState.Get().ActivationOpsCount++; - Cache.Statistics.Current.TotalActivated += activation.Balance; - #endregion - - Db.ActivationOps.Add(activation); - Context.ActivationOps.Add(activation); - } - - public virtual async Task Revert(Block block, ActivationOperation activation) - { - #region entities - var sender = (User)await Cache.Accounts.GetAsync(activation.AccountId); - var commitment = await Db.Commitments.FirstAsync(x => x.AccountId == activation.AccountId); - #endregion - - #region revert operation - Db.TryAttach(sender); - RevertReceive(sender, activation.Balance); - sender.ActivationsCount--; - - commitment.AccountId = null; - commitment.Level = null; - - Cache.AppState.Get().ActivationOpsCount--; - #endregion - - Db.ActivationOps.Remove(activation); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index a97599753..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class AttestationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var metadata = content.Required("metadata"); - var reward = metadata - .RequiredArray("balance_updates") - .EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind")[0] == 'f' && x.RequiredString("category")[0] == 'r'); - var deposit = metadata - .RequiredArray("balance_updates") - .EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind")[0] == 'f' && x.RequiredString("category")[0] == 'd'); - - var sender = Cache.Accounts.GetExistingDelegate(metadata.RequiredString("delegate")); - - var attestation = new AttestationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - Power = metadata.RequiredArray("slots").Count(), - DelegateId = sender.Id, - Reward = reward.ValueKind != JsonValueKind.Undefined ? reward.RequiredInt64("change") : 0, - Deposit = deposit.ValueKind != JsonValueKind.Undefined ? deposit.RequiredInt64("change") : 0 - }; - #endregion - - #region entities - Db.TryAttach(sender); - #endregion - - #region apply operation - ReceiveLockedRewards(sender, attestation.Reward); - - sender.AttestationsCount++; - - block.Operations |= Operations.Attestations; - block.AttestationPower += attestation.Power; - - var newDeactivationLevel = sender.Staked ? GracePeriod.Reset(attestation.Level, Context.Protocol) : GracePeriod.Init(attestation.Level, Context.Protocol); - if (sender.DeactivationLevel < newDeactivationLevel) - { - if (sender.DeactivationLevel <= attestation.Level) - await ActivateBaker(sender); - - attestation.ResetDeactivation = sender.DeactivationLevel; - sender.DeactivationLevel = newDeactivationLevel; - } - - Cache.AppState.Get().AttestationOpsCount++; - Cache.Statistics.Current.TotalCreated += attestation.Reward; - Cache.Statistics.Current.TotalFrozen += attestation.Reward + attestation.Deposit; - #endregion - - //Db.AttestationOps.Add(attestation); - Context.AttestationOps.Add(attestation); - } - - public virtual async Task Revert(Block block, AttestationOperation attestation) - { - #region entities - var sender = Cache.Accounts.GetDelegate(attestation.DelegateId); - Db.TryAttach(sender); - #endregion - - #region revert operation - RevertReceiveLockedRewards(sender, attestation.Reward); - - sender.AttestationsCount--; - - if (attestation.ResetDeactivation != null) - { - if (attestation.ResetDeactivation <= attestation.Level) - await DeactivateBaker(sender); - - sender.DeactivationLevel = (int)attestation.ResetDeactivation; - } - - Cache.AppState.Get().AttestationOpsCount--; - #endregion - - //Db.AttestationOps.Remove(attestation); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 1c2e1e1d9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,441 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class DelegationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var prevDelegate = sender.DelegateId is int senderDelegateId - ? await Cache.Accounts.GetAsync(senderDelegateId) as Data.Models.Delegate - : sender as Data.Models.Delegate; - var newDelegate = content.OptionalString("delegate") is string _delegateAddress - ? await Cache.Accounts.GetOrCreateAsync(_delegateAddress) - : null; - - var result = content.Required("metadata").Required("operation_result"); - - var delegation = new DelegationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = Context.Block.Level, - Timestamp = Context.Block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - DelegateId = newDelegate?.Id, - PrevDelegateId = prevDelegate?.Id, - Amount = sender.Balance - content.RequiredInt64("fee"), - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = GetConsumedGas(result) - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, delegation.BakerFee); - sender.LastLevel = delegation.Level; - sender.Counter = delegation.Counter; - sender.DelegationsCount++; - - if (prevDelegate != null) - { - Db.TryAttach(prevDelegate); - prevDelegate.LastLevel = delegation.Level; - if (prevDelegate != sender) - prevDelegate.DelegationsCount++; - } - - if (newDelegate != null) - { - Db.TryAttach(newDelegate); - newDelegate.LastLevel = delegation.Level; - if (newDelegate != sender && newDelegate != prevDelegate) - newDelegate.DelegationsCount++; - } - - Context.Block.Operations |= Operations.Delegations; - - Cache.AppState.Get().DelegationOpsCount++; - #endregion - - #region apply result - if (delegation.Status == OperationStatus.Applied) - { - if (sender is Data.Models.Delegate baker) - { - #region reactivate baker - if (baker.DeactivationLevel <= delegation.Level) - await ActivateBaker(baker); - - delegation.PrevDeactivationLevel = baker.DeactivationLevel; - baker.DeactivationLevel = GracePeriod.Init(Context.Block.Level, Context.Protocol); - #endregion - } - else - { - if (prevDelegate != null) - { - #region reset current delegation - if (result.TryGetProperty("balance_updates", out var updates)) - await Unstake(delegation, [.. updates.EnumerateArray()]); - - delegation.PrevDelegationLevel = sender.DelegationLevel; - - Undelegate(sender, prevDelegate); - #endregion - } - - if (sender == newDelegate) - { - #region register baker - sender = newDelegate = RegisterBaker((sender as User)!); - - if (sender.OriginationsCount != 0) - { - var weirdOriginations = await Db.OriginationOps - .AsNoTracking() - .Where(x => x.DelegateId == sender.Id && x.Status == OperationStatus.Applied) - .ToListAsync(); - - foreach (var origination in weirdOriginations) - { - var weirdDelegator = await Cache.Accounts.GetAsync(origination.ContractId!.Value); - var hasDelegated = await Db.DelegationOps - .AsNoTracking() - .Where(x => x.SenderId == weirdDelegator.Id && x.Status == OperationStatus.Applied) - .AnyAsync(); - - if (!hasDelegated) - { - Db.TryAttach(weirdDelegator); - weirdDelegator.LastLevel = delegation.Level; - Delegate(weirdDelegator, (sender as Data.Models.Delegate)!, origination.Level); - } - } - } - #endregion - } - else if (newDelegate is Data.Models.Delegate _newDelegate) - { - Delegate(sender, _newDelegate, delegation.Level); - } - } - } - #endregion - - Proto.Manager.Set(sender); - Db.DelegationOps.Add(delegation); - Context.DelegationOps.Add(delegation); - } - - public virtual async Task ApplyInternal(Block block, ManagerOperation parent, JsonElement content) - { - #region init - var initiator = await Cache.Accounts.GetAsync(parent.SenderId); - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var prevDelegate = sender.DelegateId is int senderDelegateId - ? await Cache.Accounts.GetAsync(senderDelegateId) as Data.Models.Delegate - : null; - var newDelegate = content.OptionalString("delegate") is string _delegateAddress - ? await Cache.Accounts.GetOrCreateAsync(_delegateAddress) - : null; - - var result = content.Required("result"); - - var delegation = new DelegationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = parent.Level, - Timestamp = parent.Timestamp, - OpHash = parent.OpHash, - Counter = parent.Counter, - Nonce = content.RequiredInt32("nonce"), - InitiatorId = initiator.Id, - SenderId = sender.Id, - SenderCodeHash = (sender as Contract)?.CodeHash, - DelegateId = newDelegate?.Id, - PrevDelegateId = prevDelegate?.Id, - Amount = sender.Balance, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = GetConsumedGas(result) - }; - #endregion - - #region apply operation - if (parent is TransactionOperation parentTx) - { - parentTx.InternalOperations = (short?)((parentTx.InternalOperations ?? 0) + 1); - parentTx.InternalDelegations = (short?)((parentTx.InternalDelegations ?? 0) + 1); - } - - Db.TryAttach(sender); - sender.LastLevel = delegation.Level; - sender.DelegationsCount++; - - if (prevDelegate != null) - { - Db.TryAttach(prevDelegate); - prevDelegate.LastLevel = delegation.Level; - if (prevDelegate != sender) - prevDelegate.DelegationsCount++; - } - - if (newDelegate != null) - { - Db.TryAttach(newDelegate); - newDelegate.LastLevel = delegation.Level; - if (newDelegate != sender && newDelegate != prevDelegate) - newDelegate.DelegationsCount++; - } - - if (initiator != sender && initiator != prevDelegate && initiator != newDelegate) - { - initiator.DelegationsCount++; - } - - Context.Block.Operations |= Operations.Delegations; - - Cache.AppState.Get().DelegationOpsCount++; - #endregion - - #region apply result - if (delegation.Status == OperationStatus.Applied) - { - if (prevDelegate != null) - { - #region reset current delegation - //if (result.TryGetProperty("balance_updates", out var updates)) - // await Unstake(delegation, [.. updates.EnumerateArray()]); - - delegation.PrevDelegationLevel = sender.DelegationLevel; - - Undelegate(sender, prevDelegate); - #endregion - } - - if (newDelegate is Data.Models.Delegate _newDelegate) - { - Delegate(sender, _newDelegate, delegation.Level); - } - } - #endregion - - Db.DelegationOps.Add(delegation); - Context.DelegationOps.Add(delegation); - } - - public virtual async Task Revert(Block block, DelegationOperation delegation) - { - #region init - var sender = await Cache.Accounts.GetAsync(delegation.SenderId); - var prevDelegate = delegation.PrevDelegateId is int prevDelegateId - ? await Cache.Accounts.GetAsync(prevDelegateId) as Data.Models.Delegate - : null; - var newDelegate = delegation.DelegateId is int delegateId - ? await Cache.Accounts.GetAsync(delegateId) - : null; - - Db.TryAttach(sender); - Db.TryAttach(prevDelegate); - Db.TryAttach(newDelegate); - #endregion - - #region revert result - if (delegation.Status == OperationStatus.Applied) - { - if (sender is Data.Models.Delegate baker) - { - if (delegation.PrevDeactivationLevel is int prevDeactivationLevel) - { - #region deactivate baker - if (delegation.PrevDeactivationLevel <= delegation.Level) - await DeactivateBaker(baker); - - baker.DeactivationLevel = prevDeactivationLevel; - #endregion - } - else - { - #region unregister baker - if (baker.DelegatorsCount != 0) - { - var weirdOriginations = await Db.OriginationOps - .AsNoTracking() - .Where(x => x.DelegateId == baker.Id && x.Status == OperationStatus.Applied) - .ToListAsync(); - - foreach (var origination in weirdOriginations) - { - var weirdDelegator = await Cache.Accounts.GetAsync(origination.ContractId!.Value); - var delegated = await Db.DelegationOps - .AsNoTracking() - .Where(x => x.SenderId == weirdDelegator.Id && x.Status == OperationStatus.Applied) - .AnyAsync(); - - if (!delegated) - { - Db.TryAttach(weirdDelegator); - weirdDelegator.LastLevel = delegation.Level; - Undelegate(weirdDelegator, baker); - } - } - } - - sender = newDelegate = UnregisterBaker(baker); - - if (prevDelegate != null) - { - Delegate(sender, prevDelegate, delegation.PrevDelegationLevel!.Value); - await RevertUnstake(delegation); - } - #endregion - } - } - else - { - if (newDelegate is Data.Models.Delegate _newDelegate) - { - Undelegate(sender, _newDelegate); - } - - if (prevDelegate != null) - { - Delegate(sender, prevDelegate, delegation.PrevDelegationLevel!.Value); - await RevertUnstake(delegation); - } - } - } - #endregion - - #region revert operation - RevertPayFee(sender, delegation.BakerFee); - sender.LastLevel = delegation.Level; - sender.Counter = delegation.Counter - 1; - if (sender is User user) user.Revealed = true; - sender.DelegationsCount--; - - if (prevDelegate != null) - { - prevDelegate.LastLevel = delegation.Level; - if (prevDelegate != sender) - prevDelegate.DelegationsCount--; - } - - if (newDelegate != null) - { - newDelegate.LastLevel = delegation.Level; - if (newDelegate != sender && newDelegate != prevDelegate) - newDelegate.DelegationsCount--; - } - - Cache.AppState.Get().DelegationOpsCount--; - #endregion - - Db.DelegationOps.Remove(delegation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - public virtual async Task RevertInternal(Block block, DelegationOperation delegation) - { - #region init - var initiator = await Cache.Accounts.GetAsync(delegation.InitiatorId!.Value); - var sender = await Cache.Accounts.GetAsync(delegation.SenderId); - var prevDelegate = delegation.PrevDelegateId is int prevDelegateId - ? await Cache.Accounts.GetAsync(prevDelegateId) as Data.Models.Delegate - : null; - var newDelegate = delegation.DelegateId is int delegateId - ? await Cache.Accounts.GetAsync(delegateId) - : null; - - Db.TryAttach(initiator); - Db.TryAttach(sender); - Db.TryAttach(prevDelegate); - Db.TryAttach(newDelegate); - #endregion - - #region revert result - if (delegation.Status == OperationStatus.Applied) - { - if (newDelegate is Data.Models.Delegate _newDelegate) - { - Undelegate(sender, _newDelegate); - } - - if (prevDelegate != null) - { - Delegate(sender, prevDelegate, delegation.PrevDelegationLevel!.Value); - //await RevertUnstake(delegation); - } - } - #endregion - - #region revert operation - sender.LastLevel = delegation.Level; - sender.DelegationsCount--; - - if (prevDelegate != null) - { - prevDelegate.LastLevel = delegation.Level; - if (prevDelegate != sender) - prevDelegate.DelegationsCount--; - } - - if (newDelegate != null) - { - newDelegate.LastLevel = delegation.Level; - if (newDelegate != sender && newDelegate != prevDelegate) - newDelegate.DelegationsCount--; - } - - if (initiator != sender && initiator != prevDelegate && initiator != newDelegate) - { - initiator.DelegationsCount--; - } - - Cache.AppState.Get().DelegationOpsCount--; - #endregion - - Db.DelegationOps.Remove(delegation); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual int GetConsumedGas(JsonElement result) - { - return result.OptionalInt32("consumed_gas") ?? 0; - } - - protected virtual Task Unstake(DelegationOperation op, List balanceUpdates) => Task.CompletedTask; - - protected virtual Task RevertUnstake(DelegationOperation op) => Task.CompletedTask; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 3fffca4d6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class NonceRevelationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var balanceUpdate = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind") == "freezer" && x.RequiredString("category") == "rewards"); - - var reward = balanceUpdate.ValueKind != JsonValueKind.Undefined - ? balanceUpdate.RequiredInt64("change") - : 0; - - var revealedBlock = await Cache.Blocks.GetAsync(content.RequiredInt32("level")); - var sender = Cache.Accounts.GetDelegate(revealedBlock.ProposerId!.Value); - - var revelation = new NonceRevelationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerId = Context.Proposer.Id, - SenderId = sender.Id, - RevealedLevel = revealedBlock.Level, - RevealedCycle = revealedBlock.Cycle, - Nonce = Hex.Parse(content.RequiredString("nonce")), - RewardDelegated = reward - }; - #endregion - - #region entities - var blockBaker = Context.Proposer; - - //Db.TryAttach(blockBaker); - Db.TryAttach(sender); - Db.TryAttach(revealedBlock); - #endregion - - #region apply operation - ReceiveLockedRewards(blockBaker, revelation.RewardDelegated); - - sender.NonceRevelationsCount++; - if (blockBaker != sender) blockBaker.NonceRevelationsCount++; - - block.Operations |= Operations.Revelations; - - revealedBlock.RevelationId = revelation.Id; - - Cache.AppState.Get().NonceRevelationOpsCount++; - Cache.Statistics.Current.TotalCreated += revelation.RewardDelegated; - Cache.Statistics.Current.TotalFrozen += revelation.RewardDelegated; - #endregion - - Db.NonceRevelationOps.Add(revelation); - Context.NonceRevelationOps.Add(revelation); - } - - public virtual async Task Revert(Block block, NonceRevelationOperation revelation) - { - #region entities - var blockBaker = Context.Proposer; - var sender = Cache.Accounts.GetDelegate(revelation.SenderId); - var revealedBlock = await Cache.Blocks.GetAsync(revelation.RevealedLevel); - - //Db.TryAttach(blockBaker); - Db.TryAttach(sender); - Db.TryAttach(revealedBlock); - #endregion - - #region apply operation - RevertReceiveLockedRewards(blockBaker, revelation.RewardDelegated); - - sender.NonceRevelationsCount--; - if (blockBaker != sender) blockBaker.NonceRevelationsCount--; - - revealedBlock.RevelationId = null; - - Cache.AppState.Get().NonceRevelationOpsCount--; - #endregion - - Db.NonceRevelationOps.Remove(revelation); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 51760b1ec..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,736 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; - -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class OriginationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public OriginationOperation Origination { get; private set; } = null!; - public IEnumerable? BigMapDiffs { get; private set; } - public Contract? Contract { get; private set; } - - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var contractDelegate = content.OptionalString("delegate") is string _delegateAddress - ? await Cache.Accounts.GetOrCreateAsync(_delegateAddress) - : null; - - var result = content.Required("metadata").Required("operation_result"); - - var origination = new OriginationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - Balance = content.RequiredInt64("balance"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - DelegateId = contractDelegate?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = GetConsumedGas(result), - StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, - StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 - ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost - : null, - AllocationFee = Context.Protocol.OriginationSize * Context.Protocol.ByteCost - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, origination.BakerFee); - sender.LastLevel = origination.Level; - sender.Counter = origination.Counter; - sender.OriginationsCount++; - - if (contractDelegate != null) - { - Db.TryAttach(contractDelegate); - contractDelegate.LastLevel = block.Level; - if (contractDelegate != sender) - contractDelegate.OriginationsCount++; - } - - Context.Block.Operations |= Operations.Originations; - - Cache.AppState.Get().OriginationOpsCount++; - #endregion - - #region apply result - if (origination.Status == OperationStatus.Applied) - { - var burned = (origination.StorageFee ?? 0) + (origination.AllocationFee ?? 0); - Proto.Manager.Burn(burned); - - Spend(sender, origination.Balance + burned); - sender.ContractsCount++; - - Contract? contract; - var contractAddress = result.RequiredArray("originated_contracts", 1)[0].RequiredString(); - var ghost = await Cache.Accounts.GetAsync(contractAddress); - if (ghost != null) - { - contract = new Contract - { - Id = ghost.Id, - Index = ghost.Index, - FirstLevel = ghost.FirstLevel, - LastLevel = origination.Level, - Address = contractAddress, - CreatorId = sender.Id, - Type = AccountType.Contract, - Kind = ContractKind.SmartContract, - OriginationsCount = 1, - ActiveTokensCount = ghost.ActiveTokensCount, - TokenBalancesCount = ghost.TokenBalancesCount, - TokenTransfersCount = ghost.TokenTransfersCount, - ActiveTicketsCount = ghost.ActiveTicketsCount, - TicketBalancesCount = ghost.TicketBalancesCount, - TicketTransfersCount = ghost.TicketTransfersCount - }; - Db.Entry(ghost).State = EntityState.Detached; - Db.Entry(contract).State = EntityState.Modified; - } - else - { - contract = new Contract - { - Id = Cache.AppState.NextAccountId(), - FirstLevel = origination.Level, - LastLevel = origination.Level, - Address = contractAddress, - CreatorId = sender.Id, - Type = AccountType.Contract, - Kind = ContractKind.SmartContract, - OriginationsCount = 1 - }; - Db.Contracts.Add(contract); - } - Receive(contract, origination.Balance); - Cache.Accounts.Add(contract); - origination.ContractId = contract.Id; - Contract = contract; - - if (contractDelegate is Data.Models.Delegate _contractDelegate) - Delegate(contract, _contractDelegate, origination.Level); - - var code = await ExpandCode(contract, GetCode(content)); - var storage = GetStorage(content); - - BigMapDiffs = ParseBigMapDiffs(origination, result, code, storage); - await ProcessScript(origination, contract, code, storage); - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.OriginationOps.Add(origination); - Context.OriginationOps.Add(origination); - Origination = origination; - } - - public virtual async Task ApplyInternal(Block block, ManagerOperation parent, JsonElement content) - { - #region init - var initiator = await Cache.Accounts.GetAsync(parent.SenderId); - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var contractDelegate = content.OptionalString("delegate") is string _delegateAddress - ? await Cache.Accounts.GetOrCreateAsync(_delegateAddress) - : null; - - var result = content.Required("result"); - - var origination = new OriginationOperation - { - Id = Cache.AppState.NextOperationId(), - InitiatorId = parent.SenderId, - Level = parent.Level, - Timestamp = parent.Timestamp, - OpHash = parent.OpHash, - Counter = parent.Counter, - Nonce = content.RequiredInt32("nonce"), - Balance = content.RequiredInt64("balance"), - SenderId = sender.Id, - SenderCodeHash = (sender as Contract)?.CodeHash, - DelegateId = contractDelegate?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = GetConsumedGas(result), - StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, - StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 - ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost - : null, - AllocationFee = Context.Protocol.OriginationSize * Context.Protocol.ByteCost - }; - #endregion - - #region apply operation - if (parent is TransactionOperation parentTx) - { - parentTx.InternalOperations = (short?)((parentTx.InternalOperations ?? 0) + 1); - parentTx.InternalOriginations = (short?)((parentTx.InternalOriginations ?? 0) + 1); - } - - Db.TryAttach(sender); - sender.LastLevel = block.Level; - sender.OriginationsCount++; - - if (contractDelegate != null) - { - Db.TryAttach(contractDelegate); - contractDelegate.LastLevel = block.Level; - if (contractDelegate != sender) - contractDelegate.OriginationsCount++; - } - - if (initiator != sender && initiator != contractDelegate) - { - initiator.OriginationsCount++; - } - - block.Operations |= Operations.Originations; - - Cache.AppState.Get().OriginationOpsCount++; - #endregion - - #region apply result - if (origination.Status == OperationStatus.Applied) - { - var burned = (origination.StorageFee ?? 0) + (origination.AllocationFee ?? 0); - Proto.Manager.Burn(burned); - - Spend(initiator, burned); - - Spend(sender, origination.Balance); - sender.ContractsCount++; - - Contract? contract; - var contractAddress = result.RequiredArray("originated_contracts", 1)[0].RequiredString(); - var ghost = await Cache.Accounts.GetAsync(contractAddress); - if (ghost != null) - { - contract = new Contract - { - Id = ghost.Id, - Index = ghost.Index, - FirstLevel = ghost.FirstLevel, - LastLevel = origination.Level, - Address = contractAddress, - Counter = 0, - CreatorId = sender.Id, - Type = AccountType.Contract, - Kind = ContractKind.SmartContract, - OriginationsCount = 1, - ActiveTokensCount = ghost.ActiveTokensCount, - TokenBalancesCount = ghost.TokenBalancesCount, - TokenTransfersCount = ghost.TokenTransfersCount, - ActiveTicketsCount = ghost.ActiveTicketsCount, - TicketBalancesCount = ghost.TicketBalancesCount, - TicketTransfersCount = ghost.TicketTransfersCount - }; - Db.Entry(ghost).State = EntityState.Detached; - Db.Entry(contract).State = EntityState.Modified; - } - else - { - contract = new Contract - { - Id = Cache.AppState.NextAccountId(), - FirstLevel = origination.Level, - LastLevel = origination.Level, - Address = contractAddress, - Counter = 0, - CreatorId = sender.Id, - Type = AccountType.Contract, - Kind = ContractKind.SmartContract, - OriginationsCount = 1 - }; - Db.Contracts.Add(contract); - } - Receive(contract, origination.Balance); - Cache.Accounts.Add(contract); - origination.ContractId = contract.Id; - Contract = contract; - - if (contractDelegate is Data.Models.Delegate _contractDelegate) - Delegate(contract, _contractDelegate, origination.Level); - - var code = await ExpandCode(contract, GetCode(content)); - var storage = GetStorage(content); - - BigMapDiffs = ParseBigMapDiffs(origination, result, code, storage); - await ProcessScript(origination, contract, code, storage); - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Db.OriginationOps.Add(origination); - Context.OriginationOps.Add(origination); - Origination = origination; - } - - public virtual async Task Revert(Block block, OriginationOperation origination) - { - #region init - var sender = await Cache.Accounts.GetAsync(origination.SenderId); - var contractDelegate = origination.DelegateId is int delegateId - ? await Cache.Accounts.GetAsync(delegateId) - : null; - var contract = origination.ContractId is int contractId - ? await Cache.Accounts.GetAsync(contractId) as Contract - : null; - - Db.TryAttach(sender); - Db.TryAttach(contractDelegate); - Db.TryAttach(contract); - #endregion - - #region revert result - if (origination.Status == OperationStatus.Applied) - { - await RevertScript(origination, contract!); - - if (contractDelegate is Data.Models.Delegate _contractDelegate) - Undelegate(contract!, _contractDelegate); - - contract!.OriginationsCount--; - if (contract.TokenTransfersCount == 0 && contract.TicketTransfersCount == 0 && contract.Index is null) - { - Db.Accounts.Remove(contract); - Cache.Accounts.Remove(contract); - } - else - { - var ghost = new Account - { - Id = contract.Id, - Index = contract.Index, - Address = contract.Address, - FirstLevel = contract.FirstLevel, - LastLevel = origination.Level, - Type = AccountType.Ghost, - ActiveTokensCount = contract.ActiveTokensCount, - TokenBalancesCount = contract.TokenBalancesCount, - TokenTransfersCount = contract.TokenTransfersCount, - ActiveTicketsCount = contract.ActiveTicketsCount, - TicketBalancesCount = contract.TicketBalancesCount, - TicketTransfersCount = contract.TicketTransfersCount, - }; - - Db.Entry(contract).State = EntityState.Detached; - Db.Entry(ghost).State = EntityState.Modified; - Cache.Accounts.Add(ghost); - } - - var spent = origination.Balance + (origination.StorageFee ?? 0) + (origination.AllocationFee ?? 0); - - RevertSpend(sender, spent); - sender.ContractsCount--; - } - #endregion - - #region revert operation - RevertPayFee(sender, origination.BakerFee); - sender.LastLevel = block.Level; - sender.Counter = origination.Counter - 1; - if (sender is User user) user.Revealed = true; - sender.OriginationsCount--; - - if (contractDelegate != null) - { - contractDelegate.LastLevel = block.Level; - if (contractDelegate != sender) - contractDelegate.OriginationsCount--; - } - - Cache.AppState.Get().OriginationOpsCount--; - #endregion - - Db.OriginationOps.Remove(origination); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - public virtual async Task RevertInternal(Block block, OriginationOperation origination) - { - #region init - var initiator = await Cache.Accounts.GetAsync(origination.InitiatorId!.Value); - var sender = await Cache.Accounts.GetAsync(origination.SenderId); - var contractDelegate = origination.DelegateId is int delegateId - ? await Cache.Accounts.GetAsync(delegateId) - : null; - var contract = origination.ContractId is int contractId - ? await Cache.Accounts.GetAsync(contractId) as Contract - : null; - - Db.TryAttach(initiator); - Db.TryAttach(sender); - Db.TryAttach(contractDelegate); - Db.TryAttach(contract); - #endregion - - #region revert result - if (origination.Status == OperationStatus.Applied) - { - await RevertScript(origination, contract!); - - if (contractDelegate is Data.Models.Delegate _contractDelegate) - Undelegate(contract!, _contractDelegate); - - contract!.OriginationsCount--; - if (contract.TokenTransfersCount == 0 && contract.TicketTransfersCount == 0 && contract.Index is null) - { - Db.Accounts.Remove(contract); - Cache.Accounts.Remove(contract); - } - else - { - var ghost = new Account - { - Id = contract.Id, - Index = contract.Index, - Address = contract.Address, - FirstLevel = contract.FirstLevel, - LastLevel = origination.Level, - Type = AccountType.Ghost, - ActiveTokensCount = contract.ActiveTokensCount, - TokenBalancesCount = contract.TokenBalancesCount, - TokenTransfersCount = contract.TokenTransfersCount, - ActiveTicketsCount = contract.ActiveTicketsCount, - TicketBalancesCount = contract.TicketBalancesCount, - TicketTransfersCount = contract.TicketTransfersCount, - }; - - Db.Entry(contract).State = EntityState.Detached; - Db.Entry(ghost).State = EntityState.Modified; - Cache.Accounts.Add(ghost); - } - - var spent = (origination.StorageFee ?? 0) + (origination.AllocationFee ?? 0); - RevertSpend(initiator, spent); - - RevertSpend(sender, origination.Balance); - sender.ContractsCount--; - } - #endregion - - #region revert operation - sender.LastLevel = block.Level; - sender.OriginationsCount--; - - if (contractDelegate != null) - { - contractDelegate.LastLevel = block.Level; - if (contractDelegate != sender) - contractDelegate.OriginationsCount--; - } - - if (initiator != sender && initiator != contractDelegate) - { - initiator.OriginationsCount--; - } - - Cache.AppState.Get().OriginationOpsCount--; - #endregion - - Db.OriginationOps.Remove(origination); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual int GetConsumedGas(JsonElement result) - { - return result.OptionalInt32("consumed_gas") ?? 0; - } - - protected virtual IMicheline GetCode(JsonElement content) - { - return content.TryGetProperty("script", out var script) - ? Micheline.FromJson(script.Required("code"))! - // WTF: Before Proto5 some contracts had no code nor storage - : Micheline.FromBytes(Script.ManagerTzBytes); - } - - protected virtual IMicheline GetStorage(JsonElement content) - { - return content.TryGetProperty("script", out var script) - ? Micheline.FromJson(script.Required("storage"))! - // WTF: Different nodes return different manager prop name. - : new MichelineString(content.OptionalString("managerPubkey") ?? content.RequiredString("manager_pubkey")); - } - - protected async Task ExpandCode(Contract contract, IMicheline code) - { - if (code is not MichelineArray array) - { - var constants = await Constants.Find(Db, [code]); - if (constants.Count > 0) - { - contract.Tags |= ContractTags.Constants; - foreach (var constant in constants) - { - Db.TryAttach(constant); - constant.Refs++; - } - var dict = constants.ToDictionary(x => x.Address!, x => Micheline.FromBytes(x.Value!)); - array = Constants.Expand(code, dict) as MichelineArray - ?? throw new Exception("Contract code should be an array or constant"); - } - else - { - throw new Exception("Contract code should be an array or constant"); - } - } - return array; - } - - protected async Task ProcessScript(OriginationOperation origination, Contract contract, MichelineArray code, IMicheline storageValue) - { - #region expand top-level constants - var constants = await Constants.Find(Db, code); - if (constants.Count > 0) - { - var depth = 0; - while (code.Any(x => x is MichelinePrim prim && prim.Prim == PrimType.constant) && depth++ <= 10_000) - { - for (int i = 0; i < code.Count; i++) - { - if (code[i] is MichelinePrim prim && prim.Prim == PrimType.constant) - { - code[i] = Micheline.FromBytes(constants.First(x => x.Address == (prim.Args![0] as MichelineString)!.Value).Value!); - } - } - } - } - #endregion - - var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter); - var micheStorage = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage); - var micheCode = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code); - var micheViews = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view); - - #region process constants - if (constants.Count > 0) - { - contract.Tags |= ContractTags.Constants; - foreach (var constant in constants) - { - Db.TryAttach(constant); - constant.Refs++; - } - var dict = constants.ToDictionary(x => x.Address!, x => Micheline.FromBytes(x.Value!)); - micheParameter = Constants.Expand(micheParameter, dict); - micheStorage = Constants.Expand(micheStorage, dict); - foreach (var view in micheViews.Select(x => (x as MichelinePrim)!)) - { - view.Args![1] = Constants.Expand(view.Args[1], dict); - view.Args[2] = Constants.Expand(view.Args[2], dict); - } - } - #endregion - - var script = new Script - { - Id = Cache.AppState.NextScriptId(), - Level = origination.Level, - ContractId = contract.Id, - OriginationId = origination.Id, - ParameterSchema = micheParameter.ToBytes(), - StorageSchema = micheStorage.ToBytes(), - CodeSchema = micheCode.ToBytes(), - Views = micheViews.Any() - ? [..micheViews.Select(x => x.ToBytes())] - : null, - Current = true - }; - - var viewsBytes = script.Views? - .OrderBy(x => x, new BytesComparer()) - .SelectMany(x => x) - .ToArray() - ?? []; - var typeSchema = script.ParameterSchema.Concat(script.StorageSchema).Concat(viewsBytes); - var fullSchema = typeSchema.Concat(script.CodeSchema); - contract.TypeHash = script.TypeHash = Script.GetHash(typeSchema); - origination.ContractCodeHash = contract.CodeHash = script.CodeHash = Script.GetHash(fullSchema); - - if ((storageValue.Type == MichelineType.String || storageValue.Type == MichelineType.Bytes) && - code.ToBytes().IsEqual(Script.ManagerTzBytes)) - { - contract.Kind = ContractKind.DelegatorContract; - } - else - { - if (script.Schema.IsFA1()) - { - if (script.Schema.IsFA12()) - contract.Tags |= ContractTags.FA12; - - contract.Tags |= ContractTags.FA1; - contract.Kind = ContractKind.Asset; - } - if (script.Schema.IsFA2()) - { - contract.Tags |= ContractTags.FA2; - contract.Kind = ContractKind.Asset; - } - } - - if (BigMapDiffs != null) - { - var ind = 0; - var ptrs = BigMapDiffs.Where(x => x.Action <= BigMapDiffAction.Copy && x.Ptr >= 0).Select(x => x.Ptr).ToList(); - var view = script.Schema.Storage.Schema.ToTreeView(storageValue); - - foreach (var bigmap in view.Nodes().Where(x => x.Schema.Prim == PrimType.big_map)) - storageValue = storageValue.Replace(bigmap.Value, new MichelineInt(ptrs[^++ind])); - } - - var storage = new Storage - { - Id = Cache.AppState.NextStorageId(), - Level = origination.Level, - ContractId = contract.Id, - OriginationId = origination.Id, - RawValue = script.Schema.OptimizeStorage(storageValue, false).ToBytes(), - JsonValue = script.Schema.HumanizeStorage(storageValue), - Current = true - }; - - Db.Scripts.Add(script); - Cache.Schemas.Add(contract, script.Schema); - - Db.Storages.Add(storage); - Cache.Storages.Add(contract, storage); - - origination.ScriptId = script.Id; - origination.StorageId = storage.Id; - } - - protected async Task RevertScript(OriginationOperation origination, Contract contract) - { - #region process constants - if (contract.Tags.HasFlag(ContractTags.Constants)) - { - var script = await Db.Scripts - .AsNoTracking() - .Where(x => x.ContractId == contract.Id && x.Current) - .Select(x => new { x.ParameterSchema, x.StorageSchema, x.CodeSchema, x.Views }) - .FirstAsync(); - - var code = new MichelineArray - { - Micheline.FromBytes(script.ParameterSchema), - Micheline.FromBytes(script.StorageSchema), - Micheline.FromBytes(script.CodeSchema) - }; - if (script.Views != null) - foreach (var bytes in script.Views) - code.Add(Micheline.FromBytes(bytes)); - - // TODO: we're actually missing constants in parameter and storage, - // as they were expanded, so refs may be reverted inaccurately. - var constants = await Constants.Find(Db, code); - foreach (var constant in constants) - { - Db.TryAttach(constant); - constant.Refs--; - } - } - #endregion - - Db.Scripts.Remove(new Script - { - Id = origination.ScriptId!.Value, - ParameterSchema = [], - StorageSchema = [], - CodeSchema = [], - Level = 0, - ContractId = 0, - }); - Cache.Schemas.Remove(contract); - Cache.AppState.ReleaseScriptId(); - - if (!Cache.Storages.TryGetCached(contract, out var storage)) - { - storage = new Storage - { - Id = origination.StorageId!.Value, - RawValue = [], - JsonValue = string.Empty, - Level = 0, - ContractId = 0, - }; - } - Db.Storages.Remove(storage); - Cache.Storages.Remove(contract); - Cache.AppState.ReleaseStorageId(); - } - - protected virtual IEnumerable? ParseBigMapDiffs(OriginationOperation origination, JsonElement result, MichelineArray code, IMicheline storage) - { - List? res = null; - - var micheStorage = (code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage) as MichelinePrim)!; - var schema = new StorageSchema(micheStorage); - var tree = schema.Schema.ToTreeView(storage); - var bigmap = tree.Nodes().FirstOrDefault(x => x.Schema.Prim == PrimType.big_map); - - if (bigmap != null) - { - res = - [ - new AllocDiff { Ptr = origination.ContractId!.Value } - ]; - if (bigmap.Value is MichelineArray items && items.Count > 0) - { - foreach (var item in items) - { - var key = (item as MichelinePrim)!.Args![0]; - var value = (item as MichelinePrim)!.Args![1]; - res.Add(new UpdateDiff - { - Ptr = res[0].Ptr, - Key = key, - Value = value, - KeyHash = (bigmap.Schema as BigMapSchema)!.GetKeyHash(key) - }); - } - } - } - - return res; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 70a8b15b2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class RevealsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - - var pubKey = content.RequiredString("public_key"); - var result = content.Required("metadata").Required("operation_result"); - var reveal = new RevealOperation - { - Id = Cache.AppState.NextOperationId(), - OpHash = op.RequiredString("hash"), - Level = block.Level, - Timestamp = block.Timestamp, - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = GetConsumedGas(result) - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, reveal.BakerFee); - sender.Counter = reveal.Counter; - sender.RevealsCount++; - - block.Operations |= Operations.Reveals; - - Cache.AppState.Get().RevealOpsCount++; - #endregion - - #region apply result - ApplyResult(reveal, sender, pubKey); - #endregion - - Proto.Manager.Set(sender); - Db.RevealOps.Add(reveal); - Context.RevealOps.Add(reveal); - } - - public virtual async Task Revert(Block block, RevealOperation reveal) - { - #region entities - var sender = await Cache.Accounts.GetAsync(reveal.SenderId); - - Db.TryAttach(sender); - #endregion - - #region revert result - RevertResult(reveal, sender); - #endregion - - #region revert operation - RevertPayFee(sender, reveal.BakerFee); - sender.Counter = reveal.Counter - 1; - sender.RevealsCount--; - - Cache.AppState.Get().RevealOpsCount--; - #endregion - - Db.RevealOps.Remove(reveal); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual int GetConsumedGas(JsonElement result) - { - return result.OptionalInt32("consumed_gas") ?? 0; - } - - protected virtual void ApplyResult(RevealOperation op, Account sender, string pubKey) - { - if (sender is User user) - { - user.PublicKey = pubKey; - if (user.Balance > 0) user.Revealed = true; - } - } - - protected virtual void RevertResult(RevealOperation op, Account sender) - { - if (sender is User user) - { - if (user.RevealsCount == 1) - user.PublicKey = null; - - user.Revealed = false; - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 8cf1d8ac0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,596 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class TransactionsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public TransactionOperation Transaction { get; private set; } = null!; - public IEnumerable? BigMapDiffs { get; private set; } - public IEnumerable? TicketUpdates { get; private set; } - public Account? Target { get; private set; } - - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var target = await Cache.Accounts.GetAsync(content.OptionalString("destination")); - - var result = content.Required("metadata").Required("operation_result"); - - var transaction = new TransactionOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - Amount = content.RequiredInt64("amount"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - TargetId = target?.Id, - TargetCodeHash = (target as Contract)?.CodeHash, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = GetConsumedGas(result), - StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, - StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 - ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost - : null, - AllocationFee = HasAllocated(result) - ? (long?)Context.Protocol.OriginationSize * Context.Protocol.ByteCost - : null - }; - - - if (target is not User && content.TryGetProperty("parameters", out var parameters)) - await ProcessParameters(transaction, target, parameters); - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, transaction.BakerFee); - sender.Counter = transaction.Counter; - sender.TransactionsCount++; - - if (target != null) - { - Db.TryAttach(target); - if (target != sender) - target.TransactionsCount++; - } - - block.Operations |= Operations.Transactions; - - Cache.AppState.Get().TransactionOpsCount++; - #endregion - - #region apply result - if (transaction.Status == OperationStatus.Applied) - { - var burned = (transaction.StorageFee ?? 0) + (transaction.AllocationFee ?? 0); - Proto.Manager.Burn(burned); - - Spend(sender, transaction.Amount + burned); - - Receive(target!, transaction.Amount); - - await ResetGracePeriod(transaction, target!); - - if (result.TryGetProperty("storage", out var storage)) - { - BigMapDiffs = ParseBigMapDiffs(transaction, result); - await ProcessStorage(transaction, target!, storage); - } - - await ApplyAddressRegistryDiffs(transaction, result); - - TicketUpdates = ParseTicketUpdates("ticket_updates", result); - - if (target is SmartRollup) - Proto.Inbox.Push(transaction.Id); - - Cache.Statistics.Current.TotalBurned += burned; - if (target!.Id == NullAddress.Id) - Cache.Statistics.Current.TotalBanished += transaction.Amount; - } - #endregion - - Proto.Manager.Set(sender); - //Db.TransactionOps.Add(transaction); - Context.TransactionOps.Add(transaction); - Transaction = transaction; - Target = target; - } - - public virtual async Task ApplyInternal(Block block, ManagerOperation parent, JsonElement content) - { - #region init - var parentSender = await Cache.Accounts.GetAsync(parent.SenderId); - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var target = await Cache.Accounts.GetAsync(content.OptionalString("destination")); - - var result = content.Required("result"); - - var transaction = new TransactionOperation - { - Id = Cache.AppState.NextOperationId(), - InitiatorId = parent.SenderId, - Level = parent.Level, - Timestamp = parent.Timestamp, - OpHash = parent.OpHash, - Counter = parent.Counter, - Amount = content.RequiredInt64("amount"), - Nonce = content.RequiredInt32("nonce"), - SenderId = sender.Id, - SenderCodeHash = (sender as Contract)?.CodeHash, - TargetId = target?.Id, - TargetCodeHash = (target as Contract)?.CodeHash, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = GetConsumedGas(result), - StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, - StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 - ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost - : null, - AllocationFee = HasAllocated(result) - ? (long?)Context.Protocol.OriginationSize * Context.Protocol.ByteCost - : null - }; - - if (target is not User && content.TryGetProperty("parameters", out var parameters)) - await ProcessParameters(transaction, target, parameters); - #endregion - - #region apply operation - if (parent is TransactionOperation parentTx) - { - parentTx.InternalOperations = (short?)((parentTx.InternalOperations ?? 0) + 1); - parentTx.InternalTransactions = (short?)((parentTx.InternalTransactions ?? 0) + 1); - } - - Db.TryAttach(sender); - sender.TransactionsCount++; - - if (target != null) - { - Db.TryAttach(target); - if (target != sender) - target.TransactionsCount++; - } - - if (parentSender != sender && parentSender != target) - parentSender.TransactionsCount++; - - block.Operations |= Operations.Transactions; - - Cache.AppState.Get().TransactionOpsCount++; - #endregion - - #region apply result - if (transaction.Status == OperationStatus.Applied) - { - var burned = (transaction.StorageFee ?? 0) + (transaction.AllocationFee ?? 0); - Proto.Manager.Burn(burned); - - Spend(parentSender, burned); - - Spend(sender, transaction.Amount); - - Receive(target!, transaction.Amount); - - if (target == parentSender) - Proto.Manager.Credit(transaction.Amount); - - await ResetGracePeriod(transaction, target!); - - if (result.TryGetProperty("storage", out var storage)) - { - BigMapDiffs = ParseBigMapDiffs(transaction, result); - await ProcessStorage(transaction, target!, storage); - } - - await ApplyAddressRegistryDiffs(transaction, result); - - TicketUpdates = ParseTicketUpdates("ticket_receipt", result); - - if (target is SmartRollup) - Proto.Inbox.Push(transaction.Id); - - Cache.Statistics.Current.TotalBurned += burned; - if (target!.Id == NullAddress.Id) - Cache.Statistics.Current.TotalBanished += transaction.Amount; - } - #endregion - - //Db.TransactionOps.Add(transaction); - Context.TransactionOps.Add(transaction); - Transaction = transaction; - Target = target; - } - - public virtual async Task Revert(Block block, TransactionOperation transaction) - { - #region entities - var sender = await Cache.Accounts.GetAsync(transaction.SenderId); - var target = await Cache.Accounts.GetAsync(transaction.TargetId); - - Db.TryAttach(sender); - Db.TryAttach(target); - #endregion - - #region revert result - if (transaction.Status == OperationStatus.Applied) - { - RevertReceive(target!, transaction.Amount); - - if (target is Data.Models.Delegate delegat) - { - if (transaction.ResetDeactivation != null) - { - if (transaction.ResetDeactivation <= transaction.Level) - await DeactivateBaker(delegat); - - delegat.DeactivationLevel = (int)transaction.ResetDeactivation; - } - } - - RevertSpend(sender, transaction.Amount + (transaction.StorageFee ?? 0) + (transaction.AllocationFee ?? 0)); - - if (transaction.StorageId != null) - await RevertStorage(transaction, (target as Contract)!); - - await RevertAddressRegistryDiffs(transaction); - } - #endregion - - #region revert operation - RevertPayFee(sender, transaction.BakerFee); - - sender.TransactionsCount--; - if (target != null && target != sender) target.TransactionsCount--; - - sender.Counter = transaction.Counter - 1; - if (sender is User user) user.Revealed = true; - - Cache.AppState.Get().TransactionOpsCount--; - #endregion - - //Db.TransactionOps.Remove(transaction); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - public virtual async Task RevertInternal(Block block, TransactionOperation transaction) - { - #region entities - var parentSender = await Cache.Accounts.GetAsync(transaction.InitiatorId!.Value); - var sender = await Cache.Accounts.GetAsync(transaction.SenderId); - var target = await Cache.Accounts.GetAsync(transaction.TargetId); - - Db.TryAttach(parentSender); - Db.TryAttach(sender); - Db.TryAttach(target); - #endregion - - #region revert result - if (transaction.Status == OperationStatus.Applied) - { - RevertReceive(target!, transaction.Amount); - - if (target is Data.Models.Delegate delegat) - { - if (transaction.ResetDeactivation != null) - { - if (transaction.ResetDeactivation <= transaction.Level) - await DeactivateBaker(delegat); - - delegat.DeactivationLevel = (int)transaction.ResetDeactivation; - } - } - - RevertSpend(sender, transaction.Amount); - - RevertSpend(parentSender, (transaction.StorageFee ?? 0) + (transaction.AllocationFee ?? 0)); - - if (transaction.StorageId != null) - await RevertStorage(transaction, (target as Contract)!); - - await RevertAddressRegistryDiffs(transaction); - } - #endregion - - #region revert operation - sender.TransactionsCount--; - if (target != null && target != sender) target.TransactionsCount--; - if (parentSender != sender && parentSender != target) parentSender.TransactionsCount--; - - Cache.AppState.Get().TransactionOpsCount--; - #endregion - - //Db.TransactionOps.Remove(transaction); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual bool HasAllocated(JsonElement result) => false; - - protected virtual async Task ResetGracePeriod(TransactionOperation transaction, Account target) - { - if (target is Data.Models.Delegate delegat) - { - var newDeactivationLevel = delegat.Staked ? GracePeriod.Reset(transaction.Level, Context.Protocol) : GracePeriod.Init(transaction.Level, Context.Protocol); - if (delegat.DeactivationLevel < newDeactivationLevel) - { - if (delegat.DeactivationLevel <= transaction.Level) - await ActivateBaker(delegat); - - transaction.ResetDeactivation = delegat.DeactivationLevel; - delegat.DeactivationLevel = newDeactivationLevel; - } - } - } - - protected virtual async Task ProcessParameters(TransactionOperation transaction, Account? target, JsonElement parameters) - { - var (rawEp, rawParam) = ("default", Micheline.FromJson(parameters)!); - - if (target is Contract contract) - { - if (contract.Kind == ContractKind.DelegatorContract) - { - if (rawParam is MichelinePrim p && p.Prim == PrimType.Unit) - return; - - transaction.Entrypoint = rawEp; - transaction.RawParameters = rawParam.ToBytes(); - } - else - { - try - { - var schema = await Cache.Schemas.GetAsync(contract); - var (normEp, normParam) = schema.NormalizeParameter(rawEp, rawParam); - - transaction.Entrypoint = normEp; - transaction.RawParameters = schema.OptimizeParameter(normEp, normParam).ToBytes(); - transaction.JsonParameters = schema.HumanizeParameter(normEp, normParam); - } - catch (Exception ex) - { - transaction.Entrypoint ??= rawEp; - transaction.RawParameters ??= rawParam.ToBytes(); - - if (transaction.Status == OperationStatus.Applied) - Logger.LogError(ex, "Failed to humanize tx {hash} parameters", transaction.OpHash); - } - } - } - else - { - transaction.Entrypoint = rawEp; - transaction.RawParameters = rawParam.ToBytes(); - } - } - - protected virtual async Task ProcessStorage(TransactionOperation transaction, Account target, JsonElement storage) - { - if (target is not Contract contract || contract.Kind == ContractKind.DelegatorContract) - return; - - var schema = await Cache.Schemas.GetAsync(contract); - var currentStorage = await Cache.Storages.GetAsync(contract); - - var newStorageMicheline = schema.OptimizeStorage(Micheline.FromJson(storage)!, false); - newStorageMicheline = NormalizeStorage(transaction, newStorageMicheline, schema); - var newStorageBytes = newStorageMicheline.ToBytes(); - - if (newStorageBytes.IsEqual(currentStorage.RawValue)) - { - transaction.StorageId = currentStorage.Id; - return; - } - - Db.TryAttach(currentStorage); - currentStorage.Current = false; - - var newStorage = new Storage - { - Id = Cache.AppState.NextStorageId(), - Level = transaction.Level, - ContractId = contract.Id, - TransactionId = transaction.Id, - RawValue = newStorageBytes, - JsonValue = schema.HumanizeStorage(newStorageMicheline), - Current = true, - }; - - Db.Storages.Add(newStorage); - Cache.Storages.Add(contract, newStorage); - - transaction.StorageId = newStorage.Id; - } - - public async Task RevertStorage(TransactionOperation transaction, Contract contract) - { - var storage = await Cache.Storages.GetAsync(contract); - if (storage.TransactionId == transaction.Id) - { - var prevStorage = await Db.Storages - .Where(x => x.ContractId == contract.Id && x.Id < storage.Id) - .OrderByDescending(x => x.Id) - .FirstAsync(); - - prevStorage.Current = true; - Cache.Storages.Add(contract, prevStorage); - - Db.Storages.Remove(storage); - Cache.AppState.ReleaseStorageId(); - } - } - - protected virtual IMicheline NormalizeStorage(TransactionOperation transaction, IMicheline storage, ContractScript schema) - { - var view = schema.Storage.Schema.ToTreeView(storage); - var bigmap = view.Nodes().FirstOrDefault(x => x.Schema.Prim == PrimType.big_map); - if (bigmap != null) - storage = storage.Replace(bigmap.Value, new MichelineInt(transaction.TargetId!.Value)); - return storage; - } - - protected virtual IEnumerable? ParseBigMapDiffs(TransactionOperation transaction, JsonElement result) - { - if (transaction.Level != 5993) - return null; - // It seems there were no big_map diffs at all in proto 1 - // thus there was no an adequate way to track big_map updates, - // so the only way to handle this single big_map update is hardcoding - return - [ - new UpdateDiff - { - Ptr = transaction.TargetId!.Value, - KeyHash = "exprteAx9hWkXvYSQ4nN9SqjJGVR1sTneHQS1QEcSdzckYdXZVvsqY", - Key = new MichelineString("KT1R3uoZ6W1ZxEwzqtv75Ro7DhVY6UAcxuK2"), - Value = new MichelinePrim - { - Prim = PrimType.Pair, - Args = - [ - new MichelineString("Aliases Contract"), - new MichelinePrim - { - Prim = PrimType.Pair, - Args = - [ - new MichelinePrim { Prim = PrimType.None }, - new MichelinePrim - { - Prim = PrimType.Pair, - Args = - [ - new MichelineInt(0), - new MichelinePrim - { - Prim = PrimType.Pair, - Args = - [ - new MichelinePrim - { - Prim = PrimType.Left, - Args = - [ - new MichelinePrim { Prim = PrimType.Unit } - ] - }, - new MichelineInt(1530741267) - ] - } - ] - } - ] - } - ] - }, - } - ]; - } - - protected virtual int GetConsumedGas(JsonElement result) - { - return result.OptionalInt32("consumed_gas") ?? 0; - } - - protected virtual IEnumerable? ParseTicketUpdates(string property, JsonElement result) - { - if (!result.TryGetProperty(property, out var ticketUpdates)) - return null; - - var res = new List(); - foreach (var updates in ticketUpdates.RequiredArray().EnumerateArray()) - { - var list = new List(); - foreach (var update in updates.RequiredArray("updates").EnumerateArray()) - { - var amount = update.RequiredBigInteger("amount"); - if (amount != BigInteger.Zero) - { - list.Add(new TicketUpdate - { - Account = update.RequiredString("account"), - Amount = amount - }); - } - } - - if (list.Count > 0) - { - var ticketToken = updates.Required("ticket_token"); - var type = Micheline.FromJson(ticketToken.Required("content_type"))!; - var value = Micheline.FromJson(ticketToken.Required("content"))!; - var rawType = type.ToBytes(); - - byte[] rawContent; - string? jsonContent; - - try - { - var schema = Schema.Create((type as MichelinePrim)!); - rawContent = schema.Optimize(value).ToBytes(); - jsonContent = schema.Humanize(value); - } - catch (Exception ex) - { - Logger.LogError(ex, "Failed to parse ticket content"); - rawContent = value.ToBytes(); - jsonContent = null; - } - - res.Add(new TicketUpdates - { - Ticket = new TicketIdentity - { - Ticketer = ticketToken.RequiredString("ticketer"), - RawType = rawType, - RawContent = rawContent, - JsonContent = jsonContent, - TypeHash = Script.GetHash(rawType), - ContentHash = Script.GetHash(rawContent) - }, - Updates = list - }); - } - } - - return res.Count > 0 ? res : null; - } - - protected virtual Task ApplyAddressRegistryDiffs(TransactionOperation transaction, JsonElement result) => Task.CompletedTask; - - protected virtual Task RevertAddressRegistryDiffs(TransactionOperation transaction) => Task.CompletedTask; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index d1f77584c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class SnapshotBalanceCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(JsonElement rawBlock, Block block) - { - if (!block.Events.HasFlag(BlockEvents.BalanceSnapshot)) - return; - - await TakeSnapshot(block); - await TakeWeirdsSnapshot(block, Context.Protocol); - } - - public virtual async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.BalanceSnapshot)) - return; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "SnapshotBalances" - WHERE "Level" = {0} - """, block.Level); - } - - protected virtual Task TakeSnapshot(Block block) - { - return Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "SnapshotBalances" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount" - ) - SELECT - {0}, - COALESCE("DelegateId", "Id"), - "Id", - COALESCE("OwnDelegatedBalance", "Balance"), - "ExternalDelegatedBalance", - "DelegatorsCount" - FROM "Accounts" - WHERE "Staked" = true - """, block.Level); - } - - protected Task RemoveOutdated(Block block, Protocol protocol) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return Task.CompletedTask; - - var level = block.Level - (protocol.ConsensusRightsDelay + 3) * protocol.BlocksPerCycle; - return Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "SnapshotBalances" - WHERE "Level" <= {0} - """, level); - } - - protected virtual async Task TakeDeactivatedSnapshot(Block block) - { - var deactivated = await Db.Delegates - .AsNoTracking() - .GroupJoin(Db.Accounts, x => x.Id, x => x.DelegateId, (baker, delegators) => new { baker, delegators }) - .Where(x => x.baker.DeactivationLevel == block.Level) - .ToListAsync(); - - if (deactivated.Count != 0) - { - var values = string.Join(",\n", deactivated - .SelectMany(row => - new[] { $"({block.Level}, {row.baker.Id}, {row.baker.Id}, {row.baker.OwnDelegatedBalance}, {row.baker.ExternalDelegatedBalance}, {row.baker.DelegatorsCount})" } - .Concat(row.delegators.Select(delegator => $"({block.Level}, {delegator.DelegateId}, {delegator.Id}, {delegator.Balance}, NULL::bigint, NULL::integer)")))); - - if (values.Length > 0) - { -#pragma warning disable EF1002 // Risk of vulnerability to SQL injection. - await Db.Database.ExecuteSqlRawAsync($""" - INSERT INTO "SnapshotBalances" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount" - ) - VALUES - {values} - """); -#pragma warning restore EF1002 // Risk of vulnerability to SQL injection. - } - } - } - - protected virtual async Task SubtractCycleRewards(JsonElement rawBlock, Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - var rewards = string.Join(",\n", GetBalanceUpdates(rawBlock) - .Where(x => x.RequiredString("kind")[0] == 'f' && - x.RequiredString("category")[0] == 'r' && - x.RequiredInt64("change") < 0 && - GetFreezerCycle(x) != block.Cycle) - .Select(x => (x.RequiredString("delegate"), x.RequiredInt64("change"))) - .GroupBy(x => x.Item1) - .Select(updates => $"({Cache.Accounts.GetExistingDelegate(updates.Key).Id}, {updates.Sum(x => -x.Item2)}::bigint)")); - - if (rewards.Length > 0) - { -#pragma warning disable EF1002 // Risk of vulnerability to SQL injection. - await Db.Database.ExecuteSqlRawAsync($""" - UPDATE "SnapshotBalances" as sb - SET "OwnDelegatedBalance" = "OwnDelegatedBalance" - reward.value - FROM ( - VALUES - {rewards} - ) as reward(baker, value) - WHERE sb."Level" = {block.Level} - AND sb."BakerId" = reward.baker - AND sb."AccountId" = reward.baker - """); -#pragma warning restore EF1002 // Risk of vulnerability to SQL injection. - } - } - - protected virtual int GetFreezerCycle(JsonElement el) - { - return el.RequiredInt32("level"); - } - - protected virtual IEnumerable GetBalanceUpdates(JsonElement rawBlock) - { - return rawBlock - .GetProperty("metadata") - .GetProperty("balance_updates") - .EnumerateArray(); - } - - async Task TakeWeirdsSnapshot(Block block, Protocol protocol) - { - var weirdOriginations = (await Db.OriginationOps - .AsNoTracking() - .Join(Db.Accounts, x => x.DelegateId, x => x.Id, (op, delegat) => new { op, delegat }) - .Join(Db.Accounts, x => x.op.ContractId, x => x.Id, (opDelegat, contract) => new { opDelegat.op, opDelegat.delegat, contract }) - .Where(x => - x.op.Status == OperationStatus.Applied && - x.op.DelegateId != null && - x.delegat.Type != AccountType.Delegate && - x.contract.DelegateId == null) - .ToListAsync()) - .GroupBy(x => x.delegat.Id); - - if (weirdOriginations.Any()) - { - var values = string.Join(",\n", weirdOriginations - .Where(weirds => weirds.Sum(x => x.contract.Balance) >= protocol.MinimalStake) - .SelectMany(weirds => - new[] { $"({block.Level}, {weirds.Key}, {weirds.Key}, 0, {weirds.Sum(x => x.contract.Balance)}, {weirds.Count()})" } - .Concat(weirds.Select(x => $"({block.Level}, {weirds.Key}, {x.contract.Id}, {x.contract.Balance}, NULL::bigint, NULL::integer)")))); - - if (values.Length > 0) - { -#pragma warning disable EF1002 // Risk of vulnerability to SQL injection. - await Db.Database.ExecuteSqlRawAsync($""" - INSERT INTO "SnapshotBalances" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount" - ) - VALUES - {values} - """); -#pragma warning restore EF1002 // Risk of vulnerability to SQL injection. - } - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/StateCommit.cs deleted file mode 100644 index 2319f09b1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/StateCommit.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class StateCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual Task Apply(Block block, JsonElement rawBlock) - { - var nextProtocol = rawBlock.Required("metadata").RequiredString("next_protocol"); - var appState = Cache.AppState.Get(); - - #region entities - var state = appState; - #endregion - - state.Cycle = block.Cycle; - state.Level = block.Level; - state.Timestamp = block.Timestamp; - state.Protocol = Context.Protocol.Hash; - state.NextProtocol = nextProtocol; - state.Hash = block.Hash; - - if (block.Events.HasFlag(BlockEvents.ProtocolBegin)) state.ProtocolsCount++; - if (block.Events.HasFlag(BlockEvents.CycleBegin)) state.CyclesCount++; - - return Task.CompletedTask; - } - - public virtual async Task Revert(Block block) - { - var nextProtocol = Context.Protocol.Hash; - var appState = Cache.AppState.Get(); - - #region entities - var state = appState; - var prevBlock = await Cache.Blocks.PreviousAsync(); - var prevProtocol = await Cache.Protocols.GetAsync(prevBlock.ProtoCode); - #endregion - - state.Cycle = prevBlock.Cycle; - state.Level = prevBlock.Level; - state.Timestamp = prevBlock.Timestamp; - state.Protocol = prevProtocol.Hash; - state.NextProtocol = nextProtocol; - state.Hash = prevBlock.Hash; - - if (block.Events.HasFlag(BlockEvents.ProtocolBegin)) state.ProtocolsCount--; - if (block.Events.HasFlag(BlockEvents.CycleBegin)) state.CyclesCount--; - - Cache.Blocks.Remove(block); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/StatisticsCommit.cs deleted file mode 100644 index 7e0ba18e9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class StatisticsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(JsonElement rawBlock) - { - var prev = Cache.Statistics.Current; - var statistics = new Statistics - { - Id = 0, - Level = prev.Level + 1, - TotalActivated = prev.TotalActivated, - TotalBootstrapped = prev.TotalBootstrapped, - TotalBurned = prev.TotalBurned, - TotalBanished = prev.TotalBanished, - TotalLost = prev.TotalLost, - TotalCommitments = prev.TotalCommitments, - TotalCreated = prev.TotalCreated, - TotalFrozen = prev.TotalFrozen, - TotalRollupBonds = prev.TotalRollupBonds, - TotalSmartRollupBonds = prev.TotalSmartRollupBonds, - TotalOwnStaked = prev.TotalOwnStaked, - TotalExternalStaked = prev.TotalExternalStaked, - TotalOwnDelegated = prev.TotalOwnDelegated, - TotalExternalDelegated = prev.TotalExternalDelegated, - TotalBakingPower = prev.TotalBakingPower, - TotalVotingPower = prev.TotalVotingPower, - TotalBakers = prev.TotalBakers, - TotalStakers = prev.TotalStakers, - TotalDelegators = prev.TotalDelegators - }; - - var protocol = await Cache.Protocols.GetAsync(rawBlock.RequiredString("protocol")); - if (protocol.IsCycleEnd(statistics.Level)) - statistics.Cycle = protocol.GetCycle(statistics.Level); - - var timestamp = rawBlock.Required("header").RequiredDateTime("timestamp"); - var prevTimestamp = (await Cache.Blocks.GetAsync(prev.Level)).Timestamp; - if (timestamp.Ticks / (10_000_000L * 3600 * 24) != prevTimestamp.Ticks / (10_000_000L * 3600 * 24)) - { - Db.TryAttach(prev); - prev.Date = prevTimestamp.Date; - } - - Db.Statistics.Add(statistics); - Cache.Statistics.SetCurrent(statistics); - } - - public virtual async Task Revert(Block block) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Statistics" - WHERE "Level" = {0} - """, block.Level); - await Cache.Statistics.ResetAsync(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/VotingCommit.cs deleted file mode 100644 index 9b3d83a5d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Commits/VotingCommit.cs +++ /dev/null @@ -1,353 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class VotingCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement rawBlock) - { - var state = Cache.AppState.Get(); - var current = await Cache.Periods.GetAsync(state.VotingPeriod); - - if (block.Level != current.LastLevel) return; - - Db.TryAttach(current); - current.Status = GetPeriodStatus(current); - - await UpdateProposalsStatus(current); - - var nextPeriod = current.Status == PeriodStatus.Success - ? StartNextPeriod(block, Context.Protocol, current) - : StartProposalPeriod(block, Context.Protocol, current); - - state.VotingPeriod = nextPeriod.Index; - state.VotingEpoch = nextPeriod.Epoch; - } - - public virtual async Task Revert(Block block) - { - var state = Cache.AppState.Get(); - var current = await Cache.Periods.GetAsync(state.VotingPeriod); - - if (block.Level != current.FirstLevel - 1) return; - - var prev = await Cache.Periods.GetAsync(state.VotingPeriod - 1); - - Db.TryAttach(prev); - prev.Status = PeriodStatus.Active; - - if (prev.Kind != PeriodKind.Proposal || prev.ProposalsCount > 0) - { - var proposals = await Db.Proposals - .Where(x => x.LastPeriod >= prev.Index) - .ToListAsync(); - - foreach (var proposal in proposals) - { - proposal.Status = ProposalStatus.Active; - proposal.LastPeriod = prev.Index; - } - } - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "VotingPeriods" WHERE "Index" = {0}; - DELETE FROM "VotingSnapshots" WHERE "Period" = {0}; - """, current.Index); - Cache.Periods.Remove(current); - - state.VotingPeriod = prev.Index; - state.VotingEpoch = prev.Epoch; - } - - protected PeriodStatus GetPeriodStatus(VotingPeriod p) - { - if (p.Kind == PeriodKind.Proposal) - { - if (p.ProposalsCount == 0) - return PeriodStatus.NoProposals; - - if (p.TopVotingPower < p.TotalVotingPower.MulRatio(p.UpvotesQuorum!.Value, 10000)) - return PeriodStatus.NoQuorum; - - if (p.SingleWinner == false) - return PeriodStatus.NoSingleWinner; - } - else if (p.Kind == PeriodKind.Exploration || p.Kind == PeriodKind.Promotion) - { - if (p.YayVotingPower + p.NayVotingPower + p.PassVotingPower < p.TotalVotingPower.MulRatio(p.BallotsQuorum!.Value, 10000)) - return PeriodStatus.NoQuorum; - - if (p.YayVotingPower < (p.YayVotingPower!.Value + p.NayVotingPower!.Value).MulRatio(p.Supermajority!.Value, 10000)) - return PeriodStatus.NoSupermajority; - } - - return PeriodStatus.Success; - } - - protected async Task UpdateProposalsStatus(VotingPeriod p) - { - if (p.Kind == PeriodKind.Proposal) - { - if (p.Status == PeriodStatus.NoProposals) return; - - var proposals = await Db.Proposals - .Where(x => x.Status == ProposalStatus.Active) - .ToListAsync(); - - var pendings = Db.ChangeTracker.Entries() - .Where(x => x.Entity is Proposal p && p.Status == ProposalStatus.Active) - .Select(x => (x.Entity as Proposal)!) - .ToList(); - - foreach (var pending in pendings) - if (!proposals.Any(x => x.Id == pending.Id)) - proposals.Add(pending); - - foreach (var proposal in proposals) - proposal.Status = ProposalStatus.Skipped; - - if (p.Status == PeriodStatus.Success) - { - var winner = proposals.First(x => x.VotingPower == p.TopVotingPower); - winner.Status = GetProposalStatus(winner, p); - if (winner.Status == ProposalStatus.Active) - winner.LastPeriod = p.Index + 1; - } - } - else - { - var proposal = await Db.Proposals.FirstAsync(x => x.Status == ProposalStatus.Active); - proposal.Status = GetProposalStatus(proposal, p); - if (proposal.Status == ProposalStatus.Active) - proposal.LastPeriod = p.Index + 1; - } - } - - protected virtual ProposalStatus GetProposalStatus(Proposal proposal, VotingPeriod period) - { - if (period.Status == PeriodStatus.Success) - return period.Kind == PeriodKind.Promotion - ? ProposalStatus.Accepted - : ProposalStatus.Active; - - if (period.Status == PeriodStatus.NoSupermajority) - return ProposalStatus.Rejected; - - return ProposalStatus.Skipped; - } - - protected virtual VotingPeriod StartNextPeriod(Block block, Protocol protocol, VotingPeriod current) - { - return current.Kind switch - { - PeriodKind.Proposal => StartBallotPeriod(block, protocol, current, PeriodKind.Exploration), - PeriodKind.Exploration => StartWaitingPeriod(block, protocol, current, PeriodKind.Testing), - PeriodKind.Testing => StartBallotPeriod(block, protocol, current, PeriodKind.Promotion), - PeriodKind.Promotion => StartProposalPeriod(block, protocol, current), - _ => throw new Exception("Invalid voting period kind") - }; - } - - protected VotingPeriod StartProposalPeriod(Block block, Protocol protocol, VotingPeriod current) - { - var period = new VotingPeriod - { - Id = 0, - Index = current.Index + 1, - Epoch = current.Epoch + 1, - FirstLevel = block.Level + 1, - LastLevel = block.Level + protocol.BlocksPerVoting, - Kind = PeriodKind.Proposal, - Status = PeriodStatus.Active - }; - - #region snapshot - var snapshots = Cache.Accounts.GetDelegates() - .Where(x => x.VotingPower != 0) - .Select(x => new VotingSnapshot - { - Id = 0, - Level = block.Level, - Period = period.Index, - BakerId = x.Id, - VotingPower = x.VotingPower, - Status = VoterStatus.None - }); - - period.TotalBakers = snapshots.Count(); - period.TotalVotingPower = snapshots.Sum(x => x.VotingPower); - #endregion - - //#region temporary diagnostics - //var listing = Proto.Node.GetAsync($"chains/main/blocks/{block.Level}/context/raw/json/votes/listings?depth=1").Result - // .EnumerateArray() - // .ToDictionary(x => x[0].RequiredString(), x => x[1].RequiredInt64()); - - //if (snapshots.Count() != listing.Count) - // throw new Exception("Wrong voting snapshots"); - - //foreach (var snapshot in snapshots) - // if (!listing.TryGetValue(Cache.Accounts.GetDelegate(snapshot.BakerId).Address, out var votingPower) || snapshot.VotingPower != votingPower) - // throw new Exception("Wrong voting snapshot"); - //#endregion - - #region quorum - period.UpvotesQuorum = protocol.ProposalQuorum; - period.ProposalsCount = 0; - period.TopUpvotes = 0; - period.TopVotingPower = 0; - period.SingleWinner = false; - #endregion - - Db.VotingSnapshots.AddRange(snapshots); - Db.VotingPeriods.Add(period); - Cache.Periods.Add(period); - return period; - } - - protected VotingPeriod StartBallotPeriod(Block block, Protocol protocol, VotingPeriod current, PeriodKind kind) - { - var period = new VotingPeriod - { - Id = 0, - Index = current.Index + 1, - Epoch = current.Epoch, - FirstLevel = block.Level + 1, - LastLevel = block.Level + protocol.BlocksPerVoting, - Kind = kind, - Status = PeriodStatus.Active - }; - - #region snapshot - var snapshots = Cache.Accounts.GetDelegates() - .Where(x => x.VotingPower != 0) - .Select(x => new VotingSnapshot - { - Id = 0, - Level = block.Level, - Period = period.Index, - BakerId = x.Id, - VotingPower = x.VotingPower, - Status = VoterStatus.None - }); - - period.TotalBakers = snapshots.Count(); - period.TotalVotingPower = snapshots.Sum(x => x.VotingPower); - #endregion - - //#region temporary diagnostics - //var listing = Proto.Node.GetAsync($"chains/main/blocks/{block.Level}/context/raw/json/votes/listings?depth=1").Result - // .EnumerateArray() - // .ToDictionary(x => x[0].RequiredString(), x => x[1].RequiredInt64()); - - //if (snapshots.Count() != listing.Count) - // throw new Exception("Wrong voting snapshots"); - - //foreach (var snapshot in snapshots) - // if (!listing.TryGetValue(Cache.Accounts.GetDelegate(snapshot.BakerId).Address, out var votingPower) || snapshot.VotingPower != votingPower) - // throw new Exception("Wrong voting snapshot"); - //#endregion - - #region quorum - period.ParticipationEma = GetParticipationEma(period, protocol); - period.BallotsQuorum = GetBallotQuorum(period, protocol); - period.Supermajority = 8000; - - period.YayBallots = 0; - period.YayVotingPower = 0; - period.NayBallots = 0; - period.NayVotingPower = 0; - period.PassBallots = 0; - period.PassVotingPower = 0; - #endregion - - Db.VotingSnapshots.AddRange(snapshots); - Db.VotingPeriods.Add(period); - Cache.Periods.Add(period); - return period; - } - - protected VotingPeriod StartWaitingPeriod(Block block, Protocol protocol, VotingPeriod current, PeriodKind kind) - { - var period = new VotingPeriod - { - Id = 0, - Index = current.Index + 1, - Epoch = current.Epoch, - FirstLevel = block.Level + 1, - LastLevel = block.Level + protocol.BlocksPerVoting, - Kind = kind, - Status = PeriodStatus.Active - }; - - #region snapshot - var snapshots = Cache.Accounts.GetDelegates() - .Where(x => x.VotingPower != 0) - .Select(x => new VotingSnapshot - { - Id = 0, - Level = block.Level, - Period = period.Index, - BakerId = x.Id, - VotingPower = x.VotingPower, - Status = VoterStatus.None - }); - - period.TotalBakers = snapshots.Count(); - period.TotalVotingPower = snapshots.Sum(x => x.VotingPower); - #endregion - - //#region temporary diagnostics - //var listing = Proto.Node.GetAsync($"chains/main/blocks/{block.Level}/context/raw/json/votes/listings?depth=1").Result - // .EnumerateArray() - // .ToDictionary(x => x[0].RequiredString(), x => x[1].RequiredInt64()); - - //if (snapshots.Count() != listing.Count) - // throw new Exception("Wrong voting snapshots"); - - //foreach (var snapshot in snapshots) - // if (!listing.TryGetValue(Cache.Accounts.GetDelegate(snapshot.BakerId).Address, out var votingPower) || snapshot.VotingPower != votingPower) - // throw new Exception("Wrong voting snapshot"); - //#endregion - - Db.VotingSnapshots.AddRange(snapshots); - Db.VotingPeriods.Add(period); - Cache.Periods.Add(period); - return period; - } - - protected virtual int GetParticipationEma(VotingPeriod period, Protocol proto) - { - var prev = Db.VotingPeriods - .AsNoTracking() - .OrderByDescending(x => x.Index) - .FirstOrDefault(x => x.Kind == PeriodKind.Exploration || x.Kind == PeriodKind.Promotion); - - if (prev != null) - { - var participation = 10000.MulRatio(prev.YayVotingPower!.Value + prev.NayVotingPower!.Value + prev.PassVotingPower!.Value, prev.TotalVotingPower); - return (int)((prev.ParticipationEma!.Value * 8000 + participation * 2000) / 10000); - } - - return 8000; - } - - protected virtual int GetBallotQuorum(VotingPeriod period, Protocol proto) - { - var prev = Db.VotingPeriods - .AsNoTracking() - .OrderByDescending(x => x.Index) - .FirstOrDefault(x => x.Kind == PeriodKind.Exploration || x.Kind == PeriodKind.Promotion); - - if (prev != null) - { - var participation = 10000.MulRatio(prev.YayVotingPower!.Value + prev.NayVotingPower!.Value + prev.PassVotingPower!.Value, prev.TotalVotingPower); - return (int)((prev.BallotsQuorum!.Value * 8000 + participation * 2000) / 10000); - } - - return 8000; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Diagnostics/Diagnostics.cs deleted file mode 100644 index 283165e07..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,218 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class Diagnostics(ProtocolHandler handler) : IDiagnostics - { - protected readonly TzktContext Db = handler.Db; - protected readonly CacheService Cache = handler.Cache; - protected readonly IRpc Rpc = handler.Rpc; - protected BlockContext Context => handler.Context; - - int AddedOperations = 0; - readonly Dictionary ChangedAccounts = []; - readonly Dictionary ChangedTicketBalances = []; - - public void TrackChanges() - { - var entries = Db.ChangeTracker.Entries(); - AddedOperations += entries.Count(x => x.Entity is BaseOperation or ContractEvent && x.State == EntityState.Added); - - foreach (var account in entries.Where(x => - x.Entity is Account && (x.State == EntityState.Modified || x.State == EntityState.Added)) - .Select(x => (x.Entity as Account)!)) - ChangedAccounts[account.Id] = account; - - foreach (var ticket in entries.Where(x => - x.Entity is TicketBalance && (x.State == EntityState.Modified || x.State == EntityState.Added)) - .Select(x => (x.Entity as TicketBalance)!)) - ChangedTicketBalances[ticket.Id] = ticket; - } - - public virtual Task Run(JsonElement block) - { - var ops = block.GetProperty("operations"); - var opsCount = 0; - - if (ops.EnumerateArray().Any()) - { - foreach (var op in ops[0].EnumerateArray()) - { - var content = op.RequiredArray("contents")[0]; - if (content.RequiredString("kind")[^1] == 'e') // .._aggregate - opsCount += content.RequiredArray("committee").Count(); - else - opsCount++; - } - foreach (var op in ops[1].EnumerateArray()) - { - var content = op.RequiredArray("contents")[0]; - if (content.RequiredString("kind")[0] == 'p') - opsCount += content.RequiredArray("proposals").Count(); - else - opsCount++; - } - opsCount += ops[2].Count(); - foreach (var op in ops[3].EnumerateArray()) - { - foreach (var content in op.Required("contents").EnumerateArray()) - { - opsCount++; - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalContents)) - opsCount += internalContents.EnumerateArray().Count(x => x.RequiredString("kind") != "event" || x.Required("result").RequiredString("status") == "applied"); - } - } - } - - return RunDiagnostics(block.Required("header").RequiredInt32("level"), opsCount); - } - - public virtual Task Run(int level) - { - return RunDiagnostics(level); - } - - protected virtual async Task RunDiagnostics(int level, int ops = -1) - { - if (ops != -1 && ops != AddedOperations + Context.TransactionOps.Count + Context.AttestationOps.Count) - throw new Exception($"Diagnostics failed: wrong operations count"); - - var state = Cache.AppState.Get(); - var proto = await Cache.Protocols.GetAsync(state.NextProtocol); - - foreach (var ticketBalance in ChangedTicketBalances.Values) - { - await TestTicketBalance(level, ticketBalance); - } - - await TestGlobalCounter(level, state); - - foreach (var account in ChangedAccounts.Values) - { - if (account is Data.Models.Delegate delegat) - await TestDelegate(level, delegat, proto); - - if (account.Type <= AccountType.Contract) - await TestAccount(level, account); - } - - if (Cache.Blocks.Current().Events.HasFlag(BlockEvents.CycleBegin)) - { - foreach (var cycle in Db.ChangeTracker.Entries().Where(x => x.Entity is Cycle).Select(x => (x.Entity as Cycle)!)) - await TestCycle(state, cycle); - - await TestParticipation(state); - await TestDalParticipation(state); - await TestBakersList(state); - await TestActiveBakersList(state); - } - } - - protected virtual Task TestParticipation(AppState state) => Task.CompletedTask; - - protected virtual Task TestDalParticipation(AppState state) => Task.CompletedTask; - - protected virtual Task TestCycle(AppState state, Cycle cycle) => Task.CompletedTask; - - protected virtual async Task TestBakersList(AppState state) - { - var local = Cache.Accounts.GetDelegates().ToList(); - var remote = (await Rpc.GetDelegatesAsync(state.Level)).EnumerateArray() - .Select(x => x.GetString()) - .ToHashSet(); - - if (local.Count != remote.Count) - throw new Exception("Invalid bakers count"); - - foreach (var baker in local) - if (!remote.Contains(baker.Address)) - throw new Exception($"Invalid baker {baker.Address}"); - } - - protected virtual async Task TestActiveBakersList(AppState state) - { - var local = Cache.Accounts.GetDelegates().Where(x => x.Staked).ToList(); - var remote = (await Rpc.GetActiveDelegatesAsync(state.Level)).EnumerateArray() - .Select(x => x.GetString()) - .ToHashSet(); - - if (local.Count != remote.Count) - throw new Exception("Invalid active bakers count"); - - foreach (var baker in local) - if (!remote.Contains(baker.Address)) - throw new Exception($"Invalid active baker {baker.Address}"); - } - - protected virtual async Task TestGlobalCounter(int level, AppState state) - { - if ((await Rpc.GetGlobalCounterAsync(level)).RequiredInt32() != state.ManagerCounter) - throw new Exception("Diagnostics failed: wrong global counter"); - } - - protected virtual async Task TestDelegate(int level, Data.Models.Delegate delegat, Protocol proto) - { - var remote = await Rpc.GetDelegateAsync(level, delegat.Address); - - if (remote.RequiredInt64("balance") != delegat.Balance) - throw new Exception($"Diagnostics failed: wrong balance {delegat.Address}"); - - if (remote.RequiredBool("deactivated") != !delegat.Staked) - throw new Exception($"Diagnostics failed: wrong delegate state {delegat.Address}"); - - var deactivationCycle = (delegat.DeactivationLevel - 1) >= proto.FirstLevel - ? proto.GetCycle(delegat.DeactivationLevel - 1) - : (await Cache.Blocks.GetAsync(delegat.DeactivationLevel - 1)).Cycle; - if (remote.RequiredInt32("grace_period") != deactivationCycle) - throw new Exception($"Diagnostics failed: wrong delegate grace period {delegat.Address}"); - - if (remote.RequiredInt64("staking_balance") != delegat.OwnDelegatedBalance + delegat.ExternalDelegatedBalance) - throw new Exception($"Diagnostics failed: wrong staking balance {delegat.Address}"); - - TestDelegatorsCount(remote, delegat); - } - - protected virtual void TestDelegatorsCount(JsonElement remote, Data.Models.Delegate local) - { - if (remote.RequiredArray("delegated_contracts").Count() != local.DelegatorsCount) - throw new Exception($"Diagnostics failed: wrong delegators count {local.Address}"); - } - - protected virtual async Task TestAccount(int level, Account account) - { - var remote = await Rpc.GetContractAsync(level, account.Address); - - if (account is not Data.Models.Delegate && remote.RequiredInt64("balance") != account.Balance - account.RollupBonds - - account.SmartRollupBonds - ((account as User)?.UnstakedBalance ?? 0)) - throw new Exception($"Diagnostics failed: wrong balance {account.Address}"); - - TestAccountDelegate(remote, account); - TestAccountCounter(remote, account); - } - - protected virtual Task TestTicketBalance(int level, TicketBalance ticketBalance) => Task.CompletedTask; - - protected virtual void TestAccountDelegate(JsonElement remote, Account local) - { - if (local.Type != AccountType.User) - return; - - var remoteDelegate = remote.Required("delegate").OptionalString("value"); - var localDelegate = Cache.Accounts.GetDelegate(local.DelegateId); - - if (remoteDelegate != localDelegate?.Address) - throw new Exception($"Diagnostics failed: wrong delegate {local.Address}"); - } - - protected virtual void TestAccountCounter(JsonElement remote, Account local) - { - if (remote.RequiredInt64("balance") > 0 && remote.RequiredInt32("counter") != local.Counter) - throw new Exception($"Diagnostics failed: wrong counter {local.Address}"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Helpers.cs deleted file mode 100644 index 8c3e61236..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Helpers.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - public class Helpers(ProtocolHandler proto) : IHelpers - { - protected CacheService Cache { get; } = proto.Cache; - protected BlockContext Context => proto.Context; - - public virtual long BakingPower(Data.Models.Delegate baker) - { - if (!baker.Staked) - return 0; - - var stake = baker.OwnDelegatedBalance + baker.ExternalDelegatedBalance; - if (stake < Context.Protocol.MinimalStake) - return 0; - - return stake - stake % Context.Protocol.MinimalStake; - } - - public virtual long VotingPower(Data.Models.Delegate baker) - { - if (!baker.Staked) - return 0; - - var stake = baker.OwnDelegatedBalance + baker.ExternalDelegatedBalance; - if (stake < Context.Protocol.MinimalStake) - return 0; - - return stake - stake % Context.Protocol.MinimalStake; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Proto1Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Proto1Handler.cs deleted file mode 100644 index c018ec2a9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Proto1Handler.cs +++ /dev/null @@ -1,224 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto1; - -namespace Tzkt.Sync.Protocols -{ - class Proto1Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "alpha"; - public override int VersionNumber => 1; - - public Proto1Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - // there were no voting operations - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - await new DelegationsCommit(this).Revert(currBlock, op); - break; - case OriginationOperation op: - await new OriginationsCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new FreezerCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Rpc/Rpc.cs deleted file mode 100644 index 39713baf6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Rpc/Rpc.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class Rpc(TezosNode node) : IRpc - { - protected readonly TezosNode Node = node; - - #region indexer - public virtual Task GetBlockAsync(int level) - => Node.GetAsync($"chains/main/blocks/{level}"); - - public virtual Task GetBakingRightsAsync(int block, int cycle) - => Node.GetAsync($"chains/main/blocks/{block}/helpers/baking_rights?cycle={cycle}&max_priority=8&all=true"); - - public virtual Task GetAttestationRightsAsync(int block, int cycle) - => Node.GetAsync($"chains/main/blocks/{block}/helpers/endorsing_rights?cycle={cycle}"); - - public virtual Task GetLevelBakingRightsAsync(int block, int level, int maxRound) - => Node.GetAsync($"chains/main/blocks/{block}/helpers/baking_rights?level={level}&max_priority={maxRound + 1}&all=true"); - - public virtual Task GetLevelAttestationRightsAsync(int block, int level) - => Node.GetAsync($"chains/main/blocks/{block}/helpers/endorsing_rights?level={level}"); - - public virtual Task GetContractAsync(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/contracts/{address}"); - - public virtual Task GetDelegateAsync(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/delegates/{address}"); - - public virtual Task GetExpectedIssuance(int block) - => throw new InvalidOperationException(); - - public virtual Task GetSmartRollupGenesisInfo(int level, string address) - => throw new InvalidOperationException(); - - public virtual Task GetUnstakeRequests(int level, string address) - => throw new InvalidOperationException(); - - public virtual Task GetContractRawAsync(int level, string address) - => throw new InvalidOperationException(); - #endregion - - #region diagnostics - public virtual Task GetGlobalCounterAsync(int level) - => Node.GetAsync($"chains/main/blocks/{level}/context/raw/json/contracts/global_counter"); - - public virtual Task GetDelegatesAsync(int level) - => Node.GetAsync($"chains/main/blocks/{level}/context/delegates?active=true&inactive=true"); - - public virtual Task GetActiveDelegatesAsync(int level) - => Node.GetAsync($"chains/main/blocks/{level}/context/delegates?active=true"); - - public virtual Task GetCycleAsync(int level, int cycle) - => Node.GetAsync($"chains/main/blocks/{level}/context/raw/json/cycle/{cycle}"); - - public virtual Task GetDelegateParticipationAsync(int level, string address) - => throw new InvalidOperationException(); - - public virtual Task GetDelegateDalParticipationAsync(int level, string address) - => throw new InvalidOperationException(); - - public virtual Task GetTicketBalance(int level, string address, string ticket) - => throw new InvalidOperationException(); - - public virtual Task GetCurrentStakingBalance(int level, string address) - => throw new InvalidOperationException(); - - public virtual Task GetStakingParameters(int level, string address) - => throw new InvalidOperationException(); - #endregion - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto1/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto1/Validation/Validator.cs deleted file mode 100644 index 8c7f5a059..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto1/Validation/Validator.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto1 -{ - class Validator(ProtocolHandler protocol) : IValidator - { - protected readonly CacheService Cache = protocol.Cache; - - public Task ValidateBlock(JsonElement block) - { - if (block.RequiredString("chain_id") != Cache.AppState.GetChainId()) - throw new ValidationException("invalid chain"); - - if (block.Required("header").RequiredInt32("level") != Cache.AppState.GetNextLevel()) - throw new ValidationException("invalid block level", true); - - if (block.Required("header").RequiredString("predecessor") != Cache.AppState.GetHead()) - throw new ValidationException("invalid block predecessor", true); - - if (block.RequiredString("protocol") != Cache.AppState.GetNextProtocol()) - throw new ValidationException("invalid block protocol", true); - - return Task.CompletedTask; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Activation/ProtoActivator.cs deleted file mode 100644 index fa4d22de4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Activation/ProtoActivator.cs +++ /dev/null @@ -1,835 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto10 -{ - class ProtoActivator(ProtocolHandler proto) : Proto9.ProtoActivator(proto) - { - public const string CpmmContract = "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5"; - public const string LiquidityToken = "KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo"; - public const string FallbackToken = "KT1VqarPDicMFn1ejmQqqshUkUXTCTXwmkCN"; - public const string Tzbtc = "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn"; - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - #region unchanged - protocol.RampUpCycles = parameters["security_deposit_ramp_up_cycles"]?.Value() ?? 0; - protocol.NoRewardCycles = parameters["no_reward_cycles"]?.Value() ?? 0; - protocol.ByteCost = parameters["cost_per_byte"]?.Value() ?? 250; - protocol.HardOperationGasLimit = parameters["hard_gas_limit_per_operation"]?.Value() ?? 1_040_000; - protocol.HardOperationStorageLimit = parameters["hard_storage_limit_per_operation"]?.Value() ?? 60_000; - protocol.OriginationSize = parameters["origination_size"]?.Value() ?? 257; - protocol.ConsensusRightsDelay = parameters["preserved_cycles"]?.Value() ?? 5; - protocol.ToleratedInactivityPeriod = protocol.ConsensusRightsDelay + 1; - protocol.MinimalStake = parameters["tokens_per_roll"]?.Value() ?? 8_000_000_000; - protocol.BallotQuorumMin = parameters["quorum_min"]?.Value() ?? 2000; - protocol.BallotQuorumMax = parameters["quorum_max"]?.Value() ?? 7000; - protocol.ProposalQuorum = parameters["min_proposal_quorum"]?.Value() ?? 500; - #endregion - - var br = parameters["baking_reward_per_endorsement"] as JArray; - var ar = parameters["endorsement_reward"] as JArray; - - protocol.BlockDeposit = parameters["block_security_deposit"]?.Value() ?? 640_000_000; - protocol.AttestationDeposit = parameters["endorsement_security_deposit"]?.Value() ?? 2_500_000; - protocol.BlockReward0 = br == null ? 78_125 : br.Count > 0 ? br[0].Value() : 0; - protocol.BlockReward1 = br == null ? 11_719 : br.Count > 1 ? br[1].Value() : protocol.BlockReward0; - protocol.AttestationReward0 = ar == null ? 78_125 : ar.Count > 0 ? ar[0].Value() : 0; - protocol.AttestationReward1 = ar == null ? 52_083 : ar.Count > 1 ? ar[1].Value() : protocol.AttestationReward0; - - protocol.BlocksPerCycle = parameters["blocks_per_cycle"]?.Value() ?? 8192; - protocol.BlocksPerCommitment = parameters["blocks_per_commitment"]?.Value() ?? 64; - protocol.BlocksPerSnapshot = parameters["blocks_per_roll_snapshot"]?.Value() ?? 512; - protocol.BlocksPerVoting = parameters["blocks_per_voting_period"]?.Value() ?? 40960; - - protocol.AttestersPerBlock = parameters["endorsers_per_block"]?.Value() ?? 256; - protocol.HardBlockGasLimit = parameters["hard_gas_limit_per_block"]?.Value() ?? 5_200_000; - protocol.TimeBetweenBlocks = parameters["minimal_block_delay"]?.Value() ?? 30; - - protocol.LBToggleThreshold = (parameters["liquidity_baking_escape_ema_threshold"]?.Value() ?? 1_000_000) * 1000; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.BlockDeposit = 640_000_000; - protocol.AttestationDeposit = 2_500_000; - protocol.BlockReward0 = 78_125; - protocol.BlockReward1 = 11_719; - protocol.AttestationReward0 = 78_125; - protocol.AttestationReward1 = 52_083; - - protocol.BlocksPerCycle *= 2; - protocol.BlocksPerCommitment *= 2; - protocol.BlocksPerSnapshot *= 2; - protocol.BlocksPerVoting *= 2; - - protocol.AttestersPerBlock = 256; - protocol.HardBlockGasLimit = 5_200_000; - protocol.TimeBetweenBlocks /= 2; - - protocol.LBToggleThreshold = 1_000_000_000; - } - - protected override async Task ActivateContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - await OriginateContract(block, CpmmContract); - await OriginateContract(block, LiquidityToken); - if (!await Cache.Accounts.ExistsAsync(Tzbtc)) - await OriginateContract(block, FallbackToken); - } - - protected override async Task DeactivateContext(AppState state) - { - state.TokensCount--; - state.TokenBalancesCount--; - state.TokenTransfersCount--; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BigMapUpdates"; - DELETE FROM "BigMapKeys"; - DELETE FROM "BigMaps"; - DELETE FROM "Tokens"; - DELETE FROM "TokenBalances"; - DELETE FROM "TokenTransfers"; - """); - Cache.BigMapKeys.Reset(); - Cache.BigMaps.Reset(); - Cache.Tokens.Reset(); - Cache.TokenBalances.Reset(); - - Cache.AppState.Get().BigMapCounter = 0; - Cache.AppState.Get().BigMapKeyCounter = 0; - Cache.AppState.Get().BigMapUpdateCounter = 0; - } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - #region update voting period - var newPeriod = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(newPeriod); - newPeriod.LastLevel = newPeriod.FirstLevel + nextProto.BlocksPerVoting; // - 1 + 1 - #endregion - - var cycles = await MigrateCycles(state, nextProto); - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" > {0} - """, state.Cycle); - await MigrateCurrentRights(state, prevProto, nextProto, state.Level); - await MigrateFutureRights(cycles, state, nextProto, state.Level); - MigrateDelegates(state, prevProto, nextProto); - - Cache.BakingRights.Reset(); - Cache.BakerCycles.Reset(); - Cache.Periods.Reset(); - - var block = await Cache.Blocks.CurrentAsync(); - await OriginateContract(block, CpmmContract); - await OriginateContract(block, LiquidityToken); - if (!await Cache.Accounts.ExistsAsync(Tzbtc)) - await OriginateContract(block, FallbackToken); - } - - protected override async Task RevertContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - #region update voting periods - var newPeriod = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(newPeriod); - newPeriod.LastLevel = newPeriod.FirstLevel + prevProto.BlocksPerVoting - 1; - #endregion - - var cycles = await MigrateCycles(state, prevProto); - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" > {0} - """, state.Cycle); - await MigrateCurrentRights(state, nextProto, prevProto, state.Level - 1); - await MigrateFutureRights(cycles, state, prevProto, state.Level - 1); - MigrateDelegates(state, nextProto, prevProto); - - Cache.BakingRights.Reset(); - Cache.BakerCycles.Reset(); - Cache.Periods.Reset(); - - await RemoveContract(CpmmContract); - await RemoveContract(LiquidityToken); - if (await Cache.Accounts.ExistsAsync(FallbackToken)) - await RemoveContract(FallbackToken); - } - - async Task> MigrateCycles(AppState state, Protocol nextProto) - { - var cycles = await Db.Cycles - .Where(x => x.Index > state.Cycle) - .OrderBy(x => x.Index) - .ToListAsync(); - - foreach (var cycle in cycles) - { - cycle.FirstLevel = nextProto.GetCycleStart(cycle.Index); - cycle.LastLevel = nextProto.GetCycleEnd(cycle.Index); - } - - return cycles; - } - - async Task MigrateCurrentRights(AppState state, Protocol prevProto, Protocol nextProto, int block) - { - var rights = await Db.BakingRights - .AsNoTracking() - .Where(x => x.Level > state.Level && x.Cycle == state.Cycle) - .ToListAsync(); - - foreach (var br in rights.Where(x => x.Type == BakingRightType.Baking && x.Round == 0)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(state.Cycle, br.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlockRewards -= GetFutureBlockReward(prevProto, state.Cycle); - bakerCycle.FutureBlockRewards += GetFutureBlockReward(nextProto, state.Cycle); - } - - foreach (var ar in rights.Where(x => x.Type == BakingRightType.Attestation)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(state.Cycle, ar.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureAttestationRewards -= GetFutureAttestationReward(prevProto, state.Cycle, ar.Slots!.Value); - bakerCycle.FutureAttestations -= ar.Slots.Value; - } - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Level" > {0} - AND "Type" = {1} - """, state.Level, (int)BakingRightType.Attestation); - - var newArs = new List(); - for (int level = state.Level + 1; level < nextProto.GetCycleStart(state.Cycle + 1); level++) - { - foreach (var ar in (await Proto.Rpc.GetLevelAttestationRightsAsync(block, level - 1)).EnumerateArray()) - { - newArs.Add(new BakingRight - { - Id = 0, - Type = BakingRightType.Attestation, - Status = BakingRightStatus.Future, - BakerId = Cache.Accounts.GetExistingDelegate(ar.RequiredString("delegate")).Id, - Cycle = state.Cycle, - Level = level, - Slots = ar.RequiredArray("slots").Count() - }); - } - } - -#pragma warning disable EF1002 // Risk of vulnerability to SQL injection. - await Db.Database.ExecuteSqlRawAsync($""" - INSERT INTO "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Slots") VALUES - {string.Join(',', newArs.Select(ar => $"({ar.Cycle},{ar.Level},{ar.BakerId},{(int)ar.Type},{(int)ar.Status},{ar.Slots})"))} - """); -#pragma warning restore EF1002 // Risk of vulnerability to SQL injection. - - foreach (var ar in newArs) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(state.Cycle, ar.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(nextProto, state.Cycle, ar.Slots!.Value); - bakerCycle.FutureAttestations += ar.Slots.Value; - } - } - - async Task MigrateFutureRights(List cycles, AppState state, Protocol nextProto, int block) - { - var nextCycle = state.Cycle + 1; - var nextCycleStart = nextProto.GetCycleStart(nextCycle); - var shiftedRights = (await Proto.Rpc.GetLevelAttestationRightsAsync(block, nextCycleStart - 1)) - .EnumerateArray() - .ToList(); - -#pragma warning disable EF1002 // Risk of vulnerability to SQL injection. - await Db.Database.ExecuteSqlRawAsync($""" - INSERT INTO "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Slots") VALUES - {string.Join(',', shiftedRights.Select(ar => $@"( - {nextCycle}, - {nextCycleStart}, - {Cache.Accounts.GetExistingDelegate(ar.RequiredString("delegate")).Id}, - {(int)BakingRightType.Attestation}, - {(int)BakingRightStatus.Future}, - {ar.RequiredArray("slots").Count()} - )"))} - """); -#pragma warning restore EF1002 // Risk of vulnerability to SQL injection. - - foreach (var cycle in cycles) - { - var bakerCycles = (await Db.BakerCycles.Where(x => x.Cycle == cycle.Index).ToListAsync()) - .ToDictionary(x => x.BakerId); - - foreach (var bc in bakerCycles.Values) - { - var share = (double)bc.BakingPower / cycle.TotalBakingPower; - bc.ExpectedBlocks = nextProto.BlocksPerCycle * share; - bc.ExpectedAttestations = nextProto.AttestersPerBlock * nextProto.BlocksPerCycle * share; - bc.FutureBlockRewards = 0; - bc.FutureBlocks = 0; - bc.FutureAttestationRewards = 0; - bc.FutureAttestations = 0; - } - - await FetchBakingRights(nextProto, block, cycle, bakerCycles); - shiftedRights = await FetchAttestationRights(nextProto, block, cycle, bakerCycles, shiftedRights); - } - } - - async Task FetchBakingRights(Protocol protocol, int block, Cycle cycle, Dictionary bakerCycles) - { - GC.Collect(); - var rights = (await Proto.Rpc.GetBakingRightsAsync(block, cycle.Index)).RequiredArray().EnumerateArray(); - if (!rights.Any() || rights.Count(x => x.RequiredInt32("priority") == 0) != protocol.BlocksPerCycle) - throw new ValidationException("Rpc returned less baking rights (with priority 0) than it should be"); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@"COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") FROM STDIN (FORMAT BINARY)"); - - foreach (var br in rights) - { - var bakerId = Cache.Accounts.GetExistingDelegate(br.RequiredString("delegate")).Id; - var round = br.RequiredInt32("priority"); - if (round == 0) - { - var bakerCycle = bakerCycles[bakerId]; - bakerCycle.FutureBlockRewards += GetFutureBlockReward(protocol, cycle.Index); - bakerCycle.FutureBlocks++; - } - - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.RequiredInt32("level"), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(bakerId, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - - async Task> FetchAttestationRights(Protocol protocol, int block, Cycle cycle, Dictionary bakerCycles, List shiftedRights) - { - GC.Collect(); - var rights = (await Proto.Rpc.GetAttestationRightsAsync(block, cycle.Index)).RequiredArray().EnumerateArray(); - //var rights = new List(protocol.BlocksPerCycle * protocol.AttestersPerBlock / 2); - //var attempts = 0; - - //for (int level = cycle.FirstLevel; level <= cycle.LastLevel; level++) - //{ - // try - // { - // rights.AddRange((await Proto.Rpc.GetLevelAttestationRightsAsync(block, level)).RequiredArray().EnumerateArray()); - // attempts = 0; - // } - // catch (Exception ex) - // { - // Logger.LogError(ex, "Failed to fetch attestation rights for level {level}", level); - // if (++attempts >= 10) throw new Exception("Too many RPC errors when fetching attestation rights"); - // await Task.Delay(3000); - // level--; - // } - //} - - if (!rights.Any() || rights.Sum(x => x.RequiredArray("slots").Count()) != protocol.BlocksPerCycle * protocol.AttestersPerBlock) - throw new ValidationException("Rpc returned less attestation rights (slots) than it should be"); - - #region save rights - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@"COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") FROM STDIN (FORMAT BINARY)"); - - foreach (var ar in rights) - { - writer.StartRow(); - writer.Write(protocol.GetCycle(ar.RequiredInt32("level") + 1), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.RequiredInt32("level") + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(Cache.Accounts.GetExistingDelegate(ar.RequiredString("delegate")).Id, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.RequiredArray("slots").Count(), NpgsqlTypes.NpgsqlDbType.Integer); - } - - writer.Complete(); - #endregion - - foreach (var ar in rights.Where(x => x.RequiredInt32("level") != cycle.LastLevel)) - { - var baker = Cache.Accounts.GetExistingDelegate(ar.RequiredString("delegate")); - var slots = ar.RequiredArray("slots").Count(); - - if (!bakerCycles.TryGetValue(baker.Id, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(protocol, cycle.Index, slots); - bakerCycle.FutureAttestations += slots; - } - - foreach (var ar in shiftedRights) - { - var baker = Cache.Accounts.GetExistingDelegate(ar.RequiredString("delegate")); - var slots = ar.RequiredArray("slots").Count(); - - if (!bakerCycles.TryGetValue(baker.Id, out var bakerCycle)) - { - #region shifting hack - var snapshottedBaker = await Proto.Rpc.GetDelegateAsync(cycle.SnapshotLevel, baker.Address); - var delegators = snapshottedBaker - .RequiredArray("delegated_contracts") - .EnumerateArray() - .Select(x => x.RequiredString()) - .Where(x => x != baker.Address); - - var stakingBalance = snapshottedBaker.RequiredInt64("staking_balance"); - var delegatedBalance = snapshottedBaker.RequiredInt64("delegated_balance"); - - bakerCycle = new BakerCycle - { - Id = 0, - Cycle = cycle.Index, - BakerId = baker.Id, - OwnDelegatedBalance = stakingBalance - delegatedBalance, - ExternalDelegatedBalance = delegatedBalance, - DelegatorsCount = delegators.Count(), - OwnStakedBalance = 0, - ExternalStakedBalance = 0, - StakersCount = 0, - IssuedPseudotokens = null, - BakingPower = 0, - TotalBakingPower = cycle.TotalBakingPower, - ExpectedBlocks = 0, - ExpectedAttestations = 0 - }; - bakerCycles.Add(baker.Id, bakerCycle); - Db.BakerCycles.Add(bakerCycle); - - foreach (var delegatorAddress in delegators) - { - var snapshottedDelegator = await Proto.Rpc.GetContractAsync(cycle.SnapshotLevel, delegatorAddress); - Db.DelegatorCycles.Add(new DelegatorCycle - { - Id = 0, - Cycle = cycle.Index, - DelegatorId = (await Cache.Accounts.GetExistingAsync(delegatorAddress)).Id, - BakerId = baker.Id, - DelegatedBalance = snapshottedDelegator.RequiredInt64("balance"), - StakedPseudotokens = null - }); - } - #endregion - } - - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(protocol, cycle.Index, slots); - bakerCycle.FutureAttestations += slots; - } - - return rights.Where(x => x.RequiredInt32("level") == cycle.LastLevel).ToList(); - } - - void MigrateDelegates(AppState state, Protocol prevProto, Protocol nextProto) - { - foreach (var delegat in Cache.Accounts.GetDelegates().Where(x => x.DeactivationLevel > state.Level)) - { - Db.TryAttach(delegat); - delegat.DeactivationLevel = nextProto.GetCycleStart(prevProto.GetCycle(delegat.DeactivationLevel)); - } - } - - async Task OriginateContract(Block block, string address) - { - var rawContract = await Proto.Rpc.GetContractAsync(block.Level, address); - - #region contract - Contract contract; - var creator = await Cache.Accounts.GetExistingAsync(NullAddress.Address); - var ghost = await Cache.Accounts.GetAsync(address); - if (ghost != null) - { - contract = new Contract - { - Id = ghost.Id, - Index = ghost.Index, - FirstLevel = ghost.FirstLevel, - LastLevel = block.Level, - Address = address, - CreatorId = creator.Id, - Type = AccountType.Contract, - Kind = ContractKind.SmartContract, - MigrationsCount = 1, - ActiveTokensCount = ghost.ActiveTokensCount, - TokenBalancesCount = ghost.TokenBalancesCount, - TokenTransfersCount = ghost.TokenTransfersCount - }; - Db.Entry(ghost).State = EntityState.Detached; - Db.Entry(contract).State = EntityState.Modified; - } - else - { - contract = new Contract - { - Id = Cache.AppState.NextAccountId(), - FirstLevel = block.Level, - LastLevel = block.Level, - Address = address, - CreatorId = creator.Id, - Type = AccountType.Contract, - Kind = ContractKind.SmartContract, - MigrationsCount = 1, - }; - Db.Accounts.Add(contract); - } - Receive(contract, rawContract.RequiredInt64("balance")); - Cache.Accounts.Add(contract); - - Db.TryAttach(creator); - creator.ContractsCount++; - #endregion - - #region script - var code = (rawContract.Required("script").RequiredMicheline("code") as MichelineArray)!; - var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter); - var micheStorage = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage); - var micheCode = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code); - var micheViews = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view); - var script = new Script - { - Id = Cache.AppState.NextScriptId(), - Level = block.Level, - ContractId = contract.Id, - ParameterSchema = micheParameter.ToBytes(), - StorageSchema = micheStorage.ToBytes(), - CodeSchema = micheCode.ToBytes(), - Views = micheViews.Any() - ? micheViews.Select(x => x.ToBytes()).ToArray() - : null, - Current = true - }; - - var viewsBytes = script.Views? - .OrderBy(x => x, new BytesComparer()) - .SelectMany(x => x) - .ToArray() - ?? []; - var typeSchema = script.ParameterSchema.Concat(script.StorageSchema).Concat(viewsBytes); - var fullSchema = typeSchema.Concat(script.CodeSchema); - contract.TypeHash = script.TypeHash = Script.GetHash(typeSchema); - contract.CodeHash = script.CodeHash = Script.GetHash(fullSchema); - - if (script.Schema.IsFA1()) - { - if (script.Schema.IsFA12()) - contract.Tags |= ContractTags.FA12; - - contract.Tags |= ContractTags.FA1; - contract.Kind = ContractKind.Asset; - } - if (script.Schema.IsFA2()) - { - contract.Tags |= ContractTags.FA2; - contract.Kind = ContractKind.Asset; - } - - Db.Scripts.Add(script); - #endregion - - #region storage - var storageValue = rawContract.Required("script").RequiredMicheline("storage"); - var storage = new Storage - { - Id = Cache.AppState.NextStorageId(), - Level = block.Level, - ContractId = contract.Id, - RawValue = script.Schema.OptimizeStorage(storageValue, false).ToBytes(), - JsonValue = script.Schema.HumanizeStorage(storageValue), - Current = true - }; - - Db.Storages.Add(storage); - #endregion - - #region migration - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - Kind = MigrationKind.Origination, - AccountId = contract.Id, - BalanceChange = contract.Balance, - ScriptId = script.Id, - StorageId = storage.Id, - }; - - script.MigrationId = migration.Id; - storage.MigrationId = migration.Id; - - Db.TryAttach(block); - block.Operations |= Operations.Migrations; - - var state = Cache.AppState.Get(); - Db.TryAttach(state); - state.MigrationOpsCount++; - - var stats = Cache.Statistics.Current; - Db.TryAttach(stats); - stats.TotalCreated += contract.Balance; - - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - #endregion - - #region bigmaps - var storageScript = new ContractStorage(micheStorage); - var storageTree = storageScript.Schema.ToTreeView(storageValue); - var bigmaps = storageTree.Nodes() - .Where(x => x.Schema is BigMapSchema) - .Select(x => (x, (x.Schema as BigMapSchema)!, (int)(x.Value as MichelineInt)!.Value)); - - foreach (var (bigmap, schema, ptr) in bigmaps) - { - block.Events |= BlockEvents.Bigmaps; - - migration.BigMapUpdates = (migration.BigMapUpdates ?? 0) + 1; - Db.BigMapUpdates.Add(new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.Allocate, - BigMapPtr = ptr, - Level = block.Level, - MigrationId = migration.Id - }); - - var allocated = new BigMap - { - Id = Cache.AppState.NextBigMapId(), - Ptr = ptr, - ContractId = contract.Id, - StoragePath = bigmap.Path, - KeyType = schema.Key.ToMicheline().ToBytes(), - ValueType = schema.Value.ToMicheline().ToBytes(), - Active = true, - FirstLevel = block.Level, - LastLevel = block.Level, - ActiveKeys = 0, - TotalKeys = 0, - Updates = 1, - Tags = BigMaps.GetTags(contract, bigmap) - }; - Db.BigMaps.Add(allocated); - - if (address == LiquidityToken && allocated.StoragePath == "tokens") - { - var rawKey = new MichelineString(NullAddress.Address); - var rawValue = new MichelineInt(100); - - allocated.Tags |= BigMapTag.Ledger1; - allocated.ActiveKeys++; - allocated.TotalKeys++; - allocated.Updates++; - var key = new BigMapKey - { - Id = Cache.AppState.NextBigMapKeyId(), - Active = true, - BigMapPtr = ptr, - FirstLevel = block.Level, - LastLevel = block.Level, - JsonKey = schema.Key.Humanize(rawKey), - JsonValue = schema.Value.Humanize(rawValue), - RawKey = schema.Key.Optimize(rawKey).ToBytes(), - RawValue = schema.Value.Optimize(rawValue).ToBytes(), - KeyHash = schema.GetKeyHash(rawKey), - Updates = 1 - }; - Db.BigMapKeys.Add(key); - - migration.BigMapUpdates++; - Db.BigMapUpdates.Add(new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.AddKey, - BigMapKeyId = key.Id, - BigMapPtr = key.BigMapPtr, - JsonValue = key.JsonValue, - RawValue = key.RawValue, - Level = key.LastLevel, - MigrationId = migration.Id - }); - - #region tokens - var token = new Token - { - Id = Cache.AppState.NextSubId(migration), - Tags = TokenTags.Fa12, - BalancesCount = 1, - ContractId = contract.Id, - FirstMinterId = contract.Id, - FirstLevel = migration.Level, - HoldersCount = 1, - LastLevel = migration.Level, - TokenId = 0, - TotalBurned = 0, - TotalMinted = 100, - TotalSupply = 100, - TransfersCount = 1 - }; - var tokenBalance = new TokenBalance - { - Id = Cache.AppState.NextSubId(migration), - AccountId = NullAddress.Id, - Balance = 100, - FirstLevel = migration.Level, - LastLevel = migration.Level, - TokenId = token.Id, - ContractId = token.ContractId, - TransfersCount = 1 - }; - var tokenTransfer = new TokenTransfer - { - Id = Cache.AppState.NextSubId(migration), - Amount = 100, - Level = migration.Level, - MigrationId = migration.Id, - ToId = NullAddress.Id, - TokenId = token.Id, - ContractId = token.ContractId - }; - - Db.Tokens.Add(token); - Db.TokenBalances.Add(tokenBalance); - Db.TokenTransfers.Add(tokenTransfer); - - migration.TokenTransfers = 1; - - state.TokensCount++; - state.TokenBalancesCount++; - state.TokenTransfersCount++; - - contract.TokensCount++; - creator.ActiveTokensCount++; - creator.TokenBalancesCount++; - creator.TokenTransfersCount++; - creator.LastLevel = tokenTransfer.Level; - - block.Events |= BlockEvents.Tokens; - #endregion - } - else if (address == FallbackToken && allocated.StoragePath == "tokens") - { - allocated.Tags |= BigMapTag.Ledger1; - } - } - #endregion - } - - async Task RemoveContract(string address) - { - var contract = (await Cache.Accounts.GetExistingAsync(address) as Contract)!; - Db.TryAttach(contract); - - var bigmaps = await Db.BigMaps.AsNoTracking() - .Where(x => x.ContractId == contract.Id) - .ToListAsync(); - - var state = Cache.AppState.Get(); - Db.TryAttach(state); - state.MigrationOpsCount--; - - var creator = await Cache.Accounts.GetAsync(contract.CreatorId); - Db.TryAttach(creator); - creator.ContractsCount--; - - if (address == LiquidityToken) - { - var token = await Db.Tokens - .AsNoTracking() - .Where(x => x.ContractId == contract.Id) - .SingleAsync(); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "TokenTransfers" WHERE "TokenId" = {0}; - DELETE FROM "TokenBalances" WHERE "TokenId" = {0}; - DELETE FROM "Tokens" WHERE "Id" = {0}; - """, token.Id); - - state.TokenTransfersCount--; - state.TokenBalancesCount--; - state.TokensCount--; - - contract.TokensCount--; - - creator.ActiveTokensCount--; - creator.TokenBalancesCount--; - creator.TokenTransfersCount--; - } - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "MigrationOps" WHERE "AccountId" = {0}; - DELETE FROM "Storages" WHERE "ContractId" = {0}; - DELETE FROM "Scripts" WHERE "ContractId" = {0}; - DELETE FROM "BigMapUpdates" WHERE "BigMapPtr" = ANY({1}); - DELETE FROM "BigMapKeys" WHERE "BigMapPtr" = ANY({1}); - DELETE FROM "BigMaps" WHERE "Ptr" = ANY({1}); - """, contract.Id, bigmaps.Select(x => x.Ptr).ToList()); - - Cache.AppState.ReleaseOperationId(); - Cache.AppState.ReleaseScriptId(); - Cache.AppState.ReleaseStorageId(); - Cache.Storages.Remove(contract); - Cache.Schemas.Remove(contract); - Cache.BigMapKeys.Reset(); - foreach (var bigmap in bigmaps) - { - Cache.BigMaps.Remove(bigmap); - Cache.AppState.ReleaseBigMapId(); - Cache.AppState.ReleaseBigMapKeyId(bigmap.TotalKeys); - Cache.AppState.ReleaseBigMapUpdateId(bigmap.Updates); - } - - if (contract.TokenTransfersCount != 0) - { - var ghost = new Account - { - Id = contract.Id, - Index = contract.Index, - Address = contract.Address, - FirstLevel = contract.FirstLevel, - LastLevel = contract.LastLevel, - ActiveTokensCount = contract.ActiveTokensCount, - TokenBalancesCount = contract.TokenBalancesCount, - TokenTransfersCount = contract.TokenTransfersCount, - Type = AccountType.Ghost, - }; - - Db.Entry(contract).State = EntityState.Detached; - Db.Entry(ghost).State = EntityState.Modified; - Cache.Accounts.Add(ghost); - } - } - - protected override long GetFutureBlockReward(Protocol protocol, int cycle) - => cycle < protocol.NoRewardCycles ? 0 : (protocol.BlockReward0 * protocol.AttestersPerBlock); - - protected override long GetFutureAttestationReward(Protocol protocol, int cycle, int slots) - => cycle < protocol.NoRewardCycles ? 0 : (slots * protocol.AttestationReward0); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BakerCycleCommit.cs deleted file mode 100644 index 7c9211168..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class BakerCycleCommit : Proto6.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BakingRightsCommit.cs deleted file mode 100644 index 0d7a1ea7e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto10 -{ - class BakingRightsCommit(ProtocolHandler protocol) : Proto3.BakingRightsCommit(protocol) - { - // Tezos node is no longer able to normally return attestation rights for a cycle, - // so we have to temporarily add some crutches, until we implement rights calculation - protected override async Task> GetAttestationRights(Block block, Protocol protocol, int cycle) - { - Logger.LogInformation("Load attestation rights"); - try - { - Logger.LogInformation("Trying to load by cycle with 30 minutes timeout..."); - #region try aggressive - var res = await Proto.Node.GetAsync($"chains/main/blocks/{block.Level}/helpers/endorsing_rights?cycle={cycle}", TimeSpan.FromMinutes(30)); - - var rights = res.RequiredArray().EnumerateArray(); - if (!rights.Any() || rights.Sum(x => x.RequiredArray("slots").Count()) != protocol.BlocksPerCycle * protocol.AttestersPerBlock) - throw new ValidationException("Rpc returned less attestation rights (slots) than expected"); - - return rights; - #endregion - } - catch - { - Logger.LogInformation("Failed to load by cycle. Loading by level for {cnt} blocks with 10 seconds timeout...", protocol.BlocksPerCycle); - #region throttle - var rights = new List(protocol.BlocksPerCycle * protocol.AttestersPerBlock / 2); - var firstLevel = protocol.GetCycleStart(cycle); - var lastLevel = protocol.GetCycleEnd(cycle); - var attempts = 0; - - for (int level = firstLevel; level <= lastLevel; level++) - { - try - { - var res = await Proto.Node.GetAsync($"chains/main/blocks/{block.Level}/helpers/endorsing_rights?level={level}", TimeSpan.FromSeconds(10)); - - rights.AddRange(res.RequiredArray().EnumerateArray()); - attempts = 0; - - if (level % 128 == 0) - Logger.LogInformation("Loaded {cnt} of {total} blocks", level - firstLevel + 1, lastLevel - firstLevel + 1); - } - catch (Exception ex) - { - Logger.LogError(ex, "Failed to fetch attestation rights for level {level}. Retrying...", level); - if (++attempts >= 30) throw new Exception("Too many RPC errors when fetching attestation rights"); - await Task.Delay(1000); - level--; - } - } - - if (rights.Count == 0 || rights.Sum(x => x.RequiredArray("slots").Count()) != protocol.BlocksPerCycle * protocol.AttestersPerBlock) - throw new ValidationException("Rpc returned less attestation rights (slots) than expected"); - - return rights; - #endregion - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BigMapCommit.cs deleted file mode 100644 index 321c55354..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BigMapCommit.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Netezos.Contracts; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto10 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override BigMapTag GetTags(Contract contract, TreeView node) - { - var tags = base.GetTags(contract, node); - - // custom handler for QUIPU - if (contract.Address == "KT193D4vozYnhGJQVtw7CoxxqphqUEEwK6Vb" && - (node.Value as MichelineInt)!.Value == 12043) // %account_info - tags |= BigMapTag.Ledger11; - - return tags; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BlockCommit.cs deleted file mode 100644 index 292e88448..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/BlockCommit.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto10 -{ - class BlockCommit : Proto9.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override bool? GetLBToggleVote(JsonElement block) - => !block.Required("header").RequiredBool("liquidity_baking_escape_vote"); - - protected override int GetLBToggleEma(JsonElement block) - => block.Required("metadata").RequiredInt32("liquidity_baking_escape_ema") * 1000; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/CycleCommit.cs deleted file mode 100644 index 1ac514850..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/DeactivationCommit.cs deleted file mode 100644 index f1c6b1732..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 737b173ef..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/FreezerCommit.cs deleted file mode 100644 index 55b440804..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class FreezerCommit : Proto9.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 0a83f36c9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index c3986217b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 060200878..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index c06fbeb55..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index f5f249012..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 11e5e96cd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class DoubleConsensusCommit : Proto4.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index fd6a69403..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 9b9e19d0e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class OriginationsCommit : Proto5.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 3de3ef9d1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 4de9be436..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index d2f61d126..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class TransactionsCommit : Proto5.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index 0666ae67c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class RevelationPenaltyCommit : Proto9.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 9bb6caa3e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class SnapshotBalanceCommit : Proto9.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SoftwareCommit.cs deleted file mode 100644 index 06d074a8c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/StateCommit.cs deleted file mode 100644 index 4a88c1e52..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/StatisticsCommit.cs deleted file mode 100644 index 29f62c63f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SubsidyCommit.cs deleted file mode 100644 index 3f2414b7c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto10 -{ - class SubsidyCommit : ProtocolCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - - public virtual async Task Apply(Block block, JsonElement content) - { - var balanceUpdate = content.RequiredArray("balance_updates").EnumerateArray() - .First(x => x.RequiredString("kind") == "contract"); - var contract = (await Cache.Accounts.GetExistingAsync(balanceUpdate.RequiredString("contract")) as Contract)!; - Db.TryAttach(contract); - var op = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - AccountId = contract.Id, - BalanceChange = balanceUpdate.RequiredInt64("change"), - Level = block.Level, - Timestamp = block.Timestamp, - Kind = MigrationKind.Subsidy, - }; - Db.MigrationOps.Add(op); - Context.MigrationOps.Add(op); - Cache.AppState.Get().MigrationOpsCount++; - - Cache.Statistics.Current.TotalCreated += op.BalanceChange; - - contract.MigrationsCount++; - Receive(contract, null, op.BalanceChange); - - block.Operations |= Operations.Migrations; - - var schema = await Cache.Schemas.GetAsync(contract); - var currStorage = await Cache.Storages.GetAsync(contract); - - Db.TryAttach(currStorage); - currStorage.Current = false; - - var newStorageMicheline = schema.OptimizeStorage(content.RequiredMicheline("storage"), false); - var newStorageBytes = newStorageMicheline.ToBytes(); - var newStorage = new Storage - { - Id = Cache.AppState.NextStorageId(), - Level = op.Level, - ContractId = contract.Id, - MigrationId = op.Id, - RawValue = newStorageBytes, - JsonValue = schema.HumanizeStorage(newStorageMicheline), - Current = true, - }; - - Db.Storages.Add(newStorage); - Cache.Storages.Add(contract, newStorage); - - op.StorageId = newStorage.Id; - } - - public virtual async Task Revert(Block block) - { - foreach (var op in Context.MigrationOps.Where(x => x.Kind == MigrationKind.Subsidy)) - { - var contract = (await Cache.Accounts.GetAsync(op.AccountId) as Contract)!; - Db.TryAttach(contract); - contract.MigrationsCount--; - RevertReceive(contract, null, op.BalanceChange); - - Cache.AppState.Get().MigrationOpsCount--; - Cache.AppState.ReleaseOperationId(); - Db.MigrationOps.Remove(op); - - var storage = await Cache.Storages.GetAsync(contract); - if (storage.MigrationId == op.Id) - { - var prevStorage = await Db.Storages - .Where(x => x.ContractId == contract.Id && x.Id < storage.Id) - .OrderByDescending(x => x.Id) - .FirstAsync(); - - prevStorage.Current = true; - Cache.Storages.Add(contract, prevStorage); - - Db.Storages.Remove(storage); - Cache.AppState.ReleaseStorageId(); - } - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/TokensCommit.cs deleted file mode 100644 index 908144f71..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/VotingCommit.cs deleted file mode 100644 index d4a2d5cbf..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class VotingCommit : Proto8.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Diagnostics/Diagnostics.cs deleted file mode 100644 index d44966493..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class Diagnostics : Proto5.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Helpers.cs deleted file mode 100644 index ee439ccce..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Proto10Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Proto10Handler.cs deleted file mode 100644 index 1f2473f11..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Proto10Handler.cs +++ /dev/null @@ -1,292 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto10; - -namespace Tzkt.Sync.Protocols -{ - class Proto10Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "granada_010"; - public override int VersionNumber => 10; - - public Proto10Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement_with_slot": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - await new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - await new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Rpc/Rpc.cs deleted file mode 100644 index 4fe06c26b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto10 -{ - class Rpc : Proto6.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto10/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto10/Validation/Validator.cs deleted file mode 100644 index b3a89bf07..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto10/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto10 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Activation/ProtoActivator.cs deleted file mode 100644 index ae12ad987..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Activation/ProtoActivator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto11 -{ - class ProtoActivator : Proto10.ProtoActivator - { - public ProtoActivator(ProtocolHandler proto) : base(proto) { } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) { } - protected override Task MigrateContext(AppState state) => Task.CompletedTask; - protected override Task RevertContext(AppState state) => Task.CompletedTask; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BakerCycleCommit.cs deleted file mode 100644 index 2cd03882e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class BakerCycleCommit : Proto6.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BakingRightsCommit.cs deleted file mode 100644 index 73971fab0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class BakingRightsCommit : Proto10.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BigMapCommit.cs deleted file mode 100644 index 63feda26e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BlockCommit.cs deleted file mode 100644 index 2e11ab657..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class BlockCommit : Proto10.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/CycleCommit.cs deleted file mode 100644 index 505e22983..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/DeactivationCommit.cs deleted file mode 100644 index 5b957eed9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 7c50482f6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/FreezerCommit.cs deleted file mode 100644 index 0015f29dd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class FreezerCommit : Proto9.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index c12f8ff00..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 82bf0480e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index f4ed0f6ee..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index df7a97efb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 868df019c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index a4d8aa293..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class DoubleConsensusCommit : Proto4.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 12382334b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 3ef244d07..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class OriginationsCommit : Proto5.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index ca4acab51..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index a0d1a0c1d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto11 -{ - class RegisterConstantsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = (User)await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - - var result = content.Required("metadata").Required("operation_result"); - var registerConstant = new RegisterConstantOperation - { - Id = Cache.AppState.NextOperationId(), - OpHash = op.RequiredString("hash"), - Level = block.Level, - Timestamp = block.Timestamp, - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = GetConsumedGas(result), - StorageUsed = result.OptionalInt32("storage_size") ?? 0, - StorageFee = result.OptionalInt32("storage_size") > 0 - ? result.OptionalInt32("storage_size") * Context.Protocol.ByteCost - : null, - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, registerConstant.BakerFee); - sender.Counter = registerConstant.Counter; - sender.RegisterConstantsCount++; - - block.Operations |= Operations.RegisterConstant; - - Cache.AppState.Get().RegisterConstantOpsCount++; - #endregion - - #region apply result - if (registerConstant.Status == OperationStatus.Applied) - { - var burned = registerConstant.StorageFee ?? 0; - Proto.Manager.Burn(burned); - - Spend(sender, burned); - - registerConstant.Address = result.RequiredString("global_address"); - registerConstant.Value = content.RequiredMicheline("value").ToBytes(); - registerConstant.Refs = 0; - - Cache.AppState.Get().ConstantsCount++; - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.RegisterConstantOps.Add(registerConstant); - Context.RegisterConstantOps.Add(registerConstant); - } - - public virtual async Task Revert(Block block, RegisterConstantOperation registerConstant) - { - #region entities - var sender = (User)await Cache.Accounts.GetAsync(registerConstant.SenderId); - - Db.TryAttach(sender); - #endregion - - #region revert result - if (registerConstant.Status == OperationStatus.Applied) - { - RevertSpend(sender, registerConstant.StorageFee ?? 0); - - Cache.AppState.Get().ConstantsCount--; - } - #endregion - - #region revert operation - RevertPayFee(sender, registerConstant.BakerFee); - sender.Counter = registerConstant.Counter - 1; - sender.RegisterConstantsCount--; - sender.Revealed = true; - - Cache.AppState.Get().RegisterConstantOpsCount--; - #endregion - - Db.RegisterConstantOps.Remove(registerConstant); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual int GetConsumedGas(JsonElement result) - { - return result.OptionalInt32("consumed_gas") ?? 0; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index ce6f50736..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 361a5e90d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class TransactionsCommit : Proto5.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index 7e9a86fd0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class RevelationPenaltyCommit : Proto9.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 94c3e98d4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class SnapshotBalanceCommit : Proto9.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SoftwareCommit.cs deleted file mode 100644 index c0f2a4b2c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/StateCommit.cs deleted file mode 100644 index fbd09b634..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/StatisticsCommit.cs deleted file mode 100644 index 114c62d02..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SubsidyCommit.cs deleted file mode 100644 index ce3abbf6a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/TokensCommit.cs deleted file mode 100644 index a36020b40..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/VotingCommit.cs deleted file mode 100644 index 0fc0a0aa1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class VotingCommit : Proto8.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Diagnostics/Diagnostics.cs deleted file mode 100644 index 1c41abc7a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class Diagnostics : Proto10.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Helpers.cs deleted file mode 100644 index d8a193d60..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Proto11Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Proto11Handler.cs deleted file mode 100644 index c810547b6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Proto11Handler.cs +++ /dev/null @@ -1,298 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto11; - -namespace Tzkt.Sync.Protocols -{ - class Proto11Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "hangzhou_011"; - public override int VersionNumber => 11; - - public Proto11Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement_with_slot": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - await new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - await new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Rpc/Rpc.cs deleted file mode 100644 index 2da0b0fe9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto11 -{ - class Rpc : Proto6.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto11/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto11/Validation/Validator.cs deleted file mode 100644 index bc928ad26..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto11/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto11 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.Accounts.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.Accounts.cs deleted file mode 100644 index 540f3558b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.Accounts.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - partial class ProtoActivator : Proto11.ProtoActivator - { - protected override async Task> BootstrapAccounts(Protocol protocol, JToken parameters) - { - var accounts = await base.BootstrapAccounts(protocol, parameters); - - Cache.Statistics.Current.TotalFrozen = accounts - .Where(x => x is Data.Models.Delegate baker && baker.BakingPower != 0) - .Sum(x => (x as Data.Models.Delegate)!.BakingPower / (protocol.MaxDelegatedOverFrozenRatio + 1)); - - return accounts; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.BakerCycles.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.BakerCycles.cs deleted file mode 100644 index 60fcacefe..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.BakerCycles.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - partial class ProtoActivator : Proto11.ProtoActivator - { - public override void BootstrapBakerCycles( - Protocol protocol, - List accounts, - List cycles, - List> bakingRights, - List> attestationRights) - { - var bakers = accounts - .Where(x => x.Type == AccountType.Delegate) - .Select(x => (x as Data.Models.Delegate)!); - - foreach (var cycle in cycles) - { - var bakerCycles = bakers.ToDictionary(x => x.Id, x => - { - var bakerCycle = new BakerCycle - { - Id = 0, - Cycle = cycle.Index, - BakerId = x.Id, - OwnDelegatedBalance = x.Balance, - ExternalDelegatedBalance = x.ExternalDelegatedBalance, - DelegatorsCount = x.DelegatorsCount, - OwnStakedBalance = x.OwnStakedBalance, - ExternalStakedBalance = x.ExternalStakedBalance, - StakersCount = x.StakersCount, - IssuedPseudotokens = x.IssuedPseudotokens, - BakingPower = x.BakingPower, - TotalBakingPower = cycle.TotalBakingPower - }; - if (x.BakingPower != 0) - { - var expectedAttestations = (protocol.BlocksPerCycle * protocol.AttestersPerBlock).MulRatio(x.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedBlocks = protocol.BlocksPerCycle.MulRatio(x.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = expectedAttestations * protocol.AttestationReward0; - } - return bakerCycle; - }); - - #region future baking rights - foreach (var br in bakingRights[cycle.Index].SkipWhile(x => x.Level == 1).Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Unknown baking right recipient"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += protocol.MaxBakingReward; - } - #endregion - - #region future attestation rights - foreach (var ar in attestationRights[cycle.Index].TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Unknown attestation right recipient"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - #region shifted future endirsing rights - if (cycle.Index > 0) - { - foreach (var ar in attestationRights[cycle.Index - 1].Reverse().TakeWhile(x => x.Level == cycle.FirstLevel - 1)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Unknown attestation right recipient"); - - bakerCycle.FutureAttestations += ar.Slots; - } - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.BakingRights.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.BakingRights.cs deleted file mode 100644 index 0d6ec9390..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.BakingRights.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - partial class ProtoActivator : Proto11.ProtoActivator - { - protected override async Task<(IEnumerable, IEnumerable)> GetRights( - Protocol protocol, - List accounts, - Cycle cycle) - { - var bakers = accounts - .Where(x => x is Data.Models.Delegate d && d.BakingPower != 0) - .Select(x => (x as Data.Models.Delegate)!); - - var sampler = GetSampler(bakers.Select(x => (x.Id, x.BakingPower))); - - #region temporary diagnostics - await sampler.Validate(Proto, 1, cycle.Index); - #endregion - - var bakingRights = await RightsGenerator.GetBakingRightsAsync(sampler, protocol, cycle); - var attestationRights = await RightsGenerator.GetAttestationRightsAsync(sampler, protocol, cycle); - return (bakingRights, attestationRights); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.cs deleted file mode 100644 index fa9ea1929..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Activation/ProtoActivator.cs +++ /dev/null @@ -1,505 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.Numerics; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto11.ProtoActivator(proto) - { - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.BlocksPerSnapshot = parameters["blocks_per_stake_snapshot"]?.Value() ?? 512; - protocol.AttestersPerBlock = parameters["consensus_committee_size"]?.Value() ?? 7000; - protocol.MinimalStake = parameters["tokens_per_roll"]?.Value() ?? 6_000_000_000; - protocol.BlockDeposit = 0; - protocol.AttestationDeposit = 0; - - var totalReward = 80_000_000 / (60 / protocol.TimeBetweenBlocks); - protocol.BlockReward0 = parameters["baking_reward_fixed_portion"]?.Value() ?? (totalReward / 4); - protocol.BlockReward1 = parameters["baking_reward_bonus_per_slot"]?.Value() ?? (totalReward / 4 / (protocol.AttestersPerBlock / 3)); - protocol.AttestationReward0 = parameters["endorsing_reward_per_slot"]?.Value() ?? (totalReward / 2 / protocol.AttestersPerBlock); - protocol.AttestationReward1 = 0; - - protocol.LBToggleThreshold = (parameters["liquidity_baking_escape_ema_threshold"]?.Value() ?? 666_667) * 1000; - - protocol.ConsensusThreshold = parameters["consensus_threshold"]?.Value() ?? 4667; - protocol.MinParticipationNumerator = parameters["minimal_participation_ratio"]?["numerator"]?.Value() ?? 2; - protocol.MinParticipationDenominator = parameters["minimal_participation_ratio"]?["denominator"]?.Value() ?? 3; - protocol.DenunciationPeriod = 1; - protocol.SlashingDelay = 1; - protocol.MaxDelegatedOverFrozenRatio = 100 / (parameters["frozen_deposits_percentage"]?.Value() ?? 10) - 1; - - protocol.MaxBakingReward = protocol.BlockReward0 + protocol.AttestersPerBlock / 3 * protocol.BlockReward1; - protocol.MaxAttestationReward = protocol.AttestersPerBlock * protocol.AttestationReward0; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.AttestersPerBlock = 7000; - protocol.MinimalStake = 6_000_000_000; - protocol.BlockDeposit = 0; - protocol.AttestationDeposit = 0; - - var totalReward = 80_000_000 / (60 / protocol.TimeBetweenBlocks); - protocol.BlockReward0 = totalReward / 4; - protocol.BlockReward1 = totalReward / 4 / (protocol.AttestersPerBlock / 3); - protocol.AttestationReward0 = totalReward / 2 / protocol.AttestersPerBlock; - protocol.AttestationReward1 = 0; - - protocol.LBToggleThreshold = 666_667_000; - - protocol.ConsensusThreshold = 4667; - protocol.MinParticipationNumerator = 2; - protocol.MinParticipationDenominator = 3; - protocol.DenunciationPeriod = 1; - protocol.SlashingDelay = 1; - protocol.MaxDelegatedOverFrozenRatio = 9; - - protocol.MaxBakingReward = protocol.BlockReward0 + protocol.AttestersPerBlock / 3 * protocol.BlockReward1; - protocol.MaxAttestationReward = protocol.AttestersPerBlock * protocol.AttestationReward0; - } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - var bakers = MigrateBakers(); - await MigrateCycles(state, bakers, nextProto); - MigrateStatistics(bakers, nextProto); - - if (state.Level == 1) return; - - Proto.Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - - await MigrateSnapshots(state); - await MigrateCurrentRights(state, bakers, prevProto, nextProto); - await MigrateFutureRights(state, bakers, nextProto); - - Cache.BakingRights.Reset(); - Cache.BakerCycles.Reset(); - } - - protected override Task RevertContext(AppState state) - { - throw new NotImplementedException("Reverting Ithaca migration block is technically impossible"); - } - - List MigrateBakers() - { - var bakers = Cache.Accounts.GetDelegates().ToList(); - foreach (var baker in bakers) - { - Db.TryAttach(baker); - - if (baker.Staked) - Cache.Statistics.Current.TotalOwnDelegated -= baker.OwnDelegatedBalance; - - baker.OwnDelegatedBalance = baker.Balance; - - if (baker.Staked) - Cache.Statistics.Current.TotalOwnDelegated += baker.OwnDelegatedBalance; - - UpdateBakerPower(baker); - } - return bakers; - } - - async Task MigrateCycles(AppState state, List bakers, Protocol nextProto) - { - var selectedStakes = bakers - .Where(x => x.BakingPower != 0) - .Select(x => x.BakingPower); - - var selectedBakers = selectedStakes.Count(); - var selectedStake = selectedStakes.Sum(); - - foreach (var cycle in await Db.Cycles.Where(x => x.LastLevel > state.Level).ToListAsync()) - { - cycle.SnapshotLevel = state.Level; - cycle.TotalBakers = selectedBakers; - cycle.TotalBakingPower = selectedStake; - } - } - - void MigrateStatistics(List bakers, Protocol nextProto) - { - var stats = Cache.Statistics.Current; - Db.TryAttach(stats); - stats.TotalFrozen = bakers - .Where(x => x.BakingPower != 0) - .Sum(x => x.BakingPower / (nextProto.MaxDelegatedOverFrozenRatio + 1)); - } - - Task MigrateSnapshots(AppState state) - { - return Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "SnapshotBalances" - WHERE "Level" = {0}; - - INSERT INTO "SnapshotBalances" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount" - ) - SELECT - {0}, - COALESCE("DelegateId", "Id"), - "Id", - COALESCE("OwnDelegatedBalance", "Balance"), - "ExternalDelegatedBalance", - "DelegatorsCount" - FROM "Accounts" - WHERE "Staked" = true; - """, state.Level); - } - - async Task MigrateCurrentRights(AppState state, List bakers, Protocol prevProto, Protocol nextProto) - { - var cycle = await Db.Cycles.AsNoTracking().FirstAsync(x => x.Index == state.Cycle); - if (state.Level == cycle.LastLevel) return; - - var bakerCycles = await Cache.BakerCycles.GetAsync(state.Cycle); - var selectedBakers = bakers.Where(x => x.BakingPower != 0); - - #region revert current rights - var rights = await Db.BakingRights - .AsNoTracking() - .Where(x => x.Level > state.Level && x.Cycle == state.Cycle) - .ToListAsync(); - - foreach (var br in rights.Where(x => x.Type == BakingRightType.Baking && x.Round == 0)) - { - var bakerCycle = bakerCycles[br.BakerId]; - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks--; - bakerCycle.FutureBlockRewards -= GetFutureBlockReward(prevProto, state.Cycle); - } - - foreach (var ar in rights.Where(x => x.Type == BakingRightType.Attestation)) - { - var bakerCycle = bakerCycles[ar.BakerId]; - Db.TryAttach(bakerCycle); - - bakerCycle.FutureAttestations -= ar.Slots!.Value; - bakerCycle.FutureAttestationRewards -= GetFutureAttestationReward(prevProto, state.Cycle, ar.Slots.Value); - } - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Level" > {0} AND "Cycle" = {1} - """, state.Level, state.Cycle); - - #endregion - - #region add missed baker cycles - foreach (var baker in selectedBakers) - { - if (!bakerCycles.TryGetValue(baker.Id, out var bc)) - { - bc = new BakerCycle - { - Id = 0, - Cycle = state.Cycle, - BakerId = baker.Id - }; - Db.BakerCycles.Add(bc); - Cache.BakerCycles.Add(bc); - - if (baker.DelegatorsCount > 0) - { - await Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "DelegatorCycles" ( - "Cycle", - "DelegatorId", - "BakerId", - "DelegatedBalance", - "StakedPseudotokens" - ) - SELECT - {0}, - "AccountId", - "BakerId", - "OwnDelegatedBalance", - "Pseudotokens" - FROM "SnapshotBalances" - WHERE "Level" = {1} - AND "BakerId" = {2} - AND "BakerId" != "AccountId" - """, state.Cycle, state.Level, baker.Id); - } - } - } - #endregion - - #region update baker cycles - foreach (var (bakerId, bc) in bakerCycles) - { - var baker = Cache.Accounts.GetDelegate(bakerId); - - Db.TryAttach(bc); - bc.OwnDelegatedBalance = baker.OwnDelegatedBalance; - bc.ExternalDelegatedBalance = baker.ExternalDelegatedBalance; - bc.DelegatorsCount = baker.DelegatorsCount; - bc.OwnStakedBalance = baker.OwnStakedBalance; - bc.ExternalStakedBalance = baker.ExternalStakedBalance; - bc.IssuedPseudotokens = baker.IssuedPseudotokens; - bc.StakersCount = baker.StakersCount; - bc.BakingPower = baker.BakingPower; - bc.TotalBakingPower = cycle.TotalBakingPower; - - if (baker.BakingPower != 0) - { - var expectedAttestations = (nextProto.BlocksPerCycle * nextProto.AttestersPerBlock).MulRatio(baker.BakingPower, cycle.TotalBakingPower); - bc.FutureAttestationRewards += expectedAttestations * nextProto.AttestationReward0; - } - } - #endregion - - #region apply new rights - var sampler = GetSampler(selectedBakers.Select(x => (x.Id, x.BakingPower))); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, cycle.Index); - #endregion - - var brs = new List(); - var ars = new List(); - for (int level = state.Level + 1; level <= cycle.LastLevel; level++) - { - foreach (var br in RightsGenerator.GetBakingRights(sampler, cycle, level)) - { - brs.Add(br); - if (br.Round == 0) - { - var bakerCycle = bakerCycles[br.Baker]; - Db.TryAttach(bakerCycle); - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += nextProto.MaxBakingReward; - } - } - foreach (var ar in RightsGenerator.GetAttestationRights(sampler, nextProto, cycle, level - 1)) - { - ars.Add(ar); - var bakerCycle = bakerCycles[ar.Baker]; - Db.TryAttach(bakerCycle); - bakerCycle.FutureAttestations += ar.Slots; - } - } - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@" - COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") - FROM STDIN (FORMAT BINARY)"); - - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - #endregion - } - - async Task MigrateFutureRights(AppState state, List bakers, Protocol nextProto) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" WHERE "Cycle" > {0}; - DELETE FROM "BakerCycles" WHERE "Cycle" > {0}; - DELETE FROM "DelegatorCycles" WHERE "Cycle" > {0}; - """, state.Cycle); - - var seelctedBakers = bakers.Where(x => x.BakingPower != 0); - var sampler = GetSampler(seelctedBakers.Select(x => (x.Id, x.BakingPower))); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, state.Cycle); - #endregion - - var cycles = await Db.Cycles.AsNoTracking().Where(x => x.Index >= state.Cycle).OrderBy(x => x.Index).ToListAsync(); - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - - #region save shifted - var currentCycle = cycles.First(); - var shifted = RightsGenerator.GetAttestationRights(sampler, nextProto, currentCycle, currentCycle.LastLevel); - - using (var writer = conn.BeginBinaryImport(@" - COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") - FROM STDIN (FORMAT BINARY)")) - { - foreach (var ar in shifted) - { - writer.StartRow(); - writer.Write(currentCycle.Index + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - writer.Complete(); - } - #endregion - - foreach (var cycle in cycles.Skip(1)) - { - GC.Collect(); - var brs = await RightsGenerator.GetBakingRightsAsync(sampler, nextProto, cycle); - var ars = await RightsGenerator.GetAttestationRightsAsync(sampler, nextProto, cycle); - - #region save rights - using (var writer = conn.BeginBinaryImport(@" - COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") - FROM STDIN (FORMAT BINARY)")) - { - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(nextProto.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - - #region save delegator cycles - await Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "DelegatorCycles" ( - "Cycle", - "DelegatorId", - "BakerId", - "DelegatedBalance", - "StakedPseudotokens" - ) - SELECT - {0}, - "AccountId", - "BakerId", - "OwnDelegatedBalance", - "Pseudotokens" - FROM "SnapshotBalances" - WHERE "Level" = {1} - AND "BakerId" != "AccountId" - """, cycle.Index, cycle.SnapshotLevel); - #endregion - - #region save baker cycles - var bakerCycles = bakers.Where(x => x.Staked).ToDictionary(x => x.Id, x => - { - var bc = new BakerCycle - { - Id = 0, - BakerId = x.Id, - Cycle = cycle.Index, - OwnDelegatedBalance = x.OwnDelegatedBalance, - ExternalDelegatedBalance = x.ExternalDelegatedBalance, - DelegatorsCount = x.DelegatorsCount, - OwnStakedBalance = x.OwnStakedBalance, - ExternalStakedBalance = x.ExternalStakedBalance, - StakersCount = x.StakersCount, - IssuedPseudotokens = x.IssuedPseudotokens, - BakingPower = x.BakingPower, - TotalBakingPower = cycle.TotalBakingPower - }; - if (x.BakingPower != 0) - { - var expectedAttestations = (nextProto.BlocksPerCycle * nextProto.AttestersPerBlock).MulRatio(x.BakingPower, cycle.TotalBakingPower); - bc.ExpectedBlocks = nextProto.BlocksPerCycle.MulRatio(x.BakingPower, cycle.TotalBakingPower); - bc.ExpectedAttestations = expectedAttestations; - bc.FutureAttestationRewards = expectedAttestations * nextProto.AttestationReward0; - } - return bc; - }); - Db.BakerCycles.AddRange(bakerCycles.Values); - #endregion - - #region apply future baking rights - foreach (var br in brs.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += nextProto.MaxBakingReward; - } - #endregion - - #region apply future attestation rights - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots; - } - } - foreach (var ar in ars.TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - shifted = ars.Where(x => x.Level == cycle.LastLevel).ToList(); - } - } - - protected virtual Sampler GetSampler(IEnumerable<(int id, long stake)> selection) - { - var sorted = selection - .OrderByDescending(x => x.stake) - .ThenByDescending(x => Base58.Parse(Cache.Accounts.GetDelegate(x.id).Address), new BytesComparer()); - - return new Sampler([..sorted.Select(x => x.id)], [..sorted.Select(x => x.stake)]); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/AttestationRewardCommit.cs deleted file mode 100644 index 615a58993..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class AttestationRewardCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement rawBlock) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - var losses = rawBlock.Required("metadata").RequiredArray("balance_updates").EnumerateArray() - .Where(x => x.RequiredString("origin") == "block" && - x.RequiredString("kind") == "burned" && - x.RequiredString("category") == "lost endorsing rewards") - .ToDictionary(x => Cache.Accounts.GetExistingDelegate(x.RequiredString("delegate")).Id, x => x.RequiredInt64("change")); - - var bakerCycles = await Cache.BakerCycles.GetAsync(block.Cycle); - var ops = new List(bakerCycles.Count); - - foreach (var (bakerId, bakerCycle) in bakerCycles.Where(x => x.Value.FutureAttestationRewards > 0)) - { - ops.Add(new() - { - Id = Cache.AppState.NextOperationId(), - BakerId = bakerId, - Level = block.Level, - Timestamp = block.Timestamp, - Expected = bakerCycle.FutureAttestationRewards, - RewardDelegated = bakerCycle.FutureAttestationRewards - }); - - Db.TryAttach(bakerCycle); - if (losses.TryGetValue(bakerId, out var loss)) - { - if (bakerCycle.FutureAttestationRewards != loss) - throw new Exception("FutureAttestationRewards != loss"); - - ops[^1].RewardDelegated = 0; - bakerCycle.MissedAttestationRewards += bakerCycle.FutureAttestationRewards; - bakerCycle.FutureAttestationRewards = 0; - } - else - { - bakerCycle.AttestationRewardsDelegated += bakerCycle.FutureAttestationRewards; - bakerCycle.FutureAttestationRewards = 0; - } - } - - foreach (var op in ops) - { - var baker = Cache.Accounts.GetDelegate(op.BakerId); - Db.TryAttach(baker); - - Receive(baker, baker, op.RewardDelegated); - baker.AttestationRewardsCount++; - - block.Operations |= Operations.AttestationRewards; - - Cache.Statistics.Current.TotalCreated += op.RewardDelegated; - } - - Cache.AppState.Get().AttestationRewardOpsCount += ops.Count; - - Db.AttestationRewardOps.AddRange(ops); - Context.AttestationRewardOps.AddRange(ops); - } - - public virtual async Task Revert(Block block) - { - if (Context.AttestationRewardOps.Count == 0) - return; - - foreach (var op in Context.AttestationRewardOps) - { - var baker = Cache.Accounts.GetDelegate(op.BakerId); - Db.TryAttach(baker); - - RevertReceive(baker, baker, op.RewardDelegated); - baker.AttestationRewardsCount--; - - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, baker.Id); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureAttestationRewards = op.Expected; - if (op.Expected == op.RewardDelegated) - bakerCycle.AttestationRewardsDelegated -= op.Expected; - else - bakerCycle.MissedAttestationRewards -= op.Expected; - } - - Cache.AppState.Get().AttestationRewardOpsCount -= Context.AttestationRewardOps.Count; - - Db.AttestationRewardOps.RemoveRange(Context.AttestationRewardOps); - Cache.AppState.ReleaseOperationId(Context.AttestationRewardOps.Count); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BakerCycleCommit.cs deleted file mode 100644 index 905c40f8c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,366 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class BakerCycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply( - Block block, - Cycle? futureCycle, - IEnumerable? futureBakingRights, - IEnumerable? futureAttestationRights, - List? snapshots, - Dictionary? selectedStakes, - List currentRights) - { - #region current rights - if (block.BlockRound == 0) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, block.ProposerId!.Value); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks--; - bakerCycle.FutureBlockRewards -= Context.Protocol.MaxBakingReward; - bakerCycle.Blocks++; - bakerCycle.BlockRewardsDelegated += block.RewardDelegated + block.BonusDelegated; - bakerCycle.BlockFees += block.Fees; - } - else - { - var set = new HashSet(); - foreach (var br in currentRights.Where(x => x.Type == BakingRightType.Baking).OrderBy(x => x.Round)) - { - if (set.Add(br.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, br.BakerId); - Db.TryAttach(bakerCycle); - - if (br.Round == 0) - { - bakerCycle.FutureBlocks--; - bakerCycle.FutureBlockRewards -= Context.Protocol.MaxBakingReward; - } - - if (br.BakerId == block.ProposerId || br.BakerId == block.ProducerId) - { - bakerCycle.Blocks++; - } - else - { - bakerCycle.MissedBlocks++; - } - - if (br.BakerId == block.ProposerId) - { - bakerCycle.BlockRewardsDelegated += block.RewardDelegated; - bakerCycle.BlockFees += block.Fees; - } - else if (br.Round < block.PayloadRound) - { - bakerCycle.MissedBlockRewards += block.RewardDelegated; - bakerCycle.MissedBlockFees += block.Fees; - } - - if (br.BakerId == block.ProducerId) - { - bakerCycle.BlockRewardsDelegated += block.BonusDelegated; - } - else - { - bakerCycle.MissedBlockRewards += block.BonusDelegated; - } - } - } - } - - foreach (var ar in currentRights.Where(x => x.Type == BakingRightType.Attestation)) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, ar.BakerId); - if (bakerCycle == null) continue; - - Db.TryAttach(bakerCycle); - bakerCycle.FutureAttestations -= ar.Slots!.Value; - if (ar.Status == BakingRightStatus.Realized) - bakerCycle.Attestations += ar.Slots.Value; - else if (ar.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestations += ar.Slots.Value; - else - throw new Exception("Unexpected future rights"); - } - - foreach (var op in Context.DoubleBakingOps) - { - var offenderCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.OffenderId); - if (offenderCycle != null) - { - Db.TryAttach(offenderCycle); - offenderCycle.DoubleBakingLostStaked += op.LostStaked; - } - - var accuserCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.AccuserId); - if (accuserCycle != null) - { - Db.TryAttach(accuserCycle); - accuserCycle.DoubleBakingRewards += op.Reward; - } - } - - foreach (var op in Context.DoubleConsensusOps) - { - var offenderCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.OffenderId); - if (offenderCycle != null) - { - Db.TryAttach(offenderCycle); - offenderCycle.DoubleConsensusLostStaked += op.LostStaked; - } - - var accuserCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.AccuserId); - if (accuserCycle != null) - { - Db.TryAttach(accuserCycle); - accuserCycle.DoubleConsensusRewards += op.Reward; - } - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.BakerId); - if (bakerCycle != null) - { - Db.TryAttach(bakerCycle); - bakerCycle.NonceRevelationRewardsDelegated += op.RewardDelegated; - } - } - - foreach (var op in Context.VdfRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.VdfRevelationRewardsDelegated += op.RewardDelegated; - } - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var bakerCycles = snapshots!.ToDictionary(x => x.AccountId, snapshot => - { - var bakerCycle = new BakerCycle - { - Id = 0, - BakerId = snapshot.AccountId, - Cycle = futureCycle!.Index, - OwnDelegatedBalance = snapshot.OwnDelegatedBalance, - ExternalDelegatedBalance = snapshot.ExternalDelegatedBalance!.Value, - DelegatorsCount = snapshot.DelegatorsCount!.Value, - OwnStakedBalance = snapshot.OwnStakedBalance ?? 0, - ExternalStakedBalance = snapshot.ExternalStakedBalance ?? 0, - StakersCount = snapshot.StakersCount ?? 0, - IssuedPseudotokens = snapshot.Pseudotokens, - BakingPower = 0, - TotalBakingPower = futureCycle.TotalBakingPower - }; - if (selectedStakes!.TryGetValue(bakerCycle.BakerId, out var bakingPower)) - { - var expectedAttestations = (Context.Protocol.BlocksPerCycle * Context.Protocol.AttestersPerBlock).MulRatio(bakingPower, futureCycle.TotalBakingPower); - bakerCycle.BakingPower = bakingPower; - bakerCycle.ExpectedBlocks = Context.Protocol.BlocksPerCycle.MulRatio(bakingPower, futureCycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = expectedAttestations * Context.Protocol.AttestationReward0; - } - return bakerCycle; - }); - - #region future baking rights - foreach (var br in futureBakingRights!.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += Context.Protocol.MaxBakingReward; - } - #endregion - - #region future attestation rights - var skipLevel = futureAttestationRights!.Last().Level; - foreach (var ar in futureAttestationRights!.TakeWhile(x => x.Level < skipLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - #region shifted future attestation rights - var shifted = await Db.BakingRights.AsNoTracking() - .Where(x => x.Level == futureCycle!.FirstLevel && x.Type == BakingRightType.Attestation) - .ToListAsync(); - - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.BakerId, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots!.Value; - } - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - } - #endregion - } - - public virtual async Task Revert(Block block) - { - #region current rights - var currentRights = await Cache.BakingRights.GetAsync(block.Level); - - if (block.BlockRound == 0) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, block.ProposerId!.Value); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += Context.Protocol.MaxBakingReward; - bakerCycle.Blocks--; - bakerCycle.BlockRewardsDelegated -= block.RewardDelegated + block.BonusDelegated; - bakerCycle.BlockFees -= block.Fees; - } - else - { - var set = new HashSet(); - var bakerRound = currentRights - .Where(x => x.Type == BakingRightType.Baking) - .OrderBy(x => x.Round) - .First(x => x.Status == BakingRightStatus.Realized) - .Round; - - foreach (var br in currentRights.Where(x => x.Type == BakingRightType.Baking).OrderBy(x => x.Round)) - { - if (set.Add(br.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, br.BakerId); - Db.TryAttach(bakerCycle); - - if (br.Round == 0) - { - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += Context.Protocol.MaxBakingReward; - } - - if (br.BakerId == block.ProposerId || br.BakerId == block.ProducerId) - { - bakerCycle.Blocks--; - } - else - { - bakerCycle.MissedBlocks--; - } - - if (br.BakerId == block.ProposerId) - { - bakerCycle.BlockRewardsDelegated -= block.RewardDelegated; - bakerCycle.BlockFees -= block.Fees; - } - else if (br.Round < bakerRound) - { - bakerCycle.MissedBlockRewards -= block.RewardDelegated; - bakerCycle.MissedBlockFees -= block.Fees; - } - - if (br.BakerId == block.ProducerId) - { - bakerCycle.BlockRewardsDelegated -= block.BonusDelegated; - } - else - { - bakerCycle.MissedBlockRewards -= block.BonusDelegated; - } - } - } - } - - foreach (var ar in currentRights.Where(x => x.Type == BakingRightType.Attestation)) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, ar.BakerId); - if (bakerCycle == null) continue; - - Db.TryAttach(bakerCycle); - bakerCycle.FutureAttestations += ar.Slots!.Value; - if (ar.Status == BakingRightStatus.Realized) - bakerCycle.Attestations -= ar.Slots.Value; - else if (ar.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestations -= ar.Slots.Value; - else - throw new Exception("Unexpected future rights"); - } - - foreach (var op in Context.DoubleBakingOps) - { - var offenderCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.OffenderId); - if (offenderCycle != null) - { - Db.TryAttach(offenderCycle); - offenderCycle.DoubleBakingLostStaked -= op.LostStaked; - } - - var accuserCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.AccuserId); - if (accuserCycle != null) - { - Db.TryAttach(accuserCycle); - accuserCycle.DoubleBakingRewards -= op.Reward; - } - } - - foreach (var op in Context.DoubleConsensusOps) - { - var offenderCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.OffenderId); - if (offenderCycle != null) - { - Db.TryAttach(offenderCycle); - offenderCycle.DoubleConsensusLostStaked -= op.LostStaked; - } - - var accuserCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.AccuserId); - if (accuserCycle != null) - { - Db.TryAttach(accuserCycle); - accuserCycle.DoubleConsensusRewards -= op.Reward; - } - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.BakerId); - if (bakerCycle != null) - { - Db.TryAttach(bakerCycle); - bakerCycle.NonceRevelationRewardsDelegated -= op.RewardDelegated; - } - } - - foreach (var op in Context.VdfRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.VdfRevelationRewardsDelegated -= op.RewardDelegated; - } - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakerCycles" - WHERE "Cycle" = {0} - """, block.Cycle + Context.Protocol.ConsensusRightsDelay); - } - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BakingRightsCommit.cs deleted file mode 100644 index c0b7d14d3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,197 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class BakingRightsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public List CurrentRights { get; protected set; } = null!; - public IEnumerable? FutureBakingRights { get; protected set; } - public IEnumerable? FutureAttestationRights { get; protected set; } - - public virtual async Task Apply(Block block, Cycle? futureCycle, Dictionary? selectedStakes) - { - await ApplyCurrentRights(block); - - if (futureCycle != null) - await ApplyNewCycle(block, futureCycle, selectedStakes!); - } - - protected virtual async Task ApplyCurrentRights(Block block) - { - CurrentRights = await Cache.BakingRights.GetAsync(block.Level); - var sql = string.Empty; - - #region load missed rounds - var maxExistedRound = CurrentRights - .Where(x => x.Type == BakingRightType.Baking) - .Select(x => x.Round) - .Max(); - - if (maxExistedRound < block.BlockRound) - { - var cycle = await Db.Cycles.FirstAsync(x => x.Index == block.Cycle); - var bakerCycles = await Cache.BakerCycles.GetAsync(block.Cycle); - var sampler = GetSampler( - bakerCycles.Values.Where(x => x.BakingPower > 0).Select(x => (x.BakerId, x.BakingPower)), - block.ProtoCode > 1 && block.Cycle <= Context.Protocol.FirstCycle + Context.Protocol.ConsensusRightsDelay); //TODO: remove this crutch after ithaca is gone - #region temporary diagnostics - await sampler.Validate(Proto, block.Level, block.Cycle); - #endregion - var bakingRights = RightsGenerator.GetBakingRights(sampler, cycle, block.Level, block.BlockRound + 1); - - var sqlInsert = @" - INSERT INTO ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") VALUES "; - - foreach (var br in bakingRights.SkipWhile(x => x.Round <= maxExistedRound)) - sqlInsert += $@" - ({block.Cycle}, {block.Level}, {br.Baker}, {(int)BakingRightType.Baking}, {(int)BakingRightStatus.Future}, {br.Round}, null),"; - - await Db.Database.ExecuteSqlRawAsync(sqlInsert[..^1]); - - //TODO: execute sql with RETURNS to get identity - var addedRights = await Db.BakingRights - .Where(x => x.Level == block.Level && x.Type == BakingRightType.Baking && x.Round > maxExistedRound) - .ToListAsync(); - - CurrentRights.AddRange(addedRights); - } - #endregion - - #region remove excess - if (CurrentRights.RemoveAll(x => x.Type == BakingRightType.Baking && x.Round > block.BlockRound) > 0) - { - sql += $@" - DELETE FROM ""BakingRights"" - WHERE ""Level"" = {block.Level} - AND ""Type"" = {(int)BakingRightType.Baking} - AND ""Round"" > {block.BlockRound};"; - } - #endregion - - foreach (var cr in CurrentRights) - cr.Status = BakingRightStatus.Missed; - - CurrentRights.First(x => x.Round == block.PayloadRound).Status = BakingRightStatus.Realized; - if (block.PayloadRound != block.BlockRound) - CurrentRights.First(x => x.Round == block.BlockRound).Status = BakingRightStatus.Realized; - - if (Context.AttestationOps.Count != 0) - { - var attesters = new HashSet(Context.AttestationOps.Select(x => x.DelegateId)); - foreach (var ar in CurrentRights.Where(x => x.Type == BakingRightType.Attestation && attesters.Contains(x.BakerId))) - ar.Status = BakingRightStatus.Realized; - } - - var realized = CurrentRights.Where(x => x.Status == BakingRightStatus.Realized); - var missed = CurrentRights.Where(x => x.Status == BakingRightStatus.Missed); - - sql += $@" - UPDATE ""BakingRights"" - SET ""Status"" = {(int)BakingRightStatus.Realized} - WHERE ""Level"" = {block.Level} - AND ""Id"" = ANY(ARRAY[{string.Join(',', realized.Select(x => x.Id))}]);"; - - if (missed.Any()) - { - sql += $@" - UPDATE ""BakingRights"" - SET ""Status"" = {(int)BakingRightStatus.Missed} - WHERE ""Level"" = {block.Level} - AND ""Id"" = ANY(ARRAY[{string.Join(',', missed.Select(x => x.Id))}]);"; - } - - await Db.Database.ExecuteSqlRawAsync(sql); - } - - protected virtual async Task ApplyNewCycle(Block block, Cycle futureCycle, Dictionary selectedStakes) - { - var sampler = GetSampler( - selectedStakes.Where(x => x.Value > 0).Select(x => (x.Key, x.Value)), - block.Level == Context.Protocol.FirstCycleLevel); - - #region temporary diagnostics - await sampler.Validate(Proto, block.Level, futureCycle.Index); - #endregion - - FutureBakingRights = await RightsGenerator.GetBakingRightsAsync(sampler, Context.Protocol, futureCycle); - FutureAttestationRights = await RightsGenerator.GetAttestationRightsAsync(sampler, Context.Protocol, futureCycle); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@" - COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") - FROM STDIN (FORMAT BINARY)"); - - foreach (var ar in FutureAttestationRights) - { - writer.StartRow(); - writer.Write(Context.Protocol.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); // level + 1 (shifted) - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); // level + 1 (shifted) - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in FutureBakingRights) - { - writer.StartRow(); - writer.Write(futureCycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - - public virtual async Task Revert(Block block) - { - await RevertCurrentRights(block); - - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - await RevertNewCycle(block); - } - - public virtual async Task RevertCurrentRights(Block block) - { - CurrentRights = await Cache.BakingRights.GetAsync(block.Level); - - foreach (var cr in CurrentRights) - cr.Status = BakingRightStatus.Future; - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "BakingRights" - SET "Status" = {0} - WHERE "Level" = {1} - """, (int)BakingRightStatus.Future, block.Level); - } - - public virtual async Task RevertNewCycle(Block block) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" = {0} AND "Type" = {1} - OR "Level" > {2} - """, - block.Cycle + Context.Protocol.ConsensusRightsDelay, - (int)BakingRightType.Baking, - Context.Protocol.GetCycleStart(block.Cycle + Context.Protocol.ConsensusRightsDelay)); - } - - protected virtual Sampler GetSampler(IEnumerable<(int id, long stake)> selection, bool forceBase) - { - var sorted = selection - .OrderByDescending(x => x.stake) - .ThenByDescending(x => Base58.Parse(Cache.Accounts.GetDelegate(x.id).Address), new BytesComparer()); - - return new Sampler([..sorted.Select(x => x.id)], [..sorted.Select(x => x.stake)]); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BigMapCommit.cs deleted file mode 100644 index d2f4699d4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BlockCommit.cs deleted file mode 100644 index bde321fce..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/BlockCommit.cs +++ /dev/null @@ -1,165 +0,0 @@ -using Netezos.Encoding; -using System; -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class BlockCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Block Block { get; private set; } = null!; - - public virtual async Task Apply(JsonElement rawBlock) - { - var header = rawBlock.Required("header"); - var metadata = rawBlock.Required("metadata"); - - var level = header.RequiredInt32("level"); - var proposer = Cache.Accounts.GetExistingDelegate(metadata.RequiredString("proposer")); - var producer = Cache.Accounts.GetExistingDelegate(metadata.RequiredString("baker")); - var protocol = await Cache.Protocols.GetAsync(rawBlock.RequiredString("protocol")); - var events = BlockEvents.None; - - if (protocol.IsCycleStart(level)) - events |= BlockEvents.CycleBegin; - else if (protocol.IsCycleEnd(level)) - events |= BlockEvents.CycleEnd; - - if (protocol.FirstLevel == level) - events |= BlockEvents.ProtocolBegin; - else if (protocol.Hash != metadata.RequiredString("next_protocol")) - events |= BlockEvents.ProtocolEnd; - - if (metadata.RequiredArray("deactivated").Count() > 0) - events |= BlockEvents.Deactivations; - - if (level % protocol.BlocksPerSnapshot == 0) - events |= BlockEvents.BalanceSnapshot; - - var payloadRound = header.RequiredInt32("payload_round"); - var blockRound = Hex.Parse(header.RequiredArray("fitness", 5)[4].RequiredString()).ToInt32(); - var balanceUpdates = metadata.RequiredArray("balance_updates").EnumerateArray(); - var rewardUpdate = balanceUpdates.FirstOrDefault(x => x.RequiredString("kind") == "minted" && x.RequiredString("category") == "baking rewards"); - var bonusUpdate = balanceUpdates.FirstOrDefault(x => x.RequiredString("kind") == "minted" && x.RequiredString("category") == "baking bonuses"); - - Block = new Block - { - Id = Cache.AppState.NextOperationId(), - Hash = rawBlock.RequiredString("hash"), - Cycle = protocol.GetCycle(level), - Level = level, - ProtoCode = protocol.Code, - Timestamp = header.RequiredDateTime("timestamp"), - AttestationCommittee = protocol.AttestersPerBlock, - PayloadRound = payloadRound, - BlockRound = blockRound, - ProposerId = proposer.Id, - ProducerId = producer.Id, - Events = events, - RewardDelegated = rewardUpdate.ValueKind == JsonValueKind.Undefined ? 0 : -rewardUpdate.RequiredInt64("change"), - BonusDelegated = bonusUpdate.ValueKind == JsonValueKind.Undefined ? 0 : -bonusUpdate.RequiredInt64("change"), - LBToggle = GetLBToggleVote(rawBlock), - LBToggleEma = GetLBToggleEma(rawBlock) - }; - - Context.Block = Block; - Context.Proposer = proposer; - Context.Protocol = protocol; - - Db.TryAttach(proposer); - Receive(proposer, proposer, Block.RewardDelegated); - proposer.BlocksCount++; - - #region set baker active - var newDeactivationLevel = proposer.Staked ? GracePeriod.Reset(Block.Level, protocol) : GracePeriod.Init(Block.Level, protocol); - if (proposer.DeactivationLevel < newDeactivationLevel) - { - if (proposer.DeactivationLevel <= Block.Level) - await ActivateBaker(proposer); - - Block.ResetBakerDeactivation = proposer.DeactivationLevel; - proposer.DeactivationLevel = newDeactivationLevel; - } - #endregion - - Db.TryAttach(producer); - Receive(producer, producer, Block.BonusDelegated); - if (producer.Id != proposer.Id) - { - producer.BlocksCount++; - - #region set proposer active - newDeactivationLevel = producer.Staked ? GracePeriod.Reset(Block.Level, protocol) : GracePeriod.Init(Block.Level, protocol); - if (producer.DeactivationLevel < newDeactivationLevel) - { - if (producer.DeactivationLevel <= Block.Level) - await ActivateBaker(producer); - - Block.ResetProposerDeactivation = producer.DeactivationLevel; - producer.DeactivationLevel = newDeactivationLevel; - } - #endregion - } - - Db.TryAttach(protocol); // if we don't attach it, ef will recognize it as 'added' - if (Block.Events.HasFlag(BlockEvents.ProtocolEnd)) - protocol.LastLevel = Block.Level; - - - Cache.AppState.Get().BlocksCount++; - Cache.Statistics.Current.TotalCreated += Block.RewardDelegated + Block.BonusDelegated; - - Db.Blocks.Add(Block); - Cache.Blocks.Add(Block); - } - - public virtual async Task Revert(Block block) - { - Block = block; - - var proposer = Context.Proposer; - Db.TryAttach(proposer); - RevertReceive(proposer, proposer, Block.RewardDelegated); - proposer.BlocksCount--; - - #region reset baker activity - if (Block.ResetBakerDeactivation != null) - { - if (Block.ResetBakerDeactivation <= Block.Level) - await DeactivateBaker(proposer); - - proposer.DeactivationLevel = (int)Block.ResetBakerDeactivation; - } - #endregion - - var producer = Cache.Accounts.GetDelegate(block.ProducerId!.Value); - Db.TryAttach(producer); - RevertReceive(producer, producer, Block.BonusDelegated); - if (producer.Id != proposer.Id) - { - producer.BlocksCount--; - - #region reset proposer activity - if (Block.ResetProposerDeactivation != null) - { - if (Block.ResetProposerDeactivation <= Block.Level) - await DeactivateBaker(producer); - - producer.DeactivationLevel = (int)Block.ResetProposerDeactivation; - } - #endregion - } - - Cache.AppState.Get().BlocksCount--; - - Db.Blocks.Remove(Block); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual bool? GetLBToggleVote(JsonElement block) - => !block.Required("header").RequiredBool("liquidity_baking_escape_vote"); - - protected virtual int GetLBToggleEma(JsonElement block) - => block.Required("metadata").RequiredInt32("liquidity_baking_escape_ema") * 1000; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/CycleCommit.cs deleted file mode 100644 index 68eadca9e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/CycleCommit.cs +++ /dev/null @@ -1,115 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class CycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Cycle? FutureCycle { get; protected set; } - public List? Snapshots { get; protected set; } - public Dictionary? SelectedStakes { get; protected set; } - - public virtual async Task Apply(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - var lastSeed = await Db.Cycles - .AsNoTracking() - .Where(x => x.Index == futureCycle - 1) - .Select(x => x.Seed) - .FirstOrDefaultAsync() - ?? throw new Exception($"Seed for cycle {futureCycle - 1} is missed"); - - var nonces = block.Cycle < 2 ? [] : await Db.NonceRevelationOps - .AsNoTracking() - .Where(x => x.RevealedCycle == block.Cycle - 2) - .OrderByDescending(x => x.RevealedLevel) - .Select(x => x.Nonce) - .ToListAsync(); - - var futureSeed = Seed.GetNextSeed(lastSeed, nonces, null); - var snapshotIndex = 0; - var snapshotLevel = 1; - var activation = false; - - if (block.Cycle >= 1) - { - if (block.Cycle == Context.Protocol.FirstCycle) - { - snapshotLevel = Context.Protocol.FirstLevel - 1; - activation = true; - } - else if (block.Cycle == Context.Protocol.FirstCycle + 1 && Context.Protocol.FirstLevel >= Context.Protocol.FirstCycleLevel) - { - var snapshotProto = await Cache.Protocols.FindByCycleAsync(block.Cycle - 1); - snapshotIndex = Seed.GetSnapshotIndex(futureSeed, snapshotProto.SnapshotsPerCycle + 1, true) - 1; - snapshotLevel = snapshotProto.GetCycleStart(block.Cycle - 1) - 1 + (snapshotIndex + 1) * snapshotProto.BlocksPerSnapshot; - } - else - { - var snapshotProto = await Cache.Protocols.FindByCycleAsync(block.Cycle - 1); - snapshotIndex = Seed.GetSnapshotIndex(futureSeed, snapshotProto.SnapshotsPerCycle, true); - snapshotLevel = snapshotProto.GetCycleStart(block.Cycle - 1) - 1 + (snapshotIndex + 1) * snapshotProto.BlocksPerSnapshot; - } - } - - Snapshots = await Db.SnapshotBalances - .AsNoTracking() - .Where(x => x.Level == snapshotLevel && x.BakerId == x.AccountId) - .ToListAsync(); - - var attestationRewards = activation ? [] : await Db.BakerCycles - .AsNoTracking() - .Where(x => x.Cycle == block.Cycle - 1 && x.AttestationRewardsDelegated > 0) - .ToDictionaryAsync(x => x.BakerId, x => x.AttestationRewardsDelegated); - - SelectedStakes = Snapshots - .Where(x => x.StakingBalance >= Context.Protocol.MinimalStake) - .ToDictionary(x => x.AccountId, x => - { - var baker = Cache.Accounts.GetDelegate(x.AccountId); - - var lastBalance = baker.Balance; - if (attestationRewards.TryGetValue(baker.Id, out var reward)) - lastBalance -= reward; - if (block.ProposerId == baker.Id) - lastBalance -= block.RewardDelegated; - if (block.ProducerId == baker.Id) - lastBalance -= block.BonusDelegated; - - var depositCap = Math.Min(lastBalance, baker.FrozenDepositLimit ?? lastBalance); - return Math.Min(x.StakingBalance, depositCap * (Context.Protocol.MaxDelegatedOverFrozenRatio + 1)); - }); - - FutureCycle = new Cycle - { - Id = 0, - Index = futureCycle, - FirstLevel = Context.Protocol.GetCycleStart(futureCycle), - LastLevel = Context.Protocol.GetCycleEnd(futureCycle), - SnapshotLevel = snapshotLevel, - TotalBakers = SelectedStakes.Count, - TotalBakingPower = SelectedStakes.Values.Sum(), - Seed = futureSeed - }; - - Db.Cycles.Add(FutureCycle); - } - - public virtual async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Cycles" - WHERE "Index" = {0} - """, futureCycle); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/DeactivationCommit.cs deleted file mode 100644 index 916682630..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 51e0bf82b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/FreezerCommit.cs deleted file mode 100644 index c32355f22..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/FreezerCommit.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class FreezerCommit : ProtocolCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - - public void Apply(Block block, JsonElement rawBlock) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - foreach (var update in rawBlock.Required("metadata").RequiredArray("balance_updates").EnumerateArray() - .Where(x => x.RequiredString("origin") == "block" && - x.RequiredString("kind") == "freezer" && - x.RequiredString("category") == "deposits")) - { - Cache.Statistics.Current.TotalFrozen += update.RequiredInt64("change"); - } - } - - public void Revert() - { - // there is nothing to revert - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 244b78f8d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 9574e2473..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class AttestationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Task Apply(Block block, JsonElement op, JsonElement content) - { - var metadata = content.Required("metadata"); - return Apply(block, op.RequiredString("hash"), metadata.RequiredString("delegate"), GetPower(metadata)); - } - - public async Task Apply(Block block, string opHash, string bakerAddress, long power) - { - var baker = Cache.Accounts.GetExistingDelegate(bakerAddress); - - var attestation = new AttestationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = opHash, - Power = power, - DelegateId = baker.Id - }; - - Db.TryAttach(baker); - baker.AttestationsCount++; - - #region set baker active - var newDeactivationLevel = baker.Staked ? GracePeriod.Reset(block.Level, Context.Protocol) : GracePeriod.Init(block.Level, Context.Protocol); - if (baker.DeactivationLevel < newDeactivationLevel) - { - if (baker.DeactivationLevel <= block.Level) - await ActivateBaker(baker); - - attestation.ResetDeactivation = baker.DeactivationLevel; - baker.DeactivationLevel = newDeactivationLevel; - } - #endregion - - block.Operations |= Operations.Attestations; - block.AttestationPower += attestation.Power; - - Cache.AppState.Get().AttestationOpsCount++; - - //Db.AttestationOps.Add(attestation); - Context.AttestationOps.Add(attestation); - } - - public async Task Revert(Block block, AttestationOperation attestation) - { - var baker = Cache.Accounts.GetDelegate(attestation.DelegateId); - Db.TryAttach(baker); - baker.AttestationsCount--; - - #region reset baker activity - if (attestation.ResetDeactivation != null) - { - if (attestation.ResetDeactivation <= block.Level) - await DeactivateBaker(baker); - - baker.DeactivationLevel = (int)attestation.ResetDeactivation; - } - #endregion - - Cache.AppState.Get().AttestationOpsCount--; - - //Db.AttestationOps.Remove(attestation); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual long GetPower(JsonElement metadata) => metadata.OptionalInt64("endorsement_power") ?? metadata.RequiredInt64("consensus_power"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 2fc1fb288..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index b58507523..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 06ff64246..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class DoubleBakingCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual void Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - var freezerUpdates = balanceUpdates.Where(x => x.RequiredString("kind") == "freezer" && x.RequiredString("category") == "deposits"); - var contractUpdates = balanceUpdates.Where(x => x.RequiredString("kind") == "contract"); - - var offenderAddr = freezerUpdates.Any() - ? freezerUpdates.First().RequiredString("delegate") - : Context.Proposer.Address; // this is wrong, but no big deal - - var offenderLoss = freezerUpdates.Any() - ? -freezerUpdates.Sum(x => x.RequiredInt64("change")) - : 0; - - var accuserReward = contractUpdates.Any() - ? contractUpdates.Sum(x => x.RequiredInt64("change")) - : 0; - - var accuser = Context.Proposer; - var offender = Cache.Accounts.GetExistingDelegate(offenderAddr); - - var doubleBaking = new DoubleBakingOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - - SlashedLevel = block.Level, - AccusedLevel = content.Required("bh1").RequiredInt32("level"), - AccuserId = accuser.Id, - OffenderId = offender.Id, - - Reward = accuserReward, - LostStaked = offenderLoss, - LostUnstaked = 0, - LostExternalStaked = 0, - LostExternalUnstaked = 0 - }; - #endregion - - #region entities - Db.TryAttach(accuser); - Db.TryAttach(offender); - #endregion - - #region apply operation - Receive(accuser, accuser, doubleBaking.Reward); - - Spend(offender, offender, doubleBaking.LostStaked); - - accuser.DoubleBakingCount++; - if (offender != accuser) offender.DoubleBakingCount++; - - block.Operations |= Operations.DoubleBakings; - - Cache.AppState.Get().DoubleBakingOpsCount++; - Cache.Statistics.Current.TotalBurned += doubleBaking.LostStaked - doubleBaking.Reward; - Cache.Statistics.Current.TotalFrozen -= doubleBaking.LostStaked; - #endregion - - Db.DoubleBakingOps.Add(doubleBaking); - Context.DoubleBakingOps.Add(doubleBaking); - } - - public virtual void Revert(Block block, DoubleBakingOperation doubleBaking) - { - #region entities - var accuser = Cache.Accounts.GetDelegate(doubleBaking.AccuserId); - var offender = Cache.Accounts.GetDelegate(doubleBaking.OffenderId); - Db.TryAttach(accuser); - Db.TryAttach(offender); - #endregion - - #region apply operation - RevertReceive(accuser, accuser, doubleBaking.Reward); - - RevertSpend(offender, offender, doubleBaking.LostStaked); - - accuser.DoubleBakingCount--; - if (offender != accuser) offender.DoubleBakingCount--; - - Cache.AppState.Get().DoubleBakingOpsCount--; - #endregion - - Db.DoubleBakingOps.Remove(doubleBaking); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index a729ca666..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class DoubleConsensusCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual void Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - var freezerUpdates = balanceUpdates.Where(x => x.RequiredString("kind") == "freezer" && x.RequiredString("category") == "deposits"); - var contractUpdates = balanceUpdates.Where(x => x.RequiredString("kind") == "contract"); - - var offenderAddr = freezerUpdates.Any() - ? freezerUpdates.First().RequiredString("delegate") - : Context.Proposer.Address; // this is wrong, but no big deal - - var offenderLoss = freezerUpdates.Any() - ? -freezerUpdates.Sum(x => x.RequiredInt64("change")) - : 0; - - var accuserReward = contractUpdates.Any() - ? contractUpdates.Sum(x => x.RequiredInt64("change")) - : 0; - - var accuser = Context.Proposer; - var offender = Cache.Accounts.GetExistingDelegate(offenderAddr); - - var kind = content.RequiredString("kind") == "double_endorsement_evidence" - ? DoubleConsensusKind.DoubleAttestation - : DoubleConsensusKind.DoublePreattestation; - - var doubleConsensus = new DoubleConsensusOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - - Kind = kind, - - SlashedLevel = block.Level, - AccusedLevel = content.Required("op1").Required("operations").RequiredInt32("level") - + (kind == DoubleConsensusKind.DoubleAttestation ? 1 : 0), - - AccuserId = accuser.Id, - OffenderId = offender.Id, - - Reward = accuserReward, - LostStaked = offenderLoss, - LostUnstaked = 0, - LostExternalStaked = 0, - LostExternalUnstaked = 0 - }; - #endregion - - #region entities - Db.TryAttach(accuser); - Db.TryAttach(offender); - #endregion - - #region apply operation - Receive(accuser, accuser, doubleConsensus.Reward); - - Spend(offender, offender, doubleConsensus.LostStaked); - - accuser.DoubleConsensusCount++; - if (offender != accuser) offender.DoubleConsensusCount++; - - block.Operations |= Operations.DoubleConsensus; - - Cache.AppState.Get().DoubleConsensusOpsCount++; - Cache.Statistics.Current.TotalBurned += doubleConsensus.LostStaked - doubleConsensus.Reward; - Cache.Statistics.Current.TotalFrozen -= doubleConsensus.LostStaked; - #endregion - - Db.DoubleConsensusOps.Add(doubleConsensus); - Context.DoubleConsensusOps.Add(doubleConsensus); - } - - public virtual void Revert(Block block, DoubleConsensusOperation doubleConsensus) - { - #region entities - var accuser = Cache.Accounts.GetDelegate(doubleConsensus.AccuserId); - var offender = Cache.Accounts.GetDelegate(doubleConsensus.OffenderId); - Db.TryAttach(accuser); - Db.TryAttach(offender); - #endregion - - #region apply operation - RevertReceive(accuser, accuser, doubleConsensus.Reward); - - RevertSpend(offender, offender, doubleConsensus.LostStaked); - - accuser.DoubleConsensusCount--; - if (offender != accuser) offender.DoubleConsensusCount--; - - Cache.AppState.Get().DoubleConsensusOpsCount--; - #endregion - - Db.DoubleConsensusOps.Remove(doubleConsensus); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 9a49da1b6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class NonceRevelationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var balanceUpdate = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind") == "contract"); - - var reward = balanceUpdate.ValueKind != JsonValueKind.Undefined - ? balanceUpdate.RequiredInt64("change") - : 0; - - var revealedBlock = await Cache.Blocks.GetAsync(content.RequiredInt32("level")); - var sender = Cache.Accounts.GetDelegate(revealedBlock.ProposerId!.Value); - - var revelation = new NonceRevelationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerId = Context.Proposer.Id, - SenderId = sender.Id, - RevealedLevel = revealedBlock.Level, - RevealedCycle = revealedBlock.Cycle, - Nonce = Hex.Parse(content.RequiredString("nonce")), - RewardDelegated = reward - }; - #endregion - - #region entities - var blockBaker = Context.Proposer; - - //Db.TryAttach(blockBaker); - Db.TryAttach(sender); - Db.TryAttach(revealedBlock); - #endregion - - #region apply operation - Receive(blockBaker, blockBaker, revelation.RewardDelegated); - - sender.NonceRevelationsCount++; - if (blockBaker != sender) blockBaker.NonceRevelationsCount++; - - block.Operations |= Operations.Revelations; - - revealedBlock.RevelationId = revelation.Id; - - Cache.AppState.Get().NonceRevelationOpsCount++; - Cache.Statistics.Current.TotalCreated += revelation.RewardDelegated; - #endregion - - Db.NonceRevelationOps.Add(revelation); - Context.NonceRevelationOps.Add(revelation); - } - - public virtual async Task Revert(Block block, NonceRevelationOperation revelation) - { - #region entities - var blockBaker = Context.Proposer; - var sender = Cache.Accounts.GetDelegate(revelation.SenderId); - var revealedBlock = await Cache.Blocks.GetAsync(revelation.RevealedLevel); - - //Db.TryAttach(blockBaker); - Db.TryAttach(sender); - Db.TryAttach(revealedBlock); - #endregion - - #region apply operation - RevertReceive(blockBaker, blockBaker, revelation.RewardDelegated); - - sender.NonceRevelationsCount--; - if (blockBaker != sender) blockBaker.NonceRevelationsCount--; - - revealedBlock.RevelationId = null; - - Cache.AppState.Get().NonceRevelationOpsCount--; - #endregion - - Db.NonceRevelationOps.Remove(revelation); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 1a3a01da4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class OriginationsCommit : Proto5.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index 3b4cd6f74..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class PreattestationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public void Apply(Block block, JsonElement op, JsonElement content) - { - var metadata = content.Required("metadata"); - Apply(block, op.RequiredString("hash"), metadata.RequiredString("delegate"), GetPower(metadata)); - } - - public void Apply(Block block, string opHash, string bakerAddress, long power) - { - var baker = Cache.Accounts.GetExistingDelegate(bakerAddress); - - var preattestation = new PreattestationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = opHash, - Power = power, - DelegateId = baker.Id - }; - - Db.TryAttach(baker); - baker.PreattestationsCount++; - - block.Operations |= Operations.Preattestations; - - Cache.AppState.Get().PreattestationOpsCount++; - - Db.PreattestationOps.Add(preattestation); - Context.PreattestationOps.Add(preattestation); - } - - public Task Revert(Block block, PreattestationOperation preattestation) - { - var baker = Cache.Accounts.GetDelegate(preattestation.DelegateId); - Db.TryAttach(baker); - baker.PreattestationsCount--; - - Cache.AppState.Get().PreattestationOpsCount--; - - Db.PreattestationOps.Remove(preattestation); - Cache.AppState.ReleaseOperationId(); - - return Task.CompletedTask; - } - - protected virtual long GetPower(JsonElement metadata) => metadata.OptionalInt64("preendorsement_power") ?? metadata.RequiredInt64("consensus_power"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 923a14681..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index 948902479..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class RegisterConstantsCommit : Proto11.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 6c88bbd61..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index 8f33c6872..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class SetDepositsLimitCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = (User)await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - - var result = content.Required("metadata").Required("operation_result"); - var limit = content.OptionalString("limit"); - - var operation = new SetDepositsLimitOperation - { - Id = Cache.AppState.NextOperationId(), - OpHash = op.RequiredString("hash"), - Level = block.Level, - Timestamp = block.Timestamp, - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - Limit = limit == null ? null : BigInteger.Parse(limit) - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter; - sender.SetDepositsLimitsCount++; - - block.Operations |= Operations.SetDepositsLimits; - - Cache.AppState.Get().SetDepositsLimitOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - if (operation.Limit != null) - { - (sender as Data.Models.Delegate)!.FrozenDepositLimit = operation.Limit > long.MaxValue / 100 - ? long.MaxValue / 100 - : (long)operation.Limit; - } - else - { - (sender as Data.Models.Delegate)!.FrozenDepositLimit = null; - } - UpdateBakerPower((sender as Data.Models.Delegate)!); - } - #endregion - - Proto.Manager.Set(sender); - Db.SetDepositsLimitOps.Add(operation); - Context.SetDepositsLimitOps.Add(operation); - } - - public virtual async Task Revert(Block block, SetDepositsLimitOperation op) - { - #region entities - var sender = (User)await Cache.Accounts.GetAsync(op.SenderId); - - Db.TryAttach(sender); - #endregion - - #region revert result - if (op.Status == OperationStatus.Applied) - { - var prevOp = await Db.SetDepositsLimitOps - .AsNoTracking() - .OrderByDescending(x => x.Id) - .FirstOrDefaultAsync(x => x.SenderId == op.SenderId && x.Status == OperationStatus.Applied && x.Id < op.Id); - - if (prevOp?.Limit != null) - { - (sender as Data.Models.Delegate)!.FrozenDepositLimit = prevOp.Limit > long.MaxValue / 100 - ? long.MaxValue / 100 - : (long)prevOp.Limit; - } - else - { - (sender as Data.Models.Delegate)!.FrozenDepositLimit = null; - } - RevertBakerPower((sender as Data.Models.Delegate)!); - } - #endregion - - #region revert operation - RevertPayFee(sender, op.BakerFee); - sender.SetDepositsLimitsCount--; - sender.Counter = op.Counter - 1; - sender.Revealed = true; - - Cache.AppState.Get().SetDepositsLimitOpsCount--; - #endregion - - Db.SetDepositsLimitOps.Remove(op); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 3a267e130..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class TransactionsCommit : Proto5.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index f39f1836e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class SnapshotBalanceCommit : Proto9.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override async Task SubtractCycleRewards(JsonElement rawBlock, Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "SnapshotBalances" as sb - SET "OwnDelegatedBalance" = "OwnDelegatedBalance" - bc."AttestationRewardsDelegated" - FROM ( - SELECT "BakerId", "AttestationRewardsDelegated" - FROM "BakerCycles" - WHERE "Cycle" = {0} - AND "AttestationRewardsDelegated" != 0 - ) as bc - WHERE sb."Level" = {1} - AND sb."BakerId" = bc."BakerId" - AND sb."AccountId" = bc."BakerId" - """, block.Cycle, block.Level); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SoftwareCommit.cs deleted file mode 100644 index 416c849cd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/StateCommit.cs deleted file mode 100644 index 961144b00..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/StatisticsCommit.cs deleted file mode 100644 index cdc521a4e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SubsidyCommit.cs deleted file mode 100644 index f41f8a4f7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/TokensCommit.cs deleted file mode 100644 index 796bca2e7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/VotingCommit.cs deleted file mode 100644 index 3f731e4db..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class VotingCommit : Proto8.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Diagnostics/Diagnostics.cs deleted file mode 100644 index 7ee60a639..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class Diagnostics(ProtocolHandler handler) : Proto5.Diagnostics(handler) - { - protected override async Task TestDelegate(int level, Data.Models.Delegate delegat, Protocol proto) - { - var remote = await Rpc.GetDelegateAsync(level, delegat.Address); - - if (!CheckFullBalance(remote, delegat)) - throw new Exception($"Diagnostics failed: wrong balance {delegat.Address}"); - - if (!CheckStakingBalance(remote, delegat)) - throw new Exception($"Diagnostics failed: wrong staking balance {delegat.Address}"); - - if (!CheckDelegatedBalance(remote, delegat)) - throw new Exception($"Diagnostics failed: wrong delegated balance {delegat.Address}"); - - if (!CheckMinDelegatedBalance(remote, delegat)) - throw new Exception($"Diagnostics failed: wrong min delegated balance {delegat.Address}"); - - if (!CheckBakingPower(remote, delegat)) - throw new Exception($"Diagnostics failed: wrong baking power {delegat.Address}"); - - if (!CheckVotingPower(remote, delegat)) - throw new Exception($"Diagnostics failed: wrong voting power {delegat.Address}"); - - if (remote.RequiredBool("deactivated") != !delegat.Staked) - throw new Exception($"Diagnostics failed: wrong deactivation state {delegat.Address}"); - - var deactivationCycle = (delegat.DeactivationLevel - 1) >= proto.FirstLevel - ? proto.GetCycle(delegat.DeactivationLevel - 1) - : (await Cache.Blocks.GetAsync(delegat.DeactivationLevel - 1)).Cycle; - - if (remote.RequiredInt32("grace_period") != deactivationCycle) - throw new Exception($"Diagnostics failed: wrong grace period {delegat.Address}"); - - if (!CheckFrozenDepositLimit(remote, delegat)) - throw new Exception($"Diagnostics failed: wrong frozen deposits limit {delegat.Address}"); - - TestDelegatorsCount(remote, delegat); - } - - protected override async Task TestParticipation(AppState state) - { - var bakers = Cache.Accounts.GetDelegates().ToList(); - var bakerCycles = Db.ChangeTracker.Entries() - .Where(x => x.Entity is BakerCycle bc && bc.Cycle == state.Cycle) - .Select(x => (x.Entity as BakerCycle)!) - .ToDictionary(x => x.BakerId); - - foreach (var baker in bakers) - { - var remote = await Rpc.GetDelegateParticipationAsync(state.Level, baker.Address); - - if (bakerCycles.TryGetValue(baker.Id, out var bakerCycle)) - { - if ((long)bakerCycle.ExpectedAttestations != remote.RequiredInt64("expected_cycle_activity")) - throw new Exception($"Invalid baker ExpectedAttestations {baker.Address}"); - - if (bakerCycle.FutureAttestationRewards != remote.RequiredInt64("expected_endorsing_rewards")) - throw new Exception($"Invalid baker FutureAttestationRewards {baker.Address}"); - - if (bakerCycle.MissedAttestations != remote.RequiredInt64("missed_slots")) - { - var proto = await Cache.Protocols.GetAsync(state.Protocol); - if (bakerCycle.Cycle != proto.FirstCycle) - throw new Exception($"Invalid baker MissedAttestations {baker.Address}"); - } - } - else - { - if (remote.RequiredInt64("expected_cycle_activity") != 0) - throw new Exception($"Invalid baker ExpectedAttestations {baker.Address}"); - - if (remote.RequiredInt64("expected_endorsing_rewards") != 0) - throw new Exception($"Invalid baker FutureAttestationRewards {baker.Address}"); - - if (remote.RequiredInt64("missed_slots") != 0) - throw new Exception($"Invalid baker MissedAttestations {baker.Address}"); - } - } - } - - protected override async Task TestCycle(AppState state, Cycle cycle) - { - var level = Math.Min(state.Level, cycle.FirstLevel); - var remote = await Rpc.GetCycleAsync(level, cycle.Index); - - if (remote.RequiredString("random_seed") != Hex.Convert(cycle.Seed)) - throw new Exception($"Invalid cycle {cycle.Index} seed {Hex.Convert(cycle.Seed)}"); - - if (remote.RequiredInt64("total_active_stake") != cycle.TotalBakingPower) - throw new Exception($"Invalid cycle {cycle.Index} selected stake {cycle.TotalBakingPower}"); - - if (remote.RequiredArray("selected_stake_distribution").Count() != cycle.TotalBakers) - throw new Exception($"Invalid cycle {cycle.Index} selected bakers {cycle.TotalBakers}"); - } - - protected virtual bool CheckFullBalance(JsonElement remote, Data.Models.Delegate delegat) => - remote.RequiredInt64("full_balance") == delegat.Balance; - - protected virtual bool CheckStakingBalance(JsonElement remote, Data.Models.Delegate delegat) => - remote.RequiredInt64("staking_balance") == delegat.TotalDelegated + delegat.TotalStaked; - - protected virtual bool CheckDelegatedBalance(JsonElement remote, Data.Models.Delegate delegat) => - remote.RequiredInt64("delegated_balance") == delegat.ExternalDelegatedBalance + delegat.RollupBonds; - - protected virtual bool CheckMinDelegatedBalance(JsonElement remote, Data.Models.Delegate delegat) => true; - - protected virtual bool CheckFrozenDepositLimit(JsonElement remote, Data.Models.Delegate delegat) => - remote.OptionalInt64("frozen_deposits_limit") == delegat.FrozenDepositLimit; - - protected virtual bool CheckBakingPower(JsonElement remote, Data.Models.Delegate delegat) - { - return true; - } - - protected virtual bool CheckVotingPower(JsonElement remote, Data.Models.Delegate delegat) - { - return true; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Helpers.cs deleted file mode 100644 index 65ddd5e9c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Helpers.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) - { - public override long BakingPower(Data.Models.Delegate baker) - { - if (!baker.Staked) - return 0; - - var depositCap = baker.FrozenDepositLimit is long depositLimit - ? Math.Min(baker.Balance, depositLimit) - : baker.Balance; - - var stake = Math.Min(baker.OwnDelegatedBalance + baker.ExternalDelegatedBalance, depositCap * (Context.Protocol.MaxDelegatedOverFrozenRatio + 1)); - if (stake < Context.Protocol.MinimalStake) - return 0; - - return stake; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Proto12Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Proto12Handler.cs deleted file mode 100644 index 16c46a730..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Proto12Handler.cs +++ /dev/null @@ -1,313 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto12; - -namespace Tzkt.Sync.Protocols -{ - class Proto12Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "ithaca_012"; - public override int VersionNumber => 12; - - public Proto12Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preendorsement": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - case "double_preendorsement_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - new FreezerCommit(this).Revert(); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Rpc/Rpc.cs deleted file mode 100644 index f69b1dcb0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Rpc/Rpc.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto12 -{ - class Rpc : Proto6.Rpc - { - public Rpc(TezosNode node) : base(node) { } - - public override Task GetDelegateParticipationAsync(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/delegates/{address}/participation"); - - public override Task GetLevelBakingRightsAsync(int block, int level, int maxRound) - => Node.GetAsync($"chains/main/blocks/{block}/helpers/baking_rights?level={level}&max_round={maxRound}&all=true"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto12/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto12/Validation/Validator.cs deleted file mode 100644 index bb46e60ba..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto12/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto12 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/ProtoActivator.cs deleted file mode 100644 index 4ecffd1e6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/ProtoActivator.cs +++ /dev/null @@ -1,193 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto12.ProtoActivator(proto) - { - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.LBToggleThreshold = parameters["liquidity_baking_toggle_ema_threshold"]?.Value() ?? 1_000_000_000; - protocol.BlocksPerVoting = (parameters["cycles_per_voting_period"]?.Value() ?? 5) * protocol.BlocksPerCycle; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.LBToggleThreshold = 1_000_000_000; - } - - protected override Sampler GetSampler(IEnumerable<(int id, long stake)> selection) - { - var sorted = selection.OrderByDescending(x => - Base58.Parse(Cache.Accounts.GetDelegate(x.id).Address), new BytesComparer()); - - return new Sampler(sorted.Select(x => x.id).ToArray(), sorted.Select(x => x.stake).ToArray()); - } - - protected override async Task MigrateContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - #region voting power - UpdateBakersPower(); - #endregion - - #region voting snapshots - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "VotingSnapshots" - WHERE "Period" = {0} - """, state.VotingPeriod); - - var snapshots = Cache.Accounts.GetDelegates() - .Where(x => x.VotingPower != 0) - .Select(x => new VotingSnapshot - { - Id = 0, - Level = state.Level, - Period = state.VotingPeriod, - BakerId = x.Id, - VotingPower = x.VotingPower, - Status = VoterStatus.None - }); - - var period = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(period); - - period.TotalBakers = snapshots.Count(); - period.TotalVotingPower = snapshots.Sum(x => x.VotingPower); - - Db.VotingSnapshots.AddRange(snapshots); - #endregion - - #region patch contracts - Db.TryAttach(block); - Db.TryAttach(state); - - var patched = File.ReadAllLines("./Protocols/Handlers/Proto13/Activation/patched.contracts"); - foreach (var address in patched) - { - if (await Cache.Accounts.GetAsync(address) is Contract contract) - { - Db.TryAttach(contract); - - var oldScript = await Db.Scripts.FirstAsync(x => x.ContractId == contract.Id && x.Current); - var oldStorage = await Cache.Storages.GetAsync(contract); - - var rawContract = await Proto.Rpc.GetContractAsync(state.Level, contract.Address); - - var code = (rawContract.Required("script").RequiredMicheline("code") as MichelineArray)!; - var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter).ToBytes(); - var micheStorage = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage).ToBytes(); - var micheCode = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code).ToBytes(); - var micheViews = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view); - - var newSchema = new ContractScript(code); - var newStorageValue = rawContract.Required("script").RequiredMicheline("storage"); - var newRawStorageValue = newSchema.OptimizeStorage(newStorageValue, false).ToBytes(); - - if (oldScript.ParameterSchema.IsEqual(micheParameter) && - oldScript.StorageSchema.IsEqual(micheStorage) && - oldScript.CodeSchema.IsEqual(micheCode) && - oldStorage.RawValue.IsEqual(newRawStorageValue)) - continue; - - Db.TryAttach(oldScript); - oldScript.Current = false; - - Db.TryAttach(oldStorage); - oldStorage.Current = false; - - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = contract.Id, - Kind = MigrationKind.CodeChange - }; - var newScript = new Script - { - Id = Cache.AppState.NextScriptId(), - Level = migration.Level, - ContractId = contract.Id, - MigrationId = migration.Id, - ParameterSchema = micheParameter, - StorageSchema = micheStorage, - CodeSchema = micheCode, - Views = micheViews.Any() - ? micheViews.Select(x => x.ToBytes()).ToArray() - : null, - Current = true - }; - var newStorage = new Storage - { - Id = Cache.AppState.NextStorageId(), - Level = migration.Level, - ContractId = contract.Id, - MigrationId = migration.Id, - RawValue = newRawStorageValue, - JsonValue = newScript.Schema.HumanizeStorage(newStorageValue), - Current = true - }; - - var viewsBytes = newScript.Views? - .OrderBy(x => x, new BytesComparer()) - .SelectMany(x => x) - .ToArray() - ?? []; - var typeSchema = newScript.ParameterSchema.Concat(newScript.StorageSchema).Concat(viewsBytes); - var fullSchema = typeSchema.Concat(newScript.CodeSchema); - contract.TypeHash = newScript.TypeHash = Script.GetHash(typeSchema); - contract.CodeHash = newScript.CodeHash = Script.GetHash(fullSchema); - - migration.ScriptId = newScript.Id; - migration.StorageId = newStorage.Id; - - contract.MigrationsCount++; - contract.LastLevel = migration.Level; - - state.MigrationOpsCount++; - - block.Operations |= Operations.Migrations; - - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - Db.Scripts.Add(newScript); - Cache.Schemas.Add(contract, newScript.Schema); - - Db.Storages.Add(newStorage); - Cache.Storages.Add(contract, newStorage); - } - } - #endregion - - #region empty contracts - // Account emptying has been significatnly changed, so that its behavoir is completely incompatible with previous protocols. - // Instead of adding a lot of code crutches to support both the new and old behavior, we just use the new one for all protocols - // and simply patch the accounts broken in previous protocols. - if (state.Chain == "mainnet") - { - var emptied = File.ReadAllLines("./Protocols/Handlers/Proto13/Activation/emptied.contracts"); - foreach (var address in emptied) - { - if (await Cache.Accounts.GetAsync(address) is User user) - { - Db.TryAttach(user); - var rawUser = await Proto.Rpc.GetContractAsync(state.Level, user.Address); - user.Counter = rawUser.RequiredInt32("counter"); - user.Revealed = false; - } - } - } - #endregion - } - - protected override Task RevertContext(AppState state) => throw new NotImplementedException(); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/emptied.contracts b/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/emptied.contracts deleted file mode 100644 index 2cc79da22..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/emptied.contracts +++ /dev/null @@ -1,46 +0,0 @@ -tz1QaeUtVEHKxe7z6sMcAJ5rymV4cgC7qJDc -tz1fMPyD5NwMTmMPyxs3qhJi5UnipRShZsEf -tz1LPjCjaQVQaMVRzTVercamJF8iSnWX7GT5 -tz1g6Ar2VYhfP9v5YY4dyz1zY3D7WhsKrVMG -tz1R4tJrZ4fdUsbQtjegiqP8BU4DaszVKnBs -tz1UCC2kJSqXGjTmjEuLkuYWBih4Ex77XG56 -tz1RtdokvW49Nj4gHgGCtprVynjaPoMf765k -tz1fX1ZDMY1ZKVWQqMWHfUkDd2v3fKZfZLv9 -tz1KoH3GUY7MAA1yAto4BCLt1cngATaSU6Pm -tz1UAUgGr88dX5Z1qbgvyVj5XVDEDzYwDGb6 -tz1dnA1QTEXmpTno2VMc1endcNhAmqrY6SBy -tz1i8uTVyBMftuJVYuQXjvnjzCx6pWYx44iS -tz1UbrYKvioLxu4M1uXeWz8S3WiXEGyFwvR6 -tz1iKYgrnfS23GBHC6hN3unoc2KQoYPLDo9T -tz1PSKxCTfa11zYijcscXv3mgCzrkoTQsX3D -tz1Vj816SvAYd3FPFCwjnDy5mJQCN9GDCq76 -tz1gAEw7xfKDFg9zJPu4WhU6k1DQPy5rMSpq -tz1bR4xJwDUv3TFBr4AJsMe7ZWUsxLw3ZEfd -tz1dZrgz3C5psgcPTS5T7kMmdpdXqfystjop -tz1TjWWZpCDTBZxoto2rqJVt2Np9vJpnsAC1 -tz1MZ1tkRgZDtnS864ezFwv7vmHWRPL82aD1 -tz1MNpwFcj2i6VPESwXqWxRsFYXLpGKv8rug -tz1by29D5fnHBW1qj7gTxAs1K5d7upzECvD7 -tz1VNhUaF2YAHbyXH6dKDZBKkzCm86oF6GhK -tz1LXKcmhDABC6xL72KaJ9HDdPa3hrDGFvRm -tz1TddbcdTxgNGJNyrK9vcCKnaNbTmKQjuwY -tz1ZEcjeP1fUJ74auebkF7jxxCa849bbNpce -tz1XxVnTwSJXYtJaXpaTh822Fj7t19cXep74 -tz1VdGDu2SYAhbNyBqC1wJrcYSLLvTw7pJa8 -tz1QHVbfbojnJKKVK5D3RL2X4xsqLJCoRqfT -tz1L6K71RcchNDo1nhhYkzLrbL7c9CmH5U7M -tz1MfzAtUeWeswAuMHoU5WcJati7L8Zsuq6n -tz1feWKASQDfNunAa9yXeZ1Q3fgEdJLnAZE7 -tz1Ng1UyG8ueEBsoriQFxsfTWR8KaT96r5w3 -tz1Um7wR1ykDB5fgD2gdJnfqVxhZSmkbG1bi -tz1eoPWGL6NmRGi77s2RaDimy2sV57jNWdBR -tz1YvzxXq6qaernExLNmXe5JrRzE7eTfhFD7 -tz1fr6cPT59QdXBk8AGWL6MxjnAdtnLzajhD -tz1g3n2ra6dCvy2iX9Eqq6EWgFpEvaTntBGT -tz1RzAqLb6chM7a1eQDcRzqCp3pVYr5qojUf -tz1TBbTrbv8mSJjK69XyuPSwDReC2bQHbp1U -tz1efmzutALUZykmUEC5tGzQbsAmDRW1XZsg -tz1VkPdDAoRCtuKvW3bi8ekt6yURueHL48UD -tz1RA9aSeEzxumgQcyiRHpTKYa9og4wgGjYP -tz1Sa2PwHjDFNZHbDcQRcyVSw8aGwXFRJaSs -tz1cjCf9zoGaPVKsz35eWWHkNKb6E6saftFX diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/patched.contracts b/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/patched.contracts deleted file mode 100644 index 0064d267f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Activation/patched.contracts +++ /dev/null @@ -1,43 +0,0 @@ -KT1MzfYSbq18fYr4f44aQRoZBQN72BAtiz5j -KT1Kfbk3B6NYPCPohPBDU3Hxf5Xeyy9PdkNp -KT1JW6PwhfaEJu6U3ENsxUeja48AdtqSoekd -KT1VsSxSXUkgw6zkBGgUuDXXuJs9ToPqkrCg -KT1TcAHw5gpejyemwRtdNyFKGBLc4qwA5gtw -KT1FN5fcNNcgieGjzxbVEPWUpJGwZEpzNGA8 -KT1Um7ieBEytZtumecLqGeL56iY6BuWoBgio -KT1QuofAgnsWffHzLA7D78rxytJruGHDe7XG -KT1CSKPf2jeLpMmrgKquN2bCjBTkAcAdRVDy -KT1D5NmtDtgCwPxYNb2ZK2But6dhNLs1T1bV -KT1VvXEpeBpreAVpfp4V8ZujqWu2gVykwXBJ -KT1TzamC1SCj68ia2E4q2GWZeT24yRHvUZay -KT1LZFMGrdnPjRLsCZ1aEDUAF5myA5Eo4rQe -KT1PDAELuX7CypUHinUgFgGFskKs7ytwh5Vw -KT19xDbLsvQKnp9xqfDNPWJbKJJmV93dHDUa -KT1Cz7TyVFvHxXpxLS57RFePrhTGisUpPhvD -KT1LQ99RfGcmFe98PiBcGXuyjBkWzAcoXXhW -KT1Gow8VzXZx3Akn5kvjACqnjnyYBxQpzSKr -KT1DnfT4hfikoMY3uiPE9mQV4y3Xweramb2k -KT1FuFDZGdw86p6krdBUKoZfEMkcUmezqX5o -KT1SLWhfqPtQq7f4zLomh8BNgDeprF9B6d2M -KT1THsDNgHtN56ew9VVCAUWnqPC81pqAxCEp -KT1CM1g1o9RKDdtDKgcBWE59X2KgTc2TcYtC -KT1W148mcjmfvr9J2RvWcGHxsAFApq9mcfgT -KT1HvwFnXteMbphi7mfPDhCWkZSDvXEz8iyv -KT1RUT25eGgo9KKWXfLhj1xYjghAY1iZ2don -KT1EWLAQGPMF2uhtVRPaCH2vtFVN36Njdr6z -KT1WPEis2WhAc2FciM2tZVn8qe6pCBe9HkDp -KT1Msatnmdy24sQt6knzpALs4tvHfSPPduA2 -KT1A56dh8ivKNvLiLVkjYPyudmnY2Ti5Sba3 -KT1KRyTaxCAM3YRquifEe29BDbUKNhJ6hdtx -KT1FL3C6t9Lyfskyb6rQrCRQTnf7M9t587VM -KT1Q1kfbvzteafLvnGz92DGvkdypXfTGfEA3 -KT1CjfCztmRpsyUee1nLa9Wcpfr7vgwqRZmk -KT1MHDHRLugz3A4qP6KqZDpa7FFmZfcJauV4 -KT1BvVxWM6cjFuJNet4R9m64VDCN2iMvjuGE -KT1PyX9b8WmShQjqNgDQsvxqj9UYdmHLr3xg -KT1XTXBsEauzcv3uPvVXW92mVqrx99UGsb9T -KT1Puc9St8wdNoGtLiD2WXaHbWU7styaxYhD -KT19c8n5mWrqpxMcR3J687yssHxotj88nGhZ -KT1DrJV8vhkdLEj76h1H9Q4irZDqAkMPo1Qf -KT1D68BvUm9N1fcq6uaZnyZvmBkBvj9biyPu -KT1CT7S2b9hXNRxRrEcany9sak1qe4aaFAZJ diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/AttestationRewardCommit.cs deleted file mode 100644 index 32f0456af..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class AttestationRewardCommit : Proto12.AttestationRewardCommit - { - public AttestationRewardCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BakerCycleCommit.cs deleted file mode 100644 index 8e0cf2d8b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class BakerCycleCommit : Proto12.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BakingRightsCommit.cs deleted file mode 100644 index 7678acc63..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Netezos.Encoding; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class BakingRightsCommit(ProtocolHandler protocol) : Proto12.BakingRightsCommit(protocol) - { - protected override Sampler GetSampler(IEnumerable<(int id, long stake)> selection, bool forceBase) - { - if (forceBase) - return base.GetSampler(selection, false); - - var sorted = selection.OrderByDescending(x => - { - var baker = Cache.Accounts.GetDelegate(x.id); - return new byte[] { (byte)baker.PublicKey![0] }.Concat(Base58.Parse(baker.Address)); - }, new BytesComparer()); - - return new Sampler(sorted.Select(x => x.id).ToArray(), sorted.Select(x => x.stake).ToArray()); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BigMapCommit.cs deleted file mode 100644 index 2f61fb59b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BlockCommit.cs deleted file mode 100644 index a9c5e0de4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/BlockCommit.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class BlockCommit : Proto12.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override bool? GetLBToggleVote(JsonElement block) - { - var vote = block.Required("header").RequiredString("liquidity_baking_toggle_vote"); - return vote == "on" ? true : vote == "off" ? false : null; - } - - protected override int GetLBToggleEma(JsonElement block) - => block.Required("metadata").RequiredInt32("liquidity_baking_toggle_ema"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/CycleCommit.cs deleted file mode 100644 index a5897a8b6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/CycleCommit.cs +++ /dev/null @@ -1,108 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class CycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Cycle? FutureCycle { get; protected set; } - public List? Snapshots { get; protected set; } - public Dictionary? SelectedStakes { get; protected set; } - - public virtual async Task Apply(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - var lastSeed = await Db.Cycles - .AsNoTracking() - .Where(x => x.Index == futureCycle - 1) - .Select(x => x.Seed) - .FirstOrDefaultAsync() - ?? throw new Exception($"Seed for cycle {futureCycle - 1} is missed"); - - var nonces = block.Cycle < 2 ? [] : await Db.NonceRevelationOps - .AsNoTracking() - .Where(x => x.RevealedCycle == block.Cycle - 2) - .OrderByDescending(x => x.RevealedLevel) - .Select(x => x.Nonce) - .ToListAsync(); - - var vdfSolution = await GetVdfSolution(block); - - var futureSeed = Seed.GetNextSeed(lastSeed, nonces, vdfSolution); - var snapshotLevel = 1; - - if (block.Cycle >= 1) - { - var snapshotProto = await Cache.Protocols.FindByCycleAsync(block.Cycle - 1); - var snapshotIndex = Seed.GetSnapshotIndex(futureSeed, snapshotProto.SnapshotsPerCycle, true); - snapshotLevel = snapshotProto.GetCycleStart(block.Cycle - 1) - 1 + (snapshotIndex + 1) * snapshotProto.BlocksPerSnapshot; - } - - Snapshots = await Db.SnapshotBalances - .AsNoTracking() - .Where(x => x.Level == snapshotLevel && x.BakerId == x.AccountId) - .ToListAsync(); - - SelectedStakes = await GetSelectedStakes(block, Context.Protocol, Snapshots); - - FutureCycle = new Cycle - { - Id = 0, - Index = futureCycle, - FirstLevel = Context.Protocol.GetCycleStart(futureCycle), - LastLevel = Context.Protocol.GetCycleEnd(futureCycle), - SnapshotLevel = snapshotLevel, - TotalBakers = SelectedStakes.Count, - TotalBakingPower = SelectedStakes.Values.Sum(), - Seed = futureSeed - }; - - Db.Cycles.Add(FutureCycle); - } - - public virtual async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Cycles" - WHERE "Index" = {0} - """, futureCycle); - } - - protected virtual Task GetVdfSolution(Block block) => Task.FromResult(null); - - protected virtual async Task> GetSelectedStakes(Block block, Protocol protocol, List snapshots) - { - var attestationRewards = await Db.BakerCycles - .AsNoTracking() - .Where(x => x.Cycle == block.Cycle - 1 && x.AttestationRewardsDelegated > 0) - .ToDictionaryAsync(x => x.BakerId, x => x.AttestationRewardsDelegated); - - return snapshots - .Where(x => x.StakingBalance >= protocol.MinimalStake) - .ToDictionary(x => x.AccountId, x => - { - var baker = Cache.Accounts.GetDelegate(x.AccountId); - - var lastBalance = baker.Balance; - if (attestationRewards.TryGetValue(baker.Id, out var reward)) - lastBalance -= reward; - if (block.ProposerId == baker.Id) - lastBalance -= block.RewardDelegated; - if (block.ProducerId == baker.Id) - lastBalance -= block.BonusDelegated; - - var depositCap = Math.Min(lastBalance, baker.FrozenDepositLimit ?? lastBalance); - return Math.Min(x.StakingBalance, depositCap * (protocol.MaxDelegatedOverFrozenRatio + 1)); - }); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/DeactivationCommit.cs deleted file mode 100644 index cfd106087..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index c9e28ce85..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/FreezerCommit.cs deleted file mode 100644 index 8e2011909..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class FreezerCommit : Proto12.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index f0604d24d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 35ede66cf..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class AttestationsCommit : Proto12.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 6eabeb738..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 4fbeab2c6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index f2d4e2703..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class DoubleBakingCommit : Proto12.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 819908c33..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class DoubleConsensusCommit : Proto12.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 4b9808686..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class NonceRevelationsCommit : Proto12.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 216c717a6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class OriginationsCommit(ProtocolHandler protocol) : Proto5.OriginationsCommit(protocol) - { - protected override IEnumerable? ParseBigMapDiffs(OriginationOperation origination, JsonElement result, MichelineArray code, IMicheline storage) - { - return result.TryGetProperty("lazy_storage_diff", out var diffs) - ? BigMapDiff.ParseLazyStorage(diffs) - : null; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index 758ac859c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class PreattestationsCommit : Proto12.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 5720a7dc0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index bacf05d96..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class RegisterConstantsCommit : Proto11.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 6de39cdd8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index 3ca0b8b56..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 3c2ca284f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TransactionsCommit(ProtocolHandler protocol) : Proto5.TransactionsCommit(protocol) - { - protected override IEnumerable? ParseBigMapDiffs(TransactionOperation transaction, JsonElement result) - { - return result.TryGetProperty("lazy_storage_diff", out var diffs) - ? BigMapDiff.ParseLazyStorage(diffs) - : null; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index ac9376a5e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Netezos.Contracts; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TransferTicketCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public TransferTicketOperation Operation { get; private set; } = null!; - public IEnumerable? TicketUpdates { get; private set; } - - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var target = await Cache.Accounts.GetAsync(content.RequiredString("destination")); - var ticketer = await Cache.Accounts.GetAsync(content.RequiredString("ticket_ticketer")); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new TransferTicketOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, - StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 - ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost - : null, - Amount = BigInteger.Parse(content.RequiredString("ticket_amount")), - TicketerId = ticketer?.Id, - Entrypoint = content.RequiredString("entrypoint"), - TargetId = target?.Id - }; - - try - { - var micheType = Schema.Create((content.RequiredMicheline("ticket_ty") as MichelinePrim)!); - var value = content.RequiredMicheline("ticket_contents"); - operation.RawType = micheType.ToMicheline().ToBytes(); - operation.RawContent = micheType.Optimize(value).ToBytes(); - operation.JsonContent = micheType.Humanize(value); - } - catch (Exception ex) - { - Logger.LogError(ex, "failed to process 'transfer_ticket' parameters"); - } - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(target); - Db.TryAttach(ticketer); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.TransferTicketCount++; - if (target != null && target != sender) target.TransferTicketCount++; - if (ticketer != null && ticketer != sender && ticketer != target) ticketer.TransferTicketCount++; - - block.Operations |= Operations.TransferTicket; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().TransferTicketOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - var burned = operation.StorageFee ?? 0; - Proto.Manager.Burn(burned); - - Spend(sender, burned); - - TicketUpdates = ParseTicketUpdates(result); - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.TransferTicketOps.Add(operation); - Context.TransferTicketOps.Add(operation); - Operation = operation; - } - - public virtual async Task Revert(Block block, TransferTicketOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var target = await Cache.Accounts.GetAsync(operation.TargetId); - var ticketer = await Cache.Accounts.GetAsync(operation.TicketerId); - - Db.TryAttach(sender); - Db.TryAttach(target); - Db.TryAttach(ticketer); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - RevertSpend(sender, operation.StorageFee ?? 0); - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.TransferTicketCount--; - if (target != null && target != sender) target.TransferTicketCount--; - if (ticketer != null && ticketer != sender && ticketer != target) ticketer.TransferTicketCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TransferTicketOpsCount--; - #endregion - - Db.TransferTicketOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual IEnumerable? ParseTicketUpdates(JsonElement result) - { - if (!result.TryGetProperty("ticket_updates", out var ticketUpdates)) - return null; - - var res = new List(); - foreach (var updates in ticketUpdates.RequiredArray().EnumerateArray()) - { - var list = new List(); - foreach (var update in updates.RequiredArray("updates").EnumerateArray()) - { - var amount = update.RequiredBigInteger("amount"); - if (amount != BigInteger.Zero) - { - list.Add(new TicketUpdate - { - Account = update.RequiredString("account"), - Amount = amount - }); - } - } - - if (list.Count > 0) - { - var ticketToken = updates.Required("ticket_token"); - var type = ticketToken.RequiredMicheline("content_type"); - var value = ticketToken.RequiredMicheline("content"); - var rawType = type.ToBytes(); - - byte[] rawContent; - string? jsonContent; - - try - { - var schema = Schema.Create((type as MichelinePrim)!); - rawContent = schema.Optimize(value).ToBytes(); - jsonContent = schema.Humanize(value); - } - catch (Exception ex) - { - Logger.LogError(ex, "Failed to parse ticket content"); - rawContent = value.ToBytes(); - jsonContent = null; - } - - res.Add(new TicketUpdates - { - Ticket = new TicketIdentity - { - Ticketer = ticketToken.RequiredString("ticketer"), - RawType = rawType, - RawContent = rawContent, - JsonContent = jsonContent, - TypeHash = Script.GetHash(rawType), - ContentHash = Script.GetHash(rawContent) - }, - Updates = list - }); - } - } - - return res.Count > 0 ? res : null; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupCommitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupCommitCommit.cs deleted file mode 100644 index 99366845e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupCommitCommit.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TxRollupCommitCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetAsync(content.RequiredString("rollup")); - - var result = content.Required("metadata").Required("operation_result"); - var bond = result.RequiredArray("balance_updates").EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind") == "contract"); - - var operation = new TxRollupCommitOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - RollupId = rollup?.Id, - Bond = bond.ValueKind == JsonValueKind.Undefined ? 0 : -bond.RequiredInt64("change"), - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000) - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.TxRollupCommitCount++; - if (rollup != null) rollup.TxRollupCommitCount++; - - block.Operations |= Operations.TxRollupCommit; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().TxRollupCommitOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - sender.RollupBonds += operation.Bond; - rollup!.RollupBonds += operation.Bond; - - Cache.Statistics.Current.TotalRollupBonds += operation.Bond; - } - #endregion - - Proto.Manager.Set(sender); - Db.TxRollupCommitOps.Add(operation); - Context.TxRollupCommitOps.Add(operation); - } - - public virtual async Task Revert(Block block, TxRollupCommitOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.RollupId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - sender.RollupBonds -= operation.Bond; - rollup!.RollupBonds -= operation.Bond; - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.TxRollupCommitCount--; - if (rollup != null) rollup.TxRollupCommitCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TxRollupCommitOpsCount--; - #endregion - - Db.TxRollupCommitOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupDispatchTicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupDispatchTicketsCommit.cs deleted file mode 100644 index cc1f4c051..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupDispatchTicketsCommit.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TxRollupDispatchTicketsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetAsync(content.RequiredString("tx_rollup")); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new TxRollupDispatchTicketsOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - RollupId = rollup?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, - StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 - ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost - : null - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.TxRollupDispatchTicketsCount++; - if (rollup != null) rollup.TxRollupDispatchTicketsCount++; - - block.Operations |= Operations.TxRollupDispatchTickets; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().TxRollupDispatchTicketsOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - var burned = operation.StorageFee ?? 0; - Proto.Manager.Burn(burned); - - Spend(sender, burned); - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.TxRollupDispatchTicketsOps.Add(operation); - Context.TxRollupDispatchTicketsOps.Add(operation); - } - - public virtual async Task Revert(Block block, TxRollupDispatchTicketsOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.RollupId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - RevertSpend(sender, operation.StorageFee ?? 0); - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.TxRollupDispatchTicketsCount--; - if (rollup != null) rollup.TxRollupDispatchTicketsCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TxRollupDispatchTicketsOpsCount--; - #endregion - - Db.TxRollupDispatchTicketsOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs deleted file mode 100644 index 2cc152839..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TxRollupFinalizeCommitmentCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetAsync(content.RequiredString("rollup")); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new TxRollupFinalizeCommitmentOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - RollupId = rollup?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000) - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.TxRollupFinalizeCommitmentCount++; - if (rollup != null) rollup.TxRollupFinalizeCommitmentCount++; - - block.Operations |= Operations.TxRollupFinalizeCommitment; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().TxRollupFinalizeCommitmentOpsCount++; - #endregion - - #region apply result - //if (operation.Status == OperationStatus.Applied) - //{ - //} - #endregion - - Proto.Manager.Set(sender); - Db.TxRollupFinalizeCommitmentOps.Add(operation); - Context.TxRollupFinalizeCommitmentOps.Add(operation); - } - - public virtual async Task Revert(Block block, TxRollupFinalizeCommitmentOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.RollupId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - //if (operation.Status == OperationStatus.Applied) - //{ - //} - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.TxRollupFinalizeCommitmentCount--; - if (rollup != null) rollup.TxRollupFinalizeCommitmentCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TxRollupFinalizeCommitmentOpsCount--; - #endregion - - Db.TxRollupFinalizeCommitmentOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupOriginationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupOriginationCommit.cs deleted file mode 100644 index 600a95cd5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupOriginationCommit.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TxRollupOriginationCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - Db.TryAttach(sender); - - var result = content.Required("metadata").Required("operation_result"); - - Rollup? rollup = null; - if (result.RequiredString("status") == "applied") - { - var address = result.RequiredString("originated_rollup"); - var ghost = await Cache.Accounts.GetAsync(address); - if (ghost != null) - { - rollup = new Rollup - { - Id = ghost.Id, - Index = ghost.Index, - FirstLevel = ghost.FirstLevel, - LastLevel = ghost.LastLevel, - Address = address, - Counter = 0, - CreatorId = sender.Id, - Type = AccountType.Rollup, - ActiveTokensCount = ghost.ActiveTokensCount, - TokenBalancesCount = ghost.TokenBalancesCount, - TokenTransfersCount = ghost.TokenTransfersCount, - ActiveTicketsCount = ghost.ActiveTicketsCount, - TicketBalancesCount = ghost.TicketBalancesCount, - TicketTransfersCount = ghost.TicketTransfersCount - }; - Db.Entry(ghost).State = EntityState.Detached; - Db.Entry(rollup).State = EntityState.Modified; - } - else - { - rollup = new Rollup - { - Id = Cache.AppState.NextAccountId(), - FirstLevel = block.Level, - LastLevel = block.Level, - Address = address, - Counter = 0, - CreatorId = sender.Id, - Type = AccountType.Rollup - }; - Db.Rollups.Add(rollup); - } - Cache.Accounts.Add(rollup); - } - - var origination = new TxRollupOriginationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - RollupId = rollup?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - AllocationFee = 4_000 * Context.Protocol.ByteCost - }; - #endregion - - #region apply operation - PayFee(sender, origination.BakerFee); - - sender.TxRollupOriginationCount++; - if (rollup != null) rollup.TxRollupOriginationCount++; - - block.Operations |= Operations.TxRollupOrigination; - - sender.Counter = origination.Counter; - - Cache.AppState.Get().TxRollupOriginationOpsCount++; - #endregion - - #region apply result - if (origination.Status == OperationStatus.Applied) - { - var burned = origination.AllocationFee ?? 0; - Proto.Manager.Burn(burned); - - Spend(sender, burned); - - sender.RollupsCount++; - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.TxRollupOriginationOps.Add(origination); - Context.TxRollupOriginationOps.Add(origination); - } - - public virtual async Task Revert(Block block, TxRollupOriginationOperation origination) - { - #region entities - var sender = await Cache.Accounts.GetAsync(origination.SenderId); - var rollup = await Cache.Accounts.GetAsync(origination.RollupId) as Rollup; - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - if (origination.Status == OperationStatus.Applied) - { - RevertSpend(sender, origination.AllocationFee ?? 0); - - sender.RollupsCount--; - - if (rollup!.TokenTransfersCount == 0 && rollup.TicketTransfersCount == 0 && rollup.Index is null) - { - Db.Rollups.Remove(rollup); - Cache.Accounts.Remove(rollup); - } - else - { - var ghost = new Account - { - Id = rollup.Id, - Index = rollup.Index, - Address = rollup.Address, - FirstLevel = rollup.FirstLevel, - LastLevel = rollup.LastLevel, - ActiveTokensCount = rollup.ActiveTokensCount, - TokenBalancesCount = rollup.TokenBalancesCount, - TokenTransfersCount = rollup.TokenTransfersCount, - ActiveTicketsCount = rollup.ActiveTicketsCount, - TicketBalancesCount = rollup.TicketBalancesCount, - TicketTransfersCount = rollup.TicketTransfersCount, - Type = AccountType.Ghost, - }; - - Db.Entry(rollup).State = EntityState.Detached; - Db.Entry(ghost).State = EntityState.Modified; - Cache.Accounts.Add(ghost); - } - } - #endregion - - #region revert operation - RevertPayFee(sender, origination.BakerFee); - - sender.TxRollupOriginationCount--; - - sender.Counter = origination.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TxRollupOriginationOpsCount--; - #endregion - - Db.TxRollupOriginationOps.Remove(origination); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupRejectionCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupRejectionCommit.cs deleted file mode 100644 index d6fd23ba2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupRejectionCommit.cs +++ /dev/null @@ -1,330 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; - -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TxRollupRejectionCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetAsync(content.RequiredString("rollup")); - - var result = content.Required("metadata").Required("operation_result"); - var updates = result.RequiredArray("balance_updates").EnumerateArray(); - var reward = updates.FirstOrDefault(x => x.RequiredString("kind") == "minted"); - var loss = updates.FirstOrDefault(x => x.RequiredString("kind") == "burned"); - var freezer = updates.FirstOrDefault(x => x.RequiredString("kind") == "freezer"); - var committer = freezer.ValueKind == JsonValueKind.Undefined - ? sender // if there is no balance update, we don't know who is the committer - : await Cache.Accounts.GetExistingAsync(freezer.RequiredString("contract")); - - var operation = new TxRollupRejectionOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - RollupId = rollup?.Id, - CommitterId = committer.Id, - Reward = reward.ValueKind == JsonValueKind.Undefined ? 0 : -reward.RequiredInt64("change"), - Loss = loss.ValueKind == JsonValueKind.Undefined ? 0 : loss.RequiredInt64("change"), - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000) - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(committer); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.TxRollupRejectionCount++; - if (rollup != null) rollup.TxRollupRejectionCount++; - if (sender.Id != committer.Id) committer.TxRollupRejectionCount++; - - block.Operations |= Operations.TxRollupRejection; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().TxRollupRejectionOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - Receive(sender, operation.Reward); - - Spend(committer, operation.Loss); - - if (sender != committer) - { - Proto.Manager.Credit(operation.Reward); - - if (committer.Balance == 0 && committer is User user && user.Type == AccountType.User && user.Revealed) - { - user.Counter = Cache.AppState.GetManagerCounter(); - user.Revealed = false; - } - } - - committer.RollupBonds -= operation.Loss; - rollup!.RollupBonds -= operation.Loss; - - Cache.Statistics.Current.TotalBurned += operation.Loss - operation.Reward; - Cache.Statistics.Current.TotalRollupBonds -= operation.Loss; - } - #endregion - - Proto.Manager.Set(sender); - Db.TxRollupRejectionOps.Add(operation); - Context.TxRollupRejectionOps.Add(operation); - } - - public virtual async Task Revert(Block block, TxRollupRejectionOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.RollupId); - var committer = await Cache.Accounts.GetAsync(operation.CommitterId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(committer); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - RevertReceive(sender, operation.Reward); - - RevertSpend(committer, operation.Loss); - - if (sender != committer) - { - if (committer.Balance == operation.Loss && committer is User user && user.Type == AccountType.User && !user.Revealed) - { - user.Counter = await RestoreCounter(user, operation.Id); - user.Revealed = true; - } - } - - committer.RollupBonds += operation.Loss; - rollup!.RollupBonds += operation.Loss; - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.TxRollupRejectionCount--; - if (rollup != null) rollup.TxRollupRejectionCount--; - if (committer.Id != sender.Id) committer.TxRollupRejectionCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TxRollupRejectionOpsCount--; - #endregion - - Db.TxRollupRejectionOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - async Task RestoreCounter(User user, long opId) - { - var counter = 0; - - if (user.DelegationsCount > 0) - { - var opCounter = await Db.DelegationOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.OriginationsCount > 0) - { - var opCounter = await Db.OriginationOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TransactionsCount > 0) - { - var opCounter = await Db.TransactionOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.RevealsCount > 0) - { - var opCounter = await Db.RevealOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.RegisterConstantsCount > 0) - { - var opCounter = await Db.RegisterConstantOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.SetDepositsLimitsCount > 0) - { - var opCounter = await Db.SetDepositsLimitOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TransferTicketCount > 0) - { - var opCounter = await Db.TransferTicketOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TxRollupCommitCount > 0) - { - var opCounter = await Db.TxRollupCommitOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TxRollupDispatchTicketsCount > 0) - { - var opCounter = await Db.TxRollupDispatchTicketsOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TxRollupFinalizeCommitmentCount > 0) - { - var opCounter = await Db.TxRollupFinalizeCommitmentOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TxRollupOriginationCount > 0) - { - var opCounter = await Db.TxRollupOriginationOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TxRollupRejectionCount > 0) - { - var opCounter = await Db.TxRollupRejectionOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TxRollupRemoveCommitmentCount > 0) - { - var opCounter = await Db.TxRollupRemoveCommitmentOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TxRollupReturnBondCount > 0) - { - var opCounter = await Db.TxRollupReturnBondOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - if (user.TxRollupSubmitBatchCount > 0) - { - var opCounter = await Db.TxRollupSubmitBatchOps - .AsNoTracking() - .Where(x => x.SenderId == user.Id && x.Id < opId) - .OrderByDescending(x => x.Id) - .Select(x => x.Counter) - .FirstAsync(); - counter = Math.Max(counter, opCounter); - } - - return counter; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupRemoveCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupRemoveCommitmentCommit.cs deleted file mode 100644 index e321165b0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupRemoveCommitmentCommit.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TxRollupRemoveCommitmentCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetAsync(content.RequiredString("rollup")); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new TxRollupRemoveCommitmentOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - RollupId = rollup?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000) - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.TxRollupRemoveCommitmentCount++; - if (rollup != null) rollup.TxRollupRemoveCommitmentCount++; - - block.Operations |= Operations.TxRollupRemoveCommitment; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().TxRollupRemoveCommitmentOpsCount++; - #endregion - - #region apply result - //if (operation.Status == OperationStatus.Applied) - //{ - //} - #endregion - - Proto.Manager.Set(sender); - Db.TxRollupRemoveCommitmentOps.Add(operation); - Context.TxRollupRemoveCommitmentOps.Add(operation); - } - - public virtual async Task Revert(Block block, TxRollupRemoveCommitmentOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.RollupId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - //if (operation.Status == OperationStatus.Applied) - //{ - //} - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.TxRollupRemoveCommitmentCount--; - if (rollup != null) rollup.TxRollupRemoveCommitmentCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TxRollupRemoveCommitmentOpsCount--; - #endregion - - Db.TxRollupRemoveCommitmentOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupReturnBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupReturnBondCommit.cs deleted file mode 100644 index 14f64fcf6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupReturnBondCommit.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TxRollupReturnBondCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetAsync(content.RequiredString("rollup")); - - var result = content.Required("metadata").Required("operation_result"); - var bond = result.RequiredArray("balance_updates").EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind") == "contract"); - - var operation = new TxRollupReturnBondOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - RollupId = rollup?.Id, - Bond = bond.ValueKind == JsonValueKind.Undefined ? 0 : bond.RequiredInt64("change"), - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000) - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.TxRollupReturnBondCount++; - if (rollup != null) rollup.TxRollupReturnBondCount++; - - block.Operations |= Operations.TxRollupReturnBond; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().TxRollupReturnBondOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - sender.RollupBonds -= operation.Bond; - rollup!.RollupBonds -= operation.Bond; - - Cache.Statistics.Current.TotalRollupBonds -= operation.Bond; - } - #endregion - - Proto.Manager.Set(sender); - Db.TxRollupReturnBondOps.Add(operation); - Context.TxRollupReturnBondOps.Add(operation); - } - - public virtual async Task Revert(Block block, TxRollupReturnBondOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.RollupId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - sender.RollupBonds += operation.Bond; - rollup!.RollupBonds += operation.Bond; - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.TxRollupReturnBondCount--; - if (rollup != null) rollup.TxRollupReturnBondCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TxRollupReturnBondOpsCount--; - #endregion - - Db.TxRollupReturnBondOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupSubmitBatchCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupSubmitBatchCommit.cs deleted file mode 100644 index 6218124e6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/Operations/TxRollupSubmitBatchCommit.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TxRollupSubmitBatchCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetAsync(content.RequiredString("rollup")); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new TxRollupSubmitBatchOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - RollupId = rollup?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, - StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 - ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost - : null - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.TxRollupSubmitBatchCount++; - if (rollup != null) rollup.TxRollupSubmitBatchCount++; - - block.Operations |= Operations.TxRollupSubmitBatch; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().TxRollupSubmitBatchOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - var burned = operation.StorageFee ?? 0; - Proto.Manager.Burn(burned); - - Spend(sender, burned); - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.TxRollupSubmitBatchOps.Add(operation); - Context.TxRollupSubmitBatchOps.Add(operation); - } - - public virtual async Task Revert(Block block, TxRollupSubmitBatchOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.RollupId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - RevertSpend(sender, operation.StorageFee ?? 0); - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.TxRollupSubmitBatchCount--; - if (rollup != null) rollup.TxRollupSubmitBatchCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().TxRollupSubmitBatchOpsCount--; - #endregion - - Db.TxRollupSubmitBatchOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index e17592dd7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class SnapshotBalanceCommit : Proto12.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SoftwareCommit.cs deleted file mode 100644 index 42eabbfbd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/StateCommit.cs deleted file mode 100644 index 903bd0d59..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/StatisticsCommit.cs deleted file mode 100644 index 8e74489b1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SubsidyCommit.cs deleted file mode 100644 index bc712e713..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/TokensCommit.cs deleted file mode 100644 index 82ff54f40..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/VotingCommit.cs deleted file mode 100644 index 07053f049..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Diagnostics/Diagnostics.cs deleted file mode 100644 index 64652de74..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class Diagnostics : Proto12.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Helpers.cs deleted file mode 100644 index f3fffb4f5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Helpers.cs +++ /dev/null @@ -1,18 +0,0 @@ - -namespace Tzkt.Sync.Protocols.Proto13 -{ - public class Helpers(ProtocolHandler proto) : Proto12.Helpers(proto) - { - public override long VotingPower(Data.Models.Delegate baker) - { - if (!baker.Staked) - return 0; - - var stake = baker.OwnDelegatedBalance + baker.ExternalDelegatedBalance; - if (stake < Context.Protocol.MinimalStake) - return 0; - - return stake; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Proto13Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Proto13Handler.cs deleted file mode 100644 index ad100a697..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Proto13Handler.cs +++ /dev/null @@ -1,385 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto13; - -namespace Tzkt.Sync.Protocols -{ - class Proto13Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "jakarta_013"; - public override int VersionNumber => 13; - - public Proto13Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preendorsement": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - case "double_preendorsement_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "tx_rollup_origination": - await new TxRollupOriginationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_submit_batch": - await new TxRollupSubmitBatchCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_commit": - await new TxRollupCommitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_finalize_commitment": - await new TxRollupFinalizeCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_remove_commitment": - await new TxRollupRemoveCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_return_bond": - await new TxRollupReturnBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_rejection": - await new TxRollupRejectionCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_dispatch_tickets": - await new TxRollupDispatchTicketsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - new FreezerCommit(this).Revert(); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TxRollupOriginationOperation op: - await new TxRollupOriginationCommit(this).Revert(currBlock, op); - break; - case TxRollupSubmitBatchOperation op: - await new TxRollupSubmitBatchCommit(this).Revert(currBlock, op); - break; - case TxRollupCommitOperation op: - await new TxRollupCommitCommit(this).Revert(currBlock, op); - break; - case TxRollupFinalizeCommitmentOperation op: - await new TxRollupFinalizeCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupRemoveCommitmentOperation op: - await new TxRollupRemoveCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupReturnBondOperation op: - await new TxRollupReturnBondCommit(this).Revert(currBlock, op); - break; - case TxRollupRejectionOperation op: - await new TxRollupRejectionCommit(this).Revert(currBlock, op); - break; - case TxRollupDispatchTicketsOperation op: - await new TxRollupDispatchTicketsCommit(this).Revert(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Rpc/Rpc.cs deleted file mode 100644 index 0f911ed2e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto13 -{ - class Rpc : Proto12.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto13/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto13/Validation/Validator.cs deleted file mode 100644 index bd406608b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto13/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto13 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Activation/ProtoActivator.cs deleted file mode 100644 index 7d5a2cfb0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Activation/ProtoActivator.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - partial class ProtoActivator : Proto13.ProtoActivator - { - public ProtoActivator(ProtocolHandler proto) : base(proto) { } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.Dictator = parameters["testnet_dictator"]?.Value(); - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - if (Cache.AppState.GetChainId() == "NetXnHfVqm9iesp") // ghostnet - { - protocol.BlocksPerVoting = prev.BlocksPerCycle; - protocol.Dictator = "tz1Xf8zdT3DbAX9cHw3c3CXh79rc4nK4gCe8"; // oxhead_testnet_baker - } - } - - protected override async Task MigrateContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(block); - - var account = (await Cache.Accounts.GetAsync("tz1X81bCXPtMiHu1d4UZF4GPhMPkvkp56ssb"))!; - Db.TryAttach(account); - Receive(account, 3_000_000_000L); - account.FirstLevel = Math.Min(account.FirstLevel, state.Level); - account.LastLevel = state.Level; - account.MigrationsCount++; - - block.Operations |= Operations.Migrations; - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = account.Id, - Kind = MigrationKind.ProposalInvoice, - BalanceChange = 3_000_000_000L - }; - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - Db.TryAttach(state); - state.MigrationOpsCount++; - - var stats = Cache.Statistics.Current; - Db.TryAttach(stats); - stats.TotalCreated += 3_000_000_000L; - - if (state.ChainId == "NetXnHfVqm9iesp") // ghostnet - { - var votingPeriod = await Cache.Periods.GetAsync(58); - Db.TryAttach(votingPeriod); - votingPeriod.LastLevel = 0; - state.VotingPeriod = 58; - state.VotingEpoch = 58; - } - } - - protected override async Task RevertContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - - var invoice = await Db.MigrationOps - .AsNoTracking() - .FirstAsync(x => x.Level == block.Level && x.Kind == MigrationKind.ProposalInvoice); - - var account = await Cache.Accounts.GetAsync(invoice.AccountId); - Db.TryAttach(account); - - RevertReceive(account, invoice.BalanceChange); - account.MigrationsCount--; - - Db.MigrationOps.Remove(invoice); - Cache.AppState.ReleaseOperationId(); - - state.MigrationOpsCount--; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/AttestationRewardCommit.cs deleted file mode 100644 index b164ab5fe..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class AttestationRewardCommit : Proto12.AttestationRewardCommit - { - public AttestationRewardCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BakerCycleCommit.cs deleted file mode 100644 index ea8c8c74c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class BakerCycleCommit : Proto12.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BakingRightsCommit.cs deleted file mode 100644 index 8684ae3a9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Netezos.Encoding; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class BakingRightsCommit(ProtocolHandler protocol) : Proto13.BakingRightsCommit(protocol) - { - protected override Sampler GetSampler(IEnumerable<(int id, long stake)> selection, bool forceBase) - { - var sorted = selection.OrderByDescending(x => - { - var baker = Cache.Accounts.GetDelegate(x.id); - return new byte[] { (byte)baker.PublicKey![0] }.Concat(Base58.Parse(baker.Address)); - }, new BytesComparer()); - - return new Sampler(sorted.Select(x => x.id).ToArray(), sorted.Select(x => x.stake).ToArray()); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BigMapCommit.cs deleted file mode 100644 index e4e2f4bef..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BlockCommit.cs deleted file mode 100644 index 991db04ec..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class BlockCommit : Proto13.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/ContractEventCommit.cs deleted file mode 100644 index 8be9d9839..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class ContractEventCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement content) - { - #region init - var contract = (await Cache.Accounts.GetExistingAsync(content.RequiredString("source")) as Contract)!; - var parentTx = Context.TransactionOps.OrderByDescending(x => x.Id).FirstOrDefault(x => x.TargetId == contract.Id) - ?? throw new Exception("Event parent transaction not found"); - - var result = content.Required("result"); - if (parentTx.Status != OperationStatus.Applied || result.RequiredString("status") != "applied") - return; - - var consumedGas = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000); - - var contractEvent = new ContractEvent - { - Id = Cache.AppState.NextEventId(), - Level = block.Level, - ContractId = contract.Id, - ContractCodeHash = contract.CodeHash, - TransactionId = parentTx.Id, - Tag = content.OptionalString("tag") - }; - - try - { - var type = (content.RequiredMicheline("type") as MichelinePrim)!; - var schema = Schema.Create(type); - contractEvent.Type = type.ToBytes(); - - var rawPayload = content.OptionalMicheline("payload") ?? new MichelinePrim { Prim = PrimType.Unit }; - - contractEvent.JsonPayload = schema.Humanize(rawPayload); - contractEvent.RawPayload = schema.Optimize(rawPayload).ToBytes(); - } - catch (Exception ex) - { - Logger.LogError(ex, "Failed to process event payload"); - } - #endregion - - #region apply - parentTx.GasUsed += consumedGas; - parentTx.EventsCount = (parentTx.EventsCount ?? 0) + 1; - contract.EventsCount++; - Cache.AppState.Get().EventsCount++; - block.Events |= BlockEvents.Events; - #endregion - - Db.Events.Add(contractEvent); - } - - public virtual async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.Events)) - return; - - var events = await Db.Events - .AsNoTracking() - .Where(x => x.Level == block.Level) - .ToListAsync(); - - foreach (var contractEvent in events) - { - var contract = (await Cache.Accounts.GetAsync(contractEvent.ContractId) as Contract)!; - Db.TryAttach(contract); - contract.EventsCount--; - - Cache.AppState.Get().EventsCount--; - } - - Cache.AppState.ReleaseEventId(events.Count); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Events" - WHERE "Level" = {0} - """, block.Level); - - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/CycleCommit.cs deleted file mode 100644 index 38389b00b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/CycleCommit.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class CycleCommit(ProtocolHandler protocol) : Proto13.CycleCommit(protocol) - { - protected override async Task GetVdfSolution(Block block) - { - return (await Db.VdfRevelationOps - .AsNoTracking() - .Where(x => x.Cycle == block.Cycle - 1) - .OrderBy(x => x.Id) - .FirstOrDefaultAsync())?.Solution; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/DeactivationCommit.cs deleted file mode 100644 index 44114dd12..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 1c0ff98b9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/FreezerCommit.cs deleted file mode 100644 index 0a2769307..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class FreezerCommit : Proto12.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index e02b6fedd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 01157cb8b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class AttestationsCommit : Proto12.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 3621af3fe..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 0e15a50b5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetConsumedGas(JsonElement result) - { - return (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 5ea1aff27..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class DoubleBakingCommit : Proto12.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 313c7c357..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class DoubleConsensusCommit : Proto12.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index 648f0a434..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class IncreasePaidStorageCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var contract = await Cache.Accounts.GetAsync(content.RequiredString("destination")) as Contract; - - var result = content.Required("metadata").Required("operation_result"); - var balanceUpdate = result.OptionalArray("balance_updates")?.EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind") == "burned" && x.RequiredString("category") == "storage fees"); - var storageFee = balanceUpdate is JsonElement el && el.ValueKind != JsonValueKind.Undefined - ? el.RequiredInt64("change") - : 0; - - var operation = new IncreasePaidStorageOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - ContractId = contract?.Id, - Amount = BigInteger.Parse(content.RequiredString("amount")), - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = (int)(storageFee / Context.Protocol.ByteCost), - StorageFee = storageFee - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(contract); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.IncreasePaidStorageCount++; - if (contract != null) contract.IncreasePaidStorageCount++; - - block.Operations |= Operations.IncreasePaidStorage; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().IncreasePaidStorageOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - var burned = operation.StorageFee ?? 0; - Proto.Manager.Burn(burned); - - Spend(sender, burned); - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.IncreasePaidStorageOps.Add(operation); - Context.IncreasePaidStorageOps.Add(operation); - } - - public virtual async Task Revert(Block block, IncreasePaidStorageOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var contract = await Cache.Accounts.GetAsync(operation.ContractId); - - Db.TryAttach(sender); - Db.TryAttach(contract); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - RevertSpend(sender, operation.StorageFee ?? 0); - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.IncreasePaidStorageCount--; - if (contract != null) contract.IncreasePaidStorageCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().IncreasePaidStorageOpsCount--; - #endregion - - Db.IncreasePaidStorageOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 5f552e0d9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class NonceRevelationsCommit : Proto12.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 68eefc775..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class OriginationsCommit : Proto13.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetConsumedGas(JsonElement result) - { - return (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index 07c2122d2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class PreattestationsCommit : Proto12.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 1383cef1e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,176 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class ProposalsCommit(ProtocolHandler protocol) : Proto3.ProposalsCommit(protocol) - { - public bool DictatorSeen = false; - - public override async Task Apply(Block block, JsonElement op, JsonElement content) - { - if (content.RequiredString("source") != Context.Protocol.Dictator) - { - await base.Apply(block, op, content); - return; - } - - Logger.LogWarning("Governance dictator is resetting the current voting epoch. All the voting history will be irrevocably removed from the database."); - - // Dictator's actions cause one-way changes, so in case of reorg the indexer won't be able to revert them - DictatorSeen = true; - - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var period = await Cache.Periods.GetAsync(content.RequiredInt32("period")); - var proposalHashes = content.RequiredArray("proposals").EnumerateArray().Select(x => x.RequiredString()).ToList(); - - #region remove voting operations - if (period.Kind == PeriodKind.Proposal) - { - var proposalOps = (await Db.ProposalOps.Where(x => x.Period == period.Index).ToListAsync()) - .Concat(Db.ChangeTracker.Entries().Where(x => x.Entity is ProposalOperation && x.State == EntityState.Added).Select(x => (x.Entity as ProposalOperation)!)); - - foreach (var proposalOp in proposalOps) - { - var proposalSender = Cache.Accounts.GetDelegate(proposalOp.SenderId); - Db.TryAttach(proposalSender); - proposalSender.ProposalsCount--; - - var proposalBlock = await Cache.Blocks.GetAsync(proposalOp.Level); - Db.TryAttach(proposalBlock); - proposalBlock.Operations &= ~Operations.Proposals; - - Cache.AppState.Get().ProposalOpsCount--; - - Db.ProposalOps.Remove(proposalOp); - } - } - else if (period.Kind == PeriodKind.Exploration || period.Kind == PeriodKind.Promotion) - { - var ballotOps = (await Db.BallotOps.Where(x => x.Period == period.Index).ToListAsync()) - .Concat(Db.ChangeTracker.Entries().Where(x => x.Entity is BallotOperation && x.State == EntityState.Added).Select(x => (x.Entity as BallotOperation)!)); - - foreach (var ballotOp in ballotOps) - { - var ballotSender = Cache.Accounts.GetDelegate(ballotOp.SenderId); - Db.TryAttach(ballotSender); - ballotSender.BallotsCount--; - - var ballotBlock = await Cache.Blocks.GetAsync(ballotOp.Level); - Db.TryAttach(ballotBlock); - ballotBlock.Operations &= ~Operations.Ballots; - - Cache.AppState.Get().BallotOpsCount--; - - Db.BallotOps.Remove(ballotOp); - } - } - #endregion - - #region remove proposals - var proposals = (await Db.Proposals.Where(x => x.FirstPeriod == period.Index).ToListAsync()) - .Concat(Db.ChangeTracker.Entries().Where(x => x.Entity is Proposal && x.State == EntityState.Added).Select(x => (x.Entity as Proposal)!)); - - foreach (var proposal in proposals) - { - Cache.AppState.ReleaseProposalId(); - Cache.Proposals.Remove(proposal); - Db.Proposals.Remove(proposal); - } - - if (period.Kind != PeriodKind.Proposal && period.Dictator < DictatorStatus.Reset) - { - var activeProposal = await Db.Proposals.FirstOrDefaultAsync(x => x.FirstPeriod != period.Index && x.LastPeriod == period.Index); - if (activeProposal != null) - { - activeProposal.LastPeriod--; - activeProposal.Status = ProposalStatus.Rejected; - } - } - - Cache.Proposals.Reset(); - #endregion - - #region reset snapshots - var snapshots = await Db.VotingSnapshots.Where(x => x.Period == period.Index).ToListAsync(); - foreach (var snapshot in snapshots) - snapshot.Status = VoterStatus.None; - #endregion - - #region reset periods - Db.TryAttach(period); - - if (period.Kind != PeriodKind.Proposal && period.Dictator < DictatorStatus.Reset) - { - period.Epoch++; - - var prevPeriod = await Cache.Periods.GetAsync(period.Index - 1); - Db.TryAttach(prevPeriod); - prevPeriod.Dictator = DictatorStatus.Abort; - } - - if (proposalHashes.Count == 0) - { - period.Kind = PeriodKind.Proposal; - period.Dictator = DictatorStatus.Reset; - - period.TotalBakers = snapshots.Count; - period.TotalVotingPower = snapshots.Sum(x => x.VotingPower); - - period.UpvotesQuorum = Context.Protocol.ProposalQuorum; - period.ProposalsCount = 0; - period.TopUpvotes = 0; - period.TopVotingPower = 0; - period.SingleWinner = false; - } - else - { - period.Kind = PeriodKind.Adoption; - period.Dictator = DictatorStatus.Submit; - - period.TotalBakers = snapshots.Count; - period.TotalVotingPower = snapshots.Sum(x => x.VotingPower); - - period.UpvotesQuorum = null; - period.ProposalsCount = null; - period.TopUpvotes = null; - period.TopVotingPower = null; - period.SingleWinner = null; - } - - period.ParticipationEma = null; - period.BallotsQuorum = null; - period.Supermajority = null; - - period.YayBallots = null; - period.NayBallots = null; - period.PassBallots = null; - period.YayVotingPower = null; - period.NayVotingPower = null; - period.PassVotingPower = null; - - Cache.Periods.Reset(); - #endregion - - #region push proposal - if (proposalHashes.Count > 0) - { - var proposal = new Proposal - { - Id = Cache.AppState.NextProposalId(), - Epoch = period.Epoch, - FirstPeriod = period.Index, - LastPeriod = period.Index, - Hash = proposalHashes[0], - InitiatorId = sender.Id, - Status = ProposalStatus.Active, - Upvotes = 0, - VotingPower = 0 - }; - Db.Proposals.Add(proposal); - } - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index bbec8f8b1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class RegisterConstantsCommit : Proto11.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetConsumedGas(JsonElement result) - { - return (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index b14fd22f9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetConsumedGas(JsonElement result) - { - return (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000); - } - - protected override void ApplyResult(RevealOperation op, Account sender, string pubKey) - { - if (op.Status != OperationStatus.Applied) return; - base.ApplyResult(op, sender, pubKey); - } - - protected override void RevertResult(RevealOperation op, Account sender) - { - if (op.Status != OperationStatus.Applied) return; - base.RevertResult(op, sender); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index 083d5e63d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 0f21fd5dd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TransactionsCommit : Proto13.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetConsumedGas(JsonElement result) - { - return (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index c7a0082bb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupCommitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupCommitCommit.cs deleted file mode 100644 index ded712542..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupCommitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TxRollupCommitCommit : Proto13.TxRollupCommitCommit - { - public TxRollupCommitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupDispatchTicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupDispatchTicketsCommit.cs deleted file mode 100644 index 4a38d6aeb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupDispatchTicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TxRollupDispatchTicketsCommit : Proto13.TxRollupDispatchTicketsCommit - { - public TxRollupDispatchTicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs deleted file mode 100644 index dc2c9c51b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TxRollupFinalizeCommitmentCommit : Proto13.TxRollupFinalizeCommitmentCommit - { - public TxRollupFinalizeCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupOriginationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupOriginationCommit.cs deleted file mode 100644 index ab1151407..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupOriginationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TxRollupOriginationCommit : Proto13.TxRollupOriginationCommit - { - public TxRollupOriginationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupRejectionCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupRejectionCommit.cs deleted file mode 100644 index cfe0a561b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupRejectionCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TxRollupRejectionCommit : Proto13.TxRollupRejectionCommit - { - public TxRollupRejectionCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupRemoveCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupRemoveCommitmentCommit.cs deleted file mode 100644 index fe9018dd1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupRemoveCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TxRollupRemoveCommitmentCommit : Proto13.TxRollupRemoveCommitmentCommit - { - public TxRollupRemoveCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupReturnBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupReturnBondCommit.cs deleted file mode 100644 index def4d3eca..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupReturnBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TxRollupReturnBondCommit : Proto13.TxRollupReturnBondCommit - { - public TxRollupReturnBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupSubmitBatchCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupSubmitBatchCommit.cs deleted file mode 100644 index 2bdff147a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/TxRollupSubmitBatchCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TxRollupSubmitBatchCommit : Proto13.TxRollupSubmitBatchCommit - { - public TxRollupSubmitBatchCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 83201adcf..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class VdfRevelationCommit : ProtocolCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - - public virtual Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var balanceUpdate = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind") == "contract"); - var reward = balanceUpdate.ValueKind != JsonValueKind.Undefined - ? balanceUpdate.RequiredInt64("change") - : 0; - - var revelation = new VdfRevelationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerId = Context.Proposer.Id, - Cycle = block.Cycle, - RewardDelegated = reward, - Solution = Hex.Parse(content.RequiredArray("solution", 2)[0].RequiredString()), - Proof = Hex.Parse(content.RequiredArray("solution", 2)[1].RequiredString()) - }; - #endregion - - #region entities - var blockBaker = Context.Proposer; - //Db.TryAttach(blockBaker); - #endregion - - #region apply operation - Receive(blockBaker, blockBaker, revelation.RewardDelegated); - - blockBaker.VdfRevelationsCount++; - Cache.AppState.Get().VdfRevelationOpsCount++; - - block.Operations |= Operations.VdfRevelation; - - Cache.Statistics.Current.TotalCreated += revelation.RewardDelegated; - #endregion - - Db.VdfRevelationOps.Add(revelation); - Context.VdfRevelationOps.Add(revelation); - return Task.CompletedTask; - } - - public virtual Task Revert(Block block, VdfRevelationOperation revelation) - { - #region entities - var blockBaker = Context.Proposer; - //Db.TryAttach(blockBaker); - #endregion - - #region apply operation - RevertReceive(blockBaker, blockBaker, revelation.RewardDelegated); - - blockBaker.VdfRevelationsCount--; - Cache.AppState.Get().VdfRevelationOpsCount--; - #endregion - - Db.VdfRevelationOps.Remove(revelation); - Cache.AppState.ReleaseOperationId(); - return Task.CompletedTask; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 84f42802b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class SnapshotBalanceCommit : Proto12.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SoftwareCommit.cs deleted file mode 100644 index cf79f3772..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/StateCommit.cs deleted file mode 100644 index d5960e9a7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/StatisticsCommit.cs deleted file mode 100644 index 5177261a2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SubsidyCommit.cs deleted file mode 100644 index ba462f1eb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/TokensCommit.cs deleted file mode 100644 index 5e0452f9e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/VotingCommit.cs deleted file mode 100644 index 714499147..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Diagnostics/Diagnostics.cs deleted file mode 100644 index f3f0f99e5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class Diagnostics : Proto12.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - - protected override bool CheckDelegatedBalance(JsonElement remote, Data.Models.Delegate delegat) => - remote.RequiredInt64("delegated_balance") == delegat.ExternalDelegatedBalance; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Helpers.cs deleted file mode 100644 index 05b1d3d6e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - public class Helpers(ProtocolHandler proto) : Proto13.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Proto14Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Proto14Handler.cs deleted file mode 100644 index a9c1bc757..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Proto14Handler.cs +++ /dev/null @@ -1,404 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto14; - -namespace Tzkt.Sync.Protocols -{ - class Proto14Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "kathmandu_014"; - public override int VersionNumber => 14; - - public Proto14Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preendorsement": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - case "double_preendorsement_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "tx_rollup_origination": - await new TxRollupOriginationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_submit_batch": - await new TxRollupSubmitBatchCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_commit": - await new TxRollupCommitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_finalize_commitment": - await new TxRollupFinalizeCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_remove_commitment": - await new TxRollupRemoveCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_return_bond": - await new TxRollupReturnBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_rejection": - await new TxRollupRejectionCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_dispatch_tickets": - await new TxRollupDispatchTicketsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - new FreezerCommit(this).Revert(); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TxRollupOriginationOperation op: - await new TxRollupOriginationCommit(this).Revert(currBlock, op); - break; - case TxRollupSubmitBatchOperation op: - await new TxRollupSubmitBatchCommit(this).Revert(currBlock, op); - break; - case TxRollupCommitOperation op: - await new TxRollupCommitCommit(this).Revert(currBlock, op); - break; - case TxRollupFinalizeCommitmentOperation op: - await new TxRollupFinalizeCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupRemoveCommitmentOperation op: - await new TxRollupRemoveCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupReturnBondOperation op: - await new TxRollupReturnBondCommit(this).Revert(currBlock, op); - break; - case TxRollupRejectionOperation op: - await new TxRollupRejectionCommit(this).Revert(currBlock, op); - break; - case TxRollupDispatchTicketsOperation op: - await new TxRollupDispatchTicketsCommit(this).Revert(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Rpc/Rpc.cs deleted file mode 100644 index 49cfe5609..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto14 -{ - class Rpc : Proto12.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto14/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto14/Validation/Validator.cs deleted file mode 100644 index 158576080..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto14/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto14 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Activation/ProtoActivator.cs deleted file mode 100644 index 450458c6b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Activation/ProtoActivator.cs +++ /dev/null @@ -1,512 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto15 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto14.ProtoActivator(proto) - { - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.MinimalStake = parameters["minimal_stake"]?.Value() ?? 6_000_000L; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) { } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - await AddInvoice(state, "tz1MidLyXXvKWMmbRvKKeusDtP95NDJ5gAUx", 10_000_000_000L); - await AddInvoice(state, "tz1X81bCXPtMiHu1d4UZF4GPhMPkvkp56ssb", 15_000_000_000L); - await MigrateCurrentRights(state, prevProto, nextProto); - await MigrateFutureRights(state, nextProto); - await PatchContracts(state); - - Cache.BakingRights.Reset(); - Cache.BakerCycles.Reset(); - - if (state.ChainId == "NetXnHfVqm9iesp") // ghostnet: amend broken voting period - { - await RestartVotingPeriod(state, nextProto); - } - } - - protected override Task RevertContext(AppState state) - { - throw new NotImplementedException("Reverting Lima migration block is not implemented, because likely won't be needed"); - } - - async Task RestartVotingPeriod(AppState state, Protocol nextProto) - { - var currentPeriod = await Cache.Periods.GetAsync(58); - Db.TryAttach(currentPeriod); - - #region update current period - currentPeriod.LastLevel = state.Level; - currentPeriod.Status = currentPeriod.ProposalsCount == 0 - ? PeriodStatus.NoProposals - : PeriodStatus.NoQuorum; - #endregion - - #region update proposals status - if (currentPeriod.ProposalsCount > 0) - { - var proposals = await Db.Proposals - .Where(x => x.Status == ProposalStatus.Active) - .ToListAsync(); - - var pendings = Db.ChangeTracker.Entries() - .Where(x => x.Entity is Proposal p && p.Status == ProposalStatus.Active) - .Select(x => (x.Entity as Proposal)!) - .ToList(); - - foreach (var pending in pendings) - if (!proposals.Any(x => x.Id == pending.Id)) - proposals.Add(pending); - - foreach (var proposal in proposals) - proposal.Status = ProposalStatus.Skipped; - } - #endregion - - #region update snapshots - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "VotingSnapshots" - WHERE "Period" > 58; - """); - - Db.VotingSnapshots.AddRange((await Db.VotingSnapshots - .AsNoTracking() - .Where(x => x.Period == 58) - .ToListAsync()) - .Select(x => new VotingSnapshot - { - Id = 0, - BakerId = x.BakerId, - Level = x.Level, - Period = x.Period + 1, - Status = VoterStatus.None, - VotingPower = x.VotingPower - })); - #endregion - - #region add next period - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "VotingPeriods" - WHERE "Index" > 58; - """); - - Db.VotingPeriods.Add(new VotingPeriod - { - Id = 0, - Index = currentPeriod.Index + 1, - Epoch = currentPeriod.Epoch + 1, - FirstLevel = currentPeriod.LastLevel + 1, - LastLevel = currentPeriod.LastLevel + nextProto.BlocksPerVoting, - Kind = PeriodKind.Proposal, - Status = PeriodStatus.Active, - TotalBakers = currentPeriod.TotalBakers, - TotalVotingPower = currentPeriod.TotalVotingPower, - UpvotesQuorum = nextProto.ProposalQuorum, - ProposalsCount = 0, - TopUpvotes = 0, - TopVotingPower = 0, - SingleWinner = false, - }); - #endregion - - state.VotingPeriod = currentPeriod.Index + 1; - state.VotingEpoch = currentPeriod.Epoch + 1; - Cache.Periods.Reset(); - } - - async Task AddInvoice(AppState state, string address, long amount) - { - var block = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(block); - - var account = (await Cache.Accounts.GetAsync(address))!; - Db.TryAttach(account); - Receive(account, amount); - account.FirstLevel = Math.Min(account.FirstLevel, state.Level); - account.LastLevel = state.Level; - account.MigrationsCount++; - - block.Operations |= Operations.Migrations; - - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = account.Id, - Kind = MigrationKind.ProposalInvoice, - BalanceChange = amount - }; - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - Db.TryAttach(state); - state.MigrationOpsCount++; - - var stats = Cache.Statistics.Current; - Db.TryAttach(stats); - stats.TotalCreated += amount; - } - - async Task MigrateCurrentRights(AppState state, Protocol prevProto, Protocol nextProto) - { - var cycle = await Db.Cycles.AsNoTracking().FirstAsync(x => x.Index == state.Cycle); - if (state.Level == cycle.LastLevel) return; - - var bakerCycles = await Cache.BakerCycles.GetAsync(state.Cycle); - - #region revert current rights - var rights = await Db.BakingRights - .AsNoTracking() - .Where(x => x.Level > state.Level && x.Cycle == state.Cycle) - .ToListAsync(); - - foreach (var br in rights.Where(x => x.Type == BakingRightType.Baking && x.Round == 0)) - { - var bakerCycle = bakerCycles[br.BakerId]; - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks--; - bakerCycle.FutureBlockRewards -= prevProto.MaxBakingReward; - } - - foreach (var ar in rights.Where(x => x.Type == BakingRightType.Attestation)) - { - var bakerCycle = bakerCycles[ar.BakerId]; - Db.TryAttach(bakerCycle); - - bakerCycle.FutureAttestations -= ar.Slots!.Value; - } - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Level" > {0} AND "Cycle" = {1} - """, state.Level, state.Cycle); - - #endregion - - #region apply new rights - var sampler = GetOldSampler(bakerCycles.Values - .Where(x => x.BakingPower > 0) - .Select(x => (x.BakerId, x.BakingPower)) - .ToList()); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, cycle.Index); - #endregion - - var brs = new List(); - var ars = new List(); - for (int level = state.Level + 1; level <= cycle.LastLevel; level++) - { - foreach (var br in RightsGenerator.GetBakingRights(sampler, cycle, level)) - { - brs.Add(br); - if (br.Round == 0) - { - var bakerCycle = bakerCycles[br.Baker]; - Db.TryAttach(bakerCycle); - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += nextProto.MaxBakingReward; - } - } - foreach (var ar in RightsGenerator.GetAttestationRights(sampler, nextProto, cycle, level - 1)) - { - ars.Add(ar); - var bakerCycle = bakerCycles[ar.Baker]; - Db.TryAttach(bakerCycle); - bakerCycle.FutureAttestations += ar.Slots; - } - } - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@" - COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") - FROM STDIN (FORMAT BINARY)"); - - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - #endregion - } - - async Task MigrateFutureRights(AppState state, Protocol nextProto) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" > {0} - """, state.Cycle); - - - var cycles = await Db.Cycles - .AsNoTracking() - .Where(x => x.Index >= state.Cycle) - .OrderBy(x => x.Index) - .ToListAsync(); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - IEnumerable shifted = []; - - foreach (var cycle in cycles) - { - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - var sampler = GetOldSampler(bakerCycles.Values - .Where(x => x.BakingPower > 0) - .Select(x => (x.BakerId, x.BakingPower)) - .ToList()); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, cycle.Index); - #endregion - - if (cycle.Index == state.Cycle) - { - shifted = RightsGenerator.GetAttestationRights(sampler, nextProto, cycle, cycle.LastLevel); - - #region save shifted - using (var writer = conn.BeginBinaryImport(@" - COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") - FROM STDIN (FORMAT BINARY)")) - { - foreach (var ar in shifted) - { - writer.StartRow(); - writer.Write(cycle.Index + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - writer.Complete(); - } - #endregion - } - else - { - GC.Collect(); - var brs = await RightsGenerator.GetBakingRightsAsync(sampler, nextProto, cycle); - var ars = await RightsGenerator.GetAttestationRightsAsync(sampler, nextProto, cycle); - - #region save rights - using (var writer = conn.BeginBinaryImport(@" - COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") - FROM STDIN (FORMAT BINARY)")) - { - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(nextProto.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - - #region reset baker cycles - foreach (var bakerCycle in bakerCycles.Values) - { - bakerCycle.FutureBlocks = 0; - bakerCycle.FutureBlockRewards = 0; - bakerCycle.FutureAttestations = 0; - } - - foreach (var br in brs.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += nextProto.MaxBakingReward; - } - - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots; - } - } - - foreach (var ar in ars.TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - shifted = ars.Where(x => x.Level == cycle.LastLevel).ToList(); - } - } - } - - async Task PatchContracts(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - var patched = File.ReadAllLines("./Protocols/Handlers/Proto15/Activation/patched.contracts"); - foreach (var address in patched) - { - if (await Cache.Accounts.GetAsync(address) is Contract contract) - { - Db.TryAttach(contract); - - var oldScript = await Db.Scripts.FirstAsync(x => x.ContractId == contract.Id && x.Current); - var oldStorage = await Cache.Storages.GetAsync(contract); - - var rawContract = await Proto.Rpc.GetContractAsync(state.Level, contract.Address); - - var code = (rawContract.Required("script").RequiredMicheline("code") as MichelineArray)!; - var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter).ToBytes(); - var micheStorage = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage).ToBytes(); - var micheCode = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code).ToBytes(); - var micheViews = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view); - - var newSchema = new ContractScript(code); - var newStorageValue = rawContract.Required("script").RequiredMicheline("storage"); - var newRawStorageValue = newSchema.OptimizeStorage(newStorageValue, false).ToBytes(); - - if (oldScript.ParameterSchema.IsEqual(micheParameter) && - oldScript.StorageSchema.IsEqual(micheStorage) && - oldScript.CodeSchema.IsEqual(micheCode) && - oldStorage.RawValue.IsEqual(newRawStorageValue)) - continue; - - Db.TryAttach(oldScript); - oldScript.Current = false; - - Db.TryAttach(oldStorage); - oldStorage.Current = false; - - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = contract.Id, - Kind = MigrationKind.CodeChange - }; - var newScript = new Script - { - Id = Cache.AppState.NextScriptId(), - Level = migration.Level, - ContractId = contract.Id, - MigrationId = migration.Id, - ParameterSchema = micheParameter, - StorageSchema = micheStorage, - CodeSchema = micheCode, - Views = micheViews.Any() - ? micheViews.Select(x => x.ToBytes()).ToArray() - : null, - Current = true - }; - var newStorage = new Storage - { - Id = Cache.AppState.NextStorageId(), - Level = migration.Level, - ContractId = contract.Id, - MigrationId = migration.Id, - RawValue = newRawStorageValue, - JsonValue = newScript.Schema.HumanizeStorage(newStorageValue), - Current = true - }; - - var viewsBytes = newScript.Views? - .OrderBy(x => x, new BytesComparer()) - .SelectMany(x => x) - .ToArray() - ?? []; - var typeSchema = newScript.ParameterSchema.Concat(newScript.StorageSchema).Concat(viewsBytes); - var fullSchema = typeSchema.Concat(newScript.CodeSchema); - contract.TypeHash = newScript.TypeHash = Script.GetHash(typeSchema); - contract.CodeHash = newScript.CodeHash = Script.GetHash(fullSchema); - - migration.ScriptId = newScript.Id; - migration.StorageId = newStorage.Id; - - contract.MigrationsCount++; - contract.LastLevel = migration.Level; - - state.MigrationOpsCount++; - - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - Db.Scripts.Add(newScript); - Cache.Schemas.Add(contract, newScript.Schema); - - Db.Storages.Add(newStorage); - Cache.Storages.Add(contract, newStorage); - } - } - } - - Sampler GetOldSampler(IEnumerable<(int id, long stake)> selection) - { - var sorted = selection - .OrderByDescending(x => x.stake) - .ThenByDescending(x => - { - var baker = Cache.Accounts.GetDelegate(x.id); - return new byte[] { (byte)baker.PublicKey![0] }.Concat(Base58.Parse(baker.Address)); - }, new BytesComparer()); - - return new Sampler(sorted.Select(x => x.id).ToArray(), sorted.Select(x => x.stake).ToArray()); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Activation/patched.contracts b/Tzkt.Sync/Protocols/Handlers/Proto15/Activation/patched.contracts deleted file mode 100644 index e9980bfa6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Activation/patched.contracts +++ /dev/null @@ -1 +0,0 @@ -KT1SL6CGhjPUyLypDbFv9bXsNF2sHG7Fy3j9 diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/AttestationRewardCommit.cs deleted file mode 100644 index dbb5dc2e6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class AttestationRewardCommit : Proto12.AttestationRewardCommit - { - public AttestationRewardCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BakerCycleCommit.cs deleted file mode 100644 index 48b504e50..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class BakerCycleCommit : Proto12.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BakingRightsCommit.cs deleted file mode 100644 index 44b3bf6af..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Netezos.Encoding; - -namespace Tzkt.Sync.Protocols.Proto15 -{ - class BakingRightsCommit(ProtocolHandler protocol) : Proto14.BakingRightsCommit(protocol) - { - protected override Sampler GetSampler(IEnumerable<(int id, long stake)> selection, bool forceBase) - { - if (forceBase) - { - var sorted = selection - .OrderByDescending(x => x.stake) - .ThenByDescending(x => - { - var baker = Cache.Accounts.GetDelegate(x.id); - return new byte[] { (byte)baker.PublicKey![0] }.Concat(Base58.Parse(baker.Address)); - }, new BytesComparer()); - - return new Sampler(sorted.Select(x => x.id).ToArray(), sorted.Select(x => x.stake).ToArray()); - } - - return base.GetSampler(selection, forceBase); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BigMapCommit.cs deleted file mode 100644 index 157c1fb63..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BlockCommit.cs deleted file mode 100644 index edc5fdc32..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class BlockCommit : Proto13.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/ContractEventCommit.cs deleted file mode 100644 index b53678860..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class ContractEventCommit : Proto14.ContractEventCommit - { - public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/CycleCommit.cs deleted file mode 100644 index ce013e8d8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class CycleCommit : Proto14.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/DeactivationCommit.cs deleted file mode 100644 index cf4167eef..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 4b033d7a8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/FreezerCommit.cs deleted file mode 100644 index 38d498de7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class FreezerCommit : Proto12.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 159a2cd30..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 47a8d0e37..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class AttestationsCommit : Proto12.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 8a3066c5f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 8e26b392e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class DelegationsCommit : Proto14.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 0547a42d9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class DoubleBakingCommit : Proto12.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 9fe107e5f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class DoubleConsensusCommit : Proto12.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index d128ada1d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto15 -{ - class DrainDelegateCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var delegat = Cache.Accounts.GetExistingDelegate(content.RequiredString("delegate")); - var target = (await Cache.Accounts.GetAsync(content.RequiredString("destination")))!; - - var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - - var allocationFeeUpdate = balanceUpdates.SingleOrDefault(x => x.RequiredString("kind") == "burned"); - var allocationFee = allocationFeeUpdate.ValueKind != JsonValueKind.Undefined - ? allocationFeeUpdate.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") == Context.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") == Context.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 - { - Id = Cache.AppState.NextOperationId(), - OpHash = op.RequiredString("hash"), - Level = block.Level, - Timestamp = block.Timestamp, - DelegateId = delegat.Id, - TargetId = target.Id, - Amount = amount, - Fee = fee, - AllocationFee = allocationFee - }; - #endregion - - #region entities - Db.TryAttach(delegat); - Db.TryAttach(target); - #endregion - - #region apply operation - PayFee(delegat, operation.Fee); - - Spend(delegat, delegat, operation.Amount + operation.AllocationFee); - - Receive(target, operation.Amount); - - delegat.DrainDelegateCount++; - if (target != delegat) target.DrainDelegateCount++; - - block.Operations |= Operations.DrainDelegate; - - Cache.AppState.Get().DrainDelegateOpsCount++; - - Cache.Statistics.Current.TotalBurned += operation.AllocationFee; - #endregion - - Db.DrainDelegateOps.Add(operation); - Context.DrainDelegateOps.Add(operation); - } - - public virtual async Task Revert(Block block, DrainDelegateOperation operation) - { - #region entities - var delegat = Cache.Accounts.GetDelegate(operation.DelegateId); - Db.TryAttach(delegat); - - var target = await Cache.Accounts.GetAsync(operation.TargetId); - Db.TryAttach(target); - #endregion - - #region apply operation - RevertPayFee(delegat, operation.Fee); - - RevertSpend(delegat, delegat, operation.Amount + operation.AllocationFee); - - RevertReceive(target, operation.Amount); - - delegat.DrainDelegateCount--; - if (target != delegat) target.DrainDelegateCount--; - - Cache.AppState.Get().DrainDelegateOpsCount--; - #endregion - - Db.DrainDelegateOps.Remove(operation); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index cad4b0a55..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class IncreasePaidStorageCommit : Proto14.IncreasePaidStorageCommit - { - public IncreasePaidStorageCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index ebd93f3f9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class NonceRevelationsCommit : Proto12.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 352b0b918..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class OriginationsCommit : Proto14.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index 4da65ab7c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class PreattestationsCommit : Proto12.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index f1343f977..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class ProposalsCommit : Proto14.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index 518e03c0d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class RegisterConstantsCommit : Proto14.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 721d5aa75..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class RevealsCommit : Proto14.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index bc8ed1b06..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 7dc22dfe3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TransactionsCommit : Proto14.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index a69da0e94..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupCommitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupCommitCommit.cs deleted file mode 100644 index e978b759a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupCommitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TxRollupCommitCommit : Proto13.TxRollupCommitCommit - { - public TxRollupCommitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupDispatchTicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupDispatchTicketsCommit.cs deleted file mode 100644 index 75c6f4ed4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupDispatchTicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TxRollupDispatchTicketsCommit : Proto13.TxRollupDispatchTicketsCommit - { - public TxRollupDispatchTicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs deleted file mode 100644 index 49046ceb3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TxRollupFinalizeCommitmentCommit : Proto13.TxRollupFinalizeCommitmentCommit - { - public TxRollupFinalizeCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupOriginationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupOriginationCommit.cs deleted file mode 100644 index 69bd226d3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupOriginationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TxRollupOriginationCommit : Proto13.TxRollupOriginationCommit - { - public TxRollupOriginationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupRejectionCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupRejectionCommit.cs deleted file mode 100644 index 9b3fc5840..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupRejectionCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TxRollupRejectionCommit : Proto13.TxRollupRejectionCommit - { - public TxRollupRejectionCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupRemoveCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupRemoveCommitmentCommit.cs deleted file mode 100644 index ca07f3689..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupRemoveCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TxRollupRemoveCommitmentCommit : Proto13.TxRollupRemoveCommitmentCommit - { - public TxRollupRemoveCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupReturnBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupReturnBondCommit.cs deleted file mode 100644 index d595f2a1e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupReturnBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TxRollupReturnBondCommit : Proto13.TxRollupReturnBondCommit - { - public TxRollupReturnBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupSubmitBatchCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupSubmitBatchCommit.cs deleted file mode 100644 index 8ede211f9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/TxRollupSubmitBatchCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TxRollupSubmitBatchCommit : Proto13.TxRollupSubmitBatchCommit - { - public TxRollupSubmitBatchCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index f1f88ce82..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Keys; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto15 -{ - class UpdateSecondaryKeyCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - - var pubKey = content.RequiredString("pk"); - var pubKeyHash = PubKey.FromBase58(pubKey).Address; - var result = content.Required("metadata").Required("operation_result"); - var operation = new UpdateSecondaryKeyOperation - { - Id = Cache.AppState.NextOperationId(), - OpHash = op.RequiredString("hash"), - Level = block.Level, - Timestamp = block.Timestamp, - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - KeyType = content.RequiredString("kind") switch - { - "update_consensus_key" => SecondaryKeyType.Consensus, - "update_companion_key" => SecondaryKeyType.Companion, - _ => throw new NotImplementedException() - }, - ActivationCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay + 1, - PublicKey = pubKey, - PublicKeyHash = pubKeyHash, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000) - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter; - sender.UpdateSecondaryKeyCount++; - - block.Operations |= Operations.UpdateSecondaryKey; - - Cache.AppState.Get().UpdateSecondaryKeyOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - Cache.AppState.Get().PendingSecondaryKeys++; - } - #endregion - - Proto.Manager.Set(sender); - Db.UpdateSecondaryKeyOps.Add(operation); - Context.UpdateSecondaryKeyOps.Add(operation); - } - - public virtual async Task Revert(Block block, UpdateSecondaryKeyOperation operation) - { - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - Db.TryAttach(sender); - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - Cache.AppState.Get().PendingSecondaryKeys--; - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter - 1; - sender.UpdateSecondaryKeyCount--; - - Cache.AppState.Get().UpdateSecondaryKeyOpsCount--; - #endregion - - Db.UpdateSecondaryKeyOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - public async Task ActivateSecondaryKeys(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin) || Cache.AppState.Get().PendingSecondaryKeys == 0) - return; - - var ops = await Db.UpdateSecondaryKeyOps - .AsNoTracking() - .Where(x => x.ActivationCycle == block.Cycle && x.Status == OperationStatus.Applied) - .ToListAsync(); - - foreach (var op in ops.OrderBy(x => x.Id)) - { - var baker = Cache.Accounts.GetDelegate(op.SenderId); - Db.TryAttach(baker); - if (op.KeyType == SecondaryKeyType.Consensus) - baker.ConsensusAddress = op.PublicKeyHash; - else - baker.CompanionAddress = op.PublicKeyHash; - Cache.AppState.Get().PendingSecondaryKeys--; - } - } - - public async Task DeactivateSecondaryKeys(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - var ops = await Db.UpdateSecondaryKeyOps - .AsNoTracking() - .Where(x => x.ActivationCycle == block.Cycle && x.Status == OperationStatus.Applied) - .ToListAsync(); - - foreach (var op in ops.OrderByDescending(x => x.Id)) - { - var baker = Cache.Accounts.GetDelegate(op.SenderId); - Db.TryAttach(baker); - - var prevOp = await Db.UpdateSecondaryKeyOps - .AsNoTracking() - .Where(x => - x.SenderId == baker.Id && - x.KeyType == op.KeyType && - x.ActivationCycle < op.ActivationCycle && - x.Status == OperationStatus.Applied) - .OrderByDescending(x => x.Id) - .FirstOrDefaultAsync(); - - if (op.KeyType == SecondaryKeyType.Consensus) - baker.ConsensusAddress = prevOp?.PublicKeyHash; - else - baker.CompanionAddress = prevOp?.PublicKeyHash; - - Cache.AppState.Get().PendingSecondaryKeys++; - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 8bd85d198..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class VdfRevelationCommit : Proto14.VdfRevelationCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index ec05a3cea..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class SnapshotBalanceCommit : Proto12.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SoftwareCommit.cs deleted file mode 100644 index 0e6dcbcdc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/StateCommit.cs deleted file mode 100644 index 76648a95e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/StatisticsCommit.cs deleted file mode 100644 index 0b92b0e28..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SubsidyCommit.cs deleted file mode 100644 index 2940a7fb9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/TokensCommit.cs deleted file mode 100644 index b24dcbe36..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/VotingCommit.cs deleted file mode 100644 index 48430a00e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Diagnostics/Diagnostics.cs deleted file mode 100644 index d27b820d1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class Diagnostics : Proto14.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Helpers.cs deleted file mode 100644 index 9fa907d98..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - public class Helpers(ProtocolHandler proto) : Proto13.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Proto15Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Proto15Handler.cs deleted file mode 100644 index 9892b01dc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Proto15Handler.cs +++ /dev/null @@ -1,420 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto15; - -namespace Tzkt.Sync.Protocols -{ - class Proto15Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "lima_015"; - public override int VersionNumber => 15; - - public Proto15Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preendorsement": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - case "double_preendorsement_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "tx_rollup_origination": - await new TxRollupOriginationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_submit_batch": - await new TxRollupSubmitBatchCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_commit": - await new TxRollupCommitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_finalize_commitment": - await new TxRollupFinalizeCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_remove_commitment": - await new TxRollupRemoveCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_return_bond": - await new TxRollupReturnBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_rejection": - await new TxRollupRejectionCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_dispatch_tickets": - await new TxRollupDispatchTicketsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - new FreezerCommit(this).Revert(); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TxRollupOriginationOperation op: - await new TxRollupOriginationCommit(this).Revert(currBlock, op); - break; - case TxRollupSubmitBatchOperation op: - await new TxRollupSubmitBatchCommit(this).Revert(currBlock, op); - break; - case TxRollupCommitOperation op: - await new TxRollupCommitCommit(this).Revert(currBlock, op); - break; - case TxRollupFinalizeCommitmentOperation op: - await new TxRollupFinalizeCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupRemoveCommitmentOperation op: - await new TxRollupRemoveCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupReturnBondOperation op: - await new TxRollupReturnBondCommit(this).Revert(currBlock, op); - break; - case TxRollupRejectionOperation op: - await new TxRollupRejectionCommit(this).Revert(currBlock, op); - break; - case TxRollupDispatchTicketsOperation op: - await new TxRollupDispatchTicketsCommit(this).Revert(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Rpc/Rpc.cs deleted file mode 100644 index cc01eedc5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto15 -{ - class Rpc : Proto12.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto15/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto15/Validation/Validator.cs deleted file mode 100644 index b48522913..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto15/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto15 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Activation/ProtoActivator.cs deleted file mode 100644 index 146524a95..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Activation/ProtoActivator.cs +++ /dev/null @@ -1,259 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto15.ProtoActivator(proto) - { - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.SmartRollupOriginationSize = parameters["smart_rollup_origination_size"]?.Value() ?? 6_314; - protocol.SmartRollupStakeAmount = long.Parse(parameters["smart_rollup_stake_amount"]?.Value() ?? "10000000000"); - protocol.SmartRollupChallengeWindow = parameters["smart_rollup_challenge_window_in_blocks"]?.Value() ?? 80_640; - protocol.SmartRollupCommitmentPeriod = parameters["smart_rollup_commitment_period_in_blocks"]?.Value() ?? 60; - protocol.SmartRollupTimeoutPeriod = parameters["smart_rollup_timeout_period_in_blocks"]?.Value() ?? 40_320; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.BlocksPerCycle = prev.BlocksPerCycle * 2; - protocol.BlocksPerCommitment = prev.BlocksPerCommitment * 2; - protocol.BlocksPerSnapshot = prev.BlocksPerSnapshot * 2; - protocol.BlocksPerVoting = prev.BlocksPerVoting * 2; - protocol.HardBlockGasLimit = prev.HardBlockGasLimit / 2; - protocol.TimeBetweenBlocks = (prev.TimeBetweenBlocks + 1) / 2; - - var totalReward = 80_000_000 * protocol.TimeBetweenBlocks / 60; - protocol.BlockReward0 = totalReward / 4; - protocol.BlockReward1 = totalReward / 4 / (protocol.AttestersPerBlock / 3); - protocol.AttestationReward0 = totalReward / 2 / protocol.AttestersPerBlock; - protocol.AttestationReward1 = 0; - - protocol.SmartRollupOriginationSize = 6_314; - protocol.SmartRollupStakeAmount = 10_000_000_000; - protocol.SmartRollupChallengeWindow = 80_640; - protocol.SmartRollupCommitmentPeriod = 60; - protocol.SmartRollupTimeoutPeriod = 40_320; - - protocol.MaxBakingReward = protocol.BlockReward0 + protocol.AttestersPerBlock / 3 * protocol.BlockReward1; - protocol.MaxAttestationReward = protocol.AttestersPerBlock * protocol.AttestationReward0; - } - - protected override async Task ActivateContext(AppState state) - { - await base.ActivateContext(state); - new InboxCommit(Proto).Init(Cache.Blocks.Current()); - } - - protected override async Task DeactivateContext(AppState state) - { - await base.DeactivateContext(state); - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "InboxMessages" - """); - Cache.AppState.Get().InboxMessageCounter = 0; - } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - MigrateBakers(state, prevProto, nextProto); - await MigrateVotingPeriods(state, nextProto); - var cycles = await MigrateCycles(state, nextProto); - await MigrateFutureRights(state, nextProto, cycles); - - Cache.BakingRights.Reset(); - Cache.BakerCycles.Reset(); - Cache.Periods.Reset(); - - new InboxCommit(Proto).Init(Cache.Blocks.Current()); - } - - protected override Task RevertContext(AppState state) - { - throw new NotImplementedException("Reverting the migration block is not implemented, because likely won't be needed"); - } - - void MigrateBakers(AppState state, Protocol prevProto, Protocol nextProto) - { - foreach (var baker in Cache.Accounts.GetDelegates().Where(x => x.DeactivationLevel > state.Level)) - { - Db.TryAttach(baker); - baker.DeactivationLevel = nextProto.GetCycleStart(prevProto.GetCycle(baker.DeactivationLevel)); - } - } - - async Task MigrateVotingPeriods(AppState state, Protocol nextProto) - { - var newPeriod = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(newPeriod); - newPeriod.LastLevel = newPeriod.FirstLevel + nextProto.BlocksPerVoting - 1; - } - - async Task> MigrateCycles(AppState state, Protocol nextProto) - { - var cycles = await Db.Cycles - .Where(x => x.Index >= state.Cycle) - .OrderBy(x => x.Index) - .ToListAsync(); - - foreach (var cycle in cycles.Where(x => x.Index > state.Cycle)) - { - cycle.FirstLevel = nextProto.GetCycleStart(cycle.Index); - cycle.LastLevel = nextProto.GetCycleEnd(cycle.Index); - } - - return cycles; - } - - async Task MigrateFutureRights(AppState state, Protocol nextProto, List cycles) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" > {0} - """, state.Cycle); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - IEnumerable shifted = []; - - foreach (var cycle in cycles) - { - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - var sampler = GetOldSampler(bakerCycles.Values - .Where(x => x.BakingPower > 0) - .Select(x => (x.BakerId, x.BakingPower)) - .ToList()); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, cycle.Index); - #endregion - - if (cycle.Index == state.Cycle) - { - shifted = RightsGenerator.GetAttestationRights(sampler, nextProto, cycle, cycle.LastLevel); - - #region save shifted - using var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """); - - foreach (var ar in shifted) - { - writer.StartRow(); - writer.Write(cycle.Index + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - writer.Complete(); - #endregion - } - else - { - GC.Collect(); - var brs = await RightsGenerator.GetBakingRightsAsync(sampler, nextProto, cycle); - var ars = await RightsGenerator.GetAttestationRightsAsync(sampler, nextProto, cycle); - - #region save rights - using (var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """)) - { - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(nextProto.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - - #region reset baker cycles - foreach (var bakerCycle in bakerCycles.Values) - { - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks = 0; - bakerCycle.FutureBlockRewards = 0; - bakerCycle.FutureAttestations = 0; - - var expectedAttestations = (nextProto.BlocksPerCycle * nextProto.AttestersPerBlock).MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedBlocks = nextProto.BlocksPerCycle.MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = expectedAttestations * nextProto.AttestationReward0; - } - - foreach (var br in brs.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += nextProto.MaxBakingReward; - } - - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots; - } - } - - foreach (var ar in ars.TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - shifted = ars.Where(x => x.Level == cycle.LastLevel).ToList(); - } - } - } - - Sampler GetOldSampler(IEnumerable<(int id, long stake)> selection) - { - var sorted = selection.OrderByDescending(x => - { - var baker = Cache.Accounts.GetDelegate(x.id); - return new byte[] { (byte)baker.PublicKey![0] }.Concat(Base58.Parse(baker.Address)); - }, new BytesComparer()); - - return new Sampler(sorted.Select(x => x.id).ToArray(), sorted.Select(x => x.stake).ToArray()); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/AttestationRewardCommit.cs deleted file mode 100644 index 166b29068..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class AttestationRewardCommit : Proto12.AttestationRewardCommit - { - public AttestationRewardCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BakerCycleCommit.cs deleted file mode 100644 index 823e3731f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class BakerCycleCommit : Proto12.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BakingRightsCommit.cs deleted file mode 100644 index f101357b2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Netezos.Encoding; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class BakingRightsCommit : Proto15.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override Sampler GetSampler(IEnumerable<(int id, long stake)> selection, bool forceBase) - { - var sorted = selection.OrderByDescending(x => - { - var baker = Cache.Accounts.GetDelegate(x.id); - return new byte[] { (byte)baker.PublicKey![0] }.Concat(Base58.Parse(baker.Address)); - }, new BytesComparer()); - - return new Sampler(sorted.Select(x => x.id).ToArray(), sorted.Select(x => x.stake).ToArray()); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BigMapCommit.cs deleted file mode 100644 index 125d615a7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BlockCommit.cs deleted file mode 100644 index 2bac4a38d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class BlockCommit : Proto13.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/ContractEventCommit.cs deleted file mode 100644 index 0a83e24c2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class ContractEventCommit : Proto14.ContractEventCommit - { - public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/CycleCommit.cs deleted file mode 100644 index 7c836b8e8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class CycleCommit : Proto14.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/DeactivationCommit.cs deleted file mode 100644 index 2145dc1cb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 3394bd907..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/FreezerCommit.cs deleted file mode 100644 index d69bfcc6b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class FreezerCommit : Proto12.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/InboxCommit.cs deleted file mode 100644 index a4e1e41b1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/InboxCommit.cs +++ /dev/null @@ -1,138 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Npgsql; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - public class InboxCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public void Init(Block block) - { - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(""" - COPY "InboxMessages" ("Id", "Level", "Index", "Type", "PredecessorLevel", "OperationId", "Payload", "Protocol") - FROM STDIN (FORMAT BINARY) - """); - - var index = 0; - - writer.StartRow(); - writer.Write(Cache.AppState.NextInboxMessageId(), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(index++, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)InboxMessageType.LevelStart, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - - writer.StartRow(); - writer.Write(Cache.AppState.NextInboxMessageId(), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(index++, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)InboxMessageType.LevelInfo, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level - 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - - WriteMigrationMessage(writer, block, ref index); - - writer.StartRow(); - writer.Write(Cache.AppState.NextInboxMessageId(), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)InboxMessageType.LevelEnd, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - - writer.Complete(); - } - - public void Apply(Block block) - { - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(""" - COPY "InboxMessages" ("Id", "Level", "Index", "Type", "PredecessorLevel", "OperationId", "Payload", "Protocol") - FROM STDIN (FORMAT BINARY) - """); - - var index = 0; - - writer.StartRow(); - writer.Write(Cache.AppState.NextInboxMessageId(), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(index++, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)InboxMessageType.LevelStart, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - - writer.StartRow(); - writer.Write(Cache.AppState.NextInboxMessageId(), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(index++, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)InboxMessageType.LevelInfo, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level - 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - - if (block.Events.HasFlag(BlockEvents.ProtocolBegin)) - WriteMigrationMessage(writer, block, ref index); - - foreach (var (operationId, payload) in Proto.Inbox.Messages) - { - writer.StartRow(); - writer.Write(Cache.AppState.NextInboxMessageId(), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(index++, NpgsqlTypes.NpgsqlDbType.Integer); - if (payload == null) - { - writer.Write((int)InboxMessageType.Transfer, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(operationId, NpgsqlTypes.NpgsqlDbType.Bigint); - writer.WriteNull(); - } - else - { - writer.Write((int)InboxMessageType.External, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(operationId, NpgsqlTypes.NpgsqlDbType.Bigint); - writer.Write(payload, NpgsqlTypes.NpgsqlDbType.Bytea); - } - writer.WriteNull(); - } - - writer.StartRow(); - writer.Write(Cache.AppState.NextInboxMessageId(), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)InboxMessageType.LevelEnd, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - - writer.Complete(); - } - - public async Task Revert(Block block) - { - var cnt = await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "InboxMessages" - WHERE "Level" = {0} - """, block.Level); - - Cache.AppState.ReleaseInboxMessageId(cnt); - } - - protected virtual void WriteMigrationMessage(NpgsqlBinaryImporter writer, Block block, ref int index) - { - // migration messages were added in Proto17 - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index df1aeef93..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 09bb30d80..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class AttestationsCommit : Proto12.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 300deecc3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index dd16d205b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class DelegationsCommit : Proto14.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 8dbb84ea6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class DoubleBakingCommit : Proto12.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index d15c5453a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class DoubleConsensusCommit : Proto12.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index 03800b58d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class DrainDelegateCommit : Proto15.DrainDelegateCommit - { - public DrainDelegateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index d3146ce49..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class IncreasePaidStorageCommit : Proto14.IncreasePaidStorageCommit - { - public IncreasePaidStorageCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index b3ae0b208..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class NonceRevelationsCommit : Proto12.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index bb132f724..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class OriginationsCommit : Proto14.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index 2a9aa25e5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class PreattestationsCommit : Proto12.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 0b6613fc9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class ProposalsCommit : Proto14.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index 52a2bfdec..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class RegisterConstantsCommit : Proto14.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 4f289b879..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class RevealsCommit : Proto14.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index df845b27e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index ed1e0d612..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SmartRollupAddMessagesCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new SmartRollupAddMessagesOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - MessagesCount = 0, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = 0, - StorageFee = null, - AllocationFee = null - }; - #endregion - - #region entities - Db.TryAttach(sender); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.SmartRollupAddMessagesCount++; - - block.Operations |= Operations.SmartRollupAddMessages; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().SmartRollupAddMessagesOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - foreach (var message in content.RequiredArray("message").EnumerateArray()) - { - Proto.Inbox.Push(operation.Id, Hex.Parse(message.RequiredString())); - operation.MessagesCount++; - } - } - #endregion - - Proto.Manager.Set(sender); - Db.SmartRollupAddMessagesOps.Add(operation); - Context.SmartRollupAddMessagesOps.Add(operation); - } - - public virtual async Task Revert(Block block, SmartRollupAddMessagesOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - - Db.TryAttach(sender); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.SmartRollupAddMessagesCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().SmartRollupAddMessagesOpsCount--; - #endregion - - Db.SmartRollupAddMessagesOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index bc0578cf9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SmartRollupCementCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetSmartRollupOrDefaultAsync(content.RequiredString("rollup")); - var commitment = await Cache.SmartRollupCommitments.GetOrDefaultAsync(GetCommitment(content), rollup?.Id); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new SmartRollupCementOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - SmartRollupId = rollup?.Id, - CommitmentId = commitment?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = 0, - StorageFee = null, - AllocationFee = null - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(commitment); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.SmartRollupCementCount++; - if (rollup != null) rollup.SmartRollupCementCount++; - - block.Operations |= Operations.SmartRollupCement; - - sender.Counter = operation.Counter; - - if (commitment != null) - commitment.LastLevel = operation.Level; - - Cache.AppState.Get().SmartRollupCementOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - rollup!.InboxLevel = commitment!.InboxLevel; - rollup.LastCommitment = commitment.Hash; - rollup.CementedCommitments++; - rollup.PendingCommitments--; - - commitment.Status = SmartRollupCommitmentStatus.Cemented; - } - #endregion - - Proto.Manager.Set(sender); - Db.SmartRollupCementOps.Add(operation); - Context.SmartRollupCementOps.Add(operation); - } - - public virtual async Task Revert(Block block, SmartRollupCementOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.SmartRollupId) as SmartRollup; - var commitment = await Cache.SmartRollupCommitments.GetOrDefaultAsync(operation.CommitmentId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(commitment); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - var prevCement = await Db.SmartRollupCementOps.AsNoTracking() - .Where(x => x.Id < operation.Id && x.SmartRollupId == operation.SmartRollupId && x.Status == OperationStatus.Applied) - .OrderByDescending(x => x.Id) - .FirstOrDefaultAsync(); - var prevCementedCommitment = await Cache.SmartRollupCommitments.GetOrDefaultAsync(prevCement?.CommitmentId); - - rollup!.InboxLevel = prevCementedCommitment?.InboxLevel ?? 0; - rollup.LastCommitment = prevCementedCommitment?.Hash ?? rollup.GenesisCommitment; - rollup.CementedCommitments--; - rollup.PendingCommitments++; - - commitment!.Status = SmartRollupCommitmentStatus.Pending; - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.SmartRollupCementCount--; - if (rollup != null) rollup.SmartRollupCementCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - // commitment.LastLevel is not reverted - - Cache.AppState.Get().SmartRollupCementOpsCount--; - #endregion - - Db.SmartRollupCementOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual string? GetCommitment(JsonElement content) => content.RequiredString("commitment"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index 79ad3d0a1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SmartRollupExecuteCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public SmartRollupExecuteOperation Operation { get; private set; } = null!; - public IEnumerable? TicketUpdates { get; private set; } - - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetSmartRollupOrDefaultAsync(content.RequiredString("rollup")); - var commitment = await Cache.SmartRollupCommitments.GetOrDefaultAsync(content.RequiredString("cemented_commitment"), rollup?.Id); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new SmartRollupExecuteOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - SmartRollupId = rollup?.Id, - CommitmentId = commitment?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, - StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 - ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost - : null, - AllocationFee = null - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(commitment); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.SmartRollupExecuteCount++; - if (rollup != null) rollup.SmartRollupExecuteCount++; - - block.Operations |= Operations.SmartRollupExecute; - - sender.Counter = operation.Counter; - - if (commitment != null) - commitment.LastLevel = operation.Level; - - Cache.AppState.Get().SmartRollupExecuteOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - var burned = operation.StorageFee ?? 0; - Proto.Manager.Burn(burned); - - Spend(sender, burned); - - TicketUpdates = ParseTicketUpdates(result); - - if (commitment!.Status != SmartRollupCommitmentStatus.Executed) - { - rollup!.ExecutedCommitments++; - commitment.Status = SmartRollupCommitmentStatus.Executed; - } - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.SmartRollupExecuteOps.Add(operation); - Context.SmartRollupExecuteOps.Add(operation); - Operation = operation; - } - - public virtual async Task Revert(Block block, SmartRollupExecuteOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.SmartRollupId) as SmartRollup; - var commitment = await Cache.SmartRollupCommitments.GetOrDefaultAsync(operation.CommitmentId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(commitment); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - RevertSpend(sender, operation.StorageFee ?? 0); - - var isFirstExecution = !await Db.SmartRollupExecuteOps - .AnyAsync(x => x.Status == OperationStatus.Applied && x.CommitmentId == operation.CommitmentId && x.Id < operation.Id); - - if (isFirstExecution) - { - rollup!.ExecutedCommitments--; - commitment!.Status = SmartRollupCommitmentStatus.Cemented; - } - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.SmartRollupExecuteCount--; - if (rollup != null) rollup.SmartRollupExecuteCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - // commitment.LastLevel is not reverted - - Cache.AppState.Get().SmartRollupExecuteOpsCount--; - #endregion - - Db.SmartRollupExecuteOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual IEnumerable? ParseTicketUpdates(JsonElement result) - { - if (!result.TryGetProperty("ticket_updates", out var ticketUpdates)) - return null; - - var res = new List(); - foreach (var updates in ticketUpdates.RequiredArray().EnumerateArray()) - { - var list = new List(); - foreach (var update in updates.RequiredArray("updates").EnumerateArray()) - { - var amount = update.RequiredBigInteger("amount"); - if (amount != BigInteger.Zero) - { - list.Add(new TicketUpdate - { - Account = update.RequiredString("account"), - Amount = amount - }); - } - } - - if (list.Count > 0) - { - var ticketToken = updates.Required("ticket_token"); - var type = ticketToken.RequiredMicheline("content_type"); - var value = ticketToken.RequiredMicheline("content"); - var rawType = type.ToBytes(); - - byte[] rawContent; - string? jsonContent; - - try - { - var schema = Schema.Create((type as MichelinePrim)!); - rawContent = schema.Optimize(value).ToBytes(); - jsonContent = schema.Humanize(value); - } - catch (Exception ex) - { - Logger.LogError(ex, "Failed to parse ticket content"); - rawContent = value.ToBytes(); - jsonContent = null; - } - - res.Add(new TicketUpdates - { - Ticket = new TicketIdentity - { - Ticketer = ticketToken.RequiredString("ticketer"), - RawType = rawType, - RawContent = rawContent, - JsonContent = jsonContent, - TypeHash = Script.GetHash(rawType), - ContentHash = Script.GetHash(rawContent) - }, - Updates = list - }); - } - } - - return res.Count > 0 ? res : null; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index c5847e592..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,236 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SmartRollupOriginateCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - Db.TryAttach(sender); - - var pvmKind = content.RequiredString("pvm_kind") switch - { - "arith" => PvmKind.Arith, - "wasm_2_0_0" => PvmKind.Wasm, - _ => throw new NotImplementedException() - }; - var result = content.Required("metadata").Required("operation_result"); - - SmartRollup? rollup = null; - if (result.RequiredString("status") == "applied") - { - var address = result.RequiredString("address"); - var ghost = await Cache.Accounts.GetAsync(address); - if (ghost != null) - { - rollup = new() - { - Id = ghost.Id, - Index = ghost.Index, - FirstLevel = ghost.FirstLevel, - LastLevel = ghost.LastLevel, - Address = address, - Counter = 0, - CreatorId = sender.Id, - Type = AccountType.SmartRollup, - PvmKind = pvmKind, - ParameterSchema = content.RequiredMicheline("parameters_ty").ToBytes(), - GenesisCommitment = result.RequiredString("genesis_commitment_hash"), - LastCommitment = result.RequiredString("genesis_commitment_hash"), - InboxLevel = 0, - TotalStakers = 0, - ActiveStakers = 0, - ExecutedCommitments = 0, - CementedCommitments = 0, - PendingCommitments = 0, - RefutedCommitments = 0, - OrphanCommitments = 0, - SmartRollupBonds = 0, - ActiveTokensCount = ghost.ActiveTokensCount, - TokenBalancesCount = ghost.TokenBalancesCount, - TokenTransfersCount = ghost.TokenTransfersCount, - ActiveTicketsCount = ghost.ActiveTicketsCount, - TicketBalancesCount = ghost.TicketBalancesCount, - TicketTransfersCount = ghost.TicketTransfersCount - }; - Db.Entry(ghost).State = EntityState.Detached; - Db.Entry(rollup).State = EntityState.Modified; - } - else - { - rollup = new() - { - Id = Cache.AppState.NextAccountId(), - FirstLevel = block.Level, - LastLevel = block.Level, - Address = address, - Counter = 0, - CreatorId = sender.Id, - Type = AccountType.SmartRollup, - PvmKind = pvmKind, - ParameterSchema = content.RequiredMicheline("parameters_ty").ToBytes(), - GenesisCommitment = result.RequiredString("genesis_commitment_hash"), - LastCommitment = result.RequiredString("genesis_commitment_hash"), - InboxLevel = 0, - TotalStakers = 0, - ActiveStakers = 0, - ExecutedCommitments = 0, - CementedCommitments = 0, - PendingCommitments = 0, - RefutedCommitments = 0, - OrphanCommitments = 0, - SmartRollupBonds = 0 - }; - Db.SmartRollups.Add(rollup); - } - Cache.Accounts.Add(rollup); - } - - var operation = new SmartRollupOriginateOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - PvmKind = pvmKind, - Kernel = Hex.Parse(content.RequiredString("kernel")), - GenesisCommitment = result.OptionalString("genesis_commitment_hash"), - SmartRollupId = rollup?.Id, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = result.OptionalInt32("size") ?? 0, - StorageFee = result.OptionalInt32("size") > 0 - ? result.OptionalInt32("size") * Context.Protocol.ByteCost - : null, - AllocationFee = null - }; - - try - { - operation.ParameterType = content.RequiredMicheline("parameters_ty").ToBytes(); - } - catch (Exception ex) - { - Logger.LogWarning(ex, "Failed to parse smart rollup parameter type"); - } - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.SmartRollupOriginateCount++; - if (rollup != null) rollup.SmartRollupOriginateCount++; - - block.Operations |= Operations.SmartRollupOriginate; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().SmartRollupOriginateOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - var burned = operation.StorageFee ?? 0; - Proto.Manager.Burn(burned); - - Spend(sender, burned); - - sender.SmartRollupsCount++; - - Cache.Statistics.Current.TotalBurned += burned; - } - #endregion - - Proto.Manager.Set(sender); - Db.SmartRollupOriginateOps.Add(operation); - Context.SmartRollupOriginateOps.Add(operation); - } - - public virtual async Task Revert(Block block, SmartRollupOriginateOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.SmartRollupId) as SmartRollup; - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - RevertSpend(sender, operation.StorageFee ?? 0); - - sender.SmartRollupsCount--; - - if (rollup!.TokenTransfersCount == 0 && rollup.TicketTransfersCount == 0 && rollup.Index is null) - { - Db.SmartRollups.Remove(rollup); - Cache.Accounts.Remove(rollup); - } - else - { - var ghost = new Account - { - Id = rollup.Id, - Index = rollup.Index, - Address = rollup.Address, - FirstLevel = rollup.FirstLevel, - LastLevel = rollup.LastLevel, - ActiveTokensCount = rollup.ActiveTokensCount, - TokenBalancesCount = rollup.TokenBalancesCount, - TokenTransfersCount = rollup.TokenTransfersCount, - ActiveTicketsCount = rollup.ActiveTicketsCount, - TicketBalancesCount = rollup.TicketBalancesCount, - TicketTransfersCount = rollup.TicketTransfersCount, - Type = AccountType.Ghost, - }; - - Db.Entry(rollup).State = EntityState.Detached; - Db.Entry(ghost).State = EntityState.Modified; - Cache.Accounts.Add(ghost); - } - - Cache.Schemas.Remove(rollup); - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.SmartRollupOriginateCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().SmartRollupOriginateOpsCount--; - #endregion - - Db.SmartRollupOriginateOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index 58a89bac1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,315 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; -using Tzkt.Sync.Services.Cache; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SmartRollupPublishCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var result = content.Required("metadata").Required("operation_result"); - var commitmentHash = result.OptionalString("staked_hash"); - var bond = result.OptionalArray("balance_updates")?.EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind") == "contract") ?? default; - - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetSmartRollupOrDefaultAsync(content.RequiredString("rollup")); - var commitment = await Cache.SmartRollupCommitments.GetOrDefaultAsync(commitmentHash, rollup?.Id); - - var operation = new SmartRollupPublishOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - SmartRollupId = rollup?.Id, - CommitmentId = commitment?.Id, - Bond = bond.ValueKind == JsonValueKind.Undefined ? 0 : -bond.RequiredInt64("change"), - Flags = SmartRollupPublishFlags.None, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = 0, - StorageFee = null, - AllocationFee = null - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(commitment); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.SmartRollupPublishCount++; - if (rollup != null) rollup.SmartRollupPublishCount++; - - block.Operations |= Operations.SmartRollupPublish; - - sender.Counter = operation.Counter; - - if (commitment != null) - commitment.LastLevel = operation.Level; - - Cache.AppState.Get().SmartRollupPublishOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - if (operation.Bond != 0) - { - sender.SmartRollupBonds += operation.Bond; - rollup!.SmartRollupBonds += operation.Bond; - - var uniqueStakers = (await Db.SmartRollupPublishOps.AsNoTracking() - .Where(x => x.SmartRollupId == rollup.Id && x.BondStatus != null) - .Select(x => x.SenderId) - .Distinct() - .ToListAsync()) - .ToHashSet(); - - foreach (var publish in Context.SmartRollupPublishOps.Where(x => x.SmartRollupId == rollup.Id)) - uniqueStakers.Add(publish.SenderId); - - uniqueStakers.Add(operation.SenderId); - - rollup.TotalStakers = uniqueStakers.Count; - rollup.ActiveStakers++; - - operation.BondStatus = SmartRollupBondStatus.Active; - - Cache.Statistics.Current.TotalSmartRollupBonds += operation.Bond; - } - - if (commitment == null) - { - var commitmentEl = content.Required("commitment"); - commitment = new SmartRollupCommitment - { - Id = Cache.AppState.NextSmartRollupCommitmentId(), - SmartRollupId = rollup!.Id, - InitiatorId = operation.SenderId, - FirstLevel = operation.Level, - LastLevel = operation.Level, - InboxLevel = commitmentEl.RequiredInt32("inbox_level"), - State = commitmentEl.RequiredString("compressed_state"), - Ticks = commitmentEl.RequiredInt64("number_of_ticks"), - Hash = commitmentHash!, - Stakers = 1, - ActiveStakers = 1, - Successors = 0, - Status = SmartRollupCommitmentStatus.Pending - }; - Cache.SmartRollupCommitments.Add(commitment); - Db.SmartRollupCommitments.Add(commitment); - - var predecessorHash = commitmentEl.RequiredString("predecessor"); - if (predecessorHash != rollup.GenesisCommitment) - { - var predecessor = await Cache.SmartRollupCommitments.GetAsync(predecessorHash, rollup.Id); - Db.TryAttach(predecessor); - predecessor.Successors++; - predecessor.LastLevel = operation.Level; - - commitment.PredecessorId = predecessor.Id; - } - - rollup.PendingCommitments++; - - operation.CommitmentId = commitment.Id; - operation.Flags = SmartRollupPublishFlags.AddStaker; - Cache.SmartRollupStakes.Add(commitment); - } - else - { - var stake = await Cache.SmartRollupStakes.GetAsync(commitment, sender.Id); - if (stake == null) - { - commitment.Stakers++; - commitment.ActiveStakers++; - operation.Flags = SmartRollupPublishFlags.AddStaker; - Cache.SmartRollupStakes.Set(commitment.Id, sender.Id, 1); - } - else if (stake == 0) - { - commitment.ActiveStakers++; - operation.Flags = SmartRollupPublishFlags.ReactivateStaker; - Cache.SmartRollupStakes.Set(commitment.Id, sender.Id, 1); - } - if (commitment.Status == SmartRollupCommitmentStatus.Refuted) - { - rollup!.PendingCommitments++; - rollup.RefutedCommitments--; - - commitment.Status = SmartRollupCommitmentStatus.Pending; - if (commitment.Successors > 0) - { - var cnt = await UpdateSuccessorsStatus(Db, Cache.SmartRollupCommitments, commitment, SmartRollupCommitmentStatus.Pending); - rollup.PendingCommitments += cnt; - rollup.OrphanCommitments -= cnt; - } - operation.Flags |= SmartRollupPublishFlags.ReactivateBranch; - } - } - } - #endregion - - Proto.Manager.Set(sender); - Db.SmartRollupPublishOps.Add(operation); - Context.SmartRollupPublishOps.Add(operation); - } - - public virtual async Task Revert(Block block, SmartRollupPublishOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.SmartRollupId) as SmartRollup; - var commitment = await Cache.SmartRollupCommitments.GetOrDefaultAsync(operation.CommitmentId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(commitment); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - if (operation.Bond != 0) - { - sender.SmartRollupBonds -= operation.Bond; - rollup!.SmartRollupBonds -= operation.Bond; - - var uniqueStakers = await Db.SmartRollupPublishOps.AsNoTracking() - .Where(x => x.SmartRollupId == rollup.Id && x.BondStatus != null && x.Id < operation.Id) - .Select(x => x.SenderId) - .Distinct() - .CountAsync(); - - rollup.TotalStakers = uniqueStakers; - rollup.ActiveStakers--; - } - - if (commitment!.Stakers == 1 && operation.Flags.HasFlag(SmartRollupPublishFlags.AddStaker)) - { - rollup!.PendingCommitments--; - - if (commitment.PredecessorId != null) - { - var predecessor = await Cache.SmartRollupCommitments.GetAsync((int)commitment.PredecessorId); - Db.TryAttach(predecessor); - predecessor.Successors--; - // predecessor.LastLevel is not reverted - } - - Cache.AppState.ReleaseSmartRollupCommitmentId(); - Cache.SmartRollupStakes.Remove(commitment.Id); - Cache.SmartRollupCommitments.Remove(commitment); - Db.SmartRollupCommitments.Remove(commitment); - } - else if (operation.Flags is SmartRollupPublishFlags change) - { - if (change.HasFlag(SmartRollupPublishFlags.AddStaker)) - { - commitment.Stakers--; - commitment.ActiveStakers--; - Cache.SmartRollupStakes.Remove(commitment.Id, operation.SenderId); - } - else if (change.HasFlag(SmartRollupPublishFlags.ReactivateStaker)) - { - commitment.ActiveStakers--; - Cache.SmartRollupStakes.Set(commitment.Id, operation.SenderId, 0); - } - if (change.HasFlag(SmartRollupPublishFlags.ReactivateBranch)) - { - rollup!.PendingCommitments--; - rollup.RefutedCommitments++; - - commitment.Status = SmartRollupCommitmentStatus.Refuted; - if (commitment.Successors > 0) - { - var cnt = await UpdateSuccessorsStatus(Db, Cache.SmartRollupCommitments, commitment, SmartRollupCommitmentStatus.Orphan); - rollup.PendingCommitments -= cnt; - rollup.OrphanCommitments += cnt; - } - } - } - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.SmartRollupPublishCount--; - if (rollup != null) rollup.SmartRollupPublishCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - // commitment.LastLevel is not reverted - - Cache.AppState.Get().SmartRollupPublishOpsCount--; - #endregion - - Db.SmartRollupPublishOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - internal static async Task UpdateSuccessorsStatus( - TzktContext db, - SmartRollupCommitmentCache cache, - SmartRollupCommitment commitment, - SmartRollupCommitmentStatus status) - { - var cnt = 0; - var stack = new Stack(); - stack.Push(commitment); - - while (stack.TryPop(out var c)) - { - if (c.Successors > 0) - { - var ids = await db.SmartRollupCommitments - .AsNoTracking() - .Where(x => x.PredecessorId == c.Id) - .Select(x => x.Id) - .ToListAsync(); - - foreach (var id in ids) - { - var successor = await cache.GetAsync(id); - db.TryAttach(successor); - successor.Status = status; - stack.Push(successor); - cnt++; - } - } - } - - return cnt; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index 28fd98056..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SmartRollupRecoverBondCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetSmartRollupOrDefaultAsync(content.RequiredString("rollup")); - var staker = await Cache.Accounts.GetAsync(content.RequiredString("staker")); - - var result = content.Required("metadata").Required("operation_result"); - var bond = result.OptionalArray("balance_updates")?.EnumerateArray() - .FirstOrDefault(x => x.RequiredString("kind") == "contract") ?? default; - - var operation = new SmartRollupRecoverBondOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - SmartRollupId = rollup?.Id, - StakerId = staker?.Id, - Bond = bond.ValueKind == JsonValueKind.Undefined ? 0 : bond.RequiredInt64("change"), - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = 0, - StorageFee = null, - AllocationFee = null - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(staker); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.SmartRollupRecoverBondCount++; - if (rollup != null) rollup.SmartRollupRecoverBondCount++; - if (staker != null && staker.Id != sender.Id) staker.SmartRollupRecoverBondCount++; - - block.Operations |= Operations.SmartRollupRecoverBond; - - sender.Counter = operation.Counter; - - Cache.AppState.Get().SmartRollupRecoverBondOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - staker!.SmartRollupBonds -= operation.Bond; - rollup!.SmartRollupBonds -= operation.Bond; - rollup.ActiveStakers--; - - var bondOp = Context.SmartRollupPublishOps - .FirstOrDefault(x => x.SmartRollupId == operation.SmartRollupId && x.BondStatus == SmartRollupBondStatus.Active && x.SenderId == operation.StakerId) - ?? await Db.SmartRollupPublishOps.FirstAsync(x => x.SmartRollupId == operation.SmartRollupId && x.BondStatus == SmartRollupBondStatus.Active && x.SenderId == operation.StakerId); - bondOp.BondStatus = SmartRollupBondStatus.Returned; - - Cache.Statistics.Current.TotalSmartRollupBonds -= operation.Bond; - } - #endregion - - Proto.Manager.Set(sender); - Db.SmartRollupRecoverBondOps.Add(operation); - Context.SmartRollupRecoverBondOps.Add(operation); - } - - public virtual async Task Revert(Block block, SmartRollupRecoverBondOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.SmartRollupId) as SmartRollup; - var staker = await Cache.Accounts.GetAsync(operation.StakerId); - - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(staker); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - staker!.SmartRollupBonds += operation.Bond; - rollup!.SmartRollupBonds += operation.Bond; - rollup.ActiveStakers++; - - var bondOp = await Db.SmartRollupPublishOps - .OrderByDescending(x => x.Id) - .FirstAsync(x => x.SmartRollupId == operation.SmartRollupId && x.BondStatus == SmartRollupBondStatus.Returned && x.SenderId == operation.StakerId); - bondOp.BondStatus = SmartRollupBondStatus.Active; - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.SmartRollupRecoverBondCount--; - if (rollup != null) rollup.SmartRollupRecoverBondCount--; - if (staker != null && staker.Id != sender.Id) staker.SmartRollupRecoverBondCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - Cache.AppState.Get().SmartRollupRecoverBondOpsCount--; - #endregion - - Db.SmartRollupRecoverBondOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index 4ba0b2a6e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,563 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SmartRollupRefuteCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var refutation = content.Required("refutation"); - var result = content.Required("metadata").Required("operation_result"); - var move = refutation.RequiredString("refutation_kind") switch - { - "start" => RefutationMove.Start, - "move" when refutation.Required("step").ValueKind == JsonValueKind.Array => RefutationMove.Dissection, - "move" when refutation.Required("step").ValueKind == JsonValueKind.Object => RefutationMove.Proof, - _ => throw new NotImplementedException("Unknown refutation kind") - }; - - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var opponent = await Cache.Accounts.GetAsync(content.RequiredString("opponent")); - var rollup = await Cache.Accounts.GetSmartRollupOrDefaultAsync(content.RequiredString("rollup")); - var game = move != RefutationMove.Start - ? await Cache.RefutationGames.GetOrDefaultAsync(rollup?.Id, sender.Id, opponent?.Id) - : null; - - var operation = new SmartRollupRefuteOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - SmartRollupId = rollup?.Id, - GameId = game?.Id, - Move = move, - GameStatus = result.Optional("game_status") switch - { - null => RefutationGameStatus.None, - JsonElement el when el.ValueKind == JsonValueKind.String => el.GetString() switch - { - "ongoing" => RefutationGameStatus.Ongoing, - _ => throw new NotImplementedException("Unknown refutation game status") - }, - JsonElement el when el.ValueKind == JsonValueKind.Object => el.Required("result").RequiredString("kind") switch - { - "loser" => RefutationGameStatus.Loser, - "draw" => RefutationGameStatus.Draw, - _ => throw new NotImplementedException("Unknown refutation game result kind") - }, - _ => throw new NotImplementedException("Unknown refutation game status") - }, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = 0, - StorageFee = null, - AllocationFee = null - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(opponent); - Db.TryAttach(rollup); - Db.TryAttach(game); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.SmartRollupRefuteCount++; - if (rollup != null) rollup.SmartRollupRefuteCount++; - - block.Operations |= Operations.SmartRollupRefute; - - sender.Counter = operation.Counter; - - if (game != null) - game.LastLevel = operation.Level; - - if (operation.Move == RefutationMove.Dissection) - { - var steps = content.Required("refutation").RequiredArray("step").EnumerateArray(); - if (steps.Any()) - { - operation.DissectionStart = steps.First().RequiredInt64("tick"); - operation.DissectionEnd = steps.Last().RequiredInt64("tick"); - operation.DissectionSteps = steps.Count(); - } - } - - Cache.AppState.Get().SmartRollupRefuteOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - if (operation.Move == RefutationMove.Start) - { - var initiatorCommitmentHash = refutation.RequiredString("player_commitment_hash"); - var opponentCommitmentHash = refutation.RequiredString("opponent_commitment_hash"); - - var initiatorCommitment = await Cache.SmartRollupCommitments.GetAsync(initiatorCommitmentHash, rollup!.Id); - var opponentCommitment = await Cache.SmartRollupCommitments.GetAsync(opponentCommitmentHash, rollup.Id); - - game = new RefutationGame - { - Id = Cache.AppState.NextRefutationGameId(), - SmartRollupId = rollup.Id, - InitiatorId = sender.Id, - OpponentId = opponent!.Id, - InitiatorCommitmentId = initiatorCommitment.Id, - OpponentCommitmentId = opponentCommitment.Id, - LastMoveId = operation.Id, - FirstLevel = operation.Level, - LastLevel = operation.Level, - InitiatorReward = null, - InitiatorLoss = null, - OpponentReward = null, - OpponentLoss = null - }; - Cache.RefutationGames.Add(game); - Db.RefutationGames.Add(game); - - sender.RefutationGamesCount++; - sender.ActiveRefutationGamesCount++; - - opponent.RefutationGamesCount++; - opponent.ActiveRefutationGamesCount++; - - rollup.RefutationGamesCount++; - rollup.ActiveRefutationGamesCount++; - - operation.GameId = game.Id; - } - else - { - game!.LastMoveId = operation.Id; - - if (operation.GameStatus != RefutationGameStatus.Ongoing) - { - var initiator = await Cache.Accounts.GetAsync(game.InitiatorId); - var initiatorBaker = Cache.Accounts.GetDelegate(initiator.DelegateId) ?? (initiator as Data.Models.Delegate); - - opponent = await Cache.Accounts.GetAsync(game.OpponentId); - var opponentBaker = Cache.Accounts.GetDelegate(opponent.DelegateId) ?? (opponent as Data.Models.Delegate); - - Db.TryAttach(initiator); - Db.TryAttach(initiatorBaker); - - Db.TryAttach(opponent); - Db.TryAttach(opponentBaker); - - var updates = result.RequiredArray("balance_updates").EnumerateArray() - .Where(x => x.RequiredString("kind") == "freezer" || x.RequiredString("kind") == "contract"); - - var initiatorUpdate = updates.FirstOrDefault(x => x.RequiredString("contract") == initiator.Address); - var opponentUpdate = updates.FirstOrDefault(x => x.RequiredString("contract") == opponent.Address); - - var initiatorChange = initiatorUpdate.ValueKind != JsonValueKind.Undefined - ? initiatorUpdate.RequiredInt64("change") - : 0; - var opponentChange = opponentUpdate.ValueKind != JsonValueKind.Undefined - ? opponentUpdate.RequiredInt64("change") - : 0; - - if (initiatorChange > 0) - { - game.InitiatorReward = initiatorChange; - } - else if (initiatorChange == 0) - { - if (operation.GameStatus == RefutationGameStatus.Draw || result.Required("game_status").Required("result").RequiredString("player") == initiator.Address) - game.InitiatorLoss = 0; - else - game.InitiatorReward = 0; - } - else - { - game.InitiatorLoss = -initiatorChange; - initiator.SmartRollupBonds -= game.InitiatorLoss.Value; - rollup!.SmartRollupBonds -= game.InitiatorLoss.Value; - rollup.ActiveStakers--; - - var bondOp = await GetBondOperation(rollup, initiator); - bondOp.BondStatus = SmartRollupBondStatus.Lost; - - foreach (var commitment in await GetFundedCommitments(rollup, initiator, bondOp)) - { - commitment.ActiveStakers--; - await Cache.SmartRollupStakes.SetAsync(commitment, initiator.Id, 0); - } - - var initiatorCommitment = await Cache.SmartRollupCommitments.GetAsync(game.InitiatorCommitmentId); - if (initiatorCommitment.ActiveStakers == 0) - { - Db.TryAttach(initiatorCommitment); - - rollup.RefutedCommitments++; - rollup.PendingCommitments--; - - initiatorCommitment.Status = SmartRollupCommitmentStatus.Refuted; - if (initiatorCommitment.Successors > 0) - { - var cnt = await SmartRollupPublishCommit.UpdateSuccessorsStatus(Db, Cache.SmartRollupCommitments, initiatorCommitment, SmartRollupCommitmentStatus.Orphan); - rollup.OrphanCommitments += cnt; - rollup.PendingCommitments -= cnt; - } - } - } - - if (opponentChange > 0) - { - game.OpponentReward = opponentChange; - } - else if (opponentChange == 0) - { - if (operation.GameStatus == RefutationGameStatus.Draw || result.Required("game_status").Required("result").RequiredString("player") == opponent.Address) - game.OpponentLoss = 0; - else - game.OpponentReward = 0; - } - else - { - game.OpponentLoss = -opponentChange; - opponent.SmartRollupBonds -= game.OpponentLoss.Value; - rollup!.SmartRollupBonds -= game.OpponentLoss.Value; - rollup.ActiveStakers--; - - var bondOp = await GetBondOperation(rollup, opponent); - bondOp.BondStatus = SmartRollupBondStatus.Lost; - - foreach (var commitment in await GetFundedCommitments(rollup, opponent, bondOp)) - { - commitment.ActiveStakers--; - await Cache.SmartRollupStakes.SetAsync(commitment, opponent.Id, 0); - } - - var opponentCommitment = await Cache.SmartRollupCommitments.GetAsync(game.OpponentCommitmentId); - if (opponentCommitment.ActiveStakers == 0) - { - Db.TryAttach(opponentCommitment); - - rollup.RefutedCommitments++; - rollup.PendingCommitments--; - - opponentCommitment.Status = SmartRollupCommitmentStatus.Refuted; - if (opponentCommitment.Successors > 0) - { - var cnt = await SmartRollupPublishCommit.UpdateSuccessorsStatus(Db, Cache.SmartRollupCommitments, opponentCommitment, SmartRollupCommitmentStatus.Orphan); - rollup.OrphanCommitments += cnt; - rollup.PendingCommitments -= cnt; - } - } - } - - if (initiatorChange > 0) - Receive(initiator, initiatorChange); - else - Spend(initiator, -initiatorChange); - - if (opponentChange > 0) - Receive(opponent, opponentChange); - else - Spend(opponent, -opponentChange); - - initiator.ActiveRefutationGamesCount--; - opponent.ActiveRefutationGamesCount--; - rollup!.ActiveRefutationGamesCount--; - - var totalLoss = (game.InitiatorLoss ?? 0) + (game.OpponentLoss ?? 0); - var totalReward = (game.InitiatorReward ?? 0) + (game.OpponentReward ?? 0); - Cache.Statistics.Current.TotalBurned += totalLoss - totalReward; - Cache.Statistics.Current.TotalSmartRollupBonds -= totalLoss; - } - } - } - #endregion - - Proto.Manager.Set(sender); - Db.SmartRollupRefuteOps.Add(operation); - Context.SmartRollupRefuteOps.Add(operation); - } - - public virtual async Task Revert(Block block, SmartRollupRefuteOperation operation) - { - #region entities - var sender = await Cache.Accounts.GetAsync(operation.SenderId); - var rollup = await Cache.Accounts.GetAsync(operation.SmartRollupId) as SmartRollup; - - Db.TryAttach(sender); - Db.TryAttach(rollup); - #endregion - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - var game = await Cache.RefutationGames.GetAsync(operation.GameId!.Value); - var opponent = await Cache.Accounts.GetAsync(game.OpponentId); - - Db.TryAttach(game); - Db.TryAttach(opponent); - - if (operation.Move == RefutationMove.Start) - { - Cache.AppState.ReleaseRefutationGameId(); - Cache.RefutationGames.Remove(game); - Db.RefutationGames.Remove(game); - - sender.RefutationGamesCount--; - sender.ActiveRefutationGamesCount--; - - opponent.RefutationGamesCount--; - opponent.ActiveRefutationGamesCount--; - - rollup!.RefutationGamesCount--; - rollup.ActiveRefutationGamesCount--; - } - else - { - var prevMove = await Db.SmartRollupRefuteOps - .AsNoTracking() - .Where(x => x.GameId == game.Id && x.Id < operation.Id && x.Status == OperationStatus.Applied) - .OrderByDescending(x => x.Id) - .FirstAsync(); - - game.LastMoveId = prevMove.Id; - - if (operation.GameStatus != RefutationGameStatus.Ongoing) - { - var initiator = await Cache.Accounts.GetAsync(game.InitiatorId); - var initiatorBaker = Cache.Accounts.GetDelegate(initiator.DelegateId) ?? (initiator as Data.Models.Delegate); - - //var opponent = await Cache.Accounts.GetAsync(game.OpponentId); - var opponentBaker = Cache.Accounts.GetDelegate(opponent.DelegateId) ?? (opponent as Data.Models.Delegate); - - Db.TryAttach(initiator); - Db.TryAttach(initiatorBaker); - - Db.TryAttach(opponent); - Db.TryAttach(opponentBaker); - - var initiatorChange = game.InitiatorReward ?? -game.InitiatorLoss ?? 0; - var opponentChange = game.OpponentReward ?? -game.OpponentLoss ?? 0; - - if (initiatorChange > 0) - { - game.InitiatorReward = null; - } - else - { - game.InitiatorLoss = null; - initiator.SmartRollupBonds -= initiatorChange; - rollup!.SmartRollupBonds -= initiatorChange; - rollup.ActiveStakers++; - - var bondOp = await GetBondOperation(rollup.Id, initiator.Id); - bondOp.BondStatus = SmartRollupBondStatus.Active; - - foreach (var commitment in await GetFundedCommitments(rollup, initiator.Id, bondOp.Id, operation.Id)) - { - commitment.ActiveStakers++; - Cache.SmartRollupStakes.Set(commitment.Id, initiator.Id, 1); - } - - var initiatorCommitment = await Cache.SmartRollupCommitments.GetAsync(game.InitiatorCommitmentId); - if (initiatorCommitment.ActiveStakers == 1) - { - Db.TryAttach(initiatorCommitment); - - rollup.RefutedCommitments--; - rollup.PendingCommitments++; - - initiatorCommitment.Status = SmartRollupCommitmentStatus.Pending; - if (initiatorCommitment.Successors > 0) - { - var cnt = await SmartRollupPublishCommit.UpdateSuccessorsStatus(Db, Cache.SmartRollupCommitments, initiatorCommitment, SmartRollupCommitmentStatus.Pending); - rollup.OrphanCommitments -= cnt; - rollup.PendingCommitments += cnt; - } - } - } - - if (opponentChange > 0) - { - game.OpponentReward = null; - } - else - { - game.OpponentLoss = null; - opponent.SmartRollupBonds -= opponentChange; - rollup!.SmartRollupBonds -= opponentChange; - rollup.ActiveStakers++; - - var bondOp = await GetBondOperation(rollup.Id, opponent.Id); - bondOp.BondStatus = SmartRollupBondStatus.Active; - - foreach (var commitment in await GetFundedCommitments(rollup, opponent.Id, bondOp.Id, operation.Id)) - { - commitment.ActiveStakers++; - Cache.SmartRollupStakes.Set(commitment.Id, opponent.Id, 1); - } - - var opponentCommitment = await Cache.SmartRollupCommitments.GetAsync(game.OpponentCommitmentId); - if (opponentCommitment.ActiveStakers == 1) - { - Db.TryAttach(opponentCommitment); - - rollup.RefutedCommitments--; - rollup.PendingCommitments++; - - opponentCommitment.Status = SmartRollupCommitmentStatus.Pending; - if (opponentCommitment.Successors > 0) - { - var cnt = await SmartRollupPublishCommit.UpdateSuccessorsStatus(Db, Cache.SmartRollupCommitments, opponentCommitment, SmartRollupCommitmentStatus.Pending); - rollup.OrphanCommitments -= cnt; - rollup.PendingCommitments += cnt; - } - } - } - - if (initiatorChange > 0) - RevertReceive(initiator, initiatorChange); - else - RevertSpend(initiator, -initiatorChange); - - if (opponentChange > 0) - RevertReceive(opponent, opponentChange); - else - RevertSpend(opponent, -opponentChange); - - initiator.ActiveRefutationGamesCount++; - opponent.ActiveRefutationGamesCount++; - rollup!.ActiveRefutationGamesCount++; - } - } - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - - sender.SmartRollupRefuteCount--; - if (rollup != null) rollup.SmartRollupRefuteCount--; - - sender.Counter = operation.Counter - 1; - (sender as User)!.Revealed = true; - - // game.LastLevel is not reverted - - Cache.AppState.Get().SmartRollupRefuteOpsCount--; - #endregion - - Db.SmartRollupRefuteOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - async Task GetBondOperation(SmartRollup rollup, Account staker) - { - return Context.SmartRollupPublishOps - .FirstOrDefault(x => - x.SmartRollupId == rollup.Id && - x.BondStatus == SmartRollupBondStatus.Active && - x.SenderId == staker.Id) - ?? await Db.SmartRollupPublishOps.FirstAsync(x => - x.SmartRollupId == rollup.Id && - x.BondStatus == SmartRollupBondStatus.Active && - x.SenderId == staker.Id); - - } - - async Task GetBondOperation(int rollupId, int stakerId) - { - return await Db.SmartRollupPublishOps - .OrderByDescending(x => x.Id) - .FirstAsync(x => - x.SmartRollupId == rollupId && - x.BondStatus == SmartRollupBondStatus.Lost && - x.SenderId == stakerId); - } - - async Task> GetFundedCommitments(SmartRollup rollup, Account staker, SmartRollupPublishOperation bondOp) - { - var ids = (await Db.SmartRollupPublishOps.AsNoTracking() - .Join(Db.SmartRollupCommitments, o => o.CommitmentId, c => c.Id, (o, c) => new { o, c }) - .Where(x => - x.o.Id >= bondOp.Id && - x.o.SenderId == staker.Id && - x.o.SmartRollupId == rollup.Id && - x.o.Status == OperationStatus.Applied && - x.c.InboxLevel > rollup.InboxLevel) - .Select(x => x.o.CommitmentId!.Value) - .ToListAsync()) - .ToHashSet(); - - foreach (var op in Context.SmartRollupPublishOps) - { - if (op.Id >= bondOp.Id && - op.SenderId == staker.Id && - op.SmartRollupId == rollup.Id && - op.Status == OperationStatus.Applied && - (await Cache.SmartRollupCommitments.GetAsync(op.CommitmentId!.Value)).InboxLevel > rollup.InboxLevel) - { - ids.Add(op.CommitmentId.Value); - } - } - - var res = new List(ids.Count); - foreach (var id in ids) - { - var commitment = await Cache.SmartRollupCommitments.GetAsync(id); - Db.TryAttach(commitment); - res.Add(commitment); - } - - return res; - } - - async Task> GetFundedCommitments(SmartRollup rollup, int stakerId, long fromId, long toId) - { - var ids = (await Db.SmartRollupPublishOps.AsNoTracking() - .Join(Db.SmartRollupCommitments, o => o.CommitmentId, c => c.Id, (o, c) => new { o, c }) - .Where(x => - x.o.Id >= fromId && - x.o.Id < toId && - x.o.SenderId == stakerId && - x.o.SmartRollupId == rollup.Id && - x.o.Status == OperationStatus.Applied && - x.c.InboxLevel > rollup.InboxLevel) - .Select(x => x.o.CommitmentId!.Value) - .ToListAsync()) - .ToHashSet(); - - var res = new List(ids.Count); - foreach (var id in ids) - { - var commitment = await Cache.SmartRollupCommitments.GetAsync(id); - Db.TryAttach(commitment); - res.Add(commitment); - } - - return res; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index c0f6f1cdf..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,289 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SmartRollupTimeoutCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); - var rollup = await Cache.Accounts.GetAsync(content.RequiredString("rollup")) as SmartRollup; - - var aliceId = await Cache.Accounts.GetIdOrDefaultAsync(content.Required("stakers").RequiredString("alice")); - var bobId = await Cache.Accounts.GetIdOrDefaultAsync(content.Required("stakers").RequiredString("bob")); - var game = await Cache.RefutationGames.GetOrDefaultAsync(rollup?.Id, aliceId, bobId); - - var result = content.Required("metadata").Required("operation_result"); - - var operation = new SmartRollupRefuteOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - SmartRollupId = rollup?.Id, - GameId = game?.Id, - Move = RefutationMove.Timeout, - GameStatus = result.Optional("game_status") switch - { - null => RefutationGameStatus.None, - JsonElement el when el.ValueKind == JsonValueKind.String => el.GetString() switch - { - "ongoing" => RefutationGameStatus.Ongoing, - _ => throw new NotImplementedException("Unknown refutation game status") - }, - JsonElement el when el.ValueKind == JsonValueKind.Object => el.Required("result").RequiredString("kind") switch - { - "loser" => RefutationGameStatus.Loser, - "draw" => RefutationGameStatus.Draw, - _ => throw new NotImplementedException("Unknown refutation game result kind") - }, - _ => throw new NotImplementedException("Unknown refutation game status") - }, - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - StorageUsed = 0, - StorageFee = null, - AllocationFee = null - }; - #endregion - - #region entities - Db.TryAttach(sender); - Db.TryAttach(rollup); - Db.TryAttach(game); - #endregion - - #region apply operation - PayFee(sender, operation.BakerFee); - - sender.SmartRollupRefuteCount++; - if (rollup != null) rollup.SmartRollupRefuteCount++; - - block.Operations |= Operations.SmartRollupRefute; - - sender.Counter = operation.Counter; - - if (game != null) - game.LastLevel = operation.Level; - - Cache.AppState.Get().SmartRollupRefuteOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - game!.LastMoveId = operation.Id; - - var initiator = await Cache.Accounts.GetAsync(game.InitiatorId); - var initiatorBaker = Cache.Accounts.GetDelegate(initiator.DelegateId) ?? (initiator as Data.Models.Delegate); - - var opponent = await Cache.Accounts.GetAsync(game.OpponentId); - var opponentBaker = Cache.Accounts.GetDelegate(opponent.DelegateId) ?? (opponent as Data.Models.Delegate); - - Db.TryAttach(initiator); - Db.TryAttach(initiatorBaker); - - Db.TryAttach(opponent); - Db.TryAttach(opponentBaker); - - var updates = result.RequiredArray("balance_updates").EnumerateArray() - .Where(x => x.RequiredString("kind") == "freezer" || x.RequiredString("kind") == "contract"); - - var initiatorUpdate = updates.FirstOrDefault(x => x.RequiredString("contract") == initiator.Address); - var opponentUpdate = updates.FirstOrDefault(x => x.RequiredString("contract") == opponent.Address); - - var initiatorChange = initiatorUpdate.ValueKind != JsonValueKind.Undefined - ? initiatorUpdate.RequiredInt64("change") - : 0; - var opponentChange = opponentUpdate.ValueKind != JsonValueKind.Undefined - ? opponentUpdate.RequiredInt64("change") - : 0; - - if (initiatorChange > 0) - { - game.InitiatorReward = initiatorChange; - } - else if (initiatorChange == 0) - { - if (operation.GameStatus == RefutationGameStatus.Draw || result.Required("game_status").Required("result").RequiredString("player") == initiator.Address) - game.InitiatorLoss = 0; - else - game.InitiatorReward = 0; - } - else - { - game.InitiatorLoss = -initiatorChange; - initiator.SmartRollupBonds -= game.InitiatorLoss.Value; - rollup!.SmartRollupBonds -= game.InitiatorLoss.Value; - rollup.ActiveStakers--; - - var bondOp = await GetBondOperation(rollup, initiator); - bondOp.BondStatus = SmartRollupBondStatus.Lost; - - foreach (var commitment in await GetFundedCommitments(rollup, initiator, bondOp)) - { - commitment.ActiveStakers--; - await Cache.SmartRollupStakes.SetAsync(commitment, initiator.Id, 0); - } - - var initiatorCommitment = await Cache.SmartRollupCommitments.GetAsync(game.InitiatorCommitmentId); - if (initiatorCommitment.ActiveStakers == 0) - { - Db.TryAttach(initiatorCommitment); - - rollup.RefutedCommitments++; - rollup.PendingCommitments--; - - initiatorCommitment.Status = SmartRollupCommitmentStatus.Refuted; - if (initiatorCommitment.Successors > 0) - { - var cnt = await SmartRollupPublishCommit.UpdateSuccessorsStatus(Db, Cache.SmartRollupCommitments, initiatorCommitment, SmartRollupCommitmentStatus.Orphan); - rollup.OrphanCommitments += cnt; - rollup.PendingCommitments -= cnt; - } - } - } - - if (opponentChange > 0) - { - game.OpponentReward = opponentChange; - } - else if (opponentChange == 0) - { - if (operation.GameStatus == RefutationGameStatus.Draw || result.Required("game_status").Required("result").RequiredString("player") == opponent.Address) - game.OpponentLoss = 0; - else - game.OpponentReward = 0; - } - else - { - game.OpponentLoss = -opponentChange; - opponent.SmartRollupBonds -= game.OpponentLoss.Value; - rollup!.SmartRollupBonds -= game.OpponentLoss.Value; - rollup.ActiveStakers--; - - var bondOp = await GetBondOperation(rollup, opponent); - bondOp.BondStatus = SmartRollupBondStatus.Lost; - - foreach (var commitment in await GetFundedCommitments(rollup, opponent, bondOp)) - { - commitment.ActiveStakers--; - await Cache.SmartRollupStakes.SetAsync(commitment, opponent.Id, 0); - } - - var opponentCommitment = await Cache.SmartRollupCommitments.GetAsync(game.OpponentCommitmentId); - if (opponentCommitment.ActiveStakers == 0) - { - Db.TryAttach(opponentCommitment); - - rollup.RefutedCommitments++; - rollup.PendingCommitments--; - - opponentCommitment.Status = SmartRollupCommitmentStatus.Refuted; - if (opponentCommitment.Successors > 0) - { - var cnt = await SmartRollupPublishCommit.UpdateSuccessorsStatus(Db, Cache.SmartRollupCommitments, opponentCommitment, SmartRollupCommitmentStatus.Orphan); - rollup.OrphanCommitments += cnt; - rollup.PendingCommitments -= cnt; - } - } - } - - if (initiatorChange > 0) - Receive(initiator, initiatorChange); - else - Spend(initiator, -initiatorChange); - - if (opponentChange > 0) - Receive(opponent, opponentChange); - else - Spend(opponent, -opponentChange); - - initiator.ActiveRefutationGamesCount--; - opponent.ActiveRefutationGamesCount--; - rollup!.ActiveRefutationGamesCount--; - - var totalLoss = (game.InitiatorLoss ?? 0) + (game.OpponentLoss ?? 0); - var totalReward = (game.InitiatorReward ?? 0) + (game.OpponentReward ?? 0); - Cache.Statistics.Current.TotalBurned += totalLoss - totalReward; - Cache.Statistics.Current.TotalSmartRollupBonds -= totalLoss; - } - #endregion - - Proto.Manager.Set(sender); - Db.SmartRollupRefuteOps.Add(operation); - Context.SmartRollupRefuteOps.Add(operation); - } - - async Task GetBondOperation(SmartRollup rollup, Account staker) - { - return Context.SmartRollupPublishOps - .FirstOrDefault(x => - x.SmartRollupId == rollup.Id && - x.BondStatus == SmartRollupBondStatus.Active && - x.SenderId == staker.Id) - ?? await Db.SmartRollupPublishOps.FirstAsync(x => - x.SmartRollupId == rollup.Id && - x.BondStatus == SmartRollupBondStatus.Active && - x.SenderId == staker.Id); - - } - - async Task> GetFundedCommitments(SmartRollup rollup, Account staker, SmartRollupPublishOperation bondOp) - { - var ids = (await Db.SmartRollupPublishOps.AsNoTracking() - .Join(Db.SmartRollupCommitments, o => o.CommitmentId, c => c.Id, (o, c) => new { o, c }) - .Where(x => - x.o.Id >= bondOp.Id && - x.o.SenderId == staker.Id && - x.o.SmartRollupId == rollup.Id && - x.o.Status == OperationStatus.Applied && - x.c.InboxLevel > rollup.InboxLevel) - .Select(x => x.o.CommitmentId!.Value) - .ToListAsync()) - .ToHashSet(); - - foreach (var op in Context.SmartRollupPublishOps) - { - if (op.Id >= bondOp.Id && - op.SenderId == staker.Id && - op.SmartRollupId == rollup.Id && - op.Status == OperationStatus.Applied && - (await Cache.SmartRollupCommitments.GetAsync(op.CommitmentId!.Value)).InboxLevel > rollup.InboxLevel) - { - ids.Add(op.CommitmentId!.Value); - } - } - - var res = new List(ids.Count); - foreach (var id in ids) - { - var commitment = await Cache.SmartRollupCommitments.GetAsync(id); - Db.TryAttach(commitment); - res.Add(commitment); - } - - return res; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 34c320e4e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TransactionsCommit : Proto14.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index 10fca05f7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupCommitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupCommitCommit.cs deleted file mode 100644 index 649da8447..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupCommitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TxRollupCommitCommit : Proto13.TxRollupCommitCommit - { - public TxRollupCommitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupDispatchTicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupDispatchTicketsCommit.cs deleted file mode 100644 index 7dc2d2311..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupDispatchTicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TxRollupDispatchTicketsCommit : Proto13.TxRollupDispatchTicketsCommit - { - public TxRollupDispatchTicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs deleted file mode 100644 index 32bcb800f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TxRollupFinalizeCommitmentCommit : Proto13.TxRollupFinalizeCommitmentCommit - { - public TxRollupFinalizeCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupOriginationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupOriginationCommit.cs deleted file mode 100644 index 36270f472..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupOriginationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TxRollupOriginationCommit : Proto13.TxRollupOriginationCommit - { - public TxRollupOriginationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupRejectionCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupRejectionCommit.cs deleted file mode 100644 index 6e6f0eec3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupRejectionCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TxRollupRejectionCommit : Proto13.TxRollupRejectionCommit - { - public TxRollupRejectionCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupRemoveCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupRemoveCommitmentCommit.cs deleted file mode 100644 index 50e232c52..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupRemoveCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TxRollupRemoveCommitmentCommit : Proto13.TxRollupRemoveCommitmentCommit - { - public TxRollupRemoveCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupReturnBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupReturnBondCommit.cs deleted file mode 100644 index fbdcfb4d4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupReturnBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TxRollupReturnBondCommit : Proto13.TxRollupReturnBondCommit - { - public TxRollupReturnBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupSubmitBatchCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupSubmitBatchCommit.cs deleted file mode 100644 index 4024c0233..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/TxRollupSubmitBatchCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TxRollupSubmitBatchCommit : Proto13.TxRollupSubmitBatchCommit - { - public TxRollupSubmitBatchCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index 5d98cc735..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class UpdateSecondaryKeyCommit : Proto15.UpdateSecondaryKeyCommit - { - public UpdateSecondaryKeyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 893df02ca..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class VdfRevelationCommit : Proto14.VdfRevelationCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 938e5cb5c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SnapshotBalanceCommit : Proto12.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SoftwareCommit.cs deleted file mode 100644 index 74d73d976..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/StateCommit.cs deleted file mode 100644 index 4fe5c8c0a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/StatisticsCommit.cs deleted file mode 100644 index 630560d3d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SubsidyCommit.cs deleted file mode 100644 index 6bf19e77f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/TicketsCommit.cs deleted file mode 100644 index bf6a68cfb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/TicketsCommit.cs +++ /dev/null @@ -1,599 +0,0 @@ -using System.Numerics; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TicketsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - readonly Dictionary>> Updates = []; - - public virtual void Append(ManagerOperation parent, ManagerOperation op, IEnumerable updates) - { - if (!Updates.TryGetValue(parent, out var opUpdates)) - Updates.Add(parent, opUpdates = []); - - foreach (var update in updates) - { - if (!opUpdates.TryGetValue(update.Ticket, out var ticketUpdates)) - opUpdates.Add(update.Ticket, ticketUpdates = []); - - ticketUpdates.AddRange(update.Updates.Select(update => (op, update))); - } - } - - public virtual async Task Apply() - { - if (Updates.Count == 0) return; - - #region precache - var accountsSet = new HashSet(); - var ticketsSet = new HashSet<(int, byte[], int, byte[], int)>(); - var balancesSet = new HashSet<(int, long)>(); - - foreach (var (ticket, updates) in Updates.SelectMany(x => x.Value)) - { - accountsSet.Add(ticket.Ticketer); - foreach (var (_, upd) in updates) - accountsSet.Add(upd.Account); - } - - await Cache.Accounts.Preload(accountsSet); - - foreach (var (ticket, _) in Updates.SelectMany(x => x.Value)) - { - if (Cache.Accounts.TryGetCached(ticket.Ticketer, out var ticketer)) - ticketsSet.Add((ticketer.Id, ticket.RawType, ticket.TypeHash, ticket.RawContent, ticket.ContentHash)); - } - - await Cache.Tickets.Preload(ticketsSet); - - foreach (var (ticket, updates) in Updates.SelectMany(x => x.Value)) - { - if (Cache.Accounts.TryGetCached(ticket.Ticketer, out var ticketer)) - { - if (Cache.Tickets.TryGetCached(ticketer.Id, ticket.RawType, ticket.RawContent, out var _ticket)) - { - foreach (var (_, upd) in updates) - { - if (Cache.Accounts.TryGetCached(upd.Account, out var acc)) - balancesSet.Add((acc.Id, _ticket.Id)); - } - } - } - } - - await Cache.TicketBalances.Preload(balancesSet); - #endregion - - Context.Block.Events |= BlockEvents.Tickets; - - foreach (var (parent, opUpdates) in Updates.OrderBy(kv => kv.Key.Id)) - { - foreach (var (ticketIdentity, ticketUpdates) in opUpdates.OrderBy(x => x.Value[0].Op.Id).ThenBy(x => x.Key.ContentHash + x.Key.TypeHash)) - { - var ticketer = (GetOrCreateAccount(ticketUpdates[0].Op, ticketIdentity.Ticketer) as Contract)!; - var ticket = GetOrCreateTicket(ticketUpdates[0].Op, ticketer, ticketIdentity); - - if (ticketUpdates.Count == 1 || ticketUpdates.BigSum(x => x.Update.Amount) != BigInteger.Zero) - { - foreach (var (op, ticketUpdate) in ticketUpdates) - MintOrBurnTickets(op, ticket, ticketUpdate.Account, ticketUpdate.Amount); - } - else if (ticketUpdates.Count(x => x.Update.Amount < BigInteger.Zero) == 1) - { - var (fromOp, fromUpdate) = ticketUpdates.First(x => x.Update.Amount < BigInteger.Zero); - foreach (var (op, ticketUpdate) in ticketUpdates.Where(x => x.Update.Amount > BigInteger.Zero)) - TransferTickets(ticketUpdates[0].Op, ticket, fromUpdate.Account, ticketUpdate.Account, ticketUpdate.Amount); - } - else if (ticketUpdates.Count(x => x.Update.Amount > BigInteger.Zero) == 1) - { - var (toOp, toUpdate) = ticketUpdates.First(x => x.Update.Amount > BigInteger.Zero); - foreach (var (op, ticketUpdate) in ticketUpdates.Where(x => x.Update.Amount < BigInteger.Zero)) - TransferTickets(ticketUpdates[0].Op, ticket, ticketUpdate.Account, toUpdate.Account, -ticketUpdate.Amount); - } - else if (IsTransfersSequence(ticketUpdates)) - { - for (int i = 0; i < ticketUpdates.Count; i += 2) - { - var u1 = ticketUpdates[i].Update; - var u2 = ticketUpdates[i + 1].Update; - - if (u1.Amount < 0) // from u1 to u2 - TransferTickets(ticketUpdates[i].Op, ticket, u1.Account, u2.Account, u2.Amount); - else // from u2 to u1 - TransferTickets(ticketUpdates[i].Op, ticket, u2.Account, u1.Account, u1.Amount); - } - } - else - { - foreach (var (op, ticketUpdate) in ticketUpdates) - MintOrBurnTickets(op, ticket, ticketUpdate.Account, ticketUpdate.Amount); - } - } - } - } - - static bool IsTransfersSequence(List<(ManagerOperation Op, TicketUpdate Update)> updates) - { - if (updates.Count % 2 != 0) - return false; - - for (int i = 0; i < updates.Count; i += 2) - if (updates[i].Update.Amount > 0 || updates[i].Update.Amount != -updates[i + 1].Update.Amount) - return false; - - return true; - } - - Account GetOrCreateAccount(ManagerOperation op, string address) - { - if (!Cache.Accounts.TryGetCached(address, out var account)) - { - account = address[0] == 't' && address[1] == 'z' - ? new User - { - Id = Cache.AppState.NextAccountId(), - Address = address, - FirstLevel = op.Level, - LastLevel = op.Level, - Type = AccountType.User - } - : new Account - { - Id = Cache.AppState.NextAccountId(), - Address = address, - FirstLevel = op.Level, - LastLevel = op.Level, - Type = AccountType.Ghost - }; - - Db.Accounts.Add(account); - Cache.Accounts.Add(account); - } - return account; - } - - Ticket GetOrCreateTicket(ManagerOperation op, Contract ticketer, TicketIdentity ticketToken) - { - if (!Cache.Tickets.TryGetCached(ticketer.Id, ticketToken.RawType, ticketToken.RawContent, out var ticket)) - { - ticket = new Ticket - { - Id = op switch - { - TransactionOperation transaction => Cache.AppState.NextSubId(transaction), - TransferTicketOperation transferTicket => Cache.AppState.NextSubId(transferTicket), - SmartRollupExecuteOperation srExecute => Cache.AppState.NextSubId(srExecute), - _ => throw new ArgumentOutOfRangeException(nameof(op)) - }, - TicketerId = ticketer.Id, - FirstMinterId = op switch - { - TransactionOperation transaction => transaction.InitiatorId ?? transaction.SenderId, - TransferTicketOperation transferTicket => transferTicket.SenderId, - SmartRollupExecuteOperation srExecute => srExecute.SenderId, - _ => throw new ArgumentOutOfRangeException(nameof(op)) - }, - FirstLevel = op.Level, - LastLevel = op.Level, - TotalBurned = BigInteger.Zero, - TotalMinted = BigInteger.Zero, - TotalSupply = BigInteger.Zero, - RawType = ticketToken.RawType, - RawContent = ticketToken.RawContent, - JsonContent = ticketToken.JsonContent, - ContentHash = ticketToken.ContentHash, - TypeHash = ticketToken.TypeHash, - }; - - Db.Tickets.Add(ticket); - Cache.Tickets.Add(ticket); - - Db.TryAttach(ticketer); - ticketer.TicketsCount++; - - var state = Cache.AppState.Get(); - state.TicketsCount++; - } - return ticket; - } - - TicketBalance GetOrCreateTicketBalance(ManagerOperation op, Ticket ticket, Account account) - { - if (!Cache.TicketBalances.TryGet(account.Id, ticket.Id, out var ticketBalance)) - { - ticketBalance = new TicketBalance - { - Id = op switch - { - TransactionOperation transaction => Cache.AppState.NextSubId(transaction), - TransferTicketOperation transferTicket => Cache.AppState.NextSubId(transferTicket), - SmartRollupExecuteOperation srExecute => Cache.AppState.NextSubId(srExecute), - _ => throw new ArgumentOutOfRangeException(nameof(op)) - }, - AccountId = account.Id, - TicketId = ticket.Id, - TicketerId = ticket.TicketerId, - FirstLevel = op.Level, - LastLevel = op.Level, - Balance = BigInteger.Zero - }; - - Db.TicketBalances.Add(ticketBalance); - Cache.TicketBalances.Add(ticketBalance); - - Db.TryAttach(ticket); - ticket.BalancesCount++; - - Db.TryAttach(account); - account.TicketBalancesCount++; - - var state = Cache.AppState.Get(); - state.TicketBalancesCount++; - } - return ticketBalance; - } - - void TransferTickets(ManagerOperation op, Ticket ticket, string fromAddress, string toAddress, BigInteger amount) - { - var from = GetOrCreateAccount(op, fromAddress); - var fromBalance = GetOrCreateTicketBalance(op, ticket, from); - var to = GetOrCreateAccount(op, toAddress); - var toBalance = GetOrCreateTicketBalance(op, ticket, to); - - switch (op) - { - case TransactionOperation transaction: - transaction.TicketTransfers = (transaction.TicketTransfers ?? 0) + 1; - break; - case TransferTicketOperation transferTicket: - transferTicket.TicketTransfers = (transferTicket.TicketTransfers ?? 0) + 1; - break; - case SmartRollupExecuteOperation srExecute: - srExecute.TicketTransfers = (srExecute.TicketTransfers ?? 0) + 1; - break; - } - - Db.TryAttach(from); - from.TicketTransfersCount++; - from.LastLevel = op.Level; - - Db.TryAttach(to); - if (to != from) - { - to.TicketTransfersCount++; - to.LastLevel = op.Level; - } - - Db.TryAttach(fromBalance); - fromBalance.Balance -= amount; - fromBalance.TransfersCount++; - fromBalance.LastLevel = op.Level; - - Db.TryAttach(toBalance); - toBalance.Balance += amount; - if (toBalance != fromBalance) toBalance.TransfersCount++; - toBalance.LastLevel = op.Level; - - Db.TryAttach(ticket); - ticket.TransfersCount++; - ticket.LastLevel = op.Level; - if (amount != BigInteger.Zero && fromBalance != toBalance) - { - if (fromBalance.Balance == BigInteger.Zero) - { - from.ActiveTicketsCount--; - ticket.HoldersCount--; - } - if (toBalance.Balance == amount) - { - to.ActiveTicketsCount++; - ticket.HoldersCount++; - } - } - - var state = Cache.AppState.Get(); - state.TicketTransfersCount++; - - Db.TicketTransfers.Add(new TicketTransfer - { - Id = op switch - { - TransactionOperation transaction => Cache.AppState.NextSubId(transaction), - TransferTicketOperation transferTicket => Cache.AppState.NextSubId(transferTicket), - SmartRollupExecuteOperation srExecute => Cache.AppState.NextSubId(srExecute), - _ => throw new ArgumentOutOfRangeException(nameof(op)) - }, - Amount = amount, - FromId = from.Id, - ToId = to.Id, - Level = op.Level, - TicketId = ticket.Id, - TicketerId = ticket.TicketerId, - TransactionId = (op as TransactionOperation)?.Id, - TransferTicketId = (op as TransferTicketOperation)?.Id, - SmartRollupExecuteId = (op as SmartRollupExecuteOperation)?.Id - }); - } - - void MintOrBurnTickets(ManagerOperation op, Ticket ticket, string address, BigInteger amount) - { - var account = GetOrCreateAccount(op, address); - var balance = GetOrCreateTicketBalance(op, ticket, account); - - switch (op) - { - case TransactionOperation transaction: - transaction.TicketTransfers = (transaction.TicketTransfers ?? 0) + 1; - break; - case TransferTicketOperation transferTicket: - transferTicket.TicketTransfers = (transferTicket.TicketTransfers ?? 0) + 1; - break; - case SmartRollupExecuteOperation srExecute: - srExecute.TicketTransfers = (srExecute.TicketTransfers ?? 0) + 1; - break; - } - - Db.TryAttach(account); - account.TicketTransfersCount++; - account.LastLevel = op.Level; - - Db.TryAttach(balance); - balance.Balance += amount; - balance.TransfersCount++; - balance.LastLevel = op.Level; - - Db.TryAttach(ticket); - ticket.TransfersCount++; - ticket.LastLevel = op.Level; - ticket.TotalSupply += amount; - if (amount > BigInteger.Zero) - { - ticket.TotalMinted += amount; - if (balance.Balance == amount) - { - account.ActiveTicketsCount++; - ticket.HoldersCount++; - } - } - else if (amount < BigInteger.Zero) - { - ticket.TotalBurned += -amount; - if (balance.Balance == BigInteger.Zero) - { - account.ActiveTicketsCount--; - ticket.HoldersCount--; - } - } - - var state = Cache.AppState.Get(); - state.TicketTransfersCount++; - - Db.TicketTransfers.Add(new TicketTransfer - { - Id = op switch - { - TransactionOperation transaction => Cache.AppState.NextSubId(transaction), - TransferTicketOperation transferTicket => Cache.AppState.NextSubId(transferTicket), - SmartRollupExecuteOperation srExecute => Cache.AppState.NextSubId(srExecute), - _ => throw new ArgumentOutOfRangeException(nameof(op)) - }, - Amount = amount > BigInteger.Zero ? amount : -amount, - FromId = amount < BigInteger.Zero ? account.Id : null, - ToId = amount > BigInteger.Zero ? account.Id : null, - Level = op.Level, - TicketId = ticket.Id, - TicketerId = ticket.TicketerId, - TransactionId = (op as TransactionOperation)?.Id, - TransferTicketId = (op as TransferTicketOperation)?.Id, - SmartRollupExecuteId = (op as SmartRollupExecuteOperation)?.Id - }); - } - - public virtual async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.Tickets)) - return; - - var state = Cache.AppState.Get(); - - var transfers = await Db.TicketTransfers - .AsNoTracking() - .Where(x => x.Level == block.Level) - .OrderByDescending(x => x.Id) - .ToListAsync(); - - #region precache - var accountsSet = new HashSet(); - var ticketsSet = new HashSet(); - var balancesSet = new HashSet<(int, long)>(); - - foreach (var tr in transfers) - ticketsSet.Add(tr.TicketId); - - await Cache.Tickets.Preload(ticketsSet); - - foreach (var tr in transfers) - { - if (tr.FromId is int fromId) - { - accountsSet.Add(fromId); - balancesSet.Add((fromId, tr.TicketId)); - } - - if (tr.ToId is int toId) - { - accountsSet.Add(toId); - balancesSet.Add((toId, tr.TicketId)); - } - } - - foreach (var id in ticketsSet) - { - var ticket = Cache.Tickets.GetCached(id); - accountsSet.Add(ticket.TicketerId); - } - - await Cache.Accounts.Preload(accountsSet); - await Cache.TicketBalances.Preload(balancesSet); - #endregion - - var ticketsToRemove = new HashSet(); - var ticketBalancesToRemove = new HashSet(); - - foreach (var transfer in transfers) - { - var ticket = Cache.Tickets.GetCached(transfer.TicketId); - Db.TryAttach(ticket); - ticket.TransfersCount--; - ticket.LastLevel = block.Level; - if (ticket.TransfersCount == 0) - ticketsToRemove.Add(ticket); - - state.TicketTransfersCount--; - - if (transfer.FromId is int fromId && transfer.ToId is int toId) - { - #region revert transfer - var from = Cache.Accounts.GetCached(fromId); - var fromBalance = Cache.TicketBalances.Get(from.Id, ticket.Id); - var to = Cache.Accounts.GetCached(toId); - var toBalance = Cache.TicketBalances.Get(to.Id, ticket.Id); - - Db.TryAttach(from); - from.TicketTransfersCount--; - from.LastLevel = block.Level; - - Db.TryAttach(to); - if (to != from) - { - to.TicketTransfersCount--; - to.LastLevel = block.Level; - } - - Db.TryAttach(fromBalance); - fromBalance.Balance += transfer.Amount; - fromBalance.TransfersCount--; - fromBalance.LastLevel = block.Level; - if (fromBalance.TransfersCount == 0) - ticketBalancesToRemove.Add(fromBalance); - - Db.TryAttach(toBalance); - toBalance.Balance -= transfer.Amount; - if (toBalance != fromBalance) toBalance.TransfersCount--; - toBalance.LastLevel = block.Level; - if (toBalance.TransfersCount == 0) - ticketBalancesToRemove.Add(toBalance); - - if (transfer.Amount != BigInteger.Zero && fromBalance != toBalance) - { - if (fromBalance.Balance == transfer.Amount) - { - from.ActiveTicketsCount++; - ticket.HoldersCount++; - } - if (toBalance.Balance == BigInteger.Zero) - { - to.ActiveTicketsCount--; - ticket.HoldersCount--; - } - } - #endregion - } - else if (transfer.ToId != null) - { - #region revert mint - var to = Cache.Accounts.GetCached(transfer.ToId.Value); - var toBalance = Cache.TicketBalances.Get(to.Id, ticket.Id); - - Db.TryAttach(to); - to.TicketTransfersCount--; - to.LastLevel = block.Level; - - Db.TryAttach(toBalance); - toBalance.Balance -= transfer.Amount; - toBalance.TransfersCount--; - toBalance.LastLevel = block.Level; - if (toBalance.TransfersCount == 0) - ticketBalancesToRemove.Add(toBalance); - - if (transfer.Amount != BigInteger.Zero) - { - ticket.TotalSupply -= transfer.Amount; - ticket.TotalMinted -= transfer.Amount; - if (toBalance.Balance == BigInteger.Zero) - { - to.ActiveTicketsCount--; - ticket.HoldersCount--; - } - } - #endregion - } - else - { - #region revert burn - var from = Cache.Accounts.GetCached(transfer.FromId!.Value); - var fromBalance = Cache.TicketBalances.Get(from.Id, ticket.Id); - - Db.TryAttach(from); - from.TicketTransfersCount--; - from.LastLevel = block.Level; - - Db.TryAttach(fromBalance); - fromBalance.Balance += transfer.Amount; - fromBalance.TransfersCount--; - fromBalance.LastLevel = block.Level; - if (fromBalance.TransfersCount == 0) - ticketBalancesToRemove.Add(fromBalance); - - if (transfer.Amount != BigInteger.Zero) - { - ticket.TotalSupply += transfer.Amount; - ticket.TotalBurned -= transfer.Amount; - if (fromBalance.Balance == transfer.Amount) - { - from.ActiveTicketsCount++; - ticket.HoldersCount++; - } - } - #endregion - } - } - - foreach (var ticketBalance in ticketBalancesToRemove) - { - Db.TicketBalances.Remove(ticketBalance); - Cache.TicketBalances.Remove(ticketBalance); - - var t = Cache.Tickets.GetCached(ticketBalance.TicketId); - Db.TryAttach(t); - t.BalancesCount--; - - var a = Cache.Accounts.GetCached(ticketBalance.AccountId); - Db.TryAttach(a); - a.TicketBalancesCount--; - - state.TicketBalancesCount--; - } - - foreach (var ticket in ticketsToRemove) - { - Db.Tickets.Remove(ticket); - Cache.Tickets.Remove(ticket); - - var contract = (Contract)Cache.Accounts.GetCached(ticket.TicketerId); - Db.TryAttach(contract); - contract.TicketsCount--; - - state.TicketsCount--; - } - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "TicketTransfers" - WHERE "Level" = {0} - """, block.Level); - } - } -} \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/TokensCommit.cs deleted file mode 100644 index 93af181df..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/VotingCommit.cs deleted file mode 100644 index 379a0a2fe..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Diagnostics/Diagnostics.cs deleted file mode 100644 index 0bf01d82e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class Diagnostics : Proto14.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - - protected override async Task TestTicketBalance(int level, TicketBalance balance) - { - var ticketer = await Cache.Accounts.GetAsync(balance.TicketerId); - var ticket = Cache.Tickets.GetCached(balance.TicketId); - var account = await Cache.Accounts.GetAsync(balance.AccountId); - - var ticketIdentity = JsonSerializer.Serialize(new - { - ticketer = ticketer.Address, - content_type = Micheline.FromBytes(ticket.RawType), - content = Micheline.FromBytes(ticket.RawContent) - }); - - if (BigInteger.TryParse((await Rpc.GetTicketBalance(level, account.Address, ticketIdentity)).RequiredString(), out var remoteBalance)) - { - if (remoteBalance != balance.Balance) - throw new Exception($"Diagnostics failed: wrong ticket balance for {account.Address}"); - } - else - { - throw new Exception("Failed to get ticket balance"); - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Helpers.cs deleted file mode 100644 index 3a4abc5ba..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - public class Helpers(ProtocolHandler proto) : Proto13.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Proto16Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Proto16Handler.cs deleted file mode 100644 index 6294e79e1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Proto16Handler.cs +++ /dev/null @@ -1,513 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto16; - -namespace Tzkt.Sync.Protocols -{ - class Proto16Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "mumbai_016"; - public override int VersionNumber => 16; - - public Proto16Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preendorsement": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - case "double_preendorsement_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - var ticketsCommit = new TicketsCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - if (parent.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, parent.Transaction, parent.TicketUpdates); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "tx_rollup_origination": - await new TxRollupOriginationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_submit_batch": - await new TxRollupSubmitBatchCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_commit": - await new TxRollupCommitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_finalize_commitment": - await new TxRollupFinalizeCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_remove_commitment": - await new TxRollupRemoveCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_return_bond": - await new TxRollupReturnBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_rejection": - await new TxRollupRejectionCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_dispatch_tickets": - await new TxRollupDispatchTicketsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (parent1.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, parent1.Operation, parent1.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - new InboxCommit(this).Apply(blockCommit.Block); - - await bigMapCommit.Apply(); - await ticketsCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - new FreezerCommit(this).Revert(); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new TicketsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TxRollupOriginationOperation op: - await new TxRollupOriginationCommit(this).Revert(currBlock, op); - break; - case TxRollupSubmitBatchOperation op: - await new TxRollupSubmitBatchCommit(this).Revert(currBlock, op); - break; - case TxRollupCommitOperation op: - await new TxRollupCommitCommit(this).Revert(currBlock, op); - break; - case TxRollupFinalizeCommitmentOperation op: - await new TxRollupFinalizeCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupRemoveCommitmentOperation op: - await new TxRollupRemoveCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupReturnBondOperation op: - await new TxRollupReturnBondCommit(this).Revert(currBlock, op); - break; - case TxRollupRejectionOperation op: - await new TxRollupRejectionCommit(this).Revert(currBlock, op); - break; - case TxRollupDispatchTicketsOperation op: - await new TxRollupDispatchTicketsCommit(this).Revert(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Rpc/Rpc.cs deleted file mode 100644 index ae4c0bf0d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Rpc/Rpc.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto16 -{ - class Rpc : Proto12.Rpc - { - public Rpc(TezosNode node) : base(node) { } - - public override Task GetTicketBalance(int level, string address, string ticket) - { - return address.StartsWith("sr1") - ? Node.PostAsync($"chains/main/blocks/{level}/context/smart_rollups/smart_rollup/{address}/ticket_balance", ticket) - : Node.PostAsync($"chains/main/blocks/{level}/context/contracts/{address}/ticket_balance", ticket); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto16/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto16/Validation/Validator.cs deleted file mode 100644 index 4051e3f98..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto16/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto16 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Activation/ProtoActivator.cs deleted file mode 100644 index 672993ae5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Activation/ProtoActivator.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto17 -{ - partial class ProtoActivator : Proto15.ProtoActivator - { - public ProtoActivator(ProtocolHandler proto) : base(proto) { } - - protected override async Task ActivateContext(AppState state) - { - await base.ActivateContext(state); - new InboxCommit(Proto).Init(Cache.Blocks.Current()); - } - - protected override async Task DeactivateContext(AppState state) - { - await base.DeactivateContext(state); - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "InboxMessages" - """); - Cache.AppState.Get().InboxMessageCounter = 0; - } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.SmartRollupOriginationSize = parameters["smart_rollup_origination_size"]?.Value() ?? 6_314; - protocol.SmartRollupStakeAmount = long.Parse(parameters["smart_rollup_stake_amount"]?.Value() ?? "10000000000"); - protocol.SmartRollupChallengeWindow = parameters["smart_rollup_challenge_window_in_blocks"]?.Value() ?? 80_640; - protocol.SmartRollupCommitmentPeriod = parameters["smart_rollup_commitment_period_in_blocks"]?.Value() ?? 60; - protocol.SmartRollupTimeoutPeriod = parameters["smart_rollup_timeout_period_in_blocks"]?.Value() ?? 40_320; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - // nothing to upgrade - } - - protected override Task MigrateContext(AppState state) - { - // nothing to migrate - return Task.CompletedTask; - } - - protected override Task RevertContext(AppState state) - { - // nothing to revert - return Task.CompletedTask; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/AttestationRewardCommit.cs deleted file mode 100644 index 4c13d54a4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class AttestationRewardCommit : Proto12.AttestationRewardCommit - { - public AttestationRewardCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BakerCycleCommit.cs deleted file mode 100644 index 207e4a721..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class BakerCycleCommit : Proto12.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BakingRightsCommit.cs deleted file mode 100644 index e0c862b5c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class BakingRightsCommit : Proto16.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BigMapCommit.cs deleted file mode 100644 index 7f921d48b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BlockCommit.cs deleted file mode 100644 index 409d628e6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class BlockCommit : Proto13.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/ContractEventCommit.cs deleted file mode 100644 index a38e6176d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class ContractEventCommit : Proto14.ContractEventCommit - { - public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/CycleCommit.cs deleted file mode 100644 index 146f83f4a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class CycleCommit : Proto14.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/DeactivationCommit.cs deleted file mode 100644 index 0a9a2935f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 70d66a81b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/FreezerCommit.cs deleted file mode 100644 index 85140de85..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class FreezerCommit : Proto12.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/InboxCommit.cs deleted file mode 100644 index 46d858d26..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/InboxCommit.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto17 -{ - public class InboxCommit : Proto16.InboxCommit - { - public InboxCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override void WriteMigrationMessage(NpgsqlBinaryImporter writer, Block block, ref int index) - { - writer.StartRow(); - writer.Write(Cache.AppState.NextInboxMessageId(), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(block.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(index++, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)InboxMessageType.Migration, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.WriteNull(); - writer.WriteNull(); - writer.Write(Proto.VersionName, NpgsqlTypes.NpgsqlDbType.Text); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index af41c258f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 75e0cfb80..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class AttestationsCommit : Proto12.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index a33a8cda1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 85abe2e28..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class DelegationsCommit : Proto14.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index f7843de54..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class DoubleBakingCommit : Proto12.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index cdf2a55e7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class DoubleConsensusCommit : Proto12.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index c23de2983..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class DrainDelegateCommit : Proto15.DrainDelegateCommit - { - public DrainDelegateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index f39aeafe1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class IncreasePaidStorageCommit : Proto14.IncreasePaidStorageCommit - { - public IncreasePaidStorageCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 47e6911d8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class NonceRevelationsCommit : Proto12.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 0c14c0957..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class OriginationsCommit : Proto14.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index 8f1c16480..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class PreattestationsCommit : Proto12.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 782076e6d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class ProposalsCommit : Proto14.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index 22a908016..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class RegisterConstantsCommit : Proto14.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 2a7e1ed85..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class RevealsCommit : Proto14.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index 7b45474e8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index aef04099d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SmartRollupAddMessagesCommit : Proto16.SmartRollupAddMessagesCommit - { - public SmartRollupAddMessagesCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index 0c6287cbc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SmartRollupCementCommit : Proto16.SmartRollupCementCommit - { - public SmartRollupCementCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override string? GetCommitment(JsonElement content) - => content.Required("metadata").Required("operation_result").OptionalString("commitment_hash"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index 0a8521726..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SmartRollupExecuteCommit : Proto16.SmartRollupExecuteCommit - { - public SmartRollupExecuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index 221b10a9a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SmartRollupOriginateCommit : Proto16.SmartRollupOriginateCommit - { - public SmartRollupOriginateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index 855327f56..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SmartRollupPublishCommit : Proto16.SmartRollupPublishCommit - { - public SmartRollupPublishCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index f0df50039..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SmartRollupRecoverBondCommit : Proto16.SmartRollupRecoverBondCommit - { - public SmartRollupRecoverBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index 8d236ad0f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SmartRollupRefuteCommit : Proto16.SmartRollupRefuteCommit - { - public SmartRollupRefuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index 38682bbcd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SmartRollupTimeoutCommit : Proto16.SmartRollupTimeoutCommit - { - public SmartRollupTimeoutCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 77c2f248a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TransactionsCommit : Proto14.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index e5e158680..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupCommitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupCommitCommit.cs deleted file mode 100644 index 4a15713dd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupCommitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TxRollupCommitCommit : Proto13.TxRollupCommitCommit - { - public TxRollupCommitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupDispatchTicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupDispatchTicketsCommit.cs deleted file mode 100644 index c39d72335..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupDispatchTicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TxRollupDispatchTicketsCommit : Proto13.TxRollupDispatchTicketsCommit - { - public TxRollupDispatchTicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs deleted file mode 100644 index b58d41dfd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupFinalizeCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TxRollupFinalizeCommitmentCommit : Proto13.TxRollupFinalizeCommitmentCommit - { - public TxRollupFinalizeCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupOriginationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupOriginationCommit.cs deleted file mode 100644 index 9778d9d87..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupOriginationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TxRollupOriginationCommit : Proto13.TxRollupOriginationCommit - { - public TxRollupOriginationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupRejectionCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupRejectionCommit.cs deleted file mode 100644 index bb6ecd093..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupRejectionCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TxRollupRejectionCommit : Proto13.TxRollupRejectionCommit - { - public TxRollupRejectionCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupRemoveCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupRemoveCommitmentCommit.cs deleted file mode 100644 index 9afb68c85..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupRemoveCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TxRollupRemoveCommitmentCommit : Proto13.TxRollupRemoveCommitmentCommit - { - public TxRollupRemoveCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupReturnBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupReturnBondCommit.cs deleted file mode 100644 index 8612ed172..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupReturnBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TxRollupReturnBondCommit : Proto13.TxRollupReturnBondCommit - { - public TxRollupReturnBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupSubmitBatchCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupSubmitBatchCommit.cs deleted file mode 100644 index e94e87080..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/TxRollupSubmitBatchCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TxRollupSubmitBatchCommit : Proto13.TxRollupSubmitBatchCommit - { - public TxRollupSubmitBatchCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index b630543ed..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class UpdateSecondaryKeyCommit : Proto15.UpdateSecondaryKeyCommit - { - public UpdateSecondaryKeyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 546f51f9a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class VdfRevelationCommit : Proto14.VdfRevelationCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index f6b7d8700..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SnapshotBalanceCommit : Proto12.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SoftwareCommit.cs deleted file mode 100644 index b33d2ee5b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/StateCommit.cs deleted file mode 100644 index 50b259833..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/StatisticsCommit.cs deleted file mode 100644 index 44c24dd17..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SubsidyCommit.cs deleted file mode 100644 index 03985aa38..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/TicketsCommit.cs deleted file mode 100644 index 4e010482c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/TicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TicketsCommit : Proto16.TicketsCommit - { - public TicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/TokensCommit.cs deleted file mode 100644 index effce0c3d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/VotingCommit.cs deleted file mode 100644 index a6aa62b29..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Diagnostics/Diagnostics.cs deleted file mode 100644 index 355aea78b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class Diagnostics : Proto16.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Helpers.cs deleted file mode 100644 index c53601e59..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - public class Helpers(ProtocolHandler proto) : Proto13.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Proto17Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Proto17Handler.cs deleted file mode 100644 index 7fcf5b60c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Proto17Handler.cs +++ /dev/null @@ -1,513 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto17; - -namespace Tzkt.Sync.Protocols -{ - class Proto17Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "nairobi_017"; - public override int VersionNumber => 17; - - public Proto17Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preendorsement": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - case "double_preendorsement_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - var ticketsCommit = new TicketsCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - if (parent.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, parent.Transaction, parent.TicketUpdates); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "tx_rollup_origination": - await new TxRollupOriginationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_submit_batch": - await new TxRollupSubmitBatchCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_commit": - await new TxRollupCommitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_finalize_commitment": - await new TxRollupFinalizeCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_remove_commitment": - await new TxRollupRemoveCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_return_bond": - await new TxRollupReturnBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_rejection": - await new TxRollupRejectionCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "tx_rollup_dispatch_tickets": - await new TxRollupDispatchTicketsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (parent1.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, parent1.Operation, parent1.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - new InboxCommit(this).Apply(blockCommit.Block); - - await bigMapCommit.Apply(); - await ticketsCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - new FreezerCommit(this).Revert(); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new TicketsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TxRollupOriginationOperation op: - await new TxRollupOriginationCommit(this).Revert(currBlock, op); - break; - case TxRollupSubmitBatchOperation op: - await new TxRollupSubmitBatchCommit(this).Revert(currBlock, op); - break; - case TxRollupCommitOperation op: - await new TxRollupCommitCommit(this).Revert(currBlock, op); - break; - case TxRollupFinalizeCommitmentOperation op: - await new TxRollupFinalizeCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupRemoveCommitmentOperation op: - await new TxRollupRemoveCommitmentCommit(this).Revert(currBlock, op); - break; - case TxRollupReturnBondOperation op: - await new TxRollupReturnBondCommit(this).Revert(currBlock, op); - break; - case TxRollupRejectionOperation op: - await new TxRollupRejectionCommit(this).Revert(currBlock, op); - break; - case TxRollupDispatchTicketsOperation op: - await new TxRollupDispatchTicketsCommit(this).Revert(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Rpc/Rpc.cs deleted file mode 100644 index 1f9b57fca..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto17 -{ - class Rpc : Proto16.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto17/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto17/Validation/Validator.cs deleted file mode 100644 index f8be97516..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto17/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto17 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Activation/ProtoActivator.cs deleted file mode 100644 index 19b44747b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Activation/ProtoActivator.cs +++ /dev/null @@ -1,433 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto17.ProtoActivator(proto) - { - protected override async Task> BootstrapAccounts(Protocol protocol, JToken parameters) - { - var accounts = await base.BootstrapAccounts(protocol, parameters); - - var bakers = accounts - .Where(x => x is Data.Models.Delegate) - .Select(x => (x as Data.Models.Delegate)!); - - Cache.Statistics.Current.TotalFrozen = 0; - - await new StakingUpdateCommit(Proto).Apply([..bakers - .Where(x => x.TotalDelegated >= protocol.MinimalStake) - .Select(x => new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = 1, - Cycle = 0, - BakerId = x.Id, - StakerId = x.Id, - Type = StakingUpdateType.Stake, - Amount = Math.Min(x.Balance, x.TotalDelegated / (protocol.MaxDelegatedOverFrozenRatio + 1)) - })]); - - foreach (var baker in bakers) - { - baker.MinTotalDelegated = baker.TotalDelegated; - baker.MinTotalDelegatedLevel = 1; - } - - return accounts; - } - - public override List BootstrapCycles(Protocol protocol, List accounts, JToken parameters) - { - var cycles = base.BootstrapCycles(protocol, accounts, parameters); - - var issuances = Proto.Rpc.GetExpectedIssuance(1).Result; - - foreach (var cycle in cycles) - { - var issuance = issuances.EnumerateArray().First(x => x.RequiredInt32("cycle") == cycle.Index); - - cycle.BlockReward = issuance.RequiredInt64("baking_reward_fixed_portion"); - cycle.BlockBonusPerBlock = GetBlockBonusPerBlock(issuance, protocol); - cycle.AttestationRewardPerBlock = GetAttestationRewardPerBlock(issuance, protocol); - cycle.NonceRevelationReward = issuance.RequiredInt64("seed_nonce_revelation_tip"); - cycle.VdfRevelationReward = issuance.RequiredInt64("vdf_revelation_tip"); - cycle.DalAttestationRewardPerShard = GetDalAttestationRewardPerShard(issuance); - } - - return cycles; - } - - protected virtual long GetBlockBonusPerBlock(JsonElement issuance, Protocol protocol) - => issuance.RequiredInt64("baking_reward_bonus_per_slot") * (protocol.AttestersPerBlock - protocol.ConsensusThreshold); - - protected virtual long GetAttestationRewardPerBlock(JsonElement issuance, Protocol protocol) - => issuance.RequiredInt64("attesting_reward_per_slot") * protocol.AttestersPerBlock; - - protected virtual long GetDalAttestationRewardPerShard(JsonElement issuance) => 0; - - public override void BootstrapBakerCycles( - Protocol protocol, - List accounts, - List cycles, - List> bakingRights, - List> attestationRights) - { - var bakers = accounts - .Where(x => x.Type == AccountType.Delegate) - .Select(x => (x as Data.Models.Delegate)!); - - foreach (var cycle in cycles) - { - var attestationRewardPerSlot = cycle.AttestationRewardPerBlock / protocol.AttestersPerBlock; - var maxBlockReward = cycle.BlockReward + cycle.BlockBonusPerBlock; - - var bakerCycles = bakers.ToDictionary(x => x.Id, x => - { - var bakerCycle = new BakerCycle - { - Id = 0, - Cycle = cycle.Index, - BakerId = x.Id, - OwnDelegatedBalance = x.Balance - x.OwnStakedBalance, - ExternalDelegatedBalance = x.ExternalDelegatedBalance, - DelegatorsCount = x.DelegatorsCount, - OwnStakedBalance = x.OwnStakedBalance, - ExternalStakedBalance = x.ExternalStakedBalance, - StakersCount = x.StakersCount, - IssuedPseudotokens = x.IssuedPseudotokens, - BakingPower = x.BakingPower, - TotalBakingPower = cycle.TotalBakingPower - }; - if (x.BakingPower != 0) - { - var expectedAttestations = (protocol.BlocksPerCycle * protocol.AttestersPerBlock).MulRatio(x.BakingPower, cycle.TotalBakingPower); - var expectedDalAttestations = (protocol.BlocksPerCycle * protocol.NumberOfShards).MulRatio(x.BakingPower, cycle.TotalBakingPower); - bakerCycle.BakingPower = x.BakingPower; - bakerCycle.ExpectedBlocks = protocol.BlocksPerCycle.MulRatio(x.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = expectedAttestations * attestationRewardPerSlot; - bakerCycle.ExpectedDalAttestations = expectedDalAttestations; - bakerCycle.FutureDalAttestationRewards = expectedDalAttestations * cycle.DalAttestationRewardPerShard; - } - return bakerCycle; - }); - - #region future baking rights - foreach (var br in bakingRights[cycle.Index].SkipWhile(x => x.Level == 1).Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Unknown baking right recipient"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += maxBlockReward; - } - #endregion - - #region future attestation rights - foreach (var ar in attestationRights[cycle.Index].TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Unknown attestation right recipient"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - #region shifted future endirsing rights - if (cycle.Index > 0) - { - foreach (var ar in attestationRights[cycle.Index - 1].Reverse().TakeWhile(x => x.Level == cycle.FirstLevel - 1)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Unknown attestation right recipient"); - - bakerCycle.FutureAttestations += ar.Slots; - } - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - } - } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.MinimalFrozenStake = parameters["minimal_frozen_stake"]?.Value() ?? 600_000_000; - protocol.MaxDelegatedOverFrozenRatio = parameters["limit_of_delegation_over_baking"]?.Value() ?? 9; - protocol.MaxExternalOverOwnStakeRatio = parameters["global_limit_of_staking_over_baking"]?.Value() ?? 5; - protocol.StakePowerMultiplier = parameters["edge_of_staking_over_delegation"]?.Value() ?? 2; - - protocol.DoubleBakingSlashedPercentage = (parameters["percentage_of_frozen_deposits_slashed_per_double_baking"]?.Value() ?? 5) * 100; - protocol.DoubleConsensusSlashedPercentage = (parameters["percentage_of_frozen_deposits_slashed_per_double_attestation"]?.Value() ?? 50) * 100; - - protocol.DelegateParametersActivationDelay = protocol.ConsensusRightsDelay; - - protocol.BlockDeposit = 0; - protocol.BlockReward0 = 0; - protocol.BlockReward1 = 0; - protocol.MaxBakingReward = 0; - protocol.AttestationDeposit = 0; - protocol.AttestationReward0 = 0; - protocol.AttestationReward1 = 0; - protocol.MaxAttestationReward = 0; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.MinimalFrozenStake = 600_000_000; - protocol.MaxDelegatedOverFrozenRatio = 9; - protocol.MaxExternalOverOwnStakeRatio = 5; - protocol.StakePowerMultiplier = 2; - - protocol.DoubleBakingSlashedPercentage = 500; - protocol.DoubleConsensusSlashedPercentage = 5000; - - protocol.DelegateParametersActivationDelay = protocol.ConsensusRightsDelay; - - protocol.BlockDeposit = 0; - protocol.BlockReward0 = 0; - protocol.BlockReward1 = 0; - protocol.MaxBakingReward = 0; - protocol.AttestationDeposit = 0; - protocol.AttestationReward0 = 0; - protocol.AttestationReward1 = 0; - protocol.MaxAttestationReward = 0; - } - - protected override async Task MigrateContext(AppState state) - { - await RemoveDeadRefutationGames(state); - await RemoveBigmapKeys(state); - await MigrateBakers(state); - await MigrateCycles(state); - } - - protected async Task RemoveDeadRefutationGames(AppState state) - { - var activeGames = await Db.RefutationGames - .AsNoTracking() - .Where(x => - x.InitiatorReward == null && - x.InitiatorLoss == null && - x.OpponentReward == null && - x.OpponentLoss == null) - .ToListAsync(); - - foreach (var game in activeGames) - { - var initiatorBond = await Db.SmartRollupPublishOps - .AsNoTracking() - .Where(x => - x.SmartRollupId == game.SmartRollupId && - x.BondStatus == SmartRollupBondStatus.Active && - x.SenderId == game.InitiatorId) - .FirstOrDefaultAsync(); - - if (initiatorBond != null) - continue; - - var opponentBond = await Db.SmartRollupPublishOps - .AsNoTracking() - .Where(x => - x.SmartRollupId == game.SmartRollupId && - x.BondStatus == SmartRollupBondStatus.Active && - x.SenderId == game.OpponentId) - .FirstOrDefaultAsync(); - - if (opponentBond != null) - continue; - - Db.TryAttach(game); - game.LastLevel = state.Level; - game.InitiatorReward = 0; - game.InitiatorLoss = 0; - game.OpponentReward = 0; - game.OpponentLoss = 0; - - var initiator = await Cache.Accounts.GetAsync(game.InitiatorId); - Db.TryAttach(initiator); - initiator.ActiveRefutationGamesCount--; - - var opponent = await Cache.Accounts.GetAsync(game.OpponentId); - Db.TryAttach(opponent); - opponent.ActiveRefutationGamesCount--; - - var rollup = await Cache.Accounts.GetAsync(game.SmartRollupId); - Db.TryAttach(rollup); - rollup.ActiveRefutationGamesCount--; - } - } - - async Task RemoveBigmapKeys(AppState state) - { - var keyHashes = new HashSet - { - "exprtXBtxJxCDEDETueKAFLL7r7vZtNEo1MHajpHba1djtGKqJzWd3", - "exprtbuRhaGDS942BgZ1qFdD7HAKeBjPEqzRxgLQyWQ6HWxcaiLC2c", - "exprtePxSLgrhJmTPZEePyFBmESLhaBUN1WodvLYy9xYhEYE6dKPLe", - "exprtx9GaYz5Fy5ytiuYgSfJqeYqkxGgobust8U6dpCLaeZUMiitmg", - "expru28t4XoyB61WuRQnExk3Kq8ssGv1ejgdo9XHxpTXoQjXTGw1Dg", - "expru2fZALknjB4vJjmQBPkrs3dJZ5ytuzfmE9A7ScUk5opJiZQyiJ", - "expru2riAFKURjHJ1vNpvsZGGw6z4wtTvbstXVuwQPj1MaTqKPeQ6z", - "expruHoZDr8ioVhaAs495crYTprAYyC87CruEJ6HaS7diYV6qLARqQ", - "expruMie2gfy5smMd81NtcvvWm4jD7ThUebw9hpF3N3apKVtxkVG9M", - "expruc3QW7cdxrGurDJQa6k9QqMZjGkRDJahy2XNtBt9WQzC1yavJK", - "exprud86wYL7inFCVHkF1Jcz8uMXVY7dnbzxVupyyknZjtDVmwoQTJ", - "exprufYzeBTGn9733Ga8xEEmU4SsrSyDrzEip8V8hTBAG253T5zZQx", - "exprum9tuHNvisMa3c372AFmCa27rmkbCGrhzMSprrxgJjzXhrKAag", - "expruokt7oQ6dDHRvL4sURKUzfwJirR8FPHvpXwjgUD4KHhPWhDGbv", - "expruom5ds2hVgjdTB877Fx3ZuWT5WUnw1H6kUZavVHcJFbCkcgo3x", - "exprv2DPd1pV3GVSN2CgW7PPrAQUTuZAdeJphwToQrTNrxiJcWzvtX", - "exprv65Czv5TnKyEWgBHjDztkCkc1FAVEPxZ3V3ocgvGjfXwjPLo8M", - "exprv6S2KAvqAC18jDLYjaj1w9oc4ESdDGJkUZ63EpkqSTAz88cSYB", - "exprvNg3VDBnhtTHvc75krAEYzz6vUMr3iU5jtLdxs83FbgTbZ9nFT", - "exprvS7wNDHYKYZ19nj3ZUo7AAVMCDpTK3NNERFhqe5SJGCBL4pwFA" - }; - - var valueType = new MichelinePrim - { - Prim = PrimType.pair, - Args = - [ - new MichelinePrim - { - Prim = PrimType.timestamp - }, - new MichelinePrim - { - Prim = PrimType.ticket, - Args = - [ - new MichelinePrim - { - Prim = PrimType.@string, - Annots = - [ - new FieldAnnotation("data") - ] - } - ] - } - ] - }; - - var bigmap = await Db.BigMaps - .FirstOrDefaultAsync(x => x.Ptr == 5696); - - if (bigmap?.ValueType.IsEqual(valueType.ToBytes()) != true) - return; - - Db.TryAttach(state); - - var block = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(block); - - var contract = await Cache.Accounts.GetAsync(bigmap.ContractId); - Db.TryAttach(contract); - - var keys = await Db.BigMapKeys - .Where(x => x.BigMapPtr == bigmap.Ptr && x.Active && keyHashes.Contains(x.KeyHash)) - .ToListAsync(); - - foreach (var key in keys) - { - var value = Micheline.FromBytes(key.RawValue); - if (((((value as MichelinePrim)!.Args![1] as MichelinePrim)!.Args![1] as MichelinePrim)!.Args![1] as MichelineInt)!.Value == BigInteger.Zero) - { - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - AccountId = contract.Id, - BigMapUpdates = 1, - Kind = MigrationKind.RemoveBigMapKey, - Level = block.Level, - Timestamp = block.Timestamp - }; - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - block.Operations |= Operations.Migrations; - - contract.MigrationsCount++; - contract.LastLevel = migration.Level; - - state.MigrationOpsCount++; - - var update = new BigMapUpdate - { - Id = Cache.AppState.NextBigMapUpdateId(), - Action = BigMapAction.RemoveKey, - BigMapKeyId = key.Id, - BigMapPtr = bigmap.Ptr, - JsonValue = key.JsonValue, - Level = block.Level, - MigrationId = migration.Id, - RawValue = key.RawValue - }; - Db.BigMapUpdates.Add(update); - - key.Active = false; - key.LastLevel = block.Level; - key.Updates++; - - bigmap.ActiveKeys--; - bigmap.LastLevel = block.Level; - bigmap.Updates++; - } - } - } - - async Task MigrateBakers(AppState state) - { - UpdateBakersPower(); - - var stakes = (await Proto.Node.GetAsync($"chains/main/blocks/{state.Level}/context/raw/json/staking_balance/current?depth=1")) - .EnumerateArray() - .ToDictionary( - x => x.EnumerateArray().First().RequiredString(), - x => x.EnumerateArray().Last().RequiredInt64("own_frozen")); - - var bakers = stakes - .Where(x => x.Value > 0) - .Select(x => Cache.Accounts.GetExistingDelegate(x.Key)); - - Cache.Statistics.Current.TotalFrozen = 0; - - await new StakingUpdateCommit(Proto).Apply([..bakers.Select(x => new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = state.Level, - Cycle = state.Cycle, - BakerId = x.Id, - StakerId = x.Id, - Type = StakingUpdateType.Stake, - Amount = stakes[x.Address] - })]); - } - - async Task MigrateCycles(AppState state) - { - var issuances = await Proto.Rpc.GetExpectedIssuance(state.Level); - var protocol = await Cache.Protocols.GetAsync(state.NextProtocol); - var cycles = await Db.Cycles.Where(x => x.Index > state.Cycle).ToListAsync(); - foreach (var cycle in cycles) - { - var issuance = issuances.EnumerateArray().First(x => x.RequiredInt32("cycle") == cycle.Index); - - cycle.BlockReward = issuance.RequiredInt64("baking_reward_fixed_portion"); - cycle.BlockBonusPerBlock = GetBlockBonusPerBlock(issuance, protocol); - cycle.AttestationRewardPerBlock = GetAttestationRewardPerBlock(issuance, protocol); - cycle.NonceRevelationReward = issuance.RequiredInt64("seed_nonce_revelation_tip"); - cycle.VdfRevelationReward = issuance.RequiredInt64("vdf_revelation_tip"); - cycle.DalAttestationRewardPerShard = GetDalAttestationRewardPerShard(issuance); - } - - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/AttestationRewardCommit.cs deleted file mode 100644 index ae5200ab7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class AttestationRewardCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement rawBlock) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - var state = Cache.AppState.Get(); - var bakerCycles = await Cache.BakerCycles.GetAsync(block.Cycle); - var ops = bakerCycles - .Where(x => x.Value.FutureAttestationRewards > 0) - .ToDictionary( - x => x.Key, - bakerCycle => new AttestationRewardOperation - { - Id = Cache.AppState.NextOperationId(), - BakerId = bakerCycle.Key, - Level = block.Level, - Timestamp = block.Timestamp, - Expected = bakerCycle.Value.FutureAttestationRewards - }); - - var balanceUpdates = rawBlock.Required("metadata").RequiredArray("balance_updates").EnumerateArray().Where(x => x.RequiredString("origin") == "block").ToList(); - for (int i = 0; i < balanceUpdates.Count; i++) - { - var update = balanceUpdates[i]; - if (update.RequiredString("kind") == "minted" && (update.RequiredString("category") == "endorsing rewards" || update.RequiredString("category") == "attesting rewards")) - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected attestation rewards balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredString("kind") == "freezer" && - nextUpdate.RequiredString("category") == "deposits" && - nextUpdate.RequiredInt64("change") == change) - { - var baker = Cache.Accounts.GetExistingDelegate(nextUpdate.Required("staker").RequiredString("baker")); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected attestation rewards balance update"); - - if (baker.ExternalStakedBalance != 0) - throw new Exception("Manual staking should be disabled in Oxford"); - - op.RewardStakedOwn = change; - } - else if (nextUpdate.RequiredString("kind") == "contract" && - nextUpdate.RequiredInt64("change") == change) - { - var baker = Cache.Accounts.GetExistingDelegate(nextUpdate.RequiredString("contract")); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected attestation rewards balance update"); - - op.RewardDelegated = change; - } - else if (nextUpdate.RequiredString("kind") == "burned" && - (nextUpdate.RequiredString("category") == "lost endorsing rewards" || nextUpdate.RequiredString("category") == "lost attesting rewards") && - nextUpdate.RequiredInt64("change") == change) - { - var baker = Cache.Accounts.GetExistingDelegate(nextUpdate.RequiredString("delegate")); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected attestation rewards balance update"); - - if (op.Expected != change) - throw new Exception("FutureAttestationRewards != loss"); - - op.RewardDelegated = 0; - op.RewardStakedOwn = 0; - op.RewardStakedEdge = 0; - op.RewardStakedShared = 0; - } - else - { - throw new Exception("Unexpected attestation rewards balance updates behavior"); - } - } - } - - foreach (var op in ops.Values) - { - var bakerCycle = bakerCycles[op.BakerId]; - Db.TryAttach(bakerCycle); - - bakerCycle.FutureAttestationRewards = 0; - if (op.RewardDelegated != 0 || op.RewardStakedOwn != 0 || op.RewardStakedEdge != 0 || op.RewardStakedShared != 0) - { - if (op.Expected != op.RewardDelegated + op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared) - throw new Exception("ExpectedReward != RewardFrozen + RewardDelegated"); - - bakerCycle.AttestationRewardsDelegated = op.RewardDelegated; - bakerCycle.AttestationRewardsStakedOwn = op.RewardStakedOwn; - bakerCycle.AttestationRewardsStakedEdge = op.RewardStakedEdge; - bakerCycle.AttestationRewardsStakedShared = op.RewardStakedShared; - } - else - { - bakerCycle.MissedAttestationRewards = op.Expected; - } - - - var baker = Cache.Accounts.GetDelegate(op.BakerId); - Db.TryAttach(baker); - - ReceiveRewards(baker, op.RewardDelegated, op.RewardStakedOwn, op.RewardStakedEdge, op.RewardStakedShared); - baker.AttestationRewardsCount++; - - block.Operations |= Operations.AttestationRewards; - - Cache.Statistics.Current.TotalCreated += op.RewardDelegated + op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared; - Cache.Statistics.Current.TotalFrozen += op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared; - } - - Cache.AppState.Get().AttestationRewardOpsCount += ops.Count; - - Db.AttestationRewardOps.AddRange(ops.Values); - Context.AttestationRewardOps.AddRange(ops.Values); - } - - public virtual async Task Revert(Block block) - { - if (!block.Operations.HasFlag(Operations.AttestationRewards)) - return; - - var ops = await Db.AttestationRewardOps.Where(x => x.Level == block.Level).ToListAsync(); - - foreach (var op in ops) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureAttestationRewards = op.Expected; - bakerCycle.MissedAttestationRewards = 0; - bakerCycle.AttestationRewardsDelegated = 0; - bakerCycle.AttestationRewardsStakedOwn = 0; - bakerCycle.AttestationRewardsStakedEdge = 0; - bakerCycle.AttestationRewardsStakedShared = 0; - - var baker = Cache.Accounts.GetDelegate(op.BakerId); - Db.TryAttach(baker); - - RevertReceiveRewards(baker, op.RewardDelegated, op.RewardStakedOwn, op.RewardStakedEdge, op.RewardStakedShared); - baker.AttestationRewardsCount--; - } - - Cache.AppState.Get().AttestationRewardOpsCount -= ops.Count; - - Db.AttestationRewardOps.RemoveRange(ops); - Cache.AppState.ReleaseOperationId(ops.Count); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/AutostakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/AutostakingCommit.cs deleted file mode 100644 index 4579c4e5e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/AutostakingCommit.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class AutostakingCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement rawBlock) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - var balanceUpdates = rawBlock - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .Where(x => x.RequiredString("origin") == "block") - .ToList(); - - var updates = ParseStakingUpdates(block, balanceUpdates); - - if (updates.Count > 0) - { - Db.TryAttach(block); - block.Operations |= Operations.Autostaking; - - var state = Cache.AppState.Get(); - Db.TryAttach(state); - - foreach (var group in updates.GroupBy(x => x.BakerId)) - { - var staked = group.Where(x => x.Type == StakingUpdateType.Stake || x.Type == StakingUpdateType.Restake).Sum(x => x.Amount); - var unstaked = group.Where(x => x.Type == StakingUpdateType.Unstake).Sum(x => x.Amount); - var finalized = group.Where(x => x.Type == StakingUpdateType.Finalize).Sum(x => x.Amount); - - var operation = new AutostakingOperation - { - Id = Cache.AppState.NextOperationId(), - Level = group.First().Level, - Timestamp = block.Timestamp, - Action = staked != 0 ? StakingAction.Stake : unstaked != 0 ? StakingAction.Unstake : StakingAction.Finalize, - Amount = staked != 0 ? staked : unstaked != 0 ? unstaked : finalized, - BakerId = group.Key, - StakingUpdatesCount = group.Count() - }; - - foreach (var update in group) - update.AutostakingOpId = operation.Id; - - var baker = Cache.Accounts.GetDelegate(group.Key); - Db.TryAttach(baker); - baker.AutostakingOpsCount++; - baker.LastLevel = block.Level; - - state.AutostakingOpsCount++; - - Db.AutostakingOps.Add(operation); - Context.AutostakingOps.Add(operation); - } - - await new StakingUpdateCommit(Proto).Apply(updates); - } - } - - public virtual async Task Revert(Block block) - { - if (!block.Operations.HasFlag(Operations.Autostaking)) - return; - - var state = Cache.AppState.Get(); - Db.TryAttach(state); - - foreach (var op in await Db.AutostakingOps.Where(x => x.Level == block.Level).ToListAsync()) - { - var baker = Cache.Accounts.GetDelegate(op.BakerId); - Db.TryAttach(baker); - baker.AutostakingOpsCount--; - - state.AutostakingOpsCount--; - - Db.AutostakingOps.Remove(op); - Cache.AppState.ReleaseOperationId(); - } - - var updates = await Db.StakingUpdates - .Where(x => x.Level == block.Level && x.AutostakingOpId != null) - .OrderByDescending(x => x.Id) - .ToListAsync(); - - await new StakingUpdateCommit(Proto).Revert(updates); - } - - protected virtual List ParseStakingUpdates(Block block, List balanceUpdates) - { - var res = new List(); - - if (balanceUpdates.Count % 2 != 0) - throw new Exception("Unexpected autostaking balance updates behavior"); - - for (int i = 0; i < balanceUpdates.Count; i += 2) - { - var update = balanceUpdates[i]; - var kind = update.RequiredString("kind"); - var category = update.OptionalString("category"); - - var nextUpdate = balanceUpdates[i + 1]; - var nextKind = nextUpdate.RequiredString("kind"); - var nextCategory = nextUpdate.OptionalString("category"); - - if (kind == "contract") - { - if (nextKind != "freezer" || nextCategory != "deposits") - throw new Exception("Unexpected autostaking balance updates behavior"); - - #region stake - var baker = GetFreezerBaker(nextUpdate); - var change = nextUpdate.RequiredInt64("change"); - - if (baker != update.RequiredString("contract") || - change != -update.RequiredInt64("change")) - throw new Exception("Unexpected autostaking balance updates behavior"); - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = block.Cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - Type = StakingUpdateType.Stake, - Amount = change - }); - #endregion - } - else if (kind == "freezer" && category == "deposits") - { - if (nextKind == "freezer" && nextCategory == "unstaked_deposits") - { - #region unstake - var baker = nextUpdate.Required("staker").RequiredString("delegate"); - var staker = nextUpdate.Required("staker").RequiredString("contract"); - var change = nextUpdate.RequiredInt64("change"); - var cycle = nextUpdate.RequiredInt32("cycle"); - - if (baker != staker || - baker != GetFreezerBaker(update) || - change != -update.RequiredInt64("change")) - throw new Exception("Unexpected autostaking balance updates behavior"); - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = Cache.Accounts.GetExistingDelegate(staker).Id, - Type = StakingUpdateType.Unstake, - Amount = change - }); - #endregion - } - else - { - throw new Exception("Unexpected autostaking balance updates behavior"); - } - } - else if (kind == "freezer" && category == "unstaked_deposits") - { - if (nextKind == "contract") - { - var baker = update.Required("staker").RequiredString("delegate"); - var staker = update.Required("staker").RequiredString("contract"); - var change = nextUpdate.RequiredInt64("change"); - var cycle = update.RequiredInt32("cycle"); - - #region finalize - if (baker != staker || - baker != nextUpdate.RequiredString("contract") || - change != -update.RequiredInt64("change")) - throw new Exception("Unexpected autostaking balance updates behavior"); - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = Cache.Accounts.GetExistingDelegate(staker).Id, - Type = StakingUpdateType.Finalize, - Amount = change - }); - #endregion - } - else if (nextKind == "freezer" && nextCategory == "deposits") - { - var baker = update.Required("staker").RequiredString("delegate"); - var staker = update.Required("staker").RequiredString("contract"); - var change = nextUpdate.RequiredInt64("change"); - var cycle = update.RequiredInt32("cycle"); - - #region restake - if (baker != staker || - baker != GetFreezerBaker(nextUpdate) || - change != -update.RequiredInt64("change")) - throw new Exception("Unexpected autostaking balance updates behavior"); - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = Cache.Accounts.GetExistingDelegate(staker).Id, - Type = StakingUpdateType.Restake, - Amount = change - }); - #endregion - } - else - { - throw new Exception("Unexpected autostaking balance updates behavior"); - } - } - else if (kind != "accumulator" && kind != "minted") - { - throw new Exception("Unexpected autostaking balance updates behavior"); - } - } - - return res; - } - - protected virtual string GetFreezerBaker(JsonElement update) - { - return update.Required("staker").RequiredString("baker"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BakerCycleCommit.cs deleted file mode 100644 index 38c3846c5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,358 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class BakerCycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply( - Block block, - Cycle? futureCycle, - IEnumerable? futureBakingRights, - IEnumerable? futureAttestationRights, - List? snapshots, - Dictionary? selectedStakes, - List currentRights) - { - await ApplyCurrentRights(block, currentRights); - - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - await ApplyNewCycle(block, futureCycle!, futureBakingRights!, futureAttestationRights!, snapshots!, selectedStakes!); - } - - protected async Task ApplyCurrentRights( - Block block, - List currentRights) - { - if (block.BlockRound == 0) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, block.ProposerId!.Value); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlockRewards -= bakerCycle.FutureBlockRewards / bakerCycle.FutureBlocks; - bakerCycle.FutureBlocks--; - bakerCycle.Blocks++; - bakerCycle.BlockRewardsDelegated += block.RewardDelegated + block.BonusDelegated; - bakerCycle.BlockRewardsStakedOwn += block.RewardStakedOwn + block.BonusStakedOwn; - bakerCycle.BlockRewardsStakedEdge += block.RewardStakedEdge + block.BonusStakedEdge; - bakerCycle.BlockRewardsStakedShared += block.RewardStakedShared + block.BonusStakedShared; - bakerCycle.BlockFees += block.Fees; - } - else - { - var set = new HashSet(); - foreach (var br in currentRights.Where(x => x.Type == BakingRightType.Baking).OrderBy(x => x.Round)) - { - if (set.Add(br.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, br.BakerId); - Db.TryAttach(bakerCycle); - - if (br.Round == 0) - { - bakerCycle.FutureBlockRewards -= bakerCycle.FutureBlockRewards / bakerCycle.FutureBlocks; - bakerCycle.FutureBlocks--; - } - - if (br.BakerId == block.ProposerId || br.BakerId == block.ProducerId) - { - bakerCycle.Blocks++; - } - else - { - bakerCycle.MissedBlocks++; - } - - if (br.BakerId == block.ProposerId) - { - bakerCycle.BlockRewardsDelegated += block.RewardDelegated; - bakerCycle.BlockRewardsStakedOwn += block.RewardStakedOwn; - bakerCycle.BlockRewardsStakedEdge += block.RewardStakedEdge; - bakerCycle.BlockRewardsStakedShared += block.RewardStakedShared; - bakerCycle.BlockFees += block.Fees; - } - else if (br.Round < block.PayloadRound) - { - bakerCycle.MissedBlockRewards += block.RewardDelegated + block.RewardStakedOwn + block.RewardStakedEdge + block.RewardStakedShared; - bakerCycle.MissedBlockFees += block.Fees; - } - - if (br.BakerId == block.ProducerId) - { - bakerCycle.BlockRewardsDelegated += block.BonusDelegated; - bakerCycle.BlockRewardsStakedOwn += block.BonusStakedOwn; - bakerCycle.BlockRewardsStakedEdge += block.BonusStakedEdge; - bakerCycle.BlockRewardsStakedShared += block.BonusStakedShared; - } - else - { - bakerCycle.MissedBlockRewards += block.BonusDelegated + block.BonusStakedOwn + block.BonusStakedEdge + block.BonusStakedShared; - } - } - } - } - - foreach (var ar in currentRights.Where(x => x.Type == BakingRightType.Attestation)) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, ar.BakerId); - if (bakerCycle == null) continue; - - Db.TryAttach(bakerCycle); - bakerCycle.FutureAttestations -= ar.Slots!.Value; - if (ar.Status == BakingRightStatus.Realized) - bakerCycle.Attestations += ar.Slots.Value; - else if (ar.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestations += ar.Slots.Value; - else - throw new Exception("Unexpected future rights"); - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.BakerId); - if (bakerCycle != null) - { - Db.TryAttach(bakerCycle); - bakerCycle.NonceRevelationRewardsDelegated += op.RewardDelegated; - bakerCycle.NonceRevelationRewardsStakedOwn += op.RewardStakedOwn; - bakerCycle.NonceRevelationRewardsStakedEdge += op.RewardStakedEdge; - bakerCycle.NonceRevelationRewardsStakedShared += op.RewardStakedShared; - } - } - - foreach (var op in Context.VdfRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.VdfRevelationRewardsDelegated += op.RewardDelegated; - bakerCycle.VdfRevelationRewardsStakedOwn += op.RewardStakedOwn; - bakerCycle.VdfRevelationRewardsStakedEdge += op.RewardStakedEdge; - bakerCycle.VdfRevelationRewardsStakedShared += op.RewardStakedShared; - } - } - - protected virtual async Task ApplyNewCycle( - Block block, - Cycle futureCycle, - IEnumerable futureBakingRights, - IEnumerable futureAttestationRights, - List snapshots, - Dictionary selectedStakes) - { - var maxBlockReward = futureCycle.BlockReward + futureCycle.BlockBonusPerBlock; - - var bakerCycles = snapshots.ToDictionary(x => x.AccountId, snapshot => - { - var bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = snapshot.AccountId, - OwnDelegatedBalance = snapshot.OwnDelegatedBalance, - ExternalDelegatedBalance = snapshot.ExternalDelegatedBalance!.Value, - DelegatorsCount = snapshot.DelegatorsCount!.Value, - OwnStakedBalance = snapshot.OwnStakedBalance ?? 0, - ExternalStakedBalance = snapshot.ExternalStakedBalance ?? 0, - StakersCount = snapshot.StakersCount ?? 0, - IssuedPseudotokens = snapshot.Pseudotokens, - BakingPower = 0, - TotalBakingPower = futureCycle.TotalBakingPower - }; - if (selectedStakes.TryGetValue(bakerCycle.BakerId, out var bakingPower)) - { - var expectedAttestations = (Context.Protocol.BlocksPerCycle * Context.Protocol.AttestersPerBlock).MulRatio(bakingPower, futureCycle.TotalBakingPower); - var expectedDalAttestations = (Context.Protocol.BlocksPerCycle * Context.Protocol.NumberOfShards).MulRatio(bakingPower, futureCycle.TotalBakingPower); - bakerCycle.BakingPower = bakingPower; - bakerCycle.ExpectedBlocks = Context.Protocol.BlocksPerCycle.MulRatio(bakingPower, futureCycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = GetFutureAttestationRewards(Context.Protocol, futureCycle, bakingPower); - bakerCycle.ExpectedDalAttestations = expectedDalAttestations; - bakerCycle.FutureDalAttestationRewards = expectedDalAttestations * futureCycle.DalAttestationRewardPerShard; - } - return bakerCycle; - }); - - #region future baking rights - foreach (var br in futureBakingRights.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += maxBlockReward; - } - #endregion - - #region future attestation rights - var skipLevel = futureAttestationRights.Last().Level; - foreach (var ar in futureAttestationRights.TakeWhile(x => x.Level < skipLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - #region shifted future attestation rights - var shifted = await Db.BakingRights.AsNoTracking() - .Where(x => x.Level == futureCycle.FirstLevel && x.Type == BakingRightType.Attestation) - .ToListAsync(); - - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.BakerId, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots!.Value; - } - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - } - - public virtual async Task Revert(Block block) - { - await RevertCurrentRights(block); - - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - await RevertNewCycle(block); - } - - protected async Task RevertCurrentRights(Block block) - { - var currentRights = await Cache.BakingRights.GetAsync(block.Level); - var currentCycle = await Db.Cycles.SingleAsync(x => x.Index == block.Cycle); - var maxBlockReward = currentCycle.BlockReward + currentCycle.BlockBonusPerBlock; - - if (block.BlockRound == 0) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, block.ProposerId!.Value); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlockRewards += maxBlockReward; - bakerCycle.FutureBlocks++; - bakerCycle.Blocks--; - bakerCycle.BlockRewardsDelegated -= block.RewardDelegated + block.BonusDelegated; - bakerCycle.BlockRewardsStakedOwn -= block.RewardStakedOwn + block.BonusStakedOwn; - bakerCycle.BlockRewardsStakedEdge -= block.RewardStakedEdge + block.BonusStakedEdge; - bakerCycle.BlockRewardsStakedShared -= block.RewardStakedShared + block.BonusStakedShared; - bakerCycle.BlockFees -= block.Fees; - } - else - { - var set = new HashSet(); - var bakerRound = currentRights - .Where(x => x.Type == BakingRightType.Baking) - .OrderBy(x => x.Round) - .First(x => x.Status == BakingRightStatus.Realized) - .Round; - - foreach (var br in currentRights.Where(x => x.Type == BakingRightType.Baking).OrderBy(x => x.Round)) - { - if (set.Add(br.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, br.BakerId); - Db.TryAttach(bakerCycle); - - if (br.Round == 0) - { - bakerCycle.FutureBlockRewards += maxBlockReward; - bakerCycle.FutureBlocks++; - } - - if (br.BakerId == block.ProposerId || br.BakerId == block.ProducerId) - { - bakerCycle.Blocks--; - } - else - { - bakerCycle.MissedBlocks--; - } - - if (br.BakerId == block.ProposerId) - { - bakerCycle.BlockRewardsDelegated -= block.RewardDelegated; - bakerCycle.BlockRewardsStakedOwn -= block.RewardStakedOwn; - bakerCycle.BlockRewardsStakedEdge -= block.RewardStakedEdge; - bakerCycle.BlockRewardsStakedShared -= block.RewardStakedShared; - bakerCycle.BlockFees -= block.Fees; - } - else if (br.Round < bakerRound) - { - bakerCycle.MissedBlockRewards -= block.RewardDelegated + block.RewardStakedOwn + block.RewardStakedEdge + block.RewardStakedShared; - bakerCycle.MissedBlockFees -= block.Fees; - } - - if (br.BakerId == block.ProducerId) - { - bakerCycle.BlockRewardsDelegated -= block.BonusDelegated; - bakerCycle.BlockRewardsStakedOwn -= block.BonusStakedOwn; - bakerCycle.BlockRewardsStakedEdge -= block.BonusStakedEdge; - bakerCycle.BlockRewardsStakedShared -= block.BonusStakedShared; - } - else - { - bakerCycle.MissedBlockRewards -= block.BonusDelegated + block.BonusStakedOwn + block.BonusStakedEdge + block.BonusStakedShared; - } - } - } - } - - foreach (var ar in currentRights.Where(x => x.Type == BakingRightType.Attestation)) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, ar.BakerId); - if (bakerCycle == null) continue; - - Db.TryAttach(bakerCycle); - bakerCycle.FutureAttestations += ar.Slots!.Value; - if (ar.Status == BakingRightStatus.Realized) - bakerCycle.Attestations -= ar.Slots.Value; - else if (ar.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestations -= ar.Slots.Value; - else - throw new Exception("Unexpected future rights"); - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.BakerId); - if (bakerCycle != null) - { - Db.TryAttach(bakerCycle); - bakerCycle.NonceRevelationRewardsDelegated -= op.RewardDelegated; - bakerCycle.NonceRevelationRewardsStakedOwn -= op.RewardStakedOwn; - bakerCycle.NonceRevelationRewardsStakedEdge -= op.RewardStakedEdge; - bakerCycle.NonceRevelationRewardsStakedShared -= op.RewardStakedShared; - } - } - - foreach (var op in Context.VdfRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.VdfRevelationRewardsDelegated -= op.RewardDelegated; - bakerCycle.VdfRevelationRewardsStakedOwn -= op.RewardStakedOwn; - bakerCycle.VdfRevelationRewardsStakedEdge -= op.RewardStakedEdge; - bakerCycle.VdfRevelationRewardsStakedShared -= op.RewardStakedShared; - } - } - - protected virtual async Task RevertNewCycle(Block block) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakerCycles" - WHERE "Cycle" = {0} - """, block.Cycle + Context.Protocol.ConsensusRightsDelay); - } - - protected virtual long GetFutureAttestationRewards(Protocol protocol, Cycle cycle, long bakingPower) - { - var expectedAttestations = (protocol.BlocksPerCycle * protocol.AttestersPerBlock).MulRatio(bakingPower, cycle.TotalBakingPower); - var attestationRewardPerSlot = cycle.AttestationRewardPerBlock / Context.Protocol.AttestersPerBlock; - return expectedAttestations * attestationRewardPerSlot; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BakingRightsCommit.cs deleted file mode 100644 index 1a2a89c6b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class BakingRightsCommit : Proto16.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BigMapCommit.cs deleted file mode 100644 index 612987e54..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BlockCommit.cs deleted file mode 100644 index f8afccfc4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/BlockCommit.cs +++ /dev/null @@ -1,272 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class BlockCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Block Block { get; private set; } = null!; - - public virtual async Task Apply(JsonElement rawBlock) - { - var header = rawBlock.Required("header"); - var metadata = rawBlock.Required("metadata"); - - var level = header.RequiredInt32("level"); - var proposer = Cache.Accounts.GetExistingDelegate(metadata.RequiredString("proposer")); - var producer = Cache.Accounts.GetExistingDelegate(metadata.RequiredString("baker")); - var protocol = await Cache.Protocols.GetAsync(rawBlock.RequiredString("protocol")); - var events = BlockEvents.None; - - if (protocol.IsCycleStart(level)) - events |= BlockEvents.CycleBegin; - else if (protocol.IsCycleEnd(level)) - events |= BlockEvents.CycleEnd; - - if (protocol.FirstLevel == level) - events |= BlockEvents.ProtocolBegin; - else if (protocol.Hash != metadata.RequiredString("next_protocol")) - events |= BlockEvents.ProtocolEnd; - - if (metadata.RequiredArray("deactivated").Count() > 0) - events |= BlockEvents.Deactivations; - - if ((level - Cache.Protocols.GetCycleStart(protocol.GetCycle(level)) + 1) % protocol.BlocksPerSnapshot == 0) - events |= BlockEvents.BalanceSnapshot; - - var payloadRound = header.RequiredInt32("payload_round"); - var blockRound = Hex.Parse(header.RequiredArray("fitness", 5)[4].RequiredString()).ToInt32(); - var lbVote = header.RequiredString("liquidity_baking_toggle_vote"); - - Block = new Block - { - Id = Cache.AppState.NextOperationId(), - Hash = rawBlock.RequiredString("hash"), - Cycle = protocol.GetCycle(level), - Level = level, - ProtoCode = protocol.Code, - Timestamp = header.RequiredDateTime("timestamp"), - AttestationCommittee = GetAttestationCommittee(protocol, metadata), - PayloadRound = payloadRound, - BlockRound = blockRound, - ProposerId = proposer.Id, - ProducerId = producer.Id, - Events = events, - LBToggle = lbVote == "on" ? true : lbVote == "off" ? false : null, - LBToggleEma = metadata.RequiredInt32("liquidity_baking_toggle_ema") - }; - - Context.Block = Block; - Context.Proposer = proposer; - Context.Protocol = protocol; - - Db.TryAttach(protocol); // if we don't attach it, ef will recognize it as 'added' - if (Block.Events.HasFlag(BlockEvents.ProtocolEnd)) - protocol.LastLevel = Block.Level; - - Db.TryAttach(proposer); // if we don't attach it, ef will recognize it as 'added' - Db.TryAttach(producer); // if we don't attach it, ef will recognize it as 'added' - - Cache.AppState.Get().BlocksCount++; - - Db.Blocks.Add(Block); - Cache.Blocks.Add(Block); - } - - public async Task ApplyRewards(JsonElement rawBlock) - { - var proposer = Cache.Accounts.GetDelegate(Block.ProposerId!.Value); - var producer = Cache.Accounts.GetDelegate(Block.ProducerId!.Value); - - var balanceUpdates = rawBlock - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .Where(x => x.RequiredString("origin") == "block") - .ToList(); - - var ( - rewardDelegated, - rewardStakedOwn, - rewardStakedEdge, - rewardStakedShared, - bonusDelegated, - bonusStakedOwn, - bonusStakedEdge, - bonusStakedShared - ) = ParseRewards(proposer, producer, balanceUpdates); - - Block.RewardDelegated = rewardDelegated; - Block.RewardStakedOwn = rewardStakedOwn; - Block.RewardStakedEdge = rewardStakedEdge; - Block.RewardStakedShared = rewardStakedShared; - Block.BonusDelegated = bonusDelegated; - Block.BonusStakedOwn = bonusStakedOwn; - Block.BonusStakedEdge = bonusStakedEdge; - Block.BonusStakedShared = bonusStakedShared; - - Db.TryAttach(proposer); - ReceiveRewards(proposer, Block.RewardDelegated, Block.RewardStakedOwn, Block.RewardStakedEdge, Block.RewardStakedShared); - proposer.BlocksCount++; - - #region set baker active - var newDeactivationLevel = proposer.Staked ? GracePeriod.Reset(Block.Level, Context.Protocol) : GracePeriod.Init(Block.Level, Context.Protocol); - if (proposer.DeactivationLevel < newDeactivationLevel) - { - if (proposer.DeactivationLevel <= Block.Level) - await ActivateBaker(proposer); - - Block.ResetBakerDeactivation = proposer.DeactivationLevel; - proposer.DeactivationLevel = newDeactivationLevel; - } - #endregion - - Db.TryAttach(producer); - ReceiveRewards(producer, Block.BonusDelegated, Block.BonusStakedOwn, Block.BonusStakedEdge, Block.BonusStakedShared); - if (producer != proposer) - { - producer.BlocksCount++; - - #region set proposer active - newDeactivationLevel = producer.Staked ? GracePeriod.Reset(Block.Level, Context.Protocol) : GracePeriod.Init(Block.Level, Context.Protocol); - if (producer.DeactivationLevel < newDeactivationLevel) - { - if (producer.DeactivationLevel <= Block.Level) - await ActivateBaker(producer); - - Block.ResetProposerDeactivation = producer.DeactivationLevel; - producer.DeactivationLevel = newDeactivationLevel; - } - #endregion - } - - Cache.Statistics.Current.TotalCreated += - Block.RewardDelegated + Block.RewardStakedOwn + Block.RewardStakedEdge + Block.RewardStakedShared + - Block.BonusDelegated + Block.BonusStakedOwn + Block.BonusStakedEdge + Block.BonusStakedShared; - - Cache.Statistics.Current.TotalFrozen += - Block.RewardStakedOwn + Block.RewardStakedEdge + Block.RewardStakedShared + - Block.BonusStakedOwn + Block.BonusStakedEdge + Block.BonusStakedShared; - } - - public virtual void Revert(Block block) - { - Cache.AppState.Get().BlocksCount--; - - Db.Blocks.Remove(block); - Cache.AppState.ReleaseOperationId(); - } - - public async Task RevertRewards(Block block) - { - var proposer = Cache.Accounts.GetDelegate(block.ProposerId!.Value); - Db.TryAttach(proposer); - RevertReceiveRewards(proposer, block.RewardDelegated, block.RewardStakedOwn, block.RewardStakedEdge, block.RewardStakedShared); - proposer.BlocksCount--; - - #region reset baker activity - if (block.ResetBakerDeactivation != null) - { - if (block.ResetBakerDeactivation <= block.Level) - await DeactivateBaker(proposer); - - proposer.DeactivationLevel = (int)block.ResetBakerDeactivation; - } - #endregion - - var producer = Cache.Accounts.GetDelegate(block.ProducerId!.Value); - Db.TryAttach(producer); - RevertReceiveRewards(producer, block.BonusDelegated, block.BonusStakedOwn, block.BonusStakedEdge, block.BonusStakedShared); - if (producer != proposer) - { - producer.BlocksCount--; - - #region reset proposer activity - if (block.ResetProposerDeactivation != null) - { - if (block.ResetProposerDeactivation <= block.Level) - await DeactivateBaker(producer); - - producer.DeactivationLevel = (int)block.ResetProposerDeactivation; - } - #endregion - } - } - - protected virtual (long, long, long, long, long, long, long, long) ParseRewards(Data.Models.Delegate proposer, Data.Models.Delegate producer, List balanceUpdates) - { - var rewardDelegated = 0L; - var rewardStakedOwn = 0L; - var bonusDelegated = 0L; - var bonusStakedOwn = 0L; - - for (int i = 0; i < balanceUpdates.Count; i++) - { - var update = balanceUpdates[i]; - if (update.RequiredString("kind") == "minted" && update.RequiredString("category") == "baking rewards") - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected baking rewards balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredString("kind") == "freezer" && - nextUpdate.RequiredString("category") == "deposits" && - nextUpdate.Required("staker").RequiredString("baker") == proposer.Address && - nextUpdate.RequiredInt64("change") == change) - { - if (proposer.ExternalStakedBalance != 0) - throw new Exception("Manual staking should be disabled in Oxford"); - - rewardStakedOwn += change; - } - else if (nextUpdate.RequiredString("kind") == "contract" && - nextUpdate.RequiredString("contract") == proposer.Address && - nextUpdate.RequiredInt64("change") == change) - { - rewardDelegated += change; - } - else - { - throw new Exception("Unexpected baking rewards balance updates behavior"); - } - } - else if (update.RequiredString("kind") == "minted" && update.RequiredString("category") == "baking bonuses") - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected baking bonuses balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredString("kind") == "freezer" && - nextUpdate.RequiredString("category") == "deposits" && - nextUpdate.Required("staker").RequiredString("baker") == producer.Address && - nextUpdate.RequiredInt64("change") == change) - { - if (producer.ExternalStakedBalance != 0) - throw new Exception("Manual staking should be disabled in Oxford"); - - bonusStakedOwn += change; - } - else if (nextUpdate.RequiredString("kind") == "contract" && - nextUpdate.RequiredString("contract") == producer.Address && - nextUpdate.RequiredInt64("change") == change) - { - bonusDelegated += change; - } - else - { - throw new Exception("Unexpected baking bonuses balance updates behavior"); - } - } - } - - return (rewardDelegated, rewardStakedOwn, 0L, 0L, bonusDelegated, bonusStakedOwn, 0L, 0L); - } - - protected virtual long GetAttestationCommittee(Protocol protocol, JsonElement metadata) => protocol.AttestersPerBlock; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/ContractEventCommit.cs deleted file mode 100644 index 5025adb69..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class ContractEventCommit : Proto14.ContractEventCommit - { - public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/CycleCommit.cs deleted file mode 100644 index 8a587f6dd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/CycleCommit.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class CycleCommit(ProtocolHandler protocol) : Proto14.CycleCommit(protocol) - { - public override async Task Apply(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - await base.Apply(block); - - var res = await Proto.Rpc.GetExpectedIssuance(block.Level); - var issuance = res.EnumerateArray().First(x => x.RequiredInt32("cycle") == FutureCycle!.Index); - - FutureCycle!.BlockReward = issuance.RequiredInt64("baking_reward_fixed_portion"); - FutureCycle.BlockBonusPerBlock = issuance.RequiredInt64("baking_reward_bonus_per_slot") * (Context.Protocol.AttestersPerBlock - Context.Protocol.ConsensusThreshold); - FutureCycle.AttestationRewardPerBlock = issuance.RequiredInt64("attesting_reward_per_slot") * Context.Protocol.AttestersPerBlock; - FutureCycle.NonceRevelationReward = issuance.RequiredInt64("seed_nonce_revelation_tip"); - FutureCycle.VdfRevelationReward = issuance.RequiredInt64("vdf_revelation_tip"); - } - - protected override async Task> GetSelectedStakes(Block block, Protocol protocol, List snapshots) - { - if (block.Cycle == protocol.FirstCycle) - return await base.GetSelectedStakes(block, protocol, snapshots); - - var slashings = new Dictionary(); - var prevBlock = Cache.Blocks.Get(block.Level - 1); - if (prevBlock.Events.HasFlag(BlockEvents.DoubleBakingSlashing)) - { - var prevBlockProto = await Cache.Protocols.GetAsync(prevBlock.ProtoCode); - foreach (var op in await Db.DoubleBakingOps.AsNoTracking().Where(x => x.SlashedLevel == block.Level - 1).ToListAsync()) - slashings[op.OffenderId] = slashings.GetValueOrDefault(op.OffenderId) + prevBlockProto.DoubleBakingSlashedPercentage; - } - if (prevBlock.Events.HasFlag(BlockEvents.DoubleConsensusSlashing)) - { - var prevBlockProto = await Cache.Protocols.GetAsync(prevBlock.ProtoCode); - foreach (var op in await Db.DoubleConsensusOps.AsNoTracking().Where(x => x.SlashedLevel == block.Level - 1).ToListAsync()) - slashings[op.OffenderId] = slashings.GetValueOrDefault(op.OffenderId) + prevBlockProto.DoubleConsensusSlashedPercentage; - } - - return snapshots.Select(x => - { - var ownStaked = x.OwnStakedBalance!.Value; - var externalStaked = x.ExternalStakedBalance!.Value; - if (slashings.TryGetValue(x.AccountId, out var percentage)) - { - ownStaked = ownStaked.MulRatio(Math.Max(0, 10_000 - percentage), 10_000); - externalStaked = externalStaked.MulRatio(Math.Max(0, 10_000 - percentage), 10_000); - } - var totalStaked = ownStaked + externalStaked; - - var stakingOverBaking = Math.Min( - protocol.MaxExternalOverOwnStakeRatio * 1_000_000, - Cache.Accounts.GetDelegate(x.AccountId).LimitOfStakingOverBaking ?? 0); - - var frozen = Math.Min(totalStaked, ownStaked + ownStaked.MulRatio(stakingOverBaking, 1_000_000)); - var delegated = Math.Min(x.StakingBalance - frozen, ownStaked * protocol.MaxDelegatedOverFrozenRatio); - - return (x.AccountId, frozen, delegated); - }) - .Where(x => x.frozen >= protocol.MinimalFrozenStake && x.frozen + x.delegated >= protocol.MinimalStake) - .ToDictionary(x => x.AccountId, x => - { - return x.frozen + x.delegated; - }); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/DeactivationCommit.cs deleted file mode 100644 index 4fe280b25..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 2b5894d93..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override Task CreateFromSnapshots(Cycle futureCycle) - { - return Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "DelegatorCycles" ( - "Cycle", - "DelegatorId", - "BakerId", - "DelegatedBalance", - "StakedPseudotokens" - ) - SELECT - {0}, - "AccountId", - "BakerId", - "OwnDelegatedBalance", - "Pseudotokens" - FROM "SnapshotBalances" - WHERE "Level" = {1} - AND "BakerId" != "AccountId" - """, futureCycle.Index, futureCycle.SnapshotLevel); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/InboxCommit.cs deleted file mode 100644 index b823ecf33..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/InboxCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - public class InboxCommit : Proto17.InboxCommit - { - public InboxCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 2f0e3143d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 753a8a053..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class AttestationsCommit : Proto12.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 9c0376352..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 4582c3f61..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class DelegationsCommit(ProtocolHandler protocol) : Proto14.DelegationsCommit(protocol) - { - protected override async Task Unstake(DelegationOperation operation, List balanceUpdates) - { - if (balanceUpdates.Count == 0) - return; - - var updates = await ParseStakingUpdates(operation, balanceUpdates); - - await new StakingUpdateCommit(Proto).Apply(updates); - - operation.StakingUpdatesCount = updates.Count; - } - - protected override async Task RevertUnstake(DelegationOperation operation) - { - if (operation.StakingUpdatesCount == null) - return; - - var updates = await Db.StakingUpdates - .Where(x => x.DelegationOpId == operation.Id) - .OrderByDescending(x => x.Id) - .ToListAsync(); - - await new StakingUpdateCommit(Proto).Revert(updates); - - operation.StakingUpdatesCount = null; - } - - async Task> ParseStakingUpdates(DelegationOperation operation, List balanceUpdates) - { - var res = new List(); - - if (balanceUpdates.Count % 2 != 0) - throw new Exception("Unexpected staking balance updates behavior"); - - for (int i = 0; i < balanceUpdates.Count; i += 2) - { - var update = balanceUpdates[i]; - var kind = update.RequiredString("kind"); - var category = update.OptionalString("category"); - - var nextUpdate = balanceUpdates[i + 1]; - var nextKind = nextUpdate.RequiredString("kind"); - var nextCategory = nextUpdate.OptionalString("category"); - - if (kind == "freezer" && category == "deposits") - { - if (nextKind == "freezer" && nextCategory == "unstaked_deposits") - { - #region unstake - var baker = nextUpdate.Required("staker").RequiredString("delegate"); - var staker = nextUpdate.Required("staker").RequiredString("contract"); - var change = nextUpdate.RequiredInt64("change"); - var cycle = nextUpdate.RequiredInt32("cycle"); - - if (baker != (update.Required("staker").RequiredString("delegate")) || - staker != (update.Required("staker").RequiredString("contract")) || - change != -update.RequiredInt64("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - var pseudotokens = (BigInteger?)null; - if (i >= 2 && balanceUpdates[i - 1].RequiredString("kind") == "staking") - { - if (balanceUpdates[i - 2].RequiredString("kind") != "staking" || - balanceUpdates[i - 2].RequiredString("change") != balanceUpdates[i - 1].RequiredString("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - pseudotokens = -balanceUpdates[i - 1].RequiredBigInteger("change"); - } - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = operation.Level, - Cycle = cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = (await Cache.Accounts.GetExistingAsync(staker)).Id, - Type = StakingUpdateType.Unstake, - Amount = change, - Pseudotokens = pseudotokens, - DelegationOpId = operation.Id, - }); - #endregion - } - else - { - throw new Exception("Unexpected staking balance updates behavior"); - } - } - else if (kind == "freezer" && category == "unstaked_deposits") - { - if (nextKind == "contract") - { - #region finalize - var baker = update.Required("staker").RequiredString("delegate"); - var staker = update.Required("staker").RequiredString("contract"); - var change = nextUpdate.RequiredInt64("change"); - var cycle = update.RequiredInt32("cycle"); - - if (staker != nextUpdate.RequiredString("contract") || change != -update.RequiredInt64("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = operation.Level, - Cycle = cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = (await Cache.Accounts.GetExistingAsync(staker)).Id, - Type = StakingUpdateType.Finalize, - Amount = change, - Pseudotokens = null, - DelegationOpId = operation.Id, - }); - #endregion - } - else - { - throw new Exception("Unexpected staking balance updates behavior"); - } - } - else if (kind != "staking") - { - throw new Exception("Unexpected staking balance updates behavior"); - } - } - - return res; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 00ccce4f9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class DoubleBakingCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var accusedLevel = content.Required("bh1").RequiredInt32("level"); - var accusedRound = Hex.Parse(content.Required("bh1").RequiredArray("fitness", 5)[4].RequiredString()).ToInt32(); - var accusedBakerId = (await Db.BakingRights.AsNoTracking().FirstOrDefaultAsync(x => x.Level == accusedLevel && x.Round == accusedRound))?.BakerId; - if (accusedBakerId == null) - { - var rpcRights = await Proto.Rpc.GetLevelBakingRightsAsync(block.Level, accusedLevel, accusedRound); - var accusedBaker = rpcRights - .EnumerateArray() - .First(x => x.RequiredInt32("level") == accusedLevel && x.RequiredInt32("round") == accusedRound) - .RequiredString("delegate"); - accusedBakerId = Cache.Accounts.GetExistingDelegate(accusedBaker).Id; - } - - var accuser = Context.Proposer; - var offender = Cache.Accounts.GetDelegate(accusedBakerId.Value); - - var operation = new DoubleBakingOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - - AccusedLevel = accusedLevel, - SlashedLevel = GetSlashingLevel(block, Context.Protocol, accusedLevel), - - AccuserId = accuser.Id, - OffenderId = offender.Id, - - Reward = 0, - LostStaked = 0, - LostUnstaked = 0, - LostExternalStaked = 0, - LostExternalUnstaked = 0 - }; - #endregion - - #region apply operation - Db.TryAttach(accuser); - accuser.DoubleBakingCount++; - - if (offender != accuser) - { - Db.TryAttach(offender); - offender.DoubleBakingCount++; - } - - block.Operations |= Operations.DoubleBakings; - - Cache.AppState.Get().DoubleBakingOpsCount++; - #endregion - - Db.DoubleBakingOps.Add(operation); - Context.DoubleBakingOps.Add(operation); - } - - public void Revert(DoubleBakingOperation operation) - { - #region init - var accuser = Cache.Accounts.GetDelegate(operation.AccuserId); - var offender = Cache.Accounts.GetDelegate(operation.OffenderId); - #endregion - - #region revert operation - Db.TryAttach(accuser); - accuser.DoubleBakingCount--; - - if (offender != accuser) - { - Db.TryAttach(offender); - offender.DoubleBakingCount--; - } - - Cache.AppState.Get().DoubleBakingOpsCount--; - #endregion - - Db.DoubleBakingOps.Remove(operation); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual int GetSlashingLevel(Block block, Protocol protocol, int accusedLevel) - { - return Cache.Protocols.GetCycleEnd(block.Cycle); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 90a7f9834..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class DoubleConsensusCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public void Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var accusedLevel = GetAccusedLevel(content); - var accuser = Context.Proposer; - var offender = Cache.Accounts.GetExistingDelegate(GetOffender(content)); - - var operation = new DoubleConsensusOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - - Kind = GetKind(content), - - AccusedLevel = accusedLevel, - SlashedLevel = GetSlashingLevel(block, Context.Protocol, accusedLevel), - - AccuserId = accuser.Id, - OffenderId = offender.Id, - - Reward = 0, - LostStaked = 0, - LostUnstaked = 0, - LostExternalStaked = 0, - LostExternalUnstaked = 0 - }; - #endregion - - #region apply operation - Db.TryAttach(accuser); - accuser.DoubleConsensusCount++; - - if (offender != accuser) - { - Db.TryAttach(offender); - offender.DoubleConsensusCount++; - } - - block.Operations |= Operations.DoubleConsensus; - - Cache.AppState.Get().DoubleConsensusOpsCount++; - #endregion - - Db.DoubleConsensusOps.Add(operation); - Context.DoubleConsensusOps.Add(operation); - } - - public void Revert(DoubleConsensusOperation operation) - { - #region init - var accuser = Cache.Accounts.GetDelegate(operation.AccuserId); - var offender = Cache.Accounts.GetDelegate(operation.OffenderId); - #endregion - - #region revert operation - Db.TryAttach(accuser); - accuser.DoubleConsensusCount--; - - if (offender != accuser) - { - Db.TryAttach(offender); - offender.DoubleConsensusCount--; - } - - Cache.AppState.Get().DoubleConsensusOpsCount--; - #endregion - - Db.DoubleConsensusOps.Remove(operation); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual int GetAccusedLevel(JsonElement content) - { - return content.Required("op1").Required("operations").RequiredInt32("level"); - } - - protected virtual string GetOffender(JsonElement content) - { - var offender = content.Required("metadata").OptionalString("forbidden_delegate"); - - // one-time workaround to avoid signature brute forcing - if (offender == null && Cache.AppState.GetChainId() == "NetXdQprcVkpaWU" && Context.Block.Level == 5689908) - offender = "tz1bZ8vsMAXmaWEV7FRnyhcuUs2fYMaQ6Hkk"; - - return offender ?? throw new Exception("Failed to determine offender"); - } - - protected virtual int GetSlashingLevel(Block block, Protocol protocol, int accusedLevel) - { - return Cache.Protocols.GetCycleEnd(block.Cycle); - } - - protected virtual DoubleConsensusKind GetKind(JsonElement content) - { - return content.RequiredString("kind") == "double_endorsement_evidence" - ? DoubleConsensusKind.DoubleAttestation - : DoubleConsensusKind.DoublePreattestation; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index 83020dd99..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class DrainDelegateCommit : Proto15.DrainDelegateCommit - { - public DrainDelegateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index 76a82be3f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class IncreasePaidStorageCommit : Proto14.IncreasePaidStorageCommit - { - public IncreasePaidStorageCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 24e134f74..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class NonceRevelationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var baker = Context.Proposer; - - var balanceUpdates = content - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .ToList(); - - var (rewardDelegated, rewardStakedOwn, rewardStakedEdge, rewardStakedShared) = ParseRewards(Context.Proposer, balanceUpdates); - - var revealedBlock = await Cache.Blocks.GetAsync(content.RequiredInt32("level")); - var sender = Cache.Accounts.GetDelegate(revealedBlock.ProposerId!.Value); - - var revelation = new NonceRevelationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerId = baker.Id, - SenderId = sender.Id, - RevealedLevel = revealedBlock.Level, - RevealedCycle = revealedBlock.Cycle, - Nonce = Hex.Parse(content.RequiredString("nonce")), - RewardDelegated = rewardDelegated, - RewardStakedOwn = rewardStakedOwn, - RewardStakedEdge = rewardStakedEdge, - RewardStakedShared = rewardStakedShared - }; - #endregion - - #region apply operation - ReceiveRewards(baker, revelation.RewardDelegated, revelation.RewardStakedOwn, revelation.RewardStakedEdge, revelation.RewardStakedShared); - baker.NonceRevelationsCount++; - - if (revelation.SenderId != baker.Id) - { - Db.TryAttach(sender); - sender.NonceRevelationsCount++; - } - - Db.TryAttach(revealedBlock); - revealedBlock.RevelationId = revelation.Id; - - block.Operations |= Operations.Revelations; - - Cache.AppState.Get().NonceRevelationOpsCount++; - Cache.Statistics.Current.TotalCreated += revelation.RewardDelegated + revelation.RewardStakedOwn + revelation.RewardStakedEdge + revelation.RewardStakedShared; - Cache.Statistics.Current.TotalFrozen += revelation.RewardStakedOwn + revelation.RewardStakedEdge + revelation.RewardStakedShared; - #endregion - - Db.NonceRevelationOps.Add(revelation); - Context.NonceRevelationOps.Add(revelation); - } - - public virtual async Task Revert(Block block, NonceRevelationOperation revelation) - { - #region entities - var blockBaker = Context.Proposer; - var sender = Cache.Accounts.GetDelegate(revelation.SenderId); - var revealedBlock = await Cache.Blocks.GetAsync(revelation.RevealedLevel); - - //Db.TryAttach(blockBaker); - Db.TryAttach(sender); - Db.TryAttach(revealedBlock); - #endregion - - #region apply operation - RevertReceiveRewards(blockBaker, revelation.RewardDelegated, revelation.RewardStakedOwn, revelation.RewardStakedEdge, revelation.RewardStakedShared); - blockBaker.NonceRevelationsCount--; - - if (sender.Id != blockBaker.Id) - { - Db.TryAttach(sender); - sender.NonceRevelationsCount--; - } - - Db.TryAttach(revealedBlock); - revealedBlock.RevelationId = null; - - Cache.AppState.Get().NonceRevelationOpsCount--; - #endregion - - Db.NonceRevelationOps.Remove(revelation); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual (long, long, long, long) ParseRewards(Data.Models.Delegate proposer, List balanceUpdates) - { - var freezerUpdate = balanceUpdates.SingleOrDefault(x => x.RequiredString("kind") == "freezer"); - var contractUpdate = balanceUpdates.SingleOrDefault(x => x.RequiredString("kind") == "contract"); - - var rewardDelegated = contractUpdate.ValueKind != JsonValueKind.Undefined - ? contractUpdate.RequiredInt64("change") - : 0; - var rewardStakedOwn = freezerUpdate.ValueKind != JsonValueKind.Undefined - ? freezerUpdate.RequiredInt64("change") - : 0; - - return (rewardDelegated, rewardStakedOwn, 0L, 0L); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index f08e816de..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class OriginationsCommit : Proto14.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index d814c0b2e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class PreattestationsCommit : Proto12.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 7b6617b5b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class ProposalsCommit : Proto14.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index 7ae50c102..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class RegisterConstantsCommit : Proto14.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index bf9cc231d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class RevealsCommit : Proto14.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SetDelegateParametersCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SetDelegateParametersCommit.cs deleted file mode 100644 index 84f313706..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SetDelegateParametersCommit.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Contracts; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SetDelegateParametersCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - #region static - public static readonly string Entrypoint = "set_delegate_parameters"; - static readonly Schema Parameters = Schema.Create(new MichelinePrim - { - Prim = PrimType.pair, - Args = - [ - new MichelinePrim { Prim = PrimType.@int }, - new MichelinePrim { Prim = PrimType.@int }, - new MichelinePrim { Prim = PrimType.unit }, - ] - }); - #endregion - - public async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = (await Cache.Accounts.GetExistingAsync(content.RequiredString("source")) as User)!; - - var result = content.Required("metadata").Required("operation_result"); - var status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }; - - var limit = BigInteger.Zero; - var edge = BigInteger.Zero; - try - { - var param = Parameters.Optimize(content.Required("parameters").RequiredMicheline("value")); - limit = ((param as MichelinePrim)!.Args![0] as MichelineInt)!.Value; - edge = (((param as MichelinePrim)!.Args![1] as MichelinePrim)!.Args![0] as MichelineInt)!.Value; - } - catch when (status != OperationStatus.Applied) { } - - var operation = new SetDelegateParametersOperation - { - Id = Cache.AppState.NextOperationId(), - OpHash = op.RequiredString("hash"), - Level = block.Level, - Timestamp = block.Timestamp, - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - ActivationCycle = block.Cycle + Context.Protocol.DelegateParametersActivationDelay + 1, - LimitOfStakingOverBaking = limit.TrimToInt64(), - EdgeOfBakingOverStaking = (long)edge, - Status = status, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - AllocationFee = null, - StorageFee = null, - StorageUsed = 0 - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter; - sender.SetDelegateParametersOpsCount++; - - block.Operations |= Operations.SetDelegateParameters; - - Cache.AppState.Get().SetDelegateParametersOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - Cache.AppState.Get().PendingDelegateParameters++; - } - #endregion - - Proto.Manager.Set(sender); - Db.SetDelegateParametersOps.Add(operation); - Context.SetDelegateParametersOps.Add(operation); - } - - public async Task Revert(Block block, SetDelegateParametersOperation operation) - { - var sender = (await Cache.Accounts.GetAsync(operation.SenderId) as User)!; - Db.TryAttach(sender); - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - Cache.AppState.Get().PendingDelegateParameters--; - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter - 1; - sender.SetDelegateParametersOpsCount--; - - Cache.AppState.Get().SetDelegateParametersOpsCount--; - #endregion - - Db.SetDelegateParametersOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - public async Task ActivateStakingParameters(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin) || Cache.AppState.Get().PendingDelegateParameters == 0) - return; - - var ops = await Db.SetDelegateParametersOps - .AsNoTracking() - .Where(x => x.ActivationCycle == block.Cycle && x.Status == OperationStatus.Applied) - .ToListAsync(); - - foreach (var op in ops.OrderBy(x => x.Id)) - { - var baker = Cache.Accounts.GetDelegate(op.SenderId); - Db.TryAttach(baker); - baker.EdgeOfBakingOverStaking = op.EdgeOfBakingOverStaking; - baker.LimitOfStakingOverBaking = op.LimitOfStakingOverBaking; - UpdateBakerPower(baker); - Cache.AppState.Get().PendingDelegateParameters--; - } - } - - public async Task DeactivateStakingParameters(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - var ops = await Db.SetDelegateParametersOps - .AsNoTracking() - .Where(x => x.ActivationCycle == block.Cycle && x.Status == OperationStatus.Applied) - .ToListAsync(); - - foreach (var op in ops.OrderByDescending(x => x.Id)) - { - var baker = Cache.Accounts.GetDelegate(op.SenderId); - - var prevOp = await Db.SetDelegateParametersOps - .AsNoTracking() - .Where(x => - x.SenderId == baker.Id && - x.ActivationCycle < op.ActivationCycle && - x.Status == OperationStatus.Applied) - .OrderByDescending(x => x.Id) - .FirstOrDefaultAsync(); - - Db.TryAttach(baker); - baker.EdgeOfBakingOverStaking = prevOp?.EdgeOfBakingOverStaking; - baker.LimitOfStakingOverBaking = prevOp?.LimitOfStakingOverBaking; - RevertBakerPower(baker); - Cache.AppState.Get().PendingDelegateParameters++; - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index cf2143d4e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index 3c707b479..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SmartRollupAddMessagesCommit : Proto16.SmartRollupAddMessagesCommit - { - public SmartRollupAddMessagesCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index 903512ddb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SmartRollupCementCommit : Proto17.SmartRollupCementCommit - { - public SmartRollupCementCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index 16ca1449b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SmartRollupExecuteCommit : Proto16.SmartRollupExecuteCommit - { - public SmartRollupExecuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index 1b3cc7016..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SmartRollupOriginateCommit : Proto16.SmartRollupOriginateCommit - { - public SmartRollupOriginateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index 919c5d09f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SmartRollupPublishCommit : Proto16.SmartRollupPublishCommit - { - public SmartRollupPublishCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index 7cb3d3164..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SmartRollupRecoverBondCommit : Proto16.SmartRollupRecoverBondCommit - { - public SmartRollupRecoverBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index b3de2cd5b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SmartRollupRefuteCommit : Proto16.SmartRollupRefuteCommit - { - public SmartRollupRefuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index ad637947d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SmartRollupTimeoutCommit : Proto16.SmartRollupTimeoutCommit - { - public SmartRollupTimeoutCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/StakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/StakingCommit.cs deleted file mode 100644 index e0dfd8b77..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/StakingCommit.cs +++ /dev/null @@ -1,360 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class StakingCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - #region static - public static bool ValidateParameters(string entrypoint, string src, string dst) => entrypoint switch - { - "stake" => src == dst, - "unstake" => src == dst, - "finalize_unstake" => true, - _ => false - }; - #endregion - - public async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = (await Cache.Accounts.GetExistingAsync(content.RequiredString("source")) as User)!; - var senderDelegate = sender as Data.Models.Delegate ?? Cache.Accounts.GetDelegate(sender.DelegateId); - var staker = (await Cache.Accounts.GetOrCreateAsync(content.RequiredString("destination")) as User)!; - - var result = content.Required("metadata").Required("operation_result"); - var operation = new StakingOperation - { - Id = Cache.AppState.NextOperationId(), - OpHash = op.RequiredString("hash"), - Level = block.Level, - Timestamp = block.Timestamp, - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - StakerId = staker.Id, - Action = content.Required("parameters").RequiredString("entrypoint") switch - { - "stake" => StakingAction.Stake, - "unstake" => StakingAction.Unstake, - "finalize_unstake" => StakingAction.Finalize, - _ => throw new NotImplementedException() - }, - RequestedAmount = content.RequiredInt64("amount"), - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - AllocationFee = null, - StorageFee = null, - StorageUsed = 0 - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter; - sender.StakingOpsCount++; - - if (staker != sender) - { - Db.TryAttach(staker); - staker.StakingOpsCount++; - } - - block.Operations |= Operations.Staking; - - Cache.AppState.Get().StakingOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - if (result.TryGetProperty("balance_updates", out var balanceUpdates)) - { - var updates = await ParseStakingUpdates(block, operation, [.. balanceUpdates.EnumerateArray()]); - await new StakingUpdateCommit(Proto).Apply(updates); - - operation.Amount = operation.Action switch - { - StakingAction.Stake => operation.Amount = updates - .Where(x => x.Type == StakingUpdateType.Stake || x.Type == StakingUpdateType.Restake) - .Sum(x => x.Amount), - StakingAction.Unstake => operation.Amount = updates - .Where(x => x.Type == StakingUpdateType.Unstake) - .Sum(x => x.Amount), - StakingAction.Finalize => operation.Amount = updates - .Where(x => x.Type == StakingUpdateType.Finalize) - .Sum(x => x.Amount), - _ => throw new NotImplementedException() - }; - operation.BakerId = operation.Action == StakingAction.Finalize - ? updates.FirstOrDefault(x => x.Type == StakingUpdateType.Finalize)?.BakerId ?? sender.UnstakedBakerId ?? senderDelegate?.Id - : updates.FirstOrDefault(x => x.Type != StakingUpdateType.Finalize)?.BakerId ?? senderDelegate?.Id; - operation.StakingUpdatesCount = updates.Count; - } - else - { - operation.Amount = 0; - operation.BakerId = operation.Action == StakingAction.Finalize - ? sender.UnstakedBakerId ?? senderDelegate?.Id - : senderDelegate?.Id; - operation.StakingUpdatesCount = 0; - - } - - if (Cache.Accounts.GetDelegate(operation.BakerId) is Data.Models.Delegate baker && baker != sender && baker != staker) - { - Db.TryAttach(baker); - baker.StakingOpsCount++; - } - } - #endregion - - Proto.Manager.Set(sender); - Db.StakingOps.Add(operation); - Context.StakingOps.Add(operation); - } - - public async Task Revert(Block block, StakingOperation operation) - { - var sender = (await Cache.Accounts.GetAsync(operation.SenderId) as User)!; - var staker = (await Cache.Accounts.GetAsync(operation.StakerId) as User)!; - - Db.TryAttach(sender); - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - if (Cache.Accounts.GetDelegate(operation.BakerId) is Data.Models.Delegate baker && baker != sender && baker != staker) - { - Db.TryAttach(baker); - baker.StakingOpsCount--; - } - - if (operation.StakingUpdatesCount != null) - { - var updates = await Db.StakingUpdates - .Where(x => x.StakingOpId == operation.Id) - .OrderByDescending(x => x.Id) - .ToListAsync(); - await new StakingUpdateCommit(Proto).Revert(updates); - } - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter - 1; - sender.StakingOpsCount--; - - if (staker != sender) - { - Db.TryAttach(staker); - staker.StakingOpsCount--; - } - - Cache.AppState.Get().StakingOpsCount--; - #endregion - - Db.StakingOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - - async Task> ParseStakingUpdates(Block block, StakingOperation operation, List balanceUpdates) - { - var res = new List(); - - if (balanceUpdates.Count % 2 != 0) - throw new Exception("Unexpected staking balance updates behavior"); - - for (int i = 0; i < balanceUpdates.Count; i += 2) - { - var update = balanceUpdates[i]; - var kind = update.RequiredString("kind"); - var category = update.OptionalString("category"); - - var nextUpdate = balanceUpdates[i + 1]; - var nextKind = nextUpdate.RequiredString("kind"); - var nextCategory = nextUpdate.OptionalString("category"); - - if (kind == "contract") - { - if (nextKind != "freezer" || nextCategory != "deposits") - throw new Exception("Unexpected staking balance updates behavior"); - - #region stake - var baker = nextUpdate.Required("staker").OptionalString("delegate") ?? GetFreezerBaker(nextUpdate); - var staker = nextUpdate.Required("staker").OptionalString("contract") ?? GetFreezerBaker(nextUpdate); - var change = nextUpdate.RequiredInt64("change"); - - if (staker != update.RequiredString("contract") || change != -update.RequiredInt64("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - var pseudotokens = (BigInteger?)null; - if (i >= 2 && balanceUpdates[i - 1].RequiredString("kind") == "staking") - { - if (balanceUpdates[i - 2].RequiredString("kind") != "staking" || - balanceUpdates[i - 2].RequiredString("change") != balanceUpdates[i - 1].RequiredString("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - pseudotokens = balanceUpdates[i - 1].RequiredBigInteger("change"); - } - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = block.Cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = (await Cache.Accounts.GetExistingAsync(staker)).Id, - Type = StakingUpdateType.Stake, - Amount = change, - Pseudotokens = pseudotokens, - StakingOpId = operation.Id, - }); - #endregion - } - else if (kind == "freezer" && category == "deposits") - { - if (nextKind == "freezer" && nextCategory == "unstaked_deposits") - { - #region unstake - var baker = nextUpdate.Required("staker").RequiredString("delegate"); - var staker = nextUpdate.Required("staker").RequiredString("contract"); - var change = nextUpdate.RequiredInt64("change"); - var cycle = nextUpdate.RequiredInt32("cycle"); - - if (baker != (update.Required("staker").OptionalString("delegate") ?? GetFreezerBaker(update)) || - staker != (update.Required("staker").OptionalString("contract") ?? GetFreezerBaker(update)) || - change != -update.RequiredInt64("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - var pseudotokens = (BigInteger?)null; - if (i >= 2 && balanceUpdates[i - 1].RequiredString("kind") == "staking") - { - if (balanceUpdates[i - 2].RequiredString("kind") != "staking" || - balanceUpdates[i - 2].RequiredString("change") != balanceUpdates[i - 1].RequiredString("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - pseudotokens = -balanceUpdates[i - 1].RequiredBigInteger("change"); - } - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = (await Cache.Accounts.GetExistingAsync(staker)).Id, - Type = StakingUpdateType.Unstake, - Amount = change, - Pseudotokens = pseudotokens, - StakingOpId = operation.Id, - }); - #endregion - } - else - { - throw new Exception("Unexpected staking balance updates behavior"); - } - } - else if (kind == "freezer" && category == "unstaked_deposits") - { - if (nextKind == "contract") - { - #region finalize - var baker = update.Required("staker").RequiredString("delegate"); - var staker = update.Required("staker").RequiredString("contract"); - var change = nextUpdate.RequiredInt64("change"); - var cycle = update.RequiredInt32("cycle"); - - if (staker != nextUpdate.RequiredString("contract") || change != -update.RequiredInt64("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = (await Cache.Accounts.GetExistingAsync(staker)).Id, - Type = StakingUpdateType.Finalize, - Amount = change, - Pseudotokens = null, - StakingOpId = operation.Id, - }); - #endregion - } - else if (nextKind == "freezer" && nextCategory == "deposits") - { - #region restake - var baker = nextUpdate.Required("staker").OptionalString("delegate") ?? GetFreezerBaker(nextUpdate); - var staker = nextUpdate.Required("staker").OptionalString("contract") ?? GetFreezerBaker(nextUpdate); - var change = nextUpdate.RequiredInt64("change"); - var cycle = update.RequiredInt32("cycle"); - - if (baker != (update.Required("staker").OptionalString("delegate") ?? GetFreezerBaker(update)) || - staker != (update.Required("staker").OptionalString("contract") ?? GetFreezerBaker(update)) || - change != -update.RequiredInt64("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - var pseudotokens = (BigInteger?)null; - if (i >= 2 && balanceUpdates[i - 1].RequiredString("kind") == "staking") - { - if (balanceUpdates[i - 2].RequiredString("kind") != "staking" || - balanceUpdates[i - 2].RequiredString("change") != balanceUpdates[i - 1].RequiredString("change")) - throw new Exception("Unexpected staking balance updates behavior"); - - pseudotokens = balanceUpdates[i - 1].RequiredBigInteger("change"); - } - - res.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = cycle, - BakerId = Cache.Accounts.GetExistingDelegate(baker).Id, - StakerId = (await Cache.Accounts.GetExistingAsync(staker)).Id, - Type = StakingUpdateType.Restake, - Amount = change, - Pseudotokens = pseudotokens, - StakingOpId = operation.Id, - }); - #endregion - } - else - { - throw new Exception("Unexpected staking balance updates behavior"); - } - } - else if (kind != "staking") - { - throw new Exception("Unexpected staking balance updates behavior"); - } - } - - return res; - } - - protected virtual string GetFreezerBaker(JsonElement update) - { - return update.Required("staker").RequiredString("baker"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index a5365c139..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class TransactionsCommit : Proto14.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index c27e00840..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index de647cb60..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class UpdateSecondaryKeyCommit : Proto15.UpdateSecondaryKeyCommit - { - public UpdateSecondaryKeyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 7c8860574..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class VdfRevelationCommit : ProtocolCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - - public virtual Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var balanceUpdates = content - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .ToList(); - - var (rewardDelegated, rewardStakedOwn, rewardStakedEdge, rewardStakedShared) = ParseRewards(Context.Proposer, balanceUpdates); - - var revelation = new VdfRevelationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - BakerId = Context.Proposer.Id, - Cycle = block.Cycle, - Solution = Hex.Parse(content.RequiredArray("solution", 2)[0].RequiredString()), - Proof = Hex.Parse(content.RequiredArray("solution", 2)[1].RequiredString()), - RewardDelegated = rewardDelegated, - RewardStakedOwn = rewardStakedOwn, - RewardStakedEdge = rewardStakedEdge, - RewardStakedShared = rewardStakedShared - }; - #endregion - - #region apply operation - ReceiveRewards(Context.Proposer, revelation.RewardDelegated, revelation.RewardStakedOwn, revelation.RewardStakedEdge, revelation.RewardStakedShared); - Context.Proposer.VdfRevelationsCount++; - - Cache.AppState.Get().VdfRevelationOpsCount++; - - block.Operations |= Operations.VdfRevelation; - - Cache.Statistics.Current.TotalCreated += revelation.RewardDelegated + revelation.RewardStakedOwn + revelation.RewardStakedEdge + revelation.RewardStakedShared; - Cache.Statistics.Current.TotalFrozen += revelation.RewardStakedOwn + revelation.RewardStakedEdge + revelation.RewardStakedShared; - #endregion - - Db.VdfRevelationOps.Add(revelation); - Context.VdfRevelationOps.Add(revelation); - return Task.CompletedTask; - } - - public virtual Task Revert(Block block, VdfRevelationOperation revelation) - { - #region entities - var blockBaker = Context.Proposer; - //Db.TryAttach(blockBaker); - #endregion - - #region apply operation - RevertReceiveRewards(blockBaker, revelation.RewardDelegated, revelation.RewardStakedOwn, revelation.RewardStakedEdge, revelation.RewardStakedShared); - blockBaker.VdfRevelationsCount--; - - Cache.AppState.Get().VdfRevelationOpsCount--; - #endregion - - Db.VdfRevelationOps.Remove(revelation); - Cache.AppState.ReleaseOperationId(); - return Task.CompletedTask; - } - - protected virtual (long, long, long, long) ParseRewards(Data.Models.Delegate proposer, List balanceUpdates) - { - var freezerUpdate = balanceUpdates.SingleOrDefault(x => x.RequiredString("kind") == "freezer"); - var contractUpdate = balanceUpdates.SingleOrDefault(x => x.RequiredString("kind") == "contract"); - - var rewardDelegated = contractUpdate.ValueKind != JsonValueKind.Undefined - ? contractUpdate.RequiredInt64("change") - : 0; - var rewardStakedOwn = freezerUpdate.ValueKind != JsonValueKind.Undefined - ? freezerUpdate.RequiredInt64("change") - : 0; - - return (rewardDelegated, rewardStakedOwn, 0L, 0L); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SlashingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SlashingCommit.cs deleted file mode 100644 index 1a221a4c1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SlashingCommit.cs +++ /dev/null @@ -1,509 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SlashingCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply(Block block, JsonElement rawBlock) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - var slashings = rawBlock - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .Where(x => x.RequiredString("origin") == "delayed_operation"); - - if (!slashings.Any()) - return; - - var slashedRequests = await SlashUnstakeRequests(block, slashings); - - foreach (var slashing in slashings.GroupBy(x => x.RequiredString("delayed_operation_hash")).Reverse()) - { - var opHash = slashing.Key; - var accusation = Context.DoubleBakingOps.FirstOrDefault(x => x.OpHash == opHash) - ?? Context.DoubleConsensusOps.FirstOrDefault(x => x.OpHash == opHash) - ?? Db.DoubleBakingOps.FirstOrDefault(x => x.OpHash == opHash) - ?? (BaseOperation?)Db.DoubleConsensusOps.FirstOrDefault(x => x.OpHash == opHash) - ?? throw new Exception($"Cannot find delayed operation '{opHash}'"); - - var (accuserId, offenderId) = accusation switch - { - DoubleBakingOperation op => (op.AccuserId, op.OffenderId), - DoubleConsensusOperation op => (op.AccuserId, op.OffenderId), - _ => throw new InvalidOperationException() - }; - var accuser = Cache.Accounts.GetDelegate(accuserId); - var offender = Cache.Accounts.GetDelegate(offenderId); - - var updates = await ParseStakingUpdates(block, accusation, slashedRequests[opHash], slashing); - await new StakingUpdateCommit(Proto).Apply(updates); - - var lostOwnStaked = updates - .Where(x => x.Type == StakingUpdateType.SlashStaked && x.StakerId == x.BakerId) - .Sum(x => x.Amount); - var lostExternalStaked = updates - .Where(x => x.Type == StakingUpdateType.SlashStaked && x.StakerId != x.BakerId) - .Sum(x => x.Amount); - var lostOwnUnstaked = updates - .Where(x => x.Type == StakingUpdateType.SlashUnstaked && x.StakerId == x.BakerId) - .Sum(x => x.Amount); - var lostExternalUnstaked = updates - .Where(x => x.Type == StakingUpdateType.SlashUnstaked && x.StakerId != x.BakerId) - .Sum(x => x.Amount); - var reward = slashing - .Where(x => x.RequiredString("kind") == "contract") - .Sum(x => x.RequiredInt64("change")); - - Db.TryAttach(accuser); - Receive(accuser, accuser, reward); - accuser.LastLevel = block.Level; - - var accuserCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, accuser.Id); - var offenderCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, offender.Id); - - switch (accusation) - { - case DoubleBakingOperation op: - op.SlashedLevel = block.Level; - op.Reward = reward; - op.LostStaked = lostOwnStaked; - op.LostUnstaked = lostOwnUnstaked; - op.LostExternalStaked = lostExternalStaked; - op.LostExternalUnstaked = lostExternalUnstaked; - op.StakingUpdatesCount = updates.Count; - if (accuserCycle != null) - { - Db.TryAttach(accuserCycle); - accuserCycle.DoubleBakingRewards += reward; - } - if (offenderCycle != null) - { - Db.TryAttach(offenderCycle); - offenderCycle.DoubleBakingLostStaked += lostOwnStaked; - offenderCycle.DoubleBakingLostUnstaked += lostOwnUnstaked; - offenderCycle.DoubleBakingLostExternalStaked += lostExternalStaked; - offenderCycle.DoubleBakingLostExternalUnstaked += lostExternalUnstaked; - } - Db.TryAttach(block); - block.Events |= BlockEvents.DoubleBakingSlashing; - break; - case DoubleConsensusOperation op: - op.SlashedLevel = block.Level; - op.Reward = reward; - op.LostStaked = lostOwnStaked; - op.LostUnstaked = lostOwnUnstaked; - op.LostExternalStaked = lostExternalStaked; - op.LostExternalUnstaked = lostExternalUnstaked; - op.StakingUpdatesCount = updates.Count; - if (accuserCycle != null) - { - Db.TryAttach(accuserCycle); - accuserCycle.DoubleConsensusRewards += reward; - } - if (offenderCycle != null) - { - Db.TryAttach(offenderCycle); - offenderCycle.DoubleConsensusLostStaked += lostOwnStaked; - offenderCycle.DoubleConsensusLostUnstaked += lostOwnUnstaked; - offenderCycle.DoubleConsensusLostExternalStaked += lostExternalStaked; - offenderCycle.DoubleConsensusLostExternalUnstaked += lostExternalUnstaked; - } - Db.TryAttach(block); - block.Events |= BlockEvents.DoubleConsensusSlashing; - break; - default: - throw new InvalidOperationException(); - } - - Cache.Statistics.Current.TotalBurned += lostOwnStaked + lostExternalStaked + lostOwnUnstaked + lostExternalUnstaked - reward; - } - } - - public async Task Revert(Block block) - { - if (block.Events.HasFlag(BlockEvents.DoubleBakingSlashing)) - { - foreach (var op in await Db.DoubleBakingOps.Where(x => x.SlashedLevel == block.Level).ToListAsync()) - { - var accuser = Cache.Accounts.GetDelegate(op.AccuserId); - Db.TryAttach(accuser); - RevertReceive(accuser, accuser, op.Reward); - - var accuserCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, accuser.Id); - if (accuserCycle != null) - { - Db.TryAttach(accuserCycle); - accuserCycle.DoubleBakingRewards -= op.Reward; - } - - var offenderCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.OffenderId); - if (offenderCycle != null) - { - Db.TryAttach(offenderCycle); - offenderCycle.DoubleBakingLostStaked -= op.LostStaked; - offenderCycle.DoubleBakingLostUnstaked -= op.LostUnstaked; - offenderCycle.DoubleBakingLostExternalStaked -= op.LostExternalStaked; - offenderCycle.DoubleBakingLostExternalUnstaked -= op.LostExternalUnstaked; - } - - op.Reward = 0; - op.LostStaked = 0; - op.LostUnstaked = 0; - op.LostExternalStaked = 0; - op.LostExternalUnstaked = 0; - - var updates = await Db.StakingUpdates - .Where(x => x.DoubleBakingOpId == op.Id) - .OrderByDescending(x => x.Id) - .ToListAsync(); - - await new StakingUpdateCommit(Proto).Revert(updates); - - op.StakingUpdatesCount = null; - } - } - - if (block.Events.HasFlag(BlockEvents.DoubleConsensusSlashing)) - { - foreach (var op in await Db.DoubleConsensusOps.Where(x => x.SlashedLevel == block.Level).ToListAsync()) - { - var accuser = Cache.Accounts.GetDelegate(op.AccuserId); - Db.TryAttach(accuser); - RevertReceive(accuser, accuser, op.Reward); - - var accuserCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, accuser.Id); - if (accuserCycle != null) - { - Db.TryAttach(accuserCycle); - accuserCycle.DoubleConsensusRewards -= op.Reward; - } - - var offenderCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, op.OffenderId); - if (offenderCycle != null) - { - Db.TryAttach(offenderCycle); - offenderCycle.DoubleConsensusLostStaked -= op.LostStaked; - offenderCycle.DoubleConsensusLostUnstaked -= op.LostUnstaked; - offenderCycle.DoubleConsensusLostExternalStaked -= op.LostExternalStaked; - offenderCycle.DoubleConsensusLostExternalUnstaked -= op.LostExternalUnstaked; - } - - op.Reward = 0; - op.LostStaked = 0; - op.LostUnstaked = 0; - op.LostExternalStaked = 0; - op.LostExternalUnstaked = 0; - - var updates = await Db.StakingUpdates - .Where(x => x.DoubleConsensusOpId == op.Id) - .OrderByDescending(x => x.Id) - .ToListAsync(); - - await new StakingUpdateCommit(Proto).Revert(updates); - - op.StakingUpdatesCount = null; - } - } - } - - async Task>> SlashUnstakeRequests( - Block block, - IEnumerable slashings) - { - var slashedBakers = slashings - .Where(x => x.RequiredString("kind") == "freezer") - .Select(GetFreezerBaker) - .ToHashSet() - .Select(Cache.Accounts.GetExistingDelegate); - - var slashedRequests = new Dictionary>(); - foreach (var baker in slashedBakers) - { - var bakerContext = await Proto.Rpc.GetContractRawAsync(block.Level, baker.Address); - if (bakerContext.TryGetProperty("unstaked_frozen_deposits", out var prop)) - { - var cycles = prop.RequiredArray().EnumerateArray() - .Select(x => x.RequiredArray().EnumerateArray().First().RequiredInt32()) - .ToHashSet(); - - var requests = await Db.UnstakeRequests - .Where(x => x.BakerId == baker.Id && cycles.Contains(x.Cycle) && x.StakerId != null) - .ToListAsync(); - - foreach (var request in requests) - Cache.UnstakeRequests.Add(request); - - var stakers = requests - .Select(x => x.StakerId!.Value) - .ToHashSet(); - - var slashedBakerRequests = new List<(int, int, long)>(requests.Count); - foreach (var stakerId in stakers) - { - var staker = await Cache.Accounts.GetAsync(stakerId); - var rpc = await Proto.Rpc.GetUnstakeRequests(block.Level, staker.Address); - if (rpc.ValueKind != JsonValueKind.Null) - { - foreach (var request in rpc.Required("unfinalizable").RequiredArray("requests").EnumerateArray()) - { - var cycle = request.RequiredInt32("cycle"); - var actualAmount = request.RequiredInt64("amount"); - - var local = requests.First(x => x.StakerId == staker.Id && x.Cycle == cycle); - var localActualAmount = local.RequestedAmount - local.RestakedAmount - local.FinalizedAmount - local.SlashedAmount + (local.RoundingError ?? 0); - - if (localActualAmount != actualAmount) - slashedBakerRequests.Add((staker.Id, cycle, localActualAmount - actualAmount)); - } - } - } - - if (slashedBakerRequests.Count != 0) - slashedRequests.Add(baker.Id, slashedBakerRequests); - } - } - - var bakerByOp = slashings - .Where(x => x.RequiredString("kind") == "freezer") - .DistinctBy(x => x.RequiredString("delayed_operation_hash")) - .ToDictionary(x => x.RequiredString("delayed_operation_hash"), GetFreezerBaker); - - var burnedByOp = slashings - .Where(x => x.RequiredString("kind") == "burned") - .ToDictionary(x => x.RequiredString("delayed_operation_hash"), x => x.RequiredInt64("change")); - - var burnedByBaker = burnedByOp - .GroupBy(x => bakerByOp[x.Key]) - .ToDictionary(x => x.Key, x => x.Sum(y => y.Value)); - - var shares = burnedByOp - .ToDictionary(x => x.Key, x => x.Value / (double)burnedByBaker[bakerByOp[x.Key]]); - - var opsByBaker = burnedByOp.Keys - .GroupBy(x => Cache.Accounts.GetExistingDelegate(bakerByOp[x]).Id) - .ToDictionary(x => x.Key, x => x.ToList()); - - var res = shares.Keys.ToDictionary(x => x, x => new List<(int stakerId, int cycle, long slashed)>()); - foreach (var (bakerId, bakerRequests) in slashedRequests) - { - var ops = opsByBaker[bakerId]; - foreach (var (stakerId, cycle, totalSlashed) in bakerRequests) - { - var rest = totalSlashed; - foreach (var op in ops) - { - var slashed = (long)Math.Floor(totalSlashed * shares[op]); - res[op].Add((stakerId, cycle, slashed)); - rest -= slashed; - } - var last = res[ops[^1]][^1]; - res[ops[^1]][^1] = (last.stakerId, last.cycle, last.slashed + rest); - } - } - - return res; - } - - async Task> ParseStakingUpdates( - Block block, - BaseOperation operation, - List<(int stakerId, int cycle, long slashed)> unstakeRequests, - IEnumerable balanceUpdates) - { - var bakerAddress = balanceUpdates - .Where(x => x.RequiredString("kind") == "freezer") - .Select(GetFreezerBaker) - .First(); - var baker = Cache.Accounts.GetExistingDelegate(bakerAddress); - var res = new List(); - - var slashedOwn = balanceUpdates - .Where(x => x.RequiredString("kind") == "freezer" && x.RequiredString("category") == "deposits" && IsOwnStake(x)) - .Sum(x => -x.RequiredInt64("change")); - - var slashedExternal = balanceUpdates - .Where(x => x.RequiredString("kind") == "freezer" && x.RequiredString("category") == "deposits" && IsExternalStake(x)) - .Sum(x => -x.RequiredInt64("change")); - - var slashedUnstaked = balanceUpdates - .Where(x => x.RequiredString("kind") == "freezer" && x.RequiredString("category") == "unstaked_deposits" && IsExternalStake(x)) - .GroupBy(x => x.RequiredInt32("cycle")) - .ToDictionary(x => x.Key, x => x.Sum(u => -u.RequiredInt64("change"))); - - #region diagnostics - if (slashedOwn == 0) - throw new Exception("Baker own stake wasn't slashed"); - - var burnedUpdate = balanceUpdates.SingleOrDefault(x => x.RequiredString("kind") == "burned"); - var burned = burnedUpdate.ValueKind != JsonValueKind.Undefined - ? burnedUpdate.RequiredInt64("change") - : 0; - - var rewardUpdate = balanceUpdates.SingleOrDefault(x => x.RequiredString("kind") == "contract"); - var reward = rewardUpdate.ValueKind != JsonValueKind.Undefined - ? rewardUpdate.RequiredInt64("change") - : 0; - - var totalSlashed = slashedOwn + slashedExternal; - if (slashedUnstaked.Count > 0) - totalSlashed += slashedUnstaked.Sum(x => x.Value); - - if (totalSlashed != burned + reward) - throw new Exception("Wrong slashing balance updates"); - - if (balanceUpdates.Where(x => x.RequiredString("kind") == "freezer").Select(GetFreezerBaker).ToHashSet().Count != 1) - throw new Exception("Wrong slashing balance updates"); - #endregion - - #region slash own stake - if (slashedOwn > 0) - { - var stakingUpdate = new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = block.Cycle, - BakerId = baker.Id, - StakerId = baker.Id, - Type = StakingUpdateType.SlashStaked, - Amount = slashedOwn - }; - switch (operation) - { - case DoubleBakingOperation: stakingUpdate.DoubleBakingOpId = operation.Id; break; - case DoubleConsensusOperation: stakingUpdate.DoubleConsensusOpId = operation.Id; break; - default: throw new InvalidOperationException(); - } - res.Add(stakingUpdate); - } - #endregion - - #region slash external stake - if (slashedExternal > 0) - { - var stakers = await Db.Users - .Where(x => x.DelegateId == baker.Id && x.StakedPseudotokens != null) - .OrderBy(x => x.Id) - .ToListAsync(); - - var newExternalStake = baker.ExternalStakedBalance - slashedExternal; - - var updates = new List(stakers.Count); - foreach (var staker in stakers) - { - Cache.Accounts.Add(staker); - - var prevStake = staker.StakedPseudotokens != baker.IssuedPseudotokens - ? (long)((BigInteger)baker.ExternalStakedBalance * staker.StakedPseudotokens!.Value / baker.IssuedPseudotokens!.Value) - : baker.ExternalStakedBalance; - - var newStake = staker.StakedPseudotokens != baker.IssuedPseudotokens - ? (long)((BigInteger)newExternalStake * staker.StakedPseudotokens!.Value / baker.IssuedPseudotokens!.Value) - : newExternalStake; - - if (prevStake != newStake) - { - updates.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = block.Cycle, - BakerId = baker.Id, - StakerId = staker.Id, - Type = StakingUpdateType.SlashStaked, - Amount = prevStake - newStake - }); - } - } - - switch (operation) - { - case DoubleBakingOperation: - foreach (var update in updates) - update.DoubleBakingOpId = operation.Id; - break; - case DoubleConsensusOperation: - foreach (var update in updates) - update.DoubleConsensusOpId = operation.Id; - break; - default: throw new InvalidOperationException(); - } - - var actuallySlashed = updates.Sum(x => x.Amount); - if (actuallySlashed != slashedExternal) - updates[^1].RoundingError = actuallySlashed - slashedExternal; - - res.AddRange(updates); - } - #endregion - - #region slash unstaked - if (unstakeRequests.Count > 0) - { - var updates = new List(unstakeRequests.Count); - foreach (var (stakerId, cycle, amount) in unstakeRequests.OrderBy(x => x.cycle).ThenBy(x => x.stakerId)) - { - updates.Add(new StakingUpdate - { - Id = ++Cache.AppState.Get().StakingUpdatesCount, - Level = block.Level, - Cycle = cycle, - BakerId = baker.Id, - StakerId = stakerId, - Type = StakingUpdateType.SlashUnstaked, - Amount = amount - }); - } - - switch (operation) - { - case DoubleBakingOperation: - foreach (var update in updates) - update.DoubleBakingOpId = operation.Id; - break; - case DoubleConsensusOperation: - foreach (var update in updates) - update.DoubleConsensusOpId = operation.Id; - break; - default: throw new InvalidOperationException(); - } - - foreach (var cycle in unstakeRequests.Select(x => x.cycle).ToHashSet()) - { - var slashed = slashedUnstaked.TryGetValue(cycle, out var v) ? v : 0; - var actuallySlashed = unstakeRequests.Where(x => x.cycle == cycle).Sum(x => x.slashed); - if (actuallySlashed != slashed) - updates.Last(x => x.Cycle == cycle).RoundingError = actuallySlashed - slashed; - } - - res.AddRange(updates); - } - #endregion - - return res; - } - - protected virtual string GetFreezerBaker(JsonElement update) - { - return update.Required("staker").OptionalString("baker") - ?? update.Required("staker").RequiredString("delegate"); - } - - protected virtual bool IsOwnStake(JsonElement update) - { - return update.Required("staker").TryGetProperty("baker", out _); - } - - protected virtual bool IsExternalStake(JsonElement update) - { - return update.Required("staker").TryGetProperty("delegate", out _); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 23bbd2c0d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,196 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SnapshotBalanceCommit(ProtocolHandler protocol) : Proto12.SnapshotBalanceCommit(protocol) - { - protected override Task TakeSnapshot(Block block) - { - return Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "SnapshotBalances" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount", - "OwnStakedBalance", - "ExternalStakedBalance", - "StakersCount", - "Pseudotokens" - ) - - SELECT - {0}, - "Id", - "Id", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount", - "OwnStakedBalance", - "ExternalStakedBalance", - "StakersCount", - "IssuedPseudotokens" - FROM "Accounts" - WHERE "Staked" = true - AND "Type" = {1} - - UNION ALL - - SELECT - {0}, - "DelegateId", - "Id", - "Balance" - (CASE - WHEN "UnstakedBakerId" IS NOT NULL - AND "UnstakedBakerId" != "DelegateId" - THEN "UnstakedBalance" - ELSE 0 - END), - NULL::bigint, - NULL::integer, - NULL::bigint, - NULL::bigint, - NULL::integer, - "StakedPseudotokens" - FROM "Accounts" - WHERE "Staked" = true - AND "Type" != {1} - - UNION ALL - - SELECT - {0}, - account."UnstakedBakerId", - account."Id", - account."UnstakedBalance", - NULL::bigint, - NULL::integer, - NULL::bigint, - NULL::bigint, - NULL::integer, - NULL::numeric - FROM "Accounts" as account - INNER JOIN "Accounts" as unstakedBaker - ON unstakedBaker."Id" = account."UnstakedBakerId" - WHERE unstakedBaker."Staked" = true - AND account."UnstakedBakerId" IS DISTINCT FROM account."DelegateId" - AND account."UnstakedBakerId" != account."Id" - """, block.Level, (int)AccountType.Delegate); - } - - protected override async Task TakeDeactivatedSnapshot(Block block) - { - var deactivated = await Db.Delegates - .AsNoTracking() - .Where(x => x.DeactivationLevel == block.Level) - .ToListAsync(); - - if (deactivated.Count > 0) - { - var values = new List(); - foreach (var baker in deactivated) - { - var delegators = await Db.Accounts.Where(x => x.DelegateId == baker.Id).ToListAsync(); - var unstakers = baker.ExternalUnstakedBalance > 0 - ? await Db.Users - .Where(x => - x.UnstakedBakerId != null && - x.UnstakedBakerId == baker.Id && - x.UnstakedBakerId != x.DelegateId && - x.UnstakedBakerId != x.Id) - .ToListAsync() - : []; - - values.Add("(" + string.Join(',', - block.Level, - baker.Id, - baker.Id, - baker.Balance - baker.OwnStakedBalance - (baker.UnstakedBakerId != null && baker.UnstakedBakerId != baker.Id ? baker.UnstakedBalance : 0), - baker.ExternalDelegatedBalance, - baker.DelegatorsCount, - baker.OwnStakedBalance, - baker.ExternalStakedBalance, - baker.StakersCount, - baker.IssuedPseudotokens ?? (object)"NULL::numeric") + ")"); - - foreach (var delegator in delegators) - { - values.Add("(" + string.Join(',', - block.Level, - delegator.DelegateId, - delegator.Id, - delegator.Balance - (delegator is User user && user.UnstakedBakerId != null && user.UnstakedBakerId != user.DelegateId ? user.UnstakedBalance : 0), - "NULL::bigint", - "NULL::integer", - "NULL::bigint", - "NULL::bigint", - "NULL::integer", - (delegator as User)?.StakedPseudotokens ?? (object)"NULL::numeric") + ")"); - } - - foreach (var unstaker in unstakers) - { - values.Add("(" + string.Join(',', - block.Level, - unstaker.UnstakedBakerId, - unstaker.Id, - unstaker.UnstakedBalance, - "NULL::bigint", - "NULL::integer", - "NULL::bigint", - "NULL::bigint", - "NULL::integer", - "NULL::numeric") + ")"); - } - } - if (values.Count > 0) - { -#pragma warning disable EF1002 // Risk of vulnerability to SQL injection. - await Db.Database.ExecuteSqlRawAsync($""" - INSERT INTO "SnapshotBalances" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount", - "OwnStakedBalance", - "ExternalStakedBalance", - "StakersCount", - "Pseudotokens" - ) - VALUES - {string.Join(",\n", values)} - """); -#pragma warning restore EF1002 // Risk of vulnerability to SQL injection. - } - } - } - - protected override async Task SubtractCycleRewards(JsonElement rawBlock, Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "SnapshotBalances" as sb - SET - "OwnDelegatedBalance" = "OwnDelegatedBalance" - bc."AttestationRewardsDelegated", - "OwnStakedBalance" = "OwnStakedBalance" - bc."AttestationRewardsStakedOwn" - bc."AttestationRewardsStakedEdge", - "ExternalStakedBalance" = "ExternalStakedBalance" - bc."AttestationRewardsStakedShared" - FROM ( - SELECT "BakerId", "AttestationRewardsDelegated", "AttestationRewardsStakedOwn", "AttestationRewardsStakedEdge", "AttestationRewardsStakedShared" - FROM "BakerCycles" - WHERE "Cycle" = {0} - AND ("AttestationRewardsDelegated" != 0 OR "AttestationRewardsStakedOwn" != 0 OR "AttestationRewardsStakedEdge" != 0 OR "AttestationRewardsStakedShared" != 0) - ) as bc - WHERE sb."Level" = {1} - AND sb."BakerId" = bc."BakerId" - AND sb."AccountId" = bc."BakerId" - """, block.Cycle, block.Level); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SoftwareCommit.cs deleted file mode 100644 index b84fb3e07..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StakingUpdateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StakingUpdateCommit.cs deleted file mode 100644 index a57b3df9c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StakingUpdateCommit.cs +++ /dev/null @@ -1,637 +0,0 @@ -using System.Numerics; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class StakingUpdateCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply(IEnumerable updates) - { - foreach (var update in updates) - { - var baker = Cache.Accounts.GetDelegate(update.BakerId); - Db.TryAttach(baker); - baker.StakingUpdatesCount = (baker.StakingUpdatesCount ?? 0) + 1; - baker.LastLevel = update.Level; - - var staker = (User)await Cache.Accounts.GetAsync(update.StakerId); - Db.TryAttach(staker); - if (staker != baker) - { - staker.StakingUpdatesCount = (staker.StakingUpdatesCount ?? 0) + 1; - staker.LastLevel = update.Level; - } - - switch (update.Type) - { - case StakingUpdateType.Stake: - #region stake - if (staker == baker) - { - baker.OwnDelegatedBalance -= update.Amount; - baker.OwnStakedBalance += update.Amount; - - if (baker.Staked) - { - Cache.Statistics.Current.TotalOwnDelegated -= update.Amount; - Cache.Statistics.Current.TotalOwnStaked += update.Amount; - } - } - else - { - staker.Balance -= update.Amount; - - baker.ExternalDelegatedBalance -= update.Amount; - baker.ExternalStakedBalance += update.Amount; - - if (baker.Staked) - { - Cache.Statistics.Current.TotalExternalDelegated -= update.Amount; - Cache.Statistics.Current.TotalExternalStaked += update.Amount; - } - - if (update.Pseudotokens is BigInteger pseudotokens && pseudotokens > BigInteger.Zero) - { - if (staker.StakedPseudotokens == null) - { - baker.StakersCount++; - if (baker.Staked) - Cache.Statistics.Current.TotalStakers++; - } - - staker.StakedPseudotokens = (staker.StakedPseudotokens ?? BigInteger.Zero) + pseudotokens; - baker.IssuedPseudotokens = (baker.IssuedPseudotokens ?? BigInteger.Zero) + pseudotokens; - } - - var stakerCycle = await Cache.StakerCycles.GetOrCreateAsync(Context.Block.Cycle, baker.Id, staker.Id); - Db.TryAttach(stakerCycle); - stakerCycle.AddedStake += update.Amount; - stakerCycle.AvgStake += (long)(update.Amount * GetCycleProgressLeft()); - } - - Cache.Statistics.Current.TotalFrozen += update.Amount; - #endregion - break; - case StakingUpdateType.Unstake: - #region unstake - if (staker == baker) - { - baker.OwnStakedBalance -= update.Amount; - - baker.OwnDelegatedBalance += update.Amount; - baker.UnstakedBalance += update.Amount; - - if (baker.Staked) - { - Cache.Statistics.Current.TotalOwnDelegated += update.Amount; - Cache.Statistics.Current.TotalOwnStaked -= update.Amount; - } - } - else - { - baker.ExternalStakedBalance -= update.Amount; - - staker.Balance += update.Amount; - staker.UnstakedBalance += update.Amount; - baker.ExternalDelegatedBalance += update.Amount; - baker.ExternalUnstakedBalance += update.Amount; - - if (baker.Staked) - { - Cache.Statistics.Current.TotalExternalDelegated += update.Amount; - Cache.Statistics.Current.TotalExternalStaked -= update.Amount; - } - - if (update.Pseudotokens is BigInteger pseudotokens && pseudotokens > BigInteger.Zero) - { - staker.StakedPseudotokens -= pseudotokens; - baker.IssuedPseudotokens -= pseudotokens; - - if (staker.StakedPseudotokens == BigInteger.Zero) - { - baker.StakersCount--; - if (baker.Staked) - Cache.Statistics.Current.TotalStakers--; - - staker.StakedPseudotokens = null; - if (baker.IssuedPseudotokens == BigInteger.Zero) - baker.IssuedPseudotokens = null; - } - } - - var stakerCycle = await Cache.StakerCycles.GetOrCreateAsync(Context.Block.Cycle, baker.Id, staker.Id); - Db.TryAttach(stakerCycle); - stakerCycle.RemovedStake += update.Amount; - stakerCycle.AvgStake -= (long)(update.Amount * GetCycleProgressLeft()); - } - - if (staker.UnstakedBalance > 0) - { - if (staker.UnstakedBakerId == null) - staker.UnstakedBakerId = baker.Id; - else if (staker.UnstakedBakerId != baker.Id) - throw new Exception("Multiple unstaked bakers are not expected"); - } - - await UpdateUnstakeRequests(update); - - Cache.Statistics.Current.TotalFrozen -= update.Amount; - #endregion - break; - case StakingUpdateType.Restake: - #region restake - if (staker != baker) - throw new NotImplementedException("It's expected that only bakers can restake"); - - baker.OwnDelegatedBalance -= update.Amount; - baker.UnstakedBalance -= update.Amount; - - baker.OwnStakedBalance += update.Amount; - - if (baker.Staked) - { - Cache.Statistics.Current.TotalOwnDelegated -= update.Amount; - Cache.Statistics.Current.TotalOwnStaked += update.Amount; - } - - if (baker.UnstakedBalance == 0) - baker.UnstakedBakerId = null; - - await UpdateUnstakeRequests(update); - - Cache.Statistics.Current.TotalFrozen += update.Amount; - #endregion - break; - case StakingUpdateType.Finalize: - #region finalize - if (staker == baker) - { - baker.UnstakedBalance -= update.Amount; - } - else - { - staker.UnstakedBalance -= update.Amount; - - baker.ExternalUnstakedBalance -= update.Amount; - baker.ExternalDelegatedBalance -= update.Amount; - - if (baker.Staked) - Cache.Statistics.Current.TotalExternalDelegated -= update.Amount; - - var currentBaker = staker as Data.Models.Delegate ?? Cache.Accounts.GetDelegate(staker.DelegateId); - if (currentBaker != null) - { - Db.TryAttach(currentBaker); - - if (currentBaker == staker) - { - currentBaker.OwnDelegatedBalance += update.Amount; - if (currentBaker.Staked) - Cache.Statistics.Current.TotalOwnDelegated += update.Amount; - } - else - { - currentBaker.ExternalDelegatedBalance += update.Amount; - if (currentBaker.Staked) - Cache.Statistics.Current.TotalExternalDelegated += update.Amount; - } - - UpdateBakerPower(currentBaker); - } - } - - if (staker.UnstakedBalance == 0) - staker.UnstakedBakerId = null; - - await UpdateUnstakeRequests(update); - #endregion - break; - case StakingUpdateType.SlashStaked: - if (staker == baker) - { - #region slash own staked - baker.Balance -= update.Amount; - baker.OwnStakedBalance -= update.Amount; - - //Cache.Statistics.Current.TotalBurned += update.Amount; - Cache.Statistics.Current.TotalFrozen -= update.Amount; - if (baker.Staked) - Cache.Statistics.Current.TotalOwnStaked -= update.Amount; - #endregion - } - else - { - #region slash external staked - var slashed = update.Amount - (update.RoundingError ?? 0); - baker.ExternalStakedBalance -= slashed; - - //Cache.Statistics.Current.TotalBurned += slashed; - Cache.Statistics.Current.TotalFrozen -= slashed; - if (baker.Staked) - Cache.Statistics.Current.TotalExternalStaked -= slashed; - #endregion - } - break; - case StakingUpdateType.SlashUnstaked: - #region slash unstaked - if (staker == baker) - { - baker.Balance -= update.Amount; - baker.UnstakedBalance -= update.Amount; - baker.OwnDelegatedBalance -= update.Amount; - - if (baker.Staked) - Cache.Statistics.Current.TotalOwnDelegated -= update.Amount; - } - else - { - staker.Balance -= update.Amount; - staker.UnstakedBalance -= update.Amount; - - baker.ExternalUnstakedBalance -= update.Amount; - baker.ExternalDelegatedBalance -= update.Amount; - - if (baker.Staked) - Cache.Statistics.Current.TotalExternalDelegated -= update.Amount; - } - - if (update.RoundingError is long roundingError) - { - baker.ExternalDelegatedBalance += roundingError; - baker.RoundingError += roundingError; - - if (baker.Staked) - Cache.Statistics.Current.TotalExternalDelegated += roundingError; - } - - await UpdateUnstakeRequests(update); - - //Cache.Statistics.Current.TotalBurned += update.Amount; - Cache.Statistics.Current.TotalLost += update.RoundingError ?? 0; - #endregion - break; - default: - throw new Exception("Unexpected staking balance updates behavior"); - } - - UpdateBakerPower(baker); - - Db.StakingUpdates.Add(update); - } - } - - public async Task Revert(IEnumerable updates) - { - foreach (var update in updates) - { - var baker = Cache.Accounts.GetDelegate(update.BakerId); - Db.TryAttach(baker); - baker.StakingUpdatesCount--; - if (baker.StakingUpdatesCount == 0) baker.StakingUpdatesCount = null; - - var staker = (User)await Cache.Accounts.GetAsync(update.StakerId); - Db.TryAttach(staker); - if (staker != baker) - { - staker.StakingUpdatesCount--; - if (staker.StakingUpdatesCount == 0) staker.StakingUpdatesCount = null; - } - - switch (update.Type) - { - case StakingUpdateType.Stake: - #region stake - if (staker == baker) - { - baker.OwnDelegatedBalance += update.Amount; - baker.OwnStakedBalance -= update.Amount; - } - else - { - staker.Balance += update.Amount; - - baker.ExternalDelegatedBalance += update.Amount; - baker.ExternalStakedBalance -= update.Amount; - - if (update.Pseudotokens is BigInteger pseudotokens && pseudotokens > BigInteger.Zero) - { - staker.StakedPseudotokens -= pseudotokens; - baker.IssuedPseudotokens -= pseudotokens; - - if (staker.StakedPseudotokens == BigInteger.Zero) - { - baker.StakersCount--; - staker.StakedPseudotokens = null; - if (baker.IssuedPseudotokens == BigInteger.Zero) - baker.IssuedPseudotokens = null; - } - } - - var stakerCycle = await Cache.StakerCycles.GetOrCreateAsync(Context.Block.Cycle, baker.Id, staker.Id); - Db.TryAttach(stakerCycle); - stakerCycle.AddedStake -= update.Amount; - stakerCycle.AvgStake -= (long)(update.Amount * GetCycleProgressLeft()); - } - #endregion - break; - case StakingUpdateType.Unstake: - #region unstake - await RevertUnstakeRequests(update); - - if (staker.UnstakedBalance == update.Amount) - staker.UnstakedBakerId = null; - - if (staker == baker) - { - baker.OwnDelegatedBalance -= update.Amount; - baker.OwnStakedBalance += update.Amount; - - baker.UnstakedBalance -= update.Amount; - } - else - { - baker.ExternalStakedBalance += update.Amount; - - staker.Balance -= update.Amount; - staker.UnstakedBalance -= update.Amount; - baker.ExternalDelegatedBalance -= update.Amount; - baker.ExternalUnstakedBalance -= update.Amount; - - if (update.Pseudotokens is BigInteger pseudotokens && pseudotokens > BigInteger.Zero) - { - if (staker.StakedPseudotokens == null) - baker.StakersCount++; - - staker.StakedPseudotokens = (staker.StakedPseudotokens ?? BigInteger.Zero) + pseudotokens; - baker.IssuedPseudotokens = (baker.IssuedPseudotokens ?? BigInteger.Zero) + pseudotokens; - } - - var stakerCycle = await Cache.StakerCycles.GetOrCreateAsync(Context.Block.Cycle, baker.Id, staker.Id); - Db.TryAttach(stakerCycle); - stakerCycle.RemovedStake -= update.Amount; - stakerCycle.AvgStake += (long)(update.Amount * GetCycleProgressLeft()); - } - #endregion - break; - case StakingUpdateType.Restake: - #region restake - await RevertUnstakeRequests(update); - - if (baker.UnstakedBalance == 0 && update.Amount > 0) - baker.UnstakedBakerId = baker.Id; - - baker.OwnDelegatedBalance += update.Amount; - baker.UnstakedBalance += update.Amount; - - baker.OwnStakedBalance -= update.Amount; - #endregion - break; - case StakingUpdateType.Finalize: - #region finalize - await RevertUnstakeRequests(update); - - if (staker.UnstakedBalance == 0 && update.Amount > 0) - staker.UnstakedBakerId = baker.Id; - - if (staker == baker) - { - baker.UnstakedBalance += update.Amount; - } - else - { - staker.UnstakedBalance += update.Amount; - - baker.ExternalUnstakedBalance += update.Amount; - baker.ExternalDelegatedBalance += update.Amount; - - var currentBaker = staker as Data.Models.Delegate ?? Cache.Accounts.GetDelegate(staker.DelegateId); - if (currentBaker != null) - { - Db.TryAttach(currentBaker); - - if (currentBaker == staker) - currentBaker.OwnDelegatedBalance -= update.Amount; - else - currentBaker.ExternalDelegatedBalance -= update.Amount; - - RevertBakerPower(currentBaker); - } - } - #endregion - break; - case StakingUpdateType.SlashStaked: - if (staker == baker) - { - #region slash own staked - baker.Balance += update.Amount; - baker.OwnStakedBalance += update.Amount; - #endregion - } - else - { - #region slash external staked - var slashed = update.Amount - (update.RoundingError ?? 0); - baker.ExternalStakedBalance += slashed; - #endregion - } - break; - case StakingUpdateType.SlashUnstaked: - #region slash unstaked - await RevertUnstakeRequests(update); - - if (staker == baker) - { - baker.Balance += update.Amount; - baker.UnstakedBalance += update.Amount; - baker.OwnDelegatedBalance += update.Amount; - } - else - { - staker.Balance += update.Amount; - staker.UnstakedBalance += update.Amount; - - baker.ExternalUnstakedBalance += update.Amount; - baker.ExternalDelegatedBalance += update.Amount; - } - - if (update.RoundingError is long roundingError) - { - baker.ExternalDelegatedBalance -= roundingError; - baker.RoundingError -= roundingError; - } - #endregion - break; - default: - throw new Exception("Unexpected staking event type"); - } - - RevertBakerPower(baker); - - Cache.AppState.Get().StakingUpdatesCount--; - - Db.StakingUpdates.Remove(update); - } - } - - async Task UpdateUnstakeRequests(StakingUpdate update) - { - var bakerUnstaked = await Cache.UnstakeRequests.GetOrDefaultAsync(update.BakerId, null, update.Cycle); - if (bakerUnstaked == null) - { - bakerUnstaked = new UnstakeRequest - { - Id = ++Cache.AppState.Get().UnstakeRequestsCount, - Cycle = update.Cycle, - BakerId = update.BakerId, - StakerId = null, - FirstLevel = update.Level, - }; - Db.UnstakeRequests.Add(bakerUnstaked); - Cache.UnstakeRequests.Add(bakerUnstaked); - } - else - { - Db.TryAttach(bakerUnstaked); - } - - var stakerUnstaked = await Cache.UnstakeRequests.GetOrDefaultAsync(update.BakerId, update.StakerId, update.Cycle); - if (stakerUnstaked == null) - { - stakerUnstaked = new UnstakeRequest - { - Id = ++Cache.AppState.Get().UnstakeRequestsCount, - Cycle = update.Cycle, - BakerId = update.BakerId, - StakerId = update.StakerId, - FirstLevel = update.Level - }; - Db.UnstakeRequests.Add(stakerUnstaked); - Cache.UnstakeRequests.Add(stakerUnstaked); - } - else - { - Db.TryAttach(stakerUnstaked); - } - - if (update.Type == StakingUpdateType.Unstake) - { - bakerUnstaked.RequestedAmount += update.Amount; - stakerUnstaked.RequestedAmount += update.Amount; - } - else if (update.Type == StakingUpdateType.Restake) - { - bakerUnstaked.RestakedAmount += update.Amount; - stakerUnstaked.RestakedAmount += update.Amount; - } - else if (update.Type == StakingUpdateType.Finalize) - { - bakerUnstaked.FinalizedAmount += update.Amount; - stakerUnstaked.FinalizedAmount += update.Amount; - } - else - { - bakerUnstaked.SlashedAmount += update.Amount; - stakerUnstaked.SlashedAmount += update.Amount; - - if (update.RoundingError is long roundingError) - bakerUnstaked.RoundingError = (bakerUnstaked.RoundingError ?? 0) + roundingError; - } - - bakerUnstaked.UpdatesCount++; - stakerUnstaked.UpdatesCount++; - - bakerUnstaked.LastLevel = update.Level; - stakerUnstaked.LastLevel = update.Level; - } - - async Task RevertUnstakeRequests(StakingUpdate update) - { - var bakerUnstaked = await Cache.UnstakeRequests.GetAsync(update.BakerId, null, update.Cycle); - Db.TryAttach(bakerUnstaked); - - var stakerUnstaked = await Cache.UnstakeRequests.GetAsync(update.BakerId, update.StakerId, update.Cycle); - Db.TryAttach(stakerUnstaked); - - if (update.Type == StakingUpdateType.Unstake) - { - bakerUnstaked.RequestedAmount -= update.Amount; - stakerUnstaked.RequestedAmount -= update.Amount; - } - else if (update.Type == StakingUpdateType.Restake) - { - bakerUnstaked.RestakedAmount -= update.Amount; - stakerUnstaked.RestakedAmount -= update.Amount; - } - else if (update.Type == StakingUpdateType.Finalize) - { - bakerUnstaked.FinalizedAmount -= update.Amount; - stakerUnstaked.FinalizedAmount -= update.Amount; - } - else - { - bakerUnstaked.SlashedAmount -= update.Amount; - stakerUnstaked.SlashedAmount -= update.Amount; - - if (update.RoundingError is long roundingError) - { - bakerUnstaked.RoundingError -= roundingError; - if (bakerUnstaked.RoundingError == 0) - bakerUnstaked.RoundingError = null; - } - } - - bakerUnstaked.UpdatesCount--; - stakerUnstaked.UpdatesCount--; - - if (bakerUnstaked.UpdatesCount == 0) - { - Cache.AppState.Get().UnstakeRequestsCount--; - Db.UnstakeRequests.Remove(bakerUnstaked); - Cache.UnstakeRequests.Remove(bakerUnstaked); - } - else - { - var prevUpdate = await Db.StakingUpdates - .AsNoTracking() - .Where(x => - x.BakerId == update.BakerId && - x.Cycle == update.Cycle && - x.Id < update.Id) - .OrderByDescending(x => x.Id) - .FirstAsync(); - - bakerUnstaked.LastLevel = prevUpdate.Level; - } - - if (stakerUnstaked.UpdatesCount == 0) - { - Cache.AppState.Get().UnstakeRequestsCount--; - Db.UnstakeRequests.Remove(stakerUnstaked); - Cache.UnstakeRequests.Remove(stakerUnstaked); - } - else - { - var prevUpdate = await Db.StakingUpdates - .AsNoTracking() - .Where(x => - x.StakerId == update.StakerId && - x.Cycle == update.Cycle && - x.Id < update.Id) - .OrderByDescending(x => x.Id) - .FirstAsync(); - - stakerUnstaked.LastLevel = prevUpdate.Level; - } - } - - double GetCycleProgressLeft() - { - var protocol = Context.Block.Cycle < Context.Protocol.FirstCycle - ? Cache.Protocols.FindByCycle(Context.Block.Cycle) - : Context.Protocol; - - return (protocol.GetCycleEnd(Context.Block.Cycle) - Context.Block.Level) / (double)protocol.BlocksPerCycle; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StateCommit.cs deleted file mode 100644 index e9e471fa0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StatisticsCommit.cs deleted file mode 100644 index ca175efac..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SubsidyCommit.cs deleted file mode 100644 index ccc4c745f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/TicketsCommit.cs deleted file mode 100644 index 347460351..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/TicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class TicketsCommit : Proto16.TicketsCommit - { - public TicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/TokensCommit.cs deleted file mode 100644 index 8f3b2848e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/VotingCommit.cs deleted file mode 100644 index 949240cee..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Diagnostics/Diagnostics.cs deleted file mode 100644 index 99522a3b7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class Diagnostics(ProtocolHandler handler) : Proto16.Diagnostics(handler) - { - protected override bool CheckDelegatedBalance(JsonElement remote, Data.Models.Delegate delegat) - { - return remote.RequiredInt64("delegated_balance") == delegat.ExternalDelegatedBalance + delegat.ExternalStakedBalance; - } - - protected override async Task TestDelegate(int level, Data.Models.Delegate delegat, Protocol proto) - { - await base.TestDelegate(level, delegat, proto); - - var stakingBalance = await Rpc.GetCurrentStakingBalance(level, delegat.Address); - - if (stakingBalance.RequiredInt64("own_frozen") != delegat.OwnStakedBalance) - throw new Exception($"Diagnostics failed: wrong own_frozen balance for {delegat.Address}"); - - if (stakingBalance.RequiredInt64("staked_frozen") != delegat.ExternalStakedBalance) - throw new Exception($"Diagnostics failed: wrong staked_frozen balance for {delegat.Address}"); - - if (stakingBalance.RequiredInt64("delegated") != delegat.TotalDelegated) - throw new Exception($"Diagnostics failed: wrong delegated balance for {delegat.Address}"); - - if (level > proto.FirstLevel) - { - var stakingParameters = await Rpc.GetStakingParameters(level - 1, delegat.Address); - - if (stakingParameters.TryGetProperty("active", out var active)) - { - if (active.RequiredInt64("limit_of_staking_over_baking_millionth") != delegat.LimitOfStakingOverBaking && - active.RequiredInt64("limit_of_staking_over_baking_millionth") != 2147483647) - throw new Exception($"Diagnostics failed: wrong limit_of_staking_over_baking_millionth for {delegat.Address}"); - - if (active.RequiredInt64("edge_of_baking_over_staking_billionth") != delegat.EdgeOfBakingOverStaking) - throw new Exception($"Diagnostics failed: wrong edge_of_baking_over_staking_billionth for {delegat.Address}"); - } - else - { - if (delegat.LimitOfStakingOverBaking != null || delegat.EdgeOfBakingOverStaking != null) - throw new Exception($"Diagnostics failed: wrong staking parameters for {delegat.Address}"); - } - } - } - - protected override async Task TestParticipation(AppState state) - { - var bakers = Cache.Accounts.GetDelegates().ToList(); - var bakerCycles = Db.ChangeTracker.Entries() - .Where(x => x.Entity is BakerCycle bc && bc.Cycle == state.Cycle) - .Select(x => (x.Entity as BakerCycle)!) - .ToDictionary(x => x.BakerId); - - foreach (var baker in bakers) - { - var remote = await Rpc.GetDelegateParticipationAsync(state.Level, baker.Address); - - if (!bakerCycles.TryGetValue(baker.Id, out var bakerCycle)) - bakerCycle = await Db.BakerCycles.FirstOrDefaultAsync(x => x.Cycle == state.Cycle && x.BakerId == baker.Id); - - if (bakerCycle != null) - { - if ((long)bakerCycle.ExpectedAttestations != remote.RequiredInt64("expected_cycle_activity")) - throw new Exception($"Invalid baker ExpectedAttestations {baker.Address}"); - - if (bakerCycle.FutureAttestationRewards != remote.RequiredInt64("expected_attesting_rewards")) - { - if (remote.RequiredInt64("expected_attesting_rewards") != 0 || remote.RequiredInt32("expected_cycle_activity") - remote.RequiredInt32("missed_slots") >= remote.RequiredInt32("minimal_cycle_activity")) - throw new Exception($"Invalid baker FutureAttestationRewards {baker.Address}"); - } - - if (bakerCycle.MissedAttestations != remote.RequiredInt64("missed_slots")) - { - var proto = await Cache.Protocols.GetAsync(state.Protocol); - if (bakerCycle.Cycle != proto.FirstCycle && bakerCycle.BakingPower > 0) - throw new Exception($"Invalid baker MissedAttestations {baker.Address}"); - } - } - else - { - if (remote.RequiredInt64("expected_cycle_activity") != 0) - throw new Exception($"Invalid baker ExpectedAttestations {baker.Address}"); - - if (remote.RequiredInt64("expected_attesting_rewards") != 0) - throw new Exception($"Invalid baker FutureAttestationRewards {baker.Address}"); - - if (remote.RequiredInt64("missed_slots") != 0) - throw new Exception($"Invalid baker MissedAttestations {baker.Address}"); - } - } - } - - protected override async Task TestCycle(AppState state, Cycle cycle) - { - var level = Math.Min(state.Level, cycle.FirstLevel); - var remote = await Rpc.GetCycleAsync(level, cycle.Index); - - if (remote.RequiredString("random_seed") != Hex.Convert(cycle.Seed)) - throw new Exception($"Invalid cycle {cycle.Index} seed {Hex.Convert(cycle.Seed)}"); - - if (remote.RequiredArray("selected_stake_distribution").Count() != cycle.TotalBakers) - throw new Exception($"Invalid cycle {cycle.Index} selected bakers {cycle.TotalBakers}"); - - if (remote.Required("total_active_stake").RequiredInt64("frozen") + remote.Required("total_active_stake").RequiredInt64("delegated") != cycle.TotalBakingPower) - throw new Exception($"Invalid cycle {cycle.Index} selected stake {cycle.TotalBakingPower}"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Helpers.cs deleted file mode 100644 index 9e87f00d0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Helpers.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - public class Helpers(ProtocolHandler proto) : Proto13.Helpers(proto) - { - public override long BakingPower(Data.Models.Delegate baker) - { - if (!baker.Staked) - return 0; - - if (baker.OwnStakedBalance < Context.Protocol.MinimalFrozenStake) - return 0; - - var externalStakeCap = 0L; - if (baker.LimitOfStakingOverBaking is long limit) - { - var (q, r) = Math.DivRem(limit, 1_000_000); - if (r == 0) - { - externalStakeCap = baker.OwnStakedBalance * Math.Min(q, Context.Protocol.MaxExternalOverOwnStakeRatio); - } - else - { - var limitOfStakingOverBaking = Math.Min(limit, Context.Protocol.MaxExternalOverOwnStakeRatio * 1_000_000); - externalStakeCap = baker.OwnStakedBalance.MulRatio(limitOfStakingOverBaking, 1_000_000); - } - } - var overstaked = Math.Max(0, baker.ExternalStakedBalance - externalStakeCap); - var totalDelegated = baker.OwnDelegatedBalance + baker.ExternalDelegatedBalance + overstaked; - var delegationCap = baker.OwnStakedBalance * Context.Protocol.MaxDelegatedOverFrozenRatio; - - var actualStaked = baker.OwnStakedBalance + baker.ExternalStakedBalance - overstaked; - var actualDelegated = Math.Min(totalDelegated, delegationCap); - - var state = Cache.AppState.Get(); - if (state.AiActivationLevel is int aiLevel && state.Level >= aiLevel) - actualDelegated /= Context.Protocol.StakePowerMultiplier; - - var stake = actualStaked + actualDelegated; - if (stake < Context.Protocol.MinimalStake) - return 0; - - return stake; - } - public override long VotingPower(Data.Models.Delegate baker) - { - if (!baker.Staked) - return 0; - - var stake = baker.OwnStakedBalance + baker.ExternalStakedBalance + baker.OwnDelegatedBalance + baker.ExternalDelegatedBalance; - if (stake < Context.Protocol.MinimalStake) - return 0; - - return stake; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Proto18Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Proto18Handler.cs deleted file mode 100644 index 49bd17894..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Proto18Handler.cs +++ /dev/null @@ -1,498 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto18; - -namespace Tzkt.Sync.Protocols -{ - class Proto18Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "oxford_018"; - public override int VersionNumber => 18; - - public Proto18Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SetDelegateParametersCommit(this).ActivateStakingParameters(blockCommit.Block); - await new UpdateSecondaryKeyCommit(this).ActivateSecondaryKeys(blockCommit.Block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "attestation": - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preattestation": - case "preendorsement": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - case "double_preendorsement_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - var ticketsCommit = new TicketsCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var dst = content.RequiredString("destination"); - if (dst.StartsWith("tz") && content.Optional("parameters")?.RequiredString("entrypoint") is string entrypoint) - { - if (StakingCommit.ValidateParameters(entrypoint, content.RequiredString("source"), dst)) - { - await new StakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - else if (SetDelegateParametersCommit.Entrypoint == entrypoint) - { - await new SetDelegateParametersCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - } - - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - if (parent.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, parent.Transaction, parent.TicketUpdates); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (parent1.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, parent1.Operation, parent1.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await blockCommit.ApplyRewards(block); - - new InboxCommit(this).Apply(blockCommit.Block); - - await bigMapCommit.Apply(); - await ticketsCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - await new SlashingCommit(this).Apply(block, rawBlock); - await new VotingCommit(this).Apply(block, rawBlock); - await new AutostakingCommit(this).Apply(block, rawBlock); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new AutostakingCommit(this).Revert(block); - await new VotingCommit(this).Revert(block); - await new SlashingCommit(this).Revert(block); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new TicketsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - await new BlockCommit(this).RevertRewards(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case StakingOperation op: - await new StakingCommit(this).Revert(currBlock, op); - break; - case SetDelegateParametersOperation op: - await new SetDelegateParametersCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new UpdateSecondaryKeyCommit(this).DeactivateSecondaryKeys(currBlock); - await new SetDelegateParametersCommit(this).DeactivateStakingParameters(currBlock); - await new CycleCommit(this).Revert(currBlock); - new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Rpc/Rpc.cs deleted file mode 100644 index c4cf81ed0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Rpc/Rpc.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto18 -{ - class Rpc : Proto16.Rpc - { - public Rpc(TezosNode node) : base(node) { } - - public override Task GetExpectedIssuance(int level) - => Node.GetAsync($"chains/main/blocks/{level}/context/issuance/expected_issuance"); - - public override Task GetSmartRollupGenesisInfo(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/smart_rollups/smart_rollup/{address}/genesis_info"); - - public override Task GetCurrentStakingBalance(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/raw/json/staking_balance/current/{address}"); - - public override Task GetStakingParameters(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/raw/json/contracts/index/{address}/staking_parameters"); - - public override Task GetUnstakeRequests(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/contracts/{address}/unstake_requests"); - - public override Task GetContractRawAsync(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/raw/json/contracts/index/{address}"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto18/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto18/Validation/Validator.cs deleted file mode 100644 index e1048203c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto18/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto18 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Activation/ProtoActivator.cs deleted file mode 100644 index 16ecd0ec1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Activation/ProtoActivator.cs +++ /dev/null @@ -1,320 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto18.ProtoActivator(proto) - { - protected override void BootstrapStakerCycles(Protocol protocol, List accounts) - { - Db.StakerCycles.AddRange(accounts - .Where(x => x is User user && user.StakedPseudotokens != null) - .Select(x => - { - var user = (x as User)!; - var baker = Cache.Accounts.GetDelegate(x.DelegateId!.Value); - var stakedBalance = (long)(baker.ExternalStakedBalance * user.StakedPseudotokens!.Value / baker.IssuedPseudotokens!.Value); - return new StakerCycle - { - Id = 0, - Cycle = 0, - BakerId = x.DelegateId!.Value, - StakerId = x.Id, - InitialStake = stakedBalance, - AvgStake = stakedBalance, - }; - })); - } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.ConsensusRightsDelay = parameters["consensus_rights_delay"]?.Value() ?? 2; - protocol.ToleratedInactivityPeriod = protocol.ConsensusRightsDelay + 1; - protocol.DelegateParametersActivationDelay = parameters["delegate_parameters_activation_delay"]?.Value() ?? 5; - protocol.DoubleBakingSlashedPercentage = parameters["percentage_of_frozen_deposits_slashed_per_double_baking"]?.Value() ?? 500; - protocol.DoubleConsensusSlashedPercentage = parameters["percentage_of_frozen_deposits_slashed_per_double_attestation"]?.Value() ?? 5000; - protocol.NumberOfShards = parameters["dal_parametric"]?["number_of_shards"]?.Value() ?? 512; - protocol.BlocksPerSnapshot = protocol.BlocksPerCycle; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - if (protocol.ConsensusRightsDelay == 5) - { - protocol.ConsensusRightsDelay = 2; - protocol.ToleratedInactivityPeriod = protocol.ConsensusRightsDelay + 1; - } - - if (protocol.TimeBetweenBlocks >= 8) - { - protocol.BlocksPerCycle = protocol.BlocksPerCycle * 3 / 2; - protocol.BlocksPerCommitment = protocol.BlocksPerCommitment * 3 / 2; - protocol.BlocksPerVoting = protocol.BlocksPerVoting * 3 / 2; - protocol.TimeBetweenBlocks = protocol.TimeBetweenBlocks * 2 / 3; - protocol.HardBlockGasLimit = prev.HardBlockGasLimit * 2 / 3; - protocol.SmartRollupCommitmentPeriod = 15 * 60 / protocol.TimeBetweenBlocks; - protocol.SmartRollupChallengeWindow = 14 * 24 * 60 * 60 / protocol.TimeBetweenBlocks; - protocol.SmartRollupTimeoutPeriod = 7 * 24 * 60 * 60 / protocol.TimeBetweenBlocks; - } - - protocol.BlocksPerSnapshot = protocol.BlocksPerCycle; - protocol.NumberOfShards = 512; - } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - await RemoveDeadRefutationGames(state); - await RemoveFutureCycles(state, prevProto, nextProto); - MigrateBakers(state, prevProto, nextProto); - await MigrateVotingPeriods(state, nextProto); - var cycles = await MigrateCycles(state, nextProto); - await MigrateFutureRights(state, nextProto, cycles); - - Cache.BakerCycles.Reset(); - Cache.BakingRights.Reset(); - } - - async Task RemoveFutureCycles(AppState state, Protocol prevProto, Protocol nextProto) - { - if (prevProto.ConsensusRightsDelay == nextProto.ConsensusRightsDelay) - return; - - var lastCycle = state.Cycle + nextProto.ConsensusRightsDelay + 1; - var lastCycleStart = nextProto.GetCycleStart(lastCycle); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakerCycles" - WHERE "Cycle" > {0} - """, lastCycle); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Type" = {0} - AND "Cycle" > {1}; - - DELETE FROM "BakingRights" - WHERE "Type" = {2} - AND "Level" > {3}; - """, - (int)BakingRightType.Baking, - lastCycle, - (int)BakingRightType.Attestation, - lastCycleStart); - - var removedCycles = await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Cycles" - WHERE "Index" > {0} - """, lastCycle); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "DelegatorCycles" - WHERE "Cycle" > {0} - """, lastCycle); - - Cache.BakerCycles.Reset(); - Cache.BakingRights.Reset(); - - Db.TryAttach(state); - state.CyclesCount -= removedCycles; - } - - void MigrateBakers(AppState state, Protocol prevProto, Protocol nextProto) - { - foreach (var baker in Cache.Accounts.GetDelegates()) - { - Db.TryAttach(baker); - baker.MinTotalDelegated = baker.TotalDelegated; - baker.MinTotalDelegatedLevel = state.Level; - - if (baker.DeactivationLevel > state.Level) - baker.DeactivationLevel = nextProto.GetCycleStart(prevProto.GetCycle(baker.DeactivationLevel)); - } - } - - async Task MigrateVotingPeriods(AppState state, Protocol nextProto) - { - var newPeriod = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(newPeriod); - newPeriod.LastLevel = newPeriod.FirstLevel + nextProto.BlocksPerVoting - 1; - } - - async Task> MigrateCycles(AppState state, Protocol nextProto) - { - var cycles = await Db.Cycles - .Where(x => x.Index >= state.Cycle) - .OrderBy(x => x.Index) - .ToListAsync(); - - var res = await Proto.Rpc.GetExpectedIssuance(state.Level); - var issuance = res.EnumerateArray().First(x => x.RequiredInt32("cycle") == cycles.First(x => x.Index > state.Cycle).Index); - - foreach (var cycle in cycles.Where(x => x.Index > state.Cycle)) - { - cycle.BlockReward = issuance.RequiredInt64("baking_reward_fixed_portion"); - cycle.BlockBonusPerBlock = GetBlockBonusPerBlock(issuance, nextProto); - cycle.AttestationRewardPerBlock = GetAttestationRewardPerBlock(issuance, nextProto); - cycle.NonceRevelationReward = issuance.RequiredInt64("seed_nonce_revelation_tip"); - cycle.VdfRevelationReward = issuance.RequiredInt64("vdf_revelation_tip"); - - cycle.FirstLevel = nextProto.GetCycleStart(cycle.Index); - cycle.LastLevel = nextProto.GetCycleEnd(cycle.Index); - } - - return cycles; - } - - async Task MigrateFutureRights(AppState state, Protocol nextProto, List cycles) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" > {0} - """, state.Cycle); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - IEnumerable shifted = []; - - foreach (var cycle in cycles) - { - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - var sampler = GetSampler(bakerCycles.Values - .Where(x => x.BakingPower > 0) - .Select(x => (x.BakerId, x.BakingPower)) - .ToList()); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, cycle.Index); - #endregion - - if (cycle.Index == state.Cycle) - { - shifted = RightsGenerator.GetAttestationRights(sampler, nextProto, cycle, cycle.LastLevel); - - #region save shifted - using var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """); - - foreach (var ar in shifted) - { - writer.StartRow(); - writer.Write(cycle.Index + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - writer.Complete(); - #endregion - } - else - { - GC.Collect(); - var brs = await RightsGenerator.GetBakingRightsAsync(sampler, nextProto, cycle); - var ars = await RightsGenerator.GetAttestationRightsAsync(sampler, nextProto, cycle); - - #region save rights - using (var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """)) - { - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(nextProto.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - - #region reset baker cycles - var attestationRewardPerSlot = cycle.AttestationRewardPerBlock / nextProto.AttestersPerBlock; - var maxBlockReward = cycle.BlockReward + cycle.BlockBonusPerBlock; - - foreach (var bakerCycle in bakerCycles.Values) - { - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks = 0; - bakerCycle.FutureBlockRewards = 0; - bakerCycle.FutureAttestations = 0; - - var expectedAttestations = (nextProto.BlocksPerCycle * nextProto.AttestersPerBlock).MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedBlocks = nextProto.BlocksPerCycle.MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = expectedAttestations * attestationRewardPerSlot; - } - - foreach (var br in brs.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += maxBlockReward; - } - - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots; - } - } - - foreach (var ar in ars.TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - shifted = [..ars.Where(x => x.Level == cycle.LastLevel)]; - } - } - } - - protected override Sampler GetSampler(IEnumerable<(int id, long stake)> selection) - { - var sorted = selection.OrderByDescending(x => - { - var baker = Cache.Accounts.GetDelegate(x.id); - return new byte[] { (byte)baker.PublicKey![0] }.Concat(Base58.Parse(baker.Address)); - }, new BytesComparer()); - - return new Sampler([..sorted.Select(x => x.id)], [..sorted.Select(x => x.stake)]); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/AttestationRewardCommit.cs deleted file mode 100644 index a9f75555b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class AttestationRewardCommit(ProtocolHandler protocol) : Proto18.AttestationRewardCommit(protocol) - { - public override async Task Apply(Block block, JsonElement rawBlock) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - var state = Cache.AppState.Get(); - var bakerCycles = await Cache.BakerCycles.GetAsync(block.Cycle); - var ops = bakerCycles - .Where(x => x.Value.FutureAttestationRewards > 0) - .ToDictionary( - x => x.Key, - bakerCycle => new AttestationRewardOperation - { - Id = Cache.AppState.NextOperationId(), - BakerId = bakerCycle.Key, - Level = block.Level, - Timestamp = block.Timestamp, - Expected = bakerCycle.Value.FutureAttestationRewards - }); - - var balanceUpdates = rawBlock.Required("metadata").RequiredArray("balance_updates").EnumerateArray().Where(x => x.RequiredString("origin") == "block").ToList(); - for (int i = 0; i < balanceUpdates.Count; i++) - { - var update = balanceUpdates[i]; - if (update.RequiredString("kind") == "minted" && update.RequiredString("category") == "attesting rewards") - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected attestation rewards balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredInt64("change") != change) - throw new Exception("Unexpected attestation rewards balance updates behavior"); - - if (nextUpdate.RequiredString("kind") == "freezer" && nextUpdate.RequiredString("category") == "deposits") - { - var staker = nextUpdate.Required("staker"); - if (staker.TryGetProperty("baker_own_stake", out var p)) - { - var baker = Cache.Accounts.GetExistingDelegate(p.RequiredString()); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected attestation rewards balance update"); - - op.RewardStakedOwn += change; - } - else if (staker.TryGetProperty("baker_edge", out p)) - { - var baker = Cache.Accounts.GetExistingDelegate(p.RequiredString()); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected attestation rewards balance update"); - - op.RewardStakedEdge += change; - } - else if (staker.TryGetProperty("delegate", out p)) - { - var baker = Cache.Accounts.GetExistingDelegate(p.RequiredString()); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected attestation rewards balance update"); - - op.RewardStakedShared += change; - } - else - { - throw new Exception("Unexpected attestation rewards balance updates behavior"); - } - } - else if (nextUpdate.RequiredString("kind") == "contract") - { - var baker = Cache.Accounts.GetExistingDelegate(nextUpdate.RequiredString("contract")); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected attestation rewards balance update"); - - op.RewardDelegated = change; - } - else if (nextUpdate.RequiredString("kind") == "burned" && nextUpdate.RequiredString("category") == "lost attesting rewards") - { - var baker = Cache.Accounts.GetExistingDelegate(nextUpdate.RequiredString("delegate")); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected attestation rewards balance update"); - - if (op.Expected != change) - throw new Exception("FutureAttestationRewards != loss"); - - op.RewardDelegated = 0; - op.RewardStakedOwn = 0; - op.RewardStakedEdge = 0; - op.RewardStakedShared = 0; - } - else - { - throw new Exception("Unexpected attestation rewards balance updates behavior"); - } - } - } - - foreach (var op in ops.Values) - { - var bakerCycle = bakerCycles[op.BakerId]; - Db.TryAttach(bakerCycle); - - bakerCycle.FutureAttestationRewards = 0; - if (op.RewardDelegated != 0 || op.RewardStakedOwn != 0 || op.RewardStakedEdge != 0 || op.RewardStakedShared != 0) - { - if (op.Expected != op.RewardDelegated + op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared) - throw new Exception("ExpectedReward != RewardFrozen + RewardDelegated"); - - bakerCycle.AttestationRewardsDelegated = op.RewardDelegated; - bakerCycle.AttestationRewardsStakedOwn = op.RewardStakedOwn; - bakerCycle.AttestationRewardsStakedEdge = op.RewardStakedEdge; - bakerCycle.AttestationRewardsStakedShared = op.RewardStakedShared; - } - else - { - bakerCycle.MissedAttestationRewards = op.Expected; - } - - - var baker = Cache.Accounts.GetDelegate(op.BakerId); - Db.TryAttach(baker); - - ReceiveRewards(baker, op.RewardDelegated, op.RewardStakedOwn, op.RewardStakedEdge, op.RewardStakedShared); - baker.AttestationRewardsCount++; - - block.Operations |= Operations.AttestationRewards; - - Cache.Statistics.Current.TotalCreated += op.RewardDelegated + op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared; - Cache.Statistics.Current.TotalFrozen += op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared; - } - - Cache.AppState.Get().AttestationRewardOpsCount += ops.Count; - - Db.AttestationRewardOps.AddRange(ops.Values); - Context.AttestationRewardOps.AddRange(ops.Values); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/AutostakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/AutostakingCommit.cs deleted file mode 100644 index d38c7fb69..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/AutostakingCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class AutostakingCommit : Proto18.AutostakingCommit - { - public AutostakingCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override string GetFreezerBaker(JsonElement update) - { - return update.Required("staker").RequiredString("baker_own_stake"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BakerCycleCommit.cs deleted file mode 100644 index 7d712a60c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class BakerCycleCommit : Proto18.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override async Task ApplyNewCycle( - Block block, - Cycle futureCycle, - IEnumerable futureBakingRights, - IEnumerable futureAttestationRights, - List snapshots, - Dictionary selectedStakes) - { - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - return; - } - - await base.ApplyNewCycle(block, futureCycle, futureBakingRights, futureAttestationRights, snapshots, selectedStakes); - } - - protected override async Task RevertNewCycle(Block block) - { - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - return; - } - - await base.RevertNewCycle(block); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BakingRightsCommit.cs deleted file mode 100644 index 4409fa9ef..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class BakingRightsCommit : Proto16.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override async Task ApplyNewCycle(Block block, Cycle futureCycle, Dictionary selectedStakes) - { - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - return; - } - - await base.ApplyNewCycle(block, futureCycle, selectedStakes); - } - - public override async Task RevertNewCycle(Block block) - { - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - return; - } - - await base.RevertNewCycle(block); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BigMapCommit.cs deleted file mode 100644 index 952550a55..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BlockCommit.cs deleted file mode 100644 index c02f64393..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/BlockCommit.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class BlockCommit(ProtocolHandler protocol) : Proto18.BlockCommit(protocol) - { - public override async Task Apply(JsonElement rawBlock) - { - await base.Apply(rawBlock); - - var state = Cache.AppState.Get(); - if (state.AiActivationLevel is null) - { - if (rawBlock.Required("metadata").OptionalInt32("adaptive_issuance_activation_cycle") is int aiCycle && aiCycle == state.Cycle) - { - state.AiActivationLevel = Block.Level; - UpdateBakersPower(); - } - } - } - - public override void Revert(Block block) - { - var state = Cache.AppState.Get(); - if (state.AiActivationLevel == block.Level) - { - state.AiActivationLevel = null; - RevertBakersPower(); - } - - base.Revert(block); - } - - protected override (long, long, long, long, long, long, long, long) ParseRewards(Data.Models.Delegate proposer, Data.Models.Delegate producer, List balanceUpdates) - { - var rewardDelegated = 0L; - var rewardStakedOwn = 0L; - var rewardStakedEdge = 0L; - var rewardStakedShared = 0L; - var bonusDelegated = 0L; - var bonusStakedOwn = 0L; - var bonusStakedEdge = 0L; - var bonusStakedShared = 0L; - - for (int i = 0; i < balanceUpdates.Count; i++) - { - var update = balanceUpdates[i]; - if (update.RequiredString("kind") == "minted" && update.RequiredString("category") == "baking rewards") - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected baking rewards balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredInt64("change") != change) - throw new Exception("Unexpected baking rewards balance updates behavior"); - - if (nextUpdate.RequiredString("kind") == "freezer" && nextUpdate.RequiredString("category") == "deposits") - { - var staker = nextUpdate.Required("staker"); - if (staker.TryGetProperty("baker_own_stake", out var p) && p.GetString() == proposer.Address) - { - rewardStakedOwn += change; - } - else if (staker.TryGetProperty("baker_edge", out p) && p.GetString() == proposer.Address) - { - rewardStakedEdge += change; - } - else if (staker.TryGetProperty("delegate", out p) && p.GetString() == proposer.Address) - { - rewardStakedShared += change; - } - else - { - throw new Exception("Unexpected baking rewards balance updates behavior"); - } - } - else if (nextUpdate.RequiredString("kind") == "contract" && nextUpdate.RequiredString("contract") == proposer.Address) - { - rewardDelegated += change; - } - else - { - throw new Exception("Unexpected baking rewards balance updates behavior"); - } - } - else if (update.RequiredString("kind") == "minted" && update.RequiredString("category") == "baking bonuses") - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected baking bonuses balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredInt64("change") != change) - throw new Exception("Unexpected baking bonuses balance updates behavior"); - - if (nextUpdate.RequiredString("kind") == "freezer" && nextUpdate.RequiredString("category") == "deposits") - { - var staker = nextUpdate.Required("staker"); - if (staker.TryGetProperty("baker_own_stake", out var p) && p.GetString() == producer.Address) - { - bonusStakedOwn += change; - } - else if (staker.TryGetProperty("baker_edge", out p) && p.GetString() == producer.Address) - { - bonusStakedEdge += change; - } - else if (staker.TryGetProperty("delegate", out p) && p.GetString() == producer.Address) - { - bonusStakedShared += change; - } - else - { - throw new Exception("Unexpected baking bonuses balance updates behavior"); - } - } - else if (nextUpdate.RequiredString("kind") == "contract" && nextUpdate.RequiredString("contract") == producer.Address) - { - bonusDelegated += change; - } - else - { - throw new Exception("Unexpected baking bonuses balance updates behavior"); - } - } - } - - return (rewardDelegated, rewardStakedOwn, rewardStakedEdge, rewardStakedShared, bonusDelegated, bonusStakedOwn, bonusStakedEdge, bonusStakedShared); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/ContractEventCommit.cs deleted file mode 100644 index a49b6397f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class ContractEventCommit : Proto14.ContractEventCommit - { - public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/CycleCommit.cs deleted file mode 100644 index 2acdb446f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/CycleCommit.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class CycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Cycle? FutureCycle { get; protected set; } - public List? Snapshots { get; protected set; } - public Dictionary? SelectedStakes { get; protected set; } - - public async Task Apply(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - { - Cache.AppState.Get().CyclesCount--; - return; - } - } - - var index = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - var contextTask = Proto.Rpc.GetCycleAsync(block.Level, index); - var issuanceTask = Proto.Rpc.GetExpectedIssuance(block.Level); - await Task.WhenAll(contextTask, issuanceTask); - - var context = await contextTask; - var issuance = await issuanceTask; - var cycleIssuance = issuance.EnumerateArray().First(x => x.RequiredInt32("cycle") == index); - - SelectedStakes = context.RequiredArray("selected_stake_distribution") - .EnumerateArray() - .ToDictionary( - x => Cache.Accounts.GetExistingDelegate(x.RequiredString("baker")).Id, - x => x.Required("active_stake").RequiredInt64("frozen") + x.Required("active_stake").RequiredInt64("delegated")); - - Snapshots = await Db.SnapshotBalances - .AsNoTracking() - .Where(x => x.Level == block.Level - 1 && x.BakerId == x.AccountId) - .ToListAsync(); - - FutureCycle = new Cycle - { - Id = 0, - Index = index, - FirstLevel = Context.Protocol.GetCycleStart(index), - LastLevel = Context.Protocol.GetCycleEnd(index), - SnapshotLevel = block.Level - 1, - TotalBakers = SelectedStakes.Count, - TotalBakingPower = SelectedStakes.Values.Sum(), - Seed = Hex.Parse(context.RequiredString("random_seed")), - BlockReward = cycleIssuance.RequiredInt64("baking_reward_fixed_portion"), - BlockBonusPerBlock = cycleIssuance.RequiredInt64("baking_reward_bonus_per_slot") * (Context.Protocol.AttestersPerBlock - Context.Protocol.ConsensusThreshold), - AttestationRewardPerBlock = cycleIssuance.RequiredInt64("attesting_reward_per_slot") * Context.Protocol.AttestersPerBlock, - NonceRevelationReward = cycleIssuance.RequiredInt64("seed_nonce_revelation_tip"), - VdfRevelationReward = cycleIssuance.RequiredInt64("vdf_revelation_tip") - }; - - Db.Cycles.Add(FutureCycle); - } - - public async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - { - Cache.AppState.Get().CyclesCount++; - return; - } - } - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Cycles" - WHERE "Index" = {0} - """, block.Cycle + Context.Protocol.ConsensusRightsDelay); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DeactivationCommit.cs deleted file mode 100644 index 1ecd11602..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DelegationSnapshotCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DelegationSnapshotCommit.cs deleted file mode 100644 index f6c23b6b0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DelegationSnapshotCommit.cs +++ /dev/null @@ -1,225 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class DelegationSnapshotCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply() - { - if (Context.Block.Events.HasFlag(BlockEvents.CycleBegin)) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "DelegationSnapshots" - WHERE "Level" < {0} - """, Context.Block.Level - Context.Protocol.BlocksPerCycle); - - await Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "DelegationSnapshots" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount", - "PrevMinTotalDelegatedLevel", - "PrevMinTotalDelegated" - ) - - SELECT - {0}, - "Id", - "Id", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount", - "MinTotalDelegatedLevel", - "MinTotalDelegated" - FROM "Accounts" - WHERE "Type" = {1} - - UNION ALL - - SELECT - {0}, - "DelegateId", - "Id", - "Balance" - (CASE - WHEN "UnstakedBakerId" IS NOT NULL AND "UnstakedBakerId" != "DelegateId" - THEN "UnstakedBalance" - ELSE 0 - END), - NULL::bigint, - NULL::integer, - NULL::integer, - NULL::bigint - FROM "Accounts" - WHERE "Type" != {1} - AND "DelegateId" IS NOT NULL - - UNION ALL - - SELECT - {0}, - "UnstakedBakerId", - "Id", - "UnstakedBalance", - NULL::bigint, - NULL::integer, - NULL::integer, - NULL::bigint - FROM "Accounts" - WHERE "UnstakedBakerId" IS NOT NULL - AND "UnstakedBakerId" IS DISTINCT FROM "DelegateId" - AND "UnstakedBakerId" != "Id" - """, Context.Block.Level, (int)AccountType.Delegate); - - foreach (var baker in Cache.Accounts.GetDelegates()) - { - baker.MinTotalDelegated = baker.TotalDelegated; - baker.MinTotalDelegatedLevel = Context.Block.Level; - } - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "Accounts" - SET "MinTotalDelegated" = "OwnDelegatedBalance" + "ExternalDelegatedBalance", - "MinTotalDelegatedLevel" = {0} - WHERE "Type" = {1} - """, Context.Block.Level, (int)AccountType.Delegate); - - await SetBlockEvent(); - } - else if (Cache.Accounts.GetDelegates().Any(x => x.TotalDelegated < x.MinTotalDelegated)) - { - var bakers = Cache.Accounts.GetDelegates() - .Where(x => x.TotalDelegated < x.MinTotalDelegated) - .ToList(); - - var ids = bakers.Select(x => x.Id).ToList(); - - await Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "DelegationSnapshots" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount", - "PrevMinTotalDelegatedLevel", - "PrevMinTotalDelegated" - ) - - SELECT - {0}, - "Id", - "Id", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount", - "MinTotalDelegatedLevel", - "MinTotalDelegated" - FROM "Accounts" - WHERE "Id" = ANY({1}) - - UNION ALL - - SELECT - {0}, - "DelegateId", - "Id", - "Balance" - (CASE - WHEN "UnstakedBakerId" IS NOT NULL AND "UnstakedBakerId" != "DelegateId" - THEN "UnstakedBalance" - ELSE 0 - END), - NULL::bigint, - NULL::integer, - NULL::integer, - NULL::bigint - FROM "Accounts" - WHERE "DelegateId" = ANY({1}) - AND "DelegateId" != "Id" - - UNION ALL - - SELECT - {0}, - "UnstakedBakerId", - "Id", - "UnstakedBalance", - NULL::bigint, - NULL::integer, - NULL::integer, - NULL::bigint - FROM "Accounts" - WHERE "UnstakedBakerId" = ANY({1}) - AND "UnstakedBakerId" IS DISTINCT FROM "DelegateId" - AND "UnstakedBakerId" != "Id" - """, Context.Block.Level, ids); - - foreach (var baker in bakers) - { - baker.MinTotalDelegated = baker.TotalDelegated; - baker.MinTotalDelegatedLevel = Context.Block.Level; - } - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "Accounts" - SET "MinTotalDelegated" = "OwnDelegatedBalance" + "ExternalDelegatedBalance", - "MinTotalDelegatedLevel" = {0} - WHERE "Id" = ANY({1}) - """, Context.Block.Level, ids); - - await SetBlockEvent(); - } - } - - public async Task Revert() - { - if (!Context.Block.Events.HasFlag(BlockEvents.DelegationSnapshot)) - return; - - var bakerSnapshots = await Db.DelegationSnapshots - .AsNoTracking() - .Where(x => x.Level == Context.Block.Level && x.BakerId == x.AccountId) - .ToListAsync(); - - foreach (var snapshot in bakerSnapshots) - { - var baker = Cache.Accounts.GetDelegate(snapshot.BakerId); - baker.MinTotalDelegated = snapshot.PrevMinTotalDelegated!.Value; - baker.MinTotalDelegatedLevel = snapshot.PrevMinTotalDelegatedLevel!.Value; - } - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "Accounts" AS baker - SET "MinTotalDelegated" = snapshot."PrevMinTotalDelegated", - "MinTotalDelegatedLevel" = snapshot."PrevMinTotalDelegatedLevel" - FROM ( - SELECT "BakerId", "PrevMinTotalDelegatedLevel", "PrevMinTotalDelegated" - FROM "DelegationSnapshots" - WHERE "Level" = {0} - AND "BakerId" = "AccountId" - ) AS snapshot - WHERE baker."Id" = snapshot."BakerId" - """, Context.Block.Level); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "DelegationSnapshots" - WHERE "Level" = {0} - """, Context.Block.Level); - } - - async Task SetBlockEvent() - { - var block = Cache.Blocks.GetCached(Context.Block.Level); - block.Events |= BlockEvents.DelegationSnapshot; - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "Blocks" - SET "Events" = "Events" & {0} - WHERE "Level" = {1} - """, BlockEvents.DelegationSnapshot, block.Level); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 1979df2e2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class DelegatorCycleCommit(ProtocolHandler protocol) : Proto18.DelegatorCycleCommit(protocol) - { - public override async Task Apply(Block block, Cycle? futureCycle) - { - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - return; - } - - await base.Apply(block, futureCycle); - } - - public override async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - return; - } - - await base.Revert(block); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/InboxCommit.cs deleted file mode 100644 index cc1118ba2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/InboxCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - public class InboxCommit : Proto17.InboxCommit - { - public InboxCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 5fb0b124f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 5c98c733c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class AttestationsCommit(ProtocolHandler protocol) : Proto12.AttestationsCommit(protocol) - { - protected override long GetPower(JsonElement metadata) - { - return metadata.RequiredInt64("consensus_power"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 1d4563ddd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DalPublishCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DalPublishCommitmentCommit.cs deleted file mode 100644 index 0492fc682..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DalPublishCommitmentCommit.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class DalPublishCommitmentCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var sender = (await Cache.Accounts.GetExistingAsync(content.RequiredString("source")) as User)!; - - var result = content.Required("metadata").Required("operation_result"); - var operation = new DalPublishCommitmentOperation - { - Id = Cache.AppState.NextOperationId(), - OpHash = op.RequiredString("hash"), - Level = block.Level, - Timestamp = block.Timestamp, - BakerFee = content.RequiredInt64("fee"), - Counter = content.RequiredInt32("counter"), - GasLimit = content.RequiredInt32("gas_limit"), - StorageLimit = content.RequiredInt32("storage_limit"), - SenderId = sender.Id, - Slot = content.Required("slot_header").RequiredInt32("slot_index"), - Commitment = content.Required("slot_header").RequiredString("commitment"), - Status = result.RequiredString("status") switch - { - "applied" => OperationStatus.Applied, - "backtracked" => OperationStatus.Backtracked, - "failed" => OperationStatus.Failed, - "skipped" => OperationStatus.Skipped, - _ => throw new NotImplementedException() - }, - Errors = result.TryGetProperty("errors", out var errors) - ? OperationErrors.Parse(content, errors) - : null, - GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), - AllocationFee = null, - StorageFee = null, - StorageUsed = 0 - }; - #endregion - - #region apply operation - Db.TryAttach(sender); - PayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter; - sender.DalPublishCommitmentOpsCount++; - - block.Operations |= Operations.DalPublishCommitment; - - Cache.AppState.Get().DalPublishCommitmentOpsCount++; - #endregion - - #region apply result - if (operation.Status == OperationStatus.Applied) - { - // nothing to do - } - #endregion - - Proto.Manager.Set(sender); - Db.DalPublishCommitmentOps.Add(operation); - Context.DalPublishCommitmentOps.Add(operation); - } - - public async Task Revert(Block block, DalPublishCommitmentOperation operation) - { - var sender = (await Cache.Accounts.GetAsync(operation.SenderId) as User)!; - Db.TryAttach(sender); - - #region revert result - if (operation.Status == OperationStatus.Applied) - { - // nothing to do - } - #endregion - - #region revert operation - RevertPayFee(sender, operation.BakerFee); - sender.Counter = operation.Counter - 1; - sender.DalPublishCommitmentOpsCount--; - - Cache.AppState.Get().DalPublishCommitmentOpsCount--; - #endregion - - Db.DalPublishCommitmentOps.Remove(operation); - Cache.AppState.ReleaseManagerCounter(); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index b6877a5b6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class DelegationsCommit : Proto18.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 4cecb2239..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class DoubleBakingCommit : Proto18.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetSlashingLevel(Block block, Protocol protocol, int accusedLevel) - { - return Cache.Protocols.GetCycleEnd(protocol.GetCycle(accusedLevel) + protocol.SlashingDelay); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index e97941634..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class DoubleConsensusCommit(ProtocolHandler protocol) : Proto18.DoubleConsensusCommit(protocol) - { - protected override int GetSlashingLevel(Block block, Protocol protocol, int accusedLevel) - { - return Cache.Protocols.GetCycleEnd(protocol.GetCycle(accusedLevel) + protocol.SlashingDelay); - } - - protected override DoubleConsensusKind GetKind(JsonElement content) - { - return content.RequiredString("kind") == "double_attestation_evidence" - ? DoubleConsensusKind.DoubleAttestation - : DoubleConsensusKind.DoublePreattestation; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index f7d3f3495..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class DrainDelegateCommit : Proto15.DrainDelegateCommit - { - public DrainDelegateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index d8ff13389..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class IncreasePaidStorageCommit : Proto14.IncreasePaidStorageCommit - { - public IncreasePaidStorageCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 2ab94ad30..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class NonceRevelationsCommit : Proto18.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override (long, long, long, long) ParseRewards(Data.Models.Delegate proposer, List balanceUpdates) - { - var rewardDelegated = 0L; - var rewardStakedOwn = 0L; - var rewardStakedEdge = 0L; - var rewardStakedShared = 0L; - - for (int i = 0; i < balanceUpdates.Count; i++) - { - var update = balanceUpdates[i]; - if (update.RequiredString("kind") == "minted" && update.RequiredString("category") == "nonce revelation rewards") - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected nonce revelation rewards balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredInt64("change") != change) - throw new Exception("Unexpected nonce revelation rewards balance updates behavior"); - - if (nextUpdate.RequiredString("kind") == "freezer" && nextUpdate.RequiredString("category") == "deposits") - { - var staker = nextUpdate.Required("staker"); - if (staker.TryGetProperty("baker_own_stake", out var p) && p.GetString() == proposer.Address) - { - rewardStakedOwn += change; - } - else if (staker.TryGetProperty("baker_edge", out p) && p.GetString() == proposer.Address) - { - rewardStakedEdge += change; - } - else if (staker.TryGetProperty("delegate", out p) && p.GetString() == proposer.Address) - { - rewardStakedShared += change; - } - else - { - throw new Exception("Unexpected nonce revelation rewards balance updates behavior"); - } - } - else if (nextUpdate.RequiredString("kind") == "contract" && nextUpdate.RequiredString("contract") == proposer.Address) - { - rewardDelegated += change; - } - else - { - throw new Exception("Unexpected nonce revelation rewards balance updates behavior"); - } - } - } - - return (rewardDelegated, rewardStakedOwn, rewardStakedEdge, rewardStakedShared); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 396487cd5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class OriginationsCommit : Proto14.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index 476d8fe5d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class PreattestationsCommit(ProtocolHandler protocol) : Proto12.PreattestationsCommit(protocol) - { - protected override long GetPower(JsonElement metadata) - { - return metadata.RequiredInt64("consensus_power"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index baf017f8e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class ProposalsCommit : Proto14.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index d44b75358..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class RegisterConstantsCommit : Proto14.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 78184cbfd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class RevealsCommit : Proto14.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SetDelegateParametersCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SetDelegateParametersCommit.cs deleted file mode 100644 index ff6c7d31b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SetDelegateParametersCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SetDelegateParametersCommit : Proto18.SetDelegateParametersCommit - { - public SetDelegateParametersCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index 318c0f9e7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index 69ac2d121..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SmartRollupAddMessagesCommit : Proto16.SmartRollupAddMessagesCommit - { - public SmartRollupAddMessagesCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index 33568f3ff..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SmartRollupCementCommit : Proto17.SmartRollupCementCommit - { - public SmartRollupCementCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index 2f2c11f8b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SmartRollupExecuteCommit : Proto16.SmartRollupExecuteCommit - { - public SmartRollupExecuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index 04088eae7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SmartRollupOriginateCommit : Proto16.SmartRollupOriginateCommit - { - public SmartRollupOriginateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index 20fe4b325..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SmartRollupPublishCommit : Proto16.SmartRollupPublishCommit - { - public SmartRollupPublishCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index 1b4dd26e5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SmartRollupRecoverBondCommit : Proto16.SmartRollupRecoverBondCommit - { - public SmartRollupRecoverBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index 95b1c9ba7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SmartRollupRefuteCommit : Proto16.SmartRollupRefuteCommit - { - public SmartRollupRefuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index 6af9102ec..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SmartRollupTimeoutCommit : Proto16.SmartRollupTimeoutCommit - { - public SmartRollupTimeoutCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/StakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/StakingCommit.cs deleted file mode 100644 index e94921de5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/StakingCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class StakingCommit : Proto18.StakingCommit - { - public StakingCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override string GetFreezerBaker(JsonElement update) - { - return update.Required("staker").RequiredString("baker_own_stake"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 3b713c253..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class TransactionsCommit : Proto14.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index 5def5059a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index b032377ac..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class UpdateSecondaryKeyCommit : Proto15.UpdateSecondaryKeyCommit - { - public UpdateSecondaryKeyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 61091f8c9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class VdfRevelationCommit : Proto18.VdfRevelationCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override (long, long, long, long) ParseRewards(Data.Models.Delegate proposer, List balanceUpdates) - { - var rewardDelegated = 0L; - var rewardStakedOwn = 0L; - var rewardStakedEdge = 0L; - var rewardStakedShared = 0L; - - for (int i = 0; i < balanceUpdates.Count; i++) - { - var update = balanceUpdates[i]; - if (update.RequiredString("kind") == "minted" && update.RequiredString("category") == "nonce revelation rewards") - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected nonce revelation rewards balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredInt64("change") != change) - throw new Exception("Unexpected nonce revelation rewards balance updates behavior"); - - if (nextUpdate.RequiredString("kind") == "freezer" && nextUpdate.RequiredString("category") == "deposits") - { - var staker = nextUpdate.Required("staker"); - if (staker.TryGetProperty("baker_own_stake", out var p) && p.GetString() == proposer.Address) - { - rewardStakedOwn += change; - } - else if (staker.TryGetProperty("baker_edge", out p) && p.GetString() == proposer.Address) - { - rewardStakedEdge += change; - } - else if (staker.TryGetProperty("delegate", out p) && p.GetString() == proposer.Address) - { - rewardStakedShared += change; - } - else - { - throw new Exception("Unexpected nonce revelation rewards balance updates behavior"); - } - } - else if (nextUpdate.RequiredString("kind") == "contract" && nextUpdate.RequiredString("contract") == proposer.Address) - { - rewardDelegated += change; - } - else - { - throw new Exception("Unexpected nonce revelation rewards balance updates behavior"); - } - } - } - - return (rewardDelegated, rewardStakedOwn, rewardStakedEdge, rewardStakedShared); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SlashingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SlashingCommit.cs deleted file mode 100644 index d0496244b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SlashingCommit.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SlashingCommit : Proto18.SlashingCommit - { - public SlashingCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override string GetFreezerBaker(JsonElement update) - { - return update.Required("staker").OptionalString("baker_own_stake") - ?? update.Required("staker").RequiredString("delegate"); - } - - protected override bool IsOwnStake(JsonElement update) - { - return update.Required("staker").TryGetProperty("baker_own_stake", out _); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 0719502de..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,109 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SnapshotBalanceCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply() - { - if (!Context.Block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "SnapshotBalances" - WHERE "Level" < {0} - """, Context.Block.Level - Context.Protocol.BlocksPerCycle); - - await Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "SnapshotBalances" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount", - "OwnStakedBalance", - "ExternalStakedBalance", - "StakersCount", - "Pseudotokens" - ) - - SELECT - {0}, - "Id", - "Id", - 0, - 0, - 0, - "OwnStakedBalance", - "ExternalStakedBalance", - "StakersCount", - "IssuedPseudotokens" - FROM "Accounts" - WHERE "Staked" = true - AND "Type" = {1} - - UNION ALL - - SELECT - {0}, - "DelegateId", - "Id", - 0, - NULL::bigint, - NULL::integer, - NULL::bigint, - NULL::bigint, - NULL::integer, - "StakedPseudotokens" - FROM "Accounts" - WHERE "Staked" = true - AND "Type" != {1} - AND "StakedPseudotokens" IS NOT NULL - """, Context.Block.Level, (int)AccountType.Delegate); - - await Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "SnapshotBalances" ( - "Level", - "BakerId", - "AccountId", - "OwnDelegatedBalance", - "ExternalDelegatedBalance", - "DelegatorsCount" - ) - - SELECT - {0}, - ds."BakerId", - ds."AccountId", - ds."OwnDelegatedBalance", - ds."ExternalDelegatedBalance", - ds."DelegatorsCount" - FROM "Accounts" AS baker - INNER JOIN "DelegationSnapshots" AS ds - ON ds."Level" = baker."MinTotalDelegatedLevel" AND ds."BakerId" = baker."Id" - WHERE baker."Staked" = true - AND baker."Type" = {1} - - ON CONFLICT ("Level", "BakerId", "AccountId") - DO UPDATE - SET - "OwnDelegatedBalance" = EXCLUDED."OwnDelegatedBalance", - "ExternalDelegatedBalance" = EXCLUDED."ExternalDelegatedBalance", - "DelegatorsCount" = EXCLUDED."DelegatorsCount" - """, Context.Block.Level, (int)AccountType.Delegate); - } - - public async Task Revert() - { - if (!Context.Block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "SnapshotBalances" - WHERE "Level" = {0} - """, Context.Block.Level); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SoftwareCommit.cs deleted file mode 100644 index df530e89d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StakerCycleCommit.cs deleted file mode 100644 index 82a81197a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StakerCycleCommit.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class StakerCycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply() - { - if (!Context.Block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - #region finalize - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "StakerCycles" - SET "FinalStake" = snapshot.stake - FROM ( - SELECT - sc."Id" AS id, - FLOOR(baker."ExternalStakedBalance" - * COALESCE(staker."StakedPseudotokens", 0::numeric) - / COALESCE(baker."IssuedPseudotokens", 1::numeric))::bigint AS stake - FROM "StakerCycles" AS sc - INNER JOIN "Accounts" AS baker ON baker."Id" = sc."BakerId" - INNER JOIN "Accounts" AS staker ON staker."Id" = sc."StakerId" - WHERE sc."Cycle" = {0} - ) AS snapshot - WHERE "Id" = snapshot.id - """, Context.Block.Cycle - 1); - #endregion - - #region create - await Db.Database.ExecuteSqlRawAsync(""" - INSERT INTO "StakerCycles" ( - "Cycle", - "BakerId", - "StakerId", - "InitialStake", - "AvgStake", - "AddedStake", - "RemovedStake", - "FinalStake" - ) - SELECT - {0}, - sc."BakerId", - sc."StakerId", - sc."FinalStake", - sc."FinalStake", - 0, - 0, - NULL - FROM "StakerCycles" AS sc - INNER JOIN "Accounts" AS staker ON staker."Id" = sc."StakerId" - WHERE sc."Cycle" = {1} AND staker."StakedPseudotokens" IS NOT NULL - """, Context.Block.Cycle, Context.Block.Cycle - 1); - #endregion - } - - public async Task Revert() - { - if (!Context.Block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - #region revert create - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "StakerCycles" - WHERE "Cycle" = {0} - """, Context.Block.Cycle); - #endregion - - #region revert finalize - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "StakerCycles" - SET "FinalStake" = NULL - WHERE "Cycle" = {0} - """, Context.Block.Cycle - 1); - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StakingUpdateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StakingUpdateCommit.cs deleted file mode 100644 index d6ffae095..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StakingUpdateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class StakingUpdateCommit : Proto18.StakingUpdateCommit - { - public StakingUpdateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StateCommit.cs deleted file mode 100644 index b05d437e3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StatisticsCommit.cs deleted file mode 100644 index 394f93594..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SubsidyCommit.cs deleted file mode 100644 index 7af16b836..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/TicketsCommit.cs deleted file mode 100644 index 93e1cbbb8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/TicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class TicketsCommit : Proto16.TicketsCommit - { - public TicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/TokensCommit.cs deleted file mode 100644 index 4f475b464..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/VotingCommit.cs deleted file mode 100644 index ba4cf32e1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Diagnostics/Diagnostics.cs deleted file mode 100644 index a164023f3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class Diagnostics : Proto18.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Helpers.cs deleted file mode 100644 index 20d4ef82d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - public class Helpers(ProtocolHandler proto) : Proto18.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Proto19Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Proto19Handler.cs deleted file mode 100644 index 7a56484ad..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Proto19Handler.cs +++ /dev/null @@ -1,512 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto19; - -namespace Tzkt.Sync.Protocols -{ - class Proto19Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "paris_019"; - public override int VersionNumber => 19; - - public Proto19Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SetDelegateParametersCommit(this).ActivateStakingParameters(blockCommit.Block); - await new UpdateSecondaryKeyCommit(this).ActivateSecondaryKeys(blockCommit.Block); - await new StakerCycleCommit(this).Apply(); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "attestation": - case "attestation_with_dal": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preattestation": - case "preattestation_with_dal": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_attestation_evidence": - case "double_preattestation_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - var ticketsCommit = new TicketsCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var dst = content.RequiredString("destination"); - if (dst.StartsWith("tz") && content.Optional("parameters")?.RequiredString("entrypoint") is string entrypoint) - { - if (Proto18.StakingCommit.ValidateParameters(entrypoint, content.RequiredString("source"), dst)) - { - await new StakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - else if (Proto18.SetDelegateParametersCommit.Entrypoint == entrypoint) - { - await new SetDelegateParametersCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - } - - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - if (parent.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, parent.Transaction, parent.TicketUpdates); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (parent1.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, parent1.Operation, parent1.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_publish_commitment": - await new DalPublishCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await blockCommit.ApplyRewards(block); - - new InboxCommit(this).Apply(blockCommit.Block); - - await bigMapCommit.Apply(); - await ticketsCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SlashingCommit(this).Apply(block, rawBlock); - await new VotingCommit(this).Apply(block, rawBlock); - await new AutostakingCommit(this).Apply(block, rawBlock); - - Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - - await new DelegationSnapshotCommit(this).Apply(); - await new SnapshotBalanceCommit(this).Apply(); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(); - await new DelegationSnapshotCommit(this).Revert(); - await new AutostakingCommit(this).Revert(block); - await new VotingCommit(this).Revert(block); - await new SlashingCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new TicketsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - await new BlockCommit(this).RevertRewards(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case StakingOperation op: - await new StakingCommit(this).Revert(currBlock, op); - break; - case SetDelegateParametersOperation op: - await new SetDelegateParametersCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - case DalPublishCommitmentOperation op: - await new DalPublishCommitmentCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new StakerCycleCommit(this).Revert(); - await new UpdateSecondaryKeyCommit(this).DeactivateSecondaryKeys(currBlock); - await new SetDelegateParametersCommit(this).DeactivateStakingParameters(currBlock); - await new CycleCommit(this).Revert(currBlock); - new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Rpc/Rpc.cs deleted file mode 100644 index 09614e676..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Rpc/Rpc.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto19 -{ - class Rpc : Proto18.Rpc - { - public Rpc(TezosNode node) : base(node) { } - - public override Task GetCurrentStakingBalance(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/raw/json/staking_balance/{address}"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto19/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto19/Validation/Validator.cs deleted file mode 100644 index 9ff9084b0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto19/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto19 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Activation/ProtoActivator.cs deleted file mode 100644 index a2f70ab51..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Activation/ProtoActivator.cs +++ /dev/null @@ -1,112 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto2 -{ - class ProtoActivator(ProtocolHandler proto) : Proto1.ProtoActivator(proto) - { - protected override async Task MigrateContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - var protocol = await Cache.Protocols.GetAsync(block.ProtoCode); - - var weirdDelegates = (await Db.OriginationOps - .AsNoTracking() - .Join(Db.Users, x => x.DelegateId, x => x.Id, (op, delegat) => new { op, delegat }) - .Join(Db.Accounts, x => x.op.ContractId, x => x.Id, (opDelegat, contract) => new { opDelegat.op, opDelegat.delegat, contract }) - .Where(x => - x.op.Status == OperationStatus.Applied && - x.op.DelegateId != null && - x.delegat.Type != AccountType.Delegate && - x.delegat.Balance > 0 && - x.contract.DelegateId == null) - .Select(x => new - { - Contract = x.contract, - WeirdDelegate = x.delegat - }) - .ToListAsync()) - .GroupBy(x => x.WeirdDelegate.Id); - - var activatedDelegates = new Dictionary(weirdDelegates.Count()); - - Db.TryAttach(block); - Db.TryAttach(state); - - foreach (var weirds in weirdDelegates) - { - var delegat = RegisterBaker(weirds.First().WeirdDelegate, protocol); - activatedDelegates.Add(delegat.Id, delegat); - - delegat.MigrationsCount++; - delegat.LastLevel = block.Level; - - block.Operations |= Operations.Migrations; - - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = delegat.Id, - Kind = MigrationKind.ActivateDelegate - }; - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - state.MigrationOpsCount++; - - foreach (var weird in weirds) - { - var delegator = weird.Contract; - if (delegator.DelegateId != null) - throw new Exception("migration error"); - - Db.TryAttach(delegator); - Cache.Accounts.Add(delegator); - - Delegate(delegator, delegat, delegator.FirstLevel); - } - } - } - - protected override async Task RevertContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - - var delegates = await Db.Delegates - .AsNoTracking() - .GroupJoin(Db.Accounts, x => x.Id, x => x.DelegateId, (baker, delegators) => new { baker, delegators }) - .Where(x => x.baker.ActivationLevel == block.Level) - .ToListAsync(); - - foreach (var row in delegates) - { - foreach (var delegator in row.delegators) - { - Db.TryAttach(delegator); - Cache.Accounts.Add(delegator); - - Undelegate(delegator, row.baker); - } - - if (row.baker.ExternalDelegatedBalance != 0 || row.baker.DelegatorsCount > 0) - throw new Exception("migration error"); - - var user = UnregisterBaker(row.baker); - user.MigrationsCount--; - } - - var migrationOps = await Db.MigrationOps - .AsNoTracking() - .Where(x => x.Kind == MigrationKind.ActivateDelegate) - .ToListAsync(); - - Db.MigrationOps.RemoveRange(migrationOps); - Cache.AppState.ReleaseOperationId(migrationOps.Count); - - state.MigrationOpsCount -= migrationOps.Count; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BakerCycleCommit.cs deleted file mode 100644 index 25d6b0a94..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class BakerCycleCommit : Proto1.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BakingRightsCommit.cs deleted file mode 100644 index b123ae025..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class BakingRightsCommit : Proto1.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BigMapCommit.cs deleted file mode 100644 index 96344d04c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BlockCommit.cs deleted file mode 100644 index 1de96c3b1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class BlockCommit : Proto1.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/CycleCommit.cs deleted file mode 100644 index 590fc2b30..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/DeactivationCommit.cs deleted file mode 100644 index d48bf0dd1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto2 -{ - class DeactivationCommit : ProtocolCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - - public virtual async Task Apply(Block block, JsonElement rawBlock) - { - #region init - List? bakers = null; - if (block.Events.HasFlag(BlockEvents.Deactivations)) - { - var deactivated = rawBlock - .Required("metadata") - .RequiredArray("deactivated") - .EnumerateArray() - .Select(x => x.RequiredString()) - .ToHashSet(); - - bakers = [..Cache.Accounts.GetDelegates().Where(x => x.Staked && deactivated.Contains(x.Address))]; - } - else if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - bakers = [..Cache.Accounts.GetDelegates().Where(x => x.Staked && x.DeactivationLevel == block.Level)]; - } - #endregion - - if (bakers == null) return; - - foreach (var baker in bakers) - { - Db.TryAttach(baker); - baker.DeactivationLevel = block.Level; - await DeactivateBaker(baker); - } - } - - public virtual async Task Revert(Block block) - { - #region init - List? bakers = null; - if (block.Events.HasFlag(BlockEvents.Deactivations) || block.Events.HasFlag(BlockEvents.CycleBegin)) - { - bakers = [..Cache.Accounts.GetDelegates().Where(x => x.DeactivationLevel == block.Level)]; - } - #endregion - - if (bakers == null) return; - - foreach (var baker in bakers) - { - Db.TryAttach(baker); - baker.DeactivationLevel = block.Events.HasFlag(BlockEvents.CycleEnd) ? block.Level + 1 : block.Level; - await ActivateBaker(baker); - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 1bb6227eb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class DelegatorCycleCommit : Proto1.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/FreezerCommit.cs deleted file mode 100644 index b09987411..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class FreezerCommit : Proto1.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 2fb110862..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 184aae66d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index dc475ebfb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index ba6b01c17..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto2 -{ - class DoubleBakingCommit : ProtocolCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - - public virtual Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - - var offenderAddr = balanceUpdates - .First(x => x.RequiredInt64("change") < 0).RequiredString("delegate"); - - var rewards = balanceUpdates - .FirstOrDefault(x => x.RequiredString("category")[0] == 'r' && x.RequiredInt64("change") > 0); - - var lostDeposits = balanceUpdates - .FirstOrDefault(x => x.RequiredString("category")[0] == 'd' && x.RequiredInt64("change") < 0); - var lostDepositsValue = lostDeposits.ValueKind != JsonValueKind.Undefined ? -lostDeposits.RequiredInt64("change") : 0; - - var lostRewards = balanceUpdates - .FirstOrDefault(x => x.RequiredString("category")[0] == 'r' && x.RequiredInt64("change") < 0); - var lostRewardsValue = lostRewards.ValueKind != JsonValueKind.Undefined ? -lostRewards.RequiredInt64("change") : 0; - - var lostFees = balanceUpdates - .FirstOrDefault(x => x.RequiredString("category")[0] == 'f' && x.RequiredInt64("change") < 0); - var lostFeesValue = lostFees.ValueKind != JsonValueKind.Undefined ? -lostFees.RequiredInt64("change") : 0; - - var accuser = Context.Proposer; - var offender = Cache.Accounts.GetExistingDelegate(offenderAddr); - - var doubleBaking = new DoubleBakingOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - - SlashedLevel = block.Level, - AccusedLevel = content.Required("bh1").RequiredInt32("level"), - AccuserId = accuser.Id, - OffenderId = offender.Id, - - Reward = rewards.ValueKind != JsonValueKind.Undefined ? rewards.RequiredInt64("change") : 0, - LostStaked = lostDepositsValue + lostRewardsValue + lostFeesValue, - LostUnstaked = 0, - LostExternalStaked = 0, - LostExternalUnstaked = 0 - }; - #endregion - - #region entities - Db.TryAttach(accuser); - Db.TryAttach(offender); - #endregion - - #region apply operation - ReceiveLockedRewards(accuser, doubleBaking.Reward); - Spend(offender, offender, lostDepositsValue + lostFeesValue); - BurnLockedRewards(offender, lostRewardsValue); - - accuser.DoubleBakingCount++; - if (offender != accuser) offender.DoubleBakingCount++; - - block.Operations |= Operations.DoubleBakings; - - Cache.AppState.Get().DoubleBakingOpsCount++; - Cache.Statistics.Current.TotalBurned += doubleBaking.LostStaked - doubleBaking.Reward; - Cache.Statistics.Current.TotalFrozen -= doubleBaking.LostStaked - doubleBaking.Reward; - #endregion - - Db.DoubleBakingOps.Add(doubleBaking); - Context.DoubleBakingOps.Add(doubleBaking); - return Task.CompletedTask; - } - - public virtual Task Revert(Block block, DoubleBakingOperation doubleBaking) - { - #region entities - //var block = doubleBaking.Block; - var accuser = Cache.Accounts.GetDelegate(doubleBaking.AccuserId); - var offender = Cache.Accounts.GetDelegate(doubleBaking.OffenderId); - - //Db.TryAttach(block); - Db.TryAttach(accuser); - Db.TryAttach(offender); - #endregion - - #region apply operation - RevertReceiveLockedRewards(accuser, doubleBaking.Reward); - // here we can miss 1 mutez, but this may happen only in legacy protocols - // TODO: replace it with NotImplementedException after Ithaca - RevertSpend(offender, offender, doubleBaking.Reward * 2); - RevertBurnLockedRewards(offender, doubleBaking.LostStaked - doubleBaking.Reward * 2); - - accuser.DoubleBakingCount--; - if (offender != accuser) offender.DoubleBakingCount--; - - Cache.AppState.Get().DoubleBakingOpsCount--; - #endregion - - Db.DoubleBakingOps.Remove(doubleBaking); - Cache.AppState.ReleaseOperationId(); - return Task.CompletedTask; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index a649c0011..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 799471093..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class OriginationsCommit : Proto1.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 85c91aa00..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 6860e31f1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto2 -{ - class TransactionsCommit : Proto1.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override IEnumerable? ParseBigMapDiffs(TransactionOperation transaction, JsonElement result) - { - if (!result.TryGetProperty("big_map_diff", out var diffs)) - return null; - - return diffs.RequiredArray().EnumerateArray().Select(x => new UpdateDiff - { - Ptr = transaction.TargetId!.Value, - KeyHash = x.RequiredString("key_hash"), - Key = x.RequiredMicheline("key"), - Value = x.OptionalMicheline("value") - }); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index b03641161..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto2 -{ - class RevelationPenaltyCommit : ProtocolCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - - public virtual async Task Apply(Block block, JsonElement rawBlock) - { - #region init - List? revelationPenalties = null; - - if (block.Events.HasFlag(BlockEvents.CycleEnd)) - { - if (HasPenaltiesUpdates(block, Context.Protocol, rawBlock)) - { - revelationPenalties = []; - - var missedBlocks = await Db.Blocks - .Join(Db.Protocols, x => x.ProtoCode, x => x.Code, (block, protocol) => new { block, protocol }) - .Where(x => x.block.Level % x.protocol.BlocksPerCommitment == 0 && - x.block.Cycle == block.Cycle - 1 && - x.block.RevelationId == null) - .Select(x => x.block) - .ToListAsync(); - - var penalizedBakers = missedBlocks - .Select(x => x.ProposerId) - .ToHashSet(); - - var bakerCycles = await Db.BakerCycles.AsNoTracking() - .Where(x => x.Cycle == block.Cycle - 1 && penalizedBakers.Contains(x.BakerId)) - .ToListAsync(); - - var slashedBakers = bakerCycles - .Where(x => x.DoubleBakingLostStaked > 0 || x.DoubleConsensusLostStaked > 0) - .Select(x => x.BakerId) - .ToHashSet(); - - foreach (var missedBlock in missedBlocks) - { - var missedBlockProposer = Cache.Accounts.GetDelegate(missedBlock.ProposerId!.Value); - var slashed = slashedBakers.Contains(missedBlockProposer.Id); - revelationPenalties.Add(new RevelationPenaltyOperation - { - Id = Cache.AppState.NextOperationId(), - BakerId = missedBlockProposer.Id, - Level = block.Level, - Timestamp = block.Timestamp, - MissedLevel = missedBlock.Level, - Loss = slashed ? 0 : missedBlock.RewardDelegated + missedBlock.Fees - }); - } - } - } - #endregion - - if (revelationPenalties == null) return; - - foreach (var penalty in revelationPenalties) - { - #region entities - var delegat = Cache.Accounts.GetDelegate(penalty.BakerId); - Db.TryAttach(delegat); - #endregion - - if (penalty.Loss != 0) - { - var lostFees = (await Cache.Blocks.GetAsync(penalty.MissedLevel)).Fees; - Spend(delegat, delegat, lostFees); - BurnLockedRewards(delegat, penalty.Loss - lostFees); - } - - delegat.RevelationPenaltiesCount++; - block.Operations |= Operations.RevelationPenalty; - - Cache.AppState.Get().RevelationPenaltyOpsCount++; - Cache.Statistics.Current.TotalBurned += penalty.Loss; - Cache.Statistics.Current.TotalFrozen -= penalty.Loss; - - Db.RevelationPenaltyOps.Add(penalty); - Context.RevelationPenaltyOps.Add(penalty); - } - } - - public virtual async Task Revert(Block block) - { - foreach (var penalty in Context.RevelationPenaltyOps) - { - #region entities - var delegat = Cache.Accounts.GetDelegate(penalty.BakerId); - Db.TryAttach(delegat); - #endregion - - if (penalty.Loss != 0) - { - var lostFees = (await Cache.Blocks.GetAsync(penalty.MissedLevel)).Fees; - RevertSpend(delegat, delegat, lostFees); - RevertBurnLockedRewards(delegat, penalty.Loss - lostFees); - } - - delegat.RevelationPenaltiesCount--; - - Cache.AppState.Get().RevelationPenaltyOpsCount--; - - Db.RevelationPenaltyOps.Remove(penalty); - Cache.AppState.ReleaseOperationId(); - } - } - - protected virtual int GetFreezerCycle(JsonElement el) => el.RequiredInt32("level"); - - protected virtual bool HasPenaltiesUpdates(Block block, Protocol protocol, JsonElement rawBlock) - { - return rawBlock - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .Any(x => x.RequiredString("kind")[0] == 'f' && - x.RequiredInt64("change") < 0 && - GetFreezerCycle(x) != block.Cycle - protocol.ConsensusRightsDelay); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index aa2ae0f0e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto2 -{ - class SnapshotBalanceCommit : Proto1.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - - public override async Task Apply(JsonElement rawBlock, Block block) - { - if (!block.Events.HasFlag(BlockEvents.BalanceSnapshot)) - return; - - await RemoveOutdated(block, Context.Protocol); - await TakeSnapshot(block); - await TakeDeactivatedSnapshot(block); - await SubtractCycleRewards(rawBlock, block); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/StateCommit.cs deleted file mode 100644 index 30128bd67..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/StatisticsCommit.cs deleted file mode 100644 index f78943ed9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/VotingCommit.cs deleted file mode 100644 index 5b4d3ecd5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class VotingCommit : Proto1.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Diagnostics/Diagnostics.cs deleted file mode 100644 index cd4febba0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class Diagnostics : Proto1.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Helpers.cs deleted file mode 100644 index d2bbb01be..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Proto2Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Proto2Handler.cs deleted file mode 100644 index 5994f3713..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Proto2Handler.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto2; - -namespace Tzkt.Sync.Protocols -{ - class Proto2Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "alpha_002"; - public override int VersionNumber => 2; - - public Proto2Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - // there were no voting operations - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - await new DelegationsCommit(this).Revert(currBlock, op); - break; - case OriginationOperation op: - await new OriginationsCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Rpc/Rpc.cs deleted file mode 100644 index b9302de90..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto2 -{ - class Rpc : Proto1.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto2/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto2/Validation/Validator.cs deleted file mode 100644 index 94feda2ba..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto2/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto2 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Activation/ProtoActivator.cs deleted file mode 100644 index 10a351b8a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Activation/ProtoActivator.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto20 -{ - partial class ProtoActivator : Proto19.ProtoActivator - { - public ProtoActivator(ProtocolHandler proto) : base(proto) { } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - // nothing to upgrade - } - - protected override Task MigrateContext(AppState state) - { - // nothing to migrate - return Task.CompletedTask; - } - - protected override Task RevertContext(AppState state) - { - // nothing to revert - return Task.CompletedTask; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/AttestationRewardCommit.cs deleted file mode 100644 index d5eaf1749..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class AttestationRewardCommit : Proto19.AttestationRewardCommit - { - public AttestationRewardCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/AutostakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/AutostakingCommit.cs deleted file mode 100644 index 1843bf8f8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/AutostakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class AutostakingCommit : Proto19.AutostakingCommit - { - public AutostakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BakerCycleCommit.cs deleted file mode 100644 index a05239cc2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class BakerCycleCommit : Proto18.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BakingRightsCommit.cs deleted file mode 100644 index 06bb1c541..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class BakingRightsCommit : Proto18.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BigMapCommit.cs deleted file mode 100644 index d2e333768..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BlockCommit.cs deleted file mode 100644 index 0b282c784..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class BlockCommit : Proto19.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/ContractEventCommit.cs deleted file mode 100644 index 333089e37..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class ContractEventCommit : Proto14.ContractEventCommit - { - public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/CycleCommit.cs deleted file mode 100644 index de010d268..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/CycleCommit.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto20 -{ - class CycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public Cycle? FutureCycle { get; protected set; } - public List? Snapshots { get; protected set; } - public Dictionary? SelectedStakes { get; protected set; } - - public virtual async Task Apply(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - var index = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - var contextTask = Proto.Rpc.GetCycleAsync(block.Level, index); - var issuanceTask = Proto.Rpc.GetExpectedIssuance(block.Level); - await Task.WhenAll(contextTask, issuanceTask); - - var context = await contextTask; - var issuance = await issuanceTask; - var cycleIssuance = issuance.EnumerateArray().First(x => x.RequiredInt32("cycle") == index); - - SelectedStakes = context.RequiredArray("selected_stake_distribution") - .EnumerateArray() - .ToDictionary( - x => Cache.Accounts.GetExistingDelegate(x.RequiredString("baker")).Id, - x => x.Required("active_stake").RequiredInt64("frozen") + x.Required("active_stake").RequiredInt64("delegated")); - - Snapshots = await Db.SnapshotBalances - .AsNoTracking() - .Where(x => x.Level == block.Level - 1 && x.BakerId == x.AccountId) - .ToListAsync(); - - FutureCycle = new Cycle - { - Id = 0, - Index = index, - FirstLevel = Context.Protocol.GetCycleStart(index), - LastLevel = Context.Protocol.GetCycleEnd(index), - SnapshotLevel = block.Level - 1, - TotalBakers = SelectedStakes.Count, - TotalBakingPower = SelectedStakes.Values.Sum(), - Seed = Hex.Parse(context.RequiredString("random_seed")), - BlockReward = cycleIssuance.RequiredInt64("baking_reward_fixed_portion"), - BlockBonusPerBlock = GetBlockBonusPerBlock(cycleIssuance, Context.Protocol), - AttestationRewardPerBlock = GetAttestationRewardPerBlock(cycleIssuance, Context.Protocol), - NonceRevelationReward = cycleIssuance.RequiredInt64("seed_nonce_revelation_tip"), - VdfRevelationReward = cycleIssuance.RequiredInt64("vdf_revelation_tip"), - DalAttestationRewardPerShard = GetDalAttestationRewardPerShard(cycleIssuance) - }; - - Db.Cycles.Add(FutureCycle); - } - - public virtual async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Cycles" - WHERE "Index" = {0} - """, block.Cycle + Context.Protocol.ConsensusRightsDelay); - } - - protected virtual long GetBlockBonusPerBlock(JsonElement issuance, Protocol protocol) - => issuance.RequiredInt64("baking_reward_bonus_per_slot") * (protocol.AttestersPerBlock - protocol.ConsensusThreshold); - - protected virtual long GetAttestationRewardPerBlock(JsonElement issuance, Protocol protocol) - => issuance.RequiredInt64("attesting_reward_per_slot") * protocol.AttestersPerBlock; - - protected virtual long GetDalAttestationRewardPerShard(JsonElement issuance) => 0; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DeactivationCommit.cs deleted file mode 100644 index 9c0c00a9e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DelegationSnapshotCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DelegationSnapshotCommit.cs deleted file mode 100644 index 3985e64d8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DelegationSnapshotCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class DelegationSnapshotCommit(ProtocolHandler protocol) : Proto19.DelegationSnapshotCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 2d394101a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class DelegatorCycleCommit : Proto18.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/InboxCommit.cs deleted file mode 100644 index 6a2591d5d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/InboxCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - public class InboxCommit : Proto17.InboxCommit - { - public InboxCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 6892661dd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 2fe8faacd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class AttestationsCommit : Proto19.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 3eaacd3bc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DalPublishCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DalPublishCommitmentCommit.cs deleted file mode 100644 index 064c571c1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DalPublishCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class DalPublishCommitmentCommit : Proto19.DalPublishCommitmentCommit - { - public DalPublishCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 7be30cb2e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class DelegationsCommit : Proto18.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 061046a04..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class DoubleBakingCommit : Proto19.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 91cd45223..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class DoubleConsensusCommit : Proto19.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index b993719f0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class DrainDelegateCommit : Proto15.DrainDelegateCommit - { - public DrainDelegateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index a746febab..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class IncreasePaidStorageCommit : Proto14.IncreasePaidStorageCommit - { - public IncreasePaidStorageCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 07f1b2640..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class NonceRevelationsCommit : Proto19.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index ef12fc30c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class OriginationsCommit : Proto14.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index beb07b816..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class PreattestationsCommit : Proto19.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 396538951..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class ProposalsCommit : Proto14.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index 67dd94535..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class RegisterConstantsCommit : Proto14.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 3540a1957..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class RevealsCommit : Proto14.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SetDelegateParametersCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SetDelegateParametersCommit.cs deleted file mode 100644 index fd136a6a5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SetDelegateParametersCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SetDelegateParametersCommit : Proto18.SetDelegateParametersCommit - { - public SetDelegateParametersCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index 4d59f1226..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index 3e9acd552..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SmartRollupAddMessagesCommit : Proto16.SmartRollupAddMessagesCommit - { - public SmartRollupAddMessagesCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index 0f9b522e8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SmartRollupCementCommit : Proto17.SmartRollupCementCommit - { - public SmartRollupCementCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index edafda472..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SmartRollupExecuteCommit : Proto16.SmartRollupExecuteCommit - { - public SmartRollupExecuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index 28425529d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SmartRollupOriginateCommit : Proto16.SmartRollupOriginateCommit - { - public SmartRollupOriginateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index 55a1eb53d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SmartRollupPublishCommit : Proto16.SmartRollupPublishCommit - { - public SmartRollupPublishCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index 30d69790b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SmartRollupRecoverBondCommit : Proto16.SmartRollupRecoverBondCommit - { - public SmartRollupRecoverBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index 37621213f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SmartRollupRefuteCommit : Proto16.SmartRollupRefuteCommit - { - public SmartRollupRefuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index ee93181a0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SmartRollupTimeoutCommit : Proto16.SmartRollupTimeoutCommit - { - public SmartRollupTimeoutCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/StakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/StakingCommit.cs deleted file mode 100644 index 37aea0579..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/StakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class StakingCommit : Proto19.StakingCommit - { - public StakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 7819c1263..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class TransactionsCommit : Proto14.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index 56f768aa8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index 2abebbe75..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class UpdateSecondaryKeyCommit : Proto15.UpdateSecondaryKeyCommit - { - public UpdateSecondaryKeyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 414be7ed8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class VdfRevelationCommit : Proto19.VdfRevelationCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SlashingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SlashingCommit.cs deleted file mode 100644 index 6a2c761bd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SlashingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SlashingCommit : Proto19.SlashingCommit - { - public SlashingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index a64cabece..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SnapshotBalanceCommit : Proto19.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SoftwareCommit.cs deleted file mode 100644 index 3adcb6525..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StakerCycleCommit.cs deleted file mode 100644 index 0954a9c4d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StakerCycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class StakerCycleCommit(ProtocolHandler protocol) : Proto19.StakerCycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StakingUpdateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StakingUpdateCommit.cs deleted file mode 100644 index 36265b081..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StakingUpdateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class StakingUpdateCommit : Proto18.StakingUpdateCommit - { - public StakingUpdateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StateCommit.cs deleted file mode 100644 index 224599715..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StatisticsCommit.cs deleted file mode 100644 index 224175783..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SubsidyCommit.cs deleted file mode 100644 index 4d2805292..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/TicketsCommit.cs deleted file mode 100644 index 7ef7807fe..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/TicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class TicketsCommit : Proto16.TicketsCommit - { - public TicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/TokensCommit.cs deleted file mode 100644 index ed0b0b346..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/VotingCommit.cs deleted file mode 100644 index 769d90a1b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Diagnostics/Diagnostics.cs deleted file mode 100644 index deaaa109c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class Diagnostics : Proto18.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Helpers.cs deleted file mode 100644 index 3e5f081db..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - public class Helpers(ProtocolHandler proto) : Proto18.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Proto20Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Proto20Handler.cs deleted file mode 100644 index e2f06cc1b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Proto20Handler.cs +++ /dev/null @@ -1,512 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto20; - -namespace Tzkt.Sync.Protocols -{ - class Proto20Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "paris_020"; - public override int VersionNumber => 20; - - public Proto20Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SetDelegateParametersCommit(this).ActivateStakingParameters(blockCommit.Block); - await new UpdateSecondaryKeyCommit(this).ActivateSecondaryKeys(blockCommit.Block); - await new StakerCycleCommit(this).Apply(); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "attestation": - case "attestation_with_dal": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preattestation": - case "preattestation_with_dal": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_attestation_evidence": - case "double_preattestation_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - var ticketsCommit = new TicketsCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var dst = content.RequiredString("destination"); - if (dst.StartsWith("tz") && content.Optional("parameters")?.RequiredString("entrypoint") is string entrypoint) - { - if (Proto18.StakingCommit.ValidateParameters(entrypoint, content.RequiredString("source"), dst)) - { - await new StakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - else if (Proto18.SetDelegateParametersCommit.Entrypoint == entrypoint) - { - await new SetDelegateParametersCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - } - - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - if (parent.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, parent.Transaction, parent.TicketUpdates); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (parent1.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, parent1.Operation, parent1.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_publish_commitment": - await new DalPublishCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await blockCommit.ApplyRewards(block); - - new InboxCommit(this).Apply(blockCommit.Block); - - await bigMapCommit.Apply(); - await ticketsCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SlashingCommit(this).Apply(block, rawBlock); - await new VotingCommit(this).Apply(block, rawBlock); - await new AutostakingCommit(this).Apply(block, rawBlock); - - Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - - await new DelegationSnapshotCommit(this).Apply(); - await new SnapshotBalanceCommit(this).Apply(); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(); - await new DelegationSnapshotCommit(this).Revert(); - await new AutostakingCommit(this).Revert(block); - await new VotingCommit(this).Revert(block); - await new SlashingCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new TicketsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - await new BlockCommit(this).RevertRewards(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case StakingOperation op: - await new StakingCommit(this).Revert(currBlock, op); - break; - case SetDelegateParametersOperation op: - await new SetDelegateParametersCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - case DalPublishCommitmentOperation op: - await new DalPublishCommitmentCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new StakerCycleCommit(this).Revert(); - await new UpdateSecondaryKeyCommit(this).DeactivateSecondaryKeys(currBlock); - await new SetDelegateParametersCommit(this).DeactivateStakingParameters(currBlock); - await new CycleCommit(this).Revert(currBlock); - new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Rpc/Rpc.cs deleted file mode 100644 index 7c1a6a3de..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto20 -{ - class Rpc : Proto19.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto20/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto20/Validation/Validator.cs deleted file mode 100644 index 49fada097..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto20/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto20 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Activation/ProtoActivator.cs deleted file mode 100644 index 84b3fd592..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Activation/ProtoActivator.cs +++ /dev/null @@ -1,288 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto21 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto20.ProtoActivator(proto) - { - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - if (protocol.ConsensusRightsDelay == 3) - { - protocol.ConsensusRightsDelay = 2; - protocol.ToleratedInactivityPeriod = protocol.ConsensusRightsDelay + 1; - } - - if (protocol.TimeBetweenBlocks >= 5) - { - protocol.BlocksPerCycle = protocol.BlocksPerCycle * 5 / 4; - protocol.BlocksPerCommitment = protocol.BlocksPerCommitment * 5 / 4; - protocol.BlocksPerVoting = protocol.BlocksPerVoting * 5 / 4; - protocol.TimeBetweenBlocks = protocol.TimeBetweenBlocks * 4 / 5; - protocol.HardBlockGasLimit = prev.HardBlockGasLimit * 4 / 5; - protocol.SmartRollupCommitmentPeriod = prev.SmartRollupCommitmentPeriod * 5 / 4; - protocol.SmartRollupChallengeWindow = prev.SmartRollupChallengeWindow * 5 / 4; - protocol.SmartRollupTimeoutPeriod = prev.SmartRollupTimeoutPeriod * 5 / 4; - protocol.BlocksPerSnapshot = protocol.BlocksPerCycle; - protocol.MaxExternalOverOwnStakeRatio = 9; - protocol.StakePowerMultiplier = 3; - } - } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - await RemoveDeadRefutationGames(state); - await RemoveFutureCycles(state, prevProto, nextProto); - await MigrateSlashing(state, nextProto); - MigrateBakers(state, prevProto, nextProto); - await MigrateVotingPeriods(state, nextProto); - var cycles = await MigrateCycles(state, prevProto, nextProto); - await MigrateFutureRights(state, nextProto, cycles); - - Cache.BakerCycles.Reset(); - Cache.BakingRights.Reset(); - } - - async Task RemoveFutureCycles(AppState state, Protocol prevProto, Protocol nextProto) - { - if (prevProto.ConsensusRightsDelay == nextProto.ConsensusRightsDelay) - return; - - var lastCycle = state.Cycle + nextProto.ConsensusRightsDelay + 1; - var lastCycleStart = nextProto.GetCycleStart(lastCycle); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakerCycles" - WHERE "Cycle" > {0} - """, lastCycle); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Type" = {0} - AND "Cycle" > {1}; - - DELETE FROM "BakingRights" - WHERE "Type" = {2} - AND "Level" > {3}; - """, - (int)BakingRightType.Baking, - lastCycle, - (int)BakingRightType.Attestation, - lastCycleStart); - - var removedCycles = await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "Cycles" - WHERE "Index" > {0} - """, lastCycle); - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "DelegatorCycles" - WHERE "Cycle" > {0} - """, lastCycle); - - Cache.BakerCycles.Reset(); - Cache.BakingRights.Reset(); - - Db.TryAttach(state); - state.CyclesCount -= removedCycles; - } - - async Task MigrateSlashing(AppState state, Protocol nextProto) - { - foreach (var op in await Db.DoubleBakingOps.Where(x => x.SlashedLevel > state.Level).ToListAsync()) - { - var proto = await Cache.Protocols.FindByLevelAsync(op.AccusedLevel); - op.SlashedLevel = nextProto.GetCycleEnd(proto.GetCycle(op.AccusedLevel) + proto.SlashingDelay); - } - - foreach (var op in await Db.DoubleConsensusOps.Where(x => x.SlashedLevel > state.Level).ToListAsync()) - { - var proto = await Cache.Protocols.FindByLevelAsync(op.AccusedLevel); - op.SlashedLevel = nextProto.GetCycleEnd(proto.GetCycle(op.AccusedLevel) + proto.SlashingDelay); - } - } - - void MigrateBakers(AppState state, Protocol prevProto, Protocol nextProto) - { - UpdateBakersPower(); - - foreach (var baker in Cache.Accounts.GetDelegates().Where(x => x.DeactivationLevel > state.Level)) - baker.DeactivationLevel = nextProto.GetCycleStart(prevProto.GetCycle(baker.DeactivationLevel)); - } - - async Task MigrateVotingPeriods(AppState state, Protocol nextProto) - { - var newPeriod = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(newPeriod); - newPeriod.LastLevel = newPeriod.FirstLevel + nextProto.BlocksPerVoting - 1; - } - - async Task> MigrateCycles(AppState state, Protocol prevProto, Protocol nextProto) - { - var cycles = await Db.Cycles - .Where(x => x.Index >= state.Cycle) - .OrderBy(x => x.Index) - .ToListAsync(); - - var res = prevProto.ConsensusRightsDelay != nextProto.ConsensusRightsDelay - ? await Proto.Rpc.GetExpectedIssuance(state.Level + 1) // Crutch for buggy ghostnet - : await Proto.Rpc.GetExpectedIssuance(state.Level); - - foreach (var cycle in cycles.Where(x => x.Index > state.Cycle)) - { - var issuance = res.EnumerateArray().First(x => x.RequiredInt32("cycle") == cycle.Index); - - cycle.BlockReward = issuance.RequiredInt64("baking_reward_fixed_portion"); - cycle.BlockBonusPerBlock = GetBlockBonusPerBlock(issuance, nextProto); - cycle.AttestationRewardPerBlock = GetAttestationRewardPerBlock(issuance, nextProto); - cycle.NonceRevelationReward = issuance.RequiredInt64("seed_nonce_revelation_tip"); - cycle.VdfRevelationReward = issuance.RequiredInt64("vdf_revelation_tip"); - - cycle.FirstLevel = nextProto.GetCycleStart(cycle.Index); - cycle.LastLevel = nextProto.GetCycleEnd(cycle.Index); - } - - return cycles; - } - - async Task MigrateFutureRights(AppState state, Protocol nextProto, List cycles) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" > {0} - """, state.Cycle); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - IEnumerable shifted = []; - - foreach (var cycle in cycles) - { - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - var sampler = GetSampler(bakerCycles.Values - .Where(x => x.BakingPower > 0) - .Select(x => (x.BakerId, x.BakingPower)) - .ToList()); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, cycle.Index); - #endregion - - if (cycle.Index == state.Cycle) - { - shifted = RightsGenerator.GetAttestationRights(sampler, nextProto, cycle, cycle.LastLevel); - - #region save shifted - using var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """); - - foreach (var ar in shifted) - { - writer.StartRow(); - writer.Write(cycle.Index + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - writer.Complete(); - #endregion - } - else - { - GC.Collect(); - var brs = await RightsGenerator.GetBakingRightsAsync(sampler, nextProto, cycle); - var ars = await RightsGenerator.GetAttestationRightsAsync(sampler, nextProto, cycle); - - #region save rights - using (var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """)) - { - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(nextProto.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - - #region reset baker cycles - var attestationRewardPerSlot = cycle.AttestationRewardPerBlock / nextProto.AttestersPerBlock; - var maxBlockReward = cycle.BlockReward + cycle.BlockBonusPerBlock; - - foreach (var bakerCycle in bakerCycles.Values) - { - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks = 0; - bakerCycle.FutureBlockRewards = 0; - bakerCycle.FutureAttestations = 0; - - var expectedAttestations = (nextProto.BlocksPerCycle * nextProto.AttestersPerBlock).MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedBlocks = nextProto.BlocksPerCycle.MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = expectedAttestations * attestationRewardPerSlot; - } - - foreach (var br in brs.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += maxBlockReward; - } - - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots; - } - } - - foreach (var ar in ars.TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - shifted = [..ars.Where(x => x.Level == cycle.LastLevel)]; - } - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/AttestationRewardCommit.cs deleted file mode 100644 index c05de216e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class AttestationRewardCommit : Proto19.AttestationRewardCommit - { - public AttestationRewardCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/AutostakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/AutostakingCommit.cs deleted file mode 100644 index a3d9b3dfa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/AutostakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class AutostakingCommit : Proto19.AutostakingCommit - { - public AutostakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BakerCycleCommit.cs deleted file mode 100644 index b134b9105..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class BakerCycleCommit : Proto19.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BakingRightsCommit.cs deleted file mode 100644 index 41b6b634f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class BakingRightsCommit : Proto19.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BigMapCommit.cs deleted file mode 100644 index 837a2998b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BlockCommit.cs deleted file mode 100644 index a204d705c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class BlockCommit : Proto19.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/ContractEventCommit.cs deleted file mode 100644 index a2a0b010f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class ContractEventCommit : Proto14.ContractEventCommit - { - public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/CycleCommit.cs deleted file mode 100644 index 526196186..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/CycleCommit.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto21 -{ - class CycleCommit : Proto20.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - - public override async Task Apply(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - { - Cache.AppState.Get().CyclesCount--; - return; - } - } - - await base.Apply(block); - } - - public override async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - if (block.Cycle == Context.Protocol.FirstCycle) - { - var prevProto = await Cache.Protocols.GetAsync(Context.Protocol.Code - 1); - if (prevProto.ConsensusRightsDelay != Context.Protocol.ConsensusRightsDelay) - { - Cache.AppState.Get().CyclesCount++; - return; - } - } - - await base.Revert(block); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DeactivationCommit.cs deleted file mode 100644 index 09c67de32..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DelegationSnapshotCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DelegationSnapshotCommit.cs deleted file mode 100644 index 5f770904d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DelegationSnapshotCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class DelegationSnapshotCommit(ProtocolHandler protocol) : Proto19.DelegationSnapshotCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 3ec439f59..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class DelegatorCycleCommit : Proto19.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/InboxCommit.cs deleted file mode 100644 index 992e4102b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/InboxCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - public class InboxCommit : Proto17.InboxCommit - { - public InboxCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index c8a29fd03..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index a446f8e4a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class AttestationsCommit : Proto19.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 475945e0a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DalPublishCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DalPublishCommitmentCommit.cs deleted file mode 100644 index 5c592eb5c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DalPublishCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class DalPublishCommitmentCommit : Proto19.DalPublishCommitmentCommit - { - public DalPublishCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index b5e81f5ee..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class DelegationsCommit : Proto18.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index c8bde955a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class DoubleBakingCommit : Proto19.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index b22dd01cd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class DoubleConsensusCommit : Proto19.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index 18c67f46c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class DrainDelegateCommit : Proto15.DrainDelegateCommit - { - public DrainDelegateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index c4e7d4acf..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class IncreasePaidStorageCommit : Proto14.IncreasePaidStorageCommit - { - public IncreasePaidStorageCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index ceedfdd53..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class NonceRevelationsCommit : Proto19.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index d8e5e24c7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class OriginationsCommit : Proto14.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index 8928acf2b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class PreattestationsCommit : Proto19.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 504e639dd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class ProposalsCommit : Proto14.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index 20ca1715b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class RegisterConstantsCommit : Proto14.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index b3ec15f5c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class RevealsCommit : Proto14.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SetDelegateParametersCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SetDelegateParametersCommit.cs deleted file mode 100644 index edd71e604..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SetDelegateParametersCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SetDelegateParametersCommit : Proto18.SetDelegateParametersCommit - { - public SetDelegateParametersCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index 7808e6997..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index bbbf115c5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SmartRollupAddMessagesCommit : Proto16.SmartRollupAddMessagesCommit - { - public SmartRollupAddMessagesCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index b1fc72989..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SmartRollupCementCommit : Proto17.SmartRollupCementCommit - { - public SmartRollupCementCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index 6d3dc65f0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SmartRollupExecuteCommit : Proto16.SmartRollupExecuteCommit - { - public SmartRollupExecuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index 4487bbdeb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SmartRollupOriginateCommit : Proto16.SmartRollupOriginateCommit - { - public SmartRollupOriginateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index 2aad079df..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SmartRollupPublishCommit : Proto16.SmartRollupPublishCommit - { - public SmartRollupPublishCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index 1b5785e30..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SmartRollupRecoverBondCommit : Proto16.SmartRollupRecoverBondCommit - { - public SmartRollupRecoverBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index 91ce775a7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SmartRollupRefuteCommit : Proto16.SmartRollupRefuteCommit - { - public SmartRollupRefuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index 0689c9a47..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SmartRollupTimeoutCommit : Proto16.SmartRollupTimeoutCommit - { - public SmartRollupTimeoutCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/StakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/StakingCommit.cs deleted file mode 100644 index f706bb5b5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/StakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class StakingCommit : Proto19.StakingCommit - { - public StakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index d8a6b2bda..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class TransactionsCommit : Proto14.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index 5706aa7f5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index 0e903ba69..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class UpdateSecondaryKeyCommit : Proto15.UpdateSecondaryKeyCommit - { - public UpdateSecondaryKeyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index f2487df16..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class VdfRevelationCommit : Proto19.VdfRevelationCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SlashingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SlashingCommit.cs deleted file mode 100644 index 5b44d0138..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SlashingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SlashingCommit : Proto19.SlashingCommit - { - public SlashingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 4f5ce8620..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SnapshotBalanceCommit : Proto19.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SoftwareCommit.cs deleted file mode 100644 index 32bed6564..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StakerCycleCommit.cs deleted file mode 100644 index 0f75f0a04..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StakerCycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class StakerCycleCommit(ProtocolHandler protocol) : Proto19.StakerCycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StakingUpdateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StakingUpdateCommit.cs deleted file mode 100644 index 3e441337d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StakingUpdateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class StakingUpdateCommit : Proto18.StakingUpdateCommit - { - public StakingUpdateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StateCommit.cs deleted file mode 100644 index 29e6e7dbb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StatisticsCommit.cs deleted file mode 100644 index 61b8de46f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SubsidyCommit.cs deleted file mode 100644 index d8fdd9632..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/TicketsCommit.cs deleted file mode 100644 index 02901dcb9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/TicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class TicketsCommit : Proto16.TicketsCommit - { - public TicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/TokensCommit.cs deleted file mode 100644 index 4c4a56fb5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/VotingCommit.cs deleted file mode 100644 index e7733f9cd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Diagnostics/Diagnostics.cs deleted file mode 100644 index 019038d96..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto21 -{ - class Diagnostics(ProtocolHandler handler) : Proto18.Diagnostics(handler) - { - protected override bool CheckMinDelegatedBalance(JsonElement remote, Data.Models.Delegate delegat) - { - var minDelegated = remote.Required("min_delegated_in_current_cycle"); - return minDelegated.RequiredInt64("amount") == delegat.MinTotalDelegated && - minDelegated.Required("level").RequiredInt32("level") == delegat.MinTotalDelegatedLevel; - } - - protected override bool CheckFullBalance(JsonElement remote, Data.Models.Delegate delegat) - { - return remote.RequiredInt64("own_full_balance") == delegat.Balance; - } - - protected override bool CheckStakingBalance(JsonElement remote, Data.Models.Delegate delegat) - { - return remote.RequiredInt64("total_staked") == delegat.TotalStaked && remote.RequiredInt64("total_delegated") == delegat.TotalDelegated; - } - - protected override void TestDelegatorsCount(JsonElement remote, Data.Models.Delegate local) - { - var delegators = remote.RequiredArray("delegators").Count(); - if (delegators != local.DelegatorsCount && delegators != local.DelegatorsCount + 1) - throw new Exception($"Diagnostics failed: wrong delegators count {local.Address}"); - } - - protected override bool CheckFrozenDepositLimit(JsonElement remote, Data.Models.Delegate delegat) - { - return true; - } - - protected override bool CheckDelegatedBalance(JsonElement remote, Data.Models.Delegate delegat) - { - return remote.RequiredInt64("external_delegated") == delegat.ExternalDelegatedBalance; - } - - protected override bool CheckBakingPower(JsonElement remote, Data.Models.Delegate delegat) - { - var externalStakeCap = 0L; - if (delegat.LimitOfStakingOverBaking is long limit) - { - var (q, r) = Math.DivRem(limit, 1_000_000); - if (r == 0) - { - externalStakeCap = delegat.OwnStakedBalance * Math.Min(q, Context.Protocol.MaxExternalOverOwnStakeRatio); - } - else - { - var limitOfStakingOverBaking = Math.Min(limit, Context.Protocol.MaxExternalOverOwnStakeRatio * 1_000_000); - externalStakeCap = delegat.OwnStakedBalance.MulRatio(limitOfStakingOverBaking, 1_000_000); - } - } - var overstaked = Math.Max(0, delegat.ExternalStakedBalance - externalStakeCap); - var totalDelegated = remote.Required("min_delegated_in_current_cycle").RequiredInt64("amount") + overstaked; - var delegationCap = delegat.OwnStakedBalance * Context.Protocol.MaxDelegatedOverFrozenRatio; - - var actualStaked = delegat.OwnStakedBalance + delegat.ExternalStakedBalance - overstaked; - var actualDelegated = Math.Min(totalDelegated, delegationCap); - - var state = Cache.AppState.Get(); - if (state.AiActivationLevel is int aiLevel && state.Level >= aiLevel) - actualDelegated /= Context.Protocol.StakePowerMultiplier; - - var uncheckedBakingPower = actualStaked + actualDelegated; - return uncheckedBakingPower == remote.RequiredInt64("baking_power"); - } - - protected override bool CheckVotingPower(JsonElement remote, Data.Models.Delegate delegat) - { - var uncheckedVotingPower = delegat.TotalDelegated + delegat.TotalStaked; - return uncheckedVotingPower == remote.RequiredInt64("current_voting_power"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Helpers.cs deleted file mode 100644 index b7c20ed49..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - public class Helpers(ProtocolHandler proto) : Proto18.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Proto21Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Proto21Handler.cs deleted file mode 100644 index 9132d13cd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Proto21Handler.cs +++ /dev/null @@ -1,512 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto21; - -namespace Tzkt.Sync.Protocols -{ - class Proto21Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "quebec_021"; - public override int VersionNumber => 21; - - public Proto21Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SetDelegateParametersCommit(this).ActivateStakingParameters(blockCommit.Block); - await new UpdateSecondaryKeyCommit(this).ActivateSecondaryKeys(blockCommit.Block); - await new StakerCycleCommit(this).Apply(); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "attestation": - case "attestation_with_dal": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preattestation": - case "preattestation_with_dal": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_attestation_evidence": - case "double_preattestation_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - var ticketsCommit = new TicketsCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var dst = content.RequiredString("destination"); - if (dst.StartsWith("tz") && content.Optional("parameters")?.RequiredString("entrypoint") is string entrypoint) - { - if (Proto18.StakingCommit.ValidateParameters(entrypoint, content.RequiredString("source"), dst)) - { - await new StakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - else if (Proto18.SetDelegateParametersCommit.Entrypoint == entrypoint) - { - await new SetDelegateParametersCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - } - - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - if (parent.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, parent.Transaction, parent.TicketUpdates); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (parent1.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, parent1.Operation, parent1.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_publish_commitment": - await new DalPublishCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await blockCommit.ApplyRewards(block); - - new InboxCommit(this).Apply(blockCommit.Block); - - await bigMapCommit.Apply(); - await ticketsCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SlashingCommit(this).Apply(block, rawBlock); - await new VotingCommit(this).Apply(block, rawBlock); - await new AutostakingCommit(this).Apply(block, rawBlock); - - Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - - await new DelegationSnapshotCommit(this).Apply(); - await new SnapshotBalanceCommit(this).Apply(); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(); - await new DelegationSnapshotCommit(this).Revert(); - await new AutostakingCommit(this).Revert(block); - await new VotingCommit(this).Revert(block); - await new SlashingCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new StatisticsCommit(this).Revert(currBlock); - - await new AttestationRewardCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new TicketsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - await new BlockCommit(this).RevertRewards(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case StakingOperation op: - await new StakingCommit(this).Revert(currBlock, op); - break; - case SetDelegateParametersOperation op: - await new SetDelegateParametersCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - case DalPublishCommitmentOperation op: - await new DalPublishCommitmentCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new StakerCycleCommit(this).Revert(); - await new UpdateSecondaryKeyCommit(this).DeactivateSecondaryKeys(currBlock); - await new SetDelegateParametersCommit(this).DeactivateStakingParameters(currBlock); - await new CycleCommit(this).Revert(currBlock); - new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Rpc/Rpc.cs deleted file mode 100644 index 2d6f2ede7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto21 -{ - class Rpc : Proto19.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto21/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto21/Validation/Validator.cs deleted file mode 100644 index 0e2115966..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto21/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto21 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Activation/ProtoActivator.cs deleted file mode 100644 index 0e4ff7ffc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Activation/ProtoActivator.cs +++ /dev/null @@ -1,280 +0,0 @@ -using System.Numerics; -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto22 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto21.ProtoActivator(proto) - { - protected override long GetDalAttestationRewardPerShard(JsonElement issuance) - { - return issuance.RequiredInt64("dal_attesting_reward_per_shard"); - } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.ConsensusThreshold = parameters["consensus_threshold_size"]?.Value() ?? 4667; - protocol.DenunciationPeriod = parameters["denunciation_period"]?.Value() ?? 1; - protocol.SlashingDelay = parameters["slashing_delay"]?.Value() ?? 1; - protocol.ToleratedInactivityPeriod = parameters["tolerated_inactivity_period"]?.Value() ?? 2; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.ToleratedInactivityPeriod = 2; - - if (Cache.AppState.GetChainId() == "NetXdQprcVkpaWU" && - protocol.BlocksPerCycle > 10_800 && protocol.TimeBetweenBlocks == 8) - { - protocol.BlocksPerCycle = 10_800; - protocol.BlocksPerVoting = protocol.BlocksPerCycle * 14; - protocol.BlocksPerSnapshot = protocol.BlocksPerCycle; - } - else if (protocol.BlocksPerCycle > 10_800 && protocol.TimeBetweenBlocks == 4) - { - protocol.BlocksPerCycle = 10_800; - protocol.BlocksPerVoting = protocol.BlocksPerCycle * (prev.BlocksPerVoting / prev.BlocksPerCycle); - protocol.BlocksPerSnapshot = protocol.BlocksPerCycle; - } - - // for nextnet - if (protocol.MaxExternalOverOwnStakeRatio != 9) - { - protocol.MaxExternalOverOwnStakeRatio = 9; - } - } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - await RemoveDeadRefutationGames(state); - await MigrateSlashing(state, nextProto); - MigrateBakers(state, prevProto, nextProto); - await MigrateVotingPeriods(state, nextProto); - var cycles = await MigrateCycles(state, prevProto, nextProto); - await MigrateFutureRights(state, nextProto, cycles); - - Cache.BakerCycles.Reset(); - Cache.BakingRights.Reset(); - } - - protected override async Task RevertContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - await MigrateSlashing(state, prevProto); - MigrateBakers(state, nextProto, prevProto); - - Cache.BakerCycles.Reset(); - Cache.BakingRights.Reset(); - } - - async Task MigrateSlashing(AppState state, Protocol nextProto) - { - foreach (var op in await Db.DoubleBakingOps.Where(x => x.SlashedLevel > state.Level).ToListAsync()) - { - var proto = await Cache.Protocols.FindByLevelAsync(op.AccusedLevel); - op.SlashedLevel = nextProto.GetCycleEnd(proto.GetCycle(op.AccusedLevel) + proto.SlashingDelay); - } - - foreach (var op in await Db.DoubleConsensusOps.Where(x => x.SlashedLevel > state.Level).ToListAsync()) - { - var proto = await Cache.Protocols.FindByLevelAsync(op.AccusedLevel); - op.SlashedLevel = nextProto.GetCycleEnd(proto.GetCycle(op.AccusedLevel) + proto.SlashingDelay); - } - } - - void MigrateBakers(AppState state, Protocol prevProto, Protocol nextProto) - { - UpdateBakersPower(); - - foreach (var baker in Cache.Accounts.GetDelegates().Where(x => x.DeactivationLevel > state.Level)) - { - Db.TryAttach(baker); - baker.DeactivationLevel = nextProto.GetCycleStart(prevProto.GetCycle(baker.DeactivationLevel)); - } - } - - async Task MigrateVotingPeriods(AppState state, Protocol nextProto) - { - var newPeriod = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(newPeriod); - newPeriod.LastLevel = newPeriod.FirstLevel + nextProto.BlocksPerVoting - 1; - } - - async Task> MigrateCycles(AppState state, Protocol prevProto, Protocol nextProto) - { - var cycles = await Db.Cycles - .Where(x => x.Index >= state.Cycle) - .OrderBy(x => x.Index) - .ToListAsync(); - - var res = prevProto.ConsensusRightsDelay != nextProto.ConsensusRightsDelay - ? await Proto.Rpc.GetExpectedIssuance(state.Level + 1) // Crutch for buggy ghostnet - : await Proto.Rpc.GetExpectedIssuance(state.Level); - - foreach (var cycle in cycles.Where(x => x.Index > state.Cycle)) - { - var issuance = res.EnumerateArray().First(x => x.RequiredInt32("cycle") == cycle.Index); - - cycle.BlockReward = issuance.RequiredInt64("baking_reward_fixed_portion"); - cycle.BlockBonusPerBlock = GetBlockBonusPerBlock(issuance, nextProto); - cycle.AttestationRewardPerBlock = GetAttestationRewardPerBlock(issuance, nextProto); - cycle.NonceRevelationReward = issuance.RequiredInt64("seed_nonce_revelation_tip"); - cycle.VdfRevelationReward = issuance.RequiredInt64("vdf_revelation_tip"); - cycle.DalAttestationRewardPerShard = issuance.RequiredInt64("dal_attesting_reward_per_shard"); - - cycle.FirstLevel = nextProto.GetCycleStart(cycle.Index); - cycle.LastLevel = nextProto.GetCycleEnd(cycle.Index); - } - - return cycles; - } - - async Task MigrateFutureRights(AppState state, Protocol nextProto, List cycles) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" > {0} - """, state.Cycle); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - IEnumerable shifted = []; - - foreach (var cycle in cycles) - { - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - var sampler = GetSampler(bakerCycles.Values - .Where(x => x.BakingPower > 0) - .Select(x => (x.BakerId, x.BakingPower)) - .ToList()); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, cycle.Index); - #endregion - - if (cycle.Index == state.Cycle) - { - shifted = RightsGenerator.GetAttestationRights(sampler, nextProto, cycle, cycle.LastLevel); - - #region save shifted - using var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """); - - foreach (var ar in shifted) - { - writer.StartRow(); - writer.Write(cycle.Index + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - writer.Complete(); - #endregion - } - else - { - GC.Collect(); - var brs = await RightsGenerator.GetBakingRightsAsync(sampler, nextProto, cycle); - var ars = await RightsGenerator.GetAttestationRightsAsync(sampler, nextProto, cycle); - - #region save rights - using (var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """)) - { - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(nextProto.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - - #region reset baker cycles - var attestationRewardPerSlot = cycle.AttestationRewardPerBlock / nextProto.AttestersPerBlock; - var maxBlockReward = cycle.BlockReward + cycle.BlockBonusPerBlock; - - foreach (var bakerCycle in bakerCycles.Values) - { - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks = 0; - bakerCycle.FutureBlockRewards = 0; - bakerCycle.FutureAttestations = 0; - - var expectedAttestations = (nextProto.BlocksPerCycle * nextProto.AttestersPerBlock).MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - var expectedDalAttestations = (nextProto.BlocksPerCycle * nextProto.NumberOfShards).MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedBlocks = nextProto.BlocksPerCycle.MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = expectedAttestations * attestationRewardPerSlot; - bakerCycle.ExpectedDalAttestations = expectedDalAttestations; - bakerCycle.FutureDalAttestationRewards = expectedDalAttestations * cycle.DalAttestationRewardPerShard; - } - - foreach (var br in brs.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += maxBlockReward; - } - - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots; - } - } - - foreach (var ar in ars.TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - shifted = [.. ars.Where(x => x.Level == cycle.LastLevel)]; - } - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/AttestationRewardCommit.cs deleted file mode 100644 index 9d8020bf1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class AttestationRewardCommit : Proto19.AttestationRewardCommit - { - public AttestationRewardCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/AutostakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/AutostakingCommit.cs deleted file mode 100644 index 7424bdbfd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/AutostakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class AutostakingCommit : Proto19.AutostakingCommit - { - public AutostakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BakerCycleCommit.cs deleted file mode 100644 index 6b58a42ec..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class BakerCycleCommit : Proto19.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BakingRightsCommit.cs deleted file mode 100644 index bf9f9fb2a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class BakingRightsCommit : Proto19.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BigMapCommit.cs deleted file mode 100644 index e9ecc3db4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BlockCommit.cs deleted file mode 100644 index e63708ec8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class BlockCommit : Proto19.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/ContractEventCommit.cs deleted file mode 100644 index 03fe67997..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class ContractEventCommit : Proto14.ContractEventCommit - { - public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/CycleCommit.cs deleted file mode 100644 index 3efa6a40d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/CycleCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto22 -{ - class CycleCommit : Proto21.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override long GetDalAttestationRewardPerShard(JsonElement issuance) - { - return issuance.RequiredInt64("dal_attesting_reward_per_shard"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DalAttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DalAttestationRewardCommit.cs deleted file mode 100644 index 00ce4b3e8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DalAttestationRewardCommit.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DalAttestationRewardCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply(Block block, JsonElement rawBlock) - { - if (!block.Events.HasFlag(BlockEvents.CycleEnd)) - return; - - var state = Cache.AppState.Get(); - var bakerCycles = await Cache.BakerCycles.GetAsync(block.Cycle); - var ops = bakerCycles - .Where(x => x.Value.FutureDalAttestationRewards > 0) - .ToDictionary( - x => x.Key, - bakerCycle => new DalAttestationRewardOperation - { - Id = Cache.AppState.NextOperationId(), - BakerId = bakerCycle.Key, - Level = block.Level, - Timestamp = block.Timestamp, - Expected = bakerCycle.Value.FutureDalAttestationRewards - }); - - var balanceUpdates = rawBlock.Required("metadata").RequiredArray("balance_updates").EnumerateArray().Where(x => x.RequiredString("origin") == "block").ToList(); - for (int i = 0; i < balanceUpdates.Count; i++) - { - var update = balanceUpdates[i]; - if (update.RequiredString("kind") == "minted" && update.RequiredString("category") == "DAL attesting rewards") - { - if (i == balanceUpdates.Count - 1) - throw new Exception("Unexpected DAL attestation rewards balance updates behavior"); - - var change = -update.RequiredInt64("change"); - - var nextUpdate = balanceUpdates[i + 1]; - if (nextUpdate.RequiredInt64("change") != change) - throw new Exception("Unexpected DAL attestation rewards balance updates behavior"); - - if (nextUpdate.RequiredString("kind") == "freezer" && nextUpdate.RequiredString("category") == "deposits") - { - var staker = nextUpdate.Required("staker"); - if (staker.TryGetProperty("baker_own_stake", out var p)) - { - var baker = Cache.Accounts.GetExistingDelegate(p.RequiredString()); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected DAL attestation rewards balance update"); - - op.RewardStakedOwn += change; - } - else if (staker.TryGetProperty("baker_edge", out p)) - { - var baker = Cache.Accounts.GetExistingDelegate(p.RequiredString()); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected DAL attestation rewards balance update"); - - op.RewardStakedEdge += change; - } - else if (staker.TryGetProperty("delegate", out p)) - { - var baker = Cache.Accounts.GetExistingDelegate(p.RequiredString()); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected DAL attestation rewards balance update"); - - op.RewardStakedShared += change; - } - else - { - throw new Exception("Unexpected DAL attestation rewards balance updates behavior"); - } - } - else if (nextUpdate.RequiredString("kind") == "contract") - { - var baker = Cache.Accounts.GetExistingDelegate(nextUpdate.RequiredString("contract")); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected DAL attestation rewards balance update"); - - op.RewardDelegated = change; - } - else if (nextUpdate.RequiredString("kind") == "burned" && nextUpdate.RequiredString("category") == "lost DAL attesting rewards") - { - var baker = Cache.Accounts.GetExistingDelegate(nextUpdate.RequiredString("delegate")); - if (!ops.TryGetValue(baker.Id, out var op)) - throw new Exception("Unexpected DAL attestation rewards balance update"); - - if (op.Expected != change) - throw new Exception("FutureDalAttestationRewards != loss"); - - op.RewardDelegated = 0; - op.RewardStakedOwn = 0; - op.RewardStakedEdge = 0; - op.RewardStakedShared = 0; - } - else - { - throw new Exception("Unexpected DAL attestation rewards balance updates behavior"); - } - } - } - - foreach (var op in ops.Values) - { - var bakerCycle = bakerCycles[op.BakerId]; - Db.TryAttach(bakerCycle); - - bakerCycle.FutureDalAttestationRewards = 0; - if (op.RewardDelegated != 0 || op.RewardStakedOwn != 0 || op.RewardStakedEdge != 0 || op.RewardStakedShared != 0) - { - if (op.Expected != op.RewardDelegated + op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared) - throw new Exception("ExpectedReward != RewardFrozen + RewardDelegated"); - - bakerCycle.DalAttestationRewardsDelegated = op.RewardDelegated; - bakerCycle.DalAttestationRewardsStakedOwn = op.RewardStakedOwn; - bakerCycle.DalAttestationRewardsStakedEdge = op.RewardStakedEdge; - bakerCycle.DalAttestationRewardsStakedShared = op.RewardStakedShared; - } - else - { - bakerCycle.MissedDalAttestationRewards = op.Expected; - } - - - var baker = Cache.Accounts.GetDelegate(op.BakerId); - Db.TryAttach(baker); - - ReceiveRewards(baker, op.RewardDelegated, op.RewardStakedOwn, op.RewardStakedEdge, op.RewardStakedShared); - baker.DalAttestationRewardsCount++; - - block.Operations |= Operations.DalAttestationReward; - - Cache.Statistics.Current.TotalCreated += op.RewardDelegated + op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared; - Cache.Statistics.Current.TotalFrozen += op.RewardStakedOwn + op.RewardStakedEdge + op.RewardStakedShared; - } - - Cache.AppState.Get().DalAttestationRewardOpsCount += ops.Count; - - Db.DalAttestationRewardOps.AddRange(ops.Values); - Context.DalAttestationRewardOps.AddRange(ops.Values); - } - - public virtual async Task Revert(Block block) - { - if (!block.Operations.HasFlag(Operations.DalAttestationReward)) - return; - - var ops = await Db.DalAttestationRewardOps.Where(x => x.Level == block.Level).ToListAsync(); - - foreach (var op in ops) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.FutureDalAttestationRewards = op.Expected; - bakerCycle.MissedDalAttestationRewards = 0; - bakerCycle.DalAttestationRewardsDelegated = 0; - bakerCycle.DalAttestationRewardsStakedOwn = 0; - bakerCycle.DalAttestationRewardsStakedEdge = 0; - bakerCycle.DalAttestationRewardsStakedShared = 0; - - var baker = Cache.Accounts.GetDelegate(op.BakerId); - Db.TryAttach(baker); - - RevertReceiveRewards(baker, op.RewardDelegated, op.RewardStakedOwn, op.RewardStakedEdge, op.RewardStakedShared); - baker.DalAttestationRewardsCount--; - } - - Cache.AppState.Get().DalAttestationRewardOpsCount -= ops.Count; - - Db.DalAttestationRewardOps.RemoveRange(ops); - Cache.AppState.ReleaseOperationId(ops.Count); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DeactivationCommit.cs deleted file mode 100644 index 81c385e6b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DelegationSnapshotCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DelegationSnapshotCommit.cs deleted file mode 100644 index 755741348..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DelegationSnapshotCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DelegationSnapshotCommit(ProtocolHandler protocol) : Proto19.DelegationSnapshotCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index b58ea46cd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DelegatorCycleCommit : Proto19.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/InboxCommit.cs deleted file mode 100644 index 9c2e6dfed..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/InboxCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - public class InboxCommit : Proto17.InboxCommit - { - public InboxCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 4c0bb5f67..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 4653d3a7c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class AttestationsCommit : Proto19.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 3f8c74d9a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DalEntrapmentEvidenceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DalEntrapmentEvidenceCommit.cs deleted file mode 100644 index dd62c4624..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DalEntrapmentEvidenceCommit.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DalEntrapmentEvidenceCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var trapLevel = GetTrapLevel(content); - var trapSlotIndex = content.RequiredInt32("slot_index"); - - var accuser = Context.Proposer; - var offender = Cache.Accounts.GetDelegate(await GetAttester(trapLevel, GetConsensusSlot(content))); - - var operation = new DalEntrapmentEvidenceOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - - AccuserId = accuser.Id, - OffenderId = offender.Id, - - TrapLevel = trapLevel, - TrapSlotIndex = trapSlotIndex, - }; - #endregion - - #region apply operation - Db.TryAttach(accuser); - accuser.DalEntrapmentEvidenceOpsCount++; - - if (offender.Id != accuser.Id) - { - Db.TryAttach(offender); - offender.DalEntrapmentEvidenceOpsCount++; - } - - block.Operations |= Operations.DalEntrapmentEvidence; - - Cache.AppState.Get().DalEntrapmentEvidenceOpsCount++; - #endregion - - Db.DalEntrapmentEvidenceOps.Add(operation); - Context.DalEntrapmentEvidenceOps.Add(operation); - } - - public void Revert(DalEntrapmentEvidenceOperation operation) - { - #region init - var accuser = Cache.Accounts.GetDelegate(operation.AccuserId); - var offender = Cache.Accounts.GetDelegate(operation.OffenderId); - #endregion - - #region revert operation - Db.TryAttach(accuser); - accuser.DalEntrapmentEvidenceOpsCount--; - - if (offender.Id != accuser.Id) - { - Db.TryAttach(offender); - offender.DalEntrapmentEvidenceOpsCount--; - } - - Cache.AppState.Get().DalEntrapmentEvidenceOpsCount--; - #endregion - - Db.DalEntrapmentEvidenceOps.Remove(operation); - Cache.AppState.ReleaseOperationId(); - } - - protected virtual int GetTrapLevel(JsonElement content) - { - return content.Required("attestation").Required("operations").RequiredInt32("level"); - } - - protected virtual int GetConsensusSlot(JsonElement content) - { - return content.Required("attestation").Required("operations").RequiredInt32("slot"); - } - - async Task GetAttester(int level, int slot) - { - var cycleIndex = Context.Protocol.GetCycle(level); - var cycle = await Db.Cycles.SingleAsync(x => x.Index == cycleIndex); - - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - var sampler = GetSampler(bakerCycles.Values - .Where(x => x.BakingPower > 0) - .Select(x => (x.BakerId, x.BakingPower)) - .ToList()); - - return RightsGenerator.GetAttester(sampler, cycle, level, slot); - } - - Sampler GetSampler(IEnumerable<(int id, long stake)> selection) - { - var sorted = selection.OrderByDescending(x => - { - var baker = Cache.Accounts.GetDelegate(x.id); - return new byte[] { (byte)baker.PublicKey![0] }.Concat(Base58.Parse(baker.Address)); - }, new BytesComparer()); - - return new Sampler([..sorted.Select(x => x.id)], [..sorted.Select(x => x.stake)]); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DalPublishCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DalPublishCommitmentCommit.cs deleted file mode 100644 index 8e2eb57c8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DalPublishCommitmentCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DalPublishCommitmentCommit : Proto19.DalPublishCommitmentCommit - { - public DalPublishCommitmentCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index c5011be28..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DelegationsCommit : Proto18.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 264daae4e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DoubleBakingCommit : Proto19.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 5636afe99..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DoubleConsensusCommit : Proto19.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index da74f9981..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class DrainDelegateCommit : Proto15.DrainDelegateCommit - { - public DrainDelegateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index 8ff554bec..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class IncreasePaidStorageCommit : Proto14.IncreasePaidStorageCommit - { - public IncreasePaidStorageCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index e4dde9d43..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class NonceRevelationsCommit : Proto19.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index d065cb9ef..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class OriginationsCommit : Proto14.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index cdb3b6215..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class PreattestationsCommit : Proto19.PreattestationsCommit - { - public PreattestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index b8a3cf415..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class ProposalsCommit : Proto14.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index a6d46da3d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class RegisterConstantsCommit : Proto14.RegisterConstantsCommit - { - public RegisterConstantsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 83e62510f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class RevealsCommit : Proto14.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SetDelegateParametersCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SetDelegateParametersCommit.cs deleted file mode 100644 index 260a3cbf6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SetDelegateParametersCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SetDelegateParametersCommit : Proto18.SetDelegateParametersCommit - { - public SetDelegateParametersCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index fe083c6a7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SetDepositsLimitCommit : Proto12.SetDepositsLimitCommit - { - public SetDepositsLimitCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index 566e01304..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SmartRollupAddMessagesCommit : Proto16.SmartRollupAddMessagesCommit - { - public SmartRollupAddMessagesCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index fe7304f1c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SmartRollupCementCommit : Proto17.SmartRollupCementCommit - { - public SmartRollupCementCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index 599e88972..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SmartRollupExecuteCommit : Proto16.SmartRollupExecuteCommit - { - public SmartRollupExecuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index d6391ddbf..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SmartRollupOriginateCommit : Proto16.SmartRollupOriginateCommit - { - public SmartRollupOriginateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index 4bc4440d7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SmartRollupPublishCommit : Proto16.SmartRollupPublishCommit - { - public SmartRollupPublishCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index 1f6534fe4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SmartRollupRecoverBondCommit : Proto16.SmartRollupRecoverBondCommit - { - public SmartRollupRecoverBondCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index 7bfb040ec..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SmartRollupRefuteCommit : Proto16.SmartRollupRefuteCommit - { - public SmartRollupRefuteCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index 96f7cbd40..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SmartRollupTimeoutCommit : Proto16.SmartRollupTimeoutCommit - { - public SmartRollupTimeoutCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/StakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/StakingCommit.cs deleted file mode 100644 index a22852078..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/StakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class StakingCommit : Proto19.StakingCommit - { - public StakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 26f4c8414..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class TransactionsCommit : Proto14.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index cbf8ddb5e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class TransferTicketCommit : Proto13.TransferTicketCommit - { - public TransferTicketCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index 50b4b2497..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class UpdateSecondaryKeyCommit : Proto15.UpdateSecondaryKeyCommit - { - public UpdateSecondaryKeyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 4cc2b739b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class VdfRevelationCommit : Proto19.VdfRevelationCommit - { - public VdfRevelationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SlashingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SlashingCommit.cs deleted file mode 100644 index 7a5742049..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SlashingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SlashingCommit : Proto19.SlashingCommit - { - public SlashingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 51957d1f8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SnapshotBalanceCommit : Proto19.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SoftwareCommit.cs deleted file mode 100644 index b8adc600e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StakerCycleCommit.cs deleted file mode 100644 index 3ffb23831..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StakerCycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class StakerCycleCommit(ProtocolHandler protocol) : Proto19.StakerCycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StakingUpdateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StakingUpdateCommit.cs deleted file mode 100644 index 5a86d8b38..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StakingUpdateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class StakingUpdateCommit : Proto18.StakingUpdateCommit - { - public StakingUpdateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StateCommit.cs deleted file mode 100644 index c7ad8a353..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StatisticsCommit.cs deleted file mode 100644 index faf0ab50c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SubsidyCommit.cs deleted file mode 100644 index 7c651b7f4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class SubsidyCommit : Proto10.SubsidyCommit - { - public SubsidyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/TicketsCommit.cs deleted file mode 100644 index 6aee86c6f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/TicketsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class TicketsCommit : Proto16.TicketsCommit - { - public TicketsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/TokensCommit.cs deleted file mode 100644 index 514ae59ba..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/VotingCommit.cs deleted file mode 100644 index 69888894b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Diagnostics/Diagnostics.cs deleted file mode 100644 index d33a92518..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto22 -{ - class Diagnostics(ProtocolHandler handler) : Proto21.Diagnostics(handler) - { - protected override async Task TestDalParticipation(AppState state) - { - var bakers = Cache.Accounts.GetDelegates().ToList(); - var bakerCycles = Db.ChangeTracker.Entries() - .Where(x => x.Entity is BakerCycle bc && bc.Cycle == state.Cycle) - .Select(x => (x.Entity as BakerCycle)!) - .ToDictionary(x => x.BakerId); - - foreach (var baker in bakers) - { - var remote = await Rpc.GetDelegateDalParticipationAsync(state.Level, baker.Address); - - if (!bakerCycles.TryGetValue(baker.Id, out var bakerCycle)) - bakerCycle = await Db.BakerCycles.FirstOrDefaultAsync(x => x.Cycle == state.Cycle && x.BakerId == baker.Id); - - if (bakerCycle != null) - { - if (remote.RequiredInt64("expected_assigned_shards_per_slot") != bakerCycle.ExpectedDalAttestations) - throw new Exception($"Invalid baker ExpectedDalAttestations {baker.Address}"); - - if (remote.RequiredInt64("expected_dal_rewards") != bakerCycle.FutureDalAttestationRewards) - { - if (remote.RequiredInt64("expected_dal_rewards") != 0 || remote.RequiredBool("sufficient_dal_participation") && !remote.RequiredBool("denounced")) - throw new Exception($"Invalid baker FutureDalAttestationRewards {baker.Address}"); - } - } - else - { - if (remote.RequiredInt64("expected_assigned_shards_per_slot") != 0) - throw new Exception($"Invalid baker ExpectedDalAttestations {baker.Address}"); - - if (remote.RequiredInt64("expected_dal_rewards") != 0) - throw new Exception($"Invalid baker FutureDalAttestationRewards {baker.Address}"); - } - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Helpers.cs deleted file mode 100644 index 72140414c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - public class Helpers(ProtocolHandler proto) : Proto18.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Proto22Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Proto22Handler.cs deleted file mode 100644 index 9980d1c3f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Proto22Handler.cs +++ /dev/null @@ -1,520 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto22; - -namespace Tzkt.Sync.Protocols -{ - class Proto22Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "r022_022"; - public override int VersionNumber => 22; - - public Proto22Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SetDelegateParametersCommit(this).ActivateStakingParameters(blockCommit.Block); - await new UpdateSecondaryKeyCommit(this).ActivateSecondaryKeys(blockCommit.Block); - await new StakerCycleCommit(this).Apply(); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "attestation": - case "attestation_with_dal": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preattestation": - case "preattestation_with_dal": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_entrapment_evidence": - await new DalEntrapmentEvidenceCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_attestation_evidence": - case "double_preattestation_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - var ticketsCommit = new TicketsCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var dst = content.RequiredString("destination"); - if (dst.StartsWith("tz") && content.Optional("parameters")?.RequiredString("entrypoint") is string entrypoint) - { - if (Proto18.StakingCommit.ValidateParameters(entrypoint, content.RequiredString("source"), dst)) - { - await new StakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - else if (Proto18.SetDelegateParametersCommit.Entrypoint == entrypoint) - { - await new SetDelegateParametersCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - } - - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - if (parent.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, parent.Transaction, parent.TicketUpdates); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (parent1.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, parent1.Operation, parent1.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_publish_commitment": - await new DalPublishCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await blockCommit.ApplyRewards(block); - - new InboxCommit(this).Apply(blockCommit.Block); - - await bigMapCommit.Apply(); - await ticketsCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new DalAttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SlashingCommit(this).Apply(block, rawBlock); - await new VotingCommit(this).Apply(block, rawBlock); - await new AutostakingCommit(this).Apply(block, rawBlock); - - Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - - await new DelegationSnapshotCommit(this).Apply(); - await new SnapshotBalanceCommit(this).Apply(); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(); - await new DelegationSnapshotCommit(this).Revert(); - await new AutostakingCommit(this).Revert(block); - await new VotingCommit(this).Revert(block); - await new SlashingCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new StatisticsCommit(this).Revert(currBlock); - - await new DalAttestationRewardCommit(this).Revert(currBlock); - await new AttestationRewardCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new TicketsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - await new BlockCommit(this).RevertRewards(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DalEntrapmentEvidenceOperation op: - new DalEntrapmentEvidenceCommit(this).Revert(op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case StakingOperation op: - await new StakingCommit(this).Revert(currBlock, op); - break; - case SetDelegateParametersOperation op: - await new SetDelegateParametersCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - case DalPublishCommitmentOperation op: - await new DalPublishCommitmentCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new StakerCycleCommit(this).Revert(); - await new UpdateSecondaryKeyCommit(this).DeactivateSecondaryKeys(currBlock); - await new SetDelegateParametersCommit(this).DeactivateStakingParameters(currBlock); - await new CycleCommit(this).Revert(currBlock); - new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Rpc/Rpc.cs deleted file mode 100644 index b158b54ad..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Rpc/Rpc.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto22 -{ - class Rpc : Proto19.Rpc - { - public Rpc(TezosNode node) : base(node) { } - - public override Task GetDelegateDalParticipationAsync(int level, string address) - => Node.GetAsync($"chains/main/blocks/{level}/context/delegates/{address}/dal_participation"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto22/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto22/Validation/Validator.cs deleted file mode 100644 index 7cad42fa0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto22/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto22 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Activation/ProtoActivator.cs deleted file mode 100644 index a219325cb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Activation/ProtoActivator.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto23 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto22.ProtoActivator(proto) - { - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - if (prev.BlocksPerCycle == 10800 && prev.BlocksPerCommitment == 240) - protocol.BlocksPerCommitment = 84; - } - - protected override async Task ActivateContext(AppState state) - { - await base.ActivateContext(state); - Cache.AppState.Get().AiActivationLevel = 1; - UpdateBakersPower(); - } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - #region unreveal tz4 - foreach (var account in await Db.Users.Where(x => x.Revealed && x.Address.StartsWith("tz4")).ToListAsync()) - { - Cache.Accounts.Add(account); - Db.TryAttach(account); - account.Revealed = false; - } - #endregion - - #region update revelation rewards - if (prevProto.BlocksPerCommitment != nextProto.BlocksPerCommitment) - { - foreach (var cycle in await Db.Cycles.Where(x => x.Index > state.Cycle).ToListAsync()) - { - cycle.NonceRevelationReward = cycle.NonceRevelationReward * nextProto.BlocksPerCommitment / prevProto.BlocksPerCommitment; - cycle.VdfRevelationReward= cycle.VdfRevelationReward * nextProto.BlocksPerCommitment / prevProto.BlocksPerCommitment; - } - } - #endregion - } - - protected override Task RevertContext(AppState state) => throw new NotImplementedException(); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/AttestationRewardCommit.cs deleted file mode 100644 index 14120e0d0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class AttestationRewardCommit(ProtocolHandler protocol) : Proto19.AttestationRewardCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/AutostakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/AutostakingCommit.cs deleted file mode 100644 index 017eda44f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/AutostakingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class AutostakingCommit(ProtocolHandler protocol) : Proto19.AutostakingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BakerCycleCommit.cs deleted file mode 100644 index 28a9288a3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class BakerCycleCommit(ProtocolHandler protocol) : Proto19.BakerCycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BakingRightsCommit.cs deleted file mode 100644 index 5acb8a249..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class BakingRightsCommit(ProtocolHandler protocol) : Proto19.BakingRightsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BigMapCommit.cs deleted file mode 100644 index 64e488253..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BigMapCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class BigMapCommit(ProtocolHandler protocol) : Proto1.BigMapCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BlockCommit.cs deleted file mode 100644 index cdb2b6cc6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/BlockCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class BlockCommit(ProtocolHandler protocol) : Proto19.BlockCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/ContractEventCommit.cs deleted file mode 100644 index 62fa220f6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/ContractEventCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class ContractEventCommit(ProtocolHandler protocol) : Proto14.ContractEventCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/CycleCommit.cs deleted file mode 100644 index f12e0de6a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/CycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class CycleCommit(ProtocolHandler protocol) : Proto22.CycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DalAttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DalAttestationRewardCommit.cs deleted file mode 100644 index 31d1eaccb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DalAttestationRewardCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DalAttestationRewardCommit(ProtocolHandler protocol) : Proto22.DalAttestationRewardCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DeactivationCommit.cs deleted file mode 100644 index 356ae6c7d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DeactivationCommit(ProtocolHandler protocol) : Proto2.DeactivationCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DelegationSnapshotCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DelegationSnapshotCommit.cs deleted file mode 100644 index ed7f89273..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DelegationSnapshotCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DelegationSnapshotCommit(ProtocolHandler protocol) : Proto19.DelegationSnapshotCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 4c2214a79..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DelegatorCycleCommit(ProtocolHandler protocol) : Proto19.DelegatorCycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/InboxCommit.cs deleted file mode 100644 index cf5a65abd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/InboxCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class InboxCommit(ProtocolHandler protocol) : Proto17.InboxCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index ff9eb48b7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class ActivationsCommit(ProtocolHandler protocol) : Proto1.ActivationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/AttestationAggregateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/AttestationAggregateCommit.cs deleted file mode 100644 index d5eb06286..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/AttestationAggregateCommit.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto23 -{ - class AttestationAggregateCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public IEnumerable<(string, string, long)> ExtractAttestations(JsonElement op, JsonElement content) - { - var res = new List<(string, string, long)>(); - - var opHash = op.RequiredString("hash"); - foreach (var c in content.Required("metadata").RequiredArray("committee").EnumerateArray()) - { - var baker = Cache.Accounts.GetExistingDelegate(c.RequiredString("delegate")); - var power = GetPower(c); - res.Add((opHash, baker.Address, power)); - } - - return res; - } - - protected virtual long GetPower(JsonElement c) - { - return c.RequiredInt64("consensus_power"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index d1f71ba75..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class AttestationsCommit(ProtocolHandler protocol) : Proto19.AttestationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 7ee7afb09..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class BallotsCommit(ProtocolHandler protocol) : Proto3.BallotsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DalEntrapmentEvidenceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DalEntrapmentEvidenceCommit.cs deleted file mode 100644 index f26a0425b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DalEntrapmentEvidenceCommit.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DalEntrapmentEvidenceCommit(ProtocolHandler protocol) : Proto22.DalEntrapmentEvidenceCommit(protocol) - { - protected override int GetTrapLevel(JsonElement content) - { - var op = content.Required("attestation").Required("operations"); - if (!op.TryGetProperty("consensus_content", out var consensusContent)) - consensusContent = op; - - return consensusContent.RequiredInt32("level"); - } - - protected override int GetConsensusSlot(JsonElement content) - { - return content.RequiredInt32("consensus_slot"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DalPublishCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DalPublishCommitmentCommit.cs deleted file mode 100644 index 6265bc13e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DalPublishCommitmentCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DalPublishCommitmentCommit(ProtocolHandler protocol) : Proto19.DalPublishCommitmentCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index ff1c7ceb3..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DelegationsCommit(ProtocolHandler protocol) : Proto18.DelegationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index d7d77ae25..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DoubleBakingCommit(ProtocolHandler protocol) : Proto19.DoubleBakingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 001669faa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DoubleConsensusCommit(ProtocolHandler protocol) : Proto19.DoubleConsensusCommit(protocol) - { - protected override int GetAccusedLevel(JsonElement content) - { - return content.Required("metadata").Required("misbehaviour").RequiredInt32("level"); - } - - protected override string GetOffender(JsonElement content) - { - return content.Required("metadata").RequiredString("punished_delegate"); - } - - protected override DoubleConsensusKind GetKind(JsonElement content) - { - return content.Required("metadata").Required("misbehaviour").RequiredString("kind")[0] == 'a' - ? DoubleConsensusKind.DoubleAttestation - : DoubleConsensusKind.DoublePreattestation; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index 6dfc8be1a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class DrainDelegateCommit(ProtocolHandler protocol) : Proto15.DrainDelegateCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/IncreasePaidStorageCommit.cs deleted file mode 100644 index b50a35029..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/IncreasePaidStorageCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class IncreasePaidStorageCommit(ProtocolHandler protocol) : Proto14.IncreasePaidStorageCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 5a1c69db4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class NonceRevelationsCommit(ProtocolHandler protocol) : Proto19.NonceRevelationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 32aae6646..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class OriginationsCommit(ProtocolHandler protocol) : Proto14.OriginationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/PreattestationAggregateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/PreattestationAggregateCommit.cs deleted file mode 100644 index f4f977d07..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/PreattestationAggregateCommit.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto23 -{ - class PreattestationAggregateCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public IEnumerable<(string, string, long)> ExtractPreattestations(JsonElement op, JsonElement content) - { - var res = new List<(string, string, long)>(); - - var opHash = op.RequiredString("hash"); - foreach (var c in content.Required("metadata").RequiredArray("committee").EnumerateArray()) - { - var baker = Cache.Accounts.GetExistingDelegate(c.RequiredString("delegate")); - var power = GetPower(c); - res.Add((opHash, baker.Address, power)); - } - - return res; - } - - protected virtual long GetPower(JsonElement c) - { - return c.RequiredInt64("consensus_power"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index a3bc2b67d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class PreattestationsCommit(ProtocolHandler protocol) : Proto19.PreattestationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 667f106b1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class ProposalsCommit(ProtocolHandler protocol) : Proto14.ProposalsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/RegisterConstantsCommit.cs deleted file mode 100644 index dba15db62..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/RegisterConstantsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class RegisterConstantsCommit(ProtocolHandler protocol) : Proto14.RegisterConstantsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index bf5e17251..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class RevealsCommit(ProtocolHandler protocol) : Proto14.RevealsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SetDelegateParametersCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SetDelegateParametersCommit.cs deleted file mode 100644 index bed852f8a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SetDelegateParametersCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SetDelegateParametersCommit(ProtocolHandler protocol) : Proto18.SetDelegateParametersCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index e5bd31523..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SetDepositsLimitCommit(ProtocolHandler protocol) : Proto12.SetDepositsLimitCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index c8865a848..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SmartRollupAddMessagesCommit(ProtocolHandler protocol) : Proto16.SmartRollupAddMessagesCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index b7fd810d6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SmartRollupCementCommit(ProtocolHandler protocol) : Proto17.SmartRollupCementCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index 4a7a870dd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SmartRollupExecuteCommit(ProtocolHandler protocol) : Proto16.SmartRollupExecuteCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index f4a3f5453..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SmartRollupOriginateCommit(ProtocolHandler protocol) : Proto16.SmartRollupOriginateCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index ef2065092..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SmartRollupPublishCommit(ProtocolHandler protocol) : Proto16.SmartRollupPublishCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index 140b0d21c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SmartRollupRecoverBondCommit(ProtocolHandler protocol) : Proto16.SmartRollupRecoverBondCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index 66b96f7d7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SmartRollupRefuteCommit(ProtocolHandler protocol) : Proto16.SmartRollupRefuteCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index 4742fdb3b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SmartRollupTimeoutCommit(ProtocolHandler protocol) : Proto16.SmartRollupTimeoutCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/StakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/StakingCommit.cs deleted file mode 100644 index 05830db48..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/StakingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class StakingCommit(ProtocolHandler protocol) : Proto19.StakingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 9a826476e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class TransactionsCommit(ProtocolHandler protocol) : Proto14.TransactionsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/TransferTicketCommit.cs deleted file mode 100644 index 5a2a991e7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/TransferTicketCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class TransferTicketCommit(ProtocolHandler protocol) : Proto13.TransferTicketCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index 9a8aea4f6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class UpdateSecondaryKeyCommit(ProtocolHandler protocol) : Proto15.UpdateSecondaryKeyCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 1f76b1474..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class VdfRevelationCommit(ProtocolHandler protocol) : Proto19.VdfRevelationCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SlashingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SlashingCommit.cs deleted file mode 100644 index 4355fb026..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SlashingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SlashingCommit(ProtocolHandler protocol) : Proto19.SlashingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 8111f0618..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SnapshotBalanceCommit(ProtocolHandler protocol) : Proto19.SnapshotBalanceCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SoftwareCommit.cs deleted file mode 100644 index a8a047dac..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SoftwareCommit(ProtocolHandler protocol) : Proto5.SoftwareCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StakerCycleCommit.cs deleted file mode 100644 index 4b28f44c7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StakerCycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class StakerCycleCommit(ProtocolHandler protocol) : Proto19.StakerCycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StakingUpdateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StakingUpdateCommit.cs deleted file mode 100644 index beba3163d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StakingUpdateCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class StakingUpdateCommit(ProtocolHandler protocol) : Proto18.StakingUpdateCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StateCommit.cs deleted file mode 100644 index 6b8d3d8fb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StateCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class StateCommit(ProtocolHandler protocol) : Proto1.StateCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StatisticsCommit.cs deleted file mode 100644 index a9b9ce535..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class StatisticsCommit(ProtocolHandler protocol) : Proto1.StatisticsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SubsidyCommit.cs deleted file mode 100644 index 3b1a86f17..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class SubsidyCommit(ProtocolHandler protocol) : Proto10.SubsidyCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/TicketsCommit.cs deleted file mode 100644 index d62959850..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/TicketsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class TicketsCommit(ProtocolHandler protocol) : Proto16.TicketsCommit(protocol) { } -} \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/TokensCommit.cs deleted file mode 100644 index 2890cd2a4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/TokensCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class TokensCommit(ProtocolHandler protocol) : Proto5.TokensCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/VotingCommit.cs deleted file mode 100644 index d44276bb7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Diagnostics/Diagnostics.cs deleted file mode 100644 index c08a98e75..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - class Diagnostics(ProtocolHandler handler) : Proto22.Diagnostics(handler) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Helpers.cs deleted file mode 100644 index d73309863..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto23 -{ - public class Helpers(ProtocolHandler proto) : Proto18.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Proto23Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Proto23Handler.cs deleted file mode 100644 index 36d29fb22..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Proto23Handler.cs +++ /dev/null @@ -1,530 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto23; - -namespace Tzkt.Sync.Protocols -{ - class Proto23Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "s023_023"; - public override int VersionNumber => 23; - - public Proto23Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SetDelegateParametersCommit(this).ActivateStakingParameters(blockCommit.Block); - await new UpdateSecondaryKeyCommit(this).ActivateSecondaryKeys(blockCommit.Block); - await new StakerCycleCommit(this).Apply(); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "attestation": - case "attestation_with_dal": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "attestations_aggregate": - var attestations = new AttestationAggregateCommit(this).ExtractAttestations(operation, content); - foreach (var (opHash, baker, slots) in attestations) - await new AttestationsCommit(this).Apply(blockCommit.Block, opHash, baker, slots); - break; - case "preattestation": - case "preattestation_with_dal": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preattestations_aggregate": - var preattestations = new PreattestationAggregateCommit(this).ExtractPreattestations(operation, content); - foreach (var (opHash, baker, slots) in preattestations) - new PreattestationsCommit(this).Apply(blockCommit.Block, opHash, baker, slots); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_entrapment_evidence": - await new DalEntrapmentEvidenceCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_consensus_operation_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - var ticketsCommit = new TicketsCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "increase_paid_storage": - await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "update_consensus_key": - case "update_companion_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "register_global_constant": - await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var dst = content.RequiredString("destination"); - if (dst.StartsWith("tz") && content.Optional("parameters")?.RequiredString("entrypoint") is string entrypoint) - { - if (Proto18.StakingCommit.ValidateParameters(entrypoint, content.RequiredString("source"), dst)) - { - await new StakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - else if (Proto18.SetDelegateParametersCommit.Entrypoint == entrypoint) - { - await new SetDelegateParametersCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - } - - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - if (parent.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, parent.Transaction, parent.TicketUpdates); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "transfer_ticket": - var parent1 = new TransferTicketCommit(this); - await parent1.Apply(blockCommit.Block, operation, content); - if (parent1.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, parent1.Operation, parent1.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult1)) - { - foreach (var internalContent in internalResult1.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent1.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); - } - } - } - break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_publish_commitment": - await new DalPublishCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await blockCommit.ApplyRewards(block); - - new InboxCommit(this).Apply(blockCommit.Block); - - await bigMapCommit.Apply(); - await ticketsCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new DalAttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SlashingCommit(this).Apply(block, rawBlock); - await new VotingCommit(this).Apply(block, rawBlock); - await new AutostakingCommit(this).Apply(block, rawBlock); - - Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - - await new DelegationSnapshotCommit(this).Apply(); - await new SnapshotBalanceCommit(this).Apply(); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(); - await new DelegationSnapshotCommit(this).Revert(); - await new AutostakingCommit(this).Revert(block); - await new VotingCommit(this).Revert(block); - await new SlashingCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new StatisticsCommit(this).Revert(currBlock); - - await new DalAttestationRewardCommit(this).Revert(currBlock); - await new AttestationRewardCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new TicketsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - await new BlockCommit(this).RevertRewards(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DalEntrapmentEvidenceOperation op: - new DalEntrapmentEvidenceCommit(this).Revert(op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case IncreasePaidStorageOperation op: - await new IncreasePaidStorageCommit(this).Revert(currBlock, op); - break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; - case RegisterConstantOperation op: - await new RegisterConstantsCommit(this).Revert(currBlock, op); - break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case StakingOperation op: - await new StakingCommit(this).Revert(currBlock, op); - break; - case SetDelegateParametersOperation op: - await new SetDelegateParametersCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - case TransferTicketOperation op: - await new TransferTicketCommit(this).Revert(currBlock, op); - break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - case DalPublishCommitmentOperation op: - await new DalPublishCommitmentCommit(this).Revert(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new StakerCycleCommit(this).Revert(); - await new UpdateSecondaryKeyCommit(this).DeactivateSecondaryKeys(currBlock); - await new SetDelegateParametersCommit(this).DeactivateStakingParameters(currBlock); - await new CycleCommit(this).Revert(currBlock); - new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Rpc/Rpc.cs deleted file mode 100644 index dc3ee6c53..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Rpc/Rpc.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto23 -{ - class Rpc(TezosNode node) : Proto22.Rpc(node) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto23/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto23/Validation/Validator.cs deleted file mode 100644 index 75966ade7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto23/Validation/Validator.cs +++ /dev/null @@ -1,1073 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto23 -{ - class Validator(ProtocolHandler protocol) : IValidator - { - readonly CacheService Cache = protocol.Cache; - Protocol Protocol = null!; - string Proposer = null!; - string Producer = null!; - int Level; - int Cycle; - - 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.RequiredString())) - 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 "attestations_aggregate": ValidateAttestationsAggregate(content); break; - case "preattestation": ValidatePreattestation(content); break; - case "preattestation_with_dal": ValidatePreattestation(content); break; - case "preattestations_aggregate": ValidatePreattestationsAggregate(content); break; - case "ballot": await ValidateBallot(content); break; - case "proposals": ValidateProposal(content); break; - case "activate_account": await ValidateActivation(content); break; - case "dal_entrapment_evidence": ValidateDalEntrapmentEvidence(content); break; - case "double_baking_evidence": ValidateDoubleBaking(content); break; - case "double_consensus_operation_evidence": ValidateDoubleConsensus(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 ValidateUpdateSecondaryKey(content); break; - case "update_companion_key": await ValidateUpdateSecondaryKey(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 ValidateAttestationsAggregate(JsonElement content) - { - if (content.Required("consensus_content").RequiredInt32("level") != Cache.AppState.GetLevel()) - throw new ValidationException("invalid attestations aggregate level"); - - var committee = content.RequiredArray("committee").EnumerateArray(); - if (!committee.Any()) - throw new ValidationException("invalid attestations aggregate committee size"); - - var metaCommittee = content.Required("metadata").RequiredArray("committee").EnumerateArray(); - if (committee.Count() != metaCommittee.Count()) - throw new ValidationException("invalid attestations aggregate committee metadata size"); - - foreach (var c in metaCommittee) - if (!Cache.Accounts.DelegateExists(c.RequiredString("delegate"))) - throw new ValidationException("unknown attestations aggregate 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 void ValidatePreattestationsAggregate(JsonElement content) - { - if (content.Required("consensus_content").RequiredInt32("level") != Cache.AppState.GetLevel() + 1) - throw new ValidationException("invalid preattestations aggregate level"); - - var committee = content.RequiredArray("committee").EnumerateArray(); - if (!committee.Any()) - throw new ValidationException("invalid preattestations aggregate committee size"); - - var metaCommittee = content.Required("metadata").RequiredArray("committee").EnumerateArray(); - if (committee.Count() != metaCommittee.Count()) - throw new ValidationException("invalid preattestations aggregate committee metadata size"); - - foreach (var c in metaCommittee) - if (!Cache.Accounts.DelegateExists(c.RequiredString("delegate"))) - throw new ValidationException("unknown preattestations aggregate 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 ValidateDalEntrapmentEvidence(JsonElement content) - { - } - - protected virtual void ValidateDoubleBaking(JsonElement content) - { - } - - protected virtual void ValidateDoubleConsensus(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() ?? [], - 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() ?? [], - 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() ?? [], - source, - content.RequiredInt64("fee")); - - var result = metadata.Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied) - { - var target = content.RequiredString("destination"); - - if (target.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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateUpdateSecondaryKey(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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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"); - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Activation/ProtoActivator.cs deleted file mode 100644 index 746480df8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Activation/ProtoActivator.cs +++ /dev/null @@ -1,271 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Npgsql; -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - partial class ProtoActivator(ProtocolHandler proto) : Proto23.ProtoActivator(proto) - { - protected override void ActivateFeatures() - { - Cache.AppState.Get().AiActivationLevel = 1; - } - - protected override void DeactivateFeatures() - { - Cache.AppState.Get().AiActivationLevel = null; - } - - protected override long GetBlockBonusPerBlock(JsonElement issuance, Protocol protocol) - => issuance.RequiredInt64("baking_reward_bonus_per_block"); - - protected override long GetAttestationRewardPerBlock(JsonElement issuance, Protocol protocol) - => issuance.RequiredInt64("attesting_reward_per_block"); - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - // mainnet - if (protocol.BlocksPerCycle == 10_800 && protocol.TimeBetweenBlocks == 8) - { - protocol.BlocksPerCycle = protocol.BlocksPerCycle * 4 / 3; - protocol.BlocksPerCommitment = protocol.BlocksPerCommitment * 4 / 3; - protocol.BlocksPerSnapshot = protocol.BlocksPerCycle; - protocol.BlocksPerVoting = protocol.BlocksPerVoting * 4 / 3; - protocol.TimeBetweenBlocks = protocol.TimeBetweenBlocks * 3 / 4; - protocol.HardBlockGasLimit = 1_040_000; - - protocol.SmartRollupCommitmentPeriod = 15 * 60 / protocol.TimeBetweenBlocks; - protocol.SmartRollupChallengeWindow = 14 * 24 * 60 * 60 / protocol.TimeBetweenBlocks; - protocol.SmartRollupTimeoutPeriod = 7 * 24 * 60 * 60 / protocol.TimeBetweenBlocks; - } - - // shadownet - if (Cache.AppState.Get().ChainId == "NetXsqzbfFenSTS") - { - protocol.BlocksPerVoting = protocol.BlocksPerCycle; - } - } - - protected override async Task MigrateContext(AppState state) - { - var prevProto = await Cache.Protocols.GetAsync(state.Protocol); - var nextProto = await Cache.Protocols.GetAsync(state.NextProtocol); - - await InitAddressRegistry(); - await RemoveDeadRefutationGames(state); - await MigrateSlashing(state, nextProto); - MigrateBakers(state, prevProto, nextProto); - await MigrateVotingPeriods(state, nextProto); - var cycles = await MigrateCycles(state, nextProto); - await MigrateFutureRights(state, nextProto, cycles); - - Cache.BakerCycles.Reset(); - Cache.BakingRights.Reset(); - } - - async Task InitAddressRegistry() - { - var nullAddress = await Cache.Accounts.GetAsync(NullAddress.Id); - Db.TryAttach(nullAddress); - nullAddress.Index = 0; - } - - async Task MigrateSlashing(AppState state, Protocol nextProto) - { - foreach (var op in await Db.DoubleBakingOps.Where(x => x.SlashedLevel > state.Level).ToListAsync()) - { - var proto = await Cache.Protocols.FindByLevelAsync(op.AccusedLevel); - op.SlashedLevel = nextProto.GetCycleEnd(proto.GetCycle(op.AccusedLevel) + proto.SlashingDelay); - } - - foreach (var op in await Db.DoubleConsensusOps.Where(x => x.SlashedLevel > state.Level).ToListAsync()) - { - var proto = await Cache.Protocols.FindByLevelAsync(op.AccusedLevel); - op.SlashedLevel = nextProto.GetCycleEnd(proto.GetCycle(op.AccusedLevel) + proto.SlashingDelay); - } - } - - void MigrateBakers(AppState state, Protocol prevProto, Protocol nextProto) - { - foreach (var baker in Cache.Accounts.GetDelegates().Where(x => x.DeactivationLevel > state.Level)) - { - Db.TryAttach(baker); - baker.DeactivationLevel = nextProto.GetCycleStart(prevProto.GetCycle(baker.DeactivationLevel)); - } - } - - async Task MigrateVotingPeriods(AppState state, Protocol nextProto) - { - var newPeriod = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(newPeriod); - newPeriod.LastLevel = newPeriod.FirstLevel + nextProto.BlocksPerVoting - 1; - } - - async Task> MigrateCycles(AppState state, Protocol nextProto) - { - var cycles = await Db.Cycles - .Where(x => x.Index >= state.Cycle) - .OrderBy(x => x.Index) - .ToListAsync(); - - var res = await Proto.Rpc.GetExpectedIssuance(state.Level); - - foreach (var cycle in cycles.Where(x => x.Index > state.Cycle)) - { - var issuance = res.EnumerateArray().First(x => x.RequiredInt32("cycle") == cycle.Index); - - cycle.BlockReward = issuance.RequiredInt64("baking_reward_fixed_portion"); - cycle.BlockBonusPerBlock = GetBlockBonusPerBlock(issuance, nextProto); - cycle.AttestationRewardPerBlock = GetAttestationRewardPerBlock(issuance, nextProto); - cycle.NonceRevelationReward = issuance.RequiredInt64("seed_nonce_revelation_tip"); - cycle.VdfRevelationReward = issuance.RequiredInt64("vdf_revelation_tip"); - cycle.DalAttestationRewardPerShard = issuance.RequiredInt64("dal_attesting_reward_per_shard"); - - cycle.FirstLevel = nextProto.GetCycleStart(cycle.Index); - cycle.LastLevel = nextProto.GetCycleEnd(cycle.Index); - } - - return cycles; - } - - async Task MigrateFutureRights(AppState state, Protocol nextProto, List cycles) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakingRights" - WHERE "Cycle" > {0} - """, state.Cycle); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - IEnumerable shifted = []; - - foreach (var cycle in cycles) - { - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - var sampler = GetSampler(bakerCycles.Values - .Where(x => x.BakingPower > 0) - .Select(x => (x.BakerId, x.BakingPower)) - .ToList()); - - #region temporary diagnostics - await sampler.Validate(Proto, state.Level, cycle.Index); - #endregion - - if (cycle.Index == state.Cycle) - { - shifted = RightsGenerator.GetAttestationRights(sampler, nextProto, cycle, cycle.LastLevel); - - #region save shifted - using var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """); - - foreach (var ar in shifted) - { - writer.StartRow(); - writer.Write(cycle.Index + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - writer.Complete(); - #endregion - } - else - { - GC.Collect(); - var brs = await RightsGenerator.GetBakingRightsAsync(sampler, nextProto, cycle); - var ars = await RightsGenerator.GetAttestationRightsAsync(sampler, nextProto, cycle); - - #region save rights - using (var writer = conn.BeginBinaryImport(""" - COPY "BakingRights" ("Cycle", "Level", "BakerId", "Type", "Status", "Round", "Slots") - FROM STDIN (FORMAT BINARY) - """)) - { - foreach (var ar in ars) - { - writer.StartRow(); - writer.Write(nextProto.GetCycle(ar.Level + 1), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Level + 1, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(ar.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.Slots, NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in brs) - { - writer.StartRow(); - writer.Write(cycle.Index, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Level, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Baker, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.Round, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - - #region reset baker cycles - var attestationRewardPerSlot = cycle.AttestationRewardPerBlock / nextProto.AttestersPerBlock; - var maxBlockReward = cycle.BlockReward + cycle.BlockBonusPerBlock; - - foreach (var bakerCycle in bakerCycles.Values) - { - Db.TryAttach(bakerCycle); - - bakerCycle.FutureBlocks = 0; - bakerCycle.FutureBlockRewards = 0; - bakerCycle.FutureAttestations = 0; - - var expectedAttestations = (nextProto.BlocksPerCycle * nextProto.AttestersPerBlock).MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - var expectedDalAttestations = (nextProto.BlocksPerCycle * nextProto.NumberOfShards).MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedBlocks = nextProto.BlocksPerCycle.MulRatio(bakerCycle.BakingPower, cycle.TotalBakingPower); - bakerCycle.ExpectedAttestations = expectedAttestations; - bakerCycle.FutureAttestationRewards = expectedAttestations * attestationRewardPerSlot; - bakerCycle.ExpectedDalAttestations = expectedDalAttestations; - bakerCycle.FutureDalAttestationRewards = expectedDalAttestations * cycle.DalAttestationRewardPerShard; - } - - foreach (var br in brs.Where(x => x.Round == 0)) - { - if (!bakerCycles.TryGetValue(br.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += maxBlockReward; - } - - foreach (var ar in shifted) - { - if (bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - { - bakerCycle.FutureAttestations += ar.Slots; - } - } - - foreach (var ar in ars.TakeWhile(x => x.Level < cycle.LastLevel)) - { - if (!bakerCycles.TryGetValue(ar.Baker, out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureAttestations += ar.Slots; - } - #endregion - - shifted = [..ars.Where(x => x.Level == cycle.LastLevel)]; - } - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/AttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/AttestationRewardCommit.cs deleted file mode 100644 index 2185fb20b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/AttestationRewardCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class AttestationRewardCommit(ProtocolHandler protocol) : Proto19.AttestationRewardCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/AutostakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/AutostakingCommit.cs deleted file mode 100644 index 9d52493d1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/AutostakingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class AutostakingCommit(ProtocolHandler protocol) : Proto19.AutostakingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BakerCycleCommit.cs deleted file mode 100644 index e906789af..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - class BakerCycleCommit(ProtocolHandler protocol) : Proto19.BakerCycleCommit(protocol) - { - public override async Task Apply(Block block, Cycle? futureCycle, IEnumerable? futureBakingRights, IEnumerable? futureAttestationRights, List? snapshots, Dictionary? selectedStakes, List currentRights) - { - if (Cache.AppState.Get().AbaActivationLevel == block.Level) - { - var state = Cache.AppState.Get(); - var cycles = await Db.Cycles.Where(x => x.Index >= block.Cycle).ToListAsync(); - foreach (var cycle in cycles) - { - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - foreach (var bakerCycle in bakerCycles.Values) - { - Db.TryAttach(bakerCycle); - bakerCycle.FutureAttestationRewards = GetFutureAttestationRewards(Context.Protocol, cycle, bakerCycle.BakingPower); - } - } - } - - await base.Apply(block, futureCycle, futureBakingRights, futureAttestationRights, snapshots, selectedStakes, currentRights); - } - - public override async Task Revert(Block block) - { - await base.Revert(block); - - if (Cache.AppState.Get().AbaActivationLevel == block.Level) - { - var state = Cache.AppState.Get(); - var cycles = await Db.Cycles.Where(x => x.Index >= block.Cycle).ToListAsync(); - foreach (var cycle in cycles) - { - var bakerCycles = await Cache.BakerCycles.GetAsync(cycle.Index); - foreach (var bakerCycle in bakerCycles.Values) - { - Db.TryAttach(bakerCycle); - bakerCycle.FutureAttestationRewards = base.GetFutureAttestationRewards(Context.Protocol, cycle, bakerCycle.BakingPower); - } - } - } - } - - protected override long GetFutureAttestationRewards(Protocol protocol, Cycle cycle, long bakingPower) - { - if (Cache.AppState.Get().AbaActivationLevel is not null) - return (protocol.BlocksPerCycle * cycle.AttestationRewardPerBlock).MulRatioUp(bakingPower, cycle.TotalBakingPower); - - return base.GetFutureAttestationRewards(protocol, cycle, bakingPower); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BakingRightsCommit.cs deleted file mode 100644 index 16be38c73..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class BakingRightsCommit(ProtocolHandler protocol) : Proto19.BakingRightsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BigMapCommit.cs index 68f3a1d35..e593e8f9e 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BigMapCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BigMapCommit.cs @@ -1,4 +1,538 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using Microsoft.EntityFrameworkCore; +using Netezos.Contracts; +using Netezos.Encoding; +using Npgsql; +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class BigMapCommit(ProtocolHandler protocol) : Proto1.BigMapCommit(protocol) { } + class BigMapCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public List<(BigMap, BigMapKey?, BigMapUpdate, ContractOperation)> Updates = []; + + readonly List<(ContractOperation op, Contract contract, BigMapDiff diff)> Diffs = []; + readonly Dictionary TempPtrs = new(7); + int TempPtr = 0; + + public virtual void Append(ContractOperation op, Contract contract, IEnumerable diffs) + { + foreach (var diff in diffs) + { + #region transform temp ptrs + if (diff.Ptr < 0) + { + if (diff.Action <= BigMapDiffAction.Copy) + { + TempPtrs[diff.Ptr] = --TempPtr; + diff.Ptr = TempPtr; + } + else + { + diff.Ptr = TempPtrs[diff.Ptr]; + } + } + if (diff is CopyDiff copy && copy.SourcePtr < 0) + { + copy.SourcePtr = TempPtrs[copy.SourcePtr]; + } + #endregion + Diffs.Add((op, contract, diff)); + } + } + + public virtual async Task Apply() + { + if (Diffs.Count == 0) return; + Context.Block.Events |= BlockEvents.Bigmaps; + + #region prefetch + var allocated = new HashSet(7); + var copiedFrom = new HashSet(7); + + foreach (var diff in Diffs.Where(x => x.diff.Ptr >= 0)) + { + if (diff.diff.Action == BigMapDiffAction.Alloc) + { + allocated.Add(diff.diff.Ptr); + } + else if (diff.diff is CopyDiff copy) + { + var origin = GetOrigin(copy); + if (origin < 0) + allocated.Add(diff.diff.Ptr); + else + copiedFrom.Add(origin); + } + } + + await Cache.BigMaps.Prefetch(Diffs + .Where(x => x.diff.Ptr >= 0 && !allocated.Contains(x.diff.Ptr)) + .Select(x => x.diff.Ptr)); + + await Cache.BigMapKeys.Prefetch(Diffs + .Where(x => x.diff.Ptr >= 0 && !allocated.Contains(x.diff.Ptr) && x.diff.Action == BigMapDiffAction.Update) + .Select(x => (x.diff.Ptr, (x.diff as UpdateDiff)!.KeyHash))); + + var copiedKeys = copiedFrom.Count == 0 ? [] : + await Db.BigMapKeys + .AsNoTracking() + .Where(x => copiedFrom.Contains(x.BigMapPtr)) + .ToListAsync(); + #endregion + + BigMapUpdate bigMapUpdate; + var bigMapUpdates = new List(Updates.Count); + var images = new Dictionary>(); + foreach (var diff in Diffs) + { + switch (diff.diff) + { + case AllocDiff alloc: + if (alloc.Ptr >= 0) + { + #region allocate new + var script = await Cache.Schemas.GetAsync(diff.contract); + var storage = await Cache.Storages.GetAsync(diff.contract); + var storageView = script.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); + var bigMapNode = storageView.Nodes() + .FirstOrDefault(x => x.Schema.Prim == PrimType.big_map && x.Value is MichelineInt v && v.Value == alloc.Ptr); + + if (bigMapNode == null) + { + storage = (Db.ChangeTracker.Entries() + .First(x => x.Entity is Storage s && (s.OriginationId == diff.op.Id || s.TransactionId == diff.op.Id)) + .Entity as Storage)!; + storageView = script.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); + bigMapNode = storageView.Nodes() + .FirstOrDefault(x => x.Schema.Prim == PrimType.big_map && x.Value is MichelineInt v && v.Value == alloc.Ptr) + ?? throw new Exception($"Allocated big_map {alloc.Ptr} missed in the storage"); + } + var bigMapSchema = (bigMapNode.Schema as BigMapSchema)!; + var allocatedBigMap = new BigMap + { + Id = Cache.AppState.NextBigMapId(), + Ptr = alloc.Ptr, + ContractId = diff.contract.Id, + StoragePath = bigMapNode.Path, + KeyType = bigMapSchema.Key.ToMicheline().ToBytes(), + ValueType = bigMapSchema.Value.ToMicheline().ToBytes(), + Active = true, + FirstLevel = diff.op.Level, + LastLevel = diff.op.Level, + ActiveKeys = 0, + TotalKeys = 0, + Updates = 1, + Tags = GetTags(diff.contract, bigMapNode) + }; + Db.BigMaps.Add(allocatedBigMap); + Cache.BigMaps.Add(allocatedBigMap); + + bigMapUpdate = new BigMapUpdate + { + Id = Cache.AppState.NextBigMapUpdateId(), + Action = BigMapAction.Allocate, + BigMapPtr = alloc.Ptr, + Level = diff.op.Level, + TransactionId = (diff.op as TransactionOperation)?.Id, + OriginationId = (diff.op as OriginationOperation)?.Id + }; + //Db.BigMapUpdates.Add(bigMapUpdate); + bigMapUpdates.Add(bigMapUpdate); + Updates.Add((allocatedBigMap, null, bigMapUpdate, diff.op)); + diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; + + images.Add(alloc.Ptr, []); + #endregion + } + else + { + #region alloc temp + images.Add(alloc.Ptr, []); + #endregion + } + break; + case CopyDiff copy: + if (copy.SourcePtr >= 0 && !copiedFrom.Contains(copy.SourcePtr)) + break; + if (!images.TryGetValue(copy.SourcePtr, out var src)) + { + src = copiedKeys + .Where(x => x.BigMapPtr == copy.SourcePtr) + .ToDictionary(x => x.KeyHash, x => (x.RawKey, x.RawValue)); + } + if (copy.Ptr >= 0) + { + #region copy to new + var script = await Cache.Schemas.GetAsync(diff.contract); + var storage = await Cache.Storages.GetAsync(diff.contract); + var storageView = script.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); + var bigMapNode = storageView.Nodes() + .FirstOrDefault(x => x.Schema.Prim == PrimType.big_map && x.Value is MichelineInt v && v.Value == copy.Ptr); + + if (bigMapNode == null) + { + storage = (Db.ChangeTracker.Entries() + .First(x => x.Entity is Storage s && (s.OriginationId == diff.op.Id || s.TransactionId == diff.op.Id)) + .Entity as Storage)!; + storageView = script.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); + bigMapNode = storageView.Nodes() + .FirstOrDefault(x => x.Schema.Prim == PrimType.big_map && x.Value is MichelineInt v && v.Value == copy.Ptr) + ?? throw new Exception($"Copied big_map {copy.Ptr} missed in the storage"); + } + + var bigMapSchema = (bigMapNode.Schema as BigMapSchema)!; + + var keys = src.Select(kv => + { + var rawKey = Micheline.FromBytes(kv.Value.RawKey); + var rawValue = Micheline.FromBytes(kv.Value.RawValue); + return new BigMapKey + { + Id = Cache.AppState.NextBigMapKeyId(), + BigMapPtr = copy.Ptr, + Active = true, + KeyHash = kv.Key, + JsonKey = bigMapSchema.Key.Humanize(rawKey), + JsonValue = bigMapSchema.Value.Humanize(rawValue), + RawKey = bigMapSchema.Key.Optimize(rawKey).ToBytes(), + RawValue = bigMapSchema.Value.Optimize(rawValue).ToBytes(), + FirstLevel = diff.op.Level, + LastLevel = diff.op.Level, + Updates = 1 + }; + }).ToList(); + + Db.BigMapKeys.AddRange(keys); + Cache.BigMapKeys.Add(keys); + + var copiedBigMap = new BigMap + { + Id = Cache.AppState.NextBigMapId(), + Ptr = copy.Ptr, + ContractId = diff.contract.Id, + StoragePath = bigMapNode.Path, + KeyType = bigMapSchema.Key.ToMicheline().ToBytes(), + ValueType = bigMapSchema.Value.ToMicheline().ToBytes(), + Active = true, + FirstLevel = diff.op.Level, + LastLevel = diff.op.Level, + ActiveKeys = keys.Count, + TotalKeys = keys.Count, + Updates = keys.Count + 1, + Tags = GetTags(diff.contract, bigMapNode) + }; + Db.BigMaps.Add(copiedBigMap); + Cache.BigMaps.Add(copiedBigMap); + + bigMapUpdate = new BigMapUpdate + { + Id = Cache.AppState.NextBigMapUpdateId(), + Action = BigMapAction.Allocate, + BigMapPtr = copy.Ptr, + Level = diff.op.Level, + TransactionId = (diff.op as TransactionOperation)?.Id, + OriginationId = (diff.op as OriginationOperation)?.Id + }; + //Db.BigMapUpdates.Add(bigMapUpdate); + bigMapUpdates.Add(bigMapUpdate); + Updates.Add((copiedBigMap, null, bigMapUpdate, diff.op)); + + foreach (var key in keys) + { + bigMapUpdate = new BigMapUpdate + { + Id = Cache.AppState.NextBigMapUpdateId(), + Action = BigMapAction.AddKey, + BigMapKeyId = key.Id, + BigMapPtr = key.BigMapPtr, + JsonValue = key.JsonValue, + RawValue = key.RawValue, + Level = key.FirstLevel, + TransactionId = (diff.op as TransactionOperation)?.Id, + OriginationId = (diff.op as OriginationOperation)?.Id + }; + //Db.BigMapUpdates.Add(bigMapUpdate); + bigMapUpdates.Add(bigMapUpdate); + Updates.Add((copiedBigMap, key, bigMapUpdate, diff.op)); + } + diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + keys.Count + 1; + + images.Add(copy.Ptr, keys.ToDictionary(x => x.KeyHash, x => (x.RawKey, x.RawValue))); + #endregion + } + else + { + #region copy to temp + images.Add(copy.Ptr, src.ToDictionary(x => x.Key, x => x.Value)); + #endregion + } + break; + case UpdateDiff update: + if (update.Ptr >= 0) + { + var bigMap = Cache.BigMaps.Get(update.Ptr); + + if (Cache.BigMapKeys.TryGet(update.Ptr, update.KeyHash, out var key)) + { + if (update.Value != null) + { + #region update key + Db.TryAttach(bigMap); + bigMap.LastLevel = diff.op.Level; + if (!key.Active) bigMap.ActiveKeys++; + bigMap.Updates++; + + Db.TryAttach(key); + key.Active = true; + key.JsonValue = bigMap.Schema.Value.Humanize(update.Value); + key.RawValue = bigMap.Schema.Value.Optimize(update.Value).ToBytes(); + key.LastLevel = diff.op.Level; + key.Updates++; + + bigMapUpdate = new BigMapUpdate + { + Id = Cache.AppState.NextBigMapUpdateId(), + Action = BigMapAction.UpdateKey, + BigMapKeyId = key.Id, + BigMapPtr = key.BigMapPtr, + JsonValue = key.JsonValue, + RawValue = key.RawValue, + Level = key.LastLevel, + TransactionId = (diff.op as TransactionOperation)?.Id, + OriginationId = (diff.op as OriginationOperation)?.Id + }; + //Db.BigMapUpdates.Add(bigMapUpdate); + bigMapUpdates.Add(bigMapUpdate); + Updates.Add((bigMap, key, bigMapUpdate, diff.op)); + diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; + #endregion + } + else if (key.Active) // WTF: edo2net:76611 - key was removed twice + { + #region remove key + Db.TryAttach(bigMap); + bigMap.LastLevel = diff.op.Level; + bigMap.ActiveKeys--; + bigMap.Updates++; + + Db.TryAttach(key); + key.Active = false; + key.LastLevel = diff.op.Level; + key.Updates++; + + bigMapUpdate = new BigMapUpdate + { + Id = Cache.AppState.NextBigMapUpdateId(), + Action = BigMapAction.RemoveKey, + BigMapKeyId = key.Id, + BigMapPtr = key.BigMapPtr, + JsonValue = key.JsonValue, + RawValue = key.RawValue, + Level = key.LastLevel, + TransactionId = (diff.op as TransactionOperation)?.Id, + OriginationId = (diff.op as OriginationOperation)?.Id + }; + //Db.BigMapUpdates.Add(bigMapUpdate); + bigMapUpdates.Add(bigMapUpdate); + Updates.Add((bigMap, key, bigMapUpdate, diff.op)); + diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; + #endregion + } + } + else if (update.Value != null) // WTF: edo2net:34839 - non-existent key was removed + { + #region add key + Db.TryAttach(bigMap); + bigMap.LastLevel = diff.op.Level; + bigMap.ActiveKeys++; + bigMap.TotalKeys++; + bigMap.Updates++; + + key = new BigMapKey + { + Id = Cache.AppState.NextBigMapKeyId(), + Active = true, + BigMapPtr = update.Ptr, + FirstLevel = diff.op.Level, + LastLevel = diff.op.Level, + JsonKey = bigMap.Schema.Key.Humanize(update.Key), + JsonValue = bigMap.Schema.Value.Humanize(update.Value), + RawKey = bigMap.Schema.Key.Optimize(update.Key).ToBytes(), + RawValue = bigMap.Schema.Value.Optimize(update.Value).ToBytes(), + KeyHash = update.KeyHash, + Updates = 1 + }; + + Db.BigMapKeys.Add(key); + Cache.BigMapKeys.Add(key); + + bigMapUpdate = new BigMapUpdate + { + Id = Cache.AppState.NextBigMapUpdateId(), + Action = BigMapAction.AddKey, + BigMapKeyId = key.Id, + BigMapPtr = key.BigMapPtr, + JsonValue = key.JsonValue, + RawValue = key.RawValue, + Level = key.LastLevel, + TransactionId = (diff.op as TransactionOperation)?.Id, + OriginationId = (diff.op as OriginationOperation)?.Id + }; + //Db.BigMapUpdates.Add(bigMapUpdate); + bigMapUpdates.Add(bigMapUpdate); + Updates.Add((bigMap, key, bigMapUpdate, diff.op)); + diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; + #endregion + } + } + else + { + #region update temp + if (!images.TryGetValue(update.Ptr, out var image)) + throw new Exception("Can't update non-existent temporary big_map"); + + if (image.TryGetValue(update.KeyHash, out var key)) + { + if (update.Value != null) + { + image[update.KeyHash] = (key.RawKey, update.Value.ToBytes()); + } + else + { + image.Remove(update.KeyHash); + } + } + else if (update.Value != null) // WTF: edo2net:34839 - non-existent key was removed + { + image.Add(update.KeyHash, (update.Key.ToBytes(), update.Value.ToBytes())); + } + #endregion + } + break; + case RemoveDiff remove: + if (remove.Ptr >= 0) + { + var removedBigMap = Cache.BigMaps.Get(remove.Ptr); + + Db.TryAttach(removedBigMap); + removedBigMap.Active = false; + removedBigMap.LastLevel = diff.op.Level; + removedBigMap.Updates++; + + bigMapUpdate = new BigMapUpdate + { + Id = Cache.AppState.NextBigMapUpdateId(), + Action = BigMapAction.Remove, + BigMapPtr = remove.Ptr, + Level = diff.op.Level, + TransactionId = (diff.op as TransactionOperation)?.Id, + OriginationId = (diff.op as OriginationOperation)?.Id + }; + //Db.BigMapUpdates.Add(bigMapUpdate); + bigMapUpdates.Add(bigMapUpdate); + Updates.Add((removedBigMap, null, bigMapUpdate, diff.op)); + diff.op.BigMapUpdates = (diff.op.BigMapUpdates ?? 0) + 1; + } + break; + default: + break; + } + } + if (bigMapUpdates.Count != 0) + BigMapUpdate.Write((Db.Database.GetDbConnection() as NpgsqlConnection)!, bigMapUpdates); + } + + int GetOrigin(CopyDiff copy) + { + return Diffs + .FirstOrDefault(x => x.diff.Action == BigMapDiffAction.Copy && x.diff.Ptr == copy.SourcePtr).diff is CopyDiff prevCopy + ? GetOrigin(prevCopy) + : copy.SourcePtr; + } + + protected virtual BigMapTag GetTags(Contract contract, TreeView node) => BigMaps.GetTags(contract, node); + + public virtual async Task Revert(Block block) + { + if (block.Events.HasFlag(BlockEvents.Bigmaps)) + { + var bigmaps = await Db.BigMaps.Where(x => x.LastLevel == block.Level).ToListAsync(); + var keys = await Db.BigMapKeys.Where(x => x.LastLevel == block.Level).ToListAsync(); + var updates = await Db.BigMapUpdates + .AsNoTracking() + .Where(x => x.Level == block.Level) + .Select(x => new + { + Ptr = x.BigMapPtr, + KeyId = x.BigMapKeyId + }) + .ToListAsync(); + + await Db.Database.ExecuteSqlRawAsync(""" + DELETE FROM "BigMapUpdates" + WHERE "Level" = {0} + """, block.Level); + Cache.AppState.ReleaseBigMapUpdateId(updates.Count); + + foreach (var key in keys) + { + var bigmap = bigmaps.First(x => x.Ptr == key.BigMapPtr); + Cache.BigMaps.Add(bigmap); + Cache.BigMapKeys.Add(key); + + if (key.FirstLevel == block.Level) + { + if (key.Active) bigmap.ActiveKeys--; + bigmap.TotalKeys--; + Db.BigMapKeys.Remove(key); + Cache.BigMapKeys.Remove(key); + Cache.AppState.ReleaseBigMapKeyId(); + } + else + { + var prevUpdate = await Db.BigMapUpdates + .Where(x => x.BigMapKeyId == key.Id) + .OrderByDescending(x => x.Id) + .FirstAsync(); + + var prevActive = prevUpdate.Action != BigMapAction.RemoveKey; + if (key.Active && !prevActive) + bigmap.ActiveKeys--; + else if (!key.Active && prevActive) + bigmap.ActiveKeys++; + + key.Active = prevActive; + key.JsonValue = prevUpdate.JsonValue!; + key.RawValue = prevUpdate.RawValue!; + key.LastLevel = prevUpdate.Level; + key.Updates -= updates.Count(x => x.KeyId == key.Id); + } + } + + foreach (var bigmap in bigmaps) + { + Cache.BigMaps.Add(bigmap); + if (bigmap.FirstLevel == block.Level) + { + Db.BigMaps.Remove(bigmap); + Cache.BigMaps.Remove(bigmap); + Cache.AppState.ReleaseBigMapId(); + } + else + { + bigmap.Active = true; + bigmap.Updates -= updates.Count(x => x.Ptr == bigmap.Ptr); + bigmap.LastLevel = bigmap.Updates > 1 + ? (await Db.BigMapUpdates + .Where(x => x.BigMapPtr == bigmap.Ptr) + .OrderByDescending(x => x.Id) + .FirstAsync()) + .Level + : bigmap.FirstLevel; + } + } + } + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BlockCommit.cs index 90acedf97..83e05523b 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BlockCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/BlockCommit.cs @@ -1,33 +1,118 @@ -using System.Text.Json; +using System.Collections; +using System.Text.Json; using Tzkt.Data.Models; namespace Tzkt.Sync.Protocols.Proto24 { - class BlockCommit(ProtocolHandler protocol) : Proto19.BlockCommit(protocol) + class BlockCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) { - public override async Task Apply(JsonElement rawBlock) + public Block Block { get; private set; } = null!; + + public virtual async Task Apply(JsonElement rawBlock) { - await base.Apply(rawBlock); + var hash = rawBlock.RequiredString("hash"); + var header = rawBlock.Required("header"); + var level = header.RequiredInt32("level"); + var timestamp = header.RequiredDateTime("timestamp"); + var metadata = rawBlock.Required("metadata"); + + var baker = await GetOrCreateBaker(metadata.OptionalString("baker"), level, timestamp); + var protocol = await Cache.Protocols.GetAsync(rawBlock.RequiredString("protocol")); + + Block = new Block + { + Id = Cache.AppState.NextOperationId(), + Hash = hash, + Level = level, + Cycle = 0, + ProtoCode = protocol.Code, + Timestamp = timestamp, + ProposerId = baker?.Id, + ProducerId = baker?.Id, + Operations = Context.MigrationOps.Count != 0 + ? Operations.Migrations + : Operations.None, + }; - var state = Cache.AppState.Get(); - if (state.AbaActivationLevel is null) + if (baker != null) { - var abaLevel = rawBlock.Required("metadata").Optional("all_bakers_attest_activation_level")?.RequiredInt32("level"); - if (abaLevel == Block.Level) - state.AbaActivationLevel = abaLevel; + Db.TryAttach(baker); + baker.BlocksCount++; } + + Context.Block = Block; + Context.Protocol = protocol; + + Cache.AppState.Get().BlocksCount++; + + Db.Blocks.Add(Block); + Cache.Blocks.Add(Block); } - public override void Revert (Block block) + public virtual void Revert(Block block) { - var state = Cache.AppState.Get(); - if (state.AbaActivationLevel == block.Level) - state.AbaActivationLevel = null; + var baker = Cache.Accounts.GetDelegate(block.ProposerId); - base.Revert(block); + if (baker != null) + { + Db.TryAttach(baker); + baker.BlocksCount--; + } + + Cache.AppState.Get().BlocksCount--; + + Db.Blocks.Remove(block); + Cache.Blocks.Remove(block); + Cache.AppState.ReleaseOperationId(); } - protected override long GetAttestationCommittee(Protocol protocol, JsonElement metadata) - => metadata.Optional("attestations")?.RequiredInt64("total_committee_power") ?? 0L; + public async Task GetOrCreateBaker(string? address, int level, DateTime timestamp) + { + if (address is not string _address) + return null; + + if (Cache.Accounts.DelegateExists(_address)) + return Cache.Accounts.GetExistingDelegate(_address); + + if (await Cache.Accounts.ExistsAsync(_address)) + throw new NotImplementedException(); + + var baker = new Data.Models.Delegate + { + Id = Cache.AppState.NextAccountId(), + Address = _address, + Type = AccountType.Delegate, + FirstLevel = level, + LastLevel = level, + Staked = true, + ActivationLevel = level, + DeactivationLevel = int.MaxValue, + }; + + Db.Accounts.Add(baker); + Cache.Accounts.Add(baker); + Cache.Statistics.Current.TotalBakers++; + + var migration = new MigrationOperation + { + Id = Cache.AppState.NextOperationId(), + Level = level, + Timestamp = timestamp, + AccountId = baker.Id, + Kind = MigrationKind.ActivateDelegate, + BalanceChange = baker.Balance, + }; + + baker.MigrationsCount++; + + Cache.AppState.Get().MigrationOpsCount++; + + Cache.Statistics.Current.TotalBootstrapped += migration.BalanceChange; + + Db.MigrationOps.Add(migration); + Context.MigrationOps.Add(migration); + + return baker; + } } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/ContractEventCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/ContractEventCommit.cs index 89cd357aa..d6b840c43 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/ContractEventCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/ContractEventCommit.cs @@ -1,4 +1,91 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Netezos.Contracts; +using Netezos.Encoding; +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class ContractEventCommit(ProtocolHandler protocol) : Proto14.ContractEventCommit(protocol) { } + class ContractEventCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public virtual async Task Apply(Block block, JsonElement content) + { + #region init + var contract = (await Cache.Accounts.GetExistingAsync(content.RequiredString("source")) as Contract)!; + var parentTx = Context.TransactionOps.OrderByDescending(x => x.Id).FirstOrDefault(x => x.TargetId == contract.Id) + ?? throw new Exception("Event parent transaction not found"); + + var result = content.Required("result"); + if (parentTx.Status != OperationStatus.Applied || result.RequiredString("status") != "applied") + return; + + var consumedGas = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000); + + var contractEvent = new ContractEvent + { + Id = Cache.AppState.NextEventId(), + Level = block.Level, + ContractId = contract.Id, + ContractCodeHash = contract.CodeHash, + TransactionId = parentTx.Id, + Tag = content.OptionalString("tag") + }; + + try + { + var type = (content.RequiredMicheline("type") as MichelinePrim)!; + var schema = Schema.Create(type); + contractEvent.Type = type.ToBytes(); + + var rawPayload = content.OptionalMicheline("payload") ?? new MichelinePrim { Prim = PrimType.Unit }; + + contractEvent.JsonPayload = schema.Humanize(rawPayload); + contractEvent.RawPayload = schema.Optimize(rawPayload).ToBytes(); + } + catch (Exception ex) + { + Logger.LogError(ex, "Failed to process event payload"); + } + #endregion + + #region apply + parentTx.GasUsed += consumedGas; + parentTx.EventsCount = (parentTx.EventsCount ?? 0) + 1; + contract.EventsCount++; + Cache.AppState.Get().EventsCount++; + block.Events |= BlockEvents.Events; + #endregion + + Db.Events.Add(contractEvent); + } + + public virtual async Task Revert(Block block) + { + if (!block.Events.HasFlag(BlockEvents.Events)) + return; + + var events = await Db.Events + .AsNoTracking() + .Where(x => x.Level == block.Level) + .ToListAsync(); + + foreach (var contractEvent in events) + { + var contract = (await Cache.Accounts.GetAsync(contractEvent.ContractId) as Contract)!; + Db.TryAttach(contract); + contract.EventsCount--; + + Cache.AppState.Get().EventsCount--; + } + + Cache.AppState.ReleaseEventId(events.Count); + + await Db.Database.ExecuteSqlRawAsync(""" + DELETE FROM "Events" + WHERE "Level" = {0} + """, block.Level); + + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/CycleCommit.cs deleted file mode 100644 index 713451a83..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/CycleCommit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - class CycleCommit(ProtocolHandler protocol) : Proto22.CycleCommit(protocol) - { - protected override long GetBlockBonusPerBlock(JsonElement issuance, Protocol protocol) - => issuance.RequiredInt64("baking_reward_bonus_per_block"); - - protected override long GetAttestationRewardPerBlock(JsonElement issuance, Protocol protocol) - => issuance.RequiredInt64("attesting_reward_per_block"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DalAttestationRewardCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DalAttestationRewardCommit.cs deleted file mode 100644 index a72bb0ad8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DalAttestationRewardCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DalAttestationRewardCommit(ProtocolHandler protocol) : Proto22.DalAttestationRewardCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DeactivationCommit.cs deleted file mode 100644 index 3174be075..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DeactivationCommit(ProtocolHandler protocol) : Proto2.DeactivationCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DelegationSnapshotCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DelegationSnapshotCommit.cs deleted file mode 100644 index e92eba5bd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DelegationSnapshotCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DelegationSnapshotCommit(ProtocolHandler protocol) : Proto19.DelegationSnapshotCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 10b5f8a89..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DelegatorCycleCommit(ProtocolHandler protocol) : Proto19.DelegatorCycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/InboxCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/InboxCommit.cs deleted file mode 100644 index 2123e264b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/InboxCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class InboxCommit(ProtocolHandler protocol) : Proto17.InboxCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 0da4e0d3f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class ActivationsCommit(ProtocolHandler protocol) : Proto1.ActivationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/AttestationAggregateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/AttestationAggregateCommit.cs deleted file mode 100644 index 48f3e6c1a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/AttestationAggregateCommit.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - class AttestationAggregateCommit(ProtocolHandler protocol) : Proto23.AttestationAggregateCommit(protocol) - { - protected override long GetPower(JsonElement c) - { - var consensusPower = c.Required("consensus_power"); - return consensusPower.OptionalInt64("baking_power") ?? consensusPower.RequiredInt64("slots"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 7f350ccea..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - class AttestationsCommit(ProtocolHandler protocol) : Proto19.AttestationsCommit(protocol) - { - protected override long GetPower(JsonElement metadata) - { - var consensusPower = metadata.Required("consensus_power"); - return consensusPower.OptionalInt64("baking_power") ?? consensusPower.RequiredInt64("slots"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index e56eab445..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class BallotsCommit(ProtocolHandler protocol) : Proto3.BallotsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DalEntrapmentEvidenceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DalEntrapmentEvidenceCommit.cs deleted file mode 100644 index 15a3a8d93..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DalEntrapmentEvidenceCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DalEntrapmentEvidenceCommit(ProtocolHandler protocol) : Proto23.DalEntrapmentEvidenceCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DalPublishCommitmentCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DalPublishCommitmentCommit.cs deleted file mode 100644 index 3ad09faaa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DalPublishCommitmentCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DalPublishCommitmentCommit(ProtocolHandler protocol) : Proto19.DalPublishCommitmentCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index b2c220969..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DelegationsCommit(ProtocolHandler protocol) : Proto18.DelegationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 43b9cc508..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DoubleBakingCommit(ProtocolHandler protocol) : Proto19.DoubleBakingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index b89eb9714..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DoubleConsensusCommit(ProtocolHandler protocol) : Proto23.DoubleConsensusCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DrainDelegateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DrainDelegateCommit.cs deleted file mode 100644 index 3ef3f255e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/DrainDelegateCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class DrainDelegateCommit(ProtocolHandler protocol) : Proto15.DrainDelegateCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/IncreasePaidStorageCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/IncreasePaidStorageCommit.cs index 3b28c72e6..2dcfd3a48 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/IncreasePaidStorageCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/IncreasePaidStorageCommit.cs @@ -1,4 +1,137 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Numerics; +using System.Text.Json; +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class IncreasePaidStorageCommit(ProtocolHandler protocol) : Proto14.IncreasePaidStorageCommit(protocol) { } + class IncreasePaidStorageCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public virtual async Task Apply(Block block, JsonElement op, JsonElement content) + { + #region init + var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); + var contract = await Cache.Accounts.GetOrCreateAsync(content.RequiredString("destination")); + + var metadata = content.Required("metadata"); + var result = metadata.Required("operation_result"); + + var refund = metadata + .OptionalArray("balance_updates")? + .EnumerateArray() + .FirstOrDefault(x => + x.RequiredString("kind") == "accumulator" && + x.RequiredString("category") == "block fees" && + x.RequiredInt64("change") < 0) + ?? default; + + var bakerFee = content.RequiredInt64("fee") + + (refund.ValueKind != JsonValueKind.Undefined ? refund.RequiredInt64("change") : 0); + + var balanceUpdate = result.OptionalArray("balance_updates")?.EnumerateArray() + .FirstOrDefault(x => x.RequiredString("kind") == "burned" && x.RequiredString("category") == "storage fees"); + + var storageFee = balanceUpdate is JsonElement el && el.ValueKind != JsonValueKind.Undefined + ? el.RequiredInt64("change") + : 0; + + var operation = new IncreasePaidStorageOperation + { + Id = Cache.AppState.NextOperationId(), + Level = block.Level, + Timestamp = block.Timestamp, + OpHash = op.RequiredString("hash"), + BakerFee = bakerFee, + Counter = content.RequiredInt32("counter"), + GasLimit = content.RequiredInt32("gas_limit"), + StorageLimit = content.RequiredInt32("storage_limit"), + SenderId = sender.Id, + ContractId = contract.Id, + Amount = BigInteger.Parse(content.RequiredString("amount")), + Status = result.RequiredString("status") switch + { + "applied" => OperationStatus.Applied, + "backtracked" => OperationStatus.Backtracked, + "failed" => OperationStatus.Failed, + "skipped" => OperationStatus.Skipped, + _ => throw new NotImplementedException() + }, + Errors = result.TryGetProperty("errors", out var errors) + ? OperationErrors.Parse(content, errors) + : null, + GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), + StorageUsed = (int)(storageFee / Context.Protocol.ByteCost), + StorageFee = storageFee + }; + #endregion + + #region entities + Db.TryAttach(sender); + Db.TryAttach(contract); + #endregion + + #region apply operation + PayFee(sender, operation.BakerFee); + + sender.IncreasePaidStorageCount++; + if (contract != sender) contract.IncreasePaidStorageCount++; + + block.Operations |= Operations.IncreasePaidStorage; + + sender.Counter = operation.Counter; + + Cache.AppState.Get().IncreasePaidStorageOpsCount++; + #endregion + + #region apply result + if (operation.Status == OperationStatus.Applied) + { + var burned = operation.StorageFee ?? 0; + Proto.Manager.Burn(burned); + + Spend(sender, burned); + + Cache.Statistics.Current.TotalBurned += burned; + } + #endregion + + Proto.Manager.Set(sender); + Db.IncreasePaidStorageOps.Add(operation); + Context.IncreasePaidStorageOps.Add(operation); + } + + public virtual async Task Revert(Block block, IncreasePaidStorageOperation operation) + { + #region entities + var sender = await Cache.Accounts.GetAsync(operation.SenderId); + var contract = await Cache.Accounts.GetAsync(operation.ContractId); + + Db.TryAttach(sender); + Db.TryAttach(contract); + #endregion + + #region revert result + if (operation.Status == OperationStatus.Applied) + { + RevertSpend(sender, operation.StorageFee ?? 0); + } + #endregion + + #region revert operation + RevertPayFee(sender, operation.BakerFee); + + sender.IncreasePaidStorageCount--; + if (contract != sender) contract.IncreasePaidStorageCount--; + + sender.Counter = operation.Counter - 1; + (sender as User)!.Revealed = true; + + Cache.AppState.Get().IncreasePaidStorageOpsCount--; + #endregion + + Db.IncreasePaidStorageOps.Remove(operation); + Cache.AppState.ReleaseManagerCounter(); + Cache.AppState.ReleaseOperationId(); + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 633011e78..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class NonceRevelationsCommit(ProtocolHandler protocol) : Proto19.NonceRevelationsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/OriginationsCommit.cs index f803c1d4d..491bea768 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/OriginationsCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/OriginationsCommit.cs @@ -1,4 +1,706 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Netezos.Contracts; +using Netezos.Encoding; + +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class OriginationsCommit(ProtocolHandler protocol) : Proto14.OriginationsCommit(protocol) { } + class OriginationsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public OriginationOperation Origination { get; private set; } = null!; + public IEnumerable? BigMapDiffs { get; private set; } + public Contract? Contract { get; private set; } + + public virtual async Task Apply(Block block, JsonElement op, JsonElement content) + { + #region init + var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); + var contractDelegate = content.OptionalString("delegate") is string _delegateAddress + ? await Cache.Accounts.GetOrCreateAsync(_delegateAddress) + : null; + + var metadata = content.Required("metadata"); + var result = metadata.Required("operation_result"); + + var refund = metadata + .OptionalArray("balance_updates")? + .EnumerateArray() + .FirstOrDefault(x => + x.RequiredString("kind") == "accumulator" && + x.RequiredString("category") == "block fees" && + x.RequiredInt64("change") < 0) + ?? default; + + var bakerFee = content.RequiredInt64("fee") + + (refund.ValueKind != JsonValueKind.Undefined ? refund.RequiredInt64("change") : 0); + + var origination = new OriginationOperation + { + Id = Cache.AppState.NextOperationId(), + Level = block.Level, + Timestamp = block.Timestamp, + OpHash = op.RequiredString("hash"), + Balance = content.RequiredInt64("balance"), + BakerFee = bakerFee, + Counter = content.RequiredInt32("counter"), + GasLimit = content.RequiredInt32("gas_limit"), + StorageLimit = content.RequiredInt32("storage_limit"), + SenderId = sender.Id, + DelegateId = contractDelegate?.Id, + Status = result.RequiredString("status") switch + { + "applied" => OperationStatus.Applied, + "backtracked" => OperationStatus.Backtracked, + "failed" => OperationStatus.Failed, + "skipped" => OperationStatus.Skipped, + _ => throw new NotImplementedException() + }, + Errors = result.TryGetProperty("errors", out var errors) + ? OperationErrors.Parse(content, errors) + : null, + GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), + StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, + StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 + ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost + : null, + AllocationFee = Context.Protocol.OriginationSize * Context.Protocol.ByteCost + }; + #endregion + + #region apply operation + Db.TryAttach(sender); + PayFee(sender, origination.BakerFee); + sender.LastLevel = origination.Level; + sender.Counter = origination.Counter; + sender.OriginationsCount++; + + if (contractDelegate != null) + { + Db.TryAttach(contractDelegate); + contractDelegate.LastLevel = block.Level; + if (contractDelegate != sender) + contractDelegate.OriginationsCount++; + } + + Context.Block.Operations |= Operations.Originations; + + Cache.AppState.Get().OriginationOpsCount++; + #endregion + + #region apply result + if (origination.Status == OperationStatus.Applied) + { + var burned = (origination.StorageFee ?? 0) + (origination.AllocationFee ?? 0); + Proto.Manager.Burn(burned); + + Spend(sender, origination.Balance + burned); + sender.ContractsCount++; + + Contract? contract; + var contractAddress = result.RequiredArray("originated_contracts", 1)[0].RequiredString(); + var ghost = await Cache.Accounts.GetAsync(contractAddress); + if (ghost != null) + { + contract = new Contract + { + Id = ghost.Id, + Index = ghost.Index, + FirstLevel = ghost.FirstLevel, + LastLevel = origination.Level, + Address = contractAddress, + CreatorId = sender.Id, + Type = AccountType.Contract, + Kind = ContractKind.SmartContract, + OriginationsCount = 1, + ActiveTokensCount = ghost.ActiveTokensCount, + TokenBalancesCount = ghost.TokenBalancesCount, + TokenTransfersCount = ghost.TokenTransfersCount, + ActiveTicketsCount = ghost.ActiveTicketsCount, + TicketBalancesCount = ghost.TicketBalancesCount, + TicketTransfersCount = ghost.TicketTransfersCount + }; + var isAdded = Db.Entry(ghost).State == EntityState.Added; + Db.Entry(ghost).State = EntityState.Detached; + Db.Entry(contract).State = isAdded ? EntityState.Added : EntityState.Modified; + } + else + { + contract = new Contract + { + Id = Cache.AppState.NextAccountId(), + FirstLevel = origination.Level, + LastLevel = origination.Level, + Address = contractAddress, + CreatorId = sender.Id, + Type = AccountType.Contract, + Kind = ContractKind.SmartContract, + OriginationsCount = 1 + }; + Db.Contracts.Add(contract); + } + Receive(contract, origination.Balance); + Cache.Accounts.Add(contract); + origination.ContractId = contract.Id; + Contract = contract; + + var code = await ExpandCode(contract, Micheline.FromJson(content.Required("script").Required("code"))!); + var storage = Micheline.FromJson(content.Required("script").Required("storage"))!; + + BigMapDiffs = ParseBigMapDiffs(origination, result, code, storage); + await ProcessScript(origination, contract, code, storage); + + Cache.Statistics.Current.TotalBurned += burned; + } + #endregion + + Proto.Manager.Set(sender); + Db.OriginationOps.Add(origination); + Context.OriginationOps.Add(origination); + Origination = origination; + } + + public virtual async Task ApplyInternal(Block block, ManagerOperation parent, JsonElement content) + { + #region init + var initiator = await Cache.Accounts.GetAsync(parent.SenderId); + var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); + var contractDelegate = content.OptionalString("delegate") is string _delegateAddress + ? await Cache.Accounts.GetOrCreateAsync(_delegateAddress) + : null; + + var result = content.Required("result"); + + var origination = new OriginationOperation + { + Id = Cache.AppState.NextOperationId(), + InitiatorId = parent.SenderId, + Level = parent.Level, + Timestamp = parent.Timestamp, + OpHash = parent.OpHash, + Counter = parent.Counter, + Nonce = content.RequiredInt32("nonce"), + Balance = content.RequiredInt64("balance"), + SenderId = sender.Id, + SenderCodeHash = (sender as Contract)?.CodeHash, + DelegateId = contractDelegate?.Id, + Status = result.RequiredString("status") switch + { + "applied" => OperationStatus.Applied, + "backtracked" => OperationStatus.Backtracked, + "failed" => OperationStatus.Failed, + "skipped" => OperationStatus.Skipped, + _ => throw new NotImplementedException() + }, + Errors = result.TryGetProperty("errors", out var errors) + ? OperationErrors.Parse(content, errors) + : null, + GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), + StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, + StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 + ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost + : null, + AllocationFee = Context.Protocol.OriginationSize * Context.Protocol.ByteCost + }; + #endregion + + #region apply operation + if (parent is TransactionOperation parentTx) + { + parentTx.InternalOperations = (short?)((parentTx.InternalOperations ?? 0) + 1); + parentTx.InternalOriginations = (short?)((parentTx.InternalOriginations ?? 0) + 1); + } + + Db.TryAttach(sender); + sender.LastLevel = block.Level; + sender.OriginationsCount++; + + if (contractDelegate != null) + { + Db.TryAttach(contractDelegate); + contractDelegate.LastLevel = block.Level; + if (contractDelegate != sender) + contractDelegate.OriginationsCount++; + } + + if (initiator != sender && initiator != contractDelegate) + { + initiator.OriginationsCount++; + } + + block.Operations |= Operations.Originations; + + Cache.AppState.Get().OriginationOpsCount++; + #endregion + + #region apply result + if (origination.Status == OperationStatus.Applied) + { + var burned = (origination.StorageFee ?? 0) + (origination.AllocationFee ?? 0); + Proto.Manager.Burn(burned); + + Spend(initiator, burned); + + Spend(sender, origination.Balance); + sender.ContractsCount++; + + Contract? contract; + var contractAddress = result.RequiredArray("originated_contracts", 1)[0].RequiredString(); + var ghost = await Cache.Accounts.GetAsync(contractAddress); + if (ghost != null) + { + contract = new Contract + { + Id = ghost.Id, + Index = ghost.Index, + FirstLevel = ghost.FirstLevel, + LastLevel = origination.Level, + Address = contractAddress, + Counter = 0, + CreatorId = sender.Id, + Type = AccountType.Contract, + Kind = ContractKind.SmartContract, + OriginationsCount = 1, + ActiveTokensCount = ghost.ActiveTokensCount, + TokenBalancesCount = ghost.TokenBalancesCount, + TokenTransfersCount = ghost.TokenTransfersCount, + ActiveTicketsCount = ghost.ActiveTicketsCount, + TicketBalancesCount = ghost.TicketBalancesCount, + TicketTransfersCount = ghost.TicketTransfersCount + }; + var isAdded = Db.Entry(ghost).State == EntityState.Added; + Db.Entry(ghost).State = EntityState.Detached; + Db.Entry(contract).State = isAdded ? EntityState.Added : EntityState.Modified; + } + else + { + contract = new Contract + { + Id = Cache.AppState.NextAccountId(), + FirstLevel = origination.Level, + LastLevel = origination.Level, + Address = contractAddress, + Counter = 0, + CreatorId = sender.Id, + Type = AccountType.Contract, + Kind = ContractKind.SmartContract, + OriginationsCount = 1 + }; + Db.Contracts.Add(contract); + } + Receive(contract, origination.Balance); + Cache.Accounts.Add(contract); + origination.ContractId = contract.Id; + Contract = contract; + + var code = await ExpandCode(contract, Micheline.FromJson(content.Required("script").Required("code"))!); + var storage = Micheline.FromJson(content.Required("script").Required("storage"))!; + + BigMapDiffs = ParseBigMapDiffs(origination, result, code, storage); + await ProcessScript(origination, contract, code, storage); + + Cache.Statistics.Current.TotalBurned += burned; + } + #endregion + + Db.OriginationOps.Add(origination); + Context.OriginationOps.Add(origination); + Origination = origination; + } + + public virtual async Task Revert(Block block, OriginationOperation origination) + { + #region init + var sender = await Cache.Accounts.GetAsync(origination.SenderId); + var contractDelegate = origination.DelegateId is int delegateId + ? await Cache.Accounts.GetAsync(delegateId) + : null; + var contract = origination.ContractId is int contractId + ? await Cache.Accounts.GetAsync(contractId) as Contract + : null; + + Db.TryAttach(sender); + Db.TryAttach(contractDelegate); + Db.TryAttach(contract); + #endregion + + #region revert result + if (origination.Status == OperationStatus.Applied) + { + await RevertScript(origination, contract!); + + contract!.OriginationsCount--; + if (contract.TransactionsCount == 0 && + contract.TransferTicketCount == 0 && + contract.IncreasePaidStorageCount == 0 && + contract.TokenTransfersCount == 0 && + contract.TicketTransfersCount == 0 && + contract.Index is null) + { + Db.Accounts.Remove(contract); + Cache.Accounts.Remove(contract); + } + else + { + var ghost = new Account + { + Id = contract.Id, + Index = contract.Index, + Address = contract.Address, + FirstLevel = contract.FirstLevel, + LastLevel = origination.Level, + Type = AccountType.Ghost, + TransactionsCount = contract.TransactionsCount, + TransferTicketCount = contract.TransferTicketCount, + IncreasePaidStorageCount = contract.IncreasePaidStorageCount, + ActiveTokensCount = contract.ActiveTokensCount, + TokenBalancesCount = contract.TokenBalancesCount, + TokenTransfersCount = contract.TokenTransfersCount, + ActiveTicketsCount = contract.ActiveTicketsCount, + TicketBalancesCount = contract.TicketBalancesCount, + TicketTransfersCount = contract.TicketTransfersCount, + }; + + Db.Entry(contract).State = EntityState.Detached; + Db.Entry(ghost).State = EntityState.Modified; + Cache.Accounts.Add(ghost); + } + + var spent = origination.Balance + (origination.StorageFee ?? 0) + (origination.AllocationFee ?? 0); + + RevertSpend(sender, spent); + sender.ContractsCount--; + } + #endregion + + #region revert operation + RevertPayFee(sender, origination.BakerFee); + sender.LastLevel = block.Level; + sender.Counter = origination.Counter - 1; + if (sender is User user) user.Revealed = true; + sender.OriginationsCount--; + + if (contractDelegate != null) + { + contractDelegate.LastLevel = block.Level; + if (contractDelegate != sender) + contractDelegate.OriginationsCount--; + } + + Cache.AppState.Get().OriginationOpsCount--; + #endregion + + Db.OriginationOps.Remove(origination); + Cache.AppState.ReleaseManagerCounter(); + Cache.AppState.ReleaseOperationId(); + } + + public virtual async Task RevertInternal(Block block, OriginationOperation origination) + { + #region init + var initiator = await Cache.Accounts.GetAsync(origination.InitiatorId!.Value); + var sender = await Cache.Accounts.GetAsync(origination.SenderId); + var contractDelegate = origination.DelegateId is int delegateId + ? await Cache.Accounts.GetAsync(delegateId) + : null; + var contract = origination.ContractId is int contractId + ? await Cache.Accounts.GetAsync(contractId) as Contract + : null; + + Db.TryAttach(initiator); + Db.TryAttach(sender); + Db.TryAttach(contractDelegate); + Db.TryAttach(contract); + #endregion + + #region revert result + if (origination.Status == OperationStatus.Applied) + { + await RevertScript(origination, contract!); + + contract!.OriginationsCount--; + if (contract.TransactionsCount == 0 && + contract.TransferTicketCount == 0 && + contract.IncreasePaidStorageCount == 0 && + contract.TokenTransfersCount == 0 && + contract.TicketTransfersCount == 0 && + contract.Index is null) + { + Db.Accounts.Remove(contract); + Cache.Accounts.Remove(contract); + } + else + { + var ghost = new Account + { + Id = contract.Id, + Index = contract.Index, + Address = contract.Address, + FirstLevel = contract.FirstLevel, + LastLevel = origination.Level, + Type = AccountType.Ghost, + TransactionsCount = contract.TransactionsCount, + TransferTicketCount = contract.TransferTicketCount, + IncreasePaidStorageCount = contract.IncreasePaidStorageCount, + ActiveTokensCount = contract.ActiveTokensCount, + TokenBalancesCount = contract.TokenBalancesCount, + TokenTransfersCount = contract.TokenTransfersCount, + ActiveTicketsCount = contract.ActiveTicketsCount, + TicketBalancesCount = contract.TicketBalancesCount, + TicketTransfersCount = contract.TicketTransfersCount, + }; + + Db.Entry(contract).State = EntityState.Detached; + Db.Entry(ghost).State = EntityState.Modified; + Cache.Accounts.Add(ghost); + } + + var spent = (origination.StorageFee ?? 0) + (origination.AllocationFee ?? 0); + RevertSpend(initiator, spent); + + RevertSpend(sender, origination.Balance); + sender.ContractsCount--; + } + #endregion + + #region revert operation + sender.LastLevel = block.Level; + sender.OriginationsCount--; + + if (contractDelegate != null) + { + contractDelegate.LastLevel = block.Level; + if (contractDelegate != sender) + contractDelegate.OriginationsCount--; + } + + if (initiator != sender && initiator != contractDelegate) + { + initiator.OriginationsCount--; + } + + Cache.AppState.Get().OriginationOpsCount--; + #endregion + + Db.OriginationOps.Remove(origination); + Cache.AppState.ReleaseOperationId(); + } + + protected async Task ExpandCode(Contract contract, IMicheline code) + { + if (code is not MichelineArray array) + { + var constants = await Constants.Find(Db, [code]); + if (constants.Count > 0) + { + contract.Tags |= ContractTags.Constants; + foreach (var constant in constants) + { + Db.TryAttach(constant); + constant.Refs++; + } + var dict = constants.ToDictionary(x => x.Address!, x => Micheline.FromBytes(x.Value!)); + array = Constants.Expand(code, dict) as MichelineArray + ?? throw new Exception("Contract code should be an array or constant"); + } + else + { + throw new Exception("Contract code should be an array or constant"); + } + } + return array; + } + + protected async Task ProcessScript(OriginationOperation origination, Contract contract, MichelineArray code, IMicheline storageValue) + { + #region expand top-level constants + var constants = await Constants.Find(Db, code); + if (constants.Count > 0) + { + var depth = 0; + while (code.Any(x => x is MichelinePrim prim && prim.Prim == PrimType.constant) && depth++ <= 10_000) + { + for (int i = 0; i < code.Count; i++) + { + if (code[i] is MichelinePrim prim && prim.Prim == PrimType.constant) + { + code[i] = Micheline.FromBytes(constants.First(x => x.Address == (prim.Args![0] as MichelineString)!.Value).Value!); + } + } + } + } + #endregion + + var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter); + var micheStorage = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage); + var micheCode = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code); + var micheViews = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view); + + #region process constants + if (constants.Count > 0) + { + contract.Tags |= ContractTags.Constants; + foreach (var constant in constants) + { + Db.TryAttach(constant); + constant.Refs++; + } + var dict = constants.ToDictionary(x => x.Address!, x => Micheline.FromBytes(x.Value!)); + micheParameter = Constants.Expand(micheParameter, dict); + micheStorage = Constants.Expand(micheStorage, dict); + foreach (var view in micheViews.Select(x => (x as MichelinePrim)!)) + { + view.Args![1] = Constants.Expand(view.Args[1], dict); + view.Args[2] = Constants.Expand(view.Args[2], dict); + } + } + #endregion + + var script = new Script + { + Id = Cache.AppState.NextScriptId(), + Level = origination.Level, + ContractId = contract.Id, + OriginationId = origination.Id, + ParameterSchema = micheParameter.ToBytes(), + StorageSchema = micheStorage.ToBytes(), + CodeSchema = micheCode.ToBytes(), + Views = micheViews.Any() + ? [.. micheViews.Select(x => x.ToBytes())] + : null, + Current = true + }; + + var viewsBytes = script.Views? + .OrderBy(x => x, new BytesComparer()) + .SelectMany(x => x) + .ToArray() + ?? []; + var typeSchema = script.ParameterSchema.Concat(script.StorageSchema).Concat(viewsBytes); + var fullSchema = typeSchema.Concat(script.CodeSchema); + contract.TypeHash = script.TypeHash = Script.GetHash(typeSchema); + origination.ContractCodeHash = contract.CodeHash = script.CodeHash = Script.GetHash(fullSchema); + + if ((storageValue.Type == MichelineType.String || storageValue.Type == MichelineType.Bytes) && + code.ToBytes().IsEqual(Script.ManagerTzBytes)) + { + contract.Kind = ContractKind.DelegatorContract; + } + else + { + if (script.Schema.IsFA1()) + { + if (script.Schema.IsFA12()) + contract.Tags |= ContractTags.FA12; + + contract.Tags |= ContractTags.FA1; + contract.Kind = ContractKind.Asset; + } + if (script.Schema.IsFA2()) + { + contract.Tags |= ContractTags.FA2; + contract.Kind = ContractKind.Asset; + } + } + + if (BigMapDiffs != null) + { + var ind = 0; + var ptrs = BigMapDiffs.Where(x => x.Action <= BigMapDiffAction.Copy && x.Ptr >= 0).Select(x => x.Ptr).ToList(); + var view = script.Schema.Storage.Schema.ToTreeView(storageValue); + + foreach (var bigmap in view.Nodes().Where(x => x.Schema.Prim == PrimType.big_map)) + storageValue = storageValue.Replace(bigmap.Value, new MichelineInt(ptrs[^++ind])); + } + + var storage = new Storage + { + Id = Cache.AppState.NextStorageId(), + Level = origination.Level, + ContractId = contract.Id, + OriginationId = origination.Id, + RawValue = script.Schema.OptimizeStorage(storageValue, false).ToBytes(), + JsonValue = script.Schema.HumanizeStorage(storageValue), + Current = true + }; + + Db.Scripts.Add(script); + Cache.Schemas.Add(contract, script.Schema); + + Db.Storages.Add(storage); + Cache.Storages.Add(contract, storage); + + origination.ScriptId = script.Id; + origination.StorageId = storage.Id; + } + + protected async Task RevertScript(OriginationOperation origination, Contract contract) + { + #region process constants + if (contract.Tags.HasFlag(ContractTags.Constants)) + { + var script = await Db.Scripts + .AsNoTracking() + .Where(x => x.ContractId == contract.Id && x.Current) + .Select(x => new { x.ParameterSchema, x.StorageSchema, x.CodeSchema, x.Views }) + .FirstAsync(); + + var code = new MichelineArray + { + Micheline.FromBytes(script.ParameterSchema), + Micheline.FromBytes(script.StorageSchema), + Micheline.FromBytes(script.CodeSchema) + }; + if (script.Views != null) + foreach (var bytes in script.Views) + code.Add(Micheline.FromBytes(bytes)); + + // TODO: we're actually missing constants in parameter and storage, + // as they were expanded, so refs may be reverted inaccurately. + var constants = await Constants.Find(Db, code); + foreach (var constant in constants) + { + Db.TryAttach(constant); + constant.Refs--; + } + } + #endregion + + Db.Scripts.Remove(new Script + { + Id = origination.ScriptId!.Value, + ParameterSchema = [], + StorageSchema = [], + CodeSchema = [], + Level = 0, + ContractId = 0, + }); + Cache.Schemas.Remove(contract); + Cache.AppState.ReleaseScriptId(); + + if (!Cache.Storages.TryGetCached(contract, out var storage)) + { + storage = new Storage + { + Id = origination.StorageId!.Value, + RawValue = [], + JsonValue = string.Empty, + Level = 0, + ContractId = 0, + }; + } + Db.Storages.Remove(storage); + Cache.Storages.Remove(contract); + Cache.AppState.ReleaseStorageId(); + } + + protected virtual IEnumerable? ParseBigMapDiffs(OriginationOperation origination, JsonElement result, MichelineArray code, IMicheline storage) + { + return result.TryGetProperty("lazy_storage_diff", out var diffs) + ? BigMapDiff.ParseLazyStorage(diffs) + : null; + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/PreattestationAggregateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/PreattestationAggregateCommit.cs deleted file mode 100644 index a905111c0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/PreattestationAggregateCommit.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - class PreattestationAggregateCommit(ProtocolHandler protocol) : Proto23.PreattestationAggregateCommit(protocol) - { - protected override long GetPower(JsonElement c) - { - var consensusPower = c.Required("consensus_power"); - return consensusPower.OptionalInt64("baking_power") ?? consensusPower.RequiredInt64("slots"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/PreattestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/PreattestationsCommit.cs deleted file mode 100644 index a36dc5782..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/PreattestationsCommit.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - class PreattestationsCommit(ProtocolHandler protocol) : Proto19.PreattestationsCommit(protocol) - { - protected override long GetPower(JsonElement metadata) - { - var consensusPower = metadata.Required("consensus_power"); - return consensusPower.OptionalInt64("baking_power") ?? consensusPower.RequiredInt64("slots"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 1ef6e97eb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class ProposalsCommit(ProtocolHandler protocol) : Proto14.ProposalsCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/RegisterConstantsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/RegisterConstantsCommit.cs index 0f9822ec9..ea7ca8acc 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/RegisterConstantsCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/RegisterConstantsCommit.cs @@ -1,4 +1,125 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Text.Json; +using Netezos.Encoding; +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class RegisterConstantsCommit(ProtocolHandler protocol) : Proto14.RegisterConstantsCommit(protocol) { } + class RegisterConstantsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public virtual async Task Apply(Block block, JsonElement op, JsonElement content) + { + #region init + var sender = (User)await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); + + var metadata = content.Required("metadata"); + var result = metadata.Required("operation_result"); + + var refund = metadata + .OptionalArray("balance_updates")? + .EnumerateArray() + .FirstOrDefault(x => + x.RequiredString("kind") == "accumulator" && + x.RequiredString("category") == "block fees" && + x.RequiredInt64("change") < 0) + ?? default; + + var bakerFee = content.RequiredInt64("fee") + + (refund.ValueKind != JsonValueKind.Undefined ? refund.RequiredInt64("change") : 0); + + var registerConstant = new RegisterConstantOperation + { + Id = Cache.AppState.NextOperationId(), + OpHash = op.RequiredString("hash"), + Level = block.Level, + Timestamp = block.Timestamp, + BakerFee = bakerFee, + Counter = content.RequiredInt32("counter"), + GasLimit = content.RequiredInt32("gas_limit"), + StorageLimit = content.RequiredInt32("storage_limit"), + SenderId = sender.Id, + Status = result.RequiredString("status") switch + { + "applied" => OperationStatus.Applied, + "backtracked" => OperationStatus.Backtracked, + "failed" => OperationStatus.Failed, + "skipped" => OperationStatus.Skipped, + _ => throw new NotImplementedException() + }, + Errors = result.TryGetProperty("errors", out var errors) + ? OperationErrors.Parse(content, errors) + : null, + GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), + StorageUsed = result.OptionalInt32("storage_size") ?? 0, + StorageFee = result.OptionalInt32("storage_size") > 0 + ? result.OptionalInt32("storage_size") * Context.Protocol.ByteCost + : null, + }; + #endregion + + #region apply operation + Db.TryAttach(sender); + PayFee(sender, registerConstant.BakerFee); + sender.Counter = registerConstant.Counter; + sender.RegisterConstantsCount++; + + block.Operations |= Operations.RegisterConstant; + + Cache.AppState.Get().RegisterConstantOpsCount++; + #endregion + + #region apply result + if (registerConstant.Status == OperationStatus.Applied) + { + var burned = registerConstant.StorageFee ?? 0; + Proto.Manager.Burn(burned); + + Spend(sender, burned); + + registerConstant.Address = result.RequiredString("global_address"); + registerConstant.Value = content.RequiredMicheline("value").ToBytes(); + registerConstant.Refs = 0; + + Cache.AppState.Get().ConstantsCount++; + + Cache.Statistics.Current.TotalBurned += burned; + } + #endregion + + Proto.Manager.Set(sender); + Db.RegisterConstantOps.Add(registerConstant); + Context.RegisterConstantOps.Add(registerConstant); + } + + public virtual async Task Revert(Block block, RegisterConstantOperation registerConstant) + { + #region entities + var sender = (User)await Cache.Accounts.GetAsync(registerConstant.SenderId); + + Db.TryAttach(sender); + #endregion + + #region revert result + if (registerConstant.Status == OperationStatus.Applied) + { + RevertSpend(sender, registerConstant.StorageFee ?? 0); + + Cache.AppState.Get().ConstantsCount--; + } + #endregion + + #region revert operation + RevertPayFee(sender, registerConstant.BakerFee); + sender.Counter = registerConstant.Counter - 1; + sender.RegisterConstantsCount--; + sender.Revealed = true; + + Cache.AppState.Get().RegisterConstantOpsCount--; + #endregion + + Db.RegisterConstantOps.Remove(registerConstant); + Cache.AppState.ReleaseManagerCounter(); + Cache.AppState.ReleaseOperationId(); + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/RevealsCommit.cs index 911b675b8..91ffa0e2f 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/RevealsCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/RevealsCommit.cs @@ -1,4 +1,117 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Text.Json; +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class RevealsCommit(ProtocolHandler protocol) : Proto14.RevealsCommit(protocol) { } + class RevealsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public virtual async Task Apply(Block block, JsonElement op, JsonElement content) + { + #region init + var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); + + var pubKey = content.RequiredString("public_key"); + var metadata = content.Required("metadata"); + var result = metadata.Required("operation_result"); + + var refund = metadata + .OptionalArray("balance_updates")? + .EnumerateArray() + .FirstOrDefault(x => + x.RequiredString("kind") == "accumulator" && + x.RequiredString("category") == "block fees" && + x.RequiredInt64("change") < 0) + ?? default; + + var bakerFee = content.RequiredInt64("fee") + + (refund.ValueKind != JsonValueKind.Undefined ? refund.RequiredInt64("change") : 0); + + var reveal = new RevealOperation + { + Id = Cache.AppState.NextOperationId(), + OpHash = op.RequiredString("hash"), + Level = block.Level, + Timestamp = block.Timestamp, + BakerFee = bakerFee, + Counter = content.RequiredInt32("counter"), + GasLimit = content.RequiredInt32("gas_limit"), + StorageLimit = content.RequiredInt32("storage_limit"), + SenderId = sender.Id, + Status = result.RequiredString("status") switch + { + "applied" => OperationStatus.Applied, + "backtracked" => OperationStatus.Backtracked, + "failed" => OperationStatus.Failed, + "skipped" => OperationStatus.Skipped, + _ => throw new NotImplementedException() + }, + Errors = result.TryGetProperty("errors", out var errors) + ? OperationErrors.Parse(content, errors) + : null, + GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000) + }; + #endregion + + #region apply operation + Db.TryAttach(sender); + PayFee(sender, reveal.BakerFee); + sender.Counter = reveal.Counter; + sender.RevealsCount++; + + block.Operations |= Operations.Reveals; + + Cache.AppState.Get().RevealOpsCount++; + #endregion + + #region apply result + if (reveal.Status == OperationStatus.Applied) + { + if (sender is User user) + { + user.PublicKey = pubKey; + if (user.Balance > 0) user.Revealed = true; + } + } + #endregion + + Proto.Manager.Set(sender); + Db.RevealOps.Add(reveal); + Context.RevealOps.Add(reveal); + } + + public virtual async Task Revert(Block block, RevealOperation reveal) + { + #region entities + var sender = await Cache.Accounts.GetAsync(reveal.SenderId); + + Db.TryAttach(sender); + #endregion + + #region revert result + if (reveal.Status == OperationStatus.Applied) + { + if (sender is User user) + { + if (user.RevealsCount == 1) + user.PublicKey = null; + + user.Revealed = false; + } + } + #endregion + + #region revert operation + RevertPayFee(sender, reveal.BakerFee); + sender.Counter = reveal.Counter - 1; + sender.RevealsCount--; + + Cache.AppState.Get().RevealOpsCount--; + #endregion + + Db.RevealOps.Remove(reveal); + Cache.AppState.ReleaseManagerCounter(); + Cache.AppState.ReleaseOperationId(); + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SetDelegateParametersCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SetDelegateParametersCommit.cs deleted file mode 100644 index e24c0edd7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SetDelegateParametersCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SetDelegateParametersCommit(ProtocolHandler protocol) : Proto18.SetDelegateParametersCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SetDepositsLimitCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SetDepositsLimitCommit.cs deleted file mode 100644 index b1be3339d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SetDepositsLimitCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SetDepositsLimitCommit(ProtocolHandler protocol) : Proto12.SetDepositsLimitCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupAddMessagesCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupAddMessagesCommit.cs deleted file mode 100644 index 84db91bfa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupAddMessagesCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SmartRollupAddMessagesCommit(ProtocolHandler protocol) : Proto16.SmartRollupAddMessagesCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupCementCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupCementCommit.cs deleted file mode 100644 index 9135b985d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupCementCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SmartRollupCementCommit(ProtocolHandler protocol) : Proto17.SmartRollupCementCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupExecuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupExecuteCommit.cs deleted file mode 100644 index 12e30e22c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupExecuteCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SmartRollupExecuteCommit(ProtocolHandler protocol) : Proto16.SmartRollupExecuteCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupOriginateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupOriginateCommit.cs deleted file mode 100644 index 75fcc1932..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupOriginateCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SmartRollupOriginateCommit(ProtocolHandler protocol) : Proto16.SmartRollupOriginateCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupPublishCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupPublishCommit.cs deleted file mode 100644 index 292755a1c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupPublishCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SmartRollupPublishCommit(ProtocolHandler protocol) : Proto16.SmartRollupPublishCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupRecoverBondCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupRecoverBondCommit.cs deleted file mode 100644 index c82c9866e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupRecoverBondCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SmartRollupRecoverBondCommit(ProtocolHandler protocol) : Proto16.SmartRollupRecoverBondCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupRefuteCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupRefuteCommit.cs deleted file mode 100644 index f5ba5e6af..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupRefuteCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SmartRollupRefuteCommit(ProtocolHandler protocol) : Proto16.SmartRollupRefuteCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupTimeoutCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupTimeoutCommit.cs deleted file mode 100644 index 313c54b7e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/SmartRollupTimeoutCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SmartRollupTimeoutCommit(ProtocolHandler protocol) : Proto16.SmartRollupTimeoutCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/StakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/StakingCommit.cs deleted file mode 100644 index 0e60141d0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/StakingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class StakingCommit(ProtocolHandler protocol) : Proto19.StakingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/TransactionsCommit.cs index 7e0a4d020..cb99516bf 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/TransactionsCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/TransactionsCommit.cs @@ -1,12 +1,507 @@ -using System.Text.Json; +using System.Numerics; +using System.Text.Json; using Microsoft.EntityFrameworkCore; +using Netezos.Contracts; +using Netezos.Encoding; using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; namespace Tzkt.Sync.Protocols.Proto24 { - class TransactionsCommit(ProtocolHandler protocol) : Proto14.TransactionsCommit(protocol) + class TransactionsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) { - protected override async Task ApplyAddressRegistryDiffs(TransactionOperation transaction, JsonElement result) + public TransactionOperation Transaction { get; private set; } = null!; + public IEnumerable? BigMapDiffs { get; private set; } + public IEnumerable? TicketUpdates { get; private set; } + public Account? Target { get; private set; } + + public virtual async Task Apply(Block block, JsonElement op, JsonElement content) + { + if (Cache.AppState.Get().BlocksCount <= 3) + { + if (content.RequiredString("source") == NullAddress.Address) + { + if (await Cache.Accounts.ExistsAsync(content.RequiredString("destination"), AccountType.User)) + { + var to = await Cache.Accounts.GetAsync(content.RequiredString("destination")); + if (to!.Balance == content.RequiredInt64("amount")) + return; + } + } + } + + #region init + var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); + var target = await Cache.Accounts.GetOrCreateAsync(content.RequiredString("destination")); + + var metadata = content.Required("metadata"); + var result = metadata.Required("operation_result"); + + var refund = metadata + .OptionalArray("balance_updates")? + .EnumerateArray() + .FirstOrDefault(x => + x.RequiredString("kind") == "accumulator" && + x.RequiredString("category") == "block fees" && + x.RequiredInt64("change") < 0) + ?? default; + + var bakerFee = content.RequiredInt64("fee") + + (refund.ValueKind != JsonValueKind.Undefined ? refund.RequiredInt64("change") : 0); + + var transaction = new TransactionOperation + { + Id = Cache.AppState.NextOperationId(), + Level = block.Level, + Timestamp = block.Timestamp, + OpHash = op.RequiredString("hash"), + Amount = content.RequiredInt64("amount"), + BakerFee = bakerFee, + Counter = content.RequiredInt32("counter"), + GasLimit = content.RequiredInt32("gas_limit"), + StorageLimit = content.RequiredInt32("storage_limit"), + SenderId = sender.Id, + TargetId = target.Id, + TargetCodeHash = (target as Contract)?.CodeHash, + Status = result.RequiredString("status") switch + { + "applied" => OperationStatus.Applied, + "backtracked" => OperationStatus.Backtracked, + "failed" => OperationStatus.Failed, + "skipped" => OperationStatus.Skipped, + _ => throw new NotImplementedException() + }, + Errors = result.TryGetProperty("errors", out var errors) + ? OperationErrors.Parse(content, errors) + : null, + GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), + StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, + StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 + ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost + : null, + AllocationFee = result.OptionalBool("allocated_destination_contract") == true + ? (long?)Context.Protocol.OriginationSize * Context.Protocol.ByteCost + : null + }; + + if (target is not User && content.TryGetProperty("parameters", out var parameters)) + await ProcessParameters(transaction, target, parameters); + #endregion + + #region apply operation + Db.TryAttach(sender); + PayFee(sender, transaction.BakerFee); + sender.Counter = transaction.Counter; + sender.TransactionsCount++; + + if (target != sender) + { + Db.TryAttach(target); + target.TransactionsCount++; + } + + block.Operations |= Operations.Transactions; + + Cache.AppState.Get().TransactionOpsCount++; + #endregion + + #region apply result + if (transaction.Status == OperationStatus.Applied) + { + var burned = (transaction.StorageFee ?? 0) + (transaction.AllocationFee ?? 0); + Proto.Manager.Burn(burned); + + Spend(sender, transaction.Amount + burned); + + Receive(target, transaction.Amount); + + if (result.TryGetProperty("storage", out var storage)) + { + BigMapDiffs = ParseBigMapDiffs(transaction, result); + await ProcessStorage(transaction, target, storage); + } + + await ApplyAddressRegistryDiffs(transaction, result); + + TicketUpdates = ParseTicketUpdates("ticket_updates", result); + + Cache.Statistics.Current.TotalBurned += burned; + if (target.Id == NullAddress.Id) + Cache.Statistics.Current.TotalBanished += transaction.Amount; + } + #endregion + + Proto.Manager.Set(sender); + //Db.TransactionOps.Add(transaction); + Context.TransactionOps.Add(transaction); + Transaction = transaction; + Target = target; + } + + public virtual async Task ApplyInternal(Block block, ManagerOperation parent, JsonElement content) + { + #region init + var parentSender = await Cache.Accounts.GetAsync(parent.SenderId); + var sender = await Cache.Accounts.GetOrCreateAsync(content.RequiredString("source")); + var target = await Cache.Accounts.GetOrCreateAsync(content.RequiredString("destination")); + + var result = content.Required("result"); + + var transaction = new TransactionOperation + { + Id = Cache.AppState.NextOperationId(), + InitiatorId = parent.SenderId, + Level = parent.Level, + Timestamp = parent.Timestamp, + OpHash = parent.OpHash, + Counter = parent.Counter, + Amount = content.RequiredInt64("amount"), + Nonce = content.RequiredInt32("nonce"), + SenderId = sender.Id, + SenderCodeHash = (sender as Contract)?.CodeHash, + TargetId = target.Id, + TargetCodeHash = (target as Contract)?.CodeHash, + Status = result.RequiredString("status") switch + { + "applied" => OperationStatus.Applied, + "backtracked" => OperationStatus.Backtracked, + "failed" => OperationStatus.Failed, + "skipped" => OperationStatus.Skipped, + _ => throw new NotImplementedException() + }, + Errors = result.TryGetProperty("errors", out var errors) + ? OperationErrors.Parse(content, errors) + : null, + GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), + StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, + StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 + ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost + : null, + AllocationFee = result.OptionalBool("allocated_destination_contract") == true + ? (long?)Context.Protocol.OriginationSize * Context.Protocol.ByteCost + : null + }; + + if (target is not User && content.TryGetProperty("parameters", out var parameters)) + await ProcessParameters(transaction, target, parameters); + #endregion + + #region apply operation + if (parent is TransactionOperation parentTx) + { + parentTx.InternalOperations = (short?)((parentTx.InternalOperations ?? 0) + 1); + parentTx.InternalTransactions = (short?)((parentTx.InternalTransactions ?? 0) + 1); + } + + Db.TryAttach(sender); + sender.TransactionsCount++; + + if (target != sender) + { + Db.TryAttach(target); + target.TransactionsCount++; + } + + if (parentSender != sender && parentSender != target) + parentSender.TransactionsCount++; + + block.Operations |= Operations.Transactions; + + Cache.AppState.Get().TransactionOpsCount++; + #endregion + + #region apply result + if (transaction.Status == OperationStatus.Applied) + { + var burned = (transaction.StorageFee ?? 0) + (transaction.AllocationFee ?? 0); + Proto.Manager.Burn(burned); + + Spend(parentSender, burned); + + Spend(sender, transaction.Amount); + + Receive(target, transaction.Amount); + + if (target == parentSender) + Proto.Manager.Credit(transaction.Amount); + + if (result.TryGetProperty("storage", out var storage)) + { + BigMapDiffs = ParseBigMapDiffs(transaction, result); + await ProcessStorage(transaction, target, storage); + } + + await ApplyAddressRegistryDiffs(transaction, result); + + TicketUpdates = ParseTicketUpdates("ticket_receipt", result); + + Cache.Statistics.Current.TotalBurned += burned; + if (target.Id == NullAddress.Id) + Cache.Statistics.Current.TotalBanished += transaction.Amount; + } + #endregion + + //Db.TransactionOps.Add(transaction); + Context.TransactionOps.Add(transaction); + Transaction = transaction; + Target = target; + } + + public virtual async Task Revert(Block block, TransactionOperation transaction) + { + #region entities + var sender = await Cache.Accounts.GetAsync(transaction.SenderId); + var target = await Cache.Accounts.GetAsync(transaction.TargetId); + + Db.TryAttach(sender); + Db.TryAttach(target); + #endregion + + #region revert result + if (transaction.Status == OperationStatus.Applied) + { + RevertReceive(target, transaction.Amount); + + RevertSpend(sender, transaction.Amount + (transaction.StorageFee ?? 0) + (transaction.AllocationFee ?? 0)); + + if (transaction.StorageId != null) + await RevertStorage(transaction, (target as Contract)!); + + await RevertAddressRegistryDiffs(transaction); + } + #endregion + + #region revert operation + RevertPayFee(sender, transaction.BakerFee); + + sender.TransactionsCount--; + if (target != sender) target.TransactionsCount--; + + sender.Counter = transaction.Counter - 1; + if (sender is User user) user.Revealed = true; + + Cache.AppState.Get().TransactionOpsCount--; + #endregion + + //Db.TransactionOps.Remove(transaction); + Cache.AppState.ReleaseManagerCounter(); + Cache.AppState.ReleaseOperationId(); + } + + public virtual async Task RevertInternal(Block block, TransactionOperation transaction) + { + #region entities + var parentSender = await Cache.Accounts.GetAsync(transaction.InitiatorId!.Value); + var sender = await Cache.Accounts.GetAsync(transaction.SenderId); + var target = await Cache.Accounts.GetAsync(transaction.TargetId); + + Db.TryAttach(parentSender); + Db.TryAttach(sender); + Db.TryAttach(target); + #endregion + + #region revert result + if (transaction.Status == OperationStatus.Applied) + { + RevertReceive(target, transaction.Amount); + + RevertSpend(sender, transaction.Amount); + + RevertSpend(parentSender, (transaction.StorageFee ?? 0) + (transaction.AllocationFee ?? 0)); + + if (transaction.StorageId != null) + await RevertStorage(transaction, (target as Contract)!); + + await RevertAddressRegistryDiffs(transaction); + } + #endregion + + #region revert operation + sender.TransactionsCount--; + if (target != sender) target.TransactionsCount--; + if (parentSender != sender && parentSender != target) parentSender.TransactionsCount--; + + Cache.AppState.Get().TransactionOpsCount--; + #endregion + + //Db.TransactionOps.Remove(transaction); + Cache.AppState.ReleaseOperationId(); + } + + protected virtual async Task ProcessParameters(TransactionOperation transaction, Account target, JsonElement param) + { + string? rawEp = null; + IMicheline? rawParam; + try + { + rawEp = param.RequiredString("entrypoint"); + rawParam = Micheline.FromJson(param.Required("value"))!; + } + catch (Exception ex) + { + Logger.LogWarning(ex, "Failed to parse tx parameters"); + transaction.Entrypoint = rawEp ?? string.Empty; + transaction.RawParameters = new MichelineArray().ToBytes(); + return; + } + + if (target is Contract contract) + { + var schema = contract.Kind > ContractKind.DelegatorContract + ? (await Cache.Schemas.GetAsync(contract)) + : Script.ManagerTz; + + try + { + var (normEp, normParam) = schema.NormalizeParameter(rawEp, rawParam); + + transaction.Entrypoint = normEp; + transaction.RawParameters = schema.OptimizeParameter(normEp, normParam).ToBytes(); + transaction.JsonParameters = schema.HumanizeParameter(normEp, normParam); + } + catch (Exception ex) + { + transaction.Entrypoint ??= rawEp; + transaction.RawParameters ??= rawParam.ToBytes(); + + if (transaction.Status == OperationStatus.Applied) + Logger.LogError(ex, "Failed to humanize tx {hash} parameters", transaction.OpHash); + } + } + else + { + transaction.Entrypoint = rawEp; + transaction.RawParameters = rawParam.ToBytes(); + } + } + + protected virtual async Task ProcessStorage(TransactionOperation transaction, Account target, JsonElement storage) + { + if (target is not Contract contract || contract.Kind == ContractKind.DelegatorContract) + return; + + var schema = await Cache.Schemas.GetAsync(contract); + var currentStorage = await Cache.Storages.GetAsync(contract); + + var newStorageMicheline = schema.OptimizeStorage(Micheline.FromJson(storage)!, false); + var newStorageBytes = newStorageMicheline.ToBytes(); + + if (newStorageBytes.IsEqual(currentStorage.RawValue)) + { + transaction.StorageId = currentStorage.Id; + return; + } + + Db.TryAttach(currentStorage); + currentStorage.Current = false; + + var newStorage = new Storage + { + Id = Cache.AppState.NextStorageId(), + Level = transaction.Level, + ContractId = contract.Id, + TransactionId = transaction.Id, + RawValue = newStorageBytes, + JsonValue = schema.HumanizeStorage(newStorageMicheline), + Current = true, + }; + + Db.Storages.Add(newStorage); + Cache.Storages.Add(contract, newStorage); + + transaction.StorageId = newStorage.Id; + } + + public async Task RevertStorage(TransactionOperation transaction, Contract contract) + { + var storage = await Cache.Storages.GetAsync(contract); + if (storage.TransactionId == transaction.Id) + { + var prevStorage = await Db.Storages + .Where(x => x.ContractId == contract.Id && x.Id < storage.Id) + .OrderByDescending(x => x.Id) + .FirstAsync(); + + prevStorage.Current = true; + Cache.Storages.Add(contract, prevStorage); + + Db.Storages.Remove(storage); + Cache.AppState.ReleaseStorageId(); + } + } + + protected virtual IEnumerable? ParseBigMapDiffs(TransactionOperation transaction, JsonElement result) + { + return result.TryGetProperty("lazy_storage_diff", out var diffs) + ? BigMapDiff.ParseLazyStorage(diffs) + : null; + } + + protected virtual IEnumerable? ParseTicketUpdates(string property, JsonElement result) + { + if (!result.TryGetProperty(property, out var ticketUpdates)) + return null; + + var res = new List(); + foreach (var updates in ticketUpdates.RequiredArray().EnumerateArray()) + { + var list = new List(); + foreach (var update in updates.RequiredArray("updates").EnumerateArray()) + { + var amount = update.RequiredBigInteger("amount"); + if (amount != BigInteger.Zero) + { + list.Add(new TicketUpdate + { + Account = update.RequiredString("account"), + Amount = amount + }); + } + } + + if (list.Count > 0) + { + var ticketToken = updates.Required("ticket_token"); + var type = Micheline.FromJson(ticketToken.Required("content_type"))!; + var value = Micheline.FromJson(ticketToken.Required("content"))!; + var rawType = type.ToBytes(); + + byte[] rawContent; + string? jsonContent; + + try + { + var schema = Schema.Create((type as MichelinePrim)!); + rawContent = schema.Optimize(value).ToBytes(); + jsonContent = schema.Humanize(value); + } + catch (Exception ex) + { + Logger.LogError(ex, "Failed to parse ticket content"); + rawContent = value.ToBytes(); + jsonContent = null; + } + + res.Add(new TicketUpdates + { + Ticket = new TicketIdentity + { + Ticketer = ticketToken.RequiredString("ticketer"), + RawType = rawType, + RawContent = rawContent, + JsonContent = jsonContent, + TypeHash = Script.GetHash(rawType), + ContentHash = Script.GetHash(rawContent) + }, + Updates = list + }); + } + } + + return res.Count > 0 ? res : null; + } + + protected virtual async Task ApplyAddressRegistryDiffs(TransactionOperation transaction, JsonElement result) { if (result.TryGetProperty("address_registry_diff", out var diffs)) { @@ -37,7 +532,7 @@ protected override async Task ApplyAddressRegistryDiffs(TransactionOperation tra } } - protected override async Task RevertAddressRegistryDiffs(TransactionOperation transaction) + protected virtual async Task RevertAddressRegistryDiffs(TransactionOperation transaction) { if (transaction.AddressRegistryIndex is int minIndex) { diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/TransferTicketCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/TransferTicketCommit.cs index 41ae80283..baaa8e864 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/TransferTicketCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/TransferTicketCommit.cs @@ -1,4 +1,225 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Numerics; +using System.Text.Json; +using Netezos.Contracts; +using Netezos.Encoding; +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class TransferTicketCommit(ProtocolHandler protocol) : Proto13.TransferTicketCommit(protocol) { } + class TransferTicketCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public TransferTicketOperation Operation { get; private set; } = null!; + public IEnumerable? TicketUpdates { get; private set; } + + public virtual async Task Apply(Block block, JsonElement op, JsonElement content) + { + #region init + var sender = await Cache.Accounts.GetExistingAsync(content.RequiredString("source")); + var target = await Cache.Accounts.GetOrCreateAsync(content.RequiredString("destination")); + var ticketer = await Cache.Accounts.GetOrCreateAsync(content.RequiredString("ticket_ticketer")); + + var metadata = content.Required("metadata"); + var result = metadata.Required("operation_result"); + + var refund = metadata + .OptionalArray("balance_updates")? + .EnumerateArray() + .FirstOrDefault(x => + x.RequiredString("kind") == "accumulator" && + x.RequiredString("category") == "block fees" && + x.RequiredInt64("change") < 0) + ?? default; + + var bakerFee = content.RequiredInt64("fee") + + (refund.ValueKind != JsonValueKind.Undefined ? refund.RequiredInt64("change") : 0); + + var operation = new TransferTicketOperation + { + Id = Cache.AppState.NextOperationId(), + Level = block.Level, + Timestamp = block.Timestamp, + OpHash = op.RequiredString("hash"), + BakerFee = bakerFee, + Counter = content.RequiredInt32("counter"), + GasLimit = content.RequiredInt32("gas_limit"), + StorageLimit = content.RequiredInt32("storage_limit"), + SenderId = sender.Id, + Status = result.RequiredString("status") switch + { + "applied" => OperationStatus.Applied, + "backtracked" => OperationStatus.Backtracked, + "failed" => OperationStatus.Failed, + "skipped" => OperationStatus.Skipped, + _ => throw new NotImplementedException() + }, + Errors = result.TryGetProperty("errors", out var errors) + ? OperationErrors.Parse(content, errors) + : null, + GasUsed = (int)(((result.OptionalInt64("consumed_milligas") ?? 0) + 999) / 1000), + StorageUsed = result.OptionalInt32("paid_storage_size_diff") ?? 0, + StorageFee = result.OptionalInt32("paid_storage_size_diff") > 0 + ? result.OptionalInt32("paid_storage_size_diff") * Context.Protocol.ByteCost + : null, + Amount = BigInteger.Parse(content.RequiredString("ticket_amount")), + TicketerId = ticketer.Id, + Entrypoint = content.RequiredString("entrypoint"), + TargetId = target.Id + }; + + try + { + var micheType = Schema.Create((content.RequiredMicheline("ticket_ty") as MichelinePrim)!); + var value = content.RequiredMicheline("ticket_contents"); + operation.RawType = micheType.ToMicheline().ToBytes(); + operation.RawContent = micheType.Optimize(value).ToBytes(); + operation.JsonContent = micheType.Humanize(value); + } + catch (Exception ex) + { + Logger.LogError(ex, "failed to process 'transfer_ticket' parameters"); + } + #endregion + + #region entities + Db.TryAttach(sender); + Db.TryAttach(target); + Db.TryAttach(ticketer); + #endregion + + #region apply operation + PayFee(sender, operation.BakerFee); + + sender.TransferTicketCount++; + if (target != sender) target.TransferTicketCount++; + if (ticketer != sender && ticketer != target) ticketer.TransferTicketCount++; + + block.Operations |= Operations.TransferTicket; + + sender.Counter = operation.Counter; + + Cache.AppState.Get().TransferTicketOpsCount++; + #endregion + + #region apply result + if (operation.Status == OperationStatus.Applied) + { + var burned = operation.StorageFee ?? 0; + Proto.Manager.Burn(burned); + + Spend(sender, burned); + + TicketUpdates = ParseTicketUpdates(result); + + Cache.Statistics.Current.TotalBurned += burned; + } + #endregion + + Proto.Manager.Set(sender); + Db.TransferTicketOps.Add(operation); + Context.TransferTicketOps.Add(operation); + Operation = operation; + } + + public virtual async Task Revert(Block block, TransferTicketOperation operation) + { + #region entities + var sender = await Cache.Accounts.GetAsync(operation.SenderId); + var target = await Cache.Accounts.GetAsync(operation.TargetId); + var ticketer = await Cache.Accounts.GetAsync(operation.TicketerId); + + Db.TryAttach(sender); + Db.TryAttach(target); + Db.TryAttach(ticketer); + #endregion + + #region revert result + if (operation.Status == OperationStatus.Applied) + { + RevertSpend(sender, operation.StorageFee ?? 0); + } + #endregion + + #region revert operation + RevertPayFee(sender, operation.BakerFee); + + sender.TransferTicketCount--; + if (target != sender) target.TransferTicketCount--; + if (ticketer != sender && ticketer != target) ticketer.TransferTicketCount--; + + sender.Counter = operation.Counter - 1; + (sender as User)!.Revealed = true; + + Cache.AppState.Get().TransferTicketOpsCount--; + #endregion + + Db.TransferTicketOps.Remove(operation); + Cache.AppState.ReleaseManagerCounter(); + Cache.AppState.ReleaseOperationId(); + } + + protected virtual IEnumerable? ParseTicketUpdates(JsonElement result) + { + if (!result.TryGetProperty("ticket_updates", out var ticketUpdates)) + return null; + + var res = new List(); + foreach (var updates in ticketUpdates.RequiredArray().EnumerateArray()) + { + var list = new List(); + foreach (var update in updates.RequiredArray("updates").EnumerateArray()) + { + var amount = update.RequiredBigInteger("amount"); + if (amount != BigInteger.Zero) + { + list.Add(new TicketUpdate + { + Account = update.RequiredString("account"), + Amount = amount + }); + } + } + + if (list.Count > 0) + { + var ticketToken = updates.Required("ticket_token"); + var type = ticketToken.RequiredMicheline("content_type"); + var value = ticketToken.RequiredMicheline("content"); + var rawType = type.ToBytes(); + + byte[] rawContent; + string? jsonContent; + + try + { + var schema = Schema.Create((type as MichelinePrim)!); + rawContent = schema.Optimize(value).ToBytes(); + jsonContent = schema.Humanize(value); + } + catch (Exception ex) + { + Logger.LogError(ex, "Failed to parse ticket content"); + rawContent = value.ToBytes(); + jsonContent = null; + } + + res.Add(new TicketUpdates + { + Ticket = new TicketIdentity + { + Ticketer = ticketToken.RequiredString("ticketer"), + RawType = rawType, + RawContent = rawContent, + JsonContent = jsonContent, + TypeHash = Script.GetHash(rawType), + ContentHash = Script.GetHash(rawContent) + }, + Updates = list + }); + } + } + + return res.Count > 0 ? res : null; + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/UpdateSecondaryKeyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/UpdateSecondaryKeyCommit.cs deleted file mode 100644 index e4133d3ee..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/UpdateSecondaryKeyCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class UpdateSecondaryKeyCommit(ProtocolHandler protocol) : Proto15.UpdateSecondaryKeyCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/VdfRevelationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/VdfRevelationCommit.cs deleted file mode 100644 index 47c9043b8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/Operations/VdfRevelationCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class VdfRevelationCommit(ProtocolHandler protocol) : Proto19.VdfRevelationCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SlashingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SlashingCommit.cs deleted file mode 100644 index ce565916c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SlashingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SlashingCommit(ProtocolHandler protocol) : Proto19.SlashingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index e09c8ddfc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SnapshotBalanceCommit(ProtocolHandler protocol) : Proto19.SnapshotBalanceCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SoftwareCommit.cs deleted file mode 100644 index 83cbadd0f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SoftwareCommit(ProtocolHandler protocol) : Proto5.SoftwareCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StakerCycleCommit.cs deleted file mode 100644 index 9ef11b232..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StakerCycleCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class StakerCycleCommit(ProtocolHandler protocol) : Proto19.StakerCycleCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StakingUpdateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StakingUpdateCommit.cs deleted file mode 100644 index bbc0b878c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StakingUpdateCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class StakingUpdateCommit(ProtocolHandler protocol) : Proto18.StakingUpdateCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StateCommit.cs index f1e42500c..cf7bee69e 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StateCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StateCommit.cs @@ -1,4 +1,49 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Text.Json; +using Tzkt.Data.Models; + +namespace Tzkt.Sync.Protocols.Proto24 { - class StateCommit(ProtocolHandler protocol) : Proto1.StateCommit(protocol) { } + class StateCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public virtual Task Apply(Block block, JsonElement rawBlock) + { + var state = Cache.AppState.Get(); + + state.Hash = block.Hash; + state.Level = block.Level; + state.Timestamp = block.Timestamp; + state.Cycle = block.Cycle; + state.Protocol = Context.Protocol.Hash; + state.NextProtocol = rawBlock.Required("metadata").RequiredString("next_protocol"); + + return Task.CompletedTask; + } + + public virtual async Task Revert() + { + var state = Cache.AppState.Get(); + + if (state.BlocksCount == 0) + { + state.Hash = string.Empty; + state.Level = state.Level - 1; + state.Timestamp = DateTimeOffset.MinValue.UtcDateTime; + state.Cycle = -1; + state.Protocol = string.Empty; + state.NextProtocol = Context.Protocol.Hash; + } + else + { + var prevBlock = await Cache.Blocks.PreviousAsync(); + var prevProtocol = await Cache.Protocols.GetAsync(prevBlock.ProtoCode); + + state.Hash = prevBlock.Hash; + state.Level = prevBlock.Level; + state.Timestamp = prevBlock.Timestamp; + state.Cycle = prevBlock.Cycle; + state.Protocol = prevProtocol.Hash; + state.NextProtocol = Context.Protocol.Hash; + } + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StatisticsCommit.cs index 61759b6fd..37a0216e7 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StatisticsCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/StatisticsCommit.cs @@ -1,4 +1,61 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Tzkt.Data.Models; + +namespace Tzkt.Sync.Protocols.Proto24 { - class StatisticsCommit(ProtocolHandler protocol) : Proto1.StatisticsCommit(protocol) { } + class StatisticsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public virtual async Task Apply(JsonElement rawBlock) + { + var prev = Cache.Statistics.Current; + var statistics = new Statistics + { + Id = 0, + Level = prev.Level + 1, + TotalActivated = prev.TotalActivated, + TotalBootstrapped = prev.TotalBootstrapped, + TotalBurned = prev.TotalBurned, + TotalBanished = prev.TotalBanished, + TotalLost = prev.TotalLost, + TotalCommitments = prev.TotalCommitments, + TotalCreated = prev.TotalCreated, + TotalFrozen = prev.TotalFrozen, + TotalRollupBonds = prev.TotalRollupBonds, + TotalSmartRollupBonds = prev.TotalSmartRollupBonds, + TotalOwnStaked = prev.TotalOwnStaked, + TotalExternalStaked = prev.TotalExternalStaked, + TotalOwnDelegated = prev.TotalOwnDelegated, + TotalExternalDelegated = prev.TotalExternalDelegated, + TotalBakingPower = prev.TotalBakingPower, + TotalVotingPower = prev.TotalVotingPower, + TotalBakers = prev.TotalBakers, + TotalStakers = prev.TotalStakers, + TotalDelegators = prev.TotalDelegators + }; + + if (Cache.AppState.Get().BlocksCount != 0) + { + var timestamp = rawBlock.Required("header").RequiredDateTime("timestamp"); + var prevTimestamp = (await Cache.Blocks.GetAsync(prev.Level)).Timestamp; + if (timestamp.Ticks / (10_000_000L * 3600 * 24) != prevTimestamp.Ticks / (10_000_000L * 3600 * 24)) + { + Db.TryAttach(prev); + prev.Date = prevTimestamp.Date; + } + } + + Db.Statistics.Add(statistics); + Cache.Statistics.SetCurrent(statistics); + } + + public virtual async Task Revert(Block block) + { + await Db.Database.ExecuteSqlRawAsync(""" + DELETE FROM "Statistics" + WHERE "Level" = {0} + """, block.Level); + await Cache.Statistics.ResetAsync(); + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SubsidyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SubsidyCommit.cs deleted file mode 100644 index 497f688e0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/SubsidyCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class SubsidyCommit(ProtocolHandler protocol) : Proto10.SubsidyCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/TicketsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/TicketsCommit.cs index 408503b05..a912e0951 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/TicketsCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/TicketsCommit.cs @@ -1,4 +1,599 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Numerics; +using Microsoft.EntityFrameworkCore; +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class TicketsCommit(ProtocolHandler protocol) : Proto16.TicketsCommit(protocol) { } + class TicketsCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + readonly Dictionary>> Updates = []; + + public virtual void Append(ManagerOperation parent, ManagerOperation op, IEnumerable updates) + { + if (!Updates.TryGetValue(parent, out var opUpdates)) + Updates.Add(parent, opUpdates = []); + + foreach (var update in updates) + { + if (!opUpdates.TryGetValue(update.Ticket, out var ticketUpdates)) + opUpdates.Add(update.Ticket, ticketUpdates = []); + + ticketUpdates.AddRange(update.Updates.Select(update => (op, update))); + } + } + + public virtual async Task Apply() + { + if (Updates.Count == 0) return; + + #region precache + var accountsSet = new HashSet(); + var ticketsSet = new HashSet<(int, byte[], int, byte[], int)>(); + var balancesSet = new HashSet<(int, long)>(); + + foreach (var (ticket, updates) in Updates.SelectMany(x => x.Value)) + { + accountsSet.Add(ticket.Ticketer); + foreach (var (_, upd) in updates) + accountsSet.Add(upd.Account); + } + + await Cache.Accounts.Preload(accountsSet); + + foreach (var (ticket, _) in Updates.SelectMany(x => x.Value)) + { + if (Cache.Accounts.TryGetCached(ticket.Ticketer, out var ticketer)) + ticketsSet.Add((ticketer.Id, ticket.RawType, ticket.TypeHash, ticket.RawContent, ticket.ContentHash)); + } + + await Cache.Tickets.Preload(ticketsSet); + + foreach (var (ticket, updates) in Updates.SelectMany(x => x.Value)) + { + if (Cache.Accounts.TryGetCached(ticket.Ticketer, out var ticketer)) + { + if (Cache.Tickets.TryGetCached(ticketer.Id, ticket.RawType, ticket.RawContent, out var _ticket)) + { + foreach (var (_, upd) in updates) + { + if (Cache.Accounts.TryGetCached(upd.Account, out var acc)) + balancesSet.Add((acc.Id, _ticket.Id)); + } + } + } + } + + await Cache.TicketBalances.Preload(balancesSet); + #endregion + + Context.Block.Events |= BlockEvents.Tickets; + + foreach (var (parent, opUpdates) in Updates.OrderBy(kv => kv.Key.Id)) + { + foreach (var (ticketIdentity, ticketUpdates) in opUpdates.OrderBy(x => x.Value[0].Op.Id).ThenBy(x => x.Key.ContentHash + x.Key.TypeHash)) + { + var ticketer = (GetOrCreateAccount(ticketUpdates[0].Op, ticketIdentity.Ticketer) as Contract)!; + var ticket = GetOrCreateTicket(ticketUpdates[0].Op, ticketer, ticketIdentity); + + if (ticketUpdates.Count == 1 || ticketUpdates.BigSum(x => x.Update.Amount) != BigInteger.Zero) + { + foreach (var (op, ticketUpdate) in ticketUpdates) + MintOrBurnTickets(op, ticket, ticketUpdate.Account, ticketUpdate.Amount); + } + else if (ticketUpdates.Count(x => x.Update.Amount < BigInteger.Zero) == 1) + { + var (fromOp, fromUpdate) = ticketUpdates.First(x => x.Update.Amount < BigInteger.Zero); + foreach (var (op, ticketUpdate) in ticketUpdates.Where(x => x.Update.Amount > BigInteger.Zero)) + TransferTickets(ticketUpdates[0].Op, ticket, fromUpdate.Account, ticketUpdate.Account, ticketUpdate.Amount); + } + else if (ticketUpdates.Count(x => x.Update.Amount > BigInteger.Zero) == 1) + { + var (toOp, toUpdate) = ticketUpdates.First(x => x.Update.Amount > BigInteger.Zero); + foreach (var (op, ticketUpdate) in ticketUpdates.Where(x => x.Update.Amount < BigInteger.Zero)) + TransferTickets(ticketUpdates[0].Op, ticket, ticketUpdate.Account, toUpdate.Account, -ticketUpdate.Amount); + } + else if (IsTransfersSequence(ticketUpdates)) + { + for (int i = 0; i < ticketUpdates.Count; i += 2) + { + var u1 = ticketUpdates[i].Update; + var u2 = ticketUpdates[i + 1].Update; + + if (u1.Amount < 0) // from u1 to u2 + TransferTickets(ticketUpdates[i].Op, ticket, u1.Account, u2.Account, u2.Amount); + else // from u2 to u1 + TransferTickets(ticketUpdates[i].Op, ticket, u2.Account, u1.Account, u1.Amount); + } + } + else + { + foreach (var (op, ticketUpdate) in ticketUpdates) + MintOrBurnTickets(op, ticket, ticketUpdate.Account, ticketUpdate.Amount); + } + } + } + } + + static bool IsTransfersSequence(List<(ManagerOperation Op, TicketUpdate Update)> updates) + { + if (updates.Count % 2 != 0) + return false; + + for (int i = 0; i < updates.Count; i += 2) + if (updates[i].Update.Amount > 0 || updates[i].Update.Amount != -updates[i + 1].Update.Amount) + return false; + + return true; + } + + Account GetOrCreateAccount(ManagerOperation op, string address) + { + if (!Cache.Accounts.TryGetCached(address, out var account)) + { + account = address[0] == 't' && address[1] == 'z' + ? new User + { + Id = Cache.AppState.NextAccountId(), + Address = address, + FirstLevel = op.Level, + LastLevel = op.Level, + Type = AccountType.User + } + : new Account + { + Id = Cache.AppState.NextAccountId(), + Address = address, + FirstLevel = op.Level, + LastLevel = op.Level, + Type = AccountType.Ghost + }; + + Db.Accounts.Add(account); + Cache.Accounts.Add(account); + } + return account; + } + + Ticket GetOrCreateTicket(ManagerOperation op, Contract ticketer, TicketIdentity ticketToken) + { + if (!Cache.Tickets.TryGetCached(ticketer.Id, ticketToken.RawType, ticketToken.RawContent, out var ticket)) + { + ticket = new Ticket + { + Id = op switch + { + TransactionOperation transaction => Cache.AppState.NextSubId(transaction), + TransferTicketOperation transferTicket => Cache.AppState.NextSubId(transferTicket), + SmartRollupExecuteOperation srExecute => Cache.AppState.NextSubId(srExecute), + _ => throw new ArgumentOutOfRangeException(nameof(op)) + }, + TicketerId = ticketer.Id, + FirstMinterId = op switch + { + TransactionOperation transaction => transaction.InitiatorId ?? transaction.SenderId, + TransferTicketOperation transferTicket => transferTicket.SenderId, + SmartRollupExecuteOperation srExecute => srExecute.SenderId, + _ => throw new ArgumentOutOfRangeException(nameof(op)) + }, + FirstLevel = op.Level, + LastLevel = op.Level, + TotalBurned = BigInteger.Zero, + TotalMinted = BigInteger.Zero, + TotalSupply = BigInteger.Zero, + RawType = ticketToken.RawType, + RawContent = ticketToken.RawContent, + JsonContent = ticketToken.JsonContent, + ContentHash = ticketToken.ContentHash, + TypeHash = ticketToken.TypeHash, + }; + + Db.Tickets.Add(ticket); + Cache.Tickets.Add(ticket); + + Db.TryAttach(ticketer); + ticketer.TicketsCount++; + + var state = Cache.AppState.Get(); + state.TicketsCount++; + } + return ticket; + } + + TicketBalance GetOrCreateTicketBalance(ManagerOperation op, Ticket ticket, Account account) + { + if (!Cache.TicketBalances.TryGet(account.Id, ticket.Id, out var ticketBalance)) + { + ticketBalance = new TicketBalance + { + Id = op switch + { + TransactionOperation transaction => Cache.AppState.NextSubId(transaction), + TransferTicketOperation transferTicket => Cache.AppState.NextSubId(transferTicket), + SmartRollupExecuteOperation srExecute => Cache.AppState.NextSubId(srExecute), + _ => throw new ArgumentOutOfRangeException(nameof(op)) + }, + AccountId = account.Id, + TicketId = ticket.Id, + TicketerId = ticket.TicketerId, + FirstLevel = op.Level, + LastLevel = op.Level, + Balance = BigInteger.Zero + }; + + Db.TicketBalances.Add(ticketBalance); + Cache.TicketBalances.Add(ticketBalance); + + Db.TryAttach(ticket); + ticket.BalancesCount++; + + Db.TryAttach(account); + account.TicketBalancesCount++; + + var state = Cache.AppState.Get(); + state.TicketBalancesCount++; + } + return ticketBalance; + } + + void TransferTickets(ManagerOperation op, Ticket ticket, string fromAddress, string toAddress, BigInteger amount) + { + var from = GetOrCreateAccount(op, fromAddress); + var fromBalance = GetOrCreateTicketBalance(op, ticket, from); + var to = GetOrCreateAccount(op, toAddress); + var toBalance = GetOrCreateTicketBalance(op, ticket, to); + + switch (op) + { + case TransactionOperation transaction: + transaction.TicketTransfers = (transaction.TicketTransfers ?? 0) + 1; + break; + case TransferTicketOperation transferTicket: + transferTicket.TicketTransfers = (transferTicket.TicketTransfers ?? 0) + 1; + break; + case SmartRollupExecuteOperation srExecute: + srExecute.TicketTransfers = (srExecute.TicketTransfers ?? 0) + 1; + break; + } + + Db.TryAttach(from); + from.TicketTransfersCount++; + from.LastLevel = op.Level; + + Db.TryAttach(to); + if (to != from) + { + to.TicketTransfersCount++; + to.LastLevel = op.Level; + } + + Db.TryAttach(fromBalance); + fromBalance.Balance -= amount; + fromBalance.TransfersCount++; + fromBalance.LastLevel = op.Level; + + Db.TryAttach(toBalance); + toBalance.Balance += amount; + if (toBalance != fromBalance) toBalance.TransfersCount++; + toBalance.LastLevel = op.Level; + + Db.TryAttach(ticket); + ticket.TransfersCount++; + ticket.LastLevel = op.Level; + if (amount != BigInteger.Zero && fromBalance != toBalance) + { + if (fromBalance.Balance == BigInteger.Zero) + { + from.ActiveTicketsCount--; + ticket.HoldersCount--; + } + if (toBalance.Balance == amount) + { + to.ActiveTicketsCount++; + ticket.HoldersCount++; + } + } + + var state = Cache.AppState.Get(); + state.TicketTransfersCount++; + + Db.TicketTransfers.Add(new TicketTransfer + { + Id = op switch + { + TransactionOperation transaction => Cache.AppState.NextSubId(transaction), + TransferTicketOperation transferTicket => Cache.AppState.NextSubId(transferTicket), + SmartRollupExecuteOperation srExecute => Cache.AppState.NextSubId(srExecute), + _ => throw new ArgumentOutOfRangeException(nameof(op)) + }, + Amount = amount, + FromId = from.Id, + ToId = to.Id, + Level = op.Level, + TicketId = ticket.Id, + TicketerId = ticket.TicketerId, + TransactionId = (op as TransactionOperation)?.Id, + TransferTicketId = (op as TransferTicketOperation)?.Id, + SmartRollupExecuteId = (op as SmartRollupExecuteOperation)?.Id + }); + } + + void MintOrBurnTickets(ManagerOperation op, Ticket ticket, string address, BigInteger amount) + { + var account = GetOrCreateAccount(op, address); + var balance = GetOrCreateTicketBalance(op, ticket, account); + + switch (op) + { + case TransactionOperation transaction: + transaction.TicketTransfers = (transaction.TicketTransfers ?? 0) + 1; + break; + case TransferTicketOperation transferTicket: + transferTicket.TicketTransfers = (transferTicket.TicketTransfers ?? 0) + 1; + break; + case SmartRollupExecuteOperation srExecute: + srExecute.TicketTransfers = (srExecute.TicketTransfers ?? 0) + 1; + break; + } + + Db.TryAttach(account); + account.TicketTransfersCount++; + account.LastLevel = op.Level; + + Db.TryAttach(balance); + balance.Balance += amount; + balance.TransfersCount++; + balance.LastLevel = op.Level; + + Db.TryAttach(ticket); + ticket.TransfersCount++; + ticket.LastLevel = op.Level; + ticket.TotalSupply += amount; + if (amount > BigInteger.Zero) + { + ticket.TotalMinted += amount; + if (balance.Balance == amount) + { + account.ActiveTicketsCount++; + ticket.HoldersCount++; + } + } + else if (amount < BigInteger.Zero) + { + ticket.TotalBurned += -amount; + if (balance.Balance == BigInteger.Zero) + { + account.ActiveTicketsCount--; + ticket.HoldersCount--; + } + } + + var state = Cache.AppState.Get(); + state.TicketTransfersCount++; + + Db.TicketTransfers.Add(new TicketTransfer + { + Id = op switch + { + TransactionOperation transaction => Cache.AppState.NextSubId(transaction), + TransferTicketOperation transferTicket => Cache.AppState.NextSubId(transferTicket), + SmartRollupExecuteOperation srExecute => Cache.AppState.NextSubId(srExecute), + _ => throw new ArgumentOutOfRangeException(nameof(op)) + }, + Amount = amount > BigInteger.Zero ? amount : -amount, + FromId = amount < BigInteger.Zero ? account.Id : null, + ToId = amount > BigInteger.Zero ? account.Id : null, + Level = op.Level, + TicketId = ticket.Id, + TicketerId = ticket.TicketerId, + TransactionId = (op as TransactionOperation)?.Id, + TransferTicketId = (op as TransferTicketOperation)?.Id, + SmartRollupExecuteId = (op as SmartRollupExecuteOperation)?.Id + }); + } + + public virtual async Task Revert(Block block) + { + if (!block.Events.HasFlag(BlockEvents.Tickets)) + return; + + var state = Cache.AppState.Get(); + + var transfers = await Db.TicketTransfers + .AsNoTracking() + .Where(x => x.Level == block.Level) + .OrderByDescending(x => x.Id) + .ToListAsync(); + + #region precache + var accountsSet = new HashSet(); + var ticketsSet = new HashSet(); + var balancesSet = new HashSet<(int, long)>(); + + foreach (var tr in transfers) + ticketsSet.Add(tr.TicketId); + + await Cache.Tickets.Preload(ticketsSet); + + foreach (var tr in transfers) + { + if (tr.FromId is int fromId) + { + accountsSet.Add(fromId); + balancesSet.Add((fromId, tr.TicketId)); + } + + if (tr.ToId is int toId) + { + accountsSet.Add(toId); + balancesSet.Add((toId, tr.TicketId)); + } + } + + foreach (var id in ticketsSet) + { + var ticket = Cache.Tickets.GetCached(id); + accountsSet.Add(ticket.TicketerId); + } + + await Cache.Accounts.Preload(accountsSet); + await Cache.TicketBalances.Preload(balancesSet); + #endregion + + var ticketsToRemove = new HashSet(); + var ticketBalancesToRemove = new HashSet(); + + foreach (var transfer in transfers) + { + var ticket = Cache.Tickets.GetCached(transfer.TicketId); + Db.TryAttach(ticket); + ticket.TransfersCount--; + ticket.LastLevel = block.Level; + if (ticket.TransfersCount == 0) + ticketsToRemove.Add(ticket); + + state.TicketTransfersCount--; + + if (transfer.FromId is int fromId && transfer.ToId is int toId) + { + #region revert transfer + var from = Cache.Accounts.GetCached(fromId); + var fromBalance = Cache.TicketBalances.Get(from.Id, ticket.Id); + var to = Cache.Accounts.GetCached(toId); + var toBalance = Cache.TicketBalances.Get(to.Id, ticket.Id); + + Db.TryAttach(from); + from.TicketTransfersCount--; + from.LastLevel = block.Level; + + Db.TryAttach(to); + if (to != from) + { + to.TicketTransfersCount--; + to.LastLevel = block.Level; + } + + Db.TryAttach(fromBalance); + fromBalance.Balance += transfer.Amount; + fromBalance.TransfersCount--; + fromBalance.LastLevel = block.Level; + if (fromBalance.TransfersCount == 0) + ticketBalancesToRemove.Add(fromBalance); + + Db.TryAttach(toBalance); + toBalance.Balance -= transfer.Amount; + if (toBalance != fromBalance) toBalance.TransfersCount--; + toBalance.LastLevel = block.Level; + if (toBalance.TransfersCount == 0) + ticketBalancesToRemove.Add(toBalance); + + if (transfer.Amount != BigInteger.Zero && fromBalance != toBalance) + { + if (fromBalance.Balance == transfer.Amount) + { + from.ActiveTicketsCount++; + ticket.HoldersCount++; + } + if (toBalance.Balance == BigInteger.Zero) + { + to.ActiveTicketsCount--; + ticket.HoldersCount--; + } + } + #endregion + } + else if (transfer.ToId != null) + { + #region revert mint + var to = Cache.Accounts.GetCached(transfer.ToId.Value); + var toBalance = Cache.TicketBalances.Get(to.Id, ticket.Id); + + Db.TryAttach(to); + to.TicketTransfersCount--; + to.LastLevel = block.Level; + + Db.TryAttach(toBalance); + toBalance.Balance -= transfer.Amount; + toBalance.TransfersCount--; + toBalance.LastLevel = block.Level; + if (toBalance.TransfersCount == 0) + ticketBalancesToRemove.Add(toBalance); + + if (transfer.Amount != BigInteger.Zero) + { + ticket.TotalSupply -= transfer.Amount; + ticket.TotalMinted -= transfer.Amount; + if (toBalance.Balance == BigInteger.Zero) + { + to.ActiveTicketsCount--; + ticket.HoldersCount--; + } + } + #endregion + } + else + { + #region revert burn + var from = Cache.Accounts.GetCached(transfer.FromId!.Value); + var fromBalance = Cache.TicketBalances.Get(from.Id, ticket.Id); + + Db.TryAttach(from); + from.TicketTransfersCount--; + from.LastLevel = block.Level; + + Db.TryAttach(fromBalance); + fromBalance.Balance += transfer.Amount; + fromBalance.TransfersCount--; + fromBalance.LastLevel = block.Level; + if (fromBalance.TransfersCount == 0) + ticketBalancesToRemove.Add(fromBalance); + + if (transfer.Amount != BigInteger.Zero) + { + ticket.TotalSupply += transfer.Amount; + ticket.TotalBurned -= transfer.Amount; + if (fromBalance.Balance == transfer.Amount) + { + from.ActiveTicketsCount++; + ticket.HoldersCount++; + } + } + #endregion + } + } + + foreach (var ticketBalance in ticketBalancesToRemove) + { + Db.TicketBalances.Remove(ticketBalance); + Cache.TicketBalances.Remove(ticketBalance); + + var t = Cache.Tickets.GetCached(ticketBalance.TicketId); + Db.TryAttach(t); + t.BalancesCount--; + + var a = Cache.Accounts.GetCached(ticketBalance.AccountId); + Db.TryAttach(a); + a.TicketBalancesCount--; + + state.TicketBalancesCount--; + } + + foreach (var ticket in ticketsToRemove) + { + Db.Tickets.Remove(ticket); + Cache.Tickets.Remove(ticket); + + var contract = (Contract)Cache.Accounts.GetCached(ticket.TicketerId); + Db.TryAttach(contract); + contract.TicketsCount--; + + state.TicketsCount--; + } + + await Db.Database.ExecuteSqlRawAsync(""" + DELETE FROM "TicketTransfers" + WHERE "Level" = {0} + """, block.Level); + } + } } \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/TokensCommit.cs index 78e0c8780..a1ce31211 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/TokensCommit.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/TokensCommit.cs @@ -1,4 +1,1060 @@ -namespace Tzkt.Sync.Protocols.Proto24 +using System.Numerics; +using Microsoft.EntityFrameworkCore; +using Netezos.Encoding; +using Tzkt.Data.Models; +using Tzkt.Data.Models.Base; + +namespace Tzkt.Sync.Protocols.Proto24 { - class TokensCommit(ProtocolHandler protocol) : Proto5.TokensCommit(protocol) { } + class TokensCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) + { + public virtual async Task Apply(Block block, + List<(BigMap BigMap, BigMapKey? Key, BigMapUpdate Update, ContractOperation Op)> updates) + { + updates = updates.OrderBy(x => x.Op.Id).ThenBy(x => x.BigMap.Ptr).ToList(); + var ops = new Dictionary Transfers, + List<(string Address, BigInteger Balance)> Balances + )> Tokens + )>(); + var opBlocks = new Dictionary { { block.Level, block } }; + + #region discover ledgers + Dictionary? pendingBigMaps = null; + foreach (var (bigmap, _, update, op) in updates) + { + if (update.Action == BigMapAction.Allocate) + { + if ((bigmap.Tags & BigMapTag.LedgerTypes) != 0) + { + var contract = (await Cache.Accounts.GetAsync( + op is TransactionOperation tx + ? tx.TargetId + : (op as OriginationOperation)!.ContractId!.Value + ) as Contract)!; + + if (contract.Tags.HasFlag(ContractTags.Ledger)) + { + // there must be only one ledger bigmap + bigmap.Tags &= ~BigMapTag.LedgerMask; + Logger.LogWarning("Multiple ledger bigmaps discovered for {contract}", contract.Address); + } + else + { + Db.TryAttach(contract); + contract.Tags |= ContractTags.Ledger; + if ((bigmap.Tags & BigMapTag.LedgerNft) != 0) + contract.Tags |= ContractTags.Nft; + } + } + } + else if (update.Action == BigMapAction.Remove) + { + if ((bigmap.Tags & BigMapTag.LedgerTypes) != 0) + { + var contract = (await Cache.Accounts.GetAsync( + op is TransactionOperation tx + ? tx.TargetId + : (op as OriginationOperation)!.ContractId!.Value + ) as Contract)!; + + Db.TryAttach(contract); + contract.Tags &= ~ContractTags.Ledger; + if ((bigmap.Tags & BigMapTag.LedgerNft) != 0) + contract.Tags &= ~ContractTags.Nft; + } + } + else if ((bigmap.Tags & (BigMapTag.Persistent | BigMapTag.Ledger)) == BigMapTag.Persistent && + op is TransactionOperation tx && tx.Entrypoint == "transfer" && await Cache.Accounts.GetAsync(tx.TargetId) is Contract contract && + (contract.Tags & (ContractTags.FA | ContractTags.Ledger)) == ContractTags.FA) + { + Db.TryAttach(bigmap); + bigmap.Tags |= BigMaps.GetLedgerType(bigmap.Schema); + + if (bigmap.Tags.HasFlag(BigMapTag.Ledger)) + { + Db.TryAttach(contract); + contract.Tags |= ContractTags.Ledger; + if ((bigmap.Tags & BigMapTag.LedgerNft) != 0) + contract.Tags |= ContractTags.Nft; + + pendingBigMaps ??= []; + pendingBigMaps.Add(bigmap.Ptr, bigmap); + } + else + { + bigmap.Tags |= BigMapTag.Ledger; + Logger.LogWarning("Unsupported ledger bigmap #{ptr} ignored", bigmap.Ptr); + } + } + } + if (pendingBigMaps != null) + { + #region load entities + var ptrs = pendingBigMaps.Keys.ToHashSet(); + var pendingUpdates = await Db.BigMapUpdates + .AsNoTracking() + .Where(x => ptrs.Contains(x.BigMapPtr) && + x.Action != BigMapAction.Allocate && + x.Level < block.Level) + .ToListAsync(); + + var keys = pendingUpdates.Count == 0 ? [] : await Db.BigMapKeys + .AsNoTracking() + .Where(x => ptrs.Contains(x.BigMapPtr)) + .ToDictionaryAsync(x => x.Id); + + var txIds = pendingUpdates + .Where(x => x.TransactionId != null) + .Select(x => x.TransactionId!.Value) + .ToHashSet(); + + var txs = txIds.Count == 0 ? [] : await Db.TransactionOps + //.AsNoTracking() + .Where(x => txIds.Contains(x.Id)) + .ToDictionaryAsync(x => x.Id); + + var origIds = pendingUpdates + .Where(x => x.OriginationId != null) + .Select(x => x.OriginationId!.Value) + .ToHashSet(); + + var origs = origIds.Count == 0 ? [] : await Db.OriginationOps + //.AsNoTracking() + .Where(x => origIds.Contains(x.Id)) + .ToDictionaryAsync(x => x.Id); + + var contracts = pendingBigMaps.Values + .Select(x => x.ContractId) + .ToHashSet(); + + // transfers with no balance updates, e.g. to itself or with 0 amount + var pendingTransfers = await Db.TransactionOps + //.AsNoTracking() + .Where(x => contracts.Contains(x.TargetId) && + x.Status == OperationStatus.Applied && + x.Entrypoint == "transfer" && + x.TokenTransfers == null && + x.Level < block.Level) + .ToListAsync(); + #endregion + + #region preload + var blocks = pendingTransfers.Select(x => x.Level) + .Concat(pendingUpdates.Select(x => x.Level)) + .ToHashSet(); + + var targets = pendingTransfers.Select(x => x.TargetId) + .Concat(pendingBigMaps.Select(x => x.Value.ContractId)) + .ToHashSet(); + + await Cache.Blocks.Preload(blocks); + await Cache.Accounts.Preload(targets); + #endregion + + #region group + foreach (var tx in pendingTransfers) + { + if (!opBlocks.ContainsKey(tx.Level)) + { + var opBlock = Cache.Blocks.GetCached(tx.Level); + opBlocks.Add(tx.Level, opBlock); + Db.TryAttach(opBlock); + } + + var tokens = new Dictionary Transfers, + List<(string Address, BigInteger Balance)> Balances + )>(); + + foreach (var (from, to, tokenId, amount) in ParseTransferParam(Micheline.FromBytes(tx.RawParameters!))) + { + if (!tokens.TryGetValue(tokenId, out var ctx)) + { + ctx = ([], []); + tokens.Add(tokenId, ctx); + } + ctx.Transfers.Add((from, to, amount)); + } + + var contract = (Cache.Accounts.GetCached(tx.TargetId) as Contract)!; + ops.Add(tx, (false, contract, tokens)); + } + + foreach (var update in pendingUpdates) + { + var bigmap = pendingBigMaps[update.BigMapPtr]; + var op = update.OriginationId != null + ? origs[update.OriginationId.Value] as ContractOperation + : txs[update.TransactionId!.Value]; + + if (!opBlocks.ContainsKey(op.Level)) + { + var opBlock = Cache.Blocks.GetCached(op.Level); + opBlocks.Add(op.Level, opBlock); + Db.TryAttach(opBlock); + } + + if (!ops.TryGetValue(op, out var opCtx)) + { + var contract = (Cache.Accounts.GetCached(bigmap.ContractId) as Contract)!; + opCtx = (false, contract, []); + ops.Add(op, opCtx); + } + + if (update.Action == BigMapAction.Remove) + { + ops[op] = (true, ops[op].Contract, ops[op].Tokens); + } + else + { + var key = keys[update.BigMapKeyId!.Value]; + + foreach (var (address, tokenId, balance) in BigMaps.ParseLedger(bigmap, key, update)) + { + if (!opCtx.Tokens.TryGetValue(tokenId, out var tokenCtx)) + { + tokenCtx = ([], []); + opCtx.Tokens.Add(tokenId, tokenCtx); + } + tokenCtx.Balances.Add((address, balance)); + } + } + + } + #endregion + } + #endregion + + #region group updates + foreach (var tx in Context.TransactionOps) + { + if (tx.Status == OperationStatus.Applied && tx.Entrypoint == "transfer") + { + var contract = (await Cache.Accounts.GetAsync(tx.TargetId) as Contract)!; + if (contract.Tags.HasFlag(ContractTags.Ledger)) + { + var tokens = new Dictionary Transfers, + List<(string Address, BigInteger Balance)> Balances + )>(); + + foreach (var (from, to, tokenId, amount) in ParseTransferParam(Micheline.FromBytes(tx.RawParameters!))) + { + if (!tokens.TryGetValue(tokenId, out var ctx)) + { + ctx = ([], []); + tokens.Add(tokenId, ctx); + } + ctx.Transfers.Add((from, to, amount)); + } + + ops.Add(tx, (false, contract, tokens)); + } + } + } + foreach (var (bigmap, key, update, op) in updates) + { + if ((bigmap.Tags & BigMapTag.LedgerTypes) == 0 || update.Action == BigMapAction.Allocate) + continue; + + if (!ops.TryGetValue(op, out var opCtx)) + { + var contract = (await Cache.Accounts.GetAsync( + op is TransactionOperation tx + ? tx.TargetId + : (op as OriginationOperation)!.ContractId!.Value + ) as Contract)!; + + opCtx = (false, contract, []); + ops.Add(op, opCtx); + } + + if (update.Action == BigMapAction.Remove) + { + ops[op] = (true, ops[op].Contract, ops[op].Tokens); + } + else + { + foreach (var (address, tokenId, balance) in BigMaps.ParseLedger(bigmap, key!, update)) + { + if (!opCtx.Tokens.TryGetValue(tokenId, out var tokenCtx)) + { + tokenCtx = ([], []); + opCtx.Tokens.Add(tokenId, tokenCtx); + } + tokenCtx.Balances.Add((address, balance)); + } + } + } + #endregion + + if (ops.Count == 0) return; + + #region precache + var accountsSet = new HashSet(); + var tokensSet = new HashSet<(int, BigInteger)>(); + var balancesSet = new HashSet<(int, long)>(); + var nftAccountsSet = new HashSet(); + + foreach (var (op, opCtx) in ops) + { + foreach (var (tokenId, tokenCtx) in opCtx.Tokens) + { + foreach (var (from, to, _) in tokenCtx.Transfers) + { + accountsSet.Add(from); + accountsSet.Add(to); + tokensSet.Add((opCtx.Contract.Id, tokenId)); + } + foreach (var (address, _) in tokenCtx.Balances) + { + accountsSet.Add(address); + tokensSet.Add((opCtx.Contract.Id, tokenId)); + } + } + } + + await Cache.Tokens.Preload(tokensSet); + await Cache.Accounts.Preload(accountsSet); + + foreach (var (op, opCtx) in ops) + { + foreach (var (tokenId, tokenCtx) in opCtx.Tokens) + { + foreach (var (from, to, _) in tokenCtx.Transfers) + if (Cache.Tokens.TryGet(opCtx.Contract.Id, tokenId, out var token)) + { + if (Cache.Accounts.TryGetCached(from, out var fromAcc)) + balancesSet.Add((fromAcc.Id, token.Id)); + + if (Cache.Accounts.TryGetCached(to, out var toAcc)) + balancesSet.Add((toAcc.Id, token.Id)); + } + + foreach (var (address, _) in tokenCtx.Balances) + if (Cache.Tokens.TryGet(opCtx.Contract.Id, tokenId, out var token)) + { + if (Cache.Accounts.TryGetCached(address, out var acc)) + balancesSet.Add((acc.Id, token.Id)); + + if (token.OwnerId != null) + { + nftAccountsSet.Add((int)token.OwnerId); + balancesSet.Add(((int)token.OwnerId, token.Id)); + } + } + } + } + + await Cache.Accounts.Preload(nftAccountsSet); + await Cache.TokenBalances.Preload(balancesSet); + #endregion + + foreach (var (op, opCtx) in ops.OrderBy(kv => kv.Key.Id)) + { + if (opCtx.Reset) + { + opBlocks[op.Level].Events |= BlockEvents.Tokens; + await ResetLedgers(op, opCtx.Contract); + } + + foreach (var (tokenId, tokenCtx) in opCtx.Tokens) + { + if (Cache.Tokens.TryGet(opCtx.Contract.Id, tokenId, out var token)) + { + if (token.OwnerId != null && tokenCtx.Balances.Count == 1 && tokenCtx.Balances[0].Balance != BigInteger.Zero) + { + var prevHolder = Cache.Accounts.GetCached((int)token.OwnerId); + if (prevHolder.Address != tokenCtx.Balances[0].Address) + tokenCtx.Balances.Add((prevHolder.Address, BigInteger.Zero)); + } + + if (tokenCtx.Transfers.Count > 0 && ValidateTransfers(token, tokenCtx)) + { + ProcessTransfers(op, opBlocks[op.Level], opCtx.Contract, token, tokenCtx.Transfers); + } + else + { + var diffs = GetDiffs(op, opBlocks[op.Level], token, tokenCtx.Balances); + if (diffs.Count > 0) + { + ProcessDiffs(op, opBlocks[op.Level], opCtx.Contract, token, diffs); + } + } + } + else + { + if (tokenCtx.Transfers.Count > 0 && ValidateTransfers(tokenCtx)) + { + token = GetOrCreateToken(op, opBlocks[op.Level], opCtx.Contract, tokenId); + ProcessTransfers(op, opBlocks[op.Level], opCtx.Contract, token, tokenCtx.Transfers); + } + else + { + var diffs = GetDiffs(op, opBlocks[op.Level], opCtx.Contract, tokenId, tokenCtx.Balances); + if (diffs.Count > 0) + { + token = GetOrCreateToken(op, opBlocks[op.Level], opCtx.Contract, tokenId); + ProcessDiffs(op, opBlocks[op.Level], opCtx.Contract, token, diffs); + } + } + } + } + } + } + + async Task ResetLedgers(ContractOperation op, Contract contract) + { + var tokens = await Db.Tokens + //.AsNoTracking() + .Where(x => x.ContractId == contract.Id) + .ToListAsync(); + var tokenIds = tokens.Select(x => x.Id).ToHashSet(); + + foreach (var token in tokens) + Cache.Tokens.Add(token); + + var tokenBalances = await Db.TokenBalances + .AsNoTracking() + .Where(x => tokenIds.Contains(x.TokenId)) + .ToListAsync(); + + var accountIds = tokenBalances.Select(x => x.AccountId).ToHashSet(); + await Cache.Accounts.Preload(accountIds); + + foreach (var tb in tokenBalances) + { + var tokenBalance = Cache.TokenBalances.GetOrAdd(tb); + if (tokenBalance.Balance == BigInteger.Zero) continue; + var account = Cache.Accounts.GetCached(tokenBalance.AccountId); + var token = Cache.Tokens.Get(tokenBalance.TokenId); + token.LastLevel = op.Level; + MintOrBurnTokens(op, contract, token, account, tokenBalance, -tokenBalance.Balance); + } + } + + bool ValidateTransfers((List<(string, string, BigInteger)> Transfers, List<(string, BigInteger)> Balances) ctx) + { + var dic = new Dictionary(); + foreach (var (from, to, amount) in ctx.Transfers) + { + if (!dic.ContainsKey(from)) + dic.Add(from, BigInteger.Zero); + + if (!dic.ContainsKey(to)) + dic.Add(to, BigInteger.Zero); + + dic[from] -= amount; + dic[to] += amount; + } + foreach (var (address, balance) in ctx.Balances) + { + if (balance != BigInteger.Zero) + { + if (!dic.ContainsKey(address)) + return false; + + dic[address] -= balance; + } + } + return dic.Values.All(x => x == BigInteger.Zero); + } + + bool ValidateTransfers(Token token, (List<(string, string, BigInteger)> Transfers, List<(string, BigInteger)> Balances) ctx) + { + var dic = new Dictionary(); + foreach (var (from, to, amount) in ctx.Transfers) + { + if (!dic.ContainsKey(from)) + dic.Add(from, BigInteger.Zero); + + if (!dic.ContainsKey(to)) + dic.Add(to, BigInteger.Zero); + + dic[from] -= amount; + dic[to] += amount; + } + foreach (var (address, balance) in ctx.Balances) + { + var prevBalance = BigInteger.Zero; + if (Cache.Accounts.TryGetCached(address, out var account) && + Cache.TokenBalances.TryGet(account.Id, token.Id, out var tokenBalance)) + prevBalance = tokenBalance.Balance; + + var diff = balance - prevBalance; + if (diff != BigInteger.Zero) + { + if (!dic.ContainsKey(address)) + return false; + + dic[address] -= diff; + } + } + return dic.Values.All(x => x == BigInteger.Zero); + } + + List<(Account, TokenBalance, BigInteger)> GetDiffs(ContractOperation op, Block block, Contract contract, BigInteger tokenId, List<(string, BigInteger)> balances) + { + var diffs = new List<(Account, TokenBalance, BigInteger Diff)>(balances.Count); + foreach (var (address, balance) in balances) + { + if (balance != BigInteger.Zero) + { + var token = GetOrCreateToken(op, block, contract, tokenId); + var account = GetOrCreateAccount(op, block, address); + var tokenBalance = GetOrCreateTokenBalance(op, block, token, account); + diffs.Add((account, tokenBalance, balance)); + } + } + return diffs; + } + + List<(Account, TokenBalance, BigInteger)> GetDiffs(ContractOperation op, Block block, Token token, List<(string, BigInteger)> balances) + { + var diffs = new List<(Account, TokenBalance, BigInteger Diff)>(balances.Count); + foreach (var (address, balance) in balances) + { + var prevBalance = BigInteger.Zero; + if (Cache.Accounts.TryGetCached(address, out var account) && + Cache.TokenBalances.TryGet(account.Id, token.Id, out var tokenBalance)) + prevBalance = tokenBalance.Balance; + + var diff = balance - prevBalance; + if (diff != BigInteger.Zero) + { + account = GetOrCreateAccount(op, block, address); + tokenBalance = GetOrCreateTokenBalance(op, block, token, account); + diffs.Add((account, tokenBalance, diff)); + } + } + return diffs; + } + + void ProcessTransfers(ContractOperation op, Block block, Contract contract, Token token, List<(string, string, BigInteger)> transfers) + { + Db.TryAttach(token); + token.LastLevel = op.Level; + + block.Events |= BlockEvents.Tokens; + + foreach (var (from, to, amount) in transfers) + { + var fromAcc = GetOrCreateAccount(op, block, from); + var fromBalance = GetOrCreateTokenBalance(op, block, token, fromAcc); + var toAcc = GetOrCreateAccount(op, block, to); + var toBalance = GetOrCreateTokenBalance(op, block, token, toAcc); + TransferTokens(op, contract, token, fromAcc, fromBalance, toAcc, toBalance, amount); + } + } + + void ProcessDiffs(ContractOperation op, Block block, Contract contract, Token token, List<(Account, TokenBalance, BigInteger Diff)> diffs) + { + Db.TryAttach(token); + token.LastLevel = op.Level; + + block.Events |= BlockEvents.Tokens; + + if (diffs.Count == 1 || diffs.BigSum(x => x.Diff) != BigInteger.Zero) + { + foreach (var (account, tokenBalance, diff) in diffs) + MintOrBurnTokens(op, contract, token, account, tokenBalance, diff); + } + else if (diffs.Count(x => x.Diff < BigInteger.Zero) == 1) + { + var (fromAcc, fromBalance, fromDiff) = diffs.First(x => x.Diff < BigInteger.Zero); + foreach (var (toAcc, toBalance, toDiff) in diffs) + { + if (toAcc == fromAcc) continue; + TransferTokens(op, contract, token, fromAcc, fromBalance, toAcc, toBalance, toDiff); + } + } + else if (diffs.Count(x => x.Diff > BigInteger.Zero) == 1) + { + var (toAcc, toBalance, toDiff) = diffs.First(x => x.Diff > BigInteger.Zero); + foreach (var (fromAcc, fromBalance, fromDiff) in diffs) + { + if (fromAcc == toAcc) continue; + TransferTokens(op, contract, token, fromAcc, fromBalance, toAcc, toBalance, -fromDiff); + } + } + else + { + foreach (var (account, tokenBalance, diff) in diffs) + MintOrBurnTokens(op, contract, token, account, tokenBalance, diff); + } + } + + Account GetOrCreateAccount(ContractOperation op, Block block, string address) + { + if (!Cache.Accounts.TryGetCached(address, out var account)) + { + account = address[0] == 't' && address[1] == 'z' + ? new User + { + Id = Cache.AppState.NextAccountId(), + Address = address, + FirstLevel = op.Level, + LastLevel = op.Level, + Type = AccountType.User + } + : new Account + { + Id = Cache.AppState.NextAccountId(), + Address = address, + FirstLevel = op.Level, + LastLevel = op.Level, + Type = AccountType.Ghost + }; + Db.Accounts.Add(account); + Cache.Accounts.Add(account); + + Db.TryAttach(block); + block.Events |= BlockEvents.NewAccounts; + } + return account; + } + + Token GetOrCreateToken(ContractOperation op, Block block, Contract contract, BigInteger tokenId) + { + if (!Cache.Tokens.TryGet(contract.Id, tokenId, out var token)) + { + var state = Cache.AppState.Get(); + state.TokensCount++; + + token = new Token + { + Id = Cache.AppState.NextSubId(op), + ContractId = contract.Id, + TokenId = tokenId, + FirstMinterId = op.InitiatorId ?? op.SenderId, + FirstLevel = op.Level, + LastLevel = op.Level, + TotalBurned = BigInteger.Zero, + TotalMinted = BigInteger.Zero, + TotalSupply = BigInteger.Zero, + Tags = contract.Tags.HasFlag(ContractTags.Nft) + ? TokenTags.Nft + : contract.Tags.HasFlag(ContractTags.FA2) + ? TokenTags.Fa2 + : TokenTags.Fa12, + IndexedAt = op.Level <= state.Level ? state.Level + 1 : null + }; + Db.Tokens.Add(token); + Cache.Tokens.Add(token); + + Db.TryAttach(contract); + contract.TokensCount++; + + Db.TryAttach(block); + block.Events |= BlockEvents.Tokens; + } + return token; + } + + TokenBalance GetOrCreateTokenBalance(ContractOperation op, Block block, Token token, Account account) + { + if (!Cache.TokenBalances.TryGet(account.Id, token.Id, out var tokenBalance)) + { + var state = Cache.AppState.Get(); + state.TokenBalancesCount++; + + tokenBalance = new TokenBalance + { + Id = Cache.AppState.NextSubId(op), + AccountId = account.Id, + TokenId = token.Id, + ContractId = token.ContractId, + FirstLevel = op.Level, + LastLevel = op.Level, + Balance = BigInteger.Zero, + IndexedAt = op.Level <= state.Level ? state.Level + 1 : null + }; + Db.TokenBalances.Add(tokenBalance); + Cache.TokenBalances.Add(tokenBalance); + + Db.TryAttach(token); + token.BalancesCount++; + + Db.TryAttach(account); + account.TokenBalancesCount++; + if (account.FirstLevel > op.Level) + { + account.FirstLevel = op.Level; + block.Events |= BlockEvents.NewAccounts; + } + } + return tokenBalance; + } + + void TransferTokens(ContractOperation op, Contract contract, Token token, + Account from, TokenBalance fromBalance, + Account to, TokenBalance toBalance, + BigInteger amount) + { + op.TokenTransfers = (op.TokenTransfers ?? 0) + 1; + + Db.TryAttach(from); + from.TokenTransfersCount++; + + Db.TryAttach(to); + if (to != from) to.TokenTransfersCount++; + + Db.TryAttach(fromBalance); + fromBalance.Balance -= amount; + fromBalance.TransfersCount++; + fromBalance.LastLevel = op.Level; + + Db.TryAttach(toBalance); + toBalance.Balance += amount; + if (toBalance != fromBalance) toBalance.TransfersCount++; + toBalance.LastLevel = op.Level; + + token.TransfersCount++; + if (amount != BigInteger.Zero && fromBalance.Id != toBalance.Id) + { + if (fromBalance.Balance == BigInteger.Zero) + { + from.ActiveTokensCount--; + token.HoldersCount--; + } + if (toBalance.Balance == amount) + { + to.ActiveTokensCount++; + token.HoldersCount++; + } + if (contract.Tags.HasFlag(ContractTags.Nft)) + token.OwnerId = to.Id; + } + + var state = Cache.AppState.Get(); + state.TokenTransfersCount++; + + Db.TokenTransfers.Add(new TokenTransfer + { + Id = Cache.AppState.NextSubId(op), + Amount = amount, + FromId = from.Id, + ToId = to.Id, + Level = op.Level, + TokenId = token.Id, + ContractId = token.ContractId, + TransactionId = (op as TransactionOperation)?.Id, + OriginationId = (op as OriginationOperation)?.Id, + IndexedAt = op.Level <= state.Level ? state.Level + 1 : null + }); + } + + void MintOrBurnTokens(ContractOperation op, Contract contract, Token token, + Account account, TokenBalance balance, + BigInteger diff) + { + op.TokenTransfers = (op.TokenTransfers ?? 0) + 1; + + Db.TryAttach(account); + account.TokenTransfersCount++; + + Db.TryAttach(balance); + balance.Balance += diff; + balance.TransfersCount++; + balance.LastLevel = op.Level; + + token.TransfersCount++; + if (balance.Balance == BigInteger.Zero) + { + account.ActiveTokensCount--; + token.HoldersCount--; + + if (contract.Tags.HasFlag(ContractTags.Nft)) + token.OwnerId = null; + } + if (balance.Balance == diff) + { + account.ActiveTokensCount++; + token.HoldersCount++; + + if (contract.Tags.HasFlag(ContractTags.Nft)) + token.OwnerId = account.Id; + } + if (diff > 0) token.TotalMinted += diff; + else token.TotalBurned += -diff; + token.TotalSupply += diff; + + var state = Cache.AppState.Get(); + state.TokenTransfersCount++; + + Db.TokenTransfers.Add(new TokenTransfer + { + Id = Cache.AppState.NextSubId(op), + Amount = diff > BigInteger.Zero ? diff : -diff, + FromId = diff < BigInteger.Zero ? account.Id : null, + ToId = diff > BigInteger.Zero ? account.Id : null, + Level = op.Level, + TokenId = token.Id, + ContractId = token.ContractId, + TransactionId = (op as TransactionOperation)?.Id, + OriginationId = (op as OriginationOperation)?.Id, + IndexedAt = op.Level <= state.Level ? state.Level + 1 : null + }); + } + + public virtual async Task Revert(Block block) + { + if (!block.Events.HasFlag(BlockEvents.Tokens)) + return; + + var state = Cache.AppState.Get(); + + var transfers = await Db.TokenTransfers + .AsNoTracking() + .Where(x => x.Level == block.Level) + .OrderByDescending(x => x.Id) + .ToListAsync(); + + #region precache + var accountsSet = new HashSet(); + var tokensSet = new HashSet(); + var tokenBalancesSet = new HashSet<(int, long)>(); + + foreach (var tr in transfers) + tokensSet.Add(tr.TokenId); + + await Cache.Tokens.Preload(tokensSet); + + foreach (var tr in transfers) + { + if (tr.FromId is int fromId) + { + accountsSet.Add(fromId); + tokenBalancesSet.Add((fromId, tr.TokenId)); + } + + if (tr.ToId is int toId) + { + accountsSet.Add(toId); + tokenBalancesSet.Add((toId, tr.TokenId)); + } + } + + foreach (var id in tokensSet) + { + var token = Cache.Tokens.Get(id); + accountsSet.Add(token.ContractId); + } + + await Cache.Accounts.Preload(accountsSet); + await Cache.TokenBalances.Preload(tokenBalancesSet); + #endregion + + var tokensToRemove = new HashSet(); + var tokenBalancesToRemove = new HashSet(); + + foreach (var transfer in transfers) + { + var token = Cache.Tokens.Get(transfer.TokenId); + var contract = (Contract)Cache.Accounts.GetCached(token.ContractId); + Db.TryAttach(token); + token.LastLevel = block.Level; + if (token.FirstLevel == block.Level) + tokensToRemove.Add(token); + + if (transfer.FromId is int fromId && transfer.ToId is int toId) + { + #region revert transfer + var from = Cache.Accounts.GetCached(fromId); + var to = Cache.Accounts.GetCached(toId); + var fromBalance = Cache.TokenBalances.Get(from.Id, token.Id); + var toBalance = Cache.TokenBalances.Get(to.Id, token.Id); + + Db.TryAttach(from); + Db.TryAttach(to); + Db.TryAttach(fromBalance); + Db.TryAttach(toBalance); + + from.TokenTransfersCount--; + if (to != from) to.TokenTransfersCount--; + + fromBalance.Balance += transfer.Amount; + fromBalance.TransfersCount--; + fromBalance.LastLevel = block.Level; + if (fromBalance.FirstLevel == block.Level) + tokenBalancesToRemove.Add(fromBalance); + + toBalance.Balance -= transfer.Amount; + if (toBalance != fromBalance) toBalance.TransfersCount--; + toBalance.LastLevel = block.Level; + if (toBalance.FirstLevel == block.Level) + tokenBalancesToRemove.Add(toBalance); + + token.TransfersCount--; + if (transfer.Amount != BigInteger.Zero && fromBalance.Id != toBalance.Id) + { + if (fromBalance.Balance == transfer.Amount) + { + from.ActiveTokensCount++; + token.HoldersCount++; + } + if (toBalance.Balance == BigInteger.Zero) + { + to.ActiveTokensCount--; + token.HoldersCount--; + } + + if (contract.Tags.HasFlag(ContractTags.Nft)) + token.OwnerId = from.Id; + } + + state.TokenTransfersCount--; + #endregion + } + else if (transfer.ToId != null) + { + #region revert mint + var to = Cache.Accounts.GetCached((int)transfer.ToId); + var toBalance = Cache.TokenBalances.Get(to.Id, token.Id); + + Db.TryAttach(to); + Db.TryAttach(toBalance); + + to.TokenTransfersCount--; + + toBalance.Balance -= transfer.Amount; + toBalance.TransfersCount--; + toBalance.LastLevel = block.Level; + if (toBalance.FirstLevel == block.Level) + tokenBalancesToRemove.Add(toBalance); + + token.TransfersCount--; + if (transfer.Amount != BigInteger.Zero) + { + if (toBalance.Balance == BigInteger.Zero) + { + to.ActiveTokensCount--; + token.HoldersCount--; + } + + if (contract.Tags.HasFlag(ContractTags.Nft)) + token.OwnerId = null; + + token.TotalMinted -= transfer.Amount; + token.TotalSupply -= transfer.Amount; + } + + state.TokenTransfersCount--; + #endregion + } + else + { + #region revert burn + var from = Cache.Accounts.GetCached(transfer.FromId!.Value); + var fromBalance = Cache.TokenBalances.Get(from.Id, token.Id); + + Db.TryAttach(from); + Db.TryAttach(fromBalance); + + from.TokenTransfersCount--; + + fromBalance.Balance += transfer.Amount; + fromBalance.TransfersCount--; + fromBalance.LastLevel = block.Level; + if (fromBalance.FirstLevel == block.Level) + tokenBalancesToRemove.Add(fromBalance); + + token.TransfersCount--; + if (transfer.Amount != BigInteger.Zero) + { + if (fromBalance.Balance == transfer.Amount) + { + from.ActiveTokensCount++; + token.HoldersCount++; + } + + if (contract.Tags.HasFlag(ContractTags.Nft)) + token.OwnerId = from.Id; + + token.TotalBurned -= transfer.Amount; + token.TotalSupply += transfer.Amount; + } + + state.TokenTransfersCount--; + #endregion + } + } + + foreach (var tokenBalance in tokenBalancesToRemove) + { + if (tokenBalance.FirstLevel == block.Level) + { + Db.TokenBalances.Remove(tokenBalance); + Cache.TokenBalances.Remove(tokenBalance); + + var t = Cache.Tokens.Get(tokenBalance.TokenId); + Db.TryAttach(t); + t.BalancesCount--; + + var a = Cache.Accounts.GetCached(tokenBalance.AccountId); + Db.TryAttach(a); + a.TokenBalancesCount--; + + state.TokenBalancesCount--; + } + } + + foreach (var token in tokensToRemove) + { + if (token.FirstLevel == block.Level) + { + Db.Tokens.Remove(token); + Cache.Tokens.Remove(token); + + var c = (Contract)Cache.Accounts.GetCached(token.ContractId); + Db.TryAttach(c); + c.TokensCount--; + + state.TokensCount--; + } + } + + await Db.Database.ExecuteSqlRawAsync(""" + DELETE FROM "TokenTransfers" + WHERE "Level" = {0} + """, block.Level); + } + + static List<(string, string, BigInteger, BigInteger)> ParseTransferParam(IMicheline micheline) + { + var transfers = new List<(string, string, BigInteger, BigInteger)>(); + if (micheline is MichelineArray arr) + { + foreach (var transfer in arr) + { + var transferPair = (transfer as MichelinePrim)!; + var from = transferPair.Args![0].ParseAddress(); + foreach (var tx in (transferPair.Args[1] as MichelineArray)!) + { + var txPair = (tx as MichelinePrim)!; + var to = txPair.Args![0].ParseAddress(); + var txPair2 = (txPair.Args[1] as MichelinePrim)!; + var tokenId = (txPair2.Args![0] as MichelineInt)!.Value; + var amount = (txPair2.Args[1] as MichelineInt)!.Value; + + transfers.Add((from, to, tokenId, amount)); + } + } + } + else if (micheline is MichelinePrim pair) + { + var from = pair.Args![0].ParseAddress(); + var pair2 = (pair.Args[1] as MichelinePrim)!; + var to = pair2.Args![0].ParseAddress(); + var value = (pair2.Args[1] as MichelineInt)!.Value; + + transfers.Add((from, to, BigInteger.Zero, value)); + } + return transfers; + } + } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/VotingCommit.cs deleted file mode 100644 index d8287d137..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Commits/VotingCommit.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class VotingCommit(ProtocolHandler protocol) : Proto8.VotingCommit(protocol) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Diagnostics/Diagnostics.cs deleted file mode 100644 index ed697aaca..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - class Diagnostics(ProtocolHandler handler) : Proto22.Diagnostics(handler) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Helpers.cs deleted file mode 100644 index 1cb8b6f42..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto24 -{ - public class Helpers(ProtocolHandler proto) : Proto18.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Proto24Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Proto24Handler.cs index d07ef536e..2fe648d3a 100644 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Proto24Handler.cs +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Proto24Handler.cs @@ -7,27 +7,23 @@ namespace Tzkt.Sync.Protocols { - class Proto24Handler : ProtocolHandler + class Proto24Handler( + TezosNode node, + TzktContext db, + CacheService cache, + QuotesService quotes, + IServiceProvider services, + IConfiguration config, + ILogger logger, + IMetrics metrics) : ProtocolHandler(node, db, cache, quotes, services, config, logger, metrics) { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } + public override IActivator Activator => new ProtoActivator(this); + public override IMigrator Migrator => new ProtoMigrator(this); + public override IValidator Validator => new Validator(this); + public override IRpc Rpc { get; } = new Rpc(node); public override string VersionName => "t024_024"; public override int VersionNumber => 24; - public Proto24Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - public override async Task Commit(JsonElement block) { await new StatisticsCommit(this).Apply(block); @@ -35,116 +31,21 @@ public override async Task Commit(JsonElement block) var blockCommit = new BlockCommit(this); await blockCommit.Apply(block); - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new SetDelegateParametersCommit(this).ActivateStakingParameters(blockCommit.Block); - await new UpdateSecondaryKeyCommit(this).ActivateSecondaryKeys(blockCommit.Block); - await new StakerCycleCommit(this).Apply(); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - #region implicit operations - foreach (var op in block - .Required("metadata") - .RequiredArray("implicit_operations_results") - .EnumerateArray() - .Where(x => x.RequiredString("kind") == "transaction")) - await new SubsidyCommit(this).Apply(blockCommit.Block, op); - #endregion - var operations = block.RequiredArray("operations", 4); #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "attestation": - case "attestation_with_dal": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "attestations_aggregate": - var attestations = new AttestationAggregateCommit(this).ExtractAttestations(operation, content); - foreach (var (opHash, baker, power) in attestations) - await new AttestationsCommit(this).Apply(blockCommit.Block, opHash, baker, power); - break; - case "preattestation": - case "preattestation_with_dal": - new PreattestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "preattestations_aggregate": - var preattestations = new PreattestationAggregateCommit(this).ExtractPreattestations(operation, content); - foreach (var (opHash, baker, power) in preattestations) - new PreattestationsCommit(this).Apply(blockCommit.Block, opHash, baker, power); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } + if (operations[0].EnumerateArray().Any()) + throw new NotImplementedException($"Consensus operations are not allowed"); #endregion #region operations 1 - var dictatorSeen = false; - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - var proposalsCommit = new ProposalsCommit(this); - await proposalsCommit.Apply(blockCommit.Block, operation, content); - dictatorSeen = proposalsCommit.DictatorSeen; - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - if (dictatorSeen) break; - } + if (operations[1].EnumerateArray().Any()) + throw new NotImplementedException($"Governance operations are not allowed"); #endregion #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_entrapment_evidence": - await new DalEntrapmentEvidenceCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_consensus_operation_evidence": - new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "vdf_revelation": - await new VdfRevelationCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "drain_delegate": - await new DrainDelegateCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } + if (operations[2].EnumerateArray().Any()) + throw new NotImplementedException($"Anonymous operations are not allowed"); #endregion var bigMapCommit = new BigMapCommit(this); @@ -158,25 +59,15 @@ public override async Task Commit(JsonElement block) { switch (content.RequiredString("kind")) { - case "set_deposits_limit": - await new SetDepositsLimitCommit(this).Apply(blockCommit.Block, operation, content); - break; case "increase_paid_storage": await new IncreasePaidStorageCommit(this).Apply(blockCommit.Block, operation, content); break; - case "update_consensus_key": - case "update_companion_key": - await new UpdateSecondaryKeyCommit(this).Apply(blockCommit.Block, operation, content); - break; case "reveal": await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); break; case "register_global_constant": await new RegisterConstantsCommit(this).Apply(blockCommit.Block, operation, content); break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; case "origination": var orig = new OriginationsCommit(this); await orig.Apply(blockCommit.Block, operation, content); @@ -184,21 +75,6 @@ public override async Task Commit(JsonElement block) bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); break; case "transaction": - var dst = content.RequiredString("destination"); - if (dst.StartsWith("tz") && content.Optional("parameters")?.RequiredString("entrypoint") is string entrypoint) - { - if (Proto18.StakingCommit.ValidateParameters(entrypoint, content.RequiredString("source"), dst)) - { - await new StakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - else if (Proto18.SetDelegateParametersCommit.Entrypoint == entrypoint) - { - await new SetDelegateParametersCommit(this).Apply(blockCommit.Block, operation, content); - break; - } - } - var parent = new TransactionsCommit(this); await parent.Apply(blockCommit.Block, operation, content); if (parent.BigMapDiffs != null) @@ -212,9 +88,6 @@ public override async Task Commit(JsonElement block) { switch (internalContent.RequiredString("kind")) { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; case "origination": var internalOrig = new OriginationsCommit(this); await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); @@ -230,7 +103,8 @@ public override async Task Commit(JsonElement block) ticketsCommit.Append(parent.Transaction, internalTx.Transaction, internalTx.TicketUpdates); break; case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); + if (internalContent.RequiredString("source") != NullAddress.Address) + await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); break; default: throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); @@ -258,7 +132,8 @@ public override async Task Commit(JsonElement block) ticketsCommit.Append(parent1.Operation, internalTx.Transaction, internalTx.TicketUpdates); break; case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); + if (internalContent.RequiredString("source") != NullAddress.Address) + await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); break; default: throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' inside 'transfer_ticket' is not expected"); @@ -266,67 +141,6 @@ public override async Task Commit(JsonElement block) } } break; - case "smart_rollup_add_messages": - await new SmartRollupAddMessagesCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_cement": - await new SmartRollupCementCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_execute_outbox_message": - var parent2 = new SmartRollupExecuteCommit(this); - await parent2.Apply(blockCommit.Block, operation, content); - if (parent2.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, parent2.Operation, parent2.TicketUpdates); - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult2)) - { - foreach (var internalContent in internalResult2.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent2.Operation, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - if (internalTx.TicketUpdates != null) - ticketsCommit.Append(parent2.Operation, internalTx.Transaction, internalTx.TicketUpdates); - break; - case "event": - await new ContractEventCommit(this).Apply(blockCommit.Block, internalContent); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - case "smart_rollup_originate": - await new SmartRollupOriginateCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_publish": - await new SmartRollupPublishCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_recover_bond": - await new SmartRollupRecoverBondCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_refute": - await new SmartRollupRefuteCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "smart_rollup_timeout": - await new SmartRollupTimeoutCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "dal_publish_commitment": - await new DalPublishCommitmentCommit(this).Apply(blockCommit.Block, operation, content); - break; default: throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); } @@ -335,57 +149,13 @@ public override async Task Commit(JsonElement block) } #endregion - await blockCommit.ApplyRewards(block); - - new InboxCommit(this).Apply(blockCommit.Block); - await bigMapCommit.Apply(); await ticketsCommit.Apply(); await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block, cycleCommit.FutureCycle, cycleCommit.SelectedStakes); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.Snapshots, - cycleCommit.SelectedStakes, - brCommit.CurrentRights); - - await new AttestationRewardCommit(this).Apply(blockCommit.Block, block); - await new DalAttestationRewardCommit(this).Apply(blockCommit.Block, block); await new StateCommit(this).Apply(blockCommit.Block, block); } - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SlashingCommit(this).Apply(block, rawBlock); - await new VotingCommit(this).Apply(block, rawBlock); - await new AutostakingCommit(this).Apply(block, rawBlock); - - Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - - await new DelegationSnapshotCommit(this).Apply(); - await new SnapshotBalanceCommit(this).Apply(); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(); - await new DelegationSnapshotCommit(this).Revert(); - await new AutostakingCommit(this).Revert(block); - await new VotingCommit(this).Revert(block); - await new SlashingCommit(this).Revert(block); - } - public override async Task Revert() { var currBlock = await Cache.Blocks.CurrentAsync(); @@ -393,89 +163,30 @@ public override async Task Revert() await new StatisticsCommit(this).Revert(currBlock); - await new DalAttestationRewardCommit(this).Revert(currBlock); - await new AttestationRewardCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); await new TokensCommit(this).Revert(currBlock); await new TicketsCommit(this).Revert(currBlock); await new BigMapCommit(this).Revert(currBlock); await new ContractEventCommit(this).Revert(currBlock); - await new InboxCommit(this).Revert(currBlock); - await new BlockCommit(this).RevertRewards(currBlock); foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) { switch (operation) { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case PreattestationOperation op: - await new PreattestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DalEntrapmentEvidenceOperation op: - new DalEntrapmentEvidenceCommit(this).Revert(op); - break; - case DoubleBakingOperation op: - new DoubleBakingCommit(this).Revert(op); - break; - case DoubleConsensusOperation op: - new DoubleConsensusCommit(this).Revert(op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case VdfRevelationOperation op: - await new VdfRevelationCommit(this).Revert(currBlock, op); - break; - case DrainDelegateOperation op: - await new DrainDelegateCommit(this).Revert(currBlock, op); - break; case RevealOperation op: await new RevealsCommit(this).Revert(currBlock, op); break; case IncreasePaidStorageOperation op: await new IncreasePaidStorageCommit(this).Revert(currBlock, op); break; - case UpdateSecondaryKeyOperation op: - await new UpdateSecondaryKeyCommit(this).Revert(currBlock, op); - break; case RegisterConstantOperation op: await new RegisterConstantsCommit(this).Revert(currBlock, op); break; - case SetDepositsLimitOperation op: - await new SetDepositsLimitCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; case OriginationOperation op: if (op.InitiatorId == null) await new OriginationsCommit(this).Revert(currBlock, op); else await new OriginationsCommit(this).RevertInternal(currBlock, op); break; - case StakingOperation op: - await new StakingCommit(this).Revert(currBlock, op); - break; - case SetDelegateParametersOperation op: - await new SetDelegateParametersCommit(this).Revert(currBlock, op); - break; case TransactionOperation op: if (op.InitiatorId == null) await new TransactionsCommit(this).Revert(currBlock, op); @@ -485,46 +196,14 @@ public override async Task Revert() case TransferTicketOperation op: await new TransferTicketCommit(this).Revert(currBlock, op); break; - case SmartRollupAddMessagesOperation op: - await new SmartRollupAddMessagesCommit(this).Revert(currBlock, op); - break; - case SmartRollupCementOperation op: - await new SmartRollupCementCommit(this).Revert(currBlock, op); - break; - case SmartRollupExecuteOperation op: - await new SmartRollupExecuteCommit(this).Revert(currBlock, op); - break; - case SmartRollupOriginateOperation op: - await new SmartRollupOriginateCommit(this).Revert(currBlock, op); - break; - case SmartRollupPublishOperation op: - await new SmartRollupPublishCommit(this).Revert(currBlock, op); - break; - case SmartRollupRecoverBondOperation op: - await new SmartRollupRecoverBondCommit(this).Revert(currBlock, op); - break; - case SmartRollupRefuteOperation op: - await new SmartRollupRefuteCommit(this).Revert(currBlock, op); - break; - case DalPublishCommitmentOperation op: - await new DalPublishCommitmentCommit(this).Revert(currBlock, op); - break; default: throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); } } - await new SubsidyCommit(this).Revert(currBlock); - - await new DeactivationCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new StakerCycleCommit(this).Revert(); - await new UpdateSecondaryKeyCommit(this).DeactivateSecondaryKeys(currBlock); - await new SetDelegateParametersCommit(this).DeactivateStakingParameters(currBlock); - await new CycleCommit(this).Revert(currBlock); new BlockCommit(this).Revert(currBlock); - await new StateCommit(this).Revert(currBlock); + await new StateCommit(this).Revert(); } } } diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/ProtoActivator.cs new file mode 100644 index 000000000..6f28688d6 --- /dev/null +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/ProtoActivator.cs @@ -0,0 +1,325 @@ +using Microsoft.EntityFrameworkCore; +using Netezos.Contracts; +using Netezos.Encoding; +using System.Text.Json; +using Tzkt.Data; +using Tzkt.Data.Models; +using Tzkt.Sync.Services; + +namespace Tzkt.Sync.Protocols.Proto24 +{ + public class ProtoActivator(ProtocolHandler proto) : IActivator + { + protected readonly ProtocolHandler Proto = proto; + protected readonly IRpc Rpc = proto.Rpc; + protected readonly TzktContext Db = proto.Db; + protected readonly CacheService Cache = proto.Cache; + protected readonly BlockContext Context = proto.Context; + protected readonly ILogger Logger = proto.Logger; + + public async Task ActivateContext(AppState state, JsonElement rawBlock) + { + var header = rawBlock.Required("header"); + var level = header.RequiredInt32("level"); + var timestamp = header.RequiredDateTime("timestamp"); + var protocolHash = rawBlock.RequiredString("protocol"); + + #region protocol + var constants = await Rpc.GetConstantsAsync(level); + var protocol = new Protocol + { + Id = 0, + Code = protocolHash == "PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i" ? -1 : 1, + Hash = protocolHash, + Version = Proto.VersionNumber, + FirstLevel = level, + LastLevel = -1, + FirstCycle = 0, + FirstCycleLevel = level, + + RampUpCycles = constants.OptionalInt32("security_deposit_ramp_up_cycles") ?? 0, + NoRewardCycles = constants.OptionalInt32("no_reward_cycles") ?? 0, + ByteCost = constants.OptionalInt32("cost_per_byte") ?? 250, + HardOperationGasLimit = constants.OptionalInt32("hard_gas_limit_per_operation") ?? 1_040_000, + HardOperationStorageLimit = constants.OptionalInt32("hard_storage_limit_per_operation") ?? 60_000, + OriginationSize = constants.OptionalInt32("origination_size") ?? 257, + BallotQuorumMin = constants.OptionalInt32("quorum_min") ?? 2000, + BallotQuorumMax = constants.OptionalInt32("quorum_max") ?? 7000, + ProposalQuorum = constants.OptionalInt32("min_proposal_quorum") ?? 500, + + BlocksPerCycle = constants.OptionalInt32("blocks_per_cycle") ?? 8192, + BlocksPerCommitment = constants.OptionalInt32("blocks_per_commitment") ?? 64, + + HardBlockGasLimit = constants.OptionalInt32("hard_gas_limit_per_block") ?? 5_200_000, + TimeBetweenBlocks = constants.OptionalInt32("minimal_block_delay") ?? 30, + + AttestersPerBlock = constants.OptionalInt32("consensus_committee_size") ?? 7000, + + MinParticipationNumerator = constants.Optional("minimal_participation_ratio")?.OptionalInt32("numerator") ?? 2, + MinParticipationDenominator = constants.Optional("minimal_participation_ratio")?.OptionalInt32("denominator") ?? 3, + + LBToggleThreshold = constants.OptionalInt32("liquidity_baking_toggle_ema_threshold") ?? 1_000_000_000, + BlocksPerVoting = (constants.OptionalInt32("cycles_per_voting_period") ?? 5) * (constants.OptionalInt32("blocks_per_cycle") ?? 8192), + Dictator = constants.OptionalString("testnet_dictator"), + MinimalStake = constants.OptionalInt64("minimal_stake") ?? 6_000_000L, + SmartRollupOriginationSize = constants.OptionalInt32("smart_rollup_origination_size") ?? 6_314, + SmartRollupStakeAmount = constants.OptionalInt64("smart_rollup_stake_amount") ?? 10_000_000_000L, + SmartRollupChallengeWindow = constants.OptionalInt32("smart_rollup_challenge_window_in_blocks") ?? 80_640, + SmartRollupCommitmentPeriod = constants.OptionalInt32("smart_rollup_commitment_period_in_blocks") ?? 60, + SmartRollupTimeoutPeriod = constants.OptionalInt32("smart_rollup_timeout_period_in_blocks") ?? 40_320, + + MinimalFrozenStake = constants.OptionalInt64("minimal_frozen_stake") ?? 600_000_000, + MaxDelegatedOverFrozenRatio = constants.OptionalInt32("limit_of_delegation_over_baking") ?? 9, + MaxExternalOverOwnStakeRatio = constants.OptionalInt32("global_limit_of_staking_over_baking") ?? 5, + StakePowerMultiplier = constants.OptionalInt32("edge_of_staking_over_delegation") ?? 2, + + BlockDeposit = 0, + BlockReward0 = 0, + BlockReward1 = 0, + MaxBakingReward = 0, + AttestationDeposit = 0, + AttestationReward0 = 0, + AttestationReward1 = 0, + MaxAttestationReward = 0, + + ConsensusRightsDelay = constants.OptionalInt32("consensus_rights_delay") ?? 2, + DelegateParametersActivationDelay = constants.OptionalInt32("delegate_parameters_activation_delay") ?? 5, + DoubleBakingSlashedPercentage = constants.OptionalInt32("percentage_of_frozen_deposits_slashed_per_double_baking") ?? 500, + DoubleConsensusSlashedPercentage = constants.OptionalInt32("percentage_of_frozen_deposits_slashed_per_double_attestation") ?? 5000, + NumberOfShards = constants.Optional("dal_parametric")?.OptionalInt32("number_of_shards") ?? 512, + BlocksPerSnapshot = constants.OptionalInt32("blocks_per_cycle") ?? 8192, + + ConsensusThreshold = constants.OptionalInt32("consensus_threshold_size") ?? 4667, + DenunciationPeriod = constants.OptionalInt32("denunciation_period") ?? 1, + SlashingDelay = constants.OptionalInt32("slashing_delay") ?? 1, + ToleratedInactivityPeriod = constants.OptionalInt32("tolerated_inactivity_period") ?? 2, + }; + + state.ProtocolsCount++; + + Db.Protocols.Add(protocol); + Cache.Protocols.Add(protocol); + Context.Protocol = protocol; + #endregion + + #region null-address + var nullAddress = new User + { + Id = Cache.AppState.NextAccountId(), + Address = NullAddress.Address, + Type = AccountType.User, + FirstLevel = level, + LastLevel = level, + Index = 0 + }; + + if (nullAddress.Id != NullAddress.Id) + throw new Exception("Failed to allocate null-address"); + + Cache.Accounts.Add(nullAddress); + Db.Accounts.Add(nullAddress); + #endregion + + #region accounts + var stats = new Statistics + { + Id = 0, + Level = level - 1 + }; + Cache.Statistics.SetCurrent(stats); + + var accounts = new List(); + var addresses = await Rpc.GetContractsAsync(level); + foreach (var address in addresses.EnumerateArray().Select(x => x.RequiredString())) + { + if (address.StartsWith("KT1")) + throw new NotImplementedException("Smart contracts bootstrap is not implemented"); + + var rawContract = await Rpc.GetContractAsync(level, address); + var rawKey = await Rpc.GetContractManagerKeyAsync(level, address); + + #region account + var user = new User + { + Id = Cache.AppState.NextAccountId(), + Address = address, + FirstLevel = level, + LastLevel = level, + Type = AccountType.User, + Balance = rawContract.RequiredInt64("balance"), + Counter = rawContract.RequiredInt32("counter"), + PublicKey = rawKey.OptionalString(), + Revealed = rawKey.OptionalString() != null + }; + + Cache.Accounts.Add(user); + Db.Accounts.Add(user); + #endregion + + #region migration + var migration = new MigrationOperation + { + Id = Cache.AppState.NextOperationId(), + Level = level, + Timestamp = timestamp, + AccountId = user.Id, + Kind = MigrationKind.Bootstrap, + BalanceChange = user.Balance, + }; + + user.MigrationsCount++; + state.MigrationOpsCount++; + stats.TotalBootstrapped += migration.BalanceChange; + + Db.MigrationOps.Add(migration); + Context.MigrationOps.Add(migration); + #endregion + } + #endregion + + #region precompiles + foreach (var address in Proto.Config.Precompiles ?? []) + { + var rawContract = await Proto.Rpc.GetContractAsync(level, address); + + var balance = rawContract.RequiredInt64("balance"); + var rawScript = rawContract.Required("script"); + var codeStr = rawScript.Required("code").GetRawText(); + var storageStr = rawScript.Required("storage").GetRawText(); + + #region contract + var creator = nullAddress; + var contract = new Contract + { + Id = Cache.AppState.NextAccountId(), + Address = address, + FirstLevel = level, + LastLevel = level, + Type = AccountType.Contract, + Kind = ContractKind.SmartContract, + Balance = balance, + CreatorId = creator.Id, + }; + + creator.ContractsCount++; + + Cache.Accounts.Add(contract); + Db.Accounts.Add(contract); + #endregion + + #region script + var code = (Micheline.FromJson(codeStr) as MichelineArray)!; + var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter); + var micheStorage = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage); + var micheCode = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code); + var micheViews = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view); + var script = new Script + { + Id = Cache.AppState.NextScriptId(), + Level = level, + ContractId = contract.Id, + ParameterSchema = micheParameter.ToBytes(), + StorageSchema = micheStorage.ToBytes(), + CodeSchema = micheCode.ToBytes(), + Views = micheViews.Any() + ? [.. micheViews.Select(x => x.ToBytes())] + : null, + Current = true + }; + + var viewsBytes = script.Views? + .OrderBy(x => x, new BytesComparer()) + .SelectMany(x => x) + .ToArray() + ?? []; + var typeSchema = script.ParameterSchema.Concat(script.StorageSchema).Concat(viewsBytes); + var fullSchema = typeSchema.Concat(script.CodeSchema); + contract.TypeHash = script.TypeHash = Script.GetHash(typeSchema); + contract.CodeHash = script.CodeHash = Script.GetHash(fullSchema); + + if (script.Schema.IsFA1()) + { + if (script.Schema.IsFA12()) + contract.Tags |= ContractTags.FA12; + + contract.Tags |= ContractTags.FA1; + contract.Kind = ContractKind.Asset; + } + if (script.Schema.IsFA2()) + { + contract.Tags |= ContractTags.FA2; + contract.Kind = ContractKind.Asset; + } + + Db.Scripts.Add(script); + Cache.Schemas.Add(contract, script.Schema); + #endregion + + #region storage + var storageValue = Micheline.FromJson(storageStr)!; + var storage = new Storage + { + Id = Cache.AppState.NextStorageId(), + Level = level, + ContractId = contract.Id, + RawValue = script.Schema.OptimizeStorage(storageValue, false).ToBytes(), + JsonValue = script.Schema.HumanizeStorage(storageValue), + Current = true + }; + + Db.Storages.Add(storage); + Cache.Storages.Add(contract, storage); + #endregion + + #region migration + var migration = new MigrationOperation + { + Id = Cache.AppState.NextOperationId(), + Level = level, + Timestamp = timestamp, + AccountId = contract.Id, + Kind = MigrationKind.Origination, + BalanceChange = contract.Balance, + ScriptId = script.Id, + StorageId = storage.Id + }; + + script.MigrationId = migration.Id; + storage.MigrationId = migration.Id; + + contract.MigrationsCount++; + + state.MigrationOpsCount++; + stats.TotalBootstrapped += migration.BalanceChange; + + Db.MigrationOps.Add(migration); + Context.MigrationOps.Add(migration); + #endregion + } + #endregion + } + + public async Task DeactivateContext(AppState state) + { + await Db.Database.ExecuteSqlRawAsync(""" + DELETE FROM "Protocols"; + DELETE FROM "Accounts"; + DELETE FROM "MigrationOps"; + DELETE FROM "Scripts"; + DELETE FROM "Storages"; + """); + + await Cache.Protocols.ResetAsync(); + await Cache.Accounts.ResetAsync(); + Cache.Schemas.Reset(); + Cache.Storages.Reset(); + + Cache.AppState.ReleaseOperationId(state.MigrationOpsCount); + state.ProtocolsCount = 0; + state.AccountCounter = 0; + state.MigrationOpsCount = 0; + state.ScriptCounter = 0; + state.StorageCounter = 0; + } + } +} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/ProtoMigrator.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/ProtoMigrator.cs new file mode 100644 index 000000000..28f1f6115 --- /dev/null +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/ProtoMigrator.cs @@ -0,0 +1,110 @@ +using Microsoft.EntityFrameworkCore; +using Tzkt.Data; +using Tzkt.Data.Models; +using Tzkt.Sync.Services; + +namespace Tzkt.Sync.Protocols.Proto24 +{ + public class ProtoMigrator(ProtocolHandler proto) : IMigrator + { + protected readonly ProtocolHandler Proto = proto; + protected readonly IRpc Rpc = proto.Rpc; + protected readonly TzktContext Db = proto.Db; + protected readonly CacheService Cache = proto.Cache; + protected readonly BlockContext Context = proto.Context; + protected readonly ILogger Logger = proto.Logger; + + public async Task MigrateContext(AppState state) + { + #region protocol + var prev = await Cache.Protocols.GetAsync(state.Protocol); + Db.TryAttach(prev); + prev.LastLevel = state.Level; + + var protocol = new Protocol + { + Id = 0, + Code = prev.Code + 1, + Hash = state.NextProtocol, + Version = Proto.VersionNumber, + FirstLevel = state.Level + 1, + LastLevel = -1, + FirstCycle = prev.FirstCycle, + FirstCycleLevel = prev.FirstCycleLevel, + RampUpCycles = prev.RampUpCycles, + NoRewardCycles = prev.NoRewardCycles, + BlockDeposit = prev.BlockDeposit, + BlockReward0 = prev.BlockReward0, + BlockReward1 = prev.BlockReward1, + BlocksPerCommitment = prev.BlocksPerCommitment, + BlocksPerCycle = prev.BlocksPerCycle, + BlocksPerSnapshot = prev.BlocksPerSnapshot, + BlocksPerVoting = prev.BlocksPerVoting, + ByteCost = prev.ByteCost, + AttestationDeposit = prev.AttestationDeposit, + AttestationReward0 = prev.AttestationReward0, + AttestationReward1 = prev.AttestationReward1, + AttestersPerBlock = prev.AttestersPerBlock, + HardBlockGasLimit = prev.HardBlockGasLimit, + HardOperationGasLimit = prev.HardOperationGasLimit, + HardOperationStorageLimit = prev.HardOperationStorageLimit, + OriginationSize = prev.OriginationSize, + ConsensusRightsDelay = prev.ConsensusRightsDelay, + ToleratedInactivityPeriod = prev.ToleratedInactivityPeriod, + TimeBetweenBlocks = prev.TimeBetweenBlocks, + MinimalStake = prev.MinimalStake, + BallotQuorumMin = prev.BallotQuorumMin, + BallotQuorumMax = prev.BallotQuorumMax, + ProposalQuorum = prev.ProposalQuorum, + LBToggleThreshold = prev.LBToggleThreshold, + ConsensusThreshold = prev.ConsensusThreshold, + MaxDelegatedOverFrozenRatio = prev.MaxDelegatedOverFrozenRatio, + MaxExternalOverOwnStakeRatio = prev.MaxExternalOverOwnStakeRatio, + DoubleBakingSlashedPercentage = prev.DoubleBakingSlashedPercentage, + DoubleConsensusSlashedPercentage = prev.DoubleConsensusSlashedPercentage, + MinimalFrozenStake = prev.MinimalFrozenStake, + StakePowerMultiplier = prev.StakePowerMultiplier, + MaxBakingReward = prev.MaxBakingReward, + MaxAttestationReward = prev.MaxAttestationReward, + DenunciationPeriod = prev.DenunciationPeriod, + SlashingDelay = prev.SlashingDelay, + MinParticipationDenominator = prev.MinParticipationDenominator, + MinParticipationNumerator = prev.MinParticipationNumerator, + Dictator = prev.Dictator, + SmartRollupChallengeWindow = prev.SmartRollupChallengeWindow, + SmartRollupCommitmentPeriod = prev.SmartRollupCommitmentPeriod, + SmartRollupOriginationSize = prev.SmartRollupOriginationSize, + SmartRollupStakeAmount = prev.SmartRollupStakeAmount, + SmartRollupTimeoutPeriod = prev.SmartRollupTimeoutPeriod, + DelegateParametersActivationDelay = prev.DelegateParametersActivationDelay, + NumberOfShards = prev.NumberOfShards + }; + + state.ProtocolsCount++; + + Db.Protocols.Add(protocol); + Cache.Protocols.Add(protocol); + Context.Protocol = protocol; + #endregion + } + + public async Task RevertContext(AppState state) + { + #region protocol + var current = await Cache.Protocols.GetAsync(state.NextProtocol); + await Db.Database.ExecuteSqlRawAsync(""" + DELETE FROM "Protocols" + WHERE "Code" = {0} + """, current.Code); + + state.ProtocolsCount--; + + var prev = await Cache.Protocols.GetAsync(state.Protocol); + Db.TryAttach(prev); + prev.LastLevel = -1; + + await Cache.Protocols.ResetAsync(); + #endregion + } + } +} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Rpc.cs new file mode 100644 index 000000000..52c044e9b --- /dev/null +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Rpc.cs @@ -0,0 +1,27 @@ +using System.Text.Json; +using Tzkt.Sync.Services; + +namespace Tzkt.Sync.Protocols.Proto24 +{ + class Rpc(TezosNode node) : IRpc + { + protected readonly TezosNode Node = node; + + #region indexer + public virtual Task GetBlockAsync(int level) + => Node.GetAsync($"chains/main/blocks/{level}"); + + public virtual Task GetContractAsync(int level, string address) + => Node.GetAsync($"chains/main/blocks/{level}/context/contracts/{address}"); + + public virtual Task GetContractManagerKeyAsync(int level, string address) + => Node.GetAsync($"chains/main/blocks/{level}/context/contracts/{address}/manager_key"); + + public virtual Task GetConstantsAsync(int level) + => Node.GetAsync($"chains/main/blocks/{level}/context/constants"); + + public virtual Task GetContractsAsync(int level) + => Node.GetAsync($"chains/main/blocks/{level}/context/contracts"); + #endregion + } +} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Rpc/Rpc.cs deleted file mode 100644 index 02e53a69d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Rpc/Rpc.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - class Rpc(TezosNode node) : Proto22.Rpc(node) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Validation/Validator.cs deleted file mode 100644 index fbd6ba395..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto24/Validation/Validator.cs +++ /dev/null @@ -1,1080 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto24 -{ - class Validator(ProtocolHandler protocol) : IValidator - { - readonly CacheService Cache = protocol.Cache; - Protocol Protocol = null!; - string Proposer = null!; - string Producer = null!; - int Level; - int Cycle; - - 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.RequiredString())) - 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 - - #region aba activation level - var state = Cache.AppState.Get(); - var abaLevel = metadata.Optional("all_bakers_attest_activation_level")?.RequiredInt32("level"); - if (abaLevel != state.AbaActivationLevel && abaLevel < Level) - throw new ValidationException("invalid ABA activation level"); - #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 "attestations_aggregate": ValidateAttestationsAggregate(content); break; - case "preattestation": ValidatePreattestation(content); break; - case "preattestation_with_dal": ValidatePreattestation(content); break; - case "preattestations_aggregate": ValidatePreattestationsAggregate(content); break; - case "ballot": await ValidateBallot(content); break; - case "proposals": ValidateProposal(content); break; - case "activate_account": await ValidateActivation(content); break; - case "dal_entrapment_evidence": ValidateDalEntrapmentEvidence(content); break; - case "double_baking_evidence": ValidateDoubleBaking(content); break; - case "double_consensus_operation_evidence": ValidateDoubleConsensus(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 ValidateUpdateSecondaryKey(content); break; - case "update_companion_key": await ValidateUpdateSecondaryKey(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 ValidateAttestationsAggregate(JsonElement content) - { - if (content.Required("consensus_content").RequiredInt32("level") != Cache.AppState.GetLevel()) - throw new ValidationException("invalid attestations aggregate level"); - - var committee = content.RequiredArray("committee").EnumerateArray(); - if (!committee.Any()) - throw new ValidationException("invalid attestations aggregate committee size"); - - var metaCommittee = content.Required("metadata").RequiredArray("committee").EnumerateArray(); - if (committee.Count() != metaCommittee.Count()) - throw new ValidationException("invalid attestations aggregate committee metadata size"); - - foreach (var c in metaCommittee) - if (!Cache.Accounts.DelegateExists(c.RequiredString("delegate"))) - throw new ValidationException("unknown attestations aggregate 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 void ValidatePreattestationsAggregate(JsonElement content) - { - if (content.Required("consensus_content").RequiredInt32("level") != Cache.AppState.GetLevel() + 1) - throw new ValidationException("invalid preattestations aggregate level"); - - var committee = content.RequiredArray("committee").EnumerateArray(); - if (!committee.Any()) - throw new ValidationException("invalid preattestations aggregate committee size"); - - var metaCommittee = content.Required("metadata").RequiredArray("committee").EnumerateArray(); - if (committee.Count() != metaCommittee.Count()) - throw new ValidationException("invalid preattestations aggregate committee metadata size"); - - foreach (var c in metaCommittee) - if (!Cache.Accounts.DelegateExists(c.RequiredString("delegate"))) - throw new ValidationException("unknown preattestations aggregate 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 ValidateDalEntrapmentEvidence(JsonElement content) - { - } - - protected virtual void ValidateDoubleBaking(JsonElement content) - { - } - - protected virtual void ValidateDoubleConsensus(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() ?? [], - 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() ?? [], - 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() ?? [], - source, - content.RequiredInt64("fee")); - - var result = metadata.Required("operation_result"); - var applied = result.RequiredString("status") == "applied"; - - if (applied) - { - var target = content.RequiredString("destination"); - - if (target.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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - source, - content.RequiredInt64("fee")); - } - - protected virtual async Task ValidateUpdateSecondaryKey(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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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() ?? [], - 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"); - } - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto24/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto24/Validator.cs new file mode 100644 index 000000000..1fe8532a5 --- /dev/null +++ b/Tzkt.Sync/Protocols/Handlers/Proto24/Validator.cs @@ -0,0 +1,27 @@ +using System.Text.Json; +using Tzkt.Sync.Services; + +namespace Tzkt.Sync.Protocols.Proto24 +{ + class Validator(ProtocolHandler protocol) : IValidator + { + readonly CacheService Cache = protocol.Cache; + + public virtual async Task ValidateBlock(JsonElement block) + { + 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); + + var header = block.Required("header"); + + if (header.RequiredInt32("level") != Cache.AppState.GetNextLevel()) + throw new ValidationException($"invalid block level", true); + + if (header.RequiredString("predecessor") != Cache.AppState.GetHead() && Cache.AppState.GetHead() != string.Empty) + throw new ValidationException($"invalid block predecessor", true); + } + } +} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Activation/ProtoActivator.cs deleted file mode 100644 index 3e28660e6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Activation/ProtoActivator.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto3 -{ - class ProtoActivator : Proto1.ProtoActivator - { - public ProtoActivator(ProtocolHandler proto) : base(proto) { } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.OriginationSize = parameters["origination_size"]?.Value() ?? 257; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BakerCycleCommit.cs deleted file mode 100644 index a3b4f22a0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,338 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto3 -{ - class BakerCycleCommit(ProtocolHandler protocol) : Proto1.BakerCycleCommit(protocol) - { - public override async Task Apply( - Block block, - Cycle? futureCycle, - IEnumerable? futureBakingRights, - IEnumerable? futureAttestationRights, - List? snapshots, - List currentRights) - { - #region current rights - var prevBlock = await Cache.Blocks.CurrentAsync(); - var prevBakingRights = prevBlock.Level == 1 ? [] - : await Cache.BakingRights.GetAsync(prevBlock.Level); - - foreach (var rights in currentRights.GroupBy(x => x.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, rights.Key); - Db.TryAttach(bakerCycle); - - var bakingRights = rights - .Where(x => x.Type == BakingRightType.Baking) - .OrderBy(x => x.Round) - .ToList(); - - var attestationRight = rights - .FirstOrDefault(x => x.Type == BakingRightType.Attestation); - - #region rights and deposits - foreach (var br in bakingRights) - { - if (br.Round == 0) - { - bakerCycle.FutureBlocks--; - } - - if (br.Status == BakingRightStatus.Realized) - { - bakerCycle.Blocks++; - } - else if (br.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlocks++; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - - if (attestationRight != null) - { - bakerCycle.FutureAttestations -= attestationRight.Slots!.Value; - - if (attestationRight.Status == BakingRightStatus.Realized) - { - bakerCycle.Attestations += attestationRight.Slots!.Value; - } - else if (attestationRight.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedAttestations += attestationRight.Slots!.Value; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - - #region attestation rewards - if (attestationRight != null) - { - bakerCycle.FutureAttestationRewards -= GetFutureAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots!.Value); - - var successReward = GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, prevBlock.BlockRound); - - var prevRights = prevBakingRights - .Where(x => x.Type == BakingRightType.Baking && x.BakerId == rights.Key) - .OrderBy(x => x.Round) - .ToList(); - - var maxReward = prevRights.FirstOrDefault()?.Status > BakingRightStatus.Realized - ? GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, prevRights[0].Round!.Value) - : successReward; - - if (attestationRight.Status == BakingRightStatus.Realized) - bakerCycle.AttestationRewardsDelegated += successReward; - else if (attestationRight.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestationRewards += successReward; - else - throw new Exception("Unexpected future rights"); - - if (maxReward != successReward) - { - var prevBakerCycle = await Cache.BakerCycles.GetAsync(prevBlock.Cycle, rights.Key); - Db.TryAttach(prevBakerCycle); - - prevBakerCycle.MissedBlockRewards += maxReward - successReward; - } - } - #endregion - - #region baking rewards - if (bakingRights.Count > 0) - { - if (bakingRights[0].Round == 0) - bakerCycle.FutureBlockRewards -= GetFutureBlockReward(Context.Protocol, block.Cycle); - - var successReward = GetBlockReward(Context.Protocol, block.Cycle); - - var actualReward = bakingRights[^1].Status == BakingRightStatus.Realized - ? GetBlockReward(Context.Protocol, block.Cycle) - : 0; - - //var maxReward = attestationRight?.Status > BakingRightStatus.Realized - // ? GetBlockReward(Context.Protocol, bakingRights[0].Round!.Value, block.AttestationPower + attestationRight.Slots.Value) - // : successReward; - - if (actualReward > 0) - { - bakerCycle.BlockRewardsDelegated += actualReward; - } - - if (successReward != actualReward) - { - bakerCycle.MissedBlockRewards += successReward - actualReward; - } - - //if (maxReward != successReward) - //{ - // bakerCycle.MissedAttestationRewards += maxReward - successReward; - //} - } - #endregion - - #region fees - if (bakingRights.Count > 0) - { - if (bakingRights[^1].Status == BakingRightStatus.Realized) - { - bakerCycle.BlockFees += block.Fees; - } - else if (bakingRights[0].Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlockFees += block.Fees; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - } - - foreach (var op in Context.DoubleBakingOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleBakingLostStaked += op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleBakingRewards += op.Reward; - } - - foreach (var op in Context.DoubleConsensusOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleConsensusLostStaked += op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleConsensusRewards += op.Reward; - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.NonceRevelationRewardsDelegated += op.RewardDelegated; - } - - foreach (var op in Context.RevelationPenaltyOps) - { - var penaltyBlock = await Cache.Blocks.GetAsync(op.MissedLevel); - var penaltyCycle = await Cache.BakerCycles.GetAsync(penaltyBlock.Cycle, op.BakerId); - Db.TryAttach(penaltyCycle); - - penaltyCycle.NonceRevelationLosses += op.Loss; - } - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var bakerCycles = snapshots!.ToDictionary( - snapshot => Cache.Accounts.GetDelegate(snapshot.AccountId).Address, - snapshot => - { - var bakingPower = snapshot.StakingBalance - snapshot.StakingBalance % Context.Protocol.MinimalStake; - var share = (double)bakingPower / futureCycle!.TotalBakingPower; - - var bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = snapshot.AccountId, - OwnDelegatedBalance = snapshot.OwnDelegatedBalance, - ExternalDelegatedBalance = snapshot.ExternalDelegatedBalance!.Value, - DelegatorsCount = snapshot.DelegatorsCount!.Value, - OwnStakedBalance = snapshot.OwnStakedBalance ?? 0, - ExternalStakedBalance = snapshot.ExternalStakedBalance ?? 0, - StakersCount = snapshot.StakersCount ?? 0, - IssuedPseudotokens = snapshot.Pseudotokens, - BakingPower = bakingPower, - TotalBakingPower = futureCycle.TotalBakingPower, - ExpectedBlocks = Context.Protocol.BlocksPerCycle * share, - ExpectedAttestations = Context.Protocol.AttestersPerBlock * Context.Protocol.BlocksPerCycle * share - }; - - return bakerCycle; - }); - - #region future baking rights - foreach (var br in futureBakingRights!) - { - if (br.RequiredInt32("priority") > 0) - continue; - - if (!bakerCycles.TryGetValue(br.RequiredString("delegate"), out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += GetFutureBlockReward(Context.Protocol, futureCycle!.Index); - } - #endregion - - #region future attestation rights - var skipLevel = futureAttestationRights!.Last().RequiredInt32("level"); - - foreach (var ar in futureAttestationRights!.TakeWhile(x => x.RequiredInt32("level") < skipLevel)) - { - if (!bakerCycles.TryGetValue(ar.RequiredString("delegate"), out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - var slots = ar.RequiredArray("slots").Count(); - - bakerCycle.FutureAttestations += slots; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, futureCycle!.Index, slots); - } - #endregion - - #region shifted future attestation rights - // TODO: cache shifted rights - var shiftedRights = await Db.BakingRights.AsNoTracking() - .Where(x => x.Level == futureCycle!.FirstLevel && x.Type == BakingRightType.Attestation) - .ToListAsync(); - - foreach (var ar in shiftedRights) - { - var baker = Cache.Accounts.GetDelegate(ar.BakerId); - if (!bakerCycles.TryGetValue(baker.Address, out var bakerCycle)) - { - #region shifting hack - //shifting is actually a bad idea, but this is the lesser of two evils while Tezos protocol has bugs in the freezer. - var snapshottedBaker = await Proto.Rpc.GetDelegateAsync(futureCycle!.SnapshotLevel, baker.Address); - var delegators = snapshottedBaker - .RequiredArray("delegated_contracts") - .EnumerateArray() - .Select(x => x.RequiredString()) - .Where(x => x != baker.Address); - - if (snapshottedBaker.RequiredInt32("grace_period") != block.Cycle - 3) - throw new Exception("Deactivated baker got baking rights"); - - var stakingBalance = snapshottedBaker.RequiredInt64("staking_balance"); - var delegatedBalance = snapshottedBaker.RequiredInt64("delegated_balance"); - - bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = baker.Id, - OwnDelegatedBalance = stakingBalance - delegatedBalance, - ExternalDelegatedBalance = delegatedBalance, - DelegatorsCount = delegators.Count(), - OwnStakedBalance = 0, - ExternalStakedBalance = 0, - StakersCount = 0, - IssuedPseudotokens = null, - BakingPower = 0, - TotalBakingPower = futureCycle.TotalBakingPower, - ExpectedBlocks = 0, - ExpectedAttestations = 0 - }; - bakerCycles.Add(baker.Address, bakerCycle); - - foreach (var delegatorAddress in delegators) - { - var snapshottedDelegator = await Proto.Rpc.GetContractAsync(futureCycle.SnapshotLevel, delegatorAddress); - Db.DelegatorCycles.Add(new DelegatorCycle - { - Id = 0, - Cycle = futureCycle.Index, - DelegatorId = (await Cache.Accounts.GetExistingAsync(delegatorAddress)).Id, - BakerId = baker.Id, - DelegatedBalance = snapshottedDelegator.RequiredInt64("balance"), - StakedPseudotokens = null - }); - } - #endregion - } - - bakerCycle.FutureAttestations += ar.Slots!.Value; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, futureCycle!.Index, (int)ar.Slots); - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - } - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BakingRightsCommit.cs deleted file mode 100644 index 94c3d97f0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,146 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Npgsql; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto3 -{ - class BakingRightsCommit(ProtocolHandler protocol) : Proto1.BakingRightsCommit(protocol) - { - public override async Task Apply(Block block) - { - #region current rights - CurrentRights = await Cache.BakingRights.GetAsync(block.Level); - var sql = string.Empty; - - if (block.BlockRound == 0 && block.AttestationPower == block.AttestationCommittee) - { - CurrentRights.RemoveAll(x => x.Type == BakingRightType.Baking && x.Round > 0); - CurrentRights.ForEach(x => x.Status = BakingRightStatus.Realized); - - sql = $@" - DELETE FROM ""BakingRights"" - WHERE ""Level"" = {block.Level} - AND ""Type"" = {(int)BakingRightType.Baking} - AND ""Round"" > 0; - - UPDATE ""BakingRights"" - SET ""Status"" = {(int)BakingRightStatus.Realized} - WHERE ""Level"" = {block.Level};"; - } - else - { - #region load missed rounds - var maxExistedRound = CurrentRights - .Where(x => x.Type == BakingRightType.Baking) - .Select(x => x.Round) - .Max(); - - if (maxExistedRound < block.BlockRound) - { - var bakingRights = await Proto.Rpc.GetLevelBakingRightsAsync(block.Level - 1, block.Level, block.BlockRound); - //bakingRights = bakingRights.OrderBy(x => x.Round); - - var sqlInsert = @" - INSERT INTO ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") VALUES "; - - foreach (var br in bakingRights.EnumerateArray().SkipWhile(x => x.RequiredInt32("priority") <= maxExistedRound)) - sqlInsert += $@" - ({block.Cycle}, {block.Level}, {Cache.Accounts.GetExistingDelegate(br.RequiredString("delegate")).Id}, {(int)BakingRightType.Baking}, {(int)BakingRightStatus.Future}, {br.RequiredInt32("priority")}, null),"; - - await Db.Database.ExecuteSqlRawAsync(sqlInsert[..^1]); - - //TODO: execute sql with RETURNS to get identity - var addedRights = await Db.BakingRights - .Where(x => x.Level == block.Level && x.Type == BakingRightType.Baking && x.Round > maxExistedRound) - .ToListAsync(); - - CurrentRights.AddRange(addedRights); - } - #endregion - - #region remove excess - if (CurrentRights.RemoveAll(x => x.Type == BakingRightType.Baking && x.Round > block.BlockRound) > 0) - { - sql += $@" - DELETE FROM ""BakingRights"" - WHERE ""Level"" = {block.Level} - AND ""Type"" = {(int)BakingRightType.Baking} - AND ""Round"" > {block.BlockRound};"; - } - #endregion - - foreach (var cr in CurrentRights) - cr.Status = BakingRightStatus.Missed; - - CurrentRights.First(x => x.Round == block.BlockRound).Status = BakingRightStatus.Realized; - - if (Context.AttestationOps.Count != 0) - { - var attesters = new HashSet(Context.AttestationOps.Select(x => x.DelegateId)); - foreach (var ar in CurrentRights.Where(x => x.Type == BakingRightType.Attestation && attesters.Contains(x.BakerId))) - ar.Status = BakingRightStatus.Realized; - } - - var realized = CurrentRights.Where(x => x.Status == BakingRightStatus.Realized); - var missed = CurrentRights.Where(x => x.Status == BakingRightStatus.Missed); - - sql += $@" - UPDATE ""BakingRights"" - SET ""Status"" = {(int)BakingRightStatus.Realized} - WHERE ""Level"" = {block.Level} - AND ""Id"" = ANY(ARRAY[{string.Join(',', realized.Select(x => x.Id))}]);"; - - if (missed.Any()) - { - sql += $@" - UPDATE ""BakingRights"" - SET ""Status"" = {(int)BakingRightStatus.Missed} - WHERE ""Level"" = {block.Level} - AND ""Id"" = ANY(ARRAY[{string.Join(',', missed.Select(x => x.Id))}]);"; - } - } - - await Db.Database.ExecuteSqlRawAsync(sql); - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var futureCycle = block.Cycle + Context.Protocol.ConsensusRightsDelay; - - FutureBakingRights = await GetBakingRights(block, Context.Protocol, futureCycle); - FutureAttestationRights = await GetAttestationRights(block, Context.Protocol, futureCycle); - - var conn = (Db.Database.GetDbConnection() as NpgsqlConnection)!; - using var writer = conn.BeginBinaryImport(@"COPY ""BakingRights"" (""Cycle"", ""Level"", ""BakerId"", ""Type"", ""Status"", ""Round"", ""Slots"") FROM STDIN (FORMAT BINARY)"); - - foreach (var ar in FutureAttestationRights) - { - writer.StartRow(); - writer.Write(Context.Protocol.GetCycle(ar.RequiredInt32("level") + 1), NpgsqlTypes.NpgsqlDbType.Integer); // level + 1 (shifted) - writer.Write(ar.RequiredInt32("level") + 1, NpgsqlTypes.NpgsqlDbType.Integer); // level + 1 (shifted) - writer.Write(Cache.Accounts.GetExistingDelegate(ar.RequiredString("delegate")).Id, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Attestation, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - writer.Write(ar.RequiredArray("slots").Count(), NpgsqlTypes.NpgsqlDbType.Integer); - } - - foreach (var br in FutureBakingRights) - { - writer.StartRow(); - writer.Write(futureCycle, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.RequiredInt32("level"), NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(Cache.Accounts.GetExistingDelegate(br.RequiredString("delegate")).Id, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightType.Baking, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write((int)BakingRightStatus.Future, NpgsqlTypes.NpgsqlDbType.Integer); - writer.Write(br.RequiredInt32("priority"), NpgsqlTypes.NpgsqlDbType.Integer); - writer.WriteNull(); - } - - writer.Complete(); - } - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BigMapCommit.cs deleted file mode 100644 index 90650d1ff..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BlockCommit.cs deleted file mode 100644 index acc460917..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class BlockCommit : Proto1.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/CycleCommit.cs deleted file mode 100644 index 1457b1421..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/DeactivationCommit.cs deleted file mode 100644 index d9034886c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 01426a41c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto3 -{ - class DelegatorCycleCommit(ProtocolHandler protocol) : Proto1.DelegatorCycleCommit(protocol) - { - public override async Task Apply(Block block, Cycle? futureCycle) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin)) - return; - - await CreateFromSnapshots(futureCycle!); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/FreezerCommit.cs deleted file mode 100644 index 573634873..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class FreezerCommit : Proto1.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index da245be24..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 5cac927d4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index ba8ff5e38..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto3 -{ - class BallotsCommit : ProtocolCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var period = await Cache.Periods.GetAsync(content.RequiredInt32("period")); - var proposal = await Cache.Proposals.GetAsync(period.Epoch, content.RequiredString("proposal")); - var sender = Cache.Accounts.GetExistingDelegate(content.RequiredString("source")); - - var snapshot = await Db.VotingSnapshots - .FirstOrDefaultAsync(x => x.Period == period.Index && x.BakerId == sender.Id) - ?? throw new ValidationException("Ballot sender is not on the voters list"); - - var ballot = new BallotOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - SenderId = sender.Id, - VotingPower = snapshot.VotingPower, - Epoch = period.Epoch, - Period = period.Index, - ProposalId = proposal.Id, - Vote = content.RequiredString("ballot") switch - { - "yay" => Vote.Yay, - "nay" => Vote.Nay, - "pass" => Vote.Pass, - _ => throw new Exception("invalid ballot value") - } - }; - #endregion - - #region entities - //Db.TryAttach(block); - Db.TryAttach(period); - Db.TryAttach(proposal); - Db.TryAttach(sender); - //Db.TryAttach(snapshot); - #endregion - - #region apply operation - if (ballot.Vote == Vote.Yay) - { - period.YayBallots++; - period.YayVotingPower += ballot.VotingPower; - snapshot.Status = VoterStatus.VotedYay; - } - else if (ballot.Vote == Vote.Nay) - { - period.NayBallots++; - period.NayVotingPower += ballot.VotingPower; - snapshot.Status = VoterStatus.VotedNay; - } - else - { - period.PassBallots++; - period.PassVotingPower += ballot.VotingPower; - snapshot.Status = VoterStatus.VotedPass; - } - - sender.BallotsCount++; - - block.Operations |= Operations.Ballots; - - Cache.AppState.Get().BallotOpsCount++; - #endregion - - Db.BallotOps.Add(ballot); - Context.BallotOps.Add(ballot); - } - - public virtual async Task Revert(Block block, BallotOperation ballot) - { - #region entities - var sender = Cache.Accounts.GetDelegate(ballot.SenderId); - - var snapshot = await Db.VotingSnapshots - .FirstAsync(x => x.Period == ballot.Period && x.BakerId == ballot.SenderId); - - var period = await Cache.Periods.GetAsync(ballot.Period); - - Db.TryAttach(sender); - Db.TryAttach(period); - #endregion - - #region revert operation - if (ballot.Vote == Vote.Yay) - { - period.YayBallots--; - period.YayVotingPower -= ballot.VotingPower; - snapshot.Status = VoterStatus.None; - } - else if (ballot.Vote == Vote.Nay) - { - period.NayBallots--; - period.NayVotingPower -= ballot.VotingPower; - snapshot.Status = VoterStatus.None; - } - else - { - period.PassBallots--; - period.PassVotingPower -= ballot.VotingPower; - snapshot.Status = VoterStatus.None; - } - - sender.BallotsCount--; - - Cache.AppState.Get().BallotOpsCount--; - #endregion - - Db.BallotOps.Remove(ballot); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 1a38ac3f5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 242c0cb1b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 11547c08f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 1c87ad52c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class OriginationsCommit : Proto1.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index ece0d870c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto3 -{ - class ProposalsCommit : ProtocolCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - - public virtual async Task Apply(Block block, JsonElement op, JsonElement content) - { - var period = await Cache.Periods.GetAsync(content.RequiredInt32("period")); - Db.TryAttach(period); - var sender = Cache.Accounts.GetExistingDelegate(content.RequiredString("source")); - Db.TryAttach(sender); - - var snapshot = await Db.VotingSnapshots - .FirstOrDefaultAsync(x => x.Period == period.Index && x.BakerId == sender.Id) - ?? throw new ValidationException("Proposal sender is not on the voters list"); - - foreach (var proposalHash in content.RequiredArray("proposals").EnumerateArray()) - { - var proposal = await Cache.Proposals.GetOrCreateAsync(period.Epoch, proposalHash.RequiredString(), () => new Proposal - { - Id = Cache.AppState.NextProposalId(), - Hash = proposalHash.RequiredString(), - Epoch = period.Epoch, - FirstPeriod = period.Index, - LastPeriod = period.Index, - InitiatorId = sender.Id, - Status = ProposalStatus.Active - }); - - if (proposal.Upvotes == 0) - Db.Proposals.Add(proposal); - else - Db.TryAttach(proposal); - - var duplicated = Context.ProposalOps.Any(x => x.Period == period.Index && x.SenderId == sender.Id && x.ProposalId == proposal.Id); - if (!duplicated) duplicated = await Db.ProposalOps.AnyAsync(x => x.Period == period.Index && x.SenderId == sender.Id && x.ProposalId == proposal.Id); - - var proposalOp = new ProposalOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - SenderId = sender.Id, - VotingPower = snapshot.VotingPower, - Duplicated = duplicated, - Epoch = period.Epoch, - Period = period.Index, - ProposalId = proposal.Id, - }; - - #region apply operation - if (!proposalOp.Duplicated) - { - if (proposal.Upvotes == 0) - { - period.ProposalsCount++; - } - - proposal.Upvotes++; - proposal.VotingPower += proposalOp.VotingPower; - - if (proposal.VotingPower > period.TopVotingPower) - { - period.TopUpvotes = proposal.Upvotes; - period.TopVotingPower = proposal.VotingPower; - period.SingleWinner = true; - } - else if (proposal.VotingPower == period.TopVotingPower) - { - period.SingleWinner = false; - } - - snapshot.Status = VoterStatus.Upvoted; - } - - sender.ProposalsCount++; - - block.Operations |= Operations.Proposals; - - Cache.AppState.Get().ProposalOpsCount++; - #endregion - - Db.ProposalOps.Add(proposalOp); - Context.ProposalOps.Add(proposalOp); - } - } - - public virtual async Task Revert(Block block, ProposalOperation proposalOp) - { - #region entities - var sender = Cache.Accounts.GetDelegate(proposalOp.SenderId); - var proposal = await Cache.Proposals.GetAsync(proposalOp.ProposalId); - - var snapshot = await Db.VotingSnapshots - .FirstAsync(x => x.Period == proposalOp.Period && x.BakerId == proposalOp.SenderId); - - var period = await Cache.Periods.GetAsync(proposalOp.Period); - - Db.TryAttach(period); - Db.TryAttach(sender); - Db.TryAttach(proposal); - #endregion - - #region revert operation - if (!proposalOp.Duplicated) - { - proposal.Upvotes--; - proposal.VotingPower -= proposalOp.VotingPower; - - if (period.ProposalsCount > 1) - { - var proposals = await Db.Proposals - .Where(x => x.Epoch == period.Epoch) - .ToListAsync(); - - var prevMax = proposals - .OrderByDescending(x => x.VotingPower) - .First(); - - period.TopUpvotes = prevMax.Upvotes; - period.TopVotingPower = prevMax.VotingPower; - period.SingleWinner = proposals.Count(x => x.VotingPower == period.TopVotingPower) == 1; - } - else - { - period.TopUpvotes = proposal.Upvotes; - period.TopVotingPower = proposal.VotingPower; - period.SingleWinner = proposal.VotingPower > 0; - } - - if (proposal.Upvotes == 0) - { - period.ProposalsCount--; - } - - if (!await Db.ProposalOps.AnyAsync(x => x.Period == period.Index && x.SenderId == sender.Id && x.Id < proposalOp.Id)) - snapshot.Status = VoterStatus.None; - } - - sender.ProposalsCount--; - - Cache.AppState.Get().ProposalOpsCount--; - #endregion - - if (proposal.Upvotes == 0) - { - Db.Proposals.Remove(proposal); - Cache.Proposals.Remove(proposal); - Cache.AppState.ReleaseProposalId(); - } - - Db.ProposalOps.Remove(proposalOp); - Cache.AppState.ReleaseOperationId(); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 059e4c9ff..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 26d419a67..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto3 -{ - class TransactionsCommit : Proto2.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override bool HasAllocated(JsonElement result) => result.OptionalBool("allocated_destination_contract") ?? false; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index dea7b3186..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class RevelationPenaltyCommit : Proto2.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 4da8b57f6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class SnapshotBalanceCommit : Proto2.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/StateCommit.cs deleted file mode 100644 index 8c9002bfc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/StatisticsCommit.cs deleted file mode 100644 index 99d42bbf6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/VotingCommit.cs deleted file mode 100644 index 76aa4999a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class VotingCommit : Proto1.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Diagnostics/Diagnostics.cs deleted file mode 100644 index d8515ec53..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class Diagnostics : Proto1.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Helpers.cs deleted file mode 100644 index ceff6539b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Proto3Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Proto3Handler.cs deleted file mode 100644 index e65f97749..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Proto3Handler.cs +++ /dev/null @@ -1,256 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto3; - -namespace Tzkt.Sync.Protocols -{ - class Proto3Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "alpha_003"; - public override int VersionNumber => 3; - - public Proto3Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - await new DelegationsCommit(this).Revert(currBlock, op); - break; - case OriginationOperation op: - await new OriginationsCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Rpc/Rpc.cs deleted file mode 100644 index 690fc680f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto3 -{ - class Rpc : Proto1.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto3/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto3/Validation/Validator.cs deleted file mode 100644 index 1a8527b9d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto3/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto3 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Activation/ProtoActivator.cs deleted file mode 100644 index 278b8d91a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Activation/ProtoActivator.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto4 -{ - class ProtoActivator(ProtocolHandler proto) : Proto3.ProtoActivator(proto) - { - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.HardBlockGasLimit = parameters["hard_gas_limit_per_block"]?.Value() ?? 8_000_000; - protocol.HardOperationGasLimit = parameters["hard_gas_limit_per_operation"]?.Value() ?? 800_000; - protocol.MinimalStake = parameters["tokens_per_roll"]?.Value() ?? 8_000_000_000; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.HardBlockGasLimit = 8_000_000; - protocol.HardOperationGasLimit = 800_000; - protocol.MinimalStake = 8_000_000_000; - } - - // Proposal invoice - - protected override async Task MigrateContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(block); - - UpdateBakersPower(); - - var account = (await Cache.Accounts.GetAsync("tz1iSQEcaGpUn6EW5uAy3XhPiNg7BHMnRSXi"))!; - Db.TryAttach(account); - Receive(account, 100_000_000); - account.FirstLevel = account.LastLevel = state.Level; - account.MigrationsCount++; - - block.Operations |= Operations.Migrations; - - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = account.Id, - Kind = MigrationKind.ProposalInvoice, - BalanceChange = 100_000_000 - }; - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - Db.TryAttach(state); - state.MigrationOpsCount++; - - var stats = Cache.Statistics.Current; - Db.TryAttach(stats); - stats.TotalCreated += 100_000_000; - } - - protected override async Task RevertContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - - var invoice = await Db.MigrationOps - .AsNoTracking() - .FirstAsync(x => x.Level == block.Level && x.Kind == MigrationKind.ProposalInvoice); - - var account = await Cache.Accounts.GetAsync(invoice.AccountId); - Db.TryAttach(account); - - RevertReceive(account, 100_000_000); - account.MigrationsCount--; - - Db.MigrationOps.Remove(invoice); - Cache.AppState.ReleaseOperationId(); - - state.MigrationOpsCount--; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BakerCycleCommit.cs deleted file mode 100644 index 791c6505a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,343 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto4 -{ - class BakerCycleCommit(ProtocolHandler protocol) : Proto1.BakerCycleCommit(protocol) - { - public override async Task Apply( - Block block, - Cycle? futureCycle, - IEnumerable? futureBakingRights, - IEnumerable? futureAttestationRights, - List? snapshots, - List currentRights) - { - #region current rights - var prevBlock = await Cache.Blocks.CurrentAsync(); - var prevBakingRights = prevBlock.Level == 1 ? [] - : await Cache.BakingRights.GetAsync(prevBlock.Level); - - foreach (var rights in currentRights.GroupBy(x => x.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, rights.Key); - Db.TryAttach(bakerCycle); - - var bakingRights = rights - .Where(x => x.Type == BakingRightType.Baking) - .OrderBy(x => x.Round) - .ToList(); - - var attestationRight = rights - .FirstOrDefault(x => x.Type == BakingRightType.Attestation); - - #region rights and deposits - foreach (var br in bakingRights) - { - if (br.Round == 0) - { - bakerCycle.FutureBlocks--; - } - - if (br.Status == BakingRightStatus.Realized) - { - bakerCycle.Blocks++; - } - else if (br.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlocks++; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - - if (attestationRight != null) - { - bakerCycle.FutureAttestations -= attestationRight.Slots!.Value; - - if (attestationRight.Status == BakingRightStatus.Realized) - { - bakerCycle.Attestations += attestationRight.Slots!.Value; - } - else if (attestationRight.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedAttestations += attestationRight.Slots!.Value; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - - #region attestation rewards - if (attestationRight != null) - { - bakerCycle.FutureAttestationRewards -= GetFutureAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots!.Value); - - var successReward = GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, prevBlock.BlockRound); - - var prevRights = prevBakingRights - .Where(x => x.Type == BakingRightType.Baking && x.BakerId == rights.Key) - .OrderBy(x => x.Round) - .ToList(); - - var maxReward = prevRights.FirstOrDefault()?.Status > BakingRightStatus.Realized - ? GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, prevRights[0].Round!.Value) - : successReward; - - if (attestationRight.Status == BakingRightStatus.Realized) - bakerCycle.AttestationRewardsDelegated += successReward; - else if (attestationRight.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestationRewards += successReward; - else - throw new Exception("Unexpected future rights"); - - if (maxReward != successReward) - { - var prevBakerCycle = await Cache.BakerCycles.GetAsync(prevBlock.Cycle, rights.Key); - Db.TryAttach(prevBakerCycle); - - prevBakerCycle.MissedBlockRewards += maxReward - successReward; - } - } - #endregion - - #region baking rewards - if (bakingRights.Count > 0) - { - if (bakingRights[0].Round == 0) - bakerCycle.FutureBlockRewards -= GetFutureBlockReward(Context.Protocol, block.Cycle); - - var successReward = GetBlockReward(Context.Protocol, block.Cycle); - - var actualReward = bakingRights[^1].Status == BakingRightStatus.Realized - ? GetBlockReward(Context.Protocol, block.Cycle) - : 0; - - //var maxReward = attestationRight?.Status > BakingRightStatus.Realized - // ? GetBlockReward(Context.Protocol, bakingRights[0].Round!.Value, block.AttestationPower + attestationRight.Slots.Value) - // : successReward; - - if (actualReward > 0) - { - bakerCycle.BlockRewardsDelegated += actualReward; - } - - if (successReward != actualReward) - { - bakerCycle.MissedBlockRewards += successReward - actualReward; - } - - //if (maxReward != successReward) - //{ - // bakerCycle.MissedAttestationRewards += maxReward - successReward; - //} - } - #endregion - - #region fees - if (bakingRights.Count > 0) - { - if (bakingRights[^1].Status == BakingRightStatus.Realized) - { - bakerCycle.BlockFees += block.Fees; - } - else if (bakingRights[0].Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlockFees += block.Fees; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - } - - foreach (var op in Context.DoubleBakingOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleBakingLostStaked += op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleBakingRewards += op.Reward; - } - - foreach (var op in Context.DoubleConsensusOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleConsensusLostStaked += op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleConsensusRewards += op.Reward; - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.NonceRevelationRewardsDelegated += op.RewardDelegated; - } - - foreach (var op in Context.RevelationPenaltyOps) - { - var penaltyBlock = await Cache.Blocks.GetAsync(op.MissedLevel); - var penaltyCycle = await Cache.BakerCycles.GetAsync(penaltyBlock.Cycle, op.BakerId); - Db.TryAttach(penaltyCycle); - - penaltyCycle.NonceRevelationLosses += op.Loss; - } - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - //Only in Athens handler for better performance - var snapshotBlock = await Cache.Blocks.GetAsync(futureCycle!.SnapshotLevel); - var snapshotProtocol = await Cache.Protocols.GetAsync(snapshotBlock.ProtoCode); - //--------------------------------------------- - - var bakerCycles = snapshots!.ToDictionary( - snapshot => Cache.Accounts.GetDelegate(snapshot.AccountId).Address, - snapshot => - { - var bakingPower = snapshot.StakingBalance - snapshot.StakingBalance % snapshotProtocol.MinimalStake; - var share = (double)bakingPower / futureCycle.TotalBakingPower; - - var bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = snapshot.AccountId, - OwnDelegatedBalance = snapshot.OwnDelegatedBalance, - ExternalDelegatedBalance = snapshot.ExternalDelegatedBalance!.Value, - DelegatorsCount = snapshot.DelegatorsCount!.Value, - OwnStakedBalance = snapshot.OwnStakedBalance ?? 0, - ExternalStakedBalance = snapshot.ExternalStakedBalance ?? 0, - StakersCount = snapshot.StakersCount ?? 0, - IssuedPseudotokens = snapshot.Pseudotokens, - BakingPower = bakingPower, - TotalBakingPower = futureCycle.TotalBakingPower, - ExpectedBlocks = Context.Protocol.BlocksPerCycle * share, - ExpectedAttestations = Context.Protocol.AttestersPerBlock * Context.Protocol.BlocksPerCycle * share - }; - - return bakerCycle; - }); - - #region future baking rights - foreach (var br in futureBakingRights!) - { - if (br.RequiredInt32("priority") > 0) - continue; - - if (!bakerCycles.TryGetValue(br.RequiredString("delegate"), out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += GetFutureBlockReward(Context.Protocol, futureCycle.Index); - } - #endregion - - #region future attestation rights - var skipLevel = futureAttestationRights!.Last().RequiredInt32("level"); - - foreach (var ar in futureAttestationRights!.TakeWhile(x => x.RequiredInt32("level") < skipLevel)) - { - if (!bakerCycles.TryGetValue(ar.RequiredString("delegate"), out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - var slots = ar.RequiredArray("slots").Count(); - - bakerCycle.FutureAttestations += slots; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, futureCycle.Index, slots); - } - #endregion - - #region shifted future attestation rights - // TODO: cache shifted rights - var shiftedRights = await Db.BakingRights.AsNoTracking() - .Where(x => x.Level == futureCycle.FirstLevel && x.Type == BakingRightType.Attestation) - .ToListAsync(); - - foreach (var ar in shiftedRights) - { - var baker = Cache.Accounts.GetDelegate(ar.BakerId); - if (!bakerCycles.TryGetValue(baker.Address, out var bakerCycle)) - { - #region shifting hack - //shifting is actually a bad idea, but this is the lesser of two evils while Tezos protocol has bugs in the freezer. - var snapshottedBaker = await Proto.Rpc.GetDelegateAsync(futureCycle.SnapshotLevel, baker.Address); - var delegators = snapshottedBaker - .RequiredArray("delegated_contracts") - .EnumerateArray() - .Select(x => x.RequiredString()) - .Where(x => x != baker.Address); - - if (snapshottedBaker.RequiredInt32("grace_period") != block.Cycle - 3) - throw new Exception("Deactivated baker got baking rights"); - - var stakingBalance = snapshottedBaker.RequiredInt64("staking_balance"); - var delegatedBalance = snapshottedBaker.RequiredInt64("delegated_balance"); - - bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = baker.Id, - OwnDelegatedBalance = stakingBalance - delegatedBalance, - ExternalDelegatedBalance = delegatedBalance, - DelegatorsCount = delegators.Count(), - OwnStakedBalance = 0, - ExternalStakedBalance = 0, - StakersCount = 0, - IssuedPseudotokens = null, - BakingPower = 0, - TotalBakingPower = futureCycle.TotalBakingPower, - ExpectedBlocks = 0, - ExpectedAttestations = 0 - }; - bakerCycles.Add(baker.Address, bakerCycle); - - foreach (var delegatorAddress in delegators) - { - var snapshottedDelegator = await Proto.Rpc.GetContractAsync(futureCycle.SnapshotLevel, delegatorAddress); - Db.DelegatorCycles.Add(new DelegatorCycle - { - Id = 0, - Cycle = futureCycle.Index, - DelegatorId = (await Cache.Accounts.GetExistingAsync(delegatorAddress)).Id, - BakerId = baker.Id, - DelegatedBalance = snapshottedDelegator.RequiredInt64("balance"), - StakedPseudotokens = null - }); - } - #endregion - } - - bakerCycle.FutureAttestations += ar.Slots!.Value; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, futureCycle.Index, (int)ar.Slots); - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - } - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BakingRightsCommit.cs deleted file mode 100644 index 61cebe535..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class BakingRightsCommit : Proto3.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BigMapCommit.cs deleted file mode 100644 index 9d2c67000..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BlockCommit.cs deleted file mode 100644 index 3761e88e1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class BlockCommit : Proto1.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/CycleCommit.cs deleted file mode 100644 index e6d983622..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/DeactivationCommit.cs deleted file mode 100644 index fe23bac71..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 2acda959f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/FreezerCommit.cs deleted file mode 100644 index a60f65ed6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/FreezerCommit.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto4 -{ - class FreezerCommit : Proto1.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetFreezerCycle(JsonElement el) => el.RequiredInt32("cycle"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index bbb2840b6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index a7d34b4b7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index d199a37e8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 0603f800a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index bc599b104..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 529ead94d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto4 -{ - class DoubleConsensusCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual Task Apply(Block block, JsonElement op, JsonElement content) - { - #region init - var balanceUpdates = content.Required("metadata").RequiredArray("balance_updates").EnumerateArray(); - - var offenderAddr = balanceUpdates - .First(x => x.RequiredInt64("change") < 0).RequiredString("delegate"); - - var rewards = balanceUpdates - .FirstOrDefault(x => x.RequiredString("category")[0] == 'r' && x.RequiredInt64("change") > 0); - - var lostDeposits = balanceUpdates - .FirstOrDefault(x => x.RequiredString("category")[0] == 'd' && x.RequiredInt64("change") < 0); - var lostDepositsValue = lostDeposits.ValueKind != JsonValueKind.Undefined ? -lostDeposits.RequiredInt64("change") : 0; - - var lostRewards = balanceUpdates - .FirstOrDefault(x => x.RequiredString("category")[0] == 'r' && x.RequiredInt64("change") < 0); - var lostRewardsValue = lostRewards.ValueKind != JsonValueKind.Undefined ? -lostRewards.RequiredInt64("change") : 0; - - var lostFees = balanceUpdates - .FirstOrDefault(x => x.RequiredString("category")[0] == 'f' && x.RequiredInt64("change") < 0); - var lostFeesValue = lostFees.ValueKind != JsonValueKind.Undefined ? -lostFees.RequiredInt64("change") : 0; - - var accuser = Context.Proposer; - var offender = Cache.Accounts.GetExistingDelegate(offenderAddr); - - var doubleConsensus = new DoubleConsensusOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - OpHash = op.RequiredString("hash"), - - Kind = DoubleConsensusKind.DoubleAttestation, - - SlashedLevel = block.Level, - AccusedLevel = content.Required("op1").Required("operations").RequiredInt32("level"), - - AccuserId = accuser.Id, - OffenderId = offender.Id, - - Reward = rewards.ValueKind != JsonValueKind.Undefined ? rewards.RequiredInt64("change") : 0, - LostStaked = lostDepositsValue + lostRewardsValue + lostFeesValue, - LostUnstaked = 0, - LostExternalStaked = 0, - LostExternalUnstaked = 0 - }; - #endregion - - #region entities - Db.TryAttach(accuser); - Db.TryAttach(offender); - #endregion - - #region apply operation - ReceiveLockedRewards(accuser, doubleConsensus.Reward); - Spend(offender, offender, lostDepositsValue + lostFeesValue); - BurnLockedRewards(offender, lostRewardsValue); - - accuser.DoubleConsensusCount++; - if (offender != accuser) offender.DoubleConsensusCount++; - - block.Operations |= Operations.DoubleConsensus; - - Cache.AppState.Get().DoubleConsensusOpsCount++; - Cache.Statistics.Current.TotalBurned += doubleConsensus.LostStaked - doubleConsensus.Reward; - Cache.Statistics.Current.TotalFrozen -= doubleConsensus.LostStaked - doubleConsensus.Reward; - #endregion - - Db.DoubleConsensusOps.Add(doubleConsensus); - Context.DoubleConsensusOps.Add(doubleConsensus); - return Task.CompletedTask; - } - - public virtual Task Revert(Block block, DoubleConsensusOperation doubleConsensus) - { - #region entities - //var block = doubleConsensus.Block; - var accuser = Cache.Accounts.GetDelegate(doubleConsensus.AccuserId); - var offender = Cache.Accounts.GetDelegate(doubleConsensus.OffenderId); - - //Db.TryAttach(block); - Db.TryAttach(accuser); - Db.TryAttach(offender); - #endregion - - #region apply operation - RevertReceiveLockedRewards(accuser, doubleConsensus.Reward); - // here we can miss 1 mutez, but this may happen only in legacy protocols - // TODO: replace it with NotImplementedException after Ithaca - RevertSpend(offender, offender, doubleConsensus.Reward * 2); - RevertBurnLockedRewards(offender, doubleConsensus.LostStaked - doubleConsensus.Reward * 2); - - accuser.DoubleConsensusCount--; - if (offender != accuser) offender.DoubleConsensusCount--; - - Cache.AppState.Get().DoubleConsensusOpsCount--; - #endregion - - Db.DoubleConsensusOps.Remove(doubleConsensus); - Cache.AppState.ReleaseOperationId(); - return Task.CompletedTask; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index d5b3b3093..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 2d59f6b48..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class OriginationsCommit : Proto1.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index be73c3bfa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index f4dec8c94..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 9c93c0560..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto4 -{ - class TransactionsCommit : Proto3.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override Task ResetGracePeriod(TransactionOperation transaction, Account target) => Task.CompletedTask; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index 8633fdad5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto4 -{ - class RevelationPenaltyCommit : Proto2.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetFreezerCycle(JsonElement el) => el.RequiredInt32("cycle"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 8c1d80a8e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto4 -{ - class SnapshotBalanceCommit : Proto2.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override int GetFreezerCycle(JsonElement el) => el.RequiredInt32("cycle"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/StateCommit.cs deleted file mode 100644 index e39e146fb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/StatisticsCommit.cs deleted file mode 100644 index c3880a556..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/VotingCommit.cs deleted file mode 100644 index a2111946b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class VotingCommit : Proto1.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Diagnostics/Diagnostics.cs deleted file mode 100644 index 2fba14ae2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class Diagnostics : Proto1.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Helpers.cs deleted file mode 100644 index e3270d784..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Proto4Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Proto4Handler.cs deleted file mode 100644 index 0df0f054a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Proto4Handler.cs +++ /dev/null @@ -1,262 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto4; - -namespace Tzkt.Sync.Protocols -{ - class Proto4Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "athens_004"; - public override int VersionNumber => 4; - - public Proto4Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - await new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - await new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - await new DelegationsCommit(this).Revert(currBlock, op); - break; - case OriginationOperation op: - await new OriginationsCommit(this).Revert(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Rpc/Rpc.cs deleted file mode 100644 index 97cb3ed2f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto4 -{ - class Rpc : Proto1.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto4/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto4/Validation/Validator.cs deleted file mode 100644 index 9a88fc40b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto4/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto4 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Activation/ProtoActivator.cs deleted file mode 100644 index b8929c9b4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Activation/ProtoActivator.cs +++ /dev/null @@ -1,428 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using System.Security.Principal; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class ProtoActivator(ProtocolHandler proto) : Proto4.ProtoActivator(proto) - { - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.BallotQuorumMin = parameters["quorum_min"]?.Value() ?? 2000; - protocol.BallotQuorumMax = parameters["quorum_max"]?.Value() ?? 7000; - protocol.ProposalQuorum = parameters["min_proposal_quorum"]?.Value() ?? 500; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.BallotQuorumMin = 2000; - protocol.BallotQuorumMax = 7000; - protocol.ProposalQuorum = 500; - } - - // Airdrop - // Proposal invoice - // Code change - - protected override async Task MigrateContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(block); - - var statistics = Cache.Statistics.Current; - Db.TryAttach(statistics); - - #region airdrop - var managers = File.ReadAllLines("./Protocols/Handlers/Proto5/Activation/airdropped.contracts"); - - if (state.Chain == "mainnet") - await Cache.Accounts.LoadAsync(managers); - else - await Cache.Accounts.Preload(managers); - - foreach (var address in managers) - { - if (Cache.Accounts.TryGetCached(address, out var manager)) - { - Db.TryAttach(manager); - - Receive(manager, 1); - manager.Counter = state.ManagerCounter; - manager.MigrationsCount++; - manager.LastLevel = block.Level; - - block.Operations |= Operations.Migrations; - - var airdropMigration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = state.Level, - Timestamp = state.Timestamp, - AccountId = manager.Id, - Kind = MigrationKind.AirDrop, - BalanceChange = 1 - }; - Db.MigrationOps.Add(airdropMigration); - Context.MigrationOps.Add(airdropMigration); - - state.MigrationOpsCount++; - statistics.TotalCreated += airdropMigration.BalanceChange; - } - } - #endregion - - #region invoice - var account = (await Cache.Accounts.GetAsync("KT1DUfaMfTRZZkvZAYQT5b3byXnvqoAykc43"))!; - Db.TryAttach(account); - Receive(account, 500_000_000); - account.MigrationsCount++; - account.LastLevel = block.Level; - - block.Operations |= Operations.Migrations; - - var invoiceMigration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = account.Id, - Kind = MigrationKind.ProposalInvoice, - BalanceChange = 500_000_000 - }; - Db.MigrationOps.Add(invoiceMigration); - Context.MigrationOps.Add(invoiceMigration); - - state.MigrationOpsCount++; - statistics.TotalCreated += 500_000_000; - #endregion - - #region scripts - var contracts = await Db.Contracts.ToListAsync(); // ~27k - var scripts = await Db.Scripts.Where(x => x.Current).ToDictionaryAsync(x => x.ContractId); - var storages = await Db.Storages.Where(x => x.Current).ToDictionaryAsync(x => x.ContractId); - var originations = await Db.OriginationOps.Where(x => x.ContractId != null).ToDictionaryAsync(x => x.ContractId!.Value); - - Cache.Schemas.Reset(); - Cache.Storages.Reset(); - - foreach (var contract in contracts) - { - Cache.Accounts.Update(contract); - - if (contract.Kind == ContractKind.DelegatorContract) - { - var script = scripts[contract.Id]; - script.Level = block.Level; - script.OriginationId = null; - - var storage = storages[contract.Id]; - storage.Level = block.Level; - storage.OriginationId = null; - - var origination = originations[contract.Id]; - origination.ScriptId = null; - origination.StorageId = null; - - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = contract.Id, - Kind = MigrationKind.CodeChange, - ScriptId = script.Id, - StorageId = storage.Id - }; - - script.MigrationId = migration.Id; - storage.MigrationId = migration.Id; - - contract.MigrationsCount++; - contract.LastLevel = block.Level; - - state.MigrationOpsCount++; - - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - } - else - { - var script = scripts[contract.Id]; - var storage = storages[contract.Id]; - - var rawContract = await Proto.Rpc.GetContractAsync(block.Level, contract.Address); - - var code = (Micheline.FromJson(rawContract.Required("script").Required("code")) as MichelineArray)!; - var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter).ToBytes(); - var micheStorage = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage).ToBytes(); - var micheCode = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code).ToBytes(); - var micheViews = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view); - - var newSchema = new Netezos.Contracts.ContractScript(code); - var newStorageValue = Micheline.FromJson(rawContract.Required("script").Required("storage"))!; - var newRawStorageValue = newSchema.OptimizeStorage(newStorageValue, false).ToBytes(); - - if (script.ParameterSchema.IsEqual(micheParameter) && - script.StorageSchema.IsEqual(micheStorage) && - script.CodeSchema.IsEqual(micheCode) && - storage.RawValue.IsEqual(newRawStorageValue)) - continue; - - script.Current = false; - storage.Current = false; - - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = contract.Id, - Kind = MigrationKind.CodeChange - }; - var newScript = new Script - { - Id = Cache.AppState.NextScriptId(), - Level = migration.Level, - ContractId = contract.Id, - MigrationId = migration.Id, - ParameterSchema = micheParameter, - StorageSchema = micheStorage, - CodeSchema = micheCode, - Views = micheViews.Any() - ? micheViews.Select(x => x.ToBytes()).ToArray() - : null, - Current = true - }; - var newStorage = new Storage - { - Id = Cache.AppState.NextStorageId(), - Level = migration.Level, - ContractId = contract.Id, - MigrationId = migration.Id, - RawValue = newRawStorageValue, - JsonValue = newScript.Schema.HumanizeStorage(newStorageValue), - Current = true - }; - - var viewsBytes = newScript.Views? - .OrderBy(x => x, new BytesComparer()) - .SelectMany(x => x) - .ToArray() - ?? []; - var typeSchema = newScript.ParameterSchema.Concat(newScript.StorageSchema).Concat(viewsBytes); - var fullSchema = typeSchema.Concat(newScript.CodeSchema); - contract.TypeHash = newScript.TypeHash = Script.GetHash(typeSchema); - contract.CodeHash = newScript.CodeHash = Script.GetHash(fullSchema); - - migration.ScriptId = newScript.Id; - migration.StorageId = newStorage.Id; - - contract.MigrationsCount++; - contract.LastLevel = block.Level; - - state.MigrationOpsCount++; - - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - Db.Scripts.Add(newScript); - Cache.Schemas.Add(contract, newScript.Schema); - - Db.Storages.Add(newStorage); - Cache.Storages.Add(contract, newStorage); - - var tree = script.Schema.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); - var bigmap = tree.Nodes().FirstOrDefault(x => x.Schema.Prim == PrimType.big_map); - if (bigmap != null) - { - var newTree = newScript.Schema.Storage.Schema.ToTreeView(Micheline.FromBytes(newStorage.RawValue)); - var newBigmap = newTree.Nodes().FirstOrDefault(x => x.Schema.Prim == PrimType.big_map); - if (newBigmap?.Value is not MichelineInt micheInt) - throw new Exception("Expected micheline int"); - var newPtr = (int)micheInt.Value; - - if (newBigmap.Path != bigmap.Path) - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "BigMaps" - SET "StoragePath" = {0} - WHERE "Ptr" = {1} - """, newBigmap.Path, contract.Id); - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "BigMaps" SET "Ptr" = {0} WHERE "Ptr" = {1}; - UPDATE "BigMapKeys" SET "BigMapPtr" = {0} WHERE "BigMapPtr" = {1}; - UPDATE "BigMapUpdates" SET "BigMapPtr" = {0} WHERE "BigMapPtr" = {1}; - """, newPtr, contract.Id); - - foreach (var prevStorage in await Db.Storages.Where(x => x.ContractId == contract.Id).ToListAsync()) - { - var prevValue = Micheline.FromBytes(prevStorage.RawValue); - var prevTree = script.Schema.Storage.Schema.ToTreeView(prevValue); - var prevBigmap = prevTree.Nodes().First(x => x.Schema.Prim == PrimType.big_map); - (prevBigmap.Value as MichelineInt)!.Value = newPtr; - - prevStorage.RawValue = prevValue.ToBytes(); - prevStorage.JsonValue = script.Schema.HumanizeStorage(prevValue); - } - } - } - } - #endregion - } - - protected override async Task RevertContext(AppState state) - { - #region airdrop - var airDrops = await Db.MigrationOps - .AsNoTracking() - .Where(x => x.Kind == MigrationKind.AirDrop) - .ToListAsync(); - - foreach (var airDrop in airDrops) - { - var account = await Cache.Accounts.GetAsync(airDrop.AccountId); - Db.TryAttach(account); - - RevertReceive(account, 1); - account.MigrationsCount--; - } - - Db.MigrationOps.RemoveRange(airDrops); - Cache.AppState.ReleaseOperationId(airDrops.Count); - - state.MigrationOpsCount -= airDrops.Count; - #endregion - - #region invoice - var invoice = await Db.MigrationOps - .AsNoTracking() - .FirstAsync(x => x.Level == state.Level && x.Kind == MigrationKind.ProposalInvoice); - - var invoiceAccount = await Cache.Accounts.GetAsync(invoice.AccountId); - Db.TryAttach(invoiceAccount); - - RevertReceive(invoiceAccount, 500_000_000); - invoiceAccount.MigrationsCount--; - - Db.MigrationOps.Remove(invoice); - Cache.AppState.ReleaseOperationId(); - - state.MigrationOpsCount--; - #endregion - - #region scripts - var contracts = await Db.Contracts.ToDictionaryAsync(x => x.Id); // ~27k - var scripts = await Db.Scripts.Where(x => x.Current).ToDictionaryAsync(x => x.ContractId); - var storages = await Db.Storages.Where(x => x.Current).ToDictionaryAsync(x => x.ContractId); - var originations = await Db.OriginationOps.Where(x => x.ContractId != null).ToDictionaryAsync(x => x.ContractId!.Value); - - var codeChanges = await Db.MigrationOps.Where(x => x.Kind == MigrationKind.CodeChange).ToListAsync(); - - Cache.Schemas.Reset(); - Cache.Storages.Reset(); - - foreach (var change in codeChanges) - { - var contract = contracts[change.AccountId]; - Cache.Accounts.Update(contract); - - if (contract.Kind == ContractKind.DelegatorContract) - { - var origination = originations[contract.Id]; - - var script = scripts[contract.Id]; - script.Level = origination.Level; - script.OriginationId = origination.Id; - - var storage = storages[contract.Id]; - storage.Level = origination.Level; - storage.OriginationId = origination.Id; - - origination.ScriptId = script.Id; - origination.StorageId = storage.Id; - - script.MigrationId = null; - storage.MigrationId = null; - - contract.MigrationsCount--; - contract.LastLevel = state.Level; - } - else - { - var script = scripts[contract.Id]; - var storage = storages[contract.Id]; - - var oldScript = await Db.Scripts - .Where(x => x.ContractId == contract.Id && x.Id < script.Id) - .OrderByDescending(x => x.Id) - .FirstAsync(); - - var oldStorage = await Db.Storages - .Where(x => x.ContractId == contract.Id && x.Id < storage.Id) - .OrderByDescending(x => x.Id) - .FirstAsync(); - - var tree = script.Schema.Storage.Schema.ToTreeView(Micheline.FromBytes(storage.RawValue)); - var bigmap = tree.Nodes().FirstOrDefault(x => x.Schema.Prim == PrimType.big_map); - if (bigmap != null) - { - var oldTree = oldScript.Schema.Storage.Schema.ToTreeView(Micheline.FromBytes(oldStorage.RawValue)); - var oldBigmap = oldTree.Nodes().First(x => x.Schema.Prim == PrimType.big_map); - - if (bigmap.Value is not MichelineInt mi) - throw new Exception("Expected micheline int"); - var newPtr = (int)mi.Value; - - if (oldBigmap.Path != bigmap.Path) - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "BigMaps" - SET "StoragePath" = {0} - WHERE "Ptr" = {1} - """, oldBigmap.Path, newPtr); - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "BigMaps" SET "Ptr" = {0} WHERE "Ptr" = {1}; - UPDATE "BigMapKeys" SET "BigMapPtr" = {0} WHERE "BigMapPtr" = {1}; - UPDATE "BigMapUpdates" SET "BigMapPtr" = {0} WHERE "BigMapPtr" = {1}; - """, contract.Id, newPtr); - - foreach (var prevStorage in await Db.Storages.Where(x => x.ContractId == contract.Id && x.Level < change.Level).ToListAsync()) - { - var prevValue = Micheline.FromBytes(prevStorage.RawValue); - var prevTree = oldScript.Schema.Storage.Schema.ToTreeView(prevValue); - var prevBigmap = prevTree.Nodes().First(x => x.Schema.Prim == PrimType.big_map); - (prevBigmap.Value as MichelineInt)!.Value = contract.Id; - - prevStorage.RawValue = prevValue.ToBytes(); - prevStorage.JsonValue = oldScript.Schema.HumanizeStorage(prevValue); - } - } - - oldScript.Current = true; - Cache.Schemas.Add(contract, oldScript.Schema); - - oldStorage.Current = true; - Cache.Storages.Add(contract, oldStorage); - - Db.Scripts.Remove(script); - Cache.AppState.ReleaseScriptId(); - - Db.Storages.Remove(storage); - Cache.AppState.ReleaseStorageId(); - - contract.TypeHash = oldScript.TypeHash; - contract.CodeHash = oldScript.CodeHash; - contract.MigrationsCount--; - } - } - - Db.MigrationOps.RemoveRange(codeChanges); - Cache.AppState.ReleaseOperationId(codeChanges.Count); - state.MigrationOpsCount -= codeChanges.Count; - #endregion - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Activation/airdropped.contracts b/Tzkt.Sync/Protocols/Handlers/Proto5/Activation/airdropped.contracts deleted file mode 100644 index a7c90c867..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Activation/airdropped.contracts +++ /dev/null @@ -1,7321 +0,0 @@ -tz1NKR6nBuLPxSGnFBBTXWLtD2Dt5UAYPWXo -tz1aXABbWvy6G4nmoD3dK2L5V3wGHKgwGcak -tz1Y7pazKpSVPMAVW4zePjgMR1CpavTB8Hrn -tz1cm14E6MYtC7kKyrzxVnVwqxxeBS9qhFPf -tz1ScuhbY4kJRgs3nyrMiryF6Y8f5PMZ7hNh -tz1Rkk1uqUm8MUp43T52jGCf33DSW3Whvx7X -tz1QvaDfZXxAyQDyHZgZzq2ShWd1q5z6t99S -tz1SraYbcCskcKKak9xoo6cFCL78SMZ4wVwV -tz1QRPi75y6cQRkBQ5nc9FMzZHQt1KsjWEFM -tz1QgYSR7EscvzhAeYmWfVwqFh4c6tR4FYij -tz1T1FACxevZPfeBdRAqqkghFKG6KXMcS8kW -tz1NZFbi7NAEpJp4rLtXWMegJbgBAPRPdXU6 -tz1bfNHk8DLEkqaUgLAVqxGSFGNK7ND29Xma -tz1c1Vz6CfHYJBsUXjctvjgtAZLvhWuQYCiP -tz1W9naQFyP95rmLDL1CMpiN2dnicwBFMpua -tz1PQTrTN55T1MLTHUgyRpXWWf6szwFFTBfh -tz1gDY5XK9wsER9NuVze3MdMEkU6BN2d5CyQ -tz1LvpBpeGHpt81mHMgF3sBkeV2rpoLchSVF -tz1S1iYBnVYaXg91WfdydTLrCEjyQxffg3do -tz1VSSw1jf4tU7VPsREBGnq87uHyoTEhpq2E -tz1ZeJyiLssYNpb4MNScU1dJ6dtawK45zM5e -tz1b1cyP61Vx9RVTfLcroVpgrUg7D7hZfzXq -tz1LgweJAEGQh7jUiUh8rZgWhtnT4E156nDV -tz1TAp9yWFdpXz22kr4GthiADEyCKwaxkipi -tz1iMNj3xLspSMJwRArSY2Cu1nN8bDsNxtJC -tz1XbRKHxkoUCHy1gmpvUS59Zg54yxFArLsb -tz1bhxCy1BwtzLubSgjwUh7qjiQ6poD1g48x -tz1edJhY67SMEgDU29gFP9eUhstDEv5beyaS -tz1LCzWDoM8esaDB1eV28eWwW4AjWz4F7izF -tz1UAQhz6cByqWFB7Qs7XveQgubSt7moa4kB -tz1gC5hQXAt3rWCinQWzWBdrZ8B3PyDajV5F -tz1QNVESmiEXXUH7yBz4ANK6xhu6uKEUgdgD -tz1RAGVXPLBmDdLYFGULE5nTeeTeiKuDPst8 -tz1TFsT9qv1M7VPutZu8oNUqtxxM8feP13u1 -tz1YFfTNkS5hUcBQoDCHD3bfDwrDHmsUEhvB -tz1XRporsuEKCMdo889ARn2K9vLvzCtVF5TE -tz1YgPMnXGFojDyVpmPUUUW3V8amsrt9Wua7 -tz1frcqkaTwWcQcubmikS5MgSqUWJHs1K3un -tz1S3L7qfH6e6rAtsiUPi1ZeQpnRGizap28v -tz1X6BVHcVDguWacjvzPRTMc1yh5H7z8EKWM -tz1LM9w2PmkHmtg1HAV7W58SyrzzZ4XGWGRa -tz1eXvcerUTcj31KdRTdmvoArqPXuPBP3Pff -tz1KxFQ6DsrYvxrPrtMduPs25A7hvygiutCW -tz1WSvcWB4vBCDhBSTL1MasTYG659KuHVApM -tz1dJkN11AVvrztczZhE86okTYSnySscnNym -tz1cTx8Fpcwdsp2gAQMDYVGPmAH5N27Rmc5D -tz1UKBETpgJycFMCmP4VhfAyKhn2XMrsFJgw -tz1gTng77kDsGxsd7VK2MyM71FBNue3yZGAq -tz1dHfqfWRxxNAkHruHj58DzF5wtZbVJkBbo -tz1NrV38iG3YSvoBxtwD7Bdz4tHnVTSPU2Pq -tz1SNHrbps97bUrvaW7KqLw8WVnpYVicAFFr -tz1WT1AxUNEkwAgWWXhUyn1JG7dGapwuoyzg -tz1ev1rYjmsReEsVUJqkvSWZmMtNu5S6V7ji -tz1Xgpgtd1paVjjVRqSbkkbn1ed13ZxJBNhQ -tz1eGhkgPVK4GhfbP25V2oG2XQh54YeQ9yKf -tz1hAYXDrtiDJcNAXX55EzCdXazW2eDjYeW5 -tz1ZweS5ngz67hqQeULpxAyaBRGA2THkqZTn -tz1gdbsUc1m1usMdNQyoVkwiVRYMX9S2eP69 -tz1PCfUwRcEmzGnDXvKKWKNM2Cseb8aWyUhR -tz1LiarvB1ePcnJJ8cpoRfPXQ6oUjTJwcKrk -tz1M6PLXT41DuGHZNQuofHXuvmRn9D7qxH2r -tz1TZT8Yssethby6EkJVQLiZjzLxHGEaSHjC -tz1NqDjmgNGiZZXSbKReE9HvenfkYZJaM5GD -tz1XUA8HFBmniSXqtnDogGsKm6uDD57Z1bpn -tz1LCpz8Z84iusmNbLEd7qUWK3qwYs1t1sHK -tz1aVJfY98fzwdMkHAiLx2CUBUmbn79xRF9k -tz1dtNYgkNXYmkRiXS6DAtbxcB516P73VfUm -tz1TSeQrJvJbXx6oos3qZguzAmxmdezRPBgv -tz1Vyo4HXn8gGypBJEPvk6cbXQMnc8XwfFJ7 -tz1XsajhaXKv1BggG26SrkFcc1RCYS43rBZU -tz1SXddeBYXni8jtS4R5BY8b1Y5my3nUiWWK -tz1i8FgMe6Qxx5mJYtAENS2dPcqm6K3T9KP9 -tz1WFuNUXu6brJQxSgJyxfHSzUGBGqNtwcZz -tz1Xxcj6F7F5KKXfQpBDSvmUDuKDRESvqK6G -tz1huBpdek7wtbcGcS8C1CCnQZtyzdDnD2uS -tz1fsADSpxKLeSrQ1VYe2FeYR7pRRo7oiDan -tz1YibrHq1gEyyg95wxN3LStN3wG8LjqMqU2 -tz1L8E8Jb62mMtNu47eeQQCAfSMpARf4BxrZ -tz1TLfHnawNuj2oXXfeZcLwKTG2wEqC12tqZ -tz1QLGfV4zWx6DoadwzUQREoUQWwKcC1Eov2 -tz1X3NXmf98BNpMXACFAzVZBUNA1fcUhYiQa -tz1NS6mMwh6vNiqrzcqBp6RcSKaTPWAViCc1 -tz1fiw7uVofXYh91QRv2mZV9hMYa9jArE4G3 -tz1XGWvkyGRKmWFk9L3Myk9rEdTGaUpWsPfu -tz1fgVT7JvznFuaitE8VfQu1s4tye8YKMwn7 -tz1PCDUB2ze2VwjLJr35dKccNARWSpwqzoJg -tz1dNS6SUd2dA8FFtiMnjscYmKzM3xJAEHsL -tz1hTXZgbgy2vEL69f1kmFhA7iGs2hhkGWYn -tz1W79sNH7CtnMMcCkqvoz4G1rYW9fWWQLnh -tz1NK1p1MJNjrYv7A6rpYnc6APWw6Xi56e6M -tz1VRAfMaLE7MZoqdaGbkRUCyPqspavX2Drd -tz1LBGDpuDxnaR4XmBb45frtKCbbQfzLTxee -tz1aoPsdFb4nb1vhbmXC5xqzGf6MbcQPatNy -tz1abo8ytLNGqbDShMkBV4SiMrGy7BnGUERz -tz1ZLCCaeFip9k58NB8BLV8TA1YqbP2dBrfz -tz1aMMv9Jo9a54CyJmjsn5tEJeK8wEV5NKnx -tz1PpVatW9gVvANGiYb3fqRCsfXe8c9rrkvX -tz1hTkSgQn1f4a7BKY1hcc9DSaLE7HNymyaD -tz1Lc3HSkv4UVGUrGuRqbj9Q4uLMUAZsxa7Q -tz1e1ZQSbxB7GgMVYJgbHixmoiwzgHbnBBFc -tz1byFHCjc9j2LQoQeDM5EubgQha8awmDfuT -tz1XzLkdPBhuUhe2DKuQAKTikgyTVJaYNbCW -tz1LqSfBZQXWiXwsYchUiYSFgkiNT3eY9Wij -tz1WP5Z5xTmVEJ5kzijbx7W2rwsVTGwGZJUi -tz1ah57gi1vRRSGZE8cxDC3ny9qgtqwRSbVF -tz1KhQhhwkG7pw3ALzfKrJyZEq1R5wnnsEAq -tz1QwSNvLS98FMXkAk8Xt3N27xSLYB7KyYAe -tz1MnVR6Brprz6Vwym6NyP5tSoB6H9kbQrwV -tz1eU4rbqQw8hcuwtzaHqaZJfyucFphkWQ77 -tz1gR4HFjpoyQjn2nBs2nsoZJ4G8V26nmkEG -tz2Md2gC8G1XdiWrvjHeAjA35XSQFjszG53t -tz1KnBDeUJUwHJn3Mvium2cDLCJJeH5oQeu4 -tz1eSfJEiApkcdS2jzLSE38ptV6Ln9W1FYfr -tz1Z9ptnRn4b7vWL8HdchZwrn8DbgrPATbdc -tz1dCF4VHPbsciQghy27kMVrHEWLKZ6t5gYv -tz1gigZf4k48gWRqjE37rAbEh3vH5Ko1onFB -tz1KhkPKXkPP46qUHmMJzQKAn7MNJSRFbSk3 -tz1avsiW5Bkm3rYQqJ89b96pEEB4W1FTe6on -tz1WpGSbvi44uwuQD6ugB12b6MD4ymVbduNr -tz1dzd9rfqkZ96w4W2K3HySbujwdUzViPfPY -tz2VemTgqDzXRQJ4dFKLMkxDCjNF3dYvToig -tz1fmvngj5t4hdpKmsnMBBkyqbyqBTF6uMt3 -tz1YU4K7aqjyoihpdmCK5qK1GonJAXzgspLw -tz1NFWm5UbbfBeCz5rkspYuL9sceQbEssu7L -tz1WXH3sNPfNAwLUwmGzPeRMJiCzzEuzBSGg -tz1ZQcfdrkgQCKAZBxv17Q2N1nTiaT5DBczA -tz1MdgxdRhMs6fEfPf3meLv1hzx4Lafh9fgs -tz1X6EX9BnTSNcX7mWHcHVhu8X7oBEvwFbVa -tz1ZtxYMz1KMaDqhPnMfJ7dPCMYUb68Y9m75 -tz1duKPCi8Uhns86ZemukQMcm8QWM4ptg1wn -tz1Rn8bN3KmQb7oB7scjA1uqC2UgWriAuaDP -tz1PmqsVBC4KovPQaj5DpeY2s6JrboaeyfUA -tz1byuvkHo3KHiF3LrL4WtBspuDmvqBy3mQ3 -tz1MN42j93iFggNqdmFjF6BNuR6SbjLEafrv -tz1MU7usZwvL1hsnvyVUbRmRN5Uy2HpXeEoy -tz1Mvef6LM2sqmGWHyxq5wWRRfkA3nCeNqUB -tz1hUeKd8hrX9YwYxdFMP7E5vEcY8UXucbdW -tz1fWy6UkrjKa8hv8V5LXtDhrBEnJ2o7qQiZ -tz1aUcNi3z3pqsAt4YhvNdJYP9Es6XGTB63Z -tz1RLXJNuQP6Rrb2yr2S8ntbcYFi2jHPBYwV -tz1a59L2oXYMU5TWE9bEpKXRbaGUAa9aH3gr -tz1W1wWgocyJZQJBxHLwgQfgvaKSTqp8vv3f -tz1h1skKwR6SSr8W36gPY3KTnauCrZxFPx49 -tz1fmffdkQVYP7Rp98cmxB2TkBG6mE6bN4rH -tz1c8BwFmDv7fQTFaykTAHHXsYqiZC6piSVb -tz1VYWfiE6no7RGJugznwvVwnHqJfTEgna6m -tz1XokfKsnh8J9kNNBYF1rVSxdb5Mz88PQ75 -tz1Pd7g7oMRqa11j2guUGxSoBikUomqyh9dm -tz1ZQ91XFMavdhesoEgpRY8gu7fVwdk5JFBh -tz1PuF9qgtkMqbiCUcvPrRa3RvAEtJMAR359 -tz1dvFGBg7SXn4dawhvjtH2uknHVzWH5LzEC -tz1U8FcEdDcH2RSpV1savphUdE1pjW7zYeek -tz1iFNuwSojgkEcN5rfXcFQmGkaHLkseRMgr -tz1LVM4HTLPLzTVQ3ACqzUMZdEEVLxCr9zqG -tz1RgXNzn6BNKg7C4jbnimjmAjDbWJke2BwD -tz1NMZm28evTT1xajZTgYCYXnKdV1E4crqzP -tz1TbwNbSiGCTXfDc2KcSii9CFRiGHmZuMKK -tz1XG69vhU1WsUTbe2JyAmQd8bYjuGsPeW3T -tz1NfeYqr8SnWGjM8gUECz4XaMe6yGqf9XAL -tz1eMunwnxsqThVs14ZaQGN5xPAGo4R97cAk -tz1eiBh17x9nt6RjEPjaScyPx1XoPxEnqDSE -tz1PFoXQ1T2nxthtvdjfnFKbSCGzZ3xSQqL2 -tz1SbtkKrRomurZ8yqZ3xcVtvTTfF7aTir6Z -tz1MC2mcq6gBnkH9YN3komWCPhLjifhB6TBa -tz1VpQ5SmjxKrYQsywbbkN4Zj13KM2HwBsx5 -tz1bVoTGYUtowdENLzVZ9CJgC5zs1e31LLRo -tz1XNDbB74ddBbDe6Z79gPb35cds6KRpz1B3 -tz1VbuU7b98QKAa6NcWRMF6AvUj9FSLbUCYF -tz1UtM7VfBHkHEpiDNX4kPoDDRnAASsGjHKn -tz1VTPiP7xZG68SA52zYd4uYUDPx9F8Ct8FP -tz1S2UfaFhNrCMcogayBvUsVeo8oLKbNoFAE -tz1gTYTWzPEcGzN28aX4xdxoMKVzxBXzh5xb -tz1NeHC2YGkonEtKvPqenxQXDGu7i7YiM6NU -tz1RVJDwY8cjx6r4K1vUA1MBnrA1eGL9G2KS -tz2GvUcW5V7c5EydFHeZ9rQYHeyu8rZznULf -tz1cexKWqZejUsz8jG2x3gVbzo6SNHGRSk2x -tz1ib69j9zFTPDg945i8Vh7N9CcZFeNEsXw3 -tz1fuTgEpvM1FaPMjDVcnR96yppwTV5mZjPH -tz1c1NxmVZyCJSVEwjFYRDtEeTAcNtLE2S66 -tz1YSeZQ1HNGmF5zwZBsgVCdfxAjymJacnkT -tz1i6b84TgU9RCuF3YbQeQwRQ3AtBasMDPF3 -tz1dmSoNDupcMTdth9SeVnULXUCFxZ9agLZS -tz1ing6UzUtN3nYtKU7pjpPgy9d71QYz7uzU -tz1crwjf2wgcWi4nKqbSqT4T4YcnxYva13LA -tz1UQyi1QpbnJa8wQSmy75c2hHQDNgiJVyxH -tz1gt5LCjShBooU6zV628qowXHk6q6xSzkfN -tz1NnusmVZuP15pN4u3JL17cL6cypwxu2X5g -tz1L376FZNuAvS3Z6wijefLoCmQ6d3WH1FUe -tz1d1YpUy1Ra4rvdM23h8rYYvjFfCgnJeB6c -tz1QyMVFXRfen2FAobYLMeYRH1LPLXTEcjaQ -tz1LxjVUpjkvaZVopmBD1fBae2zMmVWdHkhu -tz1fUeor2DN8Wa48ECXoETMCugePFW2pRkre -tz1Q7pAwrwwSd3SBteZKGKqxogV7fMsHr5X9 -tz1a9yomk7jQUPvgNjVDmCZqar8i1Xjb6wCB -tz1g79Fz4i7ZRHEUKzecdVDr5HgYXNHi24cP -tz1SFbzWLjAfey8BdYuJGaJBTyPeThFuFDkh -tz1XsDHdWLtPuMpVBSA2TvjuGdrBkkB3tgrk -tz1Ksob8NKnsNPSz48hXbEvNkNJ5LoaiD3ZN -tz1RCRTSZzcruuPg7HZ5S5rBeLw9La6mkvTk -tz1ZRxSXFd7RvfTWz4dHADJPDPtZoom9K3gA -tz1dEZn2ShqE8vH5HKHoWsgCDPKT63niXWyL -tz1NUpLdg3FuCiAsm8ko41kDAPBpCuxVzJeM -tz1f6qKMqtQXhYPppMUXfdJy7A4amKz1aGub -tz1iaG6zmN2iGTzUKfSCusW7RzjUVGjZ2fX2 -tz1Nw3LgJ1PBb9FMAbpbYh3ahr3L2ee6RvKY -tz1ZGqbsseJ5jHKmE9aiVUBxNFYhSkjYzWK6 -tz1TbXQHHamC6JAh1gu19vZL2fU8nSMA2HZw -tz1YP1cjQiLUm5mfqL69UfgbtoSJqxHJmkKx -tz1b7PiVuu6GLX9jUR9GrhK7c2CTEoo7BSMw -tz1aKAmXphpct3AWpZUStVerRwUZQwnTA29B -tz1cMNBdGjXNpjt656WVMHrYbS3iFDmHZGT5 -tz1XSkfYf6VMLRF3UP1wJwEimrQpFiXdxDSx -tz1gbtpCvhreemGysp2A2b3SnUhvQciM613r -tz1Rrrjy9RYmuWTjwfUfEBdZUT471AvTHGcc -tz1aykuqNnTAYc42nX8HbXC67tHj3jc6uipU -tz1Nw6oPn5MqyHKfkedGtjGctbh9KJaF4Awo -tz1ZSywSEV989VM3iY2eJCK8dXxe5pC6ar8b -tz1PNg922K3xkkNp8nSi8WrZNZGCQZYCQD5b -tz1bsuuZeQTjeZDh6XDN8yyKo1svfVgbHNYC -tz1iHUxmchkPhxpwmvG3H25bYQiSUVsfz6SY -tz1NJigRWkq2KqKEunFFJ5PjcBxp69bu2izm -tz1X3QUebJWqoMNfLE1GtryyzjG63qXHQko1 -tz1RpYciLQa7poihGkW2hresu9Si1Uyru4pk -tz1eHc6c1oK4xX9L6CbnLUmF3NrMhvhF5Lmu -tz1eW3NTNaMd6XLUUpBYsafzhpq5H5iwLYZn -tz1YhEBnBuBxj8YVpGKyW9RkfGLBvz6eo5D6 -tz1Zax2zQHDBW4zUR9A61VPR4N5nwBJMUmQV -tz1NUcTNHJCKSTVanVWG84PbPedd6Zxw1QsP -tz1gFTy3ckKKmdQf6DKe91p5okrDgQ22ka56 -tz1WptxRfqFXU1V7gyHdfFcct1xzQPhVf8Kr -tz1R3VLrjHBuAEebwkRshqbn3h4zH84e5Gjg -tz1UzLYahpdtDaS4BkRCbF8F9DCvF2kuXDUC -tz1hKt7LMARHex91LQqBzMdHo2Hxy7Qbr5z8 -tz1d4jAcgYe8x4pL51691W3YW6H1ahvPQMPs -tz1eHsZ3KJthCxWKC6ApNa4GtqUiMHdDFjoj -tz1RVPLgVjvvpU58T2R2a4Ym7iKjtKuDf7Zu -tz1PUSeHbieTq2bRA6ENE8YQWJgbkoyqxmZi -tz1doeR4WQkH6hiAWNNux36xGFxJRSVCWPPu -tz1T4uth2KGKAhknx6f98KznnKXKSeG4s9Za -tz1QWPqziKAi48nANYDp8ENBAaUtpiDSgxf9 -tz1RyKP3wTpHw69L8Vfb3JVWmhsqVRXJ4D8o -tz1SHH5qwqQY1nhUrcg7wbjmpdNzJ354x1k5 -tz1SGVPeeX6ZfF9M1DhnEPRg1yrbFNe9jgny -tz1Zwpc7bunsoGyA1vsMuu9RK4crW673tuwB -tz1gcbRtf3iPye1KAhze4dgiaRGNc1eub3kR -tz1VHD2Q2bLEsVj6Usk4jLXbhjfLKeH72ZgB -tz1NBzzqCFc5wBUGS71SwTAqt2BZGDGNfH29 -tz1gQ5ao9g2Qj95B3kYaRpYsjEXiYbGbm1XF -tz1UrypHmooyv8jG19E9LwUh4fS5p1gFK3Fh -tz1Nm9vh1ncDoSmjfZKWjAZaBWqtcso79ivn -tz1i591p6b3ZnhwQweqhY2X2tSLEY7P6pXaN -tz1iBm6fp454D5BexRVpEt8tfc4yzPHiavu8 -tz1bfWNapfCziFkiRE8SMmJ6gN2FLWGCPptz -tz1NvYZTyKa1dtHebmVRnnn1J9Tveu2wA7Yf -tz1itTF43dYMrZPhzXiCG34q2bTDAjPMjDTL -tz1M9zUhh2pao6uixTbgbhcUNoCBhcbxyRSg -tz1bVjcE2G8FGutCKnEEaH9ALXq4TWTGMhsp -tz1SmZ69mgYB34JCay6VpaEPf8qcHsDmmXxy -tz1TvVdaiY52Ti171TAEqDbhS7VebMnoAy51 -tz1dKxEWuF28A5K1PwYcHTXGcVvEhk5z9Y93 -tz1KrL4fJ5MH2MRLtEbZt9qQBh4CFoiHztxG -tz1Mx2GkhxK268AC2XeRUqpSNhTucAh52TUi -tz1caMMZ1kJ8dVWxyBjVgmYmbSFGVr1JZNL2 -tz1dMynaWimNhjCVptyMzKxKzx8j13Qbj22u -tz1LHqDGGRtsBYt4XMnLeFb4jvZtDjvCEb4S -tz1RB4E7ibuzjBJ6R7auCwsBuUtHBskeXEbA -tz1XjHJ7QB7H4TpsgMU88BrnAzGVdKWKqHrG -tz1extRAKJM5oGAeKxtTABMzoCQCA97zNDiq -tz1MRZ3zahnCRmyUTpK6X37FEvuZN71LeDZR -tz1Ky8ahCnxzRBBNEdW2qxD8siVSLjywX3md -tz1Zg6mz612FdAQGqmQAmfBtmtqHnZckAZP1 -tz1ZL2PcxvpJrvEoN92dNyQUQooyMvTJJY5A -tz1cDem6SGUTij95XGbCr53q6viP1RQ7LRyG -tz1L9apyTubXAJzTbJFEzARo4EdwzL9xMssf -tz1YSLMoBqD6XjrP74XMjqWwHuMXCDKiUKRW -tz1YKc5KjTDCkq8fZoaFUxUvstTfAHCuYd3j -tz1TA3ykehBTBSYzvHe54UmrTYmi7VgtG9vT -tz1h4SoxFcJnqqngepYxHgA58dRt86ZLP3Y5 -tz1XUNRGqfVYM9ag2Enr2Yxym2UfHN1sPiau -tz1UMRjofBcjkVcVCEGzQHBH3fhoy1AWYKHY -tz1fPtr6hhk5WCywFS6AbKdWSn27u3kgRtGB -tz1YkTGLyRFVPCVmSpxMCm4mX3ZR8KLkAHZ6 -tz1hgLVQxzLNVxF7HNRpxGrfPYhcvZdypvuP -tz1YNitrUVF9gtM6RzMShHfoRsVZk4GKHDH8 -tz1aC2JeZJth5tPxttHaVcDgd2wU8LABeuhq -tz1McxuA7pDphmPBZj36rGjyQcDweh9JQ411 -tz1dChgiro2FR9aMEdc1yTarqYicmpuoGSfj -tz1NYB4kupxgKAHDXED4HbUiJ2jxwwJWhibv -tz1RuQjDbFhJmi3zxRmebeDhGqHgcQbxm3Js -tz1LAE1mxkHuthxF5bwL2NU5aWjmKTkytpB6 -tz1NN9GsetPWMLizhDLLprgvidCDznNKf3xm -tz1cwNHazXQrsYDJ7N48hxxMcKsN8y7mQDZa -tz1KvZvGziApiPQLSqbz76VyYJdmVYxfPzAT -tz1QgyjHq311Fb5SuopnJKu8FzBvGR6NLGWV -tz1ND8vUEMvSnivJBQmVxWmVHRfefFGkxAsv -tz1MGD618T58SDPv5ZDHKX6Hr5tPqfThcDcL -tz1hGk36EhPKPaeqogtiumKq51WzZz615eB8 -tz1YeN9oHE84dHYHVgKqDJTD49DQ8bph1yFu -tz1ioFjThzRx2TpUW6CneS7bU3cBArUTvpJt -tz1UG1XAgHhg2yvoNS6oxrpjT1YpBscUFw9X -tz1QoAm9mbbTRyj3gHzYUL3DA3vvFmFvgdsi -tz1TA16g2cBDb2eVs8Qtfms6FgbjZMWHpAHV -tz1fGVyy7iF91Z7q8vWi9zup2VWMyWXguQCa -tz1NwAmpqJNEUGPMPf3kYiYwU1uk3GjqwSqQ -tz1TRtNupdhgSDt4tMDHRQoBcPie1gkTYK4d -tz1ZrTj4GKHJBJfZ8YP82v6d9V2EbLDxwASi -tz1PZAAv2REQubLzqdyRua5fEXfXv2KiVKbP -tz1YEiY1EwYUY826kKTK191ejbu7tuQc7hYs -tz1c2BRk9Wmr4AMQUL3NNNJVr5ktsnFSyKc9 -tz1Mck9hr3TT1EkdVomX54fn8qAjMiW2JpaR -tz1RruBSkWAQTBqgcGzJsFrAaaEqEuAwbWKn -tz1URZVUpBozfxzmRYPXLoRdpZ12yEyuMAsP -tz1igyCJwiBiiCskyVY2NRYHTZ9YrswnEQhm -tz1eN87iLCZU4NMnXbid32zcnzFwf7EGUnKW -tz1gXcpsRNXtCNGjQ2go4Kk2ws55Wg49Gge5 -tz1Yjw8Y9y1G49j44qXKCb8AopHyt5zEHfUX -tz1M4PuBwW7s4d4sdS5USGtFpBYwZopXTvm2 -tz1UaoWVo6Lij1zEZMvPhGKdg2AzTnupXxKt -tz1gDogWYSYC3gToxAskMRo4rLQzoWtUHf7z -tz1YeVDDvLZ27SPktSGwp59kt3BPWGWn2WLR -tz1PLy7eCiQoyxqQgfgh1VndqGKdx2yCjEwb -tz1Rmzb5arozP6rTqrBmpqw44jJKTXqY6a9w -tz1RwBTDY3TWWuJSFcKiRbdGtHLkYVbWZMLP -tz1gnoZs7H3pfzQDCR34Uk3Fv8QeWA8wnJgg -tz1YsfvyMeiGnfozk43JMdtycPevSzEBzUeA -tz1KiRYbGgbshLm29RK3G3NwP2eLDtXwDW98 -tz1NTHBtm92Nyx2WAKytctrkXf4evUNg2ZP9 -tz1LPKwNf9bKcyDaw6BYoqpjdy7cha9aozuQ -tz1Rs6Kh34oUD4CFnrRHiDFDjLQ32YWyKFVR -tz1V2W8sy2MRnc5Co9Sdyt4RPpJ9BHvAyvu5 -tz1YWWapvxs89AJzVqdHYt4V9UNojo1gPhyn -tz1azgw2KF8msE7rReY2NMcGgzZsNVku4QNc -tz1ajTLAAwe5Js9optdBwgtrd9Ba8YBJhikg -tz1eVao34vPSSpDHdmjZVyuDiP7pbSvZC4iJ -tz1ZMEeyiM7fAfF4xMDof5g137M49GbpWkPb -tz1fYi5LUp6nx9iEJRjT2Xg1ZXYqEAHCrdeb -tz1ZuWktn98vAXF9FHVtYpXcowA7mzhghAC4 -tz1YMNpq7Qi5WRaLo4BhP1DTUWuHNimGvMy3 -tz1USXQwGcPFt2x39tEbkaUNNZSpJ9Ht4kvi -tz1Xyi289wRm66PrJWGncSdtEPjooTrVGoFR -tz1MNPyoDD63nU2i9w2ZKJW6KUMZ3yuxB61Z -tz1Qujjve5qpiEsgRHCPQPifPbiVVh8Hs2hA -tz1XrndFCirVpQmgYBifwHudze1XaVHpgyx8 -tz1gR18MNcRqTANRzpbxUvZUvCxnQzSPtg5n -tz1apUSSKFzHMhGTxG6GXWoV5oKXUWj6CyDv -tz1SD3eK4iu1AcH3jpzdisZuvugNz3uCPMKe -tz1LfSyrcoPYTAKoxPKpTrbKh7rWpYnjRL62 -tz1TDRhDkyEYHFyoCXaAiWy3FYReZkMibNvf -tz1bQ9hvjpnb2gSpBgQws4fKFW8achfsiwh1 -tz1bXTyKDESFtPTJ1QkGFxxoFqL8fArqBrXs -tz1LQrBGw85TM22jGYSQLS8uegDdapSrg7R2 -tz1TBspnV3765iKF2tdKfpVwLsqAZfhSfiih -tz1MyPSZ1bXhNxGAuUU8zvr21Pw5WpYSnat5 -tz1TLf8m6jRPZ6GWrmheQEbn7Rg2APPCaT1J -tz1NoqAEwLybVXPhDuDVv4LZaXWLBmZcys8v -tz1brgXqVvPmKjyMMZJxqei3LFZ8SRRMacGq -tz1bCYtbxaUCA168yZTo7Czh1WWUvnp1998A -tz1LU8sk2tC5wByRfxSnnaLLXrmpwmNKzWhg -tz1W2HroHpJTiUPYjdzjXNMFbfjBzPK89TVS -tz1M8XAad7yqFe5afiKEXHHaNPCHVSdPX8bW -tz1MUxcQJvJhSBm3kJJNbcSRwqb1PvibpZz2 -tz1WFnKFyRTjNiwSjfsaBrT7GcRBBkcawf7H -tz1N8un1axBiRmJfjEdhzkBvyoz8bNEnDVeQ -tz1Vh4cX8VutUUUnnjmnY2omSV4F26T5orLH -tz1YYXBPQh2JtKE1bQGTHzjNgxFmGSCcqFM1 -tz1Vsw8UYtwoF9MZMVQofkecQV61CejABno2 -tz1Rpq7kFrh5ajGT95bBQcvyhnjnhegjTxpA -tz1WUY14RTYkQtu2qsfUEWRZdrGvyr9fijwd -tz1ZRT5FNTw3MM3kRVU2nBFzybyB9YBbaxwb -tz1UchcSsDHNMxpZZvrRdTChxaECd3ZT87fd -tz1Wc26BR58sJprFLVEwwe5QDqJfWsQ3xQ5W -tz1T1NcuMoQCRJwwmC66GxMm3UULo8fFQuT2 -tz1h8P9Mf8v3a6M2y1xCUDgqQGxFMvgJ8cTw -tz1XjcNTGMN3JiBpdfcDwpHgVH6EPMfWGa7C -tz1LhcUq5toJcLifYWeqVsqfFgEpw8NzeT1Z -tz1dWT92nfXRmTyDFdxESgq3XmXov99K6mhg -tz1geZV7Z1soSdNPoqPdPHnvtUJPFT6aJ6Jw -tz1ZyVQogizz8YbJm5WELbNVQJqoW4cjZbqw -tz1h2NsbomNZrFYGe31rPFdRJGDydPAPWSP3 -tz1YWnRASmfaftpzHiF3Vxcs7e31b5qqXNfr -tz1YUz4njKjx4NbJ3iZVZ1f5YeNXcPcER5dC -tz1NvFYAbdRpXenrZ6Bu1354hkfze4QP1VhH -tz1afoDwVcKBNEcmfsgT4LRatfidqLqj11eH -tz1QGiEghgMZCGCTRG9VURS1LgsTwgZBioX7 -tz1dvWWMoSiLZV7rGsRGL5Y7JVgM1zmtDzoi -tz1ZishSmVWcQCLM1sfq7tYaux2ck2tXLe5V -tz1gSz5Yi4XrQ9861ZdufCNZijyCe4NA5R5v -tz1RUe8iGQmofvYc7FDrSwKsj2uCSJt9A6XW -tz1NCmKvgBcEqhR6T4htbdicz3xyyKnNaHRk -tz1PLdPqHwX7vvXmXVxo7y22BnYYD2AAZ6fb -tz1i9ZemAHXcaoBrcApM5QxMA2sMM1YMsUS8 -tz1csHsWa9NELZaBdvvmn6Dr7uhm4sMqKN4S -tz1bsYJZr24qfMiraCzVyJ7PHCWMESahCMua -tz1djU7GRBizbbguuWD6e7eohtJDHU8FdcQk -tz1PAGie7MLXH9D1UVmsBJuAmw14ZCbR3r6m -tz1hWzGqnoyuyoyxuhCbspFoppdEevwgN3yC -tz1YQ3KvJVeJwbi3DVxSyKrJaL731jB6442u -tz1i6vAdMTthKxN77Vaf3dZVLCq9fv5ZNrBi -tz1WZGLriQrho1sViU3FNj64WKW5u9Sd1Hf7 -tz1a7WtEKg19R1KmJMf5yLEfVeQc689iZWvx -tz1h6tytkVGzVVdK6osT1ZN5wvvktyv1Sa3f -tz1hPkGLjYHPFTiqxyuq1CbLLdByvWN4yXfK -tz1arczXJAr6UFHi46hQZdjQVLyJqEM1LP4S -tz1NXPX8z79sxdwiSpjwQQNYWxK7UZvMrHgD -tz1MPNoVAsSBW64nMYaSbpUFWQpX7pQAELox -tz1L4SZmxWpnGShhJR73YiJm53dUYL683wmX -tz1L1ER8iWXSJsEDRjpnVLf7nti6c6ZLL57u -tz1h6cVnJWVg5f2oa5WUMzdDiWH5GNpNJ9yK -tz1TVBa8Ao31bMz55RATWDZynQBUV1p8Yuni -tz1W8j9DC24PpTJZ6AkiAYRuCuoVRftfEJMg -tz1h4hg5LYXbHXa9o7ofizYZMfs1AE9ZAh1Y -tz1VvB6VAd3nD95FyZrxWL9e86gAABcrutwU -tz1iPiiZAZB3i27zuBpHmXpfSUWee6De7c5g -tz1azRatbQbSijKfdw3CaRGz9LfiSkVminuQ -tz1XnMCPvbswBhSM1DazJniuy7WqhvzPo4k8 -tz1N1Xro7sjBmRpRoqeH2rCxNdrPCMpDpbq1 -tz1NjYMwFyTXkd6WqccX9Mg1UFw9dffpTFFP -tz1ckgg8X9cW5sc2BYhM6MEoXoyAqCZx9fVi -tz1LaaeqNtEPeYFnyJovpJ3nV8QJCav9Y1KX -tz1e8h4bzmh1vqQCtiuG5XeYNAtA1p4X9E19 -tz1aMcyU69aoVUnCkeQTEJCzKkTWRqLefTPa -tz1gHfY8B9icRFyiJxgPXTVSJXdRwE4LwtYF -tz1emzSs4hwBCboc1KWFPxB2xgqSiyqGUqrh -tz1brW49miUPiktsLpKPwDWgVtCQBKLhgsR3 -tz1XDzc5gZce81NLR6AAiBJtAJpisSnK38rX -tz1c7ccr85nUjZY1RBjvF3n2KZDp6JDk1EVe -tz1cHFy9DSvaFFpZ5SxQ7wxRctw1eW6rdrzD -tz1WprfaxLdysZYbQryeMzQpN9um2JEmvXiA -tz1ViQmGHnYpJsCvAk5vTrNcuZZLMSLWDkun -tz1epnSzV8comBWz7KRX8iiJkBWmum9xpso4 -tz1c7ySCFGxANLraJALEjZHZZocr6BSqZEEZ -tz1fp94J79Qr5RmRSLMEh5qQAMB1Vhbfcfo6 -tz1PjgjsWwXe9VkskDDQgPqsRGtw4wj6Db6r -tz1WesAWyTc8yMZy6Z3PCwz8GYXqFawGifqm -tz1hi8nLWVgKmapNfoVuJ21H2Y14wUjpRZVW -tz1WTPqxZMh4suAchAULyB3Q8wLiqLXgZy9Z -tz1MpvyDCaSTTaYM2LcpYPJ83JtTpSrG3qeF -tz1cjhNfjqY4EZDXRUnddKuZ5LSyyH18QrJ1 -tz1L9wiAmF19XMwW91GS7XcGNwzxB7T16ZyD -tz1gdbCMr3SF295D9t2gQnjz3MQ3KcnnHDtL -tz1YPLYHETnRorG6PnjSCwTXU9EC1pSYFNEe -tz1bt2a3Y7jfA9z54kP2MqLs964Bp5VqsYK5 -tz1hzniG4f1tEp9sPKtQBWQHVgsXgR8jwpHV -tz1ZJ1eeziBhw1rtCrejBfCYRrSWu3L5NJHA -tz1PPJjKqeRei3FcBY6YoSPG9BGmEgosTVYt -tz1RxL9ZwkMo1JmB5LwKwEQgQTRB84HV7bJW -tz1iDSdk1cJZjLk2eRmPs1pw9dJSKUwkykEj -tz1XieaBooJRnSnW2MjYo96HM8uBZ6LAGBFX -tz1gTwWQVbq2JDibuxcS61oNMhwbKKp6CvgN -tz1fLfZo6k8L6rgFZbRYLzWvSWgbootd93yT -tz1ZXcUWDEAmcjwNBdqBviJidYae9W5qhvTh -tz1RMMQSkGmwPFTEdSiLw2jzrcnqCP9EjvLL -tz1RFS2oWR1GXS1JwHUL2ZVjC1gTuooP2V3v -tz1h5ePq4eGYowZmwGNok6nFZ5bfSQnQnRyj -tz1ZBEGbz2PLNivs7K2MwdxNTjF6dTn6HTJW -tz1bLN31i6vgMgfQsCtAPE2KCk6LhkkpRKwV -tz1WkqXFw3iZb41soDVpMkuE1MTEoGu33A6s -tz1Ki9zfTT8j1RzuoJW3pEVnNu8GuKQHVyHm -tz1aLN1BXbCzy91wu9eRp6Ez917HByRUdwSB -tz1dEAo9dPRaMzG3DGNbDDuCMo3Jbhu8dHHJ -tz1Rnk48GdXznMfjwthssGiyUcXYBfabja6z -tz1PJWzhsnG63WiA4bKnmM9EF9tC5NpTCRjA -tz1V8Gf11iLX1DbhPgRHXRSS4PQtMTiHVGGr -tz1Wx11QGCJXi4JGgW9xjrYfmRHkaRX5ZPqe -tz1iacFKdTmQwRPcgi4eqJt5ao5JFk7vpVvX -tz1WcvvGU5kGRhRmokBQ3Ja1K1baChsQp38V -tz1TJcPy9txKBnVgnWtroEgnrcjeYHMV24hG -tz1QSmebfDcnnET1ZyFEJoMAezYg96ZWoAQ4 -tz1edUQR9m2dvd4qXgNCZHaW6V6EaueUC2wh -tz1Y9SZAzJW2EG1sKBHLaeNxQKbzgMQJT95v -tz1TKj27zvXU1V8jr6kf3irFxKF7Pc6SmSfq -tz1RXxH3oBVtsqLZZF8tAZ1SZnmTDV6ctKjW -tz1f8o8pQ6pPQ5woU68N7R9vcoFfyHZGXHw5 -tz1NMDbEqNdZxfJEkfBCDv9cGQW4a2wQEA9e -tz1Xth4qJVzjMshK6MUAJYdpsVxaicrkiHXu -tz1ibzAFNC4SLCShZP3NStQf2vPLEC1ex4FD -tz1MZRMHw8UpRfQUFLSq5bNR2cz2ekUh366E -tz1VuVgvGZRKNEeg29asRycx99UV27HtpUye -tz1Nh4ELDzBJ15KmD3bp4a5sxpQ2bs1CTZp3 -tz1a9R6NeQ5ccc6xcVaEGJSs8GyCnyeCiZQ7 -tz1aFBUuvqVmR6qmJVvVt8adCASyYmFu8NMo -tz1LbfDbNcam2DZMGBHxDidUG2dMN468j4iz -tz1af2ME1N4fvNqHgwDDFLi8f6zRswzqz9iB -tz1MM6jxihGZ6x7Ekb5ehG7wbHGjSSQ1Jc8s -tz1fChPJx1XFJMUmj5VeNP17ERQbkToLGQAt -tz1RT3ByS3JDLvy6FLsPn3TBn6DW2QAyWJuh -tz1iNFjnvsbFh7ALDJtA4mnH1Z4Yki6U2Jn1 -tz1LAo4MvFFCbDCqdzgVBYJ5Xc4QZ9cb6Zbu -tz1VcfJuf2Cwc8qh6sSeWnVrufq2146fdy46 -tz1Qzc6z8L1AFjtBLBxnwQnuitG9hyzcfDtR -tz1aFoGmwsMaqewRngrspXbkKpy4WSF3RBZP -tz1hKgJ7uVPqF52iyrUeDajQHrZJrrQaUBJ8 -tz1QUNS3Pkm2chhfxDjnB9MErqXJa7UabxoK -tz1MWejQiBARvGSkYfbGL9UEBxpnzyTy8uu8 -tz1RLqpeLqaoam2v4yRw2WqzPAVeNwUvBi7p -tz1QHc8wmTGtPZ79pDAeVhAKEGojfEU7zoXM -tz1VzbMBEpdAD8kQwpX4WQvuSLEWvnUV3PA3 -tz1i61e2sw4TXz6VzReJdPqAhM3QZA8Zm9WU -tz1M12x6RWZe1D7Je9iubXffrdfMNAR94j7J -tz1fftTzGPATbxoQKdgYLbWMvgqcGiVbjbGV -tz1Tx49ycfZ2r7PcTQU5jkwYGmCKommNPs9t -tz1ff6sGLHsen5gGCtp1PgxtEyYbW7VfybgM -tz1ewQoSnFB6Vu77Ue8GxoPcJzbmDQdy8gC2 -tz1gB4432cbHxkh4xg15QwZ8pTwXdTENP7k1 -tz1i1oRpQDn4obqB7HSqnbBbN6A4WqLH1Vb1 -tz1c6K1EebnxxSmKGyfzHrfxxwNVuRFx2QsX -tz1WN6iPNk2qGxcnbfrScm7t1YtQGfAVkpVv -tz1YCzUdHwHDoWQEak43Pc3YPYYu9fm7d42N -tz1boQeSLZ7hhDwyeZu4aVWEvNeRConQDEy3 -tz1PrPEduXyErSNFb7HcqkgubUfYToN9MJtD -tz1Zro5CrMCanApqeaoVGXj9NFCEVos5tjBi -tz1a4AoXw4Dkq6nRZGtcKwEnGpJyP3dMKcgE -tz1WKrtq9PTV5yeFSJyJP1qjZmuuTFER3tCg -tz1WHe8M2rhCeRbKLMAZ27QTfAYjaJHHX2Jo -tz1QrKPrQQEQq3bZ9JgqAkStxkF1ogkWnbRZ -tz1VbJoFGTCk3uJxKm6iMozS23rYUs6Fo38R -tz1i3f3av7Bb5kNAQnLERyDEHJRcr8nxLSL9 -tz1UqqihMpeALrfprVPFucc3TyQzEHjN2w9s -tz1agL3Hrt7Joy5uj5zm3XqoLaUxQ3639Cbp -tz1QrKYo5jZA2a8bSx9LhKbSxZVKot2LxJnb -tz1ReTGfqAmaGgF1ZJqGUSdm9CGiMGv4ZRM3 -tz1KzewXiaDSHNZAQMce37F7GycWdgnhdwCf -tz1UXp3bRHxG5qPEwzANDX7YyiC8n2RrfAF2 -tz1YKszkKFgEVpjmYvBzN2QfgZ7e6gvAs39S -tz1UWGNfmvUbs9G8m1ESgP2DsV9ftkHgzyUC -tz1Z9tK1TkXr4Js6sa94Wd6BWeqoCAwSUqRU -tz1dSQ6Dqdukg8G68wHzWSWTrQgR2d1m11FW -tz1M5apYDnHo7jhABPRpBRFpY8Sc8yA8gChE -tz1SFoNELYsRDHj2FYXufs8bv2AjXfkHNUhi -tz1ZKNF2LKNXVtTA2sbEV1ZB6bc9zJyBgfcL -tz1Wx9ZaHKRApxYS37wWXwuvFHFViPqXNcFX -tz1eh9sFbePmPmVZj6YvgUrTiQBCJi48s9Hs -tz1R5RsLomLJfSEFx2aoWE3jfGUgyVdBEWec -tz1Rs8JwB3ztDkFsNdngVfXiszaQdqGUCK7n -tz1cbsyBCvEygEpaeodfxqcLXLaprnkSkvuB -tz1eqsC7Xydq6yixR3uq8pashWZ43iyrKJVH -tz1b6oAsmSYrogJJSqq3z1ycxhU2bGcqfsLR -tz1boKG54izWc4tr639V3HzTC5ufvXR1Rs3A -tz1gP1auUm53p3VPCSbfSi7zTvs9gYLaNWuF -tz1iaxjRURiDKZ79hjb2tTH4AuRqQQQAHPue -tz1WdsDtYp9EzKjLWJ9Z9aQqz38ximhuDAgT -tz1SFnq3Xp4wVXgudoXe31vC5uk9SYrb1LD7 -tz1dzau4VrmhMRktMap7AnnHgoUoqkd2CZFK -tz1c5m5RRzbGMzroKNLQkwidq36WuE3PW6ZK -tz1LSHW87t4yPsf8YBcPGkunQGwbkzvoXBXJ -tz1gPgYLCufrv27eepo6iijbPyzSL5XY5PsX -tz1Q35cKBSneUt63L7TV7BDYvHtQGreTio8w -tz1XrwX7i9Nzh8e6UmG3VnFkAeoyWdTqDf3U -tz1ZjiyZZTsxTdih9nyZjgNddEmUnLqaND2g -tz1bx6kLYQoxm76rNva2HynZDjtyQ1JH9yA4 -tz1LuxkxGkXx5v5YQ1Mvu9GE91oHhnKTE81Z -tz1MZCVxbczAAc5ZVusmmQDUGeWfKsD9c1yR -tz1bNcxYnJFxaQDG1tx63Kn4ddfqE9VESaVx -tz1XMi4NgLz8FWFaHUJ5HJYs2EEwPrWpXrvM -tz1deGfw3BhMVwBSLYAXm1zEWHY32ZELcrnP -tz1UZM6KM91i3fLa7dnm2kuMdsJBTNU6kf3o -tz1McyixLhiy2V6dWvG112LbH8w4BkFnrBcM -tz1TCZcVgNzJiXsSC4cwhKGaP3BCtWQRqPr2 -tz1gpiofFFtieU74QmWHNaBFchLimZCQ3Ejw -tz1iiGd5WYLQRTQigYDU9gg2PTs9b8k7btRB -tz1V9YmVNvigCd9ZN3korEKK46eM6ajKVz2j -tz1Wj5SCpYBrFb7XA8FRrt44pLe3WWqXvAVM -tz1ds3Ecq3TJz8CY5oKR7fHdcuCaJKBwGJfk -tz1fDgZMXgmQMjDcu135CsNqzvqdDnnSqVcb -tz1gok5s5vdSh86Rbhfd5qrKXwsSxydbF7sT -tz1XCQujnE61dHnfyUu6NbZRUb4NKxdXihCR -tz1d4zPFFgQL6m929MEZwJ4r7o72G3WS7TZT -tz1i6JtPMSs2Qb22DoqJnJMgo3dqC7TVQf4w -tz1QwrzgoeAKrknbivVMTeUKVqEYwdbZmnHu -tz1M998xf6upaV1ccMKpR65gSdbMZvnyfNc6 -tz1Lz4V61YTYEWZjMwzWZHBrYGmofh6Bo4c7 -tz1Wmuwb4Fecv3hLQpqLXMfB3ZSouJehM35b -tz1WTmvP2UWK5SqPQoSBeLA4vJqRj8mwgmmC -tz1Pgd7JhXc2WYuFjJ5iTqydYVQ7r7ugdhrX -tz1Xn3YFF538YUXfQpRceHH4TQvEXteU4VBZ -tz1RdvdBWZy862xh3vpUpnQdXSGskHpsgsdv -tz1NTAfFeFPM2WSYXgSJahjVT6Jo6VgmsNzN -tz1cL3cqxanqtJDPLN4obGLT2NmAQ3ppMvrJ -tz1SgF5zx7cRdxNQTH1UHTpJkr2mt4GDix1P -tz1UrnaZezpZ9CGaCASVM1R7rhk4GxLYzHUJ -tz1RFFdZfJaaYvipfQeLuFXKnMFwiXzmJ5BX -tz1fhMPec7CRQYn5QdtzYP1PkNojBcCFxL8x -tz1dY6bYwf89TtNivdLHx1aQYRWRE7zVQ9Je -tz1QupytoUoir4o32sF9D8V9DeL4DLEfkEt9 -tz1S39MMwZnLgcFEyCGULcpLy6fSn5dGcepf -tz1aLUomZpoMmX2Awqjow7CXBPZT1SL9e723 -tz1KpGpFkyw2kjFA5aqk1aGJuYV9uHZXLs61 -tz1e5iAEMsK2ubGYHteMYihPe1opNdfffKJV -tz1ZwbwRmuAhTkJpWhDy7atsuxpUp4AWywEv -tz1aB54RYdF45nDRbXewXsaajrrTKoJcLjjd -tz1V5ZWBmoB9Nhri66hws68JKTpaQwPseEwg -tz1McWV7mtctAv23ncfCkPSMVRQzfyL8LvTX -tz1QZLrtZd6Vap9jUKFAZigqKkfHckpg8Xcb -tz1XLNaTSQY1b1oZHVCgua5ZD2AVPbkhZ7Pg -tz1S9hX37rEdmJ7QmDtGunZDvqhMKjbcPNQB -tz1NaDpZrZjcqaspwZruMjuH9wRFHq2qRFE1 -tz1S4SWBjZzjQ4dGnFsLZ4ekiSULFsxUGwhj -tz1Rb2VCth1C1p2YDLsoa2cqKZWUvMVBYcWh -tz1bNh5G6qmq2LeebfArGofZWMzgKyZ8bBVG -tz1aBD2JvJekor7tavRyrmzqowX3yenxnSPC -tz1fZvwcLmDpZpp8QTuKo72PQH44M31veibp -tz1L8GL2V19iyBnugWibig4opMLmg7VjKmPz -tz1csa7ZTAkcno4syPdUb9Zi579JnpGfWpyG -tz1Pbf654V4G97pPecAGpsteveZASdGfvUN5 -tz1Siw1EWySqPXvYnEdtoNFxZL1rfKxiXHMo -tz1iveBk6VAEMaU3FjDZXKxXPxBKJ6DbonA5 -tz1SW8dKS8Sv6DnBsxq7VW3eEistuTXwUBPN -tz1cyGUniTxbzuMn88a1hC1KkZvvXTsiLvAr -tz1PokbptxS11y83gHuKdcHtrQ7kgdXVqA9A -tz1UmE9WynfL8yt1nKrREfRZWdu4ChoSh7jF -tz1U4ZcYuUgE42WjXbHbTbM2HutCzzJR7q7w -tz1KsXFMho9bChukcRcWnyfKxBAhr5VqSFN9 -tz1gZHjDATyF7FbBubpg1oL7vmUcZVYuMmGd -tz1M5faNTveSwMgfbnWkNxnRR8CtG5Ekeyam -tz1Uq8YC4qUF2KzPifmMDcpuYUoKdt5tPcEZ -tz1iWoW4wuzfkxAbiTJLV8tPDV1ERVu3Va8u -tz1RqdidRN77WXh8X1bpjbVEgfJbrkUZMUHF -tz1fRXAJuhSrnNQji9i9wgAcTjiZwwdSbZ6v -tz1Uqjer7Uhm2SEhn8MqyLB7PqSL2PAsjmNx -tz1eeTmEp62qnfUuhBQbeHkWjmQmajQPqbfE -tz1QvUxnZYg59yFY9sfNFkroNU341kkk9DEP -tz1cJj8wLaPrm9zKo3JArHtaByQF4zjmtrmB -tz1UcaSTskqgHsjoUFkCwYgZnT1sXbpUG2TU -tz1TYSfJJrK42D1jTnX6ySWEc1Le9VFTH6Fx -tz1Z1EwWsAr9kMRZq21hqmmbsKJWxdFjBo6K -tz1UCSCR5NM2TWCmUYPQq8Ab2DkWDsqjkoMm -tz1Sv52RYk7NP9dTGibKu5mMLehfeMXN8utJ -tz1auZ9Q5eJM522VVgGgNWfHBaf2w6VqNaT7 -tz1ZvJFUb8fiRMUEQqfpZLr6TCkCFm5nKo7J -tz1MjZUp6UM6RCVHTC8byb1jCwNE2umy7s8q -tz1bH7Qos9fg5MxQA1HizxU1ktrWnMwm3B41 -tz1g4sx467Ni3PwYZQVHBDMc97PyWdovbHRe -tz1cvrgSekgCqgyc1c2qFPSeMtux6AAAfDsk -tz1WomkpFHQRRNWiDNpqvR2gEuPsu83zzYjm -tz1bXhskb8VPQm2ucTSEWChoaYmNg6tMemMH -tz1aDkA7ELrAEKJTDHqXoBLASptVVTqsAEWa -tz1czguhBZX4GfpUc7E6egcBgxWJKbGyYJmW -tz1a9cLp4ynCT6dcHRE1u5DZAEyUVfQpXiVA -tz1g2cKqFGK76qoMdu2thUGYRRbxiSBmTXDm -tz1cbutNTS7v5jH5s9z9gTHWu8m6pqkU45bX -tz1X6cMGTrLLmyuJzDQvUgWnSX6kJhmdfkHc -tz1VtHaiZsosJkRWRgvuvnJ43kRNNVoAAxJf -tz1fCPJJ7w9NHeGkQTfysmp17pL1R9k2P54M -tz1W8RLZErzBaKSGb2LusyULudvJMLFQTejY -tz1NRhLTCpFSpKzRPdxoPk5RbGm2AZwnZXpa -tz1YnynhjN4v4TzNfteMkeTAWuGsMftY4bRy -tz1VPDRQgHyckw6ZSPxaNxewGajK9rNqqvGX -tz1dDj6ycNpXXGeKNXvs6srAzas7Nbm1J1i8 -tz1Vb2LvYgpxRmcD3dNGQDtzYqmj4CqGgvy8 -tz1eAMNpEhhB2CvsAbU5P9szojcTBwp2skoA -tz1gB1zAAnEmMy6NR8QtP2kBU7mUfrcm15tA -tz1PVMeBbCXCVdqSpxCBiNnupx6c3rpkk5EZ -tz1Lfb5xZQrA1dNNoRNycsGxnwHUxihdDLKU -tz1STup3rPh1oqp8pneqsfMVCYvG2moSwbCu -tz1e2Lp5wY9YvxqkcNyxCaEJaJKcrStfWtkd -tz1ab9m6chkBQ9ZTJK22viR78T8umB4PMJRm -tz1NAKYWSp5khKcP2QK8Qfa3J4gUojvgZrdU -tz1NkztsQUmR9mXksrxfwJ2RKoH18tXATSfe -tz1R1ZWFGC9ftiMAhHaR1UvMo8EjdmSGAUJD -tz1Q1ADRhoWfvkKeehRr7awdzUccVcbjQdbh -tz1WysyCQFyhzMZnkhootLk1h5oro9d2Su99 -tz1XsxEHw1eKzL2ixxdy6LAgsVA9cQHt37vS -tz1NmFWh7LcndtxspjL7Nk87iCSyW2TLKQcD -tz1d9DkDGSgWZB4MQzUAQUKUGNME11niyjbB -tz1Uj4CYKkoeBnQSb1tmH4YPc1mToLTYcLLN -tz1N1UeRZtFtsS3GQv14QsQg9WUHvZMCr5Yr -tz1hVCb8V2Thk3XQct2YBfPR8nVwhMZA9EMV -tz1gk9i3ZaNVt3E8HgxebHL9ewV7XNHZbPXU -tz1VJ9EWrA8D79TkNTwgMi6vadFCE3PTiqhw -tz1fYd9oNN2oQfju3kqdogU9FmrqhYDQ6bvt -tz1TdSAMjnBoYbMcR9z9JAWZRfokkqMg6cWD -tz1aTM6cScZdafgp83jiTdMKcJ1R73U1o1Gf -tz1PzW8udkU5Tpwwtn8Bz2krosPFVVYY38qE -tz1LLRudxsDzVvKHZNDf4Xwkp8LkuiwkSGWn -tz1aNDU8Z9wZetey7x29GSi6PGAM9MsywHEa -tz1hZor5VPe4r4kxrkkby1JMJ7HhiCpPtgRW -tz1gE3rqbA6aKooeoWHw3KTwQ622FZHA2CWc -tz1P7RiAA85hBW82F5J9D63xvWGuFrdowRCD -tz1gW7u4ybGm78GdovqePwmzhT2vA7d6AsLq -tz1f7jdTZTSrjxK5VUNdTZF5hHvqzETPethC -tz1LKhVkwKvDD48NJFjLguGArvhrJv9BbPDQ -tz1T29VypHxs5PE19bp3UJ9Jh1VCvQFzjMy9 -tz1Z2iXC4GGATARteEVrQWH9zixb3V2UK9hX -tz1M1TU3iNQDN65qXVeVLYPygArMTgYSQ7JK -tz1Nd51LZHSQHjQA1BGfovcXxueseXbrt9vD -tz1dGiYQbnnctW4dpXwCWHtaDUrkxNsddyrK -tz1c8Ev1MWnLj5LnCNj1adaifGG7SEaPfqZ6 -tz1XF7GPMMEEmuHGJmP1Aq4zuMnhvH8DG8zA -tz1Q9f6vhR3spAtUA4qZRXoefCGFyYs4xAxn -tz1bFuhdixMpua1nWsBygcgNDzxybnnc2NXv -tz1UBrRPdSSJmHBrekJfFiPrPNzhjjkyRZqe -tz1eNyDbbQTpMgZUTkZeAtVbYm8NF5MbgGhz -tz1buqiVSed3PHpxhDWK9YvD26yvoVCW5qHQ -tz1fn436k7N8qzpXPFEm5mrKbY8L3hnEvaAW -tz1iGLuLfBLEFenYLqUmcV43EpQHMuQUD1hh -tz1hiKC6gXnXUEPjdvpS9fBrCt6ArpcNNf46 -tz1Zc8xjk16nKR3zTSGhMSwLddMpb6sz2P7m -tz1V32ywrXQxH21Z91ngBKnW7ynzs73FEGEZ -tz1VySKskgwUaycnipVKNJSDgDK9BJazwh2j -tz1XdDvrUgD4kWDuaBtLWBvawx6kWT5GyP6r -tz1UXTRtywQj5utnrYn2Q3fwoAC5vtFQNvBU -tz1TeUVup3c6gnFQFTvpvxApzmtorUWwLr4d -tz1cuLDn2xYUsNaLRfvgCzWfJvoMumLA4Q9z -tz1an96fZn43AsRxgkqhrbsepU2CJqHVZv9X -tz1h7LaGTsi4RFPcPhuw6qZfzvgmGatdnzWp -tz1TEHFdEUezFMZEnQS1pis3MGRRkLA2NcAq -tz1a7DysvrmyBne9eMKTospgUhCESLYGQyUJ -tz1KfbCaW7zubFT62BsAtdRezrXbwPYeHahf -tz1W3pFh7WH6BX4d8HQDhANoCChW2ZtocSwU -tz1i3pNANk36eArTP6T4Rr9qJ1hvAwwEGWVc -tz1csxivrNw33EK97HCiMXZpr2xPmKhcS1Qq -tz1LAd9a9HZpHJvtRv7qAwBHLxxCtwCuTRnE -tz1TLxa8BFkeemUMYWodDkSAd7P1mWrVYwpN -tz1ZPAQ6Anv9rdKXREnhBxrPZCQgkM9yB4yr -tz1gjaj4N6UczMYxHQ22jh4WnjD9F2nCuPsv -tz1NAheh2QeyP8FfMqr1PFji4RzSzYrQ1TMS -tz1hWJuESQwEdvQPk9QT4EYEh8kXRAEUndjT -tz1gZK1Yn2mxL6deBbxSakZNsnEAX83Biz5G -tz1Wzzep9wh3oRcp1TcfRRJdWLXucQ2U2hEm -tz1Pw2v8986xcNyRaAX2fyaW3FiktEDGTHhE -tz1i68xKf6pMBujMS4NBKVhyj8yYHfsoaGwT -tz1Tgh8BXtAtnXoptTciaNwo3UBa9CoxVncT -tz1ide6rxnc8TB5LzYKEKzXaNAuGFZcCi9Qb -tz1QPNzVwUs5WrhczoYcf1UvXocZghtiGZJi -tz1aAYYriVk6GVpM8urcNkyJqijPrKpadmJB -tz1foeSbgUJ2XoTDN2ZNK3SXZZvb9J92DAFf -tz1eBZgcf7CETKYaXivYUbki34jNLsspqZ3V -tz1iv7AKfbk58V95c88yMtHfGNyCms4qyQBp -tz1hGu85gdVBoKmgGbENfgGFdeXg16bAs8nE -tz1Ny27DM5Vd37jb1guhSeKYb2vqXWa5yG3t -tz1PidkgKdjJV6vWhPkr7VzV6XDc8cuL5oeT -tz1LkeGbKU35Vs3Cr18efAiLN5xq1A8Y7f6G -tz1Lu2eVhkzL8F4AmkATpPiZzwirH2ezGtXM -tz1SN24PTqVPCN8xs2mPEAMBswrNFWDngqHg -tz1ef7DLVTvcstjRdZJfQNmdQ6UADhKCLsQf -tz1W55mZyUxgirHfzBSjBBhTaA6nihhA6hBk -tz1KrJGuvxFJDvVqhFDXZS7atiM7qH7N6itu -tz1WoFhn7vRYceoEPyvVnc9bVZUY6a3iJi8z -tz1RwFr3YNrma4DgsMCczbkTbHo9skkz4uSZ -tz1YBNB2PEoHENdF58PXrxQRnCEjDWNRcGJk -tz1gETCpLYoDJqcpwLoT1Ez3DDjdvnd1GExi -tz1e5qyWfJveTBPVhUNKeztasLGkPiKhnoXy -tz1SR4reAd5EQUpvbbo5nAdKwdfr9FTjamHt -tz1hmDspj6tJfe6QVZXmaUzRAGVRssSkMe6w -tz1bVKARgL2eVQnq5NnHpuoc3tyYxumwG53U -tz1N2PgDHmp1f55w8AoaoTiZQmZcFVobT7Dq -tz1W99qh26X5p1AP2EHU8KUDNJsuwWw5jknz -tz1Riq3ArRgV2rEYBjHW5neGsubAR1YavMwX -tz1d7AqishCsRevwwT9h7XTRCH1RiAK3B5Cv -tz1hpdtB6hPKTeLDHyYq5tJTxa7P1NBnTTUV -tz1MvEpL134eW6GBwWo6pESFro83Hmic5ZgT -tz1aGvevuyHzfFP4yk4C4Z2GcNbv2zNW1Jtb -tz1LBGNEBTMYLRmE4L8d2ypbUSPWwGpUPnGH -tz1UDv6odkWg6JsefDRfQHvQfc1LgjbNA2Rq -tz1gLsieUyhHYvGM6cqQmqoSJA81sNpPL9o8 -tz1doYtRgFhWHBEapoYzJg1mKmkXsqM3Rb3b -tz1X9aBSj253Lfi33UqLSf3mZ8Ron3Ud3bAY -tz1LZmK8Nejdz2K22KFcBEi5XSxhfsTnwWvD -tz1QJt2KDx4ZgXTvqR4UWLMiHgph2yZcUnQX -tz1Y1y4cNwQ9sZ5EFMZ6Uj3kzvjzhMjTpycg -tz1cqRjKKj5f6p5ANKCNXL8hRP7sPHX6NECV -tz1ZqcLds2KfkvHccj43hWzcYAPPVTqeD63Q -tz1cnRF92uN7jbxmPTVCFN9kVJV6vYbZmkmf -tz1Pzw6FJtCZC6F95RRSX3hFQEY7DypqdaZy -tz1i6ixDCuctxUD57ZBu1NGTESbATeQmhniy -tz1LU9zTcnnGDo3DuVRXrvTQmUVrUMLx9TtZ -tz1UcaF1gMmYvVSAE8ap4isvqzq38CMsCcya -tz1fgSgp7q4PHVmV4J4hiWeDyK1AdA6xoQHS -tz1N1jVzGNQungXdGc8LgNyteoMvaQ6jn5hR -tz1cs4hUc15qY7AV2eCjLDcMcUFT37u9Wvpm -tz1cUrZSReZLWx8Vd677Z8y9gTAtMTzs7FSG -tz1VPsqrAaevhcopzt2dbzestTmpWWxv2udc -tz1PjTTwQBuAidotQSTTzPU6LMgFsrJLX7cN -tz1ekpt6VT7bfuaUvyL2TPLCyiFH5Ky7U37Q -tz1RHwB2FY7dUhdyeqFUnMfQ2hd5EtedoJ43 -tz1P6XqBxw4nhcpDDGGYATrTJ7eAXz6RwJKD -tz1N59aSzfCZTaCAfMzDCMGDY5j5yFq2qo5D -tz1RSNTy5rjECXvCiXupHbAeKgR3qQzB6kjR -tz1XPBiN3LsPt7a3GiUBrAotMSpLPhMv1ihe -tz1RFEcZGDTcNZTGShbb4E8YWUzjVBRihj7V -tz1TTUaD6tkyzCaFKKQnn8tjQSWCexj9aCkD -tz1cY2bfoTgyL1ZzpqJFjqMz5P3YFzqXUrLM -tz1Y6EcHEtSsrkkrf1Lyyd11XAWUXQpCQHmd -tz1UotMPKwd1kYySbpdtSAy9hD9WtVjZHJTj -tz1hGMvjJa4K9oPTHQbYo5SUdXNtVDpEKVrW -tz1Xa1X7Mu7uprDgmz5DXSeoo41F7N3mjZPr -tz1h4xCcVC94QQR4hrSBXh45oqqDmcbTrfYx -tz1byZmt2naz59sc23r5WdJGDobK7nyRAcAc -tz1ZcKt8A46vuam4hQSHMtBWgFrDhHnYjS9q -tz1WZqKRPBPUibFoZqFMCy8A7jvJTP3Kg4Vv -tz1cNQd5MSvcpUiwpBDUU2NuaRtkpNEWrA3d -tz1ZyFPbuvdGQbsnFinWvrrMmdYThkz3KcNt -tz1X5tGV6pbLgATJRmih5Wtgd89LQSH67mkj -tz1dmuE5NpY7w1fNwDZyEewmKnSj1seT4yLe -tz1ZUNyjnnkn5WEaw4rsN2RHsXzkvUqTanu3 -tz1em7YrJtWLrDQzSDtKfsESqnQ6ovJEzsMF -tz1g31ipEJkL9qqojn8cue7Be1uh4t4DhbEm -tz1ZFMpXRgx3j2ChQCbFfotsTXjmg6ERwmkZ -tz1eFgy9vsSCfS1Ghxz1mBSuMCwA9HA9gaDR -tz1KkovXsC3a4mDXfmptNfYKJaUo1fKZgPuL -tz1ZfMXPNkrjaGM3AXFZ1QT9weqGJ17H4Spr -tz1e9AGhrF771VGaPcKRe6bmMhZxUB7mpdAM -tz1XT6AwbixF7ney95rDYwfiiSx61LAyTpTm -tz1WcZmNVoDVMx8pNcsv1roGuzAWFbHDgG6N -tz1baMP3j98qTStsp22K2u8TCFsTKMeEWHxb -tz1bzfNsh4aeLM2XQnXfzAZE3CTRuU9xkSq4 -tz1R8mmC8QHEwpU2jYXvCW93pus53YyfWDiM -tz1czcxXThTe384469qYyu5ViKLwBr3yWJZ7 -tz1fSkWLxCqkBLE23am1RUVNxV5QmUbsxkH7 -tz1NGynWSAHcKS5GU6K4mRsmzr6XAw867b2i -tz1eW1uiZgujyAH1EgVJAQUy4ps9MoxJzdGX -tz1LcnnUX2ac3451ooJZm1aCDBafjPAuGacz -tz1eJcNdxqDEK2cQVTP9xkscBzt51T9zk2ag -tz1iVp3YHYZzWvv1r7rpCd2Whx3GxkjA8ZAr -tz1d5MUxrKNK7JEgDVhT5iwBy2U5YvCNyJp7 -tz1ieR12BYU77DDKuCQ26F9kKRk9aXA5cY2n -tz1TXQpXgQ4ynzfWCJZKN857YKPddzGUphZF -tz1dE7EDvwnTDASuHyrULLiTuHfXFc9yzx42 -tz1hgBmqAucovNjMoM7qFmjRhqyvwPv9bM8w -tz1TqMHgPXmZiU2AYfrpxqaP7gQqSGX8FP4r -tz1aSVApwPRVmiAhduAREibbXpZBpAiJjm7F -tz1ZbvHvLrVNkhscqd1xCEmsZsiTQdh7cQcK -tz1i7QaroSPKTKKWo4up6dv2Du4GbfHnNjho -tz1PsW6oNRjudWxCFBPhtgHJsSs7Rdn3DpXk -tz1L9unQqZ7vHs7QKQFVGSMMYeHNK7zRToam -tz1aMQXYmxeyMiMneaXg61pxcpFVnBqkLCFU -tz1f49cbkVAkbgLXm3Du6atypoNsU4SmfTfT -tz1PUcnWFxQ3iLTk9JmetGoVD1yLv4iPCyr4 -tz1ThHYJmHgx94eQwd2xRrwmLtKrdh7YqFoT -tz1gPX79o2K4gqAbwZE6EhMywYzSNttASPUP -tz1iaepdCgppiSgWwWTcD3k3Yaw1ZEuL2uoY -tz1fAuLA9HppLvSq7dCwhvuRaKG9xd39FcCU -tz1ZdBgrXh3vMY8ZS6sGdiBwGUDESysAU2ME -tz1dX6npSPEVQvcRoXC8ahh9ZFUkAVxt2mwG -tz1ViVNrYKmbfYtrJCkdxcjMXpXmHKvRFMnK -tz1Ldy2uV9y96UyjDLeNy2Gw1o4JmPq2D29T -tz1a5rdgmXfVrVBr1Hx4y4HkELrVP1HqAuWS -tz1YGfC6bzSYjgCfxyEr7PBKEzcXfGTJrgmQ -tz1dMxLHBcKxUFKEA6knYjj9YVgvCeVGHPKY -tz1RdiNoPSxHKyMa7YhDVzaKtDjLPCTJa2yu -tz1ggMtDHkEpcUekEwaEwtYs97K5qC9vKznb -tz1gB7EWgCGVubiTUGzZaVK9PfHtv8GqmbWF -tz1XYFetM7QS8UfmYwTvj5gCiCyJdkEvG3CU -tz1govqxHjijLhXDVJGM2v6ngBA3LwFsZTHL -tz1NHq5Re1ZtUM1LJaJ6KS9iErfehvmguTUR -tz1cC1rYX2cocoKLAHFTehiiYki9ka5jTWNg -tz1PxBAsB99G9UcKoCHsuHfxbskDta2hiRNJ -tz1RUJgudfs2uLRxTqDvPBtWCP3WrMwnYzbV -tz1PHxgyzAbcmDU4AwU1RUXwaW1cJ4wq2gsB -tz1LmJM2ttCViWYTaptT9ngGwk77euvDJZwS -tz1NtUfdMncAzemWXUZ9dBPXjzPo9BT32mKG -tz1iDMeuHo5gxX3uGYHyJkvKhz92AyN7s2iX -tz1dgoeoTX5XZx7E8zMb2cHbQu2s16SEiXhp -tz1gmAaTpeKFJmSLTpHaK69r99YBeZeMcj4p -tz1fF8eRdW8i87CnMbRdgaoTJGRRrt41kHyD -tz1TVAaxy7qCFgBwhfdWimtuUVAwmyhs8Hnd -tz1UK6xs416oi6CNNR5oSjGgGs6ZN7uJhPCv -tz1Vib2wQoEeWJQaX2THwgUjftXFv4Nox11C -tz1c21daQxxqFLdpNwaNGAYQDtoWMh6BZmdF -tz1MU7FoztU9W7XK3kyyC6mHRFEKvtiQQESm -tz1dZv86gSv6GV7S6kTrogbdeuE6uRsqE2i8 -tz1YLdZ3uWnZZ8WTXWbq7MxFViPfS2bpp3zi -tz1dfMkL5u84rgYsv3Qdgn1S61a4zAmpMDyJ -tz1Nhqn33LT4t8LVJ76UuF43a7aeiLnmzX55 -tz1WHoy5evfE2rG7h7ZQQWEqz5gYokKqaNjR -tz1eQUdCd44cWXbGwkLtLh4ZMeuUyh3zAGig -tz1ipPvBcs3DgxwLV6S4WSB7ujBCWxa1NyNf -tz1bBU9xSkpHrC8hMEc41qPxWc4hGbpanfaC -tz1LUNKAsKpCupqJXwBEWXMaXEqh2iw8SiwR -tz1SRhZnoDYFAKEXPmpMvSmnYQhkLdTNB9ud -tz1iB1T4TzuYqe3R3rfRGZnvJRiThhAo8PQg -tz1P2NPJUCVdqvUNjUv3JhoTXus8UDtsndiV -tz1QEShoqCW3u2W8mgf6FouWJUkDegNtaFEA -tz1WUSU47M6SzzEd5RZD6hkH1y8RQynXYnAE -tz1ajpRvCqQcmUzwSCFHi2QDyeXde6mBzqav -tz1eDgbXk7EdhfhH3HqM7jWfwSWKB4s8haW1 -tz1eXBRaNu6eKPRybKeRxZ2r4NDMBA934tHS -tz1hKxda3XRcPzAaE97H4EVCvtgxHtB2VXfy -tz1R9FTuZEnYkjJTTwRyTPDw9pYBHMFUnxpy -tz1hKW9ZbV7U1hb1zPfrE6HG5UWsKt6eppMa -tz1cL8DEGa4y75JaggKzwKvvbhNtWb4KiTWQ -tz1YXRFxfuvSe6pqn7raW87QnxmGS6f7e1zc -tz1SNQDQxZewdMNqQhxVMDyMBAq5KkXPKM8e -tz1Lavw8YTBL563ff1pLsigsupBwX6TJdjaV -tz1UGU8caxft8ymnTMXzLA1WUaTCQnMQwn4o -tz1MVYEHrQAf3aP4nxdwkLtVg8BbTp2u8Vqv -tz1V2Fgy9fAq86yz19uKdSC9aNQA1MVEMsPN -tz1R5JEhoM2xmPyATaCSDMwyGqo9Dgx5ZG4Y -tz1KxCWqCyjbqjehcN7Fzwunx2LGHy4J23tX -tz1i1Yt2q8qDUVCYyGSnZKNHrAjy6YF34MpT -tz1SGtEDNqVwS99hhM565KWvMHRGVg9CJeAX -tz1NsiLiNSj49r2ZcfdqE47cxWbeGrWCWgmZ -tz1iCM56csiJCBX8WNfP8jabXGGr24Nqr6gQ -tz1ZABJbCYbbsEP1gqqJVcWeLKRkevfRTiE6 -tz1PfwRGWaYKZyzXtdzeX7ARRdcsJbNpPX9y -tz1hqmHZaTnJUUPWScEHFsg5UuFHrkcvc4zp -tz1X7aptKTGV6cGkjbi5DZpNquEKmLtLe7ua -tz1cenmY5NZUTfbNJKnFmmD14jMgMzCucPtq -tz1XMMtt1S99GTQiYoA7yrxqxpf6ULQ3UmcT -tz1awKoB7BJCErHFDh8eDrvrjNBRpJB4ZXRF -tz1XddAdpYkg8XHhYFvSqTW1rKP2aJswZWF2 -tz1PGUmaubUGZXLFADPe6TQghRjrGLEVnvXw -tz1gF1jMg2GGhCyhvzf4QKVwNWLvvdx3tPY5 -tz1QpwdCa3eTsRe7gVCnK7j4YQNy5QrAqn6a -tz1Z9gKAmFGykywAargrvEPCczANKFUuSeTQ -tz1aMeNZZbFHDzPn1aN2aT4vkhCMCMYTSpYk -tz1V3VQ5w97tPZ1EapZoXsdmq1qVgws85YMG -tz1XkwHMEWKXDw5E6MWV1yj4BNw6QhqsfiJa -tz1fhYzahJnWY6r3kR6pPv3msFyej9Poiemf -tz1ZThttb554n8TVv5WLsmhJnht58jBSLJk8 -tz1cs5ecpmtmSdswAmLBW7pUYxQzG1bsYRiS -tz1QGHKdyGimFAa2XdkHm1Fdaj7cqiC92HRG -tz1QB1DyqcNuNeMYeYjWaC6XAwQMVLiXhjvE -tz1b4RvuVyigHm8JKs8JWcPQ9GLNpn7WEnFK -tz1bJ3LF26sN1eEZkXDbN8BLfGeFUc9R8Ncs -tz1Viou9RVgkzRzr6p3Np3CSskpiVRzdAaoB -tz1SzfGxgXtG7vtY3C5R1epcMWa3qAiynMcj -tz1N9s6MoCphJp4to78AXSdRbBx9gAq6j9A7 -tz1fs4GQ8EQu5gXUfZFtPARYiDL5ts8x2A5g -tz1f5EcYyP1UdLH53iagWR223Z6Ex8xB1uid -tz1dqBmCvbgsc14d6JhLbEbiebB3NTKzn6GF -tz1cEzG7K38bTLMuwEUHt36s89eACtxPYDvr -tz1MsJEaseE4LVMyP9mVf15sSc9skqQgh3mW -tz1UGt6yfSYBxUWdiqb7A6CDKHSQDUAYehp9 -tz1cCJMkTLq8wxbhGD8i5GXJFgrdmxRt5VnV -tz1Xn5mMxAMiqUzrHz2YQEgTXVpxkDi2RTcD -tz1dbJyyATpmYja8aeJqsDvgKXQj1W5u2CjQ -tz1f9NefdZrn7ooXjTR4qXPHruVWAP9UTXk1 -tz1ZgvXFtiDaEn8HhknUvaogeU5DUzDvPm8n -tz1Lt53CZZcBhnYrAvLoBHdg7yenismbNrhh -tz1PAx6ME8GPyYeqQ7Tmg9b4BHrjPDL2j5eM -tz1UpGqZwvZNqySd53dGDV5F18kJxwVi1jHy -tz1NpQRYg2Lh2CZmfssQJyp8D8DUBn8ntHfd -tz1ixXw1wRhcMvpqh5SC8rGAqBC8LUzERoEn -tz1bp79YX8nD5a831cDRYqrhoGszTfPfty4K -tz1PhRdy8gwVEwXHVYbX46GsRtNMb5iR5wUd -tz1h6KecUnoFYd5uJUMyEGhuexvNbiQZSfCp -tz1gn2mWC1tzwwtfCqNsTsivHQNLepUHxD12 -tz1ShuQDpGX3QkRuz9r8rxCVviFG8QUDEtGL -tz1dKy8iJMo8E5ryKCAPS4YFVnxTCHpJGMy6 -tz1NY4zbw3Rh3U5qVpH2QUSBqWZEog33CSvY -tz1P7hH7e7qiDdvZuGbAPYUsYGmUk4k9nVe7 -tz1dmZDp7jpnQ2sKxPmqCRHuRiUa3i6KAZcg -tz1NVU2gtfoaXkFKds8u6kTAQyDyerTd2WRu -tz1hftwBgbZFSb4mCFakApEkG69ip1dET7j6 -tz1W9CMB51U92PFNA7C2YMfCpZjF5MzDzDka -tz1XFYFSLFjJRAr1rLTXvUtsYTthecQgZLec -tz1Qdk8RCS9yskc5fcaKmGxAZkMN3AopZf7K -tz1MV9Jne4XD4kW773PLaK16tjgzDHJuje9G -tz1Y9F6EcP2aGifZethik1f4fwrX2ETNMr65 -tz1Sspuytccv7PjRuXyja54616228EW4cmb9 -tz1MkMu6LLpehhGQre3qQQnNQfNSrErCahva -tz1egU4pFEXxg7ZTQLnvpv298qzgxbMS2jST -tz1bhgRAvvv1ywLZH2cwaPUU8GBNeZG5YjSn -tz1cbsg6nNKztxZwjFwDVwWb3YwqfE6kfJ1C -tz1iAUtoHwq2bRZ9TjzsojgCPfCCSFaKz2TU -tz1PKtMoJPevMfuMZr4hwwevcwedALzcAHf7 -tz1cjUAf8aNdKYcbzYJzUMYxQA2GpuUiA8WM -tz1PqQCPkY22PSvoyPRquRdEtCKkj3LxHC8f -tz1M7iK6D7a9aLyaqoMsVMW6x3evynhGYfeX -tz1SWPoYV4BF3qUBckb9nua1b732TLsARGbs -tz1Vudd38SQZAwT9BoyoootDV1kLcUC1wm9w -tz1WMvC584UAevhHY4NNoTtn5qGxUV8aTNGD -tz1LT3orBbaBYsPnVjLbEZj6qBPjvH9r7Xgv -tz1XW2PeSv6yi6Qw5SfrdGKqMQx8iTQmWjuV -tz1fGuE2pzbwKjUCfyPJYwXfFwMuWJNQgES8 -tz1TQDPeoCNRLWwLbsB2xo6j3oFtnVbA8Mfa -tz1UifdUAXtag2xBXeuto9qY77PGAX7BuqNj -tz1dWyv3KQgN7gGw9ryAU4raANcHWz7yfAGY -tz1QiJWana4boyhwyXbBxsC4mUZKwX5pXxLo -tz1ibT4XFBQ55BX4hycJQcDdH1E7GdG47mvc -tz1M42Yj1YyFrSTxmxE98BdY48LZp4eZwuZb -tz1MVbaQxapnypvW7f2y4udHSGrMqQ62AHu5 -tz1Y7XeyjZxMhFXkGEtEA3KjMLqSh4LhSPPY -tz1h4Qi7baH3QWwGJrhwRQstURvxPnN4iyYr -tz1XgFuWc25uzYLG4KsRhe8UinPbNDFL3ca9 -tz1ZoiWfPN9pCn18gesrPBhkTuASmwhbnTUu -tz1USKCeWNK2j2YGF4kj5AaRrCy9DW3TCxJQ -tz1RP2MrdoU1jGhLnUiFdqDutjscqmG57qDz -tz1MgYfSby28aTkCnsjFkMKNHRUAvm8ADanF -tz1XLnLRoX9KE3AtZuGKHDTgUsLTMoukmcDu -tz1WEz5GvjBRTNV5hWnZq8q28TotD9nhMhYv -tz1dCFfyJSXjUZCiBSC4ZiKgryNBcHJZ9K4w -tz1ZnoEid8HKWqQsNRh828iwLB5xx9umAJ2u -tz1Wj1XUfeHzGaxwBhrTcjg2xKp4WUopxq26 -tz1YinrhwoWiyHZoy4kaCdkGE4nAT3bUt9K7 -tz1hzDSd6YrzJASsYtYbRBycEy9fCcw4SQRm -tz1ZPkAjWjpnRTNLLZmBKbrf1uG58c7Ch3rZ -tz1eqeM4Ljf9JpkA22vpHbfLoFQi4HYhqx1j -tz1S1K7XYFaLD1Nzem93ZWiKVQq3Q9pEYCB8 -tz1hJGunkqR1Vpz3EwESLhZo9KU4nWjjPnk2 -tz1UiXH9BA76558Zd612mS2tFfFbXR6jToXb -tz1PZZ8sQP7sd4vnqpm4hQHqkneyzxuzUJDQ -tz1bzZBTNZVjqVpgxr6DLcPzSFfnM1iGu8MH -tz1UtaAcMcn8ubYLcJAqMkYLHJCpEr8RkrCS -tz1XqvEoCzdzUFbBRmmaxbs3Sz6fz3sauz9L -tz1LLccJJt4Y76cu6sqfd4RwPUUWqvohB9kD -tz1XSUgrvYh6ASXU2ACes4jaasnYuJssNEmi -tz1ihvJTFL2mar1akoYHB5KqUGvzdeRVux18 -tz1XqArR4gX1L6mUvnwAYDxScfs5bqBCZGyd -tz1g8tx7NgCEcZGdLsPQ9RtNM2D6adYkMMtU -tz1dMW3m1kBRC53A4vb2YzUtYoQwWVoSDAaS -tz1Nw6dyrSrTwrBA87gdeyPEVHrBo1aMULKE -tz1eYL6q5ePD4cbKHC141n1CnPJvjBXEYV3v -tz1Z1qbWUohD2qk6oaMW5219ZCKTuatA4yZs -tz1a8ThD8NS5jVMNYsQi8mgbBHNhxA5MpVU9 -tz1ZsSRbwEJZHupPgjLprNeG1JP7zF7J6JJ4 -tz1KzqJonDeWB7ywr7e1MmSRJaAfe6xhMV1h -tz1Y8iRTecQPUoHJjwZ5A1vtdNqk9L2KC5DM -tz1c6MkKgeaYSEJPybMmK5zbFEiucNcpn6HP -tz1eh5JaKdmDtKUzFdhCtwZMU9mgxG3kSzyL -tz1R5jyvDRm73pgtxz9cZokdnCHYaAuw7mBF -tz1dFA2HMQqHSzhKsJhHFmC2R88Nf4hDjfVr -tz1eYXbtUVTYA4oXN4s9qbT3XnHYY5Coq5UT -tz1b3ryt3CU9X7m7GMngrPy2jYLwGdzoKQJX -tz1Q67HAMhisNspgGFLWyXWE4zzrCUum14K9 -tz1awAPzBFyZrbGrnDmsSkYU8yhTGbXEWSpk -tz1MG1AKxAaghP7LksEFFSCzFum7C9wsJNKL -tz1Pi6QuhiJuQAbBXoBcRmpbKmQ1jwKWni5B -tz1WjX1CLaJAzJY4TC7aph2gb9qwr8TZFNxo -tz1YtiaUHFoyyEDeoRf9FWpRJLwriUAZuzSM -tz1Qkk4xoVmhQgVwUGBWcmVC8ACM66QNVta7 -tz1bWPbWcZJeDN4EEJ45db6YTg2tjAVr2XJs -tz1ezWQXDbZTtVFvpu2HeqpFZ765cjuVLvu3 -tz1Uw65BSyWPCMAgK1LTukTNdURSiVihmzUa -tz1XXpGX4YpQDJ3sF43ZgSUPCj8WFuPoiAb6 -tz1W4TqM1ZAunXJfBHd9cKs4exJ95jPVh7n2 -tz1fU1wbvWzMSq3ggLzwLaiF7b82XU85NpBh -tz1eDgKGdT26rMXAsvvUi9nBtXbV92ay7B5Z -tz1gzfThm2ii9w91MqRA2rEMPQc5xbYTneeU -tz1iF1hxqVR5FZ85MnEnKJCoeabQTaThJCEw -tz1SgCRfcgQAtbJqTxRC8fqvRTu3eQuNsttG -tz1Zr9Vzan8SR8nJxYy6BYv4jqmqDeiYpMd6 -tz1TjYgLvZnj93DG7fzqzkeNiNHS3A7kWEs4 -tz1MBcpYvxS7XecgTQLeQLc1pJ14ctYR2eB1 -tz1fQNnaiHMKaiTMX7ytEVxy9ri8iMCsJAPp -tz1PP4J4uU2v5FtxwJWsx81qQA5gHraPHCyo -tz1NzTgQQVwQ1wqydNCd9xyJNHWoMaLzLc4h -tz1cRPfSh9qutgY1M8U26dPrPsugN2gUkf1Q -tz1WhS5yN6EGCa6mJNWbmzHqMMw9iY6mKhB8 -tz1b2yTgg7pVEzySs6BaqfyYBFuLh5zRZYDT -tz1a4fnWTkwHzJC5Fou3EXvrSoqFa9d1jSYy -tz1QaUza4sdDYzkCCpvGrZEz8wPACSPd4BGG -tz1cjbJRrAoFgBrFbboxgz538Ej7ZBkwqqR4 -tz1L2rduPfGt3KWR3k3fSsRQHtWRU5s9yE3a -tz1KrFBhrH2pSj9GhuMRdbjEDiSA9UWtkL6q -tz1LXizyZ3cRKzMhjkUi1n9js4qzDCgPbZMt -tz1XCXJemYU3ef5FypJYayzrVp5NWoJr3n1J -tz1evGkf2G3W2KntAzdkj2pX2ZjMztS1YP1v -tz1WEHikReJNfotZK8WNprja2KRL7GE4ksZi -tz1cJJdLKkT8tJdfQ4UQy7sPNAp3G4aByZGX -tz1NymTe7QhhXpSmuY2yDQLz6vocHA8YVAWG -tz1gKD2GpTCEWebVyD7b7gKhYUricKTzkiMA -tz1WQuGEcrP2bxAXfqAozUaTsoZBnbyp3DXE -tz1dgfeYCoZnnHEeQPpT1hdN9SzRwY7sGL2g -tz1cxw4g99RphbYK7FZiGDSo4CR5jyAYKLET -tz1iZKcv34svpgFktJWRd9NmEfZBzcAcyX2s -tz1W6vocxEX4Eaw37XiLncPq1YS1RNEGrBJR -tz1XNHuM9WQNsiUj2LvNSSdsi3V3cALpP4CB -tz1SvWKaYFbjDpTopSZ7V2zCqUrMs8k1Ccgy -tz1dTh3j76MHwwpDdHMrPDURYDsJVrHCnuPz -tz1diXiRpM2CEeP1pBSiyG79stosf9uY1bHa -tz1YSd7ideP154zebFuhhW1PPtdLD73qJBXz -tz1VUtPCYLC5ww1VkMsLavRzucBH3Z5g1gqg -tz1cZgFd9QjKN5qG81j2MLGtXLLcYSdhSZZq -tz1aK8zTPxkuyHR5wkaF7oUbJ5632X9qmxAr -tz1YZjAhBmudLnGPAdK72dtKXxMc9E2NR6gQ -tz1UU6tqcUSyb2hPWmjWAv6aMJ5Jzj3J4WDv -tz1bua8YUcXLoRUkVDHUn6jUxs8o6JWAi3Ke -tz1a9VGYwwDUr5NvRTpzirXWC8LZ2JLPMC8d -tz1RLV3UQwR14bZVufiHvw17s6dF36KHq8ji -tz1a13H1ioFTtkTfwhRwgx2ji2UBnfiNPjZT -tz1QjYGNeGdzHWNmvVx12Z2HKpZ6EvTdY1Kp -tz1hieNrcYFDsg1uMdqAdxPRdFbUtDwqrj33 -tz1P4UiWWNkFLnwJ3YsCfZC8Khnv23HLQaji -tz1X1Tco8ycSec1tJTgMMgFkqy65ovGbjjfz -tz1Tj46aEtcZi4mfMhH1VoNfmPK5iHkXkxjH -tz1VoNKYU2C1WBS5qr1cPFqsEXf5bygwUwv7 -tz1ZADZUDP7brp17j6iRsujboGoUzsdqZzX2 -tz1PJGLV7VgPaZQby6JXmSQMDL9dk2UPt6ap -tz1RGwaeV6feVRDkhf3quvqxvgK4Cusch1vM -tz1a7ZSEzSUgwVvZLQne65yXEFiWEAi7qeRw -tz1U3fCp32ne7B1X2DnHB3TjY3xz9Cqp1Aqk -tz1XDGSF8ccWVmnYJTDdo7bUwKccLR1ovbEZ -tz1g69CjKpS4rZYoDHoiBtSjERct5Z1PVE8s -tz1hNAvof73hC9sjK3GccnfmsoHdMG9Twi3o -tz1WZ2zno5TntrCNPUSHZU8pgzWcADKW7csW -tz1hd9aPiUu9Y69NK2E6QsNoDXyJ6f8Y6vvC -tz1fXzoM8HAC62L7fWLKcUzAicHkFSMnmJ3d -tz1ME9GCst6kt2EdFjQ3PxhvLugDopuqadnE -tz1fazu2JhtVcFEhBcBdxoe7G5BhAx9jr4Z4 -tz1NYdixubZ8mSRx1ijYmcREtTyaNoE7RoUc -tz1KwUhDpCWXb8kC11a7Z9HSLmyuU1s5xThL -tz1WTgsUP2amJZzbvxj1PdFr72eZypBwmkKP -tz1RXPEUC22RwXCBWWcjDsUMbjoZRB2LParg -tz1UgnSCVtGv1dGZmFxGZebgF7BeK7XPizN8 -tz1Mw6U4u8SJsXKWLhrC3GmE9TsJSqokDEHc -tz1RDoVUUsNXSLX485sJh4vXNAyrLVHLEdva -tz1hGRA5oPJRBgkuiVpZYjv87gr2UhTEiipg -tz1SqhPqs6bM8PKehHQxN8SGmk9mMQ4dQJnd -tz1ZHxYZGukj4VsjV3KjG4US4jAAcoR2cS7Z -tz1XjVbMonJ9UX4BFpJfZweozDjwDNqgKmKP -tz1d9JB8iMXecJJpCMnB6Pn78cZcbcK2X2MV -tz1MYuMQChBpwra2iq7dZKvb9T3tXy8WnS7J -tz1gAipbizGhuD7wPaxyB7kNqyh3qLAmZ2Gp -tz1Ya2D8W1JQhgNgwHbPXSiRJ3d7LeKMHTbM -tz1NAvKm6TYZXBZaM1fiuJ7xRD8D2ZAUdAG8 -tz1Zfbt4WD4wpF21Cv1M1tRiFiojYjBYqr4T -tz1Z24jE6oF47BhBbhLc6LzmudpLghCBidva -tz1ZaYgjuy9D4deiuJ1LLorQcBAYgHtLoFvx -tz1RRvJcrYqwded4vhoeBfevnS9jEojvNT8F -tz1gEvLykhpUdQGoo7qrD9bhFJNvTFmH17x6 -tz1RL2UhQvuKxkehWwbPRs5ZR7oULZe8JY3j -tz1ba2JHuCE7EvJBBNfRDKmacxooGqt3dHxx -tz1PXpTSmyTEnFxXPtwc82WdMXgTWaaH5AnU -tz1Kr5HvBW8DUo49kKzxeC69uQBojbjhJPeB -tz1efUkiW1qkD7MEM6wt6pZfQZ9JwiAKh7Dc -tz1h3J7kesXjR6rJ9jFV34RKbkUfKcuvCC7A -tz1TSdRcSdAv8SXBuBy16VRybk1UM8et1RCQ -tz1cbQ4Nsst6cUBnZryFsJc5zaWaaoPwYyif -tz3QbvagfgHzm8PDw9z1CaZRcSM8uXp7Cy7A -tz1YUEqSM239oa715gTfKj1tqQvpcgyoV4ML -tz1fHJepXFBYBvAJLi8QPjWmbv2CQjPNpMph -tz1dRgpWi6XVkkcHzJhLSCHvvHB7KKAMVYrS -tz1iuv2YNACU7snp8LF3XCBrenZRs4RLiX4P -tz1KyswK1qm5kMp9rKaBBJhgpzJ7jGPQLLE4 -tz1inubZ9EP4n68WEkBCvXxAHe6paYv9i3Th -tz1UdsvCc5PVHJRi8M8Mh3tdWGcXcQm7vWt4 -tz1MqdN7He2JHxYvsTnNMUedauN7HBhzv8oo -tz1efPj2RLrQP1jkLvW4hdc5KKBqYwdLgf1z -tz1YnwKtZ1p2x4tVqymjHejRdSeoRVZpZDuj -tz1XKkUmEghFEqL88J7QPbQyFtVoMq7jQiRv -tz1iSn4TCSk3w4tnYxYdB9gJZd4qjhTqqSJA -tz1Pnf59kDx4Vb5txhVsVSABRBP8DYkbLw7Y -tz1ZU5zYqnNW1AQGV79MCuCb2FZSWRnB2hQV -tz1ddeBCnfeNeGwcud5t5b235N4nBLjrFRyQ -tz1i2oDpZorJDSbPeAVEQ71kqFYuVMgYFC8f -tz1faTQ3nSu4tzdFWchQFiuiSJekYpnYGq5J -tz1NP5mvqMBYyB8ERLFDKjxs1iLLSKQsiSuo -tz1MebeR83EMhD5QZDVvmETRsjpMs6T9RPQg -tz1hvN7RZ2K8uv6o7KS23NqFpR4qwo2mEJ82 -tz1cHwGeWrFQkPx6sM4b24qtuGKxf1npKhDi -tz1Xw2eyrGgBgBPkPsAvomLbKZq4ggFJu9NJ -tz1UtKnPofAbQhgf1CCF1nxunVoWTaCfQdVG -tz1cVUExWd6xgFQmsEiZW8ScowJwq7jPeukP -tz1R26Qd3Do6Dn6N9w1Gzj3Cit7FEvFisCQF -tz1UBrxTcF56Jeih8oUX12SwP4iHpzvxkVX1 -tz1f52u7sTzXfEuNuD2URyHkeEUMDDQXeAeM -tz1arr5AWL1HfDWWtL7rWYrN3nMDiVX1UAUu -tz1fSYi8oFQZZx6wbYKzB72qD4E3AapStKsP -tz1eFLuRqDEEtTShHfiUPAjk5ZLA7p2Sic5K -tz1eK3AU8GNUkLGwVipDepb6sPm5sV1n6T4F -tz1hFdfTcmE2A1dm3iQoNpCCtML1v2ZAzaPi -tz1KmuhR6P52hw6xs5P69BXJYAURoznhvN1k -tz1inyWprU5rGB5P3JK2dzwqxpAAe3PfDj9J -tz1fYSqC4iT4VDeEneic5eC4NDWnEEcwMMSv -tz1afqbE13STvFjhi9L59Q6jPYmzr5RnDYih -tz1XxpwdUhTiUvwcnHrN1GvhMHjB5DMaHzJx -tz1SBG1ZNjdsdH3CVX83NBPQvn4yqG5yaz4x -tz1RLKDBWhewQrzZMGPGHmyQzBcDTSegJRdL -tz1P1tD2LaFnKcHjUx4vmq9PwXdXpQ3Yq2YL -tz1N9ujQeguYiy3eFaz2mJgyMBswYBGzjDEf -tz1d4v23SsRgCT4MtZFjqv3uFjuQRJVfgX2o -tz1aKgWiid6erza4bz3aCV5Gyy7w1aGNkvqA -tz1btZitoNSeutHNGVFn2xVMDxnSCLqeVtM9 -tz1hzA7Yk692HCH8z3AuEy5WCGfvtM2EbQZ9 -tz1eFt42jSB4sZFti7cx5H62dTUpXwgx8WLS -tz1Mo1AQab2ghB7zk6FxbjFC8TDLgx8e3NtX -tz1cPvRbikcYy7ZsJ5QJAyEJP3eRpUMfZo16 -tz1arkzuFRarytu7yfGrceLT6G8vTyK8gmWM -tz1iphStUbYDrnxndJhYJxjGBfTjdr4z99ne -tz1aL1ytkLuZdnbFqf8adZPjJkzWCt9baqhv -tz1MYRKMgnjpJQqargjfD4Mo4tzSiXbYQJ2X -tz1eVWviLuHuKKsLAxTiiBKZJoZXNeaF7pJZ -tz1b8nzoTova2f9HQMyk1R6tvWBKvubBLn5t -tz1ME9hZQJrmz9w3aHbiJVy32V5fuoxe8zt3 -tz1MUemCMtj7XebHWQrrCH51eC5JXoXB4zPZ -tz1Zm2MqPVcdL5oWGgZqbNm7YtkfpGfTfEyE -tz1aLUznPCtdSkX98KJsnf6u36XwSo9hAAv1 -tz1MX8fMz6EWnC6P4i5r8oUVvih5qbL6stYp -tz1d5upA55xvjCqxcVg5foQHb8eXinkZ5UVN -tz1QCj36fj1bYgm1HtG9n7dwNKjr2BUSuRq2 -tz1Tm8Qk5wv9uXySSGMoFzBfN2zSSksW79oa -tz1WByzxwf1NAKAGsiFpwiGMp8xAjXJ9sCpt -tz1KuTnddg2phPx39uNAw2igziryCM4X1Lc1 -tz1hGbU9HoL9yGEQr8pcSpDfX3DAmUyPV7T3 -tz1WZBCQML3noMws5BtoUxuhGhG5ZFBcusLp -tz1TGY2oMohFm35AMUtpW3bKUgmvMEMWf3Cs -tz1XzpJqQbJkejbYWiu9qAQ6aMGvbHRM1vRa -tz1P8QiaHp2NeBQdtvi9Co3uB7iL5Myox46D -tz1dMC16vyvNcM1tZC43r59C7NgneNZLKzdD -tz1PvjgQptBQPs93TgW2oVJ9LFinVXtdtPFi -tz1XPcG8FCdksXW1EVeziJyJk28vnEs6sBTv -tz1NBiJXxFS79DK3g6d5zA9Ut67kGrkQbgLU -tz1YTNtmJfvcatU4UFzVHsGPPLynvMunstt2 -tz1SkM9nqbfy1vu3ELjeB3ZB9PXZNaU9anhc -tz1fQGuFpadNcx3fP5CBdsc1ZfZPx7ivs7oN -tz1SmPLQVMCLRfqGn3bdmbQFnzj7HELmG5RY -tz1Q1dasmqTmGGT4xKkuTwMizvxfftkwTKJS -tz1NU7CSZ1FQHyujdgUd6r3iyxtiRujn4rJr -tz1QZkd6mNJTRT9Rmmmp3ob7EtjzJvLQxRH2 -tz1hV8jWF9XXjowB7SpUFbiPepHqbz22y7eh -tz1ZztHuwDNFpSFvJSLF8t2NRAX71CbUznwv -tz1L8c1WnrCqSmnaWswHivdvBpJNUPX4HoAq -tz1RuzEo3M9C1zPrDvNFxQ4QJjEqTeS3R8jg -tz1XdCESPcDoVLnwWy5UfX32gDvsxCjwTuQY -tz1euupseX5f1UCSjqhCwbgFuFWb2BwSSs1q -tz1QpEkv2Amn8aooErChk2MbSYfkb37TTSqo -tz1UBsFrp5wJcRJkR8E3ZLhr5SHg1VwAXgED -tz1TTuukAxvawxknzm74xNBJwAz4cUDDkfuR -tz1STAzkywd9GnKGvJBPL4xWte3LCniyu5ho -tz1PRGFL2NyUTw3f4c5bbr5c93JNnxR8U14g -tz1XQQEB2c1FaJLLLZmMknGMLUYaXbUYb7m8 -tz1enLANvrjyLV3HFY2Ns1HTNHUsmSGJUnjh -tz1WpCHnT2QzsXwcNf9Ygye5qQbQPcfGdTL7 -tz1Ss8o4NBn3R3uCoRSbC66n5S35VqLhpZaX -tz1KuTwAJt4dt3j3iMhQEKvvXJGSkpVjhJbm -tz1h1MGwVU9Y9xHfzw3e5qNEZjYg9TcPRRNj -tz1P3gPGCsDSJ6Z6UtvZ15hAtZJt5fDdygjy -tz1fsyvgd7i6D1viDnzF8Kpef4hkcCgxzKeR -tz1hRP1xoVQMTcMbFqWZEZjLEsFZ7FdudeL6 -tz1cVy783HTdXbFCG3ym4ips8T6L1pTzgE6j -tz1d8fsPxqkuxB6ewRAXavCsd1aZ7whCjao1 -tz1iRPtn6aihfYi7kSBT4NDZX5sf1MMEzsUV -tz1dkGnEQC5AwXDi73ohCHuqJVWLzqyUjW15 -tz1eu6yStzPxYRqFPWedmfmU8cYLSAgc6quc -tz1XGw4J9Jjx1mKkc7SAyFMPrKqQqGXXJ33q -tz1PzQLKGmYnbwTK8KpBvwjzMr1C8KZGQfAa -tz1MMxnTRyX1BgYqP46DVzWnM18oBShUwmyZ -tz1QRHTyR36L2xvubmFwzPLoGV21JJRCyQud -tz1Vkq2NnqppZH6BZS7oq1JAhQVJkRMS3KDJ -tz1eLsguQsLwcU1Z6QZ884m3PE6s6ims59vU -tz1XJudTi9dRy4EsD5PgnjUYzq2uoYqfGE25 -tz1hjiqGKK6LFgBozMvfruA76JxGGYbWhcMp -tz1br6uakELPHjJvnBEsAkraVtu575WyrRYs -tz1giufvaZCFyEAC2zEkr3Y7CyHwPNmZSTHX -tz1ePndTsUJ5cEe8t5Bvot5f6BFBiHYyYpfS -tz1SFvqu8RhS6z5r9VVMtnqreH6kM5Wmoimd -tz1P2ato2SX2ty1nSSPHRCNb8Wq3aDxyJYEz -tz1ZjRdXBpcF3HejCL3TYQ4FUm5Nzz52fQQW -tz1hhq27RMeNxtAA9mJLdwZ68vmy3RjQbRkV -tz1LARH77G81qtW4915q12EdxKbTqduKaW2T -tz1MqffipyWCgqmBsmZve6P828iPpCDijHhY -tz1iPLUmehTibjsVsF3Q8Lfoaavk2s2TMkcZ -tz1QAQGycdLEoD3ngzkrh9ytJdc91wEhRMUu -tz1eFbWstB6RkTrVeunEs12CcTJjabZDFuQ1 -tz1SfhkJR8Jv167JcA6tQdTXo4NANa968WTh -tz1XDo2qfGvyJJ2SDnb8R9UGMFJ9Ma6RvnWU -tz1VutFvBVFi3QQwxUUQFTBZkZ5LjSApuad9 -tz1YV9EQLXxJsBPD5mqMBxwWCHb2T7S3h7Lr -tz1VJuz3q8zhL2UeTWQnDaf2j7K8zTUfi3WB -tz1RDGoiiH43riAB1S51Ph1fgL491oDsuyeL -tz1fFebU1VocbYMFLkccuQvXZ2VTdj36YeZn -tz1iXpzwecZtBxtpHbpHjydomdCRCnKdy6f1 -tz1TxsT3m7LfiHUSrnkVfEyxSnTFmBSpWoq1 -tz1eSqUzDbrDCGg3vuQS89yVR2qPLQ3jWGNq -tz1PJQiXjL6REQnESuqpPSuN1cUHkSvwRgEK -tz1UwVBRmopbRVMCkhuzrEFLYbjaT5sEtohS -tz1NUEGJaraLo2BXmC5fAMT4UigNHP6CssDR -tz1RXjf4F2QrTZTFTsKT5EaMchrpRZMEE4fx -tz1Ptmn8aVC2cpi72rHtPRuFWUg36iCWfv61 -tz1RRRuUBLozgNNHLgbd2q4xKtpro5gnp3Ur -tz1cCjhXZSvw7LkBWrjmcDjnVfum1HbW6x1H -tz1VbUgdvYWNDnKaTCBJtKr4g2koPdK4Po1s -tz1MDjMt7pquDvuoRtM5khpv1ShB4z3S5ixQ -tz1fTHWgVS559ft1TwHBGWqQciYLherXqSuQ -tz1hTGt4XAB2PBtdZ4vyepJashHDKt8yFF9J -tz1NJVfs3231wyjyYy8EexHemVeuTd4tMMdJ -tz1iQCAwbTEeMomsWw7PnwTUP7Tf1xXtSk6D -tz1gCpdrNiB3KsQk3yQ8s3JymGdziVNegRyR -tz1fde8n5yd3MJh4dxeA8LWe9EsSmBwG6K6N -tz1TTKUr4Jgyctox4PriUy2qAMQNec1QPZzt -tz1L3GxpNFvD8X2qiXHKDbUxQhxbAfM42vWt -tz1bZbtMyuyCHNydH9jw7w9nZjh3dwPHEGps -tz1cm4webPRnf6Gyx2f1azYy4gJYcctYbbvW -tz1de5Xw3Ro1EzbtcDvgqXbuzA7JRXJPqWLi -tz1aXY92AoXC3CR6VF5dWtHjwqHWjr3Hzupa -tz1TDf2RXDhW5eKBeLgsiT2it7pccNyomt8a -tz1fJdhkSk8efKiXjBvnmaLafjZ6YeQBxPyL -tz1g2Q64KwkKSeAoWukDHXsnshjpjnT1WSXB -tz1Y8BGJdDdvgNRZb3m5KDmWRm5FdL8fyGEH -tz1Mcitf5kXpESV3KocZKXAQCRmDjsGSmzy7 -tz1RMKBQT48R6VFMWWcuA4wSpaJNcfCpBB6z -tz1QMf6K2jtd5BjLXK4S44PQjCR8SS6cJLgV -tz1VC3VWVFHQWrw5ei2kuSKN86H5Dv9LkhYY -tz1dk8PUpqzpffswUzQC3B3eNi44wGPHD4k4 -tz1WwneQQhV7ge9fF1abHGK7B7sV5dfNxKBj -tz1VgeKeiTHXcRmZanRbAWiquxkLGwjhujmp -tz1Yzb5t3vHcBqAuViRVjgF6gPHtto799Kwz -tz1iNMeV8ZMHjpPNswkHqPP1gKqZ3YF5jFb7 -tz1esesV8JQpKgcvUQJzJsdnHEvFa9mLLWmn -tz1SKwshxRaTJwgC54ikV4JGFQMLri3YaAfu -tz1gaxmhJwk3zZx5zM6UYfdgVdMGzcWV8c58 -tz1PAnjjpT9szYQbJGg6cvfZQRww4h3partb -tz1VqAFmGUXwbqePs2iYMCkoajE1C7WHzBKw -tz1QGQpBAp6LZG6jQdZipRspTca3uQrLW3Gw -tz1Qcbco1gyrCsnyX7zR8bQc72qrxe4gEaWE -tz1bqaCkEQ6s8B6SnmzrbhbbbmRBvFeHJVDX -tz1gL1Vhawnii4bSbHZH3VSrcQYoHWwoohqq -tz1YVQkcCeJuvE5S1Ted3oWr6EKiuZi8Rfuw -tz1UBhpck1dr2Q5ZgQr87CghEN53wgBnsB8c -tz1e4DUppgu6gwnj8pYkiMQPZL2iUJnNRZib -tz1dTSUdo9pdffudm5cRibPfPWubGcnisiNq -tz1PhbXA3JiT5gJsfyfvoeQ2UyWuuKJvXbhN -tz1U4H4kWg7E5dhpXWZKMepd49CG2EQm6qFs -tz1ibaS9fYgQKJJ3G6naBfqKTsMzV9nFGxFr -tz1MJDy6BvydDaJuzB5Z6A3vixPFHgLjnigM -tz1hCPnEWW4retRfF4uvzr1UintrSUcGScnv -tz1NMTY6z883ct6jP7NB9ZVk3F5keHchFDo9 -tz1Qy4HHdfMtSZguJkCqJzbpcSRFe2b88sPb -tz1WMUdFMYDpkyqkxS16Md1zndrpUEqf9tXU -tz1dGYAk9NLfKAs63Qczz7MgeHhYNRJxxiMx -tz1gJzYcpTwdyu1bSQvPjMqEmhQ9JGN3dV1V -tz1NUBKrehQgXmXTer764TPYsw1aLBRBNqv8 -tz1eR94com3RZVtqyNwH7jY2B39CW8R6HZ4V -tz1VqSg2e3TRfCnezC1spsqRLeSNJXg8sEpW -tz1iUCHs5o4J7XnowifGcuXDJdmQEFbtAHMK -tz1PSGSn8LtUVsZDowq5M7ougLMPyFHbqLxd -tz1Vs4JA5zEqFtVYTVi1L69PvAFucC62L3Q7 -tz1LfYbotcHwUag2pJBu7KBwjRDjHRn4iEgH -tz1a68KumzAHic1pucmaauNiYKMZURP9itoC -tz1f1qtSYCuXvToXcaqauCm4HTfNXckuWmEP -tz1ZKjHfnw7pWTkfJMwGguDBqr6vngFH68ci -tz1NgpBajEj3gMRoERvJFo8UgDDws1juZdcJ -tz1fjxAWaB1rBV4fBgyaakFJH9SzeKuVHKWL -tz1U8CdLT81uFKVQ7KcoxDfrxtAqM5MB9ajA -tz1d2pY8JEZNogrBaf7gJbHXJeG8MDMtQond -tz1ZES3XUrczjMUYxULJ9oafgs9MWUgsgHps -tz1SFkF15gEWGhWk4MmSwnZqLa4BsUhScMRf -tz1Lrxsk4FrWrYzo4NoBx2yP3NHRFCsf922w -tz1TajMkoqfoMFY8Ju9WpXDPk1NpjN7uBDLX -tz1h9JupofsAGX1ux7prQAc4TdAFtGwMbnXe -tz1bZRn7hGQESXtqPMJghWeCVtyJDoZk6j5r -tz1dZ6BYyqnnpPCN8BVe9XFfDypQhknxGDVK -tz1bm4QU2YTE43JbeQyH1fq3WbfU7Pr22zmk -tz1VBGCAwhHvWjFF4x3YcgT4Jme8Tr4p9KRv -tz1hissJBkFvdyRzyjMx3HEof11kEfoJwQbg -tz1XCUn7bVwgtiLHpkf5B1TURiiHvBGrqUaC -tz1VLzjWYbH2mS9DfLk1XoPmvGLmVZy1Xj2S -tz1fFPouhmqt5mWWfzbM6oJnA3LmxpvrwuBV -tz1QByKsW7D6mYQKHmdP1wg7cCYUtY5duYFW -tz1ZR434YcGYMfdwzXpkJQm1G2RK7PxZveXx -tz1RUUejaDHC5jTp11KjZdqYs5SnwpaHGJjq -tz1PqHkUzB4zZeuM7U9jrx9sfnegDw62znry -tz1g7vRTyYVtWbt5s5bsQgtwaYcub9DzyqZy -tz1QNtQogrYREvvJikdshiqtgpHRFNCgJaAX -tz1U7rsDD6n49Z8FoKRqPzh6D58FHh1yYp5n -tz1Kgtnevj1hYW16zRBy8fho8PwVbHxvorNM -tz1QsrG8Ya831Raa9TNgi2EU54hKsQCUp8D3 -tz1WLrZ6iE9pZuNT6JnGqmwAgYbbbPdvB9Zd -tz1eBsWJnWfij5qTFQHc33K6fcWDsvYaA4yD -tz1eLrWFhTm5h6UNfhyaFCtQ3ympBFgzDLQJ -tz1NbQSBNMzkxYUFJexZbbE9QbSyWNKJja1X -tz1SToswCrLFRNZYMx6T6qbesbGDMD2dEYuZ -tz1TMBAER3ggWmDa7YBWDy9F638odj9LMA4M -tz1SSRnRcQK6AXgKgKMKCwJ8hKhDPfHJ8VFK -tz1L2Y13vSUWaTpqBux5YbAkwwWXSXg7dcqK -tz1Up5e9fRU46ZeHypd7YPrZt9LFoeAF2iyw -tz1XHYPn8ucbvNkyWHkCSv5t81tkXbQE5nih -tz1hgAkqxPQmmwj5iy4bmfchhGLvKzc6eRi3 -tz1KnMdgFFZYpNwG1evsxZUHwcaMeuo11nNJ -tz1XgV96TpPqSUSS12oDj46APKy2Nm4oKJRw -tz1hkcQf9bBSmsAcj9bBELpMJYYe7UTLkQSo -tz1eD2iaeEThDAFrXTp1VnrwEmumw5PnwH9i -tz1MRv61rS6FrdTUJh1fJgKE7REh7sUp1LLg -tz1acdCfoYGsBJC2rtpcKTDy98gpuut2Ct8w -tz1hy3o7q5oeYr6FKfRneDU1xJxbdXnUggDT -tz1gaY2Ctwzz3UriRRMEdkg2nHVBsivmsJ5B -tz1NVoaCCBc5C5uzbE4wBcJHvCqYZdD2fWwF -tz1XBzWZtvHgVTvq8H5k1qoR7CjBDAf3hq3a -tz1RBNjUBM5UMBQ3gHztV2HRXxJoV1NgP7A3 -tz1MuJM1KkCD2n5u1cBkVpopTJA6pQiJGWBT -tz1RT5LUHfiTg4Xwq2ktaG2wKLMa2ufi9JRw -tz1ec4gUtfrreAp9q2XLJi9wukxreKL7xbw9 -tz1ZXE18pRUUnYoayHDavH3jcMW47V4xacuc -tz1LaGwWRhTjTtWaQX9A3nkS8r8jjBxjWon8 -tz1dfLFubTXyEAbyRbdivBndKuPaB3zdDmCJ -tz1g5whHF58fFpCzjr2uWhcJbL5EskgV93GR -tz1LsmyzPWiKAzeTZbamhxMXzocdatFZXWxV -tz1TAvSpH3iDJcVDxoEi9i5Jye9WBdqPxi8w -tz1hwy4Kr2Ju5AThoqpcUSkUxuN4ccqtWDah -tz1LPtheLTLSpCmr3b7Nq6c6pE3rwFMa81ha -tz1PB4fzcfCmCyYceAofoZEL6VK7WTSZUrV1 -tz1icMDeMgAAKg6YKjH7VoZvxNZW3pnSxUVC -tz1RmqyyydSnqGQCtcU8NibDdooqMkBFCjNA -tz1N9cn4pGXEd1rooiXDBET2bHi3oJDMx5zS -tz1gYZnZ8KLxpCgjTRRSNAbqoWhx6YhNG34h -tz1UkAZTVru14LzfYWUrxQ3eqcZufLZA4qAh -tz1KkzhKMr1KxRvUrkebkQHDGumGgyAybi3G -tz1TqZSmpDQK9iXKgMcXXr9UZ549wRLWztVh -tz1TF6niL1iCQxbFFaqMyD7DmjysMMdGqkPP -tz1PziRyFwu96Rw1vqgzEdd7SqMuT4hQaggz -tz1UiQXZKpSy3d7NibchyHfv3NTR9GfoBuMd -tz1ead2Ab6w1JM4qzEgvrohhwYVts8kFw7Jb -tz1SMNq65nihUmgXVJRVPcSe2HCE2e3FjbjY -tz1RHgne5A2crLnNWDxSAjbvbz9fw2vDFMmB -tz1Qyg2GrxEQjSNQD6DPvR1op9grAwRXvLTd -tz1S2x8wnPLMn9NxArnQaLLjwBmZ8wtbGxDp -tz1TRbFJoiPEXBfH2Amwpx35EjXNcFysFXMr -tz1chJa7WDGM5aufDyTATNwFsEJWnQncdmAg -tz1N3u6uXiQraDKjmjoGazKea3rLehMq17zu -tz1Z5DSy4hDRwF2cvkBUSuh4jSkrdK1oAHEg -tz1Z6VxErCjXjXZX6PFBwP7pFzRHCNnM4vuN -tz1b8hnVbR2dZQZVBBqm4wrkiFNC5xMhaPK3 -tz1ZvSLq2VesCoPFjuucau51azHn9wwFrdpy -tz1eoVvePebCRg8819ZGympeCcr3WNX7haqR -tz1SfeJWWhnJrTfiYzUf6trgcTpx9PfVmLPQ -tz1ZK7ACgaJBLf638d1EkewLKxeqWSPTtF26 -tz1eifGCCeVF35W7k5byeVVV3QvHwja52JWb -tz1YWxEDehuHmpRnEnZGM4wuZ7Dc9KMbzsbJ -tz1dmy1VTqqacXmB9pCXqL4AZP4wr9evsnHB -tz1Nh3sNX9kxq4eJ8qiCZdxksdExcJYQcYi5 -tz1fEtmmanfGebES2bWvNR2V5t7qNcCeUZ4h -tz1YA21W1BUHSyAtG4gvEwG35Epgejmdqauf -tz1YJ4u5SLmontKV4TxApruxmwMBE9RP3dfc -tz1W1W8JTYCtxEDTLcGCdXRhKCHZujkTnrEc -tz1hM8Vm8tMJnEUNB9pvh4jyZTmiGyuwPqdU -tz1QnoqyzAvtBQ75MR8PMnJsBHEpABArriZN -tz1MYW8dfkAz4jBVerrjFYKCduz9RrgvJucR -tz1QnzfqA2dihsQEvBaq32LSseA4dKGn5GUv -tz1LjiFMvDhNBgH49XvBvvUBUiQbXegDZRS7 -tz1V3UMCgBFDW6SbNtSq6UbVkoBRhWmQxsNH -tz1Xm8bcgpn1Bu5f9AHC3sArH8ReXay6uzE8 -tz1VdKyH7dR9VLAbjCVsqBzwzW69jZbgf5d5 -tz1LDM7CjmGduSVnFAZHu2ZJiqZJC2Sm1oaR -tz1VNo8AjhrqWDsJp9iXEwhWv42wXrdabkcn -tz1fH6J94WvhvJhvLczvahLevbArErjLtN1w -tz1hTdMjsRKZtqNittPu2qd5nmabkrGehihG -tz1XTDkB4zz6f9k3jZuwLMckssaH59XXNin1 -tz1QXndkhCpy7niq5frb88Z8Tvj5tUC6yo69 -tz1QNyvRExgjo9bs3kFgtQ6hRWdUVhQX4NM7 -tz1Zi2Kd6W37zfU67RGrKWz4RAWgNCPQJBkv -tz1eNaMgSbTg1LSt5gnp2nYDT9B1Beou9xCz -tz1W9RpFBz9b89xkjh7Rh3GkpjdWvwu8N6o6 -tz1U4rad19cxMLBx8ifT9ZaqXczpGqyPGRaE -tz1R5v6AAanaejZbHPifon9iouBC4biMcomD -tz1XZyFLwxb15z8QySvPSMxC8WQk5WCwhgo7 -tz1g26BV9irZeEHdSqvdu4sY54TRUgwzKgFm -tz1aoN5LMqzZbTNY7doo75DZ5UskgqikM79T -tz1QzszpTE9y8sptQHJQbRWM8RLDvvLJj6mg -tz1bN4goa9tDfmtDpqb4t4dQ6ZQ6j29cApNd -tz1NExwwmiWGRWsAbX6pdEhvmEjwk6bUsQjA -tz1ULk6cc8Lsj1YjXZukEsHNpt2UooyYAEAS -tz1WKoyfdEqQWtFyKFy1wyY1GhmQDRc1CxpL -tz1YNgwPAe8N63QvGAMhyHhCMYnWgiDLUo7h -tz1Z8Yoo1PdXwwvTWLZedQDaXNnR7HGdQLcB -tz1QVuQLcWtbqfG7KXFNHTqLBnVPP56257ED -tz1TG3QqLeYEHnw8GGdfBXQe7af28EcHvvbX -tz1TP6cNaJkabjqQBrmwdSz1aWhnN7a6qoWH -tz1YRNBTJm9Kr2N6FEJzzmQEtEH2gxuLVDxz -tz1csKkM9C1QTGCAvPQxguAPS6EdCy3nXix8 -tz1X4Yzm6jdZTy3wnWjNJX9NnHDRLjxhwU5t -tz1S4s3iUHimcSYVipULdLbCopU2eKNKvaNW -tz1f1a7WJq7XbpNbeQJHDM33nMVUaSH7rpfY -tz1bJ7xxmPLqogcfoxTZvAcxTYxJAALvuGiZ -tz1dEvahmqsGRTDYcvNc6a2exRRJJqeC8s72 -tz1fvQLQWyJs65TpcGdu8VmCk3gx6fGJUHqv -tz1PTm8nsKf51teTnd9kTc29ymqbftWtZ3En -tz1dE2fRzeFKqKp3gCyngdjfHj7rJxJsFg5E -tz1aHDFAVZqLvB3WzgsEWbJASrFawcgpbxcT -tz1ZvmHRCnQ2rQGDwbL24BS9ZMPyq7CJPv38 -tz1fndTXaa75dEJupBbx7etTHpef2vWzAzA7 -tz1fiT1a5Ddr5e2pFPi4XTnzqHZ3jhDrGhMt -tz1egy8qg6nuUGUcCWx7P6W6JsHCrDFQGyMg -tz1aesz82DJmo7ts2Lcjp38uvQM8GjQoFmEV -tz1NesAA9zKpVpeKJBJ9UHuUkzhjTN8HhmLs -tz1iT4Eq4yLdbU6n1dXrMZ5YT3hBvNsyKW5F -tz1hNpqSssg4ACArEFQY2oDnctY416wkmQqk -tz1bysmciCWFkLMJbrQbQPeS3CBp6U3xrdZe -tz1LEc3GZdKmzTySCLJsAr53duBnnun8n7fc -tz1WP6bosKGTkeiP69TkPqeRyBhxg5Kwsnj8 -tz1KemUFwq2fQ77Sdo7M3BbTuJ9W2nJ7nyFk -tz1iuYtgtKXJ1E8woagUufN9xqZreWByf6oa -tz1RagWxzE2QnRJS1e1yYyfQ8sRqMuTHXu8w -tz1MihkratYFJ81qxFtHPnY3HfDnKA26fSKb -tz1W4jYaYqVaMpsm9WbrLJzNx2B2PqkXfY73 -tz1SVVHa8R8VHFYhScwhphDDPDP9eNNA7KeB -tz1ZVJcDjepfJ5vhkKyEJN9gMavoRRfRzJ4S -tz1g4jN2y6rEzunL4qcY9iTgCMYbkUg9UHHU -tz1ZP7WboNpi8AJqH86q1f96bVp1m7SQYAVs -tz1bMkXmJxUyzjU7o8vYX4oTN7y3zviFWbnn -tz1gowNTUTVdmQoxjgBKFU9FC8yDKHXJd5JC -tz1dXeYQFTAGv2KMRChZJTm15nvecU3wp2YE -tz1bvbK1mLUgBu98zNJVL7gtKnyFFD5roJW8 -tz1Q6ZzdhudKVssnczdfXTUcuwCKwX24HNY3 -tz1PS1AKGQf1cRJJLSGgvDuYoJZ17ZA5Fv2M -tz1iBWdSjFbCK9LniyTnzQRdE4ZVoRCqcC5H -tz1aWnM3WsqhNE15dKfehp8oHm3cnTbH47vG -tz1TjfqyLWtmaKtD3ha3bCpqWXzE1PTbg8yA -tz1eS6oTUccdhWYYDwXaohrS9UTEH4Fk7YRW -tz1UxuePFVvFps4JoY4kdeitT9CAirbXF6Gb -tz1Pgnnix9Nv4BqVhDMTPZddsefLFSPoAAdk -tz1MU4FF27CkyuJeUn2qEZesgr4kwCDxmbTA -tz1Z13qG1gjTM39GaLLopAerF2aSmDfkKe4q -tz1dGsTBqVFbWWm97CqruY2AVNv3RADpGsNw -tz1KyfaYFcSu8fwzUSwA3XSJBxKV4xBiDmMQ -tz1PJFcEgtnR9AbAFwzDNjdPQ1a1ENpmv9ef -tz1NgoaSxpa9tjLUPXqSMVKwCAebmDsngwpA -tz1PyWn7GoEHvvMiQMvMkCk84HZtNT8x1S2L -tz1cjWbEAye7LscRKX5fzNTXuPjK9qpE3iHH -tz1LsbDKFyQB9VMR42hScKp7V3Y3zJKRmrJj -tz1eWdvuDLSGFWusVhyeUPubLZvHUUB6G5BT -tz1Tu29c5Ptb3tP5DPiy8ZHnfHbEZ8CNZHkN -tz1fRJ2udGxrp4pwxPWKxj8nKZ4BiHsRz5ZV -tz1RritgGLQitMNtMkjX1MxGp5sEJgfDcqPr -tz1hF8R6cPorqRnBuFQabzY82nvyECtHG1N7 -tz1iYJhrvcSX4JAVc7sBTr7WD2bcZBt78rYx -tz1c8vUkhubZv9Pd2UVWsiJbomfmiSE3qErb -tz1i8GdiHdjJh8o4KqJTD2inGvf6tzZNixfV -tz1QDEFAyxZ4ndWfvoMDtJ9tZL3tg5veSRSg -tz1M9Ji7dVpFTz8FjKfCBHmqFTixWyCFYEWw -tz1aDSveDEPgb5pGNY2p5jMK84kegRd4Mtga -tz1httJe8mSsJYvsRKZTVQvC8xEUY6f62MPb -tz1NVAmqvYDFJaUmuxFDrgpKRnbNjt6Vt6Zv -tz1YXHRfxNREheHyUWNLNWuTeBTKjJ1VVMc5 -tz1iEwETXtHsmrW7nDbDvC1GHe9ex4F5U7na -tz1PgMyej4qHZ4HwbP29D9pTaHUF8hpCm9Ed -tz1U8TWDWmVUK3S7qSZjCRi6kZ4wmq1rh9ic -tz1Rozuw1yXnbQG8tB1YQeEikZJQabooTSEh -tz1Lfb1CgFeuVSC3khjxLsftWKWtUy6TWKTo -tz1hjsxrwEfht1NTS6uv4tpCFJE1xr7x361M -tz1NN8nHRQeUXSmSv9JJCa4KMYpeGvwg8qPY -tz1byP2SmPidPdJtvxT2JcVM3LmZHyQRo6Z6 -tz1eu9cieNKubQu2DmtYrmrRiZzdzgtpCxdK -tz1QGV2xH7tGpaSREcaeeFbKh4pdKDXGPisU -tz1bbmkxVDu42FWdBTWt1jA9XaDaYhCVMVS6 -tz1Sxb5dndYqoBhAf7J7WRYwyySux7UWJexk -tz1RvbYCnV33DqVk9Q9rHNz7iwH6E2ydCtLK -tz1hUvEwmcutRBne57wGHtkrca26DErQ6QgQ -tz1dEZAsZ1UFwYMHaDpE2zm3em68EoNbVwAn -tz1hGjSRrQVxp9NNcdBvpUPJZk3gDdNSVEhX -tz1NZ3yFBZUgj94twfZGjcjHbDwy1U9k9uxV -tz1ZVp4BeNnp3mhTdD1otMb6q2Wt6TF9NHWt -tz1Qx4g2TJg4GRBKVvexpLcvPx3RYVqfyP4w -tz1XtGr8kjwSGBUq1nS1YyA5jMjj6TKbppSo -tz1WH2CvAP4ZB9wpwjWtNKfppJyidovDWVUp -tz1Y5rhRGCdaFomUdUukRp7osrGKVfBJ3kBS -tz1hpzhbXso74SnbuiCzWx6BLGA88FHkpgLM -tz1gc8ixhU9acybXFdpJjewTbeLA26yeKE5F -tz1c1qn3mTZzR6T8kmjUZ5hEgttpG9ovBv1S -tz1cTxcqvFvyPhECMrM5Xi1B2QKCQFf6voSq -tz1QD9GY7fMSa9SypxadGs8CdJ7axr9889fW -tz1ZVVJBL7LBGVpHszvAyX6JLfe4PjJGpU3U -tz1a9pE5Fkcg9nHf9bn71H2yJVvvGTb4vra7 -tz1R4nNimuMJNGWtXYo94rf4Zscknwi6FrEk -tz1Wbt2FpaovLSa12Sn8Wp8f13q3xU5v5em4 -tz1ck5tFLy4zpxynxuHpoaBbDabEgbYgZbaQ -tz1giucpg34aVt6U5D3z31emKkSph9HYRCF7 -tz1bS6xg5EAP8aXCsboyh12wM8tN2NXsoJLB -tz1cBioqdVHTXcsnSvxDPQC7UYYkHhTBskjG -tz1eEuc73T6xMLYDhVgrUjoMqG1eEfWaEYLi -tz1ZY9GpHhWGCJt826BaaznfrasSqLP7Rxiw -tz1PsWtVThNw66hfK6uAZQGTDEDEYT6CsU9j -tz1XgcvCPyy3PQ4QooTLMF5TbC7X5pVgouS3 -tz1hV9XQhttkNURgM5wvyziei1q4J4kJo9jR -tz1Qq3QnifKabjj17743CymmpjmKN1yR9d4F -tz1eq8Mgz3XpazeCKyUKG8ccHgvMEBHtWApm -tz1V1YyJCfahHhzB2fVh8vFpJojnCGfUSYum -tz1hr3irfch7ZhadeLfc2dxEDFjXzNr2sYGC -tz1NEbj6r5v6USq2oviQujMepxKaURbmXVGQ -tz1eABdGpTcniPcNyqj7RegCaXXHAknMxVat -tz1cc5ByFuV1kcK345vzsCJP9WKCEBwywDsa -tz1KiPCpWMYigdJn3JfgpQhySAddXmNJb2iB -tz1fL9dSZ94eJqxM5p3yC1G1x7ftBvi6ad9D -tz1TueYdAkqWJgHQao7VcvQZchjXasPMwEFZ -tz1U8UT69ZiAUfFjJJieAwHpENz5i1Tzo5T3 -tz1YRvijs5fStVERYe5PgFXcepbTkBqgEGNu -tz1iJFmkMiugbWTRyKbJ8fATqNMXAF42GSAP -tz1ciSwWip8WJoXNLmDW9DkqaxA8SKjLZGHz -tz1RjkSiorH1DUAUakJk3HVD6M8CpGDFKodf -tz1h55pkDqK562ZKWxwrKzqBtQL6pTG9jwYA -tz1fxX2widn4PbMQXWRnieEvMJTvkpBQfVEr -tz1R2PkrjjGASdiwpf6t6Q8L7bVwPWwU7vHZ -tz1cZRfaxzF54Ua1aptLQsCUBJ8iV7MUBbwZ -tz1dCBD1MVqnshpqRg9Wvr8AC17mJ114zrc4 -tz1Z2ZCcvpu8LAxuvz1BDcqivVY6jZoHK4Ci -tz1QFuVhsAarv3FmHZtUGdSU52rvHdnTcW6T -tz1ZtXZhN3rqDy1PWPB3wLJYsqHJSsn8iUJD -tz1Ya95dw1PeSj51afDCwujYa7depmNYc9BD -tz1YWeq77Us2dSkBgsdtw3YTNbrWSM1qDifi -tz1aBnCZQHiSnQTTgDeSfvSCU1As1gAYq9Kk -tz1iaqJGLJUMy6mXEWRrKtjPv2xejjmDLfib -tz1dfDKjBJgXcwaqyP8TFnK3DY6yhDf8GRk5 -tz1TYuJgi46VwFy4j9sLHjkub2tzH6VFrB4Q -tz1dhFyyNLxEDNovEGtPRt7X5pjdvWhNGWTZ -tz1iCuvurGbzAaNqUR3jh1Cy2Ev6B3i3TnnS -tz1Q11dgQxG2ur62DHJp6LCnWXzdLuJgvUp3 -tz1ZNZ2RZaCp66KzxknX4hYxEqBv5eHFtzoG -tz1SWjCeYP9XDMo8MCsiXwJmtJgZY3Yc9TDh -tz1NR97b1Xb8T4Lx2p2MCdLXUjRxUhH9g8Lx -tz1V6KS8N6usZUDcRV6C549XmQqd4QrtSDki -tz1PZ4tfA4y5EyxyoaHXGTXEGfg42zzx6MUy -tz1NEbsFKvGTLgr1mW5MxU38hSXZuoaz24PC -tz1Pn2p3b3gJgV9G5sUNnuvU36UoCCZUYfDw -tz1Tw57kZASsskdRPmzj1HQPmdm1yP1Vv4w9 -tz1gzVrtEh3osvUnjq1cU1yureSrCW17Y7YP -tz1aDn8Nqx8X11oyFKNExukTGnABi71t9Mbc -tz1QYa1cGsqgdnkQNAtCrdUUiorwTt8XQ4mU -tz1Puxqziz5A1d37Aqrn8xbm2ghW5nyHyGRX -tz1X8WtgFHbm2sioDDm3Rhx25CGb8mjjxkhC -tz1h5ejERZGwdqAFgvPU9tUp53AH3bfJJXyW -tz1NoT8LW5kBJd332uRArHjLpAQPhyuQkpSg -tz1TWD3TofoWhPadi26m13LkSjrz7nRwTyFf -tz1aDHS1bRefYo49pdrVutL1nQfMSKMb3kXQ -tz1VKq1ANKRi2eBNJgZrWrTvQJ59grG87HQm -tz1WE43w3xFNFmcQ5JdNGnXShYhR2DvyLTRU -tz1LyBRpm2Qjmw8qDX28Gg8rK5wxB7XzJyki -tz1dJ2WDDrQF334LsLWp3yeAdBqWPyLe8NiF -tz1bLH8Uj79gDgGF917FU929E18Qd7CzwEiH -tz1Ng54stCeb6Cx36C59aornPHzmpgQz5SPM -tz1YxQf7khXcXEZNE3jam9we3oP3GsXP94X4 -tz1ciCCU1CF8HegTWweNmNMcrFoFP9LuMrBm -tz1hLXzmV9HDgsKU7snvkkQAmTFta5g3YnV8 -tz1auWTEUg4JFesTiwZUmomxJfN97CchLkMb -tz1i7XQX2CrhQjNhdi6fJLAx6791kkqetgpQ -tz1RsB29FpWE5VF8eLoxwL3M54BtTvpHSkAc -tz1cybJAs6VKc48zP6mjy6GhwHKTMSZVepHr -tz1dKxjKYXT3w5rCQJnaVb5oFP3Bkg138nFS -tz1NfUFUJ2e3ue4JRLsw8J7yYdjXCnLpHFTt -tz1f6CAoVB5fxWnCkCcbiRFSHDj13rXMFdBK -tz1gRsmbzJx6SMj7xoMR94XiRtKn4nte9RtA -tz1PNvxtTyxURCnxPsT4LTPwJFMhpw6ZPWsD -tz1RcySPA66LEXEAH9ViJu2b3YAR41RHsWdr -tz1hF2Bdmwnf6kjqJqjjGTt6ZJ32nhJHDKpY -tz1b7EJmJRSA7wX9QZMLtY9zyUyq96ZZPTcX -tz1P26X5YVZEHqLrBTXyaSyXAaYBvTaCJzKn -tz1aTXiQ7gn1GRiBdj4zirFgZ5kDjSVU2VJQ -tz1Z6og1FgczmiagiWehpsYMmzM7HDqX84dM -tz1ie2CnPwU5CTk6CXfcs7cWvpB3LAX6ocpc -tz1MzK2QVygaC8MskkCb5vNyx1WyT85jZJbm -tz1X6WgK8uj6DB8CY4KT2ZdVUF7SppAaAnHA -tz1TeSAHuKzGWde66zMf3yyNo35N5VZYLmhq -tz1RgCA8BtH7wxFqRFkQGiNsJbavVCy1xbr9 -tz1UWykqx1PBaqCCrgy8wnbTB1GTzyCY9keA -tz1VJM6z9QYQG4EN7Z7HdJwYA9NN956RU8n7 -tz1b46jr21STVkv6hNWoJ5jmWEFWCPmBSgVE -tz1fJeqoW5ZPaTwn6uBZmyk6BksicB1NETSt -tz1dZjokPQv7ifGTEKKqiDXq2ofigNDwgMps -tz1Z9HWsRUz2n3Zs5xFDTuwXUsjaxsHCSae8 -tz1QgGTndfCHud6YCEgMBdW3RnbJ4zW126Ei -tz1hfS5njsGv7PHMgY2AF1zT4mtoe1Lic5Fg -tz1RR6aGSYkcK8FsTr9tVWDiiazysrrbDNuu -tz1YnpRmzoSP3tmvooHgXmFThozuKyBBKcCN -tz1PkNmowCiuLjB9iNaJM2H4ehU7JQcFbcHh -tz1Q9NqPor2RjvvDfHdEbPDbzZVs2ofGJam6 -tz1WaFAmoSchDrYYtBWePiNDeJGCy91y4czG -tz1NEaDEWTNAbQmchZFsbVNLo3hhinqQArG2 -tz1MnyYPixeTxv339nNotoHzgXhBTG7ERHqE -tz1ZWEBL1N3fDSAGCfS5cpB21SxsJ6SCZQj4 -tz1MNVL3mPhn3FNbi7ajsJ99CjyjQiXfrMtg -tz1h8mW9vnEWBDhwHYFWApjLs7vqBtakCDQx -tz1WwKGTn9v6BMFQmeH8VM1hA3pcFEoCC6DS -tz1L44DHi4oz8RtvamcvuHPzpT3gpyFcDakF -tz1gk6xNrNhDMSgugUuEYXGpQahMbgL22tud -tz1gP9k5hMxiPioQ6bhhQfSSYkPXTqUYMnaV -tz1ZtNYob9dU1gnopf2fDnKdL1r11bQxUMXT -tz1NRo5sGbpEgfcHXCL8SwVChoehNMMmAkiR -tz1XzuTEhHHTtmFWPs913FaU1RnvtCbiBKz4 -tz1Qww98pMJpnybDsx8yMZuwaW6mLXtfrSeP -tz1fe7ZzWNP49CfQ6CEsbkJjyYU1TJtLi8vh -tz1ejcF8fgKmHEmr9yfTsBwVZT3jpWWC4jf7 -tz1UGgqKsu6SBwPfwCxAaqRogJWhjd7gm714 -tz1TKkf5gCoHnYLM13GGpm5FeFfWFjzdGz23 -tz1bL2Lq9n4UzNS9VBVedeCFjJPyp2pfhXS7 -tz1Mu7UPXGNehRM1yPyprkWjppLHBDQ2XCor -tz1MDqXQMr3qDCrAwGR8fd9d8FudMwaXYQX7 -tz1NrNS2iKKVqtwqHu6co7mWtjHZU1n2rwLA -tz1er98YAcVZQb1HbMiw6Dy53a6XYXnKysYs -tz1YV8YNW9ckN81fz1BD6K8g5keEKdza2AfL -tz1NUubTN7HeX8HJMUgQupDSwZ19zYwnAHXv -tz1RMSCRweneoWsbjDVSJ24MJ2onAiZJpiHi -tz1aGWWc3Qrpo8bH2kh56Qh4hLumxET3PUmg -tz1d7utHvSYPTyMMN2peXLKSefD39j8UrMVv -tz1hS8UfYtxDMWhQ1sgeK7sHK5nzduu191vq -tz1ezraaBxhnR5wN3zKtaTT5xDf3BZ9kDAej -tz1QtDVmiyh9vXbsJZv89UDkiuAUuCKMdJYJ -tz1MddiUDJR5GmT3ZRwmQH3xMhhygD1ivZwz -tz1dY4xxRP2CRNw12hoRdS6PmzwosU97r1G1 -tz1WhDZRd7pkM7oywYcTk7ndgk7i9ipAbFD2 -tz1g3Sr9b79YuxqqWzr25yN2J1g2AidwCzLZ -tz1UFCYP7mLM9acywn5DxWdzeqJCWyv8jWAm -tz1cbSWmSoePUkk8mdCT8hLq1b97eVep9u3V -tz1iFoQsiu8trGbhKCEDo8JFJC5U9j33QHEB -tz1Nm2cmQEgmbfkCVigcFDhwzRvHLPxBHU5E -tz1PJaxWfoqogH4LQjc14MxF1iLewYJJYCtY -tz1NEx7SEtHvoZriT6RAhBGtEwzH2DQ1DRhu -tz1TqfG7XqH74QoBJgy3vZjSDxjTSDfNULg9 -tz1UcEDfWGJWnyvb4eMxcbMjSRd5D8Pi9QAd -tz1TvKD3tZGv2jGap1CHvxVPjVc6onmT1Sr7 -tz1QDDzyemjaVNvfDspNm3e8SSNKzESqwyNX -tz1WXy1Us3N6MtmemyR6pm8D4XWjZVA5778n -tz1Wrwb31eGBk5VKHuYtyPyPK7PNfuzKdvQF -tz1aMXfpdCkWK2eMUZ8JrAy8H4SoYKXnrvyB -tz1W9tPzy6MpaBJUM2Toc1W612bQTtb7t6Ls -tz1ZGYeKJewtQWmRnSgkpCjLSiBmZuajPfUq -tz1hegoKEWiX5GGiC8kmnixupiygEUCXwt4N -tz1TadTwrkkFRsqZ1Gb5EwzaDk7zZv1zTJoq -tz1ULYamUzDfKQ5aRkUUNGGv2br72tX7R21m -tz1ZE9NxxNBPK32qdqf5iHLNQzPEXDY5ySev -tz1LJYeArqHD9R4wdxbE3EB5B7f1srczE1ZN -tz1dLuXNw2EXXisVyhSSdM9Cx3oTZcQxvvDC -tz1XMYWqxHL2na6Firp91b2ibq8jL1eGabd3 -tz1cFRGoyDKDNJwhdN5g1aLTdGcqiUxPm3dd -tz1RBDubrACNN2Zqb3gpeHCwr8DP94PwpabQ -tz1UMH3WS4Gs9z5zjUymTVwyUNhkPg7vMEQa -tz1P47AGffaYyBNcye3LxFLgRPS9wChkszyf -tz1WPksc1fMTThrfS1fmtEc7gosYeKcY7uLw -tz1cDpRh28Dox1yGRU9Whihs2NPVGtCifcUg -tz1LkMMF1h1pecYFN5jca4CF17VudN1JbQ9N -tz1dNSmT7BSUcsy21mDEGMtFigkuJ8gidT7U -tz1P4SdHbKER5wD6BRBqKAkPxENfhiNXDyVq -tz1frhuGF6Ge5cwRrLC37Dd8cWypqiPppYTF -tz1detjqTgQYT9k72oqrmY1yhLPv2jF2z5S8 -tz1Rx9NbZUvcGYzf3jnzSN6FWXwBj5oE3kLk -tz1c3jUritiWEBMkZMkmoSwyRDS5HGVw9bBe -tz1g5atj1MBYGD1rGtwcUJG4mU2apGfXZFa3 -tz1Y1NMeka6UqLtdH4yyfvFvXudc6orhpPdW -tz1Yne9HDZhu1mbojPBG59MpTbaz8y3Jx1c8 -tz1bcJehdaANo65BjKMqPWaquJrYwHf9mTgt -tz1dfMfMsTyv9q7oYRTthSf75n3SgPugtSPa -tz1hVotCanJLU8ruK7X9SnaFoYGpiuBnazUw -tz1YzdsQKJWSq9ASCAQwcbH6TiM8PTR3enQj -tz1iJ3LfCgwYc1AZdpdr8K9861TBvUppigaA -tz1ezWju79e4PPMRQhbCPn3vZtGPmVipAeny -tz1e44AuU5LTsuBNWAX1FdDyBU2LezagKeLk -tz1Q8rYCuCrhiVnGhFQiEQ8xXCWXdFZMCnur -tz1MWYWTBA6C9DL4W5wWou4ZsfBcUGhX1XbK -tz1f876AvFMu4Qy5HzXSVejrSue4qn1m364Y -tz1ZbGSQnte2gpV9kZhtgmdRRAAZAwmJZJx1 -tz1ST3MGgrYZRZD63ns1eoTSUwEpzViBRk7M -tz1VvK6P5QgzUZTPSrwdaiMXZFAT5C1hkyM1 -tz1PDCdj1yWZSaf5mhvrxmTHNe914x8xTBuu -tz1bNHKL5fjTy2qhsooxkeo1akDkVmZZP1xE -tz1US2cvS1YGwBYSCp3fy7QncpmSC2uMKysH -tz1eMXAweuMdnYPJS5ZU4cpEZwY9eK7WvA2a -tz1djH5mY9hdUnEa2oDxpogQVEyTnuPSfX8H -tz1hT7ht3jHZwpGM3jon1XeAisPp4x3jqijH -tz1YcTv4seTA2rTsLANaP9SwmRgQYY84Be3X -tz1ZJMJcTNBuL2CjHdifrndgHgsb4xfvrjp6 -tz1eTF5kswznRARfrp9Jw9JXrrcUC2bsCQhy -tz1aSCcKFgVg1frWHafJG5L2gHNLb1jh6JN2 -tz1biHRn3Mrj2WAH9d61iZqRDWQnZbTdsLg6 -tz1ZvogsAbFEY2sAs7ozaVzQqjSMtNnVG98Q -tz1f6smB3atymQQLJtzVBNs4QGx5PkdwQeFj -tz1SiBmikHGWq9yXowBsANUbxrmHZGA3xBmB -tz1Wv6vHeNLXigzMwEFxwQyneWp19WvCfNBH -tz1YrgV5vfad2sVQhqNxY8HKrU9xRryWMyv8 -tz1bRNEhqvfQeAt6ePBNXu9K6HxEDBiUsDmG -tz1VicpmVy6mfnV4tv66fj5PGh6dpPQ6GKzT -tz1KmPGLQ8bi1SfMmyFGCYUnXtAiaudfCrBy -tz1bVXJaMyBUgNXpgAXixDyskX74VcGtj3a2 -tz1cj88GiaThkq9HhNaLXDmVr3wapDqr5EKx -tz1hQX7NKoCKVxKv8siyKAfBpRa2GKs3Etpc -tz1Y9Mzq9Ts8oPwqFSPyezDGbQx4M15Xerhb -tz1Skd2ztkzguxRh3bwunouWprRXRDGM3cK1 -tz1SaTsLzz3bDrvcYNueZjcp1urC7Kr15xt6 -tz1XpJ4gieV56wYpe3vK9wSscNoPgw7xTmyY -tz1bje5RKiCuM2XfXzNggnfnha4eydZpC11e -tz1WFvnpNxTj2i6ApSk2eFKi47UWvr9tawX5 -tz1YrwUpnqbH5w6sSL7hVr2UbD9aRwHXQgRZ -tz1dpqeoybAcq77tg5qgzt1JwFym5QSuiFkF -tz1R1sy7Qc5PNRiPVJprwoaUEy5eZhWG8Wk6 -tz1dam12st38dfMjLsVuzHEXAgv1NLCe9bbB -tz1YF3qPFYun8EzHzk9HfJsvg14y2NA1ZXam -tz1Q8TyAABFrMCwWVnYdkbFo8VxPZ7hrH46p -tz1PbZRt6ptcTdFfaUw8uJHX3xiq4chuq3tG -tz1WZVSyyZTzmrrXxBimW6PrcsfsB9GuFYEG -tz1hGpqxoQkzPpbME5cZGwa3HWPbVBFk8oU4 -tz1QLoJTarfJ2pu5tX3Z1hxbb3kucv3ECzpo -tz1ca4V3Nnb4pAgFT69SHygLtLdAUyZzPyEE -tz1fSCCc9YV9tJJQRFaxeGsWKzcV2hWeJFmW -tz1UpnZybYzFXNVtyJRjAbvMRpaiezrovUv9 -tz1ZbwGXKGd8rhK8nbKuGzr4chVZrC2Y933j -tz1SKtvyDvCmVywzKhoXz16PATiGEjm2MxTu -tz1dAQkpS6M4M9J7hugXSsTMFxkrsKXRmwtv -tz1bnvfUdizbXAZVyS7UgPjC3yGALfMKdEbB -tz1UCJTsBY3AmZWL5visJcDZ47otJtEi4cxw -tz1VwTLhbGQxH1StC7erqMEqpWxLgSWaMW8m -tz1T2FXQpiPLixpLEPaFeMzkhfKS9oJPMcW9 -tz1eXSkhMY6mUEpfPPjgV6k8UpauUDsbvU25 -tz1TDqqETadvbYf91BYRrVW42rLsTBUPmco6 -tz1crUfqbimmdZyYWvS4E5cghqvSwuq3c1Pg -tz1T9CfScgRCp1mgXrHrSed16RqzN5ZK5yTx -tz1R4qnjmBbYLrkYxvN2qngexLYwKQQ4faPu -tz1RHxgjhkTmFkxQ7QX7nA1kzX4akMLfVqv5 -tz1aKxUvEMB2428WSdHkLLs9u4mMiaC9P4wP -tz1LYd5zTwW9Bv3vQm7mfBvtQWWKbNuqUyRU -tz1ahJPAaTcY7mPMLbmaWBmWads3o2fM64y3 -tz1WDp8VPSuagEkbTDzFeBoPyBFzPwiQ4AfC -tz1bGhJbutx5pKAZL5steUUMuBfS275Gfrbp -tz1ZEv5ntSY94sdehM8K2wqJBNcLFFxdrU7t -tz1SCsHohc9zirzzRwCDD7rxerQAe85qJrPW -tz1S76iAuKfDLFDU2koK9fChRFPnTXutHozj -tz1LuxDWFEGxYXNkJXnDRFmih2DTP3Wi6JJ1 -tz1evGEQRRWMgSrc1ugfDyNNN1R5JZ2X4cB6 -tz1M9RNqoedtAmGKnsjxfwKAkgyyEjAiSqAe -tz1Y4taps89x3s9JutjgWoD2eKbEzGozoV7z -tz1UzeMqiu3aVVPa7NsmXkMMcjfD9eEHrSEf -tz1TqVbAX1MzenXxL1F7nAQCyVEoGH68FQxc -tz1cJbEQK9ueegpsTXhtdaPYYsfe1Hska9TZ -tz1dysFY5ii7sagQ9Fx4ZfnysQ5WRXUJ8ijK -tz1YtVuFdo6euB2xvSsG8CLJG7xTbME7SLmU -tz1Sfut3H4rbdoqonXJ4KKNqkQqJ5nQvPLye -tz1URyxNunhjs3fvr7kX2g2gcMahohcJBWMS -tz1TGEUvfE9zSdFjzSiNqRKK7Cj7QKUmsAk6 -tz1YVfearQRXpMvJSBX5bVUUf9higsauGqrf -tz1LpK2t9xMbVJ5eYd2cFboANHui7mfPmLSH -tz1LyVS3BDBXYeRioM5WtjDG82NTZrduwiTe -tz1WVbAcP4QyMiNZSH3gZSoDYNEHdZU4kMGQ -tz1ZBXLgS1Bdrih8QgxeVCGbL3AVnewf74cb -tz1YQz6yPDXUuSiAK5HvmCB93AzFpK3CQ5Tq -tz1LGgCbKrNt9E84m9XcXh4VgiGNB2VTn3TC -tz1hhbhmnYHgvREAzptY9ZwN7PnTLgNk3dxj -tz1a4P4tfuY67MsGGuBfJbfkybqyQM2o9imV -tz1YVxSwL7WjA12iJmHANjjwJ4rtE7iRdKW2 -tz1VW5Wu4X7hDubM4cW3XfaPhJTL1ZuaXmfx -tz1WLe75UmouyX5Mbz9EbWMxQ8UWxcwAPBEb -tz1TwRR5HPxMHBREgz9yQBhnUTL1RsthNiSZ -tz1iUk37Aj9rHUu85HdytFkzqJrFBGuAMuhZ -tz1dTyNwwJdN7UM22Yc46MPiK69iD5VvLs4F -tz1TaN1nWUCo8piNV8mLHmidChDs3JxWwzxR -tz1XMGquCurQFzU4F3Uyb3AeyvuJc1bUf7af -tz1etc5Jq3JJyQikoGrL3dCg4jQztiHLMWN6 -tz1c2FmiZchQLQUaZhYYRBBPSCbdYxNR7nJo -tz1gRkVQ9ZfcoprpkVTWFdqNJMdayzRcGDuk -tz1YgdCtB8eqhceakUJ89WRVFPbhHasmVB1G -tz1fm4WdHkJF7iXpDJ9bfUXMANkdhZkhX14c -tz1dGBVxgLhEnaVAScmFHp3VCdBfQNxt8XoU -tz1S6QsQRrhnRwv6AJxXhkeZJ8S6wDzHvSNZ -tz1RWC84yt5L3mL3ya7xpVRMK4nx5x8Py5V4 -tz1gzYXrQyx9qwEmuR2AVHSp811PLQKS6QSg -tz1NfDpyzx5fKhvLRFNvf2DiYQt77tEhZNzb -tz1RyAERM12xNvYjwMc3L8kKtbt8CLH4xu71 -tz1TJ5EKzgfq3QTLBXYSqsRdvMG9PCiXjak4 -tz1hnQfytn2MNkg9JMMJPWC6wwwvGXTQHAC5 -tz1NyXTtFpEGzydniJBZZaTSPLj4m5sMxkwn -tz1fwxyQir1soXRkHREkRRwpYqm4adRcQv9C -tz1evWe4T7mHWjyfLPhmDLRfKGpgUDtwmTEq -tz1anVfXGzfGXWv2JGn17Zh9vayqziWBQLmX -tz1aawEznu4hhrodSLgEBxtJo29ut1ydApYE -tz1hbfhovwJDtqBkV32jo9s5PHbAoZWTK7Su -tz1UfLC1g3GgW7Racjrde86yDYT9Z7kgQR48 -tz1dHHt8xMJtRVw3LazBQBum6TmhnoiD82GX -tz1c5HxRc5wJ1HNiG4xRePNCGTzBbVddNpkF -tz1PAyk2S6dfemVoWpixB91ktwGscfhc35PR -tz1ZY6iC1fYVx1tVmJd3Fs3bT3EvuR3FVtBx -tz1dd95PaK5RRHE3Rgb7E81BufrEXamKRc81 -tz1Wgfde2r7GRTDurVLiABLrgq743FUXrBuR -tz1LSa3abDhSht4ziYypF7nK99KjPPCqesEC -tz1Vi4YmeRCrHRrR7UjwxQLaYKxGsLajmy9x -tz1fSSn3zj3Q8J8UAQ879CY9gaQAw6prSh1h -tz1NoBQwvrhNKKbLrFSMKnm922L4wenPkbya -tz1Vy1PFhD6DSzMsNQcVxaGJG1FyuecrCZ2e -tz1ZcYwZ85ZRtBUPWTgjoJwfK2sRnXEhLbPs -tz1XZ6cV36UJJZfp9ziBrLYRoSwQDAjNS1G1 -tz1f4DMp2tmn2ZZRy81cHoUFfAQfX4nQfHAc -tz1SSyzqJUvybv1PCLvhCZwMBMq87JiJiUZJ -tz1ci3gnN4rZMcvr9PMJBjMVTZeWYZWmyDfh -tz1XWkAmNvNPVj8fAeJp2etNuqKS5HSiyrfv -tz1Mnj6t97DFAWEXfFE9rJQjCZoGRKVjohVn -tz1LZmTYTmbyGrUYwcnVHKCMG72E44gwHyik -tz1c1iHR1XbEd1afnRJQXZaGvQQAsXeS2HwM -tz1RsUJx1d7nPuk3DGBVxsgZfYYgXaBhxB2S -tz1M7CDBGzL43S6qLriPZtMCSvhEiAeqfaiB -tz1cizX8dBDmawSpqmRNtpqGEWwXnYQvu4p6 -tz1fgqxVxpiaCd8hmtfb2wZTsWRLjBcsUQL2 -tz1ZtzjyD72HjKLvSU7QHGALgVcwHDYd1kDp -tz1hx6h51CgmqTu5jpp15FJiMFUqhLBQMouP -tz1VZtBi7yYMDbiDR8NzxJ497vhyDeMj118J -tz1doSwMEvVZDKooxU1mffJD8DLKGdPjALSG -tz1NaZv7zvhFqE3ThnkJXNHa4dkUF6eErPe1 -tz1eoHDtZUhbor6YW9WeXTWJmdxhDVzXrc3X -tz1MQtoDRxCFjutaPtgDJxh81CyngRkgBaqN -tz1RSBxY9dQUfkWVc6B6PZtUT7dFnEXzaa18 -tz1Qy7LW9Q8xAbX2U1sZ5UAksdqutx2zY337 -tz1LGir6y7mekQNuk7KPKUxNNws5WecdPKFa -tz1UL6HDTf7UuW9enDPqurW1pFZv9EQNNPLT -tz1ZCW2fwNi8qsSbM4T4cWXuioNoPW3dZM34 -tz1VFwGBxWz85vdeMbe16NMrAVcsy4d2BkRe -tz1QgTQ7vMnrcTnmbdtz5nfM2JvoEpR7V4At -tz1PYwAbJQPc6ZouUAfi3g5k2VSwMRqsFf9j -tz1dBfoo2dWWzxmiDLAAgdvk15EGkpcTTkaY -tz1hwcSzg29cWAZfv58gnaVXxtuFAS6dk1oU -tz1cvLMkvMRV9CUna9Buee92mrGuTBZmNozf -tz1YS1BCi7iqpeLYQK6p2u72fE6L4qPQW9vo -tz1SM8wpFrTCzJTqVt7Sec1n9LUkWefjKgUc -tz1PN9A3W4dXzjfqx65CSNuU9VtBypuX6i1q -tz1QeNzUW6MAkpZR5WdCu1TUVsakUSnUojYk -tz1LCAfKGUQ7S6poYXFhSyfBfnRj1UaWHhPV -tz1MXymKrJ8JSMij2frczB4ywzG737trUZz8 -tz1inVcn6H7Lb2hm8BFujhPcfXByKKRDbYLw -tz1cukaPML5pVDv9zoc8yLAjFK4ATh8nvY8u -tz1hPFFEKcxdXJE8oFyaYeYwSdmEZfeapLmV -tz1W7h61zVbcR7wxrW22jaLKo1oM7GUUoFJJ -tz1Nx84PHgQvG6imBb2P36mK9mG2ghySWRje -tz1hbcMVEtZ5RLDyVtTwNtbwDoCeP7KQQnVr -tz1PTpttn6m1neGYXAuL7Xp5T22ckshES4M6 -tz1guP2ZjTmZf7EcJrPDajXVfApY8uKks3eK -tz1dyJ4d4c7EbJdbYwFiphoaF3d3DcW1c8Kz -tz1SGNnwtVhyMAFrqAxCjKnyzvAQ8D5tQcfm -tz1TPbqjqscgiGCMeAaar46WD9fFDaVktEhG -tz1f8MYAUR7vG5RPrA9YwCHPFYwLAzY6oGDR -tz1YDPJVDUBpuEFEFhRAQDQyZ3aA73Lagtjq -tz1SZsab9zhEdgoGjD27iQZoBap166p1gxTF -tz1ezWp3QwWnNsSejacyMZqnsZjPQfgDbena -tz1RepK2jgru9X6tRAcH2d62Vryst5ZZJYJV -tz1eBBFz3bCjhDtGhtCpA39Ff6ZWXNMQvX7Q -tz1PE8Aj499nE8kdLTb1HpVbgCRpXE2U3us8 -tz1ie1fRx6UyNg3DQ1EWVoG1AY58a5JPCB9U -tz1SHAcbujqr2wLky52SJ7XQ2QUPQxikKfqC -tz1P1Trz8g8Pm67QHwGWfwdcKdEhM125Sf1C -tz1ftBKR4KBGhV5ST4zwmW18aYM4E5F6RNsE -tz1hvoCD1sPZGpgUrNdYfR6YoLhpDNLRRrGi -tz1Z7mYDnwwF2uchXQEmR5iShRRazWALLvMt -tz1RRXHVmEvfT2axmSmEKBTmvv9ytEnjdygF -tz1f3TBPh4ivzSdCfm1c4g5msutBgaumXJhu -tz1go5JZBt7HWfySg5RZHvXsJ55L1J69CKbR -tz1NkDsyMbSEBjJwFGvnTPwqjwQdicp8qDd2 -tz1gzmpfJsvTyqb5rEWcoPqsnP6pHTAtKmR2 -tz1NZjeSFapfPic1FMAqZXwZ5dgf121U6K1r -tz1gshX5Q5gMUwKBXVrkEdSMhX7sVAZSht8F -tz1PAsvtVBBPUAMv5Y26446VfLmqoAGAFiBE -tz1iJXTwB5N7AgXMMrH9kP1F5Wx4MmwMRsFh -tz1YNYwt443DzWJE3tCK4qQN1Lqucq8ktFGk -tz1gUvY51J7yQBx4Wqsb7ircADJfZLkb9fsN -tz1URdVoxHUrNoxQwL7PuxDs6GzgGJ8uZT4p -tz1aWi7AkZbNziixdTUtnxYPdskSR3pp5jpq -tz1QqT27mXNfzk9tPXiqdo9MAFPpJV3pyzQ6 -tz1e8F4HUmuku3SoFmgn3hQa8jsbmTkZdKNS -tz1fMjv6kuFbTMKAp2NCcjpSPyG59r5b3BoK -tz1hQo5PNY4MbTJqBqczKWRTne86J1AUwirK -tz1eidjWnBD2fCme35HADewKRAEvyi47q3L6 -tz1iXfFaX2PvRLcCrCHqS8ShXpQqKBhKP5Ei -tz1Yn7md6TZb7oW6kAPaAueGZZaMdo8FYTxD -tz1SmyLWE2o6hd6gdEjGNHkPCuZrQapmjyGY -tz1L3sP3QQBPdsmxaeV973UwyAvjiHYMuoKp -tz1fBv2zXsYtV2xHeJ2pAmvipsNrtra5tKhw -tz1dYBzSh5qGgVvUeoRPv6oS1q4U35nWNQu3 -tz1LWTHmK6dNKyRTjHV8WqbyQzL2cLHD9BcE -tz1PNC5r5d5xpaCWCmSDmqdSbT3PbPyu2tZi -tz1fDE5BjkmvZYK7hmqNZJWQr9KRuWBSUcDK -tz1QjrKMy5CZTY4fnEL3zNM6MXm3Dd7cX2QU -tz1KeZ1qgZvoB2CedksgbfnXpiZbQMaNpQ5b -tz1Mm3xaEtYeRc8bZHquPM1nm45pGSzk5egh -tz1U7yRSdswpzFCiU9DJF4ZCqgud25cCG3D4 -tz1YuwWUvNTKH5dVBCFZrqSn55aj5M16jAen -tz1YeibHdenebK1gK3Ha2YqsJrsHHkrpc82f -tz1WfqxD5qDxZ7qv2TJQvNKUYeZhtbWUJ9gH -tz1R7vbJ35fMkBbZyacF2F67QcKM1Bhsesos -tz1gYX1s2yTv8hM4JKBWoZoTMbHiaph2sLL2 -tz1edxrnunpFGfGoRhnD9uPE954ThSEmZQxr -tz1im3TZK45PiMMbCLCMoYjZz28YbFjNyD4C -tz1P21VVfPW5AxwGBiZt9kcTMW19BMLZEcnp -tz1hcLPtE6kFRAac3ipheaSi56ktTUT7JDH4 -tz1fTKF6hPQdbyZZY25BkERotjrzSTtbcoLm -tz1hMGxrMJ5SjxDfPoibsVPMbYRJGZHqSQrW -tz1ePst1Awa2D6mi1H2tSPJpqLknUtrgn1f5 -tz1aHk1Hr6oqQo7NbyexRLHeDcGFm7JCmbsB -tz1dR3e348W1AHFxRwLAv5HNyzeresXA9dtW -tz1hinh3mRfYTXbCX1rFhtZpV7dKwV5rdpsa -tz1Z9d2Ca8KWKCUL5DL3cKruAk7YKE45aM59 -tz1cC6HNEc6b8RjSGrWy6or8qhZsz3D1Gtbs -tz1SxRd5SKiza3HvestXoRUU6LtGZKpAMJX6 -tz1Ryr9f8KDWrdbVjRRzesSrQYziphwS7FE1 -tz1QD1mvbXjb3imaQf1JsJDwR9uuu177cePs -tz1TYkYnQM4K5F6Lk2oiaB9NNQyTVFGmzWWM -tz1aVpBT746iu5fGtTfdDKtPPwjaJWZR8qNh -tz1QAzpueY4CvCmwA3ZrxZKy8SxaUdSY4FEF -tz1d2myYGrSQSAh5K3mVd5ReM3SMG2Y9NQEQ -tz1VvZ8obT7Aaa9Z7Kh99NJWZeqeXw4UwfWS -tz1iqddQ5ESb2Cv5H6Zda8dLSxhUyVkQoxtj -tz1hh8oiy1BxDx5qATqpc815ptCvKYGiZm1i -tz1Tem7eTCLKggPYyxcBwV97RKWV3DG13aLg -tz1P5LHw9Yn1okF9wZ2JBeQwY9E9APX87FQM -tz1UN3BpP7rWtXnUMekE17ipoxYV2pmskZre -tz1VMjEdFSp7DyNJrUCwcJV5XNT2QJkX5yyv -tz1WseUCU4av1jT12pvhWCqVdxj8ycYXoN7c -tz1fNsBBS3FSgyF2oiUzNBzBChk6ancg1vCu -tz1aDkMJMeJ8trKdG6W3KJe8cVFVcPVu9fGq -tz1QewmtbxXD4jhCAhHEBYNuQe8aSVxYRW6T -tz1XEGtK9JRhu8uhiw6uizrCxY3Sxtkz96LP -tz1TLBAuVXMtbSgJFS7fuCiqgh9MqR44pWva -tz1f57aELau4ib84gvKXtT91bEEnHQFVhNdr -tz1TwZ1xsLmNDNr9MiDbEqzLj9mSeJPbUyXM -tz1YFBmjA626F14yfia1v8s1XqCuzefe8DyZ -tz1ZWE3cDf4RnAuahDZkCfh5HmkNzyNJG2Tm -tz1hsCgLkH9twQ6vmghneamojod8xwWp3iyE -tz1ZSkRAcNJ8Yt74biboumAno5Yw3YeJDPdt -tz1PfVzq4Hrxqh2uBu6RD371fjwVp5kTjSFT -tz1ZL8jccNxiQ17C34hkXC6jdkTREoTxfp9Y -tz1LpPrWfmNYHmeL1MFkdhTNi5mrqPEmwKVm -tz1aoiDiKeT5Q6eLtfPjpiwMr2pEPNPsJBaA -tz1hdVwFd8qrQMiaBcqH3pBu4quizJ8edTAN -tz1Ljv1kDAtdJ4oBuvp3Emn9qPNqToyWwjQf -tz1YBzLw9ot2qbWv84UfBACoB4YZeDSxUjrJ -tz1icM1yPL1Q5eMknxqFihsmMfS8SNHykXwQ -tz1cKtu55kJKgZwEZodM3ZEYhuUK5zDnBCTK -tz1U3edsSG43oXqvDJkCEFtY6VFnDeKcSwZR -tz1hvRy1E3zCG3tM1A57N1Z7BfhHfzurHGqi -tz1cax31S1Yb82CArmWtRjmo9WxgBGUftWXz -tz1ScTzfQf3rXGi4CjGSso166qWaiGMu4Ktx -tz1fhtFpbiJTr5t3UqVcbJMa5wzELG7D66xz -tz1NvYYzYm9BXLSUKmM1MPENrwoPKU63VjJe -tz1exjPcnjbXeCvR4QN4BA7VK1mq5dpZZKZf -tz1cjiqp2ywS5EGKv7HYauRXjP6PjEVxJxUZ -tz1VFL38EoJdrcsiFL76bTMv9B3WqLL9dWPd -tz1VhZhvuehYgTkmhmZxzK487FrDn6NKmbs2 -tz1iYjkQTEbftd1Cp6Yydvx5gmribKFLVgbz -tz1dgvUmpWmjGKQX8gGzr4za2dU32ujuqHdX -tz1UQgZFckQZGwxAJm4LudnUVpobGGVC9h9A -tz1fhpmzFibVzSmH1anXvzzWU8wpceSq9Mut -tz1abT3iLZULMNFVCgm6XWiCLipghxj33cp1 -tz1Khb8tqE4EXwqMzwouQzuimTkzdasiX8pw -tz1eQSBgc5EPLeLeey2PCUH7k7uCMDXGi8Dy -tz1hBxeRd1UURpQnqDiREgbCTJpf5x6fRvcn -tz1drrjiqAsDFKAtNEYjnLVCPmg4JLhPvvu7 -tz1Wue6jC6GwUNwpXmE8QgjtLfFhr2UDuLAV -tz1eFyvNXfFyCN4NqmJUC4yiXYU5Mv14sgXX -tz1VZdWzkrDfTWwd3wGUCQVyVNM5Ng3P7oDC -tz1PCpnjY795gdeQcwfQjNqtrgY3H6juuGC9 -tz1fQUn8fj289zXJczVnB8gKwRGTxhDrYZwA -tz1dQq7QLRbQnfgGHAZgHAounRGB6EdTT29d -tz1cXB24kVXktQT5dLXcRQtvrWzpw6o3Y6Pj -tz1ish3uXYC7P6xRrPdz5oeFTHRbYfx6exDX -tz1ekFpHrJmFho9xYnvfS3BrKd4L4kJqiUHd -tz1N453N1J2oVx1kBxfzmVhYGCZKuM3Ag6be -tz1bxM2WdBjAEjNyqzrpQaMGMn2rdJyX6e7Q -tz1MnNqUM1HAjqyqpQYZrWVbMwkZ6d7jbaQH -tz1aF889ywQNT4t7y6SKBAgAPibTDD6DiCwc -tz1ToxrFZQGct7wX5K2GCsq4vMKhfw4FsMg4 -tz1Q9tq1riDaZFs3iSUrQiwb3SfwhCzp2pxy -tz1drii45P6Loz8u2dz3aLtYGsQjz6FxWURu -tz1PbZXMsJ1Lxrk9UNjuhstyiQQ67APM4o96 -tz1PHZbGiF1duWkas3qbFCSW7nzaEML4D3so -tz1VCUaDmwknn4dny4DxC1Mbp1hDWRL1UV3A -tz1PmRPnRLvc8fZLakJy2mRhBc8HkoquCJMK -tz1inGdNwhnWPbX1sLECq3xxXtKSYpFyPQc2 -tz1XrnEFyPB91ZaNqXUcZroPYjP9dx5svcQH -tz1RairQWqQmWcSwaep4ytnySHVAqueQ83Q6 -tz1RQWfnGeXBi2W8RHiQQGL2cq8kJVfAJdYD -tz1bMQ8fDH9tHTYaemuXfn88TRNrcnhpN1Bt -tz1Nts4svuzE8q5n6J6a1gAG3YxbRq3BRKTJ -tz1h71bqFm9gAoCr1d8f48WVsFqEfUMjDvEa -tz1UdeUb4yVkHjpY7CVY1eRvDiCvBD3hQurf -tz1akQCDBPh5rxGFbPXJ77Zcya1GffVYpdvN -tz1Qu8Ubb4FvAju5XBx2RqhJ9KXwPWWTFSmf -tz1Z9yqNC2YyZjjzEsnwNbrBweCWZK4GULfr -tz1fJu8x3PL4X7DE4oSFZAXT49H1XV8Tju3b -tz1gKcyk6i4XZqskhzCPzk1rj3A5TD6y6sVQ -tz1NEhUFR5Uy64uX8Ab9q1k2WsRKg9dHTkrf -tz1dB5x7yY95jrKgw2NEiRoeUMDYxMtuQLE2 -tz1Psz5Hj2fLesbi5ZRxbcMYuDA3yMFkNL8D -tz1NcZJ9GmaDFTskc9WtPZgp5SD5LNfPbPiD -tz1a11eKYh9YXq62ssmqEwyAGDkA5utfUTcH -tz1Qacga7T3traqN5aX6yHC21WeuWRGoVRwx -tz1QMTk5gG9ZHgaevmxqb1uxMsBixdeJoyau -tz1aQjzSWDAUFEiyxACqs1424tD7wwr5keCd -tz1UV4Vd93uFd6rryWxms6izNZYpK3Xm1KdY -tz1Wsexjb2fY1ARWpk8sccnC31wg7pJ1jmjK -tz1fsmAnvEQvXMYFe6fde59qYTXjgi2AVaMg -tz1eTVWDMe7BudzqdXm6U5meLqurCKtoidCR -tz1Ks5SJjaqnW14WAG7kGKC163vZei7EQJL8 -tz1iae2X8BhjNovFHxWLfJMz8EvqB6Z3mzZV -tz1MVLVGdiBm6y6Nc6gKRwJqFkfi5uiT21QK -tz1RMdXSmm6waLHrYfzzkeUEBc1VusegAuje -tz1Ks4eiw7SFbkL4n9WdQMxr1RYfC5rEqkAY -tz1SBEPn1aXuSvmjh21sY1xEqo6rRHR6wJdT -tz1cCN1vS8j5T4uWotxinvSpD6APPqdfhTvZ -tz1WXGEMT4bseWnyv5Jo4Rpx5btMd8fdnW7o -tz1cMys8zC2TPuVrGpE6zT3DrCRCZypeDLo2 -tz1PmJm8eUmAdkycYmoYZVHAbPh1FbxyLudP -tz1e1Po8dMSJXPEXvYwsnzveRWKT8WVjKkgt -tz1Y2CkfLGXHk7g7hfgJwtsxP3eK34713THz -tz1L7GdW1e5kNz8T4yHF9Sd1GCs7XjGUBTgd -tz1bdJeT3cS3jvjrnvDqQ2NycsQbRSEaosuh -tz1gTFbakrTsQTiioPbq5J3zW2N2T88Z9g1D -tz1RxbjrBQfb1W5Hz7hjtNGu4kBmfQRaT69A -tz1inh45HpkRjBPHgsKudcLz8kpjkjLPEJBk -tz1Skg1HrBKX3Qcgfn2oozxfhvLQyizwbd3B -tz1ReApFCtAo1TvJeojYg1FrqswimqR52qgR -tz1VmUhcyU5ci7NqUqT8Hg2vqJUFFyZhCuB2 -tz1PeM3szEDa9t4S6VsRdg4rYxUz4Nk1nfBd -tz1beW14Nnz8QVNV9Ea5rtCDiDLY41QdzTrH -tz1RBXzbQwA1K8dKu6FpTUtQ1Y8QtMNSBewF -tz1aaEc5hCDhMrC3qS2JaNcDjS6wUUcpAxte -tz1TesyZzEARLJZJvEri5L6JDGupFrDGpuEn -tz1irkjm27N11sP8qx1FBRcUD8Xkp57YqkjT -tz1ZXRGnvfs1z13vXe5UUGyWK3XjbU2BMk7Q -tz1c6KhNq3oPK2Rb6P6xiS3pkHrMhdjnA9BD -tz1hNEcasv2QRS1Z6fMnqt4ci3qYswSdChjN -tz1LESciXP37JgFTqwNu9s4t8YHn1du5Hqyf -tz1bGkxp33GT9GS2xeBio5vUa8He2RK7C5Sn -tz1dfBFDAx4LWn9sL6Hgv9j6q4DyHgoozsx6 -tz1WgKivcFEftjjmRAXJYSj2btiQ6iy3BvJu -tz1Z9SQpeHrAtq8igQp5CJoc7tPwqXrb9Rw3 -tz1TJ43KB6fVB8VdnYRFUBAscMsGUkgicAX6 -tz1Ptpe1wPGnpK6RZhcEKWLpRpDL7uq2JEbc -tz1QhXtPxJeER6gh3JQkwmnZa9aj1QkfrDi1 -tz1aQ3UCdqV96bPcJXEUHLV4tz9QjaTFZfJi -tz1LsxWkeHh2mnLvNop9DSocbtSzgWYWMwTi -tz1g5xyEjgFVpddfVQvu16mFLPUUydaqUNAA -tz1MKFYSTeXqeUw7nHHmdCRaAfKrDHHVxnBr -tz1bnJXTwrVmBKsx5hvKSL7roasXheGTg21a -tz1RMyTco6YC2GBEsTNJpZML5EZ3mZc45ZLg -tz1TSKnpfKifK26oGP5EvmNyN2MC3LTJNfBR -tz1YfhWbBKZiPomV7kUcXtme1zLfZHHhy3v4 -tz1Mc9GkWHo7kkRgZiSjWNo95gRrtfW1fu5f -tz1PGduXMs4CARTBtwrMyAtG1tySw23uRx8r -tz1ZELRaij31hcpGyDSJg3gvN2sS41g3mfyz -tz1UrKyv9G5rhtFKVoDGWQzKZPfsvkTPB8Cp -tz1YPD1ns3RoUHG3YgM6tfaSkWYLGQETpz8r -tz1gtYB6QdnCwWuTBtnwSC12wRvDxwLhD4CX -tz1gwyaTVX5J4S7nJUCKVo2tZ8s279RjgjXN -tz1cJkEr5A2UnKfRrjDo4ijiugqh1Yn6YEct -tz1RZZoRt14t2P5CLCBjQdJdnHUPfA51PEi4 -tz1cR5Z615rfvSQQaMa95tEyQ88mwJR38AEV -tz1cetoitmaWkfDTUjXVnH5WLN1VeiYP5Fcv -tz1SHKjuXGw4yhRWUtViCCwYo4DRRyGUN9Rp -tz1Powtizqc2sAg19hrb4KSssCFY2KccLxvu -tz1W2v45VHB9xKwDX8Z3UdL3yroB5BSnVBch -tz1Mr9brnv81LRGEo9duSK71V44RVYUQa6TQ -tz1Nc9GagmaakD36L3QfhyZNcUoemU4QraLJ -tz1T2mXEqszBKrp5q3oCggY4ZK3eVAeMqWP3 -tz1Z9rUG3aPMJV8XNGL5EnossQ6Mu83SRvwj -tz1PhT7Yve47Qio3B21zNzydThfH8nmAZiFf -tz1aM349Pc67hzt2YtVwXetD7L8tPf1nK5Ls -tz1iHMwwJYdfd88Z6fzK2FZqHGPJT5rcRY9y -tz1eAcmyoHfNQZKXJBx7fHWS18qJbpbVzMZt -tz1SFBCoiJJbasuBA4qxuBdvyRVRrWxCNtiV -tz1fVYwAuie5KeGeDF8j2M5E512NKbBUjz7W -tz1NewC1cv9DqPZf6Jg35zsYSvwbuThkxhRd -tz1iy1Zek31xG3RNgt71wdcaPQRCwzvEKVHt -tz1f5EZNJDtVowJwBr5QzcJic8PSMKm5297v -tz1Rc4YtzasT3bEPqLDQ1rQyNZDZzWPpV3gD -tz1TN6UVMLHG8PwgoV3oUuhjsThBTW1ceM9x -tz1WbhSJGdhQ37PfJ5VqaHrUjpvae5bnc7hm -tz1LGvFDBhfcdRmgQzWwxyt7b36JGxMHVvF9 -tz1RYbg2HoLpR2Cq8ACSAyF6VPq3SM8UyPsJ -tz1aYuaTEfaJEScBjxgBkpCgpPGtHRdkhAcJ -tz1KfohHYAmQFGNJXzKaYzFrJgJ6Q1V9oKm2 -tz1WdvMuiXvX51iVzyeXqcYsSNoB5e2iRhgb -tz1R9Hu6q9hH3vwh8jYnMEMrbHFqnRCFLS2X -tz1MzaDbU4YMvv8qLy64peqPMdz57gqgsj9t -tz1QttvGkFz89J4fYffjndDsoWHD4mbtFQSM -tz1daJg5oxeS7PiUEmPXNwkhSVP2zhdgx1sn -tz1f3jzWrAd4QeEM7ED35Dv1kWTNVNPLT1PG -tz1PTMSmEwqmYVLBy5cZUJfmJ1ZSC4PjLJ1S -tz1XHDUMgM7B7vm4bNeaMCSWVeTXs3yZNErh -tz1eh87dHmgq5kPZKkj5XU8usynuTQU5AzeE -tz1i5zNisP2a94FVgmgtLn1W5iqfMeikB8Hz -tz1cYBANDUBXvjo9uZCG4WtJ5MF62usTD8ZK -tz1Q4t8GWieBGY4f5tsXMMKWpZUHU8k7tqzH -tz1X1q8dSoJB46UBWDJmaJ6QXAFoKLharRa5 -tz1aNiz5S6RN2B9UxaQofLD3e5GK2nGFHqzd -tz1innRhBzT5aVdcfM7hoaitYpFrPYNUHt4f -tz1TAiWHonjVU8KKvqJwGKEp52FXPFwSyYq5 -tz1RWGEaHjwEfKTeoZNeqCw6BaoZZAKVr37y -tz1eFzzpcpdRF7hXSfuHw9BtEpxfTwLyGHAw -tz1WzqtTwb6BJcmotAGagCdqqNey8YRjcopL -tz1dqdjhDAfxiU7JN9GdLXSc1ikhqpAFFCWy -tz1eNgpQaFq63uT4KZQ3eVLEfjAGL35GMh7C -tz1U5VB4RXV35HbNusQux2pZhXZb4dG8xfw2 -tz1UZxy94hooyXxqaY5ArGmFaFu4Fh6rC3aB -tz1XujvJyuQpMG8N4popubM1qh7we1Vqfd1U -tz1cPU5wyY5Mg5DxVWs7Dz9uXfMA3nqd7rVJ -tz1eBcSoHxJd5ZahgL3D5Vq9a2Vrx35Qt5W1 -tz1YwQtEGZSdTNdMU6wQ7kBgXNWf8XNWsZdR -tz1PF2CW1v7U1shhWBMBuJUcTTXSbWwmr3N9 -tz1Kzw56L4dEiNQvevt63Jyqcamwst4MaKdA -tz1MVTWjP3wsRuoQg2x9aYdEu7iicf3UQMnz -tz1T8LrkSmq1Hrmiet7CeNwvNkcG189qQvew -tz1PisEVZmFqPFYxYyjKTsUn4v6k75rDtoSR -tz1bJ2tez9pZDQUXtTYxHxaRPMeHM72sxoKU -tz1UzPm71KXoNZA9pDd2c8eXxNFHYcXdB6KA -tz1MFDLeNrxhJorVAvfQ1wTRzk8qbQ43HDT9 -tz1ij9kEU9tZvtdxLB8ZhV3RTDhwXWJ4cq2j -tz1LhH6dNb586FMhAGzkR7pvhggkKA5iqoTv -tz1dLo4Rqt9mXMTH7sWqKcEpptzQ8Px9J3qi -tz1ZsQ6KzBZbnTkFUofS3HZpQYisAdSHtzxu -tz1aycAznjDzprdCkMW5ULtpRA2AJmbzwjXH -tz1WFcHj4RqphTJRNzHaBiykPx3PbdEk6Z7S -tz1ZCwCEsyw2Cs4o7Brc9PgDTPKMVJQQRUAq -tz1cp7CzkZo7CWWjCrnR5Z3tFw7gDzFAFuCQ -tz1Lp5ciVQC5Ey8cxGbcLD1CEVSo6uwJnJg7 -tz1S1PGD3t2sm9dTmH81Pc8TuhSj4xMkh8v7 -tz1WubjsybwYdvwTcPMkM8kEXAyop4B6gqW1 -tz1geqrkzYtgjLRoW4JrwUWrWTLvTPGEHzpP -tz1fKLwADYLMw1jhD2w6hh3kqmiwprupFBko -tz1daAQQgo1K5gizLhtUxi1NpQoKepZK2mVK -tz1fyK2KWsRdUcLSo2KvAoAZo4T8viTeojjp -tz1chQfqcCq7HTnnfX35E6rVJGL8nAt66YMZ -tz1bMsUDo8k4zJvDTMgusdLcJK5SyhyqqbEd -tz1aBZHQ9D6pg7M55AXPVLKBEFLRTw1V9tgb -tz1UKfRK5vNwsY37muJKkGEJorhcxF37sg7v -tz1NPx8gTjRLjDCGmgcYhH5yJL5zkppjcHmZ -tz1WZu4eVfYjF7eL8KLuEXVm78CzkAzgXmTm -tz1UFnfxcNk7XfYkgoTBj6kWLtRnXRmaeyFq -tz1YXTbvrdmRvhE7sn3WGZbuHR5dDkJZ7LNk -tz1PbKjTRufjYrX2C8TRdmijMdjUucsrhyi3 -tz1PwdgrJuMRpefLGZQwzof9CUdKJMdfpsAa -tz1ZBfeaDKepnNmS9rBzU9pAwxR3bSAvVEed -tz1Y1HdvxUW1AWF6MBp2MYhqpvVSdQS2FvaW -tz1dj5naU9sKd41DYJwhBj7XPXfbcoAkDg34 -tz1fDCGo6EaGdrhDMttvVhr8SegiyaYk77Wy -tz1MmWatmFsvNfujugy3Vk6HBMYjSd8QgjZy -tz1cTRw5QkyifdS3vbPnvHDskGRVemBJSJ1n -tz1TYxQP3mGhBFZkyt2PLTZxmx7MLRXTKe6n -tz1Kt2JWVszr9P7yuqQzjDgGccVZ7Z88879K -tz1YJfdRmrfek8uwgMTSotXxxehzkaZi6Gb9 -tz1PtHRy6m5Q3K4awvvGuzzGmEvSnkgUhcSz -tz1WHdTh8t6qQKho1JVWo8MNkZ75N3UqbDXC -tz1c5fikYVVBwe6F3G4asRLwgGxkHLdAmRGJ -tz1LTQxuL43TeyQeBnr6jVNXwHYzam1bdKaU -tz1S79gPQqozzjaCh6JrSJLrS1ca8uoiGqod -tz1XVbGFNUYMFh2RPM1gdrVzorAbmsfLG6RL -tz1XDThMc2XS4mU1Rjqw77uuvT5abWqiLynb -tz1NK8Z6Mgc1k3FtNQpcqt71mDUSsqLNHPda -tz1gSD5AEtzBmSh1xwV8YJAfi95FXnXZtS1q -tz1LJNhfK6pBdXYP1PFW1HGnv5Ptyjsn3bAb -tz1hzH7CrA885pkkpUAPGLZG96hF2CbqacDa -tz1UGAVxV2Mciw7xvzoc6kKVKHoAeUEVKd5U -tz1KrjKR65Srac5DEyn8vB1XouHb8jtESEue -tz1YCyWcivWxYoW93qfCqtUtEWfocfTgP8n1 -tz1SuVcqhvKPyQhQPEp89EvPHFFGgY8qcwt9 -tz1XhzHYtEd7kftWQ6PV53DoB96tdxZhp1JS -tz1V9t3avqg1YCDSLBiWwvbRnrsX3MXQHiJs -tz1WmC3boPU2x4hE3RjkMG1ee5mMNYhEDVoZ -tz1g4QwM84PS22V7tACSnFBdkym4yAfcsK6q -tz1WhTCAj7KzVGqLjUkSZD9Zpo9U8HjfY8yQ -tz1T9Qnvzj7BPGErx7CSxx7JWtKwLpfdwL4Y -tz1itXNqKTRhbw9jF1hWKqQBYsPMmAHZVfBz -tz1ZKc5uGJMTxfUuxC6p2TBXyro7624BUQYo -tz1WjA9A4HHbiBxCGXtp9aw3C3zdvUxmY8Qt -tz1UZKRdFB9cdKapMKUYMMcQFHMcQModHrbN -tz1gzwfcEEg1gT8XEUsKuqC6Dz4NuqzpWFaw -tz1UNCMudvqcXmXUViq5G8yWQcCQLJrqegUg -tz1XTrJ4CbkZVkkb4qPypaUeGYdxXiN6yTEP -tz1e89LCfbQ274ai14HNc42NPMq5nkMh4r66 -tz1XmLkyRX327wyLNmrNDxRfc9N7mx2L6BXJ -tz1c8XeVK34gLvojMwQXvyiT2bqVYJa4T38c -tz1f1M8YAk7vfgHmhVJZLWokbvdiYHmwyo82 -tz1NksTBvE6N6A7NDnyfx2AhtcrEJ5wtvWYA -tz1N1ZBHaSQPfj2mTk6ghQEPmueU5uUpbun1 -tz1dSipkD8FKbyncSjdgCHBz8WXc64N1oy23 -tz1gngcGsfx2EdyLt3MH7fNPeHJvrSdjqt4L -tz1TajbWkKvkXA3wRSDWAHutPCB55K3aXZZu -tz1eDh7W7trHnvHBAbmcQBvvyrBvHt8Vh8mw -tz1Vn99LhYTLAwSDiXme51REq6sciQrnaL1E -tz1gxcTXCvFxN1BFK6FGzhuXYwZqF6uRep7c -tz1h1rypbm5YWyiRLaSoFRZGJndD5TM5H4US -tz1U6TfUJv3Egs4zU8TnKKw6M1ww6SouU5PP -tz1Vn6tah2hnT5XMv9Fz3oLLcNyPRqbUys5y -tz1dEuqrE1KEmLCHQueAr7EreE7bNb3D57uS -tz1apZdAwWAq5NpmtvdNQKGSpejzNP6C9sYL -tz1dmSSKkFF1Vo2p7c6PExSJQE4fp4VBDHAP -tz1h2kz8sBjtTLPvRVHebA9FFCqMnY38EfMf -tz1WoEhJFWcKoPPFS8tkD8bTaFC4nRt7sM4h -tz1bzx6y5jLJBHx6BRwbz86uDFmgsuVRV8xf -tz1dpna9fUiy5GoTiTYvB8tYHkruDArRFqpU -tz1ZEgnNtaS9ZTygfSZKtirGvMBYVadBE1Xz -tz1RiBUzcg8uRaFJM42TjgqY1YRPxJHshj5c -tz1fvwoo8f5pwJd1jBLi71BsEdjyXzMJBW9T -tz1VxxkaF7qbG7EHMT9UmxeVMuAwzJv4sFjc -tz1i3ewAi6ZyZkPxAEakFmJuskYm7VsxCgBr -tz1ULdXBajAMMxCaFsgQSmiUKDPQAUJ4SZRs -tz1fUUQDcEgwaXT92XdAY9wA2H3wX1tQzAFP -tz1UjR71rGKWwoMEhyfWDD2z1641cNTuqyZR -tz1aaiivE6gsDfBnN71oxsTATxQ5MXqptjoY -tz1VTNWaZ4srAkgwuS7DsBb9CWea7Qb86PJ6 -tz1Vh72xwTzxLrfRo7MsahFjKrHkAxnyJaJN -tz1cuaHyLrxJfwZyC7PTtyd9i7sx1y7QHEDG -tz1dMWivq3oegh3DkCc2QA5Xcd5cuqLGT7HK -tz1RMmTAeAgprRboWtffTKvoytBX9twrQuUT -tz1UZC3JNWRZwvzDeD2iXVGLTmBxGAiLnErk -tz1cxLZHs74rUuUTQZfbZGwK3qVZpSMxd8xm -tz1WsaZzU6PkDGUyWm1iFqwdJHvKxXbyoFiQ -tz1KqfpjZcwdZJwATGbnPqt61FkGcnFbUuyL -tz1PJUFVxC91VKcRb23QTPZgLXrUivkAr9hB -tz1VZbTTtX3bDVhFYw1SgMjnoTZ3vTN7KnBc -tz1TKUQFGikoyJiqJybbdwDwawqx7iQ5kfu5 -tz1hW2X8xjdPANbEif1jZpNGb771wyMUeBVL -tz1eSxdVDRmR9zRjPSJGgKqgzjtBeoKStycg -tz1RAhpB25SkjHi1P7PvBPtHBewRBHzYPfSo -tz1VTZNXySyib6K3VmSzdHpmJFbcwTXPdewk -tz1MhSGe4uxyrg6s2zT22M8UE1grjndeSVfg -tz1a5sbD687MhPWaCwo8YWfxTYw4FVaMSreD -tz1L6FKzve2qs4WxYoBKnRiddGQNJWY4tdJk -tz1YhXqQhXuXZNyg98g56d3rhcBYyov7sSaT -tz1adC59sorf1vyxdiWNij4xDBBrpPMsLv5G -tz1heqxjnGNfSFaLMZEzEwaEQwQKL1EMLYvA -tz1V1j5e2XY7sD5iJVi6kb1sfKhaB4tyUctA -tz1WN1rrBKZrmv4iUBz3szKmtZxn1NkKu1fi -tz1hsdRYaBmABajZxSpcMQmPjuoH78J32xmM -tz1aY3dasjorKcKg41EXjPv9kRecbxBjWUZk -tz1VHDKreLxUgHFukXNhmUdCH9tWXGn22RHG -tz1aTtwYrQ7m1D6mHmiUrH1Tb2JnfygNwn7C -tz1c3BPyNdMqt3wXnyYydzkcwV4LpcScKoD5 -tz1Ue3KXBfX93KP7YhGCPGttu8iGAxA5ccQY -tz1ZJDXmvk65amG3BwFMfogTwZsWCxEejKbv -tz1dahmFghM3iiHk5bnQ27oYc59yUPchHztk -tz1eyqSmQvV59DXT8GPMa3SLSZVK1meL4J9j -tz1a5YrLjTvovd8Fmx3xw3u4beuMmPwWWxdy -tz1L5vnF2E5oqxWfc1C5pihFEM9rAw3qz84L -tz1hLScsaJp5YnLNVtceKuwdZNUGrEAiYzU5 -tz1iJK3w8vjmFkxt29XUa7eCZ7P5JQXtAqJM -tz1V3LsLU1wPzTPP67HvmG4Dt4hzsBZf6noP -tz1PooDSoyfKBSx8S3fC7EJbEZkMGMjFVYf5 -tz1djPXw9g3McA6ewHgosiQtSjhn1xGsF6A7 -tz1Rb7at7ntfE6jSdskZG7UGmdgS7uKSj7ye -tz1Zp4Eag1Y8Lz9aToLKfEX28trauWBkgedq -tz1QjVrKxj3fecrZgaNGzYSCseyLB1ddY3rf -tz1QpQ8aLETK6wH2cpci9WFhjxXnLvpSu12d -tz1bEGGK7tju8wEoCHiGyRAeq9J9n3Ce6sVd -tz1LhxikBqHdTp2BKSJRPibwKRpP8RHU33pd -tz1RhcLdNQfE9NW8g5SdoxjoYs9zEvHr4dFe -tz1RSdsG7DzaSyip5p9Yfz3S6yhgMVQ44NQg -tz1SW2XBqWErDj13ouScSDmadKd37UEV8K1j -tz1adyzbmGiXVMcCGEYAtekAcgQZ7fdLcAoT -tz1ZbVJtaL7FJZHzWV5XABty9QQXCpxa3kc9 -tz1LH3kpbPsj8fjbxPmVwqrHHq1oobQytPrA -tz1chjHeAPe5894gMw8WMe8Mhnngeqb1s8CC -tz1iMooVfaX2vbEvFwfrEnmJTb6epMibVoSQ -tz1aS3uHrqEJ41PbF5jc52qrhD7vNZWVVMTQ -tz1P7e9VHvVDwktKVtZh2Gjm2KJR8p1dpikX -tz1eHErjcamyJScL82MNemUVvsExTgiZVhWK -tz1hGqqRGFXcBKx6mHb5pCDJCH89VYdaABQ6 -tz1fs49mkQHH7QViX8nzzLBx28rYdWz2p1k7 -tz1aqEwTXatMxoJrELzrgUmz9pwpQZpJS1b9 -tz1UjmLd7fuuHu8HspkNHTcdxfAm3e7RcqNo -tz1dvnJtoezQaGeZTfE31rkg7hiBhbdUweK7 -tz1Q1DdZebWGGgcxXfRbr53mWrxqh3BdCBqy -tz1bs4Aj8cuMGYBzgtaLfpq1pSMTAy53mp7d -tz1TuagYfP7cdBpCd9q1QgzNo1Tkq85Gog5q -tz1fRa29C3ksty81RPMYy2vH2fzQEmnjcn6G -tz1aPbAbcZo25SkDg2cfebKNoYym7EtkdgPC -tz1ZKNNprtGTndK9Ro4SovfMqmZYoNMUHoMN -tz1bPChTkAYKvezaMVh1if8PXpszF4mmgrot -tz1fLjRYETz9WmHgTuuwR3HCV2DkUPb7mXpM -tz1RQN4zvTfCuN3WC9hEbuR1MeA3KGVX4zV6 -tz1i8ELktuRwY2uocsugpeFTgPer7h9SBGmi -tz1R9B1pLKLBEbZj1KXouSTnTbMnwMQKUsev -tz1TjcivQzZKr3grg1W5s1oVRXQTULY6hWoA -tz1iaa2NCPLCqgS6CfkWctErFKhsFQskm8Q3 -tz1Z9UdyFudCwnfqexvmNnooVZwBcAzfMv2u -tz1fk6ZoBoGo9J9TzfzkbjGBsYZfVaZdUdFA -tz1bwA9dDMjw93ivS9K6iqHuzQTAVTesA2qY -tz1WeBDikiRLNkTT4Q7tnV7PpMdwATXRSM8f -tz1P2h93uqKKG3PgFNqqto2k4qDa6UMfDdmn -tz1L9NHttBqkrkWF6WPc12xZ8pSmnhasngyg -tz1dZjFpLLMWfCNToAvC2Cnh8kzxv8EQpF6V -tz1SuK9Vj8NwynsfPkVwpGhpo8C2MkZYGoyJ -tz1R5RwtHftZvVWpB2BwCdkrTVBQqsdBMxx7 -tz1T2aEZsyGqVu1sYWN9zU2YUWC6FE3X4zSo -tz1bEf7SBwJEDyzorA1VGSgdyzBwqbrWfxBf -tz1SpsPPi2JcH5diXQ3r2KDzwj33U3WdYuyT -tz1SLgYMM3eyqPPscJhpaAqNVWBZc2hCYDeq -tz1ifurBfGeXaY3LYtzmGDHKScoDrYakqZLr -tz1bSiDhBjcS8TC2MzeBfp1AYcVcg22H28bS -tz1WPfwedozWfqqq53ChqUFobd45PGytXtms -tz1iTtMni6HTL1EUzUzDjbpDWKpyskdKXAUN -tz1gYR7VqzDBpDNaEXkMYNQTYBPAT41zBPYa -tz1PCPZ4hmvAtiPxhqski1XQsQGb7nm8e8uu -tz1NvNoyp1zpoqj455pk4aS5iGL3wnTdikye -tz1RuB8bntEknA2dZVa8kRvS6PwjAzvR7scz -tz1dTYzYmXSUZhi81aGnaV7r8Z63FFv7UHjh -tz1iFSTXR8YAxNYxjXgwdg8P3nFUFb2wpX6y -tz1URzkJ7EgdUcv1ThoNAPVGy2Bc8VCYhT1x -tz1TftJr7eftNBb7uvYG2zWcqTGs1JespAhP -tz1ZdwSPf2e4U5fWTpf72k1UvNCe1pMSaUBW -tz1PMNFozXcj3dzgq5jSvoTCCamMAmgeKbC6 -tz1i4gHJr6tUg8ba1mtGAepnR3GcqHHzuzj6 -tz1ZzTFbBx9xhUzroHT6MDE3mB7qrSyiac83 -tz1PsNezo6ETqpDnQxziMuP43ppVucBFsH8N -tz1YYW2MypRPFGR78iVq7msk7w3zHsVvcg8P -tz1aBgNowVHHJrACAWWp8JKgHLgqZuUpTEB6 -tz1cr1ezWWyUkqhAbVQf32h5mQAN14uU49ow -tz1XmoM8DdFoCDfbfdhAfadCrohzXks5pu3o -tz1QCqZDewrqteex5URZt9S4oFMDFMUN9vim -tz1bTLsXgDKJdTuRvCuyPdPDfRKX2QLkPJYL -tz1Zh4pkmvm2EJLYi8QaoKoeV4a4Gqm52vY3 -tz1hYkC5TtumLnNZVdVNehJwqG3NoQRxZ46Z -tz1KsJR3Zh1XatM26NNAazBgQQu4Qh16tNsE -tz1e99bYVs1SUkShKMFhtK3KpdDfzNsunapX -tz1XHZ7iLzPyG7KYAGkEc4E8SHH8zoUAtjpE -tz1XauTkLK9713wqU9M35pQ3RjESzGQZFQrU -tz1fugQvfrCQnzegvByshPmYHafBz7ZZ1UNf -tz1KyLNRm6eMqcWgHSvYXgvus7JWcJwzmAzU -tz1VxU3CfaPSdVb9bz9igbMXcqPLxwtwB2oC -tz1ThGE7bRubYqwXFck9PND7z6wF7kurnqKa -tz1L3pJus3ufPcaDoANZQkuUW68uu76W2XQ5 -tz1SsgL5kH8dRtyxuH5co5G2FvFFhGWA4ZWT -tz1UJJHskPp5iAodkPmS8AkjJEv8rLQDX2LZ -tz1d5kUSiEjwFRkXZeCKADMV7TVePLim9FTN -tz1Vwdt37BGCPyvFwF8LWdLrrVY4gdXozGqA -tz1amXatsnm9kz7A8Ts5aqwUHGhgDvkuXaLn -tz1fP51GTT61pPxbnEvmTFR2veoRqLEiRVjW -tz1LEeVvkkySFGu8qrtjuN1Y52wpCmW2AAbp -tz1PSfV1KjxEWsfADEYjZ1WS6fr5HYmwzM81 -tz1Qz8WNan9qH6hmTrgmgdKzv1bVjqghaegp -tz1iAzG1eZQMwBVr8eGPrZx1gUEG9Tf1ryae -tz1eVvUJju59L9VrifFYScviN4T4TvG885kW -tz1VwhqykjGh24LVr4w3czMTHEzq8kni8Stu -tz1W8quin2yez8vMPEhbvYe2bPH2fHm2u4wr -tz1SR5ntEcasyoUzpMtXp29JL72uThS8YZGd -tz1dToDcNxRuMZAayrrFz2C8JBNh8Kg9JouM -tz1UkrQSdV59AucbE1L2hWCCEFyWphLpfakK -tz1M7CDNMKFVj4ksfhbSSQsRwqLnPz7nwbm1 -tz1TYuYpZm6LNzB59sjjwdVD946QNTjjzSEc -tz1RDQZuBcqF71aKhbfaCwTAKvjm6JhSK2os -tz1eMKa88mdCzD3AokC6oRZjug85cMtcCEvw -tz1chXzB3TFZRjf4Q83QR2UUpMRL7qfK1HZg -tz1Uyvz75eqdGi7KKfsamfhu7u2EitjzbtQv -tz1cbPozjeAWHZR21LhWBE2rp96QKWdJNZ5m -tz1VBSoitcPaSVsiTFrBF6FTt1gG9Zzmeyee -tz1gQ1sqahUSWvq7ChBf4et6ZoUvJKH7EBbG -tz1PAy6qWCdTTGxyRvMZ6nDrWoJeo1eUmxcw -tz1aR4tH1GvAchxhxgyoUmYr6pH4F1KGdM9c -tz1WGqbDQ7JSo8tMhyeiCBPbmHVE7wVY8dHP -tz1d2TeUZ9UKZXuzpC28ikxrvzbSKQeSouZA -tz1XzPP1AbSxH4kPq18z6fN6Cw5z5tBDiU7g -tz1frEHfs4FX4pyn8RSQAeJGARTbxMrDJe6n -tz1TjH4n1oA9sTUHSdEWBzRg2ScWv7x44vFe -tz1ZnUYs8QMKMRuLz2agH4tXTULa1zTPQMB7 -tz1Z4UHNcgMhYufLUQVBsCsh6zX6bAJPA1Er -tz1ZEUvUK8fH536vJ13JpDS956CPoppyjbwS -tz1QsChNedxK7aXA2cNCGHbQW7ecJiRo9wJj -tz1RArmQzkF62kjDY1FoNBLJidXpBeRebhb9 -tz1Yew5wDeEYxjfDuU46BoyMR5SWzyUSF3gx -tz1gs9DaL4ydnoXY83RbHz9nqHxe6yoYrzux -tz1ge8ADpeCLgYB19hTJQVUWjxHraXfeLQko -tz1MYHoKuBam8iTkW9F2mLxnfYeyY31CCepD -tz1S69BUkgTd5cfLUmYMmAT3km3wZk9NPGYP -tz1MKbz6BLPeTFSPjNYfLQoHLSnsWnkkdo3e -tz1RksPpRvgkKLenA6USWMvu37CtiT7vWcfL -tz1UodVAZELd2CTt9pv5zPawDPr2hvZTVCQL -tz1fWS3sGSqFmuaWeMH36RWZ4pQ2ybwawLVN -tz1X1adUd1SkXEJYedfX5WhMUYtDrkDjZ3wB -tz1VYa9bZkkjMEp9Nc7hcCieY2UEm8YdPkmQ -tz1UNYpudiLahYg5snoPyE7ZvNMTEMHjk73B -tz1fQRt9R3SK7L7zmjsup1QDaKFQw1YSAsHX -tz1ZraaZi5Uncac8TaKALXtTq1ZhjsCCcTsN -tz1hD41j83sKyvb28gWqjJSeipL6wPuPVCWu -tz1Xvq3BAMabM4siZpS33wt25uhGAtsGHpid -tz1bAGT8D6N1VHdt7Rw7kvT9mGqztZwXGnBD -tz1gnUaNgiiAgEQdcdkafdaNQjUZzkK33vyx -tz1YgL8mVVMmDn7xJkUmDmnyF4a81mwpARny -tz1UdGombSxFYMKe86qjviT9QH9xBSgTrc7Z -tz1akYNZtFRAMynNfnfGnZES2yRN42jQeNyh -tz1KkYbSY4hKxRt1MAuw6xr7mkDigsoxgX66 -tz1WypfzUf4hukDr99LP2VKpSJSh71w3TLUg -tz1VGuhZEhioRToZNtwTwbmrjNh2jccoKnQi -tz1drZYFxVWM5cHhia73ofsi9CX2KDPFxhhp -tz1SZb42XWDjSHYssqWpuZuaG52kiwtTUfgX -tz1ePRx3an55me4LqZmjYsNryWXKuVZbdKSa -tz1NYaVSfZiCP48QqGPVtLMyvsKqo3Gewk81 -tz1NuzpmbZbmLRHwk58gWht3me9HJHpwX2xp -tz1XGSRbwgUMqu1G7PUUvJC3eKuFyytVqXn2 -tz1WPMrRHY8r2u72oSaa2jzoMFQkcdBVZSga -tz1dWS8ZXJLoy3YXfzDsa5fQGWNkihaPGdpH -tz1VDHxJybngE8rQw86bYdVFXSXv2R52CRw6 -tz1Req5oi5kbF3avq28tvyiEvxkvjgoQis3n -tz1MRhhycZAF3MyfRGXLQBkNG6Kw4Ly14khc -tz1eU1UX8nhsx2kiNr4wE9QruSXD367wD16h -tz1TKdUhaaZBFWjfUyguA5KbZcTiDUi7Yqac -tz1Uh84jduqToSzkbhxJoDVzPS8vog4QPbHM -tz1icC2xVj3WngJAha3ggQtiX4fmJiHnd7p1 -tz1Nhd4koSxAA94Cjg6bnS3gASS4SjZFXmVh -tz1axruFerj2taSxggzL6e89Q91DiVY4jKHd -tz1LvFzfrmr1mh8ZDpDscEwhS9rUeuxLijBY -tz1dCfgcejmgRU8MWXXs28SWtfp6k7JDnAQY -tz1b7vjDKZ9RDwiu8gkNM4wGRfDifA5j3bRq -tz1dUzviZj7Nyhtz8qaSmNwAj7KQQn1RvMeK -tz1dt21UVBp1y1pbqVBU1gLd2BjSN4VFd583 -tz1VC5KftxMS61dEXgNmFyMCF1ajqAF2BCCV -tz1eZMsoK2ocUmvHbsMgYN5Pnygk8cZdUkUi -tz1NUwxKAcWDpWyuRZkJctef61yrkFTyEbLB -tz1dZpQ5D3mnJscbdxdbrAZuLGfAMgvQ9c2z -tz1KjazowGqUehK5bczKeoJ54w2BqstGiYi4 -tz1fYxMv9AZ9h6PEddpirZHNCPJUTEH22CS9 -tz1RFvw8aT3iTgdLYb2MtKqtAoaHHZkXjG1E -tz1YumnZCbP1HX3iqTnfHrfGv7s3x3sJdgz2 -tz1UzS4bQQkAeW9e7f4dkUZFYCf2WBwhz231 -tz1XNkY6VD1LivHW3XBZHizzzgLvkWXAdFsV -tz1dDBpAEsxAV2QkPbcgT9SaRgT5jQ5grkdV -tz1efj443NRaCRMR7rRzE6pizhZVZLaJofDe -tz1NHvL328b3WYZ1UX43K2kK3YyeGi4UV9wh -tz1TiKG4qC6sh81kALHoScdnCSw541ra9Bz9 -tz1LdEXibgXKoRXA1WfnTBvuZYdBVjAbzXU4 -tz1dvMqjaPmkoqPdgBxTofhuR8cHkY62D8pS -tz1g9nGFmvgBAM9xHuvxZPQTPPNFAMZ3fJWz -tz1LT6uy73MPWjPWM1neMY6YxQfs53g7hpAB -tz1Z68zWsBL5ozP4mPowD6HePTpyedDDbhfL -tz1ahNFJEVjQ1XYeVQjUBqdHMMqyzuxyS9gh -tz1a9QeBytxnRgXJQPrTtvDXHZfA6pNNKp7R -tz1foBk8vKB5H6yd8TV8BXacihzLfqNuEFuE -tz1dHioVNVqDdqYsMuW17J5TaPgppRQYM9mw -tz1Yyz42P8rgn2N7726TsJNjCpHtoHyEEttX -tz1bYRW42EXq65b6jwyesXaAstnazouBcC5L -tz1apC7YP9sgzWRASVZTg31PAFfwbGSrQf7p -tz1NngKeVfCjJznXbDxyDZW8tfdFeUqsNncH -tz1UihTY8ezaxjPT9dY3rfNXXwu5qjft358q -tz1LG6sAZ71wVdPeNoTrVwH871WisHMKnanh -tz1eGhT75TRAEaRR2HCneyJDmVsp3Sz6S68P -tz1VDwLzoiHkuk3CqHsiehXwP4rw7zQsULz1 -tz1d3tLqG6nEeAZciwN7mycy4ENujNxnECLP -tz1cwRGw8iogHkXxzud1mtH1LRreorRzuicz -tz1Z8qWDxmuP5eK7nQGdPvakk2hLcjehcF4r -tz1X1ozJY3qFbEmaMb8fgYdNafszdK3H3dK6 -tz1S8tkXXgbQ3v7GRkK1M1g5h6RrPXqqsRu9 -tz1Uuh9jqqWj3SStiZyGiXQDE6JombV2zC4S -tz1ZumT9Mu4ZNsZNWUXu1teJgdaZb3c5cud6 -tz1hZKDMrNJzRErj49oxWuFVXRYkf6CeaXju -tz1Y9LacBnLerevBcSFW1wTcuDXGscdvd6a4 -tz1Z8FH7YMvPEgZ749HfdwfvoqgZcqoqMZYz -tz1X8L4CBRrqR24cQzLUdk3bCLgfZHVbd9Zo -tz1bx2bDVsLVp2Fu7SwzV2ig7fKnR7i88Dx3 -tz1faneXR5rYKCM5NjJs2vEaxJcadjmPoDqr -tz1NAEduEKn6tGcvHHRCdSWgrX5ecKvG2KWW -tz1cbThWeiMREHxwhwSmS4x82ytVQYAnSjqS -tz1esBLpDvS35fg9zbzRtj11hzTSyjEyck8Y -tz1S55HFzY9gC7CR7hp5knEyZPwiAtsy9ZSB -tz1Xy3h3VbR6dVKxk6FBvV8bUmWj7icmV5DJ -tz1YZ4TgBr24zHMTnj5Cc7osqTyTM8cmZiwf -tz1ekBnCN7EUesmfxsBapbgJURMR1eBCqKbX -tz1gZ4b6jNioihyYzStth13Ug3ef8dGymRKk -tz1X6vGR3NCZL3Pmrr4gJpZi4dnkLEcaG1QQ -tz1LCW3mTxF8RmNAmo254RsFQAZF3X5872Yp -tz1QaaJYdqC3PYqyWTJjN8Dqm6mSZZSSCRVq -tz1L9NP6nWW8G8qs7ZkHc2p6BTkDb3j9YJgD -tz1afDDA66AcRra8o1PxK84TSW3AWTrcoSss -tz1iZ7Wz6ERfEhzmR4yZbocJ9DPvvmJjAEW4 -tz1ZAvz7xD4vUzjnnETZg5k1YHiibMPRYhKe -tz1NTnYZspC18gBC6xExuMcE85B5d5yEyZef -tz1PqswSZ5wbaYDqHpTK2ubcBDPJ9fVPnURw -tz1S6pjCXrvR7VNWw7Noo4JnfR9HGgyhZnmX -tz1WarvuUGxp14kPdGkuwstaZyQwDdE8pDit -tz1fBYaSFqBMRxCvJC7kebc1TBXx2sLFGcNm -tz1Ue5vYtzvyaRqX8iMf5jkdPjJ7Ks7555CB -tz1QVb4BEoMU4Rq16VhgJU1tb8njPY7GQHYh -tz1ZrY7jUmoueXwWXwr6je4ouEm4yVQbbXjf -tz1fRhpHNkvfjvYoEUzixY6jVPamipvWPBFq -tz1i1xcsh4Xdd5vZKHwabszu9dwzeGYvH6d4 -tz1XgEBqSHECvqdZ9K3T7k1r5rcHQ3wxnDHo -tz1X555FpuKux29Hy4FfrRF7jekbXTYDsNQK -tz1YsKM6Q1vo2vfJqsU7PaJAR5snJFsuXJL3 -tz1hVtUY9ESPpCQNkhPdHykj6Q8FWtNz5Ryh -tz1WgNCGR3sanQVKQcQ48tQ1dT8Zq1HXMKY3 -tz1MKvcg9FQmenekSxHpaoMsYdTU1rCS2uVX -tz1WD7J4cFqjEu8wFHc42c2H6jQnYT61ne4V -tz1bFg2YZfbmLN7E7xNbjfxXapvZivd4Wose -tz1bJarHcRkxHjjFph4tXPGWD7fWHm1HnN35 -tz1RtNBphZcjAsiQRwjdviuFjoCGa1mGKC1u -tz1cxxk1vA8N9pSBYC6KvQYJzLhnrDfb6Spi -tz1PMNFEdMa9QuL9PnHUv6x44MT2PSKxHmn5 -tz1e6ZM5w27rgTc1An6AvMVG5J7ovaguVzQh -tz1WUrtuXmhNGCY3NuipYuQkoP6EdRwLpRzh -tz1SQxCdGe8HnKTmvxVpPLybnnYfwD5nh2c7 -tz1aGnQkoUCDG4SvP3F3FbmN555BJFF8H5Zm -tz1YyQTDDZwZwR1BViFb5KTEG91PpEpU1hQR -tz1b3X5oxECQV9omZWLA2ucb9yGz12NUTKxw -tz1YUbWVerz3jN98PdCw1XQttZ4RKkMwKoCw -tz1PnKyMhK9SQmJvPpsUsx5TFWQAtALkwTEx -tz1NdS3X9adSTkn2HMEuGa4b1oHHrnHTMBCn -tz1PqQCa3n7pK6DzLS5KgLQJqfwRQrkt1vXY -tz1RYrturBEaQLTBGH43oDJB4ovEtpKEki5h -tz1icSeiuEfBN2nuhvDAnUxqcvPuEgU6L11H -tz1YUTdc51cTYpPHzt6cRNe1DEwh6TEUGXxA -tz1MGuKUyDvyZ9h1KL3euzvhpkaKKD2Kg6fL -tz1cj6QHudK9pstT9fxoxh16Uw9pG5kr4BTD -tz1YGeLqCpPJXFEbLdLLbEKiQncbaVHaYu5J -tz1X5X4ts1c6c3ZbAbY73n4wDsjVRA6cioxW -tz1g2978VHvTpoKJLeh1Yup5aJgrvQktbqvd -tz1RmK4sABnhhjiogAESZkjnFG27jgaJmdEM -tz1Wprtw1cEwHVmLjP3cSi8bGwsJjpuFoGrw -tz1NdRtMxKZf9p1zxdQJxuW4tA7Nt6cveNS3 -tz1M7YoZzjf8HjKZK5xU8EsJsLULtWQcBW6r -tz1c7VawDdqrVsddt4cxmHT9YmtJupxdWD58 -tz1g7Y8WSn5S5ZXC2HN1ciVrdbqeHFYXEmqK -tz1dZBLRgG59hZHJSxPWfyUurTKyGgVhNzBM -tz1SxcHU6Cei2kZUXAfRxJ1kXfGdDsh5Mo1L -tz1atQybhSKsNW4gqsRSqZxENfdnyocvuQzd -tz1enPbcyZsjyKwyT1TEjPtHh4SfQ7Urv9gB -tz1SAUMHQKJi7Fjm1FF5WrDahtgSETxifVKv -tz1L9cVaKMriidQgCHzwbXzCNQ9tbcph25NC -tz1MRF69nUA19UZM1kTB8aV8LGHeKdPorRwA -tz1Yy6i1C6RTNHNJAEARXqsMV9r2hnaZ5DVo -tz1Rf8WSPboQJnZZ3kaLU3TL3pTsyz7tV2nw -tz1Wp3e1h55bZ3VMF7TvdsuK797EseQPVXnk -tz1eNFy1ZFCMwghtNrcWcirAFbvvKZbrdwqg -tz1LMgUf95HrpM3p4vUwRFRT1mhrJcSXncHn -tz1gx4rffboRhmSRTbY1FU8pdwedNxG7jh5s -tz1aqMVdsRSDHqNDB5kL6mvERWk8wRVYadnX -tz1T6AxmB8QyhsVYjvAsyiUcqKLxuHjduxQy -tz1TNNoRNzc68bcjrsbFuEdFiYZvebXZPrdD -tz1ZZfewiGF63duEyKF78SSPozT7QW9dkBn6 -tz1cmoS6RR2FkLrR1m2Xd9884dZxq2q9AWsr -tz1PHGFDStcM9NL7gKxsU7Pvom2goMDSWUwY -tz1bkWCV3drVg9MuTGsjRxPJtTBLHmQdiLwP -tz1UA4RQsvzu65tU9YELBRQffrJgpGn7Ld4e -tz1ibJBGF5HZYzqofZ16ikjkBth92k7VG3qu -tz1NpqwLYrHYXm6gRW6d73EcAUMX4rHRCiBy -tz1Q5HCiAcF7d2hyKoH9mus2pHQ2ZkKqpZ1d -tz1ZDwLJKQNTdK76Y3o9vAoEzHdUd9wK76ji -tz1TTrBCVkZghzBNpWNtxL2VsutbYoYkhG8Z -tz1e56HYmcedhDcmRcQaEULK9L9aWzhapp8E -tz1SW7fZUAmz5iPxRxjcubi7fKoguDHknDjU -tz1WRdT9fHNktD8jYdqJfrXsfiqVzd2bKJYw -tz1S5i83z1BYgUp1N5wXsNpQKBUypeP8K96V -tz1MtXAMEYwE3V23kiaaVcru25HbaBHC9Gen -tz1ZntsmWHfVh2cSfUsrrUccyxSCCAMYJfyz -tz1dDtscpcG8BGdmmzTGh8sHRdFBgDwGgA1g -tz1VVd7J8bb7pjqWtVkTJcWfHeYf2eN7xKjr -tz1WkJZ6NZpLMwXVJmRb3HpcRhM2LfekU4bJ -tz1ZgZ1JZXS6UfQCp48p996w8Z9eNX5yMBNL -tz1cobBmapKNEkUUFTC5ox4MZknjSobdNA2U -tz1QkDHCQLaGHfv5aRe1XXMfhidbqhHNFnyt -tz1N3h2FGXR1v9m18AJDbv3syo1ggg3eoHJj -tz1MVVMiU2RA7gJQLhakrK9yEcxgmkPsNG9i -tz1SbgkUtEz5YLk6gntEx3sMnRTQRmAsF5hX -tz1L2DvsSrZjvHA7WHrrXz9cGJ4ESjKcAUDd -tz1M8geiuoW3AdQ2ZcK3E7bxxwGRqtWjKV12 -tz1f6DMNW42QKBUhDnSw27aYC9qzhpuKHBmV -tz1i47wB54yv8pAFuvdFazWjdDKD2KGdQJbU -tz1Mwvuu2PVsBhGoA8rMHZEKLbJbseXHv1gj -tz1RLZi69nG9Jud4vCmdVFqz4P3hbyYiMM6u -tz1gF8VoqCjuo6jw2Py6b6cdR9SQ5riCbmsg -tz1bXANSpdocHpz37iT5epZpzE4N2nR5gTPo -tz1TSwVBfkwgyASjbiMYutWymUSD7avbRMHt -tz1TLo5x3Y4XoejTLiaAUr2BtsEzvdxnB5q7 -tz1b3t6zxwf14okp963tqpaWNH9aPqq7VkJX -tz1KhcZWt8ZR1s2JENWUbfefeTALskWHHXEG -tz1bMTKv7uRnKtWkm4tSeCaFpFczvFvKk8u1 -tz1M5BmzYAnVykmEYedk2csRV91SVyzPuWPZ -tz2AXHGjUY2PsQrc7iQXFiNP6d5v48Hj6GUQ -tz1S2HacZptyQ32E53LyDSRwSLuJgL3TZekM -tz1LDDqNV7Cz5TqDZ6Sa8u4TSWic12YphFnT -tz1RGPFxyzM3kFZWBWzfRze34y1hQtr7SrEx -tz1UWDSS6DGZFw3h9Ls3oQfU7rzkXXp8ZhAj -tz1YPex1fGZNqpEr4izZQUCpXvCjDqADwgVs -tz1XsFjALWXZzCzUAwNtoFZsVdZSvP7hh1J9 -tz1ZMJJhNaw3zTmwU9PSi1WUtSufjairzSi8 -tz1Ki6aBfefKJfDBiov1aHhZgP5EvvcuW3Wm -tz1ZTPDRMaT84SGmhpDrQ3Lsu4iXpqorVj9C -tz1YjUZ63YgAiwJwvHUhr5LiY5SoZDQRk7at -tz1Vk2qaDeChjQMkd9Xgw7EZ8cJ8TomtojEW -tz1LZS6NxYTjDvQ2b6B2mVXfpLUcJF5Ja6ud -tz1i5Ympic1pviAzMDVPXoqvJMrhmgJhgVCU -tz1fnLmzbQ4iNjfCjcqQfP52PvDj7y2ryGwr -tz1V81xPduu9ergNwQsvaesdVsb8MNck8yux -tz1TDZkQdfG1g3tV2Tubwnkc6VuuQ1CyE61z -tz1Lqq66Qc7685cPkv6SHT7LwELB5H2VXDLn -tz1SPJ9UZAE3g1gGdp6L8ujrdV2rmcZvWkDs -tz1iBU1L3N8PtS2TkDgL8vTvUidSqhjxXFHg -tz1Lqentqra54fEeTiaBzCbqmp7wfVT9RK2K -tz1ZqqD9jqvcAMemLaHd5WSkZauzMzexoBhn -tz1Sro5tL4Q3BAcPgwEiAU26BMjZXRV75zCe -tz1Yoz3mD3AQbYnusJEMPu9KiQfpWzyrnMzB -tz1TrE9Ag3hpeg8dcxpoQzEYZCMZgsFPoBLk -tz1PNkx9Fv2iiaFMrXyDiqoV1ZVazK2QcK59 -tz1M9hkeMa22JB3obdFsDFZohw69vkUc5Qxi -tz1KjFQh6X52qaRKQJwmesMBKauXxSch2U3J -tz1Neo9s59ERhFQi3PtEnwsJDGVdLqdQ1ADG -tz1cZ5Svvp8dmBEma2pS1t1X4fANahZFpZk3 -tz1Y9xHfb6q9bF1YFthEtZg9rUdPH7r4W6UF -tz1gjV3izW7zw12BntTMosVmbkGMNxzx87vt -tz1MnFmDN8ydXVyefs7vP3GwUWq37fjXzadx -tz1R9NLP67KnC1X9Rfwx9UNUEvjsU2kKLsv2 -tz1hDgXgJDLfXCFCA25uyLErPg4uGSwFYiJ6 -tz1TsS6KNa66yqZW7wfMe6DyBkevLToe34Qk -tz1U1HmhSzFXnBQ1LtMrK3ThtaTTuPj2aLsQ -tz1LLbE6yY18EmHrt9FknqL5UnWcsQGrpf69 -tz1evMt13Hs8NjnrYejAp5aayXE6CUVdXNvG -tz1NEKrobiRadhFJuNLgy2yVy3TeqWPC3xmM -tz1az72RTpYPG97s6Ma8nVK2NhQjamriJPXA -tz1SNVyBXtPhzVUxZCTGj2zL6YTLYfNXigzK -tz1aGhjojkLL4B7GXd5gB49aYWv7rSMUfyn7 -tz1eHefgfLzTQxwKsoX4JSuoJpkewDLSSePp -tz1WdFfko2hhFdKY39j9944PQuvPgimzVB9H -tz1bUA4HY2aZfYgnmmChdZmzHVXLAZPQC8Dk -tz1RDfvxxxPS5M19SMGE4ih5Y24ZDM4vfic5 -tz1WaEYRgqxEd5P4pLjK5yzKsNBneVnzhSd8 -tz1QmTMaxnJTKrjeuc4SyBvwEMxXC2YQPgt2 -tz1U82BGZkys3AAmeodrX9ahwrN2zD63VdiN -tz1NbnmeFTzZfeqLFcS7beUkoiijHnQsy2RJ -tz1MBMcR3VF6tNb4hBMXAh75WDR1V17CRtkG -tz1hKECxknBdrQU3yDEJi9RsP8HAMySUdtnu -tz1hYuNPvfcmJkbeNHcYekB21LGwxPNjXWQH -tz1RwcjV9MAtMvAWfNVFMvqCdDfHwVo4wzXP -tz1iK1HZVb37yWLjWqEQao8wzbXBk1YtsguK -tz1gr5c2LxYh34xVoESDDJrM8jXjGrRWbgaz -tz1icjuHE2mAZBYXKz3Qr7Xjr6euNgPx6UNB -tz1bTsUpmvNzoHuAYxRE1qmsMibC9JwyYx8h -tz1f85Ksvge7M3NKASnS6i4DY1JdDnzH8vJQ -tz1KyDHyKq9BAhN2GfUgw6NoTnr1bEL6BUnq -tz1NYojqaNY5wMHEku8nDovWnMJiipd4KK18 -tz1SGqFEqUAaVd5RN74BkdNbCY31jSKiWYxu -tz1PceE9fScHdsVCPArEWHUEhvHFfLT8ZVnS -tz1SWzHNxbB3Wgw4TiDqS6KbAJ9PFatwytbh -tz1fBN6AwLNG2cCqUNP1YH4mGdL5tbQpCgpr -tz1hjPuTah1UfMjn6ajaJwwT9kUd3qaLFmnE -tz1gNmZHSanUZfVqhdEP21Juck1JTHHVJ6sv -tz1VJ7sC2Wt5pbNjoUeaXEGX3F2ZKhSoy7Sd -tz1XXzno26KMxg4SkoXT5r7gv8k1ezLe3cVS -tz1iDdvuVHSFrnDGBascHprLjHYjLHU1MM35 -tz1QFiRcYP8T8rS7B3nHVr3RXQzoFkzY3xgS -tz1ZCNQMkzJ73EzQosgtC5tvQEecqyYqgBwX -tz1NuBpWN5eXinPTfAjmFW5ehua7jBCcSofs -tz1KzKbp6DgYaJ24LkkEKnWhKzkiVASUtETj -tz1ibsTnKBcVXbSkYRnmnbj2texkKYTqG1rt -tz1Xdw3NDWpLNyQY9AHTvQpn2fREqJfbUcpT -tz1cZsVmVVRwKdYSy2U3sUr8QVg3kfYJ4JBQ -tz1YK8VmFPbdejvd2ugYEfV6DJCseGnJdwmV -tz1fUe14tbNmjvhBkFxMSMUDSHwQdfBAj9AN -tz1TFkVc4EvKXTmDM9aJiyUzLQw4VwQwGmct -tz1MZ6BKU1J2FzcG1JufGRzhXEuLKhZoUsgW -tz1a18H6q7MJRGuXLdp6Gf3U9uEBVYbz8Brq -tz1byg6gS9veswycK66Pi6aQbZ7KjqqDYJNt -tz1aECYj7EuvFER6cck6ncZ3ZZ3KrTfJJrzW -tz1gDjPt98hzyDemtXB1ZWyrSQjQ7N31ujUG -tz1fwA8CPLfvCC7tkWohHubmr1BuKGmnvhsN -tz1RxX3moPGguSWbduqpfnwarQpzoVGqNMU4 -tz1hFhVugjQAA4gxKXm2FkZYsy9aZBoahZ2D -tz1YMXcetPBv8k2vXc3Eh5FwxCKsNMpovS59 -tz1V8NxWN7wdM82jujVcDhjaovN1sA6pWG5D -tz1YZYPpb7UxgdK3b1wxxPcZ7i5yZVCKKvAp -tz1Nns2Nu6kaqvMZfSThb5uRGdB5CLyvQN3p -tz1LFZ9AXPxpwnpuhPFWBf58RoSzbYJnoWoZ -tz1bHfNd9v6KnoasQ9Zce6FE3arL4AgsxN7J -tz1XeA5LxDH5uL75ygEUVQs3STYEbVqPiU9L -tz1aKNZAP9avToUbFvn7stL4k8Az2TDyFpDf -tz1Udcdd7FdZ3Xa7KJBbpSrrPLguZvYBLiwT -tz1Y8DpScjrAUefBHX2tGibq1kG64kTWA1t4 -tz1Pb7xLtDC9mXjPAG9kDPfytg9ZFB9f8CFv -tz1dUuAYXbRn5UTkqPFkubtW8ybMuZWjsSPy -tz1Z9MNnBhmrKkNEuYzSVg9kTJ95e244vcEP -tz1M149tygPCWG2u3S53yBuXaQ9yWeJ9GBmo -tz1YxWnzrr2fSoKbPCpY8h2miwYGg6RH3kbm -tz1h4qkpx8hpCv1ZvANBHHeQbbwnb1xXaECE -tz1Q43wS3hpiv9uRwFu5GF4xgrcrFVui4asm -tz1a7JN8iur2tR5MiBsrhJ8EdS2qRdfVDieg -tz1PJvG9DZY7xwYh78j3fXHKjG7YN3iiG8Sx -tz1Nuozf6G8SRtoCJrXtr7deGHhf41Kge1sW -tz1Y7mvYB78W1twANW5t2b1WM4GqcP1RTdaF -tz1bAy6crogLhtckCQa4XJQEZArh3J5mGTzN -tz1WSaNB82hn3vpwxzHdimSLgLhF9hTKaWei -tz1cy9X64DwV5LPU8DCvFaJeXrBoaDU87ziQ -tz1NY5aGrsuXizBjHF2qMq93tegEEDuPdJH3 -tz1ist16FUmywDkoKkRH2tCPm3AjLXymZ4c5 -tz1ftEGgWzTgBwNkWdY4iMVv3YuvXZ9SR6N4 -tz1QBcHwayREb8HGX9teF7L2k4gwV9djfcqU -tz1Soyc4qzZVDyLxhPqEMBUGa6wCU9cR5hR4 -tz1iUWsgnNeg5PSvhkVWaeJufNrLDfW6XrH7 -tz1ZuiE2g14PnFD24sqrkC1aaViwap79ZxgY -tz1Ucq9UmA8V1DY7HkNkB72kca1QUFzn6xKJ -tz1Ux67xC9YbT87FsiGvB5pDx2kYskJGr8Fi -tz1Q4wz9hPUxZ16NHtAZto8ATbFmaHs3Uur4 -tz1eNu7NKqxx4mEwmBQ59dY29uXW5cmZEaEd -tz1SLFm4A73BzotnnfBUgNbcvVy93dW7BaiD -tz1bnW2pAS7euHDLKe7b2YFRaxCiY5TURN5G -tz1cU8qeMjVQvxcYL6jMZ7LLZ6mfjLcVGMiS -tz1WuhtLErVMCMAyp54G7EE1rktihjam8iQj -tz1bCYXPafecVErWmtW2Wisno6rk8w8CQyuH -tz1Xb2jb5vVi6XL3KmZK5y8Gcv47nGtLqwGs -tz1YAoN9Thy268PQyUBz1hBqRAiqsZL5v2sK -tz1ZLuqVsiCYiDEuo3e6RdWUqy5DkhZy8fmw -tz1fU9vFSaZHqxL6iLx34FXt5S5PZo91tutV -tz1eqcNC4rMoEwme5Szim1e3TPojVktJoq4Q -tz1h2re1dVTcDfc4KR1NWdFX5Coe9Vhdo4Lq -tz1ddDLa2fJEYZM4LJ5Kcci4FKLqU3xEjF9V -tz1SQQysAG32BEER9GThA8jHEPD9yGtDsjn9 -tz1WgRbJnG7cNP2MUALtxP6cxKAEyKDQU45o -tz1U7gCDAWQKxQZGdwVHWGSJ1X2fX43bZqNV -tz1NAteXPrKoNYHyeAJbEKSkYLr7wQe1PZid -tz1gqNABReDCNxXq1JVSnPT42uy3pfaiw4pw -tz1Sv1dxwptAz5d1tmpg8xve7vPe6Wh9ZUQT -tz1c7QyPRawTYvWb5k8G4BLFBsyeYQZkvQ2H -tz1ebZftcXgEJ5Csyvy2qKWp3mK88L1ta3JH -tz1WbPGst9nXCpxbtTVetZh84ZYULKBtt7Ge -tz1bBLLkaYpbjpUBfJJpbea2igx8L6UhJjNP -tz1W2G3tCXpCQR1NpJqEu9kc9GGeVF8ywUqC -tz1bg8LAbL3qiKunept9a11TyWB8oxP1Thsi -tz1UNYUBumfXNsqGbbCAxh7E7TXND4PE8EKj -tz1SnZFo4vzR8KUG9VdUBdRt62UAyCN5Xv89 -tz1g6rP3JjpW86csyVhXqcCMsey3frxRMPHU -tz1TnJF5Nad6nboyoYjZ7zsJ9ikR6x3TQWQL -tz1RrNFg8Pm4WXEpzsrb6YeGZeib6moPn849 -tz1XqibuwNurNvJ9yNgSCPKPjWXrQMNZfgxa -tz1PdgAjhBftSQtvPLyxEp2mciuoRHq6E6sJ -tz1a6nweoz7yhdQ2NUN9LLHWfqmyzJo6dL5C -tz1iPVJE1vK5j3UUCyACo7HBPR4upWoCNJWM -tz1ZAAFqiRUUJrGDxn7Ui8s4M2vN9wdU5g4g -tz1XoUNnc1Yg2oJsJpr6FBsT7Ae8hRocj5ps -tz1L6Gc475aLAHQDkC3xrS1fkLjtwnHU9Mfy -tz1ebS1x6AcVpgY3ANm6Qv5mLJRijzqMrkuR -tz1bFhhoZaB12jBTHJUZXCp3d4sHEQNXBrWB -tz1M6orwLsFdaeRGSSPRBBifnRE56ab1Zhof -tz1guKPtF7gv4ATsAzo1Y3Czn1KVgFDo7zsA -tz1eH61gpL3WRcSsRFYD5cLu8LG77JkcTj7Z -tz1fVVgH1xmkL7oSnEy8sjRe7uPQAQ2ZpqwZ -tz1RpyA5iyUSjKnK7kRweBVBQS3G2iW6uVLY -tz1S8GHFe6nt9BQwAWphz421ANcuXarfHJ1C -tz1PQUjZRM56eyPK5uHz4eEL81B5fp6W7QLF -tz1ZBxho8kCaKoiXnkPeZKcGHi6ye2dS7GTb -tz1W2Ga6Jc41ZRheJYef5G713AXxeCReb7NX -tz1aA5Ay7efG89YqvgPuYdAtsUJJPAzTb4jq -tz1Z16pEvBbpGscZVPhoVHnXgHcwHKKH65e2 -tz1UbXRwQD8DMpGkLSki2dVcWdaF1pXeUTem -tz1eGagkQ7AyRmA5E1B4jndbELpSTvvA3vG4 -tz1iLWFuXnF2kowVezYWzQA94i96ppgZ7anT -tz1fkfvsHbxw9X549MbLyoJrBA9qBKmXPtdk -tz1RSYMhWiM2Ykr2n4dzvxPidV6UpJwx7VrR -tz1UEAGBJB6TK4auFTEyzi2VKuX2xAW6coNx -tz1VcMKgosgn87LQspMxXZCZxGTpEFfFbauQ -tz1UdHpZy9uCgKHmFeW75wLtdJzqjgesCNKY -tz1NwCtqG4pErKBSFJ2tcqRt9bE2tMXKUoCi -tz1Y8HiCfNscsVe3yAX8MFK6mG9oKiwk9Det -tz1hWpQTcuRwAXtyUvqvWriphTheyvBUrbtW -tz1Ltdr4SCkbTz4Qc4EWtHHtKXkARc7qhcFH -tz1TniEuRqp5kmPKt8TqpBFztr8MY6gQ1YSX -tz1V4G6zvpPuvtey6rxtzwL6eXc25B1dzJuE -tz1VTdtRTmSWTxq3mNsYSNic33cnCqZkpveB -tz1huWjTav2XyakshDhuo7KGpJPHiL8VPc5s -tz1hD7cf9HfEorTa6Rtx3vtUA9CPhHVEdkXc -tz1c9FZ6aWMUmnW8CPy53WrTubqGAE46Su7v -tz1gEUTMwpgRam7Z5nJ6VSovEFy2jyDrE3x2 -tz1bkfy7GnKyLkrGQ2ZRY69nMGYWJ3QHi3cA -tz1QrmMv8Yik9ojUkthdDqez8r2Yn1DbEZJE -tz1Kg6bP2uBubp97e1UFo23ojhZiT1KwBJhE -tz1LxTNUZsWcEU427oFqzK9QUaCLaPfci58Z -tz1RfFdFfd9qDuEuZA3d64hB42n9XMnbGr3Y -tz1dAiixt6ri6HCvuSskqF841hUzRmcLzwC5 -tz1fqXWoSDLetJ5xCSDynbrji13kAQiRA6ZV -tz1Nafgsi9L5r3t8Uu55KGybRTbvGJWdx87y -tz1asGZid6kP4taRN5zHi1LjwJ1rCCJzo57u -tz1XXekn5qL6ACdD9pY2ZmvpPuuCUX7ZApsq -tz1Tn1cA66XWUra2QcuwRGJh9sztXd3sXuwg -tz1PySvhR4oRPzLT5b9gDkaSRkrnbDxhYw5j -tz1egJPxcwLGfA6NPhRkQiRyQrP44VaB2pfr -tz1gzPS3RezZJAz8qBCEUSSDKp1ecHJBBa62 -tz1d2uzShWSkEanuh7K2KuHSx7w3jw6nb2s5 -tz1XTkj5boSHgDeFy9CxL7NMCNJSbr8ALJTn -tz1bYDGbpcHjnzs6z99FsahRk4La3XE95oBb -tz1T4oiHrYKM1FH6MYZ1eGphuqnQvZ6cCzYA -tz1aGjJdLYJ6k3QE5FiWJbsDGBiHff9fAWq4 -tz1QwsWho3A1pmoNuqwfZ4TzSijhgRc17Uiw -tz1a76WaD64sTBQsZpd7oMYe6oP8AXzD54hb -tz1Suy1qkXLNoEqojH5TUhiAVzS879NJLrwj -tz1eCdnQFKxyEnq9c6qoQu56PpLmedVZYwwG -tz1YCQwzfc7cguAq9CxUFjDXpS5b2tHutvQU -tz1UNLFheuuEZLypLQQtP2aSDDbkY97dMK51 -tz1VZ922rSnrAe8sMYgqLCm34SyXLe9DUowh -tz1YnobzuwVRKj9QKXiyTXhPbQkSvcxuyGLE -tz1MqfnL8DSZpi27xLjGV3J5JWojD2gR6tFb -tz1avuGkYTbzqQrRhJ5m1Eqw5GxBgFiFNtuv -tz1dhk4nHBtPSGJAt3H8r6f1zbZWLXLveTHc -tz1d4Pp9H4KHkZ9CYE9xbLsMovSEKBRXYyfe -tz1VgXhygzAxqeP6ANzcE8UNSVJnMQfbiTvg -tz1goUvnCUQz1EuSsrhyYR6wLYjzfewh5Tn9 -tz1Q1zNaHiQTmhxHvH69aetZWQc4wQmsjjou -tz1WSJ3ESHtBFKFoqjSXA6Gj2rdaeJnx2a1n -tz1WPfvZx3p38pVsnHNWNM8ptmfbbURiuDPk -tz1e1DLKdxmEGc212QS2zF64HmSWZcLQG3t5 -tz1iRUHz9QTRTMqDvz4iP7PgfhnhmXB4EepR -tz1VNRzivNhx2WShenTAAutdwvAxMzkvJJH4 -tz1PntGhJ22HXsACcfoX6kgXWxFESj7bkjqg -tz1RrEf9fd2yxkJWFaYB7KS2G8z1PABQAwkA -tz1YqreBAYBYsQwSVqdKC1myB1h4HTvAfCFs -tz1XdxDiJDJ5Kb51PjU28syS3tfScQC4QCPe -tz1Zf9pgeqGc9P5UwiiTSJz8bFrK2C9Ew68o -tz1ZY5fjgFrL4f3sQLDy6yMVL3RhBKK2r1LF -tz1d1BWpVhpkFRimiLxpqspFT9HQrWfXhbKz -tz1S7qrC8hQ5bsf9qBKAZNQs4W4KYVBcoYCV -tz1dHmjzNmfkUQ6UkyhWSystVCxkXVEMv6VN -tz1b3qVa9so4R9pnrxCHDJpTv31ASPoFwbeD -tz1WM3KyyiJbrhEKUicUvjT6S7Lr44b8e87Z -tz1XqxbuqCwHUHujD9cYhbmQdLY67a15Wmom -tz1fF3yKw8SPtbvuErj7CQrZ2ij7fbBsSnqA -tz1SGeQWSsv9BrP1ZsGQ4Ge2VJVPwh1J3RqX -tz1NDyNzRZSfNbJpyUWrxR8RfEYgZMdAs9bw -tz1cfKgUTmHw6FxQpinFTxxZYZq1aMcVYCDp -tz1Wd4h1jULxcLyMUgzRVc4GBJdDTxkKoq87 -tz1WT7FCtrKGKU95QfqYo31GsaXuUcbJgsfv -tz1ZCaJwLm6AYMUa8b8MXRvvmtgCCW44d8Qd -tz1PZSZKPPx6ADBtm7nPvgUvTDEJRxJv5tiW -tz1dj4wBNSCoRKNRipgtAYcNStXTFsohhBvN -tz1hUPz8cQqJbJYKRf3scH3u9uUAuvrft3DL -tz1axwJL85fk6Cxy5NQJGeFHyx9r72AqgNzT -tz1iYfagYPGuqa8wnsVEhJtqG9hinKNFbUds -tz1MhBQVxjwQ27fNJdDR8QGsKTNwP2tbkhu4 -tz1cQULP32bgu2D3Yh659gc8bnUXXuEareLF -tz1L2avGSSMtGvVzuKTr8P2Qy68iWdYnRVSw -tz1SKtXJm4RhyR3p4q4CacJ1JDYF4ozbvPVu -tz1iXyzcTsnvksUxDKFZ9ho1rftKbxfVESBv -tz1h7Ewjk2yNJX2RyUY3zzKXjtpKc6yUyYN7 -tz1WL149J5i3mnRi8MDedd7CRUfyYj8Cemom -tz1L11ZaFqwsgwzGLQGsM5KB9QAvvrRRUtjQ -tz1cWhG1nWGnD1k11GJPtcbokDDGx7e2HNaH -tz1U1EygzsEKXK7FPCerubeb2BYqhyUFw1oL -tz1MSfNQuVDmpfSfJz7nM43ub63zRt7UvVyj -tz1ecJyhLUxi2etJYcMvx11M7uZPjJ4oVHKg -tz1NDc5bmSFNhexxP5AH1Dovtj9zvsJ2oFy6 -tz1fhKcAZ4XxCTh5VJ7ZivUBun24eyAnN51r -tz1MurbVLWQ6pcTExWcdBXJ61qr9zsg74oKA -tz1NW8R6K8sL2HUj9fJRXHtMKTyGwy7g1dtw -tz1WXRxG1WFXzP8n2zGycBtyo6QVAGb8BhoZ -tz1ZgNszELkA3ctSbS9m1sups7hSZDeTKVuV -tz1gyQe2jPRDkwwSYS2dSbXaQqD4dSAUuTGi -tz1h3XTnuF39FLrzNe16azXBnJdSQESsNEwc -tz1VQiCDPDDeXwbSNasjc4Ad5dqnvRUNCUm4 -tz1XXE6VEtXsizNLodg2kEkt8wcTvSkR17kV -tz1gBn4SNMAEYy6Q7L6p6wQNQM8GPWiJMzxy -tz1g2LZH61pVU6bDfRKgsbf1kqDSzo79fCnk -tz1YxgCjMXLRCd96GDfH2Zn7duAYqsdPPdCW -tz1dgrBMk7gjLGvzZCH3ah8S7m3LYkBggckJ -tz1frE6L4pQBYPSPaWyhYXjSAJKfA294vk7Q -tz1PRANcSUwxrb93fij69eamqtswNrH64zmE -tz1UH23s1Jy8ZiyUJTFW9m4vcsFJCCgRaJYe -tz1bYumjvPZkcFjfRcymVZp3TbfGHvE5roP3 -tz1bi7uyvrhYou4UiAmqihgqyny1REpujPEj -tz1c9nVBNvkFjqzZ2ygGZmm2C5DMdbveyjko -tz1WPtuUGMh8x7Pf1mPAyR9oVWHHdK3mvBEe -tz1TAeL8YETkcxjdhRCAis7AiAAyD4AayAyb -tz1QQCWiSTUwZeMKGvSaL2WQA73XaY9Jm2zL -tz1XcVhz8Yw8F9rScYZ8X18pLh9FmpcQ4tkh -tz1KkVXaUssuuxdg9EcEbnWXmtjJTGz1oAtJ -tz1ez6sn1zqz7nwTD6wog65gt5s65ZqzKfYX -tz1WwPKLCtbrph9FKxsTw5wFGYm32o3ToNuM -tz1a3Q4jJJTwGKF427Sp4gFP1jSgcAY5KS4k -tz1MxFmSWxiAcdGDN29UPvYajVWDM837Johj -tz1hu76oNWPuzdg4jvJXxGLREHVDJdK2o47Q -tz1bc1h7tCMkVKGPZ2sp7egajavQHcEaWrak -tz1TWhnZekRPed75imyDyWnyKoG1yH7YpDtr -tz1fF1hAFbtgcNDZU2iJTqELDfZecXXeHyMc -tz1QRHZErAgh5P5SEi34bNRxFTjTpCxJv9T7 -tz1LA1jkQ1CM2GZPjR7a9jcorqXRaY6cFDCe -tz1WHMumk6bDvAR5cx88cKSEPNC2bLhmiGPv -tz1WsR4pQsaSwXNEtTdon4WeFVmjGZ2XtoB5 -tz1aeQdFnZG56JLFbMmCz6G8YshnEVtbHRe1 -tz1hHzWeq2TjhQDpH5BaU6x56Bdpbn6VxQ4Q -tz1iXumzq6SjuSKrfRGBNSJWrZmpjyrFKNXk -tz1Zp6qtWD7GEfJfG6oCFLhxPWgKhJmVn9vu -tz1VXGGXHKJBQzCv6xf756GD74UHLPKqupA2 -tz1fQ3SBbqB2ZhhhURtByAvyHpNfGYYMYYRV -tz1fxdeeUWT6YG5aSQcaJVU5sbeFCQYKCvPX -tz1eQ6xS8Brw2nuiPcKRhF9Zsny2yJ44mKCM -tz1gVQrkBw3rLxE2M9d5HeQnqRnquiwz2XAK -tz1do38BSLyj1hZrcGnotHniGAEdEF677UH4 -tz1exXxdqa7FxA3mS9rKpY5eSemjXLS3UJ3V -tz1fJJW7FaxpVF1PA5m26EN6S7TRhChNAW5H -tz1TnVLQvhWSeYNkmLuAH5i2HRDB8CLymy4W -tz1iTa8AibFGgTSHGAq6MZK1UsULjKveJiEZ -tz1PARvCZgSmUqRfpKmYpUtNzJjdpSzbTkAW -tz1PYykHCqt16yUFWnQyFAXQNY832CNHMU87 -tz1S9VZ5E9r8zwbLUHN4nsuTJUm27DueoXQY -tz1Q45AvSuF1dkUyJj9xyj9bArsy8U95X4uy -tz1XinJYa9jAM2jmiPscfMMvAUbc3CurFXLG -tz1ZYdJb2FLDG5V9oteXXwVEoj8njHFqu9S8 -tz1i8xW8EiAurH16G87KArz8rFWMzkwim1ce -tz1NenRprrupvMajQ8oNYMC8uTVhbRRt6QUU -tz1Vb5nyXtKD9eCPPSxyTGkum9bQGJ4XLKz3 -tz1MD6pWxFh1zutxdceJbyTymEZRm4PZSCzs -tz1KmL4xEDwUUQHreqUFtAHQ6T4PtdVwiw4X -tz1T8vEkMopDbqi2skRF471QsbcEPashQL9w -tz1LCdqkbr5UTxWz6TecCqEewckEELmBQNbG -tz1TSaHBmGvSuJ51Y9C4NET4HRgBM9xPT1Ci -tz1V1LcGEc4jxpYEXdbPRYvjBuSu4rZMm7qr -tz1XxhZj4PuuUntXHUbcLuAJNC1gLE5H17TF -tz1UDMjPiXJaUs3hggy1i3aqEx6fE1uGm81S -tz1ae4vrc7XxC2vETvXpVfxRFJomYfw7oTdD -tz1hBr9CGjiNr1qBZsPxdXzKej42Jz5t2dbt -tz1inTL38yYEbvcbe6fZSRMAqxU4nFGByjyc -tz1S95XbiWiNwrfFE1kUJQq2ukiJ35CZ3h1P -tz1VAnS5k2s22kBa62B6So7CrC8na4g3BHWf -tz1QZbXDzcKniCasEA1EUZy2XQ88hC4orn58 -tz1SsZLsZQj3rHw3oeUDrbG3FCyZ86CmJQUh -tz1PfkFRbbFdcENandStxa5KsMY4bJYVokqF -tz1WuQzqscz25Cn2MZBAmrKcpcggNUrRRiYr -tz1aWwpv2uPqyMK6SxArmaXwRmHTxAVVExDm -tz1Tq66SFiuBsav82nKZkbuH35pXFZLQhVcr -tz1iYFFBsZSqr2DQEef8GazgaCogrn8K7GQP -tz1QQRyQci8bzBRMQVBjZF3JJ7pghpvYchGb -tz1V9KosGbLLayQyVsSYemJv8yTYCe4YJLAP -tz1VU52SgKkpbuAS7ccdPXdzTGpRuJyowFhP -tz1dZDBA4tEnECcpHFXaPn13G5Pw5RoM1bH2 -tz1WNbqyBy98CsnN8ypCtLfk91McYms6Dpx3 -tz1WekiMsJxe4AyQpkE179GUrH6mMDj9dXH2 -tz1iHxzijzX8yrXcfg59kXfUejAVhXeUPiQN -tz1Ur3upwTdEMzA19HfCSAsFj6UGtZDEKAn2 -tz1ZQjgsxZp9bsEzziy4MpMGHvG94wvKfYQ4 -tz1hjsh2Q8C47WrXkC7jo5wUxJch4t42Qtz3 -tz1brsodNNHL6twAbEJyb3g7ZGBuyFZmfTKu -tz1XWtuGLZUAxXGD8fT43kowH4ZuBGnFt2Gw -tz1UVP4JWdiMSQTnwTA8pWgDS8gcMEe5KoEi -tz1RRvdHbmqceiyxqSQ6Wuicc4nbKkkiwyF4 -tz1djeQEgewiJSDJ5pkovm5ycF7atLiR2D3e -tz1dV5YGxTYQ9aNYCvZax5q9FrL4uSuKGDYT -tz1gTnE8QUwoEzp4vnrTfUEeeaD6T9U9cGB1 -tz1R5ct8VLqPY5rzT7ucbWtWmwg53Pkb6ao6 -tz1RgJimZUhpgLqb4ZQUcozC6scMo6boxtSY -tz1VuNnchxqruj2S5BHezLTMFH2JQQbttdUB -tz1LHCSA9jBSbYx7EtLfdN9W7xeddfmG21Jy -tz1NRnMi2UxrHnAaxnEfqst7XFHWLgPyapZ6 -tz1VEiiciWspVKd2cfj9WbD7jdMo5F7mNYdP -tz1PVy6PKmsvTwMwS2Rex9A6Bdk4jsFyCHdZ -tz1atwtFE7ZC8J2GwYi5PpMBMCwuffSdThEU -tz1bpgKN6wSEgAtgx8eswyayQhxTV9htYTxC -tz1fDALY2R6TBxxgnET6ZjGq8PWCuRt2kxGV -tz1NNMf1Wihi51xgpDZ1b87BjNNqmgk9V5oh -tz1YWXVnCyFrLqs1wWcVTCyGTdjfqdLEeeuN -tz1Ysj41gxqERdngv3LzAQjjzepx5yMDBFAV -tz1aTfxzyrKG1aMoYzCEFXRyqC4nwgYx49Rb -tz1fcEy9MY5Kqru1v7DQ86d6E1ymZ9YQod1M -tz1gcgpaZ9WfP7Quq5Fr4o8PpMz6fJJmnmoU -tz1bHrCEjP79fDQwTVLxbg2QjjW8P57D3pLd -tz1cJYLWChNCPWt4S98nenEdxUQXq57k2AjN -tz1iYpMB8D3jqBY98FNuKPMAcPW3HKcWWW6x -tz1WKsrSgsAzjqTpGxksr4dytY4sm3nKemQF -tz1dNzgKhcCWSeB6fFpdaFeTcW4g1aidhYFm -tz1SC9G4trWAEkVKQVhe7iAV2CrWrvs6kjaE -tz1hybXSExuhDP1zxt1Z4ZpKcycCEhxX4dMZ -tz1R1d68t6LL16xn5wJfW2njudqw4MohD7w4 -tz1V1aFo3srWFtW4eCr2FgiCaoRsVTKKHqek -tz1ZSP4nR3gtDfNnA58DLnsc9mf6WFFTbrQU -tz1berZv13eG8a79PjwH9JogThoPr21T9fGJ -tz1Ybdgr3Se8gBP7QmCEhqWhVmKMHm1JWKQh -tz1SUCURZMbYMq6kLqjyyehJcf2rB7ozHEsd -tz1f8e1jyrsUeAg4Kwb4SWXjWaC5NAVeHQCm -tz1bxj1yqLUufMDVZ7ywPZ8yw6ndpvwq9SaE -tz1ZsshuCo4EXL7UiZEbNK76L4PW5r5S5ppV -tz1bYabPPQkQXSK3V1CwnXQXkYbZBwfjh3Tv -tz1YawZeG9zTFM6keHfv2i2m5msfjpdf54a6 -tz1VcW5bnpR7FFRYGNWeqoUMXQpKEmH8vSJh -tz1T6rtzXe7mWiuFaoufNo7e5q88jELTJfBy -tz1XfLYtdX7wffDKZrinE3RvMkLwYrRMSCbo -tz1bZ1VnVTdyCYcdHnHEaKVbBXvqviwbU752 -tz1faYFsJsfhQ4nA7FmEKBrpzDpPeEhB3YmS -tz1UwJL1bNtvuZNb3J8ieB7yiP3BLi1wNH7k -tz1TsZWFfvqvXjU6JWhuHZH5zT9X8V9buVXn -tz1ZYjSczHBdzzU58nBxriaNPH4wrEkNRXFo -tz1Z4EkRK5vXPJkrFraajyKRjFPkUoK4Hxj7 -tz1YjxFG5VUeM56aTqHPbgvxQn5b2wMUUSji -tz1VgaCucdLv4XGg8t6HhmtqrFV1NWV28QEF -tz1RGir95JZyA4MC5x5Aa5mNLgjyp95XfcH1 -tz1PiCXtQynRYfLU22ETcUAi6Wmdu9LeuGrC -tz1LnJ45smbHwFCRgjJ1PFEFMYqeQqBP9UPu -tz1LfCHfdqxKPoWe5MhhxyRHWdXWWA9VTFgL -tz1ViXghtzXcjTqhe4bfeDFXETxMo3xrhnek -tz1LPQbPT591nBQ1MkhxFqoKdbBR416BihFu -tz1LbEvLMqPsqKUoGxdC1aLypjzrPuwCiZVJ -tz1VqgFuE6jprTvG4sQcTJGWKwS7pB2mXB1Y -tz1eY3rPNWvjWeDqKc3Bz1MLuMSA3Gqhf2z7 -tz1baHKgJRVYb4kE81ApxV7HY8dcwmMaB4xs -tz1PYDYvzWaQ2iUb2gZATeCVTodvqCSS6h2H -tz1LXTY9YciJTiRPGU8czfU7DqooHiu1UzFm -tz1fC3bf4be41aksfLYwA3Cwt5qzhndCCFei -tz1VH38mEYwPubX2TVnDig33N1SvHT8Eh6Ch -tz1aTDu3q1LCXnhJ6AxLLayGyeHbBENdJeDx -tz1NZyDYFuhYttTZKKc5o6iALho2i9sqAmMQ -tz1PDf4q5fwLV7s4tc5vpSA2BR4CqFoKsHjZ -tz1aMs8RizrU29ktg41f7EQQSB6GHv3mgy1q -tz1SFefygCkSGA7my4dHAVsRfEfFBkofgpLX -tz1Xdy7QwRK7J2sipA6YxroC2YjJmcZDQAKF -tz1Yw6uWvUxqvE8jvjtxTgjVGgGh4jTEe2T1 -tz1WhUppFcfcJsUfNq3MK9Hf6jVD7h25Jrhw -tz1Vfxw8EsnoKV7YfUdh23ndMoZM3TUDr9tQ -tz1X5U29bVEKtZRmf5TNYoLRity9SXzvHWm6 -tz1PHdNWsiGtvJmLmcdJdjUzBmiMx3fENTC8 -tz1NELJc1jBezKwP2UZ7ovpmg6rvdbGBvgv1 -tz1i7GJwUXtvWDjvheskuJdjbHvJ8Ch2nvPr -tz1ftW18coUQifVFjZZ2UVgQa6qHHi2fRoTw -tz1SZDaAqBZSFQTEAKD2UPZRf8AH6xUjMAB2 -tz1coP8fvvzYXxuBHuKLUeDEeydL3ezh5QCG -tz1eu53Ri5TRoTkowHZhYSeUNQ99U5151mFd -tz1SFACQkHYKQ8VBUNfNAiKKgCh1MPqU4Kxt -tz1NFSVaYDPDv1U6F9riQQ4Z7wxDTcCHNpiJ -tz1iZJbuHcHJHKAWtEwLwdi18kn1CF7KEMuS -tz1N1PqJMj5R5FjYt9UfUKDF2AP3c2hccPGd -tz1N7dVu7HgEjXePunmgfxmEQ8MhENMD2Us3 -tz1gFXqEhfovaGF28HLrACtrC73SSk3iwtaj -tz1TKDXmxMHXUUNYbmXEyXpUnv525n23WUaS -tz1VMCyQzJkJLb8m79rykv38e4J4tvWnwQQW -tz1VixBF34bYT9yhAuL2myyLi2QeBBiP7mBN -tz1M6Ld2VRHso3Mb2rP1pWwCny1d2WfhDckv -tz1PyViY73WHbYhGVgkmdfS5fMCJnvDaxgYp -tz1hF5Ned5ssFcAhXnKLqTq3fSejEMGWWjj1 -tz1U9YkCHSkL54k3DvAnhbdkiDeP4fGt6sEf -tz1XnJx62q8oySfvnzRMV6f5grGRT37d3s4a -tz1NuBUMXaRQkG5sYi5xRsnVMPFrbX32g2HQ -tz1RMxYN7PkpWoosewUGo7sDHfGuULC4gNLy -tz1PYhtvHkLu2exXb9FefXzob98NaQa8u7FV -tz1e88rWmnWMYRZDknZ8fovfwXPAkRW8pabs -tz1KxM7aajjeNwogNwVJ5P8s7S9brUEBS7Dp -tz1RdnRe3rQWFYTDvYpmHx64FQQKWKqhvSeu -tz1dwUAb9ja869szhvZc6fFw5dFnjqi7Lxnt -tz1RRgasoEjcMKgF7hvchTWh4fgUyxM7gGc2 -tz1RW2LaRKp4GB7fj95UHgvbnaFdmY9uhccj -tz1cYcgTYdkARJo7GWe3scDvjB3pBS85m4X2 -tz1MBRkVcayZPJ7SZEBnUkUNSq7bpYWF7ci9 -tz1LEPNe1HLkH7n6ZFEbzVgsRixETro8U5E5 -tz1RLt8Le7dSWgkWdZVudUVpWZmXVXbQxD2J -tz1UrknXDKiJEuQAiR6MEMpCmzt9y9avkBZV -tz1c5EU1doMhJYAtXyU3EeG5bHAvCz91FfdC -tz1d2M2UM7JRHWH1fcYHzBggiCjkj4tB7KgY -tz1Q91QSAj9Hh5jPkAejW1fkfQWRtxKPKozn -tz1ck3k4K6a5P8Ydr3qF8AAZM3yG2KvK9CAN -tz1atjSGRBQHuGUMfeqd3EDdBpBRvzoFSgVM -tz1frj983J1bRi8SGqdvUpL8U5DFY7jAL5cp -tz1fJtZUekkygq6YDrAoNzphZ7bthpqX9216 -tz1bZgMLDy682LktPFpYfc97ZojTqBwJMzV6 -tz1XyVXNbamPEYPE8YPUNiT5dAyStQbgLn5B -tz1WzkrjSnbjUZQnoNBbmwDEtmUzmUJTAfWJ -tz1c2cmKovgfP73dtdaBN2AGRXq4BJNn2U6r -tz1iXBCV9iTUvsvnpKNDuLssUpxqFefXMmox -tz1XjBDbVQQHUZSb5Yb5APHBoikd6CWqYVWN -tz1RGHziBWGxfsnVXkAz17TVgJVNgdZjiNVr -tz1cg8z4bf1PoZP9KKX7ZbxJzmAdrDEzwNjp -tz1bpj6NzZ1fNMWvHhF4H8QFAT8fDb2cWdwj -tz1cpa1XyPfWPkrVecP7DMcUq5QBUKWTyvfS -tz1N7bCazrmtDmDmwLpsuPwBUy8yqTsUAHHD -tz1SLrv6Wg7gjCnugzRqU5YCHgz6dLxam41u -tz1hVoPwqALpMnUJkvXdPNwFCWJD1qmHQHrY -tz1gEXvPRHrAktbfd2GgABTAoNz8wqzUaRsZ -tz1RPkKSATApCrRJRYmzx5Qk29dJxqA9iUhL -tz1KxU3WHTEC7sM1xSuwnEFcnckvB5Qp3NUn -tz1d3GFdMXr5sjcPGYiTUUftdEqZkW2rvmu2 -tz1Wwhg6wLkmm7SXNGtbVpo3G67hpCKiwTsD -tz1fGUHUaziUPQZsv6cHXn7AZLBqA9PRTw7D -tz1Kkh4GmV36zATdyDQn4XkLS3nFmCEv2iTJ -tz1e68b1d4j93AjkN8j5fVKs6moFSxrDxThR -tz1UfH3oLfvBUbgxYdcwWLUDLP3HjYhVE9tJ -tz1MXyVaZhvZuLfKStQyX6v2RVqQYktfdGrC -tz1YuoEMn445YQtzEWkjMRFSV17VN6VodgSy -tz1c57CQekaUxmhttPTEk3BoTSMsXj6JwhFN -tz1f3nUq2FxA11XbKzx3DLkZ9pavSKGHvLNL -tz1YNazrsQcdnG3jh787Q6Ra33Q1wA72cEDj -tz1dpphwdCSk36zhhmcqvhbs9MnCjkNvUvuG -tz1gbB3uurLbrNRYUT7K8Rdt4kb5S6xXU6Uu -tz1UGwz7R45RKc364EifpU9j5UzdJs3V3jfM -tz1eya5YvdG1qDQCgkfguN1Xzt3p7MKtS6hf -tz1LJRHdbK1iP17eXjNgMUC31srdjQcKgQmM -tz1dsgJop5DZSEt5hx2LCquKAwx2VwKeSaC7 -tz1cbnGBNmdrm7s6wiKrd8CJUJosfisGXNk1 -tz1Lp5mnvnNKMhQTTePeFZVUXMQJeQk36NY3 -tz1ZNytGaPvjYtWTLDTv15qVGH5Y8MAUEC9m -tz1c8JTzmA6c7cm6ZmUwR7WES6akdiMa1kwt -tz1YcNFBmPNVBZtXtXw3PgAnThepVLA9voyj -tz1eRPcjeVygsvXhWBMRsmFDYRm1CLdj34w9 -tz1NX1ievfkXPwpzT4CQKFfTcMYN4Jq8BMeZ -tz1YU7XDro6XWArcfGubENRLuXKkTRzdR1iq -tz1NA6qGmoTqdnAVxPwShEUHTnPVauzzWAAq -tz1Q5gJtozfHN6KzgoBhZSJ6zP9McM91dLqH -tz1bC9BQNEgt6wBj5EPzDmXY9JXYZadWmZAy -tz1dhLG4JsWPQowDsYF1DcW8qPdiNgb9VtxS -tz1ioaYM91wgMBUGRjY3QGFQDfLvfU21PTLH -tz1RaLZpxnM2Hd8e4XnKDxey8ZV1Q2FJ8TdF -tz1U3Z85CJqgQgpmSootHo8A75rhvNhPapfj -tz1MVV98cigF2xPhgu5xkM9UCuEH64odx7Yt -tz1XN7XEtFh99t3hxkWmyQdLLHxcMEUhNWPM -tz1aEkurTS43xRaNswN297MHDEGUCzip6aoC -tz1YThDj3EuT3VWuXrmB7XJ9q7KCuEzZ2n5g -tz1RczYtRzrASmhKuLxrkQanDYABuhi8ZVnp -tz1h5SB1c4qyjtEUgNEhEwRERUiwNcF8Ju4C -tz1SmrzrhJdgL2sgdyT5K3fAffxqdp2aQFDc -tz1WY3cLGAV4Gx1xJQ9ukTLDC4ksKYhPjneA -tz1SGPWTKys9qPCiNVF19ZhVhqyk8ibkRHsK -tz1PnFVBxwdSKPuvHyeyP6nZVUwQxUtakYvd -tz1SSpbfRyXYCPqN6NxSzBW1H5opC9mDfpBR -tz1TTw3c77dzL3hmowGBBfgD5QJBsgEAoLyJ -tz1gR28UCrjmvP727AcBAskrVjDziPu7SvA3 -tz1hsBq6m8FzAjuX1Y1pxxvqop2pGFDppE9S -tz1QE2gRhtbpQbAPuqUzSVTJ1ex2PidstEx4 -tz1TWKXQpWcCktMMdDc2ErgRqHmCCx3j7PKB -tz1goGWGAsNmhpYePF7WiCvqpx1FffNwJmte -tz1S2wSqvp6dg8H4nXWFiKVYGk1XWPiJza6T -tz1M1VaRYfqXVYKQ5AhWPEjBsBMqVghSxrWh -tz1egtxkpQwpRxFGtmkBKFWnnyTnavZMujez -tz1WQwXF83gU231rcNwN88Au25CLxqBkRQjy -tz1QL2shiiiAPhUCYGJPakckLS4b6GDrnSbp -tz1Rn7o4gMUYQarxceCnd8Ycdorjnq9sNE9B -tz1Ljtyicmc8yBSjgMyKq4Noq3pLdJ4wexso -tz1LPX3ou6FProk5qoSNCQnRrofJjYJQTLbA -tz1Xg9eP6TTtoczTS9ud1kuxXtN2LPQdaV8i -tz1ex71SN8SCvtHAe5CenivB8AdB3iPFAXbt -tz1QUQQbj9one2QHjkiC2rVFT1KCWbmVhNEZ -tz1U4mgU1J212ZitWzzTGz5ndPtQXCVEWKxo -tz1ayAJhQpriqxuhCKXdqTNtyYYeKpVj2tHT -tz1PMiuWVKNfs8asr3qj5uw7aV2XHtbcrkXY -tz1X3FFUwvJaBMRJYLvuW1KrdqK11qgNGJan -tz1QBitMoH8FnJ9q7DUwxoL1n6wRmCG61rJ9 -tz1d93v5yEjBdoCL6X5CXytCAXXQYfQAdYXN -tz1ajVfxHBCFzRzZ2afV7obn7pnUUtdMom1m -tz1SQuSbeFjDpowR3Ct2fxM5A9qFeBE9C6JY -tz1LkUhUxxWzMr1us4wgGgXhyKCWB7QPqJ2G -tz1im24UhEbtEQyMGHzxCFeAKT3zM2UtadpQ -tz1dC1gNTYrpRx8wKdZFhUX7oK8h6o2j6UdV -tz1czv6gC589i8H6q8sJy95A8diufzto9HP4 -tz1RCpKMiiBfMhhYbV3qknyHRvmFZoXEsW4o -tz1aTc9FDmydzeJmimvgz9SHBC7uPXo7zzgA -tz1SLwX2qL8T151pNmWkex6MpJrcQQpMcGMH -tz1aNzmBBCtd7coomKiQkaSisAeRmhPsDfoB -tz1a14xLbHfVDNsSeXQv2nNYrojURVxFXmpb -tz1NPXhFTsgMgxaE5USkjk8BUG8oMfN5L7DE -tz1QJzkd3cN4awTWCBHDtfXAssAkLsKA4yXZ -tz1PwUNuytd3Fjzt5ifGzXpE5kg6RCE4Zq4k -tz1igtKgLis9s1pTRwvHdQjWCUtEr7vwGjCY -tz1UumApzHrbtqbMm7P1K6cqT2LmnTcYLVkz -tz1LcPV6cnYCzSzkZxyXCezEvkYS7XGpRWLu -tz1ToCH4Qfscx6fBM1xv318uzzxpT6RYgRtf -tz1WCDoUayLLpVPXRXvpJvfSzy7rkr6AvdPz -tz1VWmnscfeLbGTxn9nureNtjoW344Gr29Mm -tz1KpgnTwpmvztnPYGFBQbfGDLqYE6FkTdZZ -tz1VttGDs9M2kr3zMfLRHqACpAcNcKY2bYj5 -tz1dZHDW2k1eQv8U9MhXYpR8B3o5JhWCUkyP -tz1LcLv3X47coZeRrYGjQoQeyinS6dVBs5JG -tz1XamDmB2fyhqcnibAi267NTV1MvvqXLgBD -tz1N1tsKP1joseVqyrTURffm6RhndEd2uWwQ -tz1eQBM6y2ZFQs7wJ8wWg3tM6NkfhAcuF4rM -tz1d2amF5bf8L6EZBGzSg8sgZjeXfPe89Vop -tz1V4iAHr7fgBy1JkhUHbL8VXozWf1rSMxRE -tz1bsiT9d14TU7sd1wSAWV5EQV1WkXKSR8V6 -tz1YTB4e4frwoJdfEDg2FWF2vvdJuLV9VvYc -tz1dJhmFCGmXva2czAoi729ZphrdSm6onQmM -tz1PZknrSf164G3fdBQFygAcmTyUAKK9JTD3 -tz1TWqqq8vKKkYdfJWey7qUaHw6XxrTEv2Qn -tz1W1Yacs64Jheew3YWp6SBYKps16bz3kLFG -tz1daUTuSXVJKNFLzi7BWJQ5CnmcLNqkYRgP -tz1VhPSJ7PiQaB817EXXhuRDJcYU6LxE5mpi -tz1WPvrUmujf5ks27igoRyXdwTqwr1E6TrSV -tz1TvtnTQ37CEN9ab41dswY1DTiFEjTLDQjy -tz1dgiZQzgr3WAwBsbfWf85V8gxf4wGUnpHy -tz1UizYsmwvfJpQ4eVu6UfzdhFaPyPDMNs98 -tz1UgQvLCC8ZQ1LeZEopui8uXf6AAEpCRbzM -tz1RLjHMnHsBkymgH5PpoiFoF9ZPaqnNYrB9 -tz1fd7rpxfbsfRTfQj5XMmQjyVxQS5jQKMTo -tz1WoEXkCxbfiZ8dGFZJaeuCC71NfCP6TQpi -tz1P6zGG5L3wv2E2LELFaS6qqjQ13eRkVGZy -tz1PnT5zWxQNp14ZcgZQjzWJi3w7oTfHbnvz -tz1fuK4TksUdcxNZXn9Zmhkhhk8bz4ah2xhJ -tz1WFcFf3dBASgyVYXBrzW84tNZXm9kj5LXY -tz1TT2CWdHCioR9Ftrja9qCwyV7v3ax1PHmu -tz1fFdQJkoRZBTonCXXs1UgJrvJhp23D2hzJ -tz1WeZLByjmrbS3eAVQZxaGsQTYq7EHEx7pt -tz1TCeumch5SeRMjtvbrDWR8YN8hxhj6ncTy -tz1bA9PqVuThBrAVSecL2v5vgPMCdFVRngGr -tz1gNsndzLFyUjgUb48MWVCxSFfVvMHkawKN -tz1LNkbLGsZ3E7cPsp5iooVRbfKfGseXYWkv -tz1ZEXDKtWEo6GJrq6JCFQMa6SgsXqBB4D5h -tz1cfRsKu6mHLYFgmzKQhX2u1Sa8dv94pxtz -tz2TULJ1MyFyEw3MZxa6LmQqimMKGT6Mu2Ex -tz1cG5GD8eQqfeYoU7GBRgN95ML6Nz4P51nh -tz1eZEom4SLaYKKTCt5C5CeTAxrc7gpfBr6J -tz1ZaW4XpLMadcmGCkk2bLL1rTz5T5zhCmGx -tz1cSmWe7zgfSUHyLgNe6BGPd1wWuYUCYLA7 -tz1dxyvxPmLKDmRJxU8bmvfqABQYPYnWT3hi -tz1g6EjLUZ2Ren3cUvTp9d1TT2kMUm7ABYXR -tz1TAK1CFdQeBxtqDUYJTttbyntryAhesLJK -tz1YXwxLW1FHmcdRKTUapj7cXKJ1JZtMsGQV -tz1hVNW2oRyQjcbt1zryhvGdmDeKPnzFcsmJ -tz1boBsoXSPG6ruRnex9vrGwkh5PiUutyAoa -tz1fnjapDpx7T3SWmqiA3sb1oqiQ5sszrXSs -tz1TKQdQ2oxA8SUtYmc3yqBx2NXvDUTKypUP -tz1UwWvUgn8r3dXHSCEyStPLA62EzGPZbLnx -tz1X3suXmdz3ooRyK9jYRLfAsMdRh2SLzgrT -tz1fkELKp9QAw9ihZhvtZ2pJoeDqFWP8pN2S -tz1bj8dQ3NEBafpegQanFy43wNjBqmAoEVpA -tz1cANrq44NaBCcGUCAWkN7AtLujzDceNTdY -tz1M2h2hPZzov29kf7xcHXrunXb2jFSbfiNd -tz1gky3H2GMKWPQihvaVNFy7D2G49W4NvHA3 -tz1Zi77c7VCp7wcShSVXSMruEcffDdHVRLjV -tz1hqNAJtnChS2CNkPEhz24DrVBfJWK7WD5b -tz1XQzZP2WqQoBgZykbhuZqQyknqbuQCx6xr -tz1T1d9A9p2FdmTb7EbbY8FsE6sG3JdgfDZh -tz1QCxvnTWJCriWCkAMnAgc1qok24quJ43zP -tz1Vf8EVuabdYWD47ye7EVhW1cB4rxzHJ8t3 -tz1ZE2SZSDEAxKmuuG1xGdi26ZYu58UZQzFg -tz1iEi9qbHptR3p3H5Lx6aneFDwEUsFy3zvU -tz1eNVtmYZJWkbxGnZEWo978URLoXS9QpXbK -tz1N4xd2xhoSqujS1iof8PgsGrt7CwTjmpNk -tz1KgefQipAoXy8HyqeJRnFmaXbjvSTLNaBL -tz1hM2y6zfFmqdxSTWbd9AQsrwFkxjQbiLaG -tz1WJiJWuB19hepHzZLbRUo4EPhimKRXwcix -tz1UyVFUZSbgCYxzdqPitXZ3ZAUQaxnft72e -tz1RZtUhQNSazfsox8XKF6dng2TLph1WVg99 -tz1YyXA1kfveB28aDSNcRsLZ9t9iv9k8CmXP -tz1hMkcTRoxKcWhtShoLTAGxTGsUhsa2g2zJ -tz1Yygyd7BHzZPTWPr7GGHfZafyE6pR6dWgY -tz1dLP6S6NWUAAyhS8r1qWHcca6RP2yLr6eB -tz1bxs4AigxMyM6WKQJH2u3Wh1yBkoSihWh1 -tz1NLWGuYUSCSv8gE2xn6uYFLnM2bs9kBzb7 -tz1V3DUHuyQP7Jws1se4Q1W2tj4GJo7w8fjX -tz1Vu9BTLJ9XoZ6QHGjyEHGxhscHSeCp4J88 -tz1bDDzctmyK7toxPdscnfp7jHsB6E1DJUyN -tz1WdKAaKFPmG5gcxgk4kGXM3jAVPNiuQoDH -tz1hAVJUDC4UCSgYSrnrrUuwG7eMsc9Eej8f -tz1WynuZgbQmZefU4VhtKKFsxEwWPm2RnrEp -tz1cducMhvGQ5P4VCqTArpxv2pHunWvNch4K -tz1SeJC5KneGKd7V4mjcSM5y7BUnozQX2j8s -tz1iLWq8dSQhoyEbPZzXE6ZqSX4xDwPbEqiQ -tz1YYh6KtsEHp8RwtA2aCeSz6jxKWM67VCKV -tz1KxpsZdoUAJVhmhHWUQdD4w8NoHznQPzxR -tz1a9mbq6RJAUjJQ3MEfmximb36csSoyhsPU -tz1TUiAUqhQVjH4nVGkk261c3NCBsAH1RrY1 -tz1aCgzWHtcM2oGLTbvaq7Ag3PP4sqweGeoF -tz1hGR2wdKRUsDhVZ2jzWhN2Yesogt2o7gdp -tz1NBpmRyvHiwqzkQ8VjZDvmPGXko3HgJ2sZ -tz1XsZkYFd68UBfhMSX3VsRdVWQk15wKHwkf -tz1fpzEzHWuyjVnrePrQMgApXWxFQE7f3opw -tz1SfppBXmJpi59gCKvJdEq3DE5Kc9fQnvdf -tz1iBGcDYQjbfpkNfme2mwYGS3hMY41G5Q5y -tz1WWZQEqmWTgekbEUBfR3UwtLi6BXVD59xN -tz1ZaLgcr4YA59Vdghk6pGQxgjDYBroi7RCj -tz1LEvu8ewQRWhD1H2wi31m9t5AL4rbngvF3 -tz1cvhkDgksSk5dbiYETZhKgbXpFW8bewu4j -tz1RknZap48Hv1GJrDy18bJmyuWQjzA1xNgF -tz1PQ4NaQ3HJQocuV2NisNhiMEJieDAiE9cT -tz1gtdaRWGHjcYTpzKinMivt4mD8J8PmB6Rb -tz1iLhZmKyBbd6n8s1X7HrBgWYYVpUnGDRGk -tz1aQr2Giz7WNRoQPFvi812bAqfyrxsSoXBa -tz1Q3ijeiGpqQZCQ6gCbcFk6dh9tnthQhCKd -tz1LwGNurwTMW3iEo9hp2GZYtTRR19nwmXE1 -tz1N2H1oCehwxAnERSRhU8B4qg6zgaM7ZbBe -tz1cFrk2sDHzJogC8qCCpJqP2JBgfCMuLxg2 -tz1cj9oAELp1mStyHkwy1vFrH6N99Uk3TPkH -tz1gfyC3nUDPcYK5DVTVsoaKMaJceHPv7hJr -tz1WHAB3e11cj8ZW7vTXrG8Js2JhBuqusAnT -tz1Xz6JBkMgMHx1ey8MfsEqgxexh3pbJeFPQ -tz1ShicJeKQnACA67X1escBrnE636soToQaG -tz1THtmEkiv9aQibVqFgvDCWGQumLrh8FbS2 -tz1U7eKLpviunTX2zjNfWjcMXqmckXj5ovEq -tz1Ma1DpqxXt9gC46znbQctVuCisDZmtbv3o -tz1MZePd372iBF3zxZiqfAgFQj8mWcLe9wqM -tz1TAqcWVtejBqrAdcew67Q4Jpbf6wBYKzNg -tz1ShbQCoRHwQ3FU23TiKrNoT1QAkuVk2PJq -tz1NKga32xbX54HhVn41pAMRen6tM5uyNw4E -tz1f74zuYvbhfK3vuwHZWMT9fFvRqDiV8mqu -tz1Q7KpVgAjZiWRxxpfN5wtnJJys3FHi4JWV -tz1XLjsE1QptorFX2hA9wfpd391QJDeAJWpo -tz1MDK5LJJZqLu5JBKirwfHSiyRYrFj9r3Hv -tz1eXJWhKdbYZ8W6mftwE8Dws34A2xdYJCFY -tz1Wr1KNZHWevCKodxBeRBQNgAcqkC5C82Cm -tz1dcmd1BRhFv3jNSqRGQftP38a6Gxjw71Z9 -tz1Y7cYM2HNdyGbMDwCujBm8ArMeSSvHZHuj -tz1bvWnVWL31myzNEUWyinCq5rUe44gxZvWn -tz1VAjhc1gEHzVXbiBsVEye4UHTggW7gsyve -tz1Z7s1Q2Cm94ExNoLoVCkRyvFESReQc32ES -tz1UKie8ystmAXbo4Vsm3hT6QXmvdGNwHrsf -tz1emAkutW4waaUAhz7T4bFeY4wn246pUcBS -tz1Q4ZbnsAxtfpEYzagDFvHXeMfD5X4xWE6Y -tz1a3Gs9whDXUAVzKSbJ3abYaEUxhQm1wdb1 -tz1UtUWvDL7c7e96yPEBbbgLLzamqJwUjKws -tz1Tzt8ucYL8wFJD8zZixn2HStvkkwJkemgZ -tz1crqThmJLnkpfcVbqzTcuGUpzNVAJnAx6g -tz1SSNUCwNtVuYrnT1ovvhgt6hxb78cV4fMD -tz1LXtHjVLE8MkXHn7nLEZFbUJ7CLqeHSQtA -tz1cqJLHV3Vuh6ha3wPVVQdAi1urSH6ZWcig -tz1fv3KPK3m6L4d5Xfvk8MQgDdbX38gowvou -tz1NKMsPeMvYsdMjnDCGv296zUwtyMN2K9wu -tz1WgXjBRqk6BsEGt4cR44LgNQMo3J1FkA5X -tz1esmWUGABrCpZTtHecGGBiGbrCawqCJy82 -tz1eMsxQmKsRMi4NS2XHobPycHBubauR4Am3 -tz1Uyfpo4Bwox7CQXMEgthVVjrqiV9vz75uk -tz1XFmgLTxd1QtP5ZJh8UAHmR9XWANBB4Yrw -tz1iNBAc9qe2nDUetEZeMU9kfm3zkecDtXTh -tz1RkwhWujqSVYjsmd9JHEonYfyyKra2hTDU -tz1PrEm4qYLBGmYHdGq784ba9ZHVnHYQjabc -tz1gqSs8JXqkcSdcHJfBs5c9zPuzrWamd8M8 -tz1c2awAoyJf8SbWV5DtShCwpqejFqQdLPf8 -tz1VMo1LDXtiSgZGFfxsynNEr1Gi3k2APWgb -tz1bwH62gsFtrUGiaBo58PmovDLkzehg7VHH -tz1UNTYHEWdZ2aCVyG7cxEpM41C316zdEXpY -tz1RzLJwG34X6LJxsGJYojVQJVY8S1JG5CMQ -tz1QmKFZiGxH4XNU8vR3gM1siS4qDHt6jpCu -tz1RnZCX9jqNPYijAREAzfeegr4skVW76EYr -tz1bPBbqVesGujkNGBkLaESAYCMh1RYqPQWY -tz1cqLYGRhZJdhGUjysebUUP7xfAeSGcyLK3 -tz1W5JuctEY1HCUAefR1P5u8h5AgTQCzr7cV -tz1YPCK2iRxWZYHxeUtKBKRosdQ1SAHKeACe -tz1cDvrnuT3Gr5gz1jykJw34UCJ8YJsp7UUF -tz1RyBkcDFWhCnTWh1XhYE3cHaJr6brB2VS8 -tz1NfmdwTJfGDq76iqQANcKhv9KY2FNrTGw4 -tz1TFRjyG9jyucGPRY3aT2EkBoaQ6Rz6jpyv -tz1SrmE9ZrLCEuMLimvD8uUqbsiSGfg4dVgf -tz1UgcnZMDM3MLkpqc1oAtkGXbdCqhtqE4dy -tz1YoinhByHLo7na7G1yCnxarzewqLcvDmZ8 -tz1fuHcB7NK2L4RLdQkftC6ax9zxUJJWiPj8 -tz1XfFRcF6fzaZt4xDa6GzLQuAouxYcje6bq -tz1fG3NZGmag88bfnWKtBkK2qMhdkogeMvPQ -tz1aApRvwXFF9zzysxFua5pWgyD1hk2ap7b7 -tz1NnCmJQU77QMN871Bz7Hq45w3fmpaCavCj -tz1f8iG3EC1ZCyvgBpgchgbSesRCWgSNBHf3 -tz1aRy529kBZ4BsVUWzZ521sRwFhknGb4cPt -tz1M6pCPVhu4MaV4eS9MYGNWJgvDUkMiUSvN -tz1VDYDYhB5niW9u7hPUVzXmyTzQy35mZ7US -tz1UdGMYXWZBxStK1ULVAtVSB8CUcu92TFcq -tz1hygv1tWC5EMv7o9j7XeJVLJ4XvHx3Ny8W -tz1cN3q7gqU4eSm7QEetiCG8v5FMUxMVcaSz -tz1YRPHwQ7Y32RQhTeatZCgHskayuwvEgDDj -tz1ZFqeV5L582Mzrf1EkAGEgqNfY39JTPpt7 -tz1fnczkLvt5AvEuAuU1GejvozUHMCdvtHoz -tz1a1yqjsovNajXW7om5TBf4V3Kewsxuf6St -tz1bqQBbyZJKey9e1M3j7u2NJRk6honwta4E -tz1aBj2VFRo6HmD6t55qyuo8wYWwCaWwCjmK -tz1aabo5tD2uj1f37R2zGsfGhQzDgZTzJ9pS -tz1KgTpDjSEG6MPiFeii8XqBj2VRrx6vJc7C -tz1erjq72DX983TEX7em47jdcHcPU2z1RZTA -tz1aWLPsgRsjyDbitbisqeSpmoGUm4rMB8SH -tz1V8dYr6SGMdtMaDcvmBm2VJraPMbxi1GZj -tz1hvysVUSdmb7aWQM4FYPUqPQFsHGoim4wm -tz1Qpc3oQcBxMxfVr9iKuk32gS8e9n73Sedq -tz1RUdHwZh8BgDJm4ixthGQUF7ZvpcoMTrcn -tz1U2D1dE8JCUGKzB6aqqCpqjCdx6ucdGB4p -tz1h57Jt6MHJPdpHUWJUpTSNahVSrMPpkr9N -tz1eE6TqmrCkqdDwtw54f8uTExwNU3xj1Z1A -tz1MqtcyiuHsALSkrNWq3GZCm1pEdoZqTGzm -tz1aZgPqmGAFBtv8uuFUegfmC7pj7MvpVU3f -tz1QyJx9GBLF8SCd925pbjByYdmW9zN6dD6u -tz1RM2LYuV9JJTvzrtYgRK64gXYuf7TePFaN -tz1NzG1BFosctLRbNYifzA2jJCdRB7n8SxCH -tz1bRmdT4th1jXLeMdYLi8ptLrfjt6ffZ7sT -tz1f5ex7Bkdvr8SxteQz8xeSRHeB1TYnJSxs -tz1UFR8J7PuGRkFSFVcQjox2VziYsvFm9cdQ -tz1StCFLnaRWbVFKrzcDqMwtRuruRfukfGAG -tz1UW3eCqJXtx53pQYg9moWfizJW2FEUutg8 -tz1RavboLoxm9qDVjLgM8fW1cfbLPEQumVeb -tz1MUfkMyXwpr9kQGx6fk6WadoD4xtFsGDjY -tz1SjCqXwDvktEPSA1t5AFBuUq1ifZ3pKq25 -tz1eYryBhcC9jHdfQbqqsZctXV7AqMribA2q -tz1Ww6g57pBbyshtGDELRQzfrQsAEZbLaTYf -tz1UMGgYzMxAc31KjNE6SaDhQ85MzK6yvXbd -tz1NA74UquSdQuqdvjETymPYma98BaFUWSsB -tz1iv5Lfsu7V9tfacbeUVNSkBVYwj679qZ78 -tz1XEP5uMesMEK3EaB6ZRnEn3i4FFWFRxjzj -tz1gaR117vE7mNZ74fNi5gUb6k2rBS6vNbLQ -tz1gUhjdnbDvJcY3ocnrm8cz51sbVuSyfFgh -tz1Z7Ze1X5c7irpRgZ45wZunCDpZAXSW5Q3T -tz1apZBcnrVTxdui77sV32J23WUm22RXbUUF -tz1Ya5cZFQRc3w8zkqSuie7T2gKd3xYxteBE -tz1QisJNrLJrZRSeF5EoR6Mq3yNn4JQu2QGp -tz1UXsSRMJ7VepwTcbQhMf3hPttiQA1BqZgs -tz1VYW9fN3rc9pQ9KFXKV5YLRF3v9s7hE8oQ -tz1grjVRWGtENWapT6ykjVixiQXKYQ8LTH6W -tz1cUeGopiq8iDfLUcMrFFPVqzdDTPppnn7K -tz1ZgXiGLiWWQmTuXSbpPRLrYLHtzfpDQPQ9 -tz1bD7aRCWcdfhyCvXV7wQBwPfJs1y8CmArf -tz1V3HCSbL28o8ZmPyiYSaVQbkp8k7WjPNdH -tz1gGPep6kKpNSafKmFqbPm6TxJ73nxh2ZAN -tz1MDPQF342kQ31pnaeAZXzKHiNVVojSZQ1C -tz1Wb5Uftj2XNX2wDn6jaKUpziRTVtjrPjeG -tz1PCcgvK888QFji8mANzqwzkJkZvkSFzL3x -tz1b5rXctGtVA6VS2yS6MhhiQPFiS1tgZC9k -tz1VSYZ7Dc6MzZ5ZucDdruFuRdDRVEy7VdHZ -tz1h4jyHQqxe7zn8y4wnc1Tam8ksgzM2LGyH -tz1Z1dXEhr7AmkacF3o662D9S4wPKkeJaoKZ -tz1VjgxZTPrZ4M4g1fjQEfKe3T4RHVqu3nj7 -tz1NYtvbDMfWf4ampUf1fHkFVmPyvir8wkUk -tz1ddzG9oHE9H4v5vZpsEtSuJsvsCaU5kBJe -tz1MJ1BJ8vuPxJxsraFPvSbT4Ukzb5xWfCrj -tz1fYrXQEmiVDtb5FFNjyqaAnRkEw2EPvrXm -tz1QLQ6HQ2Bof2n5YyL3p7anduTEBADqU6nz -tz1d6TEuv7q8QmJnrimN7FNPsvHgaabAZPJ6 -tz1RvPjgVDie53FuCFGo9oDcmovipMeEFevU -tz1ZJTgSxBbFcLonCSWcBeDy2gR2UtYAPApb -tz1bt1CEsWuz9JZucHHSLdhuc4zBZ3XnXDY6 -tz1Kko4NdzKGbiNWoz662Y55gU76iWnaDFBK -tz1TacGNK5XQXWHgCrrx4ocwoBCMzVBJ7ArK -tz1QPYdJ7i6j3YHWBSSe7j7MWRJWPUT82HDQ -tz1KfiqVDAjJSEmRPSAb4sEvCYqggpBgrmZi -tz1Ro4tzs1fVhH2AVadLJETJEFP5vZr1QdmB -tz1My6W3y9VQmb1TBXAhs47dpQiZfgtdz2fL -tz1aE96xFUu8WDEB37YDq8mb9c27GnjBxY16 -tz1Kou3ZBz7Fk4aFg9w6TymKPAJNmZja3Qqr -tz1LgarKhWcYKAvFbtukDrzUfpsBefRWcSmM -tz1WCRECye7aXJwAwGJXKjvKyFBELCmjSm9c -tz1arawntzwUD86MEpMj9fh9Wxa2jM8wr12T -tz1PNDrrkiKpf2qFrUFSseeShuErAxobkBib -tz1TgH4yYT2U5Y1N6i3q14isAreUY4titYAu -tz1fMVvMPFhHkjbaLDudwXE5AXtPu7VCEztJ -tz1V4TWNrt2sBwaXLt8eBbduNPcZiMSu693B -tz1LWQcNUdYiVYuz5nhNBL31qAEKjWzJfy5Q -tz1YpTc52oco8j8hcXr8PL2ovmYjmsAq6JJi -tz1TjDuw1E5hbhVApsxx15uBPBuzw549afUe -tz1QC15Mdv2ukSPipRT9ruqLKsuUusDyYtos -tz1fzEEQQS8oiHgHFshqnqtg9WK9xsjrZLdC -tz1VeCaipZmqPctkMS5B7AGE82BLyvMYNogd -tz1U4amYawm8VP4X7Fj7cVYmpdyqAYv3Jq84 -tz1fGXNZcnXnQ5Lx5sz4CKWwKp26HSR64FnH -tz1YVbKoyKDp79Bnf1tw9oKJkL4R28CuEmj7 -tz1hCj8byHaJguwtY7rsY8MfoFtg4xapvgiC -tz1MsUzMWw2CLraqEUQfb669tG95UNFn5sjE -tz1VwyQsbyajcEdQKLEhNPWrWESQhQzd6fgX -tz1PQ4WyG4VPXNGWYgbJPdq3gpnZ9X7gHcHq -tz1fejjZ85pSnH66NGWmUZVm64jYpXvGTBpu -tz1UuFZoeDHk9wBZEsh5sWWL65o1nBNPCf88 -tz1aaTqNS144EBQLYQeBHJszDBRfVcHGWqvN -tz1UqZ5ep5a4C55EEgqzh3avtZPpUpn4C4QG -tz1btuHq85G7CmD3fqJ9GhQPQRJv2SFjPTZA -tz1Q6txYMozXnixq6bg6Az9NfMWHD3b8BbnT -tz1ZxB7U8ovLQqeEq7iQ4mZ8kgvc5GepbbaN -tz1UwqwPwBPoiXTriJUkBNSgtVdHhGXSKwDQ -tz1huY3Wxsabwk7zKAZEQXfVG9dkPK4vTLTg -tz1XMTwXofFof3WzNYtG1k4bTp6WRe6mdpEM -tz1aa8Qse6SjiKiWfox2jHxiiesftdAtL4Ku -tz1gQY51VP82Rf4BowbXvX2zAUzu42vghyJZ -tz1fWEycshiA1Cxm6GWUfSd8rjttWBTzrCvm -tz1aCDaCxPHTzzHbS9gPeqG3gdjjFCcAMmVT -tz1LoESMWDhK3gHpzVYQUa5YjQLzY8Lxgstw -tz1aKoJXaa5M8D4VL7dh3sCa9whrR5VHbXeB -tz1SsjMd48YS1SgpGMeQLCRTNR4wRbsFYx4s -tz1QFyPVsHSwdHSHDVfKciaxMEyqAnoXPW2K -tz1ewQDvT2i8EbTaAFRRsFFRdz2F4B9GJaAw -tz1UzGV8fAVod7wGknjqwbr7ZBRTjSiSoEs9 -tz1aUcuMiWoDGcFWo6tq99fQy3r58GvAR2Qk -tz1YEiqiXwymMELSsGN3JdtwwrZE1Z3s5oY1 -tz1T5YVQKKiomV5y7NmBdZK12EKAwb5HqqiS -tz1S5TEPPejMCZ3sXY3PELoj6j49gkmDxvGN -tz1cBohQokjgUwEEsou8zrSeM7t6HpkR3pf7 -tz1VZFSAVNmqknJ1a5NTXaKLRb7eG84FGkYS -tz1fNr6NFqwdXmMVemERsY7RPS5cvaDboXhv -tz1bJbxMqyeq9TqkFZCUbLYDudFSPoR3a4Ug -tz1QUjUph8ZLhSoEbXwBFkLxw1aJ4Dz3vVYE -tz1KxCU3drChzFmnWQBdTVQkBz6ySuWFxPWs -tz1YVyGDQ9zjDBqQsPptgRb2jiCtVeLU3jtj -tz1YWtbaP9ioiC9PnFreeptXCjFv38iQ3SHN -tz1PS2f5hW13dGAsB13yYYC5Sdr2PAcE6zLE -tz1evrVPGF78NL8TDvU21GMYaFJqBCBoK7db -tz1R5UiZ2MMF5PSYcbhubstiAKsDJtwmYeZi -tz1XD8xfBAdo4xdSRqu7TTEqFBg3tA6K7CW3 -tz1SgqZsYGNvsKQ9SLDQasBoqKd7YcJJjVgx -tz1PEfV2534oN17eNUotupoFq1HoGkkbak3t -tz1hVvsm3qGc2T3TzwYc72XCUyEsqKmgsS8F -tz1bYMvHUApZgEP5htrH1ESiC53yeTph4HxW -tz1LVKPwjosLwytE4UtRZ1uKdLiDcLzbnxah -tz1XSXtyTD2VH77SdwDPVXqdRxQR3GMqjcP4 -tz1YEhjrUg5HfZMT7HngKMSFRWqeeapqPfxd -tz1X3FGKR7VLm6syevw3tr632EnoAm562vXb -tz1hSkXsNAvsnn82PSW2H39CfdzYghts2koF -tz1XvTwQbkbySCzYu3FQ63CUMVdRnjXX8zRh -tz1MV5C6YJ4tSVX63QzA6PeaUzuUv5Ptgv1Q -tz1dL1ruAn76qXZZfHhNp8qYQLUU4WsfkXFQ -tz1RZvMkYBNHJatppYwVhGugBo1aMoeXV1fa -tz1QKC2cuerZE5kGCtkcobUw2ZpfQwtekn6p -tz1PirYyrpwDrSipQfSKj7tkQ6vcoe98dZhT -tz1PwYhSrEvrqrhRzwixAoAz5EUozSZJwggP -tz1WCQuvweEtSRLt3xq8fRQJHFSohsN5QNmU -tz1V7qeDktymTAD5pm4zaib7b6f2SGXShWK9 -tz1e62usdNmgHvjjnkgQx8w3RgPiB9ZtGpWr -tz1i1iDMoFXwk6sCJrzrUvpY7Bfb4aoEeVXT -tz1VnhYVGaBKDSpDFePBNTpMLUdYJvS92a6y -tz1XDd3ypmcimHLJqBf1NJr3XYbF5GMHdhzg -tz1UmDzo13ag8AweeKPyqkuHWtkWAv6vzbdc -tz1fNVS4g5Hu7S1xw8wBb9UujbztU7J1PTTy -tz1gHdU1ANF4y25LsyQJ7XidgtLt9GFbCrGd -tz1ZBH5ndXwEPRtDjQj7VndVa1fLAyv8QyTQ -tz1VwGTSEdECdEkdQKRDhf4HMCZSoE8nkHHr -tz1ej5qngc83XrvpvuHS3bLdyx7cHNiEQ18m -tz1QB91TxbiaipLVX5mPVm2MccnhUgzeXN3x -tz1ffsfifhYsFNRYNMQnbj8ijowcfGS8R1UM -tz1YKjCnViXp8JM4mBp76MVh9TDJs9PvN728 -tz1iYF7wRfM7KUBULyzPXWyv2pm2jSXAhVeh -tz1QLUYgKmWHaopRBCyUiuhYiTUpfHPqon9U -tz1XW4wygUYrLYXyciGph2hsi43EAGxMC6Bm -tz1NWviCWRVX9vRdQPf8iBPdB7u81WfFpco3 -tz1XoTfuCHEc9CC18KyJsSUgcm3pG8wByGzC -tz1McCuJktHBcogWtHxN8AtNA81FzYaQUPTs -tz1Q57qXVXBDJePnegB9WFqEDBbHrzPTnpoP -tz1VeHe8ecfj5EGkLzRvdfQAXxhFq81pLKPV -tz1W8HbPYgU6R7y9Hf1tKpyfykFu44fkpPbR -tz1PL9VDMANdVR5z9aSJuJzW4xoXPEu4vqaq -tz1RhUTxaKqwYGyMpCQdSBnQZRpfGrQyUV1g -tz1aDZxRLYjffJNue1NjEybmPSGbifDYqHYa -tz1gzhvZ52PW7UR9CXECvesNg8T7pPqUiQN2 -tz1f7nyNQQ3mvHt38QNoocnQBdCqcLuLfH4A -tz1hD3or6BsbMAhPNBxPLTdY6gR9xNtQZauK -tz1VakJRNyRiuXCP92EdiQCKDsngKx1dtnVA -tz1RfyD2dwDoPRfyQ9LJtrUzGNmD5rEjU5He -tz1TrMVHG6riwQCHoavtCcrZnon6XrmN6Cwz -tz1TxfzCR2KfPnUxz47s9DvzsTAWQkcEC85z -tz1QrgJ5pnm5bRuecpmXnFhqWKNjaN66BJh9 -tz1d415d1B4Rx45MdnjCMsH16jMRCxznA51T -tz1R7FAiRWu1FwqHbb87HWDT76GAhP9d5BSJ -tz1WvY26YAKCDxivnkt93ygmGjftQdzunEhy -tz1aH65UDizgRfzwZ3Q4eEqGTHgRvxjB6Bie -tz1haC6eieXdThyGiaxZsBH5T7nTQa2xSvf4 -tz1PNHfq2tvyNRu3zKCtTxZkgxHEmtPYWfV7 -tz1Zx2a4DKFr3NweJrJguGU6Ut3oGMEnPkxJ -tz1QfMx7eFBBj6WMmrTwNBJYDtLCDPKQZ8xs -tz1Wnk8NqhKhdZV2KzLybj4mJ8qyoYSJTJsx -tz1cBuEg3DuNFiab5mQE6B18eKLtn32PvHDP -tz1YKVxWuKUWfn5Zs1sZR9geLrQPt59xJe1F -tz1NNmMNQ5rzdP1ZnkbDUErRRfB6PDiyXKhM -tz1ivN9ijwRM9TNiNqhiJP67dAeteR7mtjky -tz1QaaMnfrXphPq6Wkwb9xV5cuCVW6fr2hJQ -tz1Rv1hAVF2EP9nKeMBPaaJ8GgRUwn4SynWp -tz1WzxfeGeD6cmatu4P4DTH9vLpv3axY2mwM -tz1YuHve3rV1MN49Nwn3hbdTaYNthF4XqhS3 -tz1eKsvd2G7QXsJvim5ZBYhxnuN7SJLe2phy -tz1gTexLTqUrYTNYfaLaqmGk3uobMMPqoSK3 -tz1YBZjx531sq7X2edTEcZwAncpo9UEXRcQV -tz1QW4UzeHUSqfAmRoQEcWj1zEgpNtznBRRL -tz1NsCungR8saBo2dszAYadVxJdPgkWooHYy -tz1R4GvidRDpLQvCUN2728kfVPV4u2AwvF9w -tz1aQEHKFVauxJqMgLYtvWBvbkUgHLkhoELN -tz1VLexhKGSGofvuVhPtr95h3yY47LUotueu -tz1akzbqFSAENSdS3iAFoAaM4pMQBuwgoFtT -tz1VPh7Dd9vgb7beEUKfyxzzEC2xGA54yboC -tz1VpTbpkXCULEV4UPSTC8WVPDqwtRmXjPnt -tz1dCtvMcY7HJ9hw7icDYFrjy3JJGtKdxHeb -tz1iUq4Fa8aFjzRfCjq7gyXsMPjKDDtxxGke -tz1XFxafBv1kQmteUEFswhqrBjLn48AfwBbt -tz1NFNE3oUnJoczh1PXP5SS2rM2N1frXXETw -tz1cfAG1z7mFFsvnKdYFfA8ecm3tXYELCPPN -tz1WvsDPvJsUuhXsy7Nn25Qk4DDG4ddMnhXc -tz1TfM1eVqddmzVpXG4p6HnFWPncH98g1g8K -tz1cN7NeXnFtAJZXCvEGeudPWYTNaWVuVr4Z -tz1fNGELxa86oNhcnpJcLyN1MyqLX56wGZ2D -tz1KhZ2m6mmaEchbCZNSjBxspc9qhakL9iKW -tz1UJbPmMuQ3HdaS6PaYxPbp5q9BZQ1u4qE1 -tz1TFACFZnfhg6BQ1PR47ZjJfy7mshozopRD -tz1RRH8bkhduw799JfAg92Z9UBp4H4DcNfFk -tz1geMKQP4eGPz94h1s2TRmFuuuQpX5Rpejf -tz1Yvv2tUA7xs9HZzq5tfsHbafoQPyHY5BRr -tz1hFYh2qesy4AVC6YFYXUkk4qVb9DgUF6jQ -tz1afteZjbfccCDe869xv35x8iPWTqf52TWu -tz1YneEsfwseYFSBDWhmwsAMkM3qjSQNxE1i -tz1Ky8JcgTKSbB4j7DQ5XpEgiqhWKBzhnKsW -tz1fxtdnV3FXtVjC5NBKy5kVyevmN4EERD1g -tz1NLktK4VVXB95dgiN19YSaN9Htd1Mku7QE -tz1RZvBouF1aVVNWd3vgFd7XcsLJpLsjmRo1 -tz1WnvQDmZETdQ6NRPrRE7ABaQ1MnjY4TFDN -tz1bwEStFBppeae1JamodD9iKhre33i8MxaB -tz1cSjv3DRPgfcSffmv9fe9ipJe7kmaTSxzq -tz1YV4fwPvCWbM7WYiiwubfFFUvpPTWruAyj -tz1WrvA76M6AnDnR1PiHeMjPFLopUJDcWevs -tz1dqVeSMKkcSnb9PrMTw1gY6UmZRCHnspMP -tz1h8wacf9hHzkxDHvDTayXsdgaess1jxAFN -tz1ibCnrjHsPq6hfuKyweZpKMgyNF6SRFYcV -tz1W4qY68UYBJqoftYFDSwzjpePx7ak8kcqK -tz1XVTMzsbD3xuQTYn1DX3TteAQxMzAnGCSP -tz1aG7J8ouA1LZi1sAYcwZWbctFRNuSNyRXj -tz1ajkUPpZ3syk5j3hqeMavm2cqo9HBLMukf -tz1XJ6X8eTviifJSTQJb1TTEJTU48Aby8nkA -tz1YG142gmiv8sknA4LBqsnnRQgze69DeQkv -tz1X4gS8YNHCSm9g86FKnhrz34HvRwpSQdBb -tz1NTk2gcNv1sTNQKt3Y3fyasEsftkcdjrcN -tz1incoaMURb3zkD87i8ESY2kzuyUUGjDie5 -tz1YTEbvA9K1tZp7W6LwXSxtBcBY38YxB1Si -tz1fyzYPJzG9VFGR7ksvKjmCjXh4Wyq1YS5U -tz1Y6sKBmm5Asf9Bz4iSvFj8GU1ta2t5ygiN -tz1NZfPPJz72w9Cuqy6X7FHC9gV3Hi1opoVY -tz1MZd5BNe84UJUHCuWdgZUusav2JAauo1LG -tz1XjD8QdSTY5zNN9BU2g4Xsvh2H7juPh5D3 -tz1RRtaPZmEWiSREAJ9XbBoD5jvnDs2spQLE -tz1fsYkTUducup2TQ7SqfJ8U71seWAKDWuVa -tz1gk78bJLLKz2pp1e2miPm6Ls2yQGyzAw8Y -tz1XrhZNqJaxA6H2MZj3wRw1wFSTZQMWuaKe -tz1TRhQk9igfRA5biD9MeFcTrn8WahkCsyjG -tz1dat74ZYFSVC51gtxGFFGp8M28hfTJsCmP -tz1UPAoxpcDpSkyLyZr5m9N4r7arWw2kYuQU -tz1Ptoe6zXE4nZKcUYyY6QujPwZzWwvd2NZc -tz1bTYRXt8LAVwjJJd72Rm1askKZkxWU5wMJ -tz1eNyn6ac5Esfs35UaJomVFDrH6ZbbD3q7z -tz1ZTMgW66HqKN1TRbo5fSFeAo6uULiGZGKP -tz1eJjXFUGvccy8fBg3cgP3KuT1RSAet38dj -tz1ZjqjfbxbKR35n2usMSv2gCDeb82M739XL -tz1hAEoiAP7UFQSqtLjr1pPkdQH3Qo2N6Rvr -tz1bkKGqA3Z95gVQAcfydnE8MLNs7CdRmrph -tz1T2zL5u5PgkxJfEtSz55Cqc9tkQvBCVioT -tz1gdTwX2akkuppYjYvaFoztdfKuBQ6GksM3 -tz1b9M8KbhiK2xFcHQ46tZWqYspC8NZqoCTS -tz1adKHw7SwMMSQzKoc8bXx6Xu64Ksw59hao -tz1LwFhDmnCawb5NBmzYwciuEcEmxep2fbY1 -tz1ZFWqRFs4XWNwFdaCf2s3jMMDnxx2eLczo -tz1dYMibw8L8QqbRGtXa652pj6iPJ6HmDjgd -tz1LewbaxuqBVyCqW1fqfu3MJLXqqbcALCXE -tz1iYtKcY5vxyeDp1JziEeN2Y1mrYQSbYi8v -tz1gY3RqSF8P5dYa2a8QWiHRkZdZtUGC8VzD -tz1ci24j6wEn9ydFHrKB8qmYjQqJR1gvDb5m -tz1QsuHZCBeDQyMJzPVfhHVr2ZZgJwAMX31D -tz1WnAG11tsibGzVR7AJXTsTcSnF6KZTNH3s -tz1YoQbWhUGvjbGyn6ZE6yvmmpAnjtBNTgQ6 -tz1iMexteEkuC4rRUSyA299kQRwTpfi2qxvc -tz1XBRE1e4E3w8PNbwfT4LTrWiBCYkYbFgvk -tz1UwbHJGjHh196om9XYRnR4QT3TLWEGtgKT -tz1eeaM9ZZa7GFpGifjjBmRYUWGHWYGwBkJA -tz1anqpFJsJRBD7g1cLwx5QQZ3EL3Tj9uKbd -tz1S6VSSVR9y14HsJEjxQi4eGCTUaG9V4vr2 -tz1QPXM1Coe1V1rhraikjcA9PnKWP2diVF2u -tz1Pgz2UNnBqasH4bKQ77qNMWTdPzwWEGJ15 -tz1N84NRHq9jk5G9H1yJ5piMWjo6xdLG6hkE -tz1QdEq99BBpKVokwA4jdubGFWsGQGpNACHU -tz1XvRB5UMSkvW6HSLhcvSnZ6JeaCyE7TyEg -tz1WNEywih3nbjteL6Egvy8GHCdQqTnJBijQ -tz1KqSKeHdr3CwMdmkmSqaBAmyHKDFiUBE3H -tz1MMW1ndxHXdESTFPb8n4ea85PaxLRW5pbP -tz1Lg5SiBuiE2FEFQfUNRzibxD4r3ZBqxaZF -tz1ctCVa9ggWoZr6wFFViR3zxZECA4uQGqSf -tz1hbCNCy2RRV8AbXZEK7erkqs1R7NMQC16i -tz1am1m59RrKH3Ma3FRjepHNxTqivTZE1FA7 -tz1hKqpWDZjYNoP3tUqGHyAhH7uQoU7P3NpA -tz1PcJKXhvLfKgStTYiQFv8EH5T5pDJ9jcVB -tz1WGKA5anVxP6tVmM5HdFebqpwws9uqeY1N -tz1Q15og64ECGbE4rDqU5wKygpCnQ1HA8eMu -tz1cgQAQfECg5bPASYTMyJ9QJQjSUi8rfL67 -tz1hEWs2Kgxbz5pA6LQtkVY3XiNsxMr5tc8H -tz1PW8gvkxPr3hFb5ggW1T2pnSxV1ky7LZ29 -tz1Q2dPVQKva5qyvn148GDp1di1SM84MohNk -tz1Pv4NjSheVStSrfth19qMXMzFRo3aGxNgZ -tz1aq1aC1W3MdNkRqfRW6RRrf5WJReKCuXAs -tz1Z3Jaspjyh7rYxeKPML4pavZD6m8XuFo3U -tz1eQeqBeTgw7h4qAophMSDSAMa8oQ3F7WAD -tz1Uc38Mz9pmjpfwj9W3NRrDgrjboUToSyMB -tz1Q3qbBqpoLLwCERV9nhA4qvZVq6on32mR2 -tz1ch3LKKmtc9TRerxWjwXoeKnPJcGJHuvUQ -tz1WR1zAAh4yJbQJL75Zdnw6gg86g8Am8Nud -tz1Pg2Cf1Cjv1ZKMAzUr2DphLh9N7HidyTvJ -tz1YM6FkqzaAn7LdkBFSXy54aY8LaW97SCBt -tz1cLZ4eTTBX1XY2hncLtj6Mmbn9y71xdA9m -tz1az4dSgBhDet1Vqwzt7rPzTPrWmV8pgSLY -tz1aZWdBTTgKCSo9JUQQVAt4E5uQnzcgGkau -tz1emBwYFFg2E2xvpuPmpKb3YpHwDDmkcMJ8 -tz1MQPj5RQHWWRdfeB7p31zaasToiwzRKS8z -tz1SsWa6mwShgU8ESLvjdGASwdHqwzPUxx3f -tz1XMBv41Drymz5kEspYQwnz4feoHSzeAAPN -tz1VqRpQaLsemrBWV9L6nojFCGxjiLgpCa6b -tz1eQVG5DzuG5yUjKNsdw3qFVpbR18jqeYjK -tz1Qq8r3V5yVYFMMUnEDZvqqCeKoJSr2zobA -tz1cnF2a3ncsDEtFRWVupXLPvjkwwoam3ygP -tz1WHc3Pbk6Uz7wzLkhdcbK4W4boCyrFgDZQ -tz1Uvyz14TjPXQLWtgqTFb9uhoDyonuWrdHQ -tz1bHAni81ahA9RhBtRLkRrmwCwbbtHr6DfR -tz1RERHrpHyoGnjWYEF7PNowDZPHRT544XfL -tz1QrB1ecdprvwxKEut4DvawnN1xopFDubyH -tz1cqCL41fcjEuqVPVpvvYn8rYsyj3J5TpeL -tz1LigkSRukkQf8WqWaUaAQy9di5jcyK7dtu -tz1WPJLDSZLxVpebP1G3paS9pVAuiRtgygF4 -tz1hzJukhV4Vkb27J52kw1JLFxjpbXMX8ngo -tz1PfDNoaFBjPcRgiR6uP9ZuX3Td4bG8NXds -tz1ZarqDs3TrMcKdYu9jjfgNQFuUTH8JvtU6 -tz1PkNcHYKN8FXsg7QpgEYPfZgCfdqUoMYFS -tz1Zj2MvheMbR3fRBTCb7gCPaKHRSrL2Un67 -tz1iSm1YNs7Eakd8GHVowh2cjYgcKQwakSNn -tz1XBdPurBon9CLvSpXuXheetiZJPJKrn845 -tz1M2mxY3WxN1p5o8u3fDkS8zcxp6epeC48v -tz1R5max5PEScpCardSBy54uEjrEB9Heodas -tz1cD7fK6pL6CgWWsaEh7CzD1ifWj5FEf8Zw -tz1f22VJV9CXNwuTDYxb2DpmX8S75tufjtgA -tz1TZoDbCUo19yyfNWSHjktzSoTUuw5W4BKx -tz1Ztu7GSKNc2q1fsDYaoS9M8S1Me67r2B26 -tz1bcGDu55DscNUn8yB8dw31fXRsD6LhwPLR -tz1hTNYvte5scZvkNdytQP5AvRcqxoUTxWKE -tz1hwBwpN5LALCHCjaTmHpMu6n21pd6N3f1w -tz1VuQJYDi343a4xb9o8soLibg1ZWfeGtKdL -tz1apzYQkJc1VegDGsBDvZodDsErYeUZNGmg -tz1eL9BVMR7zqPonaqJUxusRH3wkiuAPgUc8 -tz1LsitV2cEoZdx4dYDPoScejpzu6mw5BD7p -tz1dghnNtVQi5tKvjsprf6f3WMcPhFnjSRMf -tz1g1X4hx8UDWJDbskjmMgdQe6bc75nygXTT -tz1g5srsKJiBxhFV77UEWsbnjwo81RVzmENc -tz1SNUxLEah5VCR18itiMmjYtZRmWz7egbhM -tz1c9LZny8GLdvUssyVBJfCDZa7jeNHa8cQi -tz1SEbnHZqpjs2pcGgydCQAodoWJ4vyfrBtX -tz1KiDLpPY5GYUypeiyTUbhsFVCbDDYXAD4Z -tz1hatwJrwhnVt3xRGaLqiVCKA3wkmXxyQM9 -tz1Y6dujwEBGHHf2vPLxvmJYpUxCQMKzuwhu -tz1UhnGoG7vcTb6W5Xmpg8SZtE4awmNdwrTr -tz1Kovfjr4XDr9JQXAyNgshD78X4WPcUxSmq -tz1aUq36hjo5ZF7nD4tAdXN7otFyeytd3dk4 -tz1hjzrGggubjB2tUqwj6RHuscnJnzPafJq8 -tz1TtATPsuiwDAnM4XNJ8siR8bPg8WFiNtkn -tz1VTc89CE2BP7qmQtSx4LGUditTmKPzQf2x -tz1RejxUMfYQj3T6Poz6kTT26oJ6tWn8xjFE -tz1h4XnGjUnGY2ZM8T1VgprwDuUzWyJghTFs -tz1fERwp9QoejXnJHBYgrop4dXtnVNENkUHN -tz1Shsxif6qgGDf12Mvrys19MSdqzhL1fAdQ -tz1LVhvSDtQCZdaVJTPGLD9d2zMv2DdJYRJq -tz1NX8EwDVAGKmTp7T7BGzk1KP7XTD54PubB -tz1SxEAdEb6sXjXefAH9jF9kwdoHSKdCHGUK -tz1Pa4EGiBSBNLEVM6cGx3nVAxK8K6YM2K6v -tz1gKP9vMvu3zxWBGKhrSYQCkAesUv1xt4iV -tz1SZp1UBW3h4uiWzFqEdY1Z2UwURTzkPofz -tz1R5fvNPGCGYGccV7G8F8hBmxp2KCGbwTt2 -tz1UfnFF5oJMFiBPjjMVH8uZpiGti7TgbjSJ -tz1SQ1fPp2EAQ2C53kt11VvTTC3CFxQLwQBY -tz1fxDMBCbdqzCBjKcnNn8XFT9Q43WPKpUQu -tz1MTcPaHFDaj7QD9L7nA8oZR2sv5MzKoT91 -tz1heJdcVHZGaY4HYC7x7ZCyuxizXmw1Ttwa -tz1STBuqHcjFoJ3vG2EzZLgGxeoDr6y8rksC -tz1et4QwmseUPJE64hpp7MmFMFeiJcQKFZGE -tz1f3E6vvvnC2RrRPaJ51iQntnRUqVQGzHjJ -tz1Vsqt2zFJCv2tYHziedAMUTKri8n1VGsHc -tz1WB95b6ncZ41sJGKurtM9C2geYA1dNrpmm -tz1dyQ69s1WjxQoXPtZPYYF8xV66MdxjhAyJ -tz1UUCWrYX3DtVwad8piXEwrPtnTBRjqiHem -tz1d3BYaUgzfwrCDWdTva2haEYBM7nAuC7eM -tz1MzfembyQPS9GnehJCD5tMeMuq9WS6ms47 -tz1KeK8qEnZhFzLQqnz2oKaXnG4X2zQC5tz3 -tz1Ysi821gyWyfsSq7GeDDQmJgiuuFyarmGc -tz1aBFYomQBa2sg5FbfDQLFXK8e7m3bM6tmn -tz1QDVnGQvwZsdhzjCJptvQxTtabMMxkf8uG -tz1PVG85E3qx3W5X4nJBCsDjyyX2XAhsbKce -tz1Zjh92pLcmDxzc1yrXytonp27cdi4nkdev -tz1dFecN19cJVHCMrMw5TFySw4bzUSWF9TqT -tz1iXeCUUpFqQMRDBmu8qXcLtasuDmyEE9hP -tz1Ub7gTGjwJdhAt33P4SWAvidvuVDcWusBt -tz1VbuepfLNdro9xPa5NTHUSwsQKE62zUcsv -tz1iZqBEJhJgpWb1J4tiZktUnuwTz9idHm5B -tz1SHX7hDPnxGZY6mevUdNe2ovE8pwbYEy1t -tz1W4BQYD5eie4vQJn5HPN2P2sw1Xx8aZnQE -tz1LsZ6ucBAZq3C6Nvdq6K6HYj8x9nZ2Nofi -tz1VJc9t1ydrmibuV7ycHWV8BB3h9niSTUUq -tz1csDWZoie38GjdSDV4tQ822GHpMXturPww -tz1RkPCxBjSDiaeA3mJmgLsMHfdbcHvUZ4Dd -tz1fA7USMBfx36Hebsdf9KuHRPekhrZLsuSM -tz1aBhrWjcmoufrrUJNnFqhFmFSPcfSkZbjM -tz1dFomRQHfuv8kqiwZRVgM6xYiJho7KaKnX -tz1Xyo4GrXCGvyWCjB9hFMWEYqRAWi7jPurv -tz1fuKsFR3evcGbtY2zXjPSrN2ngcTKo59AT -tz1g9xNXvBcNeGbSuGokrrumG8S5xT3puuDZ -tz1PRdwK7sdwjRbk7gWWqm5uCVgJXAAbkYwy -tz1hvCHc1RUjgfP5og9RP5DVZkKefsuza5f1 -tz1hJq2w2K7cYD5SvFWLVfE5RVkUfpZXYgMP -tz1ZzonGNWfsSTdyKozcnBcWEfkyaJqQaQUp -tz1eurXGBesxyQVoqTzEqYdAXfGLLL5xRK5X -tz1KraN4NTTEyXwFqRwCjkX8E8eB3ss8nT8H -tz1R5nmEvufqHkxsHPt83LV5B5PLhKrEds3N -tz1UmjXE5thZqhFECRXFfp5cAuEL5qj9XrhS -tz1fU2PZPxVczWg9kqVvtovARZZcKVgamrMN -tz1gPjjAtWQeo2cDeYSGbSH7cCWgQpUnFUem -tz1bB5N6qnjF252cMcB6NWWfALbYwYDCjukW -tz1chMNU3Rryn2385x2U9CUfAnRqdKARyCVG -tz1bAAYhT2mRmPkuzawXqj69eqr7Jey9tq4J -tz1eoBkVodfUtkwNqUYUU6BcCbypjjyv3gmN -tz1c4EjacLXqPYnjjXGKj3t34rdsYZEyEoDL -tz1d4eCdTtGvxnV1oMpQFpPAgua2dv8sQdao -tz1hkzS6pnfnHv9KzX1nbtqXVqUkzcem8FJs -tz1fRZKYj5MAVyX5udt1AWL7Fcy1BiWEhZ6H -tz1XBoUgTQ1RvNFG2qfLBgRTYAwW7MiZfur2 -tz1bNE3JQk8aRAMFX43D62oQz6CY3v2sJWbJ -tz1URVWTwazG74cJRdzBkp9Nqw2rjWGPBW7V -tz1ZA1W6MstiE3BHdwtVVXdsY9sdTwbvK6sD -tz1Ng57JKTHPb8PaEMXxDXoN4B8y7a9rxRTh -tz1htjGkAWbeEV8w8QqaPZmr1UPNhcdxzZM1 -tz1iuABZjznuVniHsfv7VFyJakrkqDXHh5UQ -tz1Xit7j2YH4zQrf8i31zhuB9299G9byZtfZ -tz1LDH7uKSJ9gYKNWMKJE1r2jHf425nqX6f9 -tz1Ys5RPGpuq3TgKaeEgNWGhwr4ywHpr8umg -tz1ff9Ns3mMQJ5adtRUUFaKtNKtHsJhGT4jX -tz1WErPVY942dccC5pwYVss1zpMoYFfP1hzG -tz1hFToth5zHRbiD1DzZ9A2tsDKWaRPtG217 -tz1fcFcAt46T1KkSLTV6BLHTm6BuRNjD7n4A -tz1XEhymahKi3Fe3s2b5j2KuWTRWEC4DdaEq -tz1NNDuGiCqNnZ794oaSZq69NKhDvXzUeW2i -tz1bmDqRNaVy4cTX3LjtPq6mRL6dRiTp7KB1 -tz1fUVQM3pbtvLeiZoKYSQy5UMJrFhj1Rtgx -tz1eQKheekpuQ5TfWsJE7eQcDQfoCojRZc17 -tz1MQKFauf2L6jpzSL3b3pzz8P9dUuDAs1SR -tz1adcmKGsxyzEYmYMK75gfdrZdZ4ngSf9Yq -tz1M1pWrTwgaEdAewb4sL2dsX6wkCx5jZ2va -tz1RwfxGiiqgiKUcyrFtvUeU6FdX5JbjjhMi -tz1aDm22gDKh6WAHMSVW7BJfXE2QcBJrgCrS -tz1hxCpmXP6VxywySUasLaNu2WfpTu59mgs8 -tz1LeHGa3iF9Rq6sorKu7J3LmsbBC9q6TenF -tz1erVoKdcA5Ck1KWJVWUcdyLTvb1E1yZe7G -tz1Pr3MKHkXnuDGTWesh6cL8pTTnSj12zMi5 -tz1gBqQ8vN7yNFxuh856R3QBm1LvyqxvNxED -tz1WWymGTXsLH4veYLUVbYgpaDQRfjYEoBfQ -tz1N5rgzgUDqgu5VCeamfAywsHEH5sgPDzoN -tz1gVRFFjdf9LMZ9Xjhd5qWEFPdvmnx7dxeD -tz1eq4SStXXskGR5VBmPXTz9Bees75TdBxHc -tz1PXmSJEM95YA2UTAzFjpDxZabqmGBJsQoa -tz1hv4fM79qt6QWa1czpKabVvEeTrZ7vQaAw -tz1Wxr55G1zFyWEg5PXXhcKhtbcAn6Q6sF3P -tz1USsZCr4VZidNuiAqRpGvhodcGLLdyTPQC -tz1KkckK5peK6U6dHHPiHzDRt95aUnBXpVDC -tz1LWDSmntpt3hC5wuETZJsvSqfjBeemWnAi -tz1ck9NZP5JaprFiW5A9H6d83HQ3QFgK7vbA -tz1Nc7xG3cfbBxTKBzWXdkeUzaohfkiLbehB -tz1cnBfUjuJ2nkDYDrt9ntKgaC44kVWmV7QU -tz1VqgtMMQ4q5oC7DFCdyhG724fSTQH6gRm1 -tz1RP5b8k4UdqwUbxP1vsSQRvWUp9kJ2LcZb -tz1a5uQthKvob8qJGamL2MvWYASjpsBnm3fM -tz1Qa5Xj5eHndVvFKPURWxeoDtYRpwgh4Yzx -tz1aw1d1NBqjEBu7iCSfxTEL1Gpao8SRrZzF -tz1Q7LQCwqTLxYrZQGzW7f81CsgrsuXkyPtg -tz1QWEDney2nfsSEWrsMHyqeXHfvCGg7uZuX -tz1g891ESroDTrjcNe7d5eGtYCikLxMJLjBk -tz1WN3Zb1fGSZKzWYMPYLtykUhzH24dedxwG -tz1RijBHfS8NYTDdKysXR9Q3L4tX5WSW1oej -tz1dyRDa36ALHNdvEBTZ8vVWJuBKsjpoVqn6 -tz1g6se5xkiguxAA7HEYyUvqmwcKoVAApCvW -tz1bGZCNAVUo6NcWtqe4CrpsNNfFCZcWWeeP -tz1g94hUuPqrZFTtRQpsLRNi14nBayKxCrKF -tz1X2jLf78P9dBsxkXZ4sh1av6VQzwDgkmvv -tz1fZvUs8a9EpTCn6ph1TuSpiyok2ARurA7d -tz1Lg5tViMkAC3M7b2F4KjVAe9y71E8wsAro -tz1aMcz2UaUb1VHEYwToNmHRAY4o4GSDNBuL -tz1QkkkzwX4UvwPTK5quMWVGN4BWBTALuE6Y -tz1ciGi2dF9FnMj5GN28iCWFyixUb4PnvcMz -tz1NY8PPzuqLacp3Cbui7t1X5Dm3tk29yq6q -tz1YeM1k1d2ti9RyGvCvhxo3wLRG1XQeWLkT -tz1Pi7sRbpa6MWCFkD78Hkx6Smix5ZziGqxu -tz1TawnrTEtRxkZvsNL3FeaF2RAofgddNZeq -tz1SQubQ1Ea957bunWRbnJ3jMnN16sWHoXba -tz1ewEa2CeGKPinzT7cWQ5ZAjWXdX3rmcGpb -tz1csh7yQsiBmT2Z1UD6bkD6Pi17KzfPjq4Y -tz1iKC73E9qUqshLN88VyUVMnT64jn9FK7vc -tz1hehXgA5rGAAUcBmoxe8VBSMSvrS65igvu -tz1UesDNVJHzQ7gQ1B3NrxUrFJQr9uoum9xH -tz1d3BLqFtZ4FZmb1t2dCLKGWYL2wur4Y8tR -tz1iuDTAEu6KsyKavRVXB2DbXVDgpEVSSvPL -tz1cNnzrttzDxsHd5tKcuDUw5WGo7JQ7MUsr -tz1dYjHKUuurS7faw11gb6pGNMGYKHfpHb6m -tz1fo8D1Bytc8jAKypxP5UT5sKhTe4oc7D3x -tz1NMR5CDhC14HNgD1XXWGtUrTdiujgcMto2 -tz1fdmdW6kCjd2xyFi8FXrT7A88zC7mNBzXf -tz1QnHqQ23A1Ma7rguXkVz8euPA6Sip428UC -tz1bu9ehu395fGUvK9YBaD35e9sXH5ayUUMK -tz1haG5SGKSuBNZeCfP85ZtnE7VzjHonBchS -tz1d1KQiDVC29mku8fPtkM6jG4sPdKupEnE3 -tz1ama71pwErPou38nd3c7bnhuMa7UGpTFL9 -tz1SG1xjLnaZ6kNdBj59rhjmsSymtNajRh56 -tz1Lqy3vMDxyMhY5AGazhK9UuhjfCocNwCKY -tz1QXbDak1E4MqeZHWsnazyKG38of8oK4yvp -tz1ZzWkhWTDK84LoKpCLBLoY7vUsmDFn7QsW -tz1S2GXLg1wcJiyHebf2P3ecAMhfka37CJHF -tz1SPWG2xfEHVAyfhrvyuWmrupNeC4fcR27k -tz1PpvY1mwK6BB1cuMkXftE7kqjEkcLs8r4b -tz1SgrBy7zvXNqeveRHxQWyEcdwRLGbLbrv8 -tz1NfCd6v769Xk487URcaqyj1cpZ6T57T8FB -tz1giJZ28HwtShiCPzcpEnZmSC8T8fBizSi6 -tz1ZCLFyhyJbrnQYxE86suAi1rqZurNxxxoT -tz1MAkSkBDgvnA2B8M9moywteWtd9mKfUHA5 -tz1eYqjw7281QaZCtzQxDv7nA8V8jtrC9ph3 -tz1MVJf9ajuFVPcHYWAPHa6D5goewi6Akzxi -tz1WeGdhYjQMABV26fCyKKJEnj2EpdipopWa -tz1M4yyjjFr2djHmbx7o3MdmmNpAY8ne828q -tz1Wxho9a5cbKqGnWBENNnpcqBXCZvsu6Cwu -tz1in5KaYNYmxTmomirQrcNkr46wx29BQCpC -tz1NssczkTSPbyiSCHKs8rWHwhCFMECWn72y -tz1hRvPoNAcXTTxGnfevWj1dazkGTDxedbsV -tz1iep6y3A1jX518pECK52PZ8q7r89hj3zB9 -tz1SLzFLP6BimyJXBVTMjD7Gkz6rQG1KHgkW -tz1ZcXiMabHLepR8zDDZGRQGk8teAdmR8TUq -tz1LbZkmGE3U81YUdiyjS3wTj2fWbyCBBVXX -tz1SkJDkWYfwGS5k8WsM6SKTu318Z18PZiRj -tz1Uo1FAYgi9QwtQCeex4ZhZr92XJ1rucNPQ -tz1M758MYkUqxc972GtsLTkrZkCyVR7KUFZp -tz1SE2q75ix7EFqvHPiMtCoqT8uoduQWop4W -tz1KwcBWRZz9YHzT3AiZk7FMXm7YvkmoK8FD -tz1gTgEDrAnVYLjhpF9gdx2Y5VWh4H5JxAg9 -tz1Pc1rEFC7pS87MdEDCAes2u9LzLgHyfhwG -tz1Xctg3VpvFLDegtwy6dv89urMEc2sE9CPn -tz1hG1jvicLe2VofFCakth8FmkdfmaQU7jE9 -tz1dTQuLufSd2h35KYeF8yWiZFDfNsRLwYyH -tz1fp52kzZ2QuZUQtpzLbX4whLtPj6GjUjmy -tz1ZWKuCYzf9okAz5VriLdU97X3D5zoXEfxA -tz1YporHgHqCbyyZrBkPMk1G4BKWY9fkZJCk -tz1Rk2gwFrMd3Xer5BAoPtMhu6EdHL8tW427 -tz1g7gdts1Aza4KjP8NncHBikDrWEvgdeqam -tz1bmJacmda3yvQ1phTU61AtyQs22t2KbAZt -tz1SZxhLgsYrCuZmTYYYEUK2U9h5cJJc73nG -tz1erCnAM3rbzkQ9oCTxLugJxfAP8ngSkFgr -tz1PRHqEyS7SR2kW9m5gW567kANHhVckJSBD -tz1KoddQLGoRYHn1Qh6k2cbnd7GnuYr2FUuG -tz1fQxSaQcdyH8NJitUMyJr7dJANxe52Mc5G -tz1LGzeAdy6wE3q2dpim2nb6nWAu6Rw7zGcq -tz1bdyF6u2ygNGmgPvH6urdp1NHFERF1T3qv -tz1fUDFPXQUF5dugyGiVApafGLjfP5eW3vtU -tz1L2H8q4kRoSX2g1GFWBzyD6uUVvSAuJRo7 -tz1V2rvwdzFHWYGg88Pv9dAn1JvJMLCtDZCV -tz1LiWPbWyfqQKYePip1vgS91vU9NnmTqJxN -tz1Z9KrZhwrfXLDu26R4o7mJoW5WnmF1umAj -tz1Vf24triiWcHz3qDZfQrutsawj4GCwd66T -tz1aGCCv3Jk3JoAksHm28ADY6HsoFhjNK5Tw -tz1P2jG9bFPDPf4BvF6geipUYemegqMJAwG4 -tz1gmV7tdBgqn4Xt4vPqxtonpcdeBc2Yewqw -tz1TG959jKpV5XmQ1qaqeDxDnHpbzuA5FVEk -tz1hUes1R4LTeDqJRp7jBQg33ajoCzDQqg4c -tz1SoysYXCQvG27EyVekoZLuLSDAZpGz1Q7j -tz1Zh53QNA8SoHc5t5yLfWFcGZgEydAXRSHg -tz1TRdnf4cHpCa551xZp5H4h8Ma5P92ph2Yt -tz1UgMGAYe3Mi4okddwGZ2RiHYcMcHK1htW2 -tz1hXRHSqUHSW6W95bx5RsSeJj4ZJAt2q9Tb -tz1eaWCaNST5xUAhxp5QM1prgF8SiwH5gtco -tz1YCV4VzoaysjM63fuFPs6Jcu5VaYjC6vuo -tz1dBkUKozHs8oC9FYakKLthmshLrjs8dNwv -tz1euXQYBMrpux9DAgCArnX4vW9JY9pkVtTb -tz1dCanWZmpKXnAEec8ZupbmGxg7ajRJZPTA -tz1hdqwg7AciNCwxcSgDNNyTect62X6jDUTB -tz1RAc6icoKZMSDqNTLcTusApq7PmLN7X6bD -tz1RB6GqYJh2fedAsdxhW48sPMFQPap8D8MX -tz1hU9UVy7j7LzRjShRcEHiEoGVsBoi5KkUR -tz1igJETNZMt2AEQHBDyVq4JB1b2ibt1Epvr -tz1ihUxxDWU1aNXRb1tCsCrzaXyQ4kg3pe51 -tz1YpY1irgx5WmwCfabS7EB2cVY3zCFLmyb3 -tz1REjkY339cvSAHKYwu4yFYmU9W7eSRW26x -tz1WJVdqTjQAETRyhoHwBWkBA3KPQ2pu54u5 -tz1eUrp6bm2mgrB5G5MMixqaSkLxauwsUZJt -tz1a6jiWojftvtCuKoX29LrF7xQHp1oR4R4s -tz1XtVYuS9EFSfjAVUrz56k6Sa3wePvpr8TV -tz1XJmKo1HVfmRmudSYJLiAcR6wVj48ytTxF -tz1VyeAvqtSkbiSw3rMsnT3aX8eEAPyN5CpH -tz1Y2rWucVk8b4evPzjLfT1fhY7HDdeVJgNh -tz1Ng1Sn2YzkJzMCTrYU3NxW9dmomjgNxAxp -tz1XEEoQ5GmkB6mZi5f1Eav6pg15qiUwtYPQ -tz1XW1UFu4SkP63i3NesR94jiMd1BKmboytY -tz1aCmhu8pKf4SzQYgpsvg1zAJs9nhrm9ggH -tz1ddJwt6jSGMZAAZxQMAjszb8ykK4bNBqUg -tz1MxT1YuBp315Bg4mjwa3jXbtKgEGUVG5bk -tz1fZaCQjiU8c6yEZq4i5v3yqRqTpx8G7rRG -tz1ZrYqiHUp5errhxgNNn9ayF9F1RwYyVm2A -tz1cgRA2aKtefqfr9D1jzoitQoDCZAuZZgAY -tz1YqMLj2a4poV6zYcrtwyPo5XveT1Sfp8tA -tz1hGsaH7tugbMdtSKmjKwgwevKZtQ2HKpcs -tz1MxuydUAq7TGtssKy6gUVhCTbkvtFeqpg9 -tz1VDbj1hgHccNfHpSANEPVMvaS75AWqF128 -tz1MUSRjb5aVbGauD92BBCYNv2VbLw1nrDvz -tz1LKggcZY8yEi21AEwd1zeZhcp2EXz88m95 -tz1aW12WpRhn1kCZnyYWTAgiTTfbdb4qHGxn -tz1hN2JewGS68isAEryhKtRsLN8CZNZ11i8n -tz1QLjnuzpJZdueEnXRFEX882jAjkYxdRpUC -tz1dVC6jtB6XrDD6ptcWg7gJwgbWVUeg2au5 -tz1QXykbDwtwXpWETqvW8cTjPh5xAnwULqpo -tz1akzhzfVxfU3h3KndXQ971gmGUVgCGTSev -tz1feKZ3BE1x591VUXTw267SSwryGFqTCjTb -tz1QThiF9pJ8yu93TSGm1NCUB5yFdqvWGGCF -tz1QXHe9PE4iQ9mJvVbb8pDwuqN5AhgATvyb -tz1gHKCLo2FLvLbUzG5Zmyo6zDVTehKTe8jr -tz1TgcxR8ykst2bvwopE4PqKA2mVJCC936fc -tz1iZG7eCvTkshmcvxRsxU2JqR1cB8Ucg4Cn -tz1bNQMZTnZzXVrcbudir4PFttLwckD9zQCD -tz1gR7srSopj2vxVjk3obbwbyFeK4dVnq9ws -tz1aNBFhJYqwo5nazXnKZoKdGpyxuQCrKvpS -tz1Rdd3Gk6etdWsigPPpxnXMPSum7MTP3JZa -tz1LWGsr1PvafwecGd3Ha2wXRsxRB5n5qkH8 -tz1i76ZgHpoyBLQGG8S9APaCvyecmGj4mLd1 -tz1bCXpGcVHS6mGAmurEysCARV3WfugTrQJh -tz1cDjBMogQBtARSduGusL6UHJRNu5rGHMHk -tz1h3mFk8GsmW83mTrbMGP5DsrwEoC7AvyUr -tz1NaHkJq4EJczDjT9NEEDhum5MkoKcA1eXY -tz1ZyXtvh7uneiH4rN6aLwbkg4vL2uySXSBo -tz1M2uMiLS38hiEiALJQCF3gpHff6V5ftvYd -tz1gwah4bvjdFmeGjJrBFjn6KVnMbKHrWxgU -tz1ed4brTwpFg8hFUJSJ4HqnsC7sEjVesMtb -tz1SAxWMPRv6bK2nenKqCihgmD6vb1jViG2e -tz1bt4TsX3Qz9xkEBN92ctboe7Wo4LqkfpfU -tz1eSi1MnRGW7689UjVfh832eDQxaFBCBcEv -tz1XJER5TDURGAopsU2MowGHRZrDuBrKUULL -tz1KjfvZwKqqJefLGLQvc9N7ZMeGJWS7BHRY -tz1ifz81L4cs3EPK7p31zBQvu86dUEZiHecn -tz1YeqdeE6hxPGYXDerH4ayZCPB3WbsnUvDG -tz1T8tGTxvYJGhPu4C2PZRkmz7WNr1q43ARS -tz1eni7didRiMGNBknqjzBpUeAGiMe8f2H4w -tz1Nve765555nheybnxejXZSXdg67TDYwKSx -tz1hfioyfi8RKADxjacX97kZDUNRNbEF7HrM -tz1Nt6LEDtmEJFZ7UUMxj3551oVm2D4DPq2w -tz1bpT2apP2Q47MJGTuWeLYcNSPUmbixy7ky -tz1NV1z55XKbbMJttYuxuqSFw5QZvEbf7xyv -tz1dBEyKwSAWV2NAQsEXRbbspFKrP4hYEkpw -tz1ipQKYNzwFv42cjGD6DoRJ6suQutTNUN9K -tz1LewvxeaERJQTSqfuis3HpEh2X9JKs6trU -tz1QKNMkE689rPWiWTPukk6gJyML1fGTiBAQ -tz1d7ebZTb8cUt6uazANzaNVWptuYLxJ1vq2 -tz1dUo9SwiWKXFJQaZAdWxqb25MSZi6ge6ga -tz1TGYurwWRPPYQcvZTP6SZ4Mmz3WUovRqo5 -tz1h45EBiewmHmuXigE28MncvRPpPTKfoUvz -tz1Mfmh6a5Dm7ckrP1WQfRR2cMneYD9kyKTy -tz1Lf8RjAkJX9MDfUXpjPqnQEnodXpdtaixZ -tz1aXyqtR7rtQwwigdLSM4sQrFxFdYWdMLm4 -tz1NNupJkctLyxiHBb5kBfmiwFWH7yjizcYa -tz1XoDAecCkWf7EpP4XkMUKCU43Yti57DRDA -tz1ZQ47wrXXjugkUs7pZGyZgmQXDvLQMfYFM -tz1UpRgUVP7GSBSxJUUrZWbRdJ144MCgZEM4 -tz1VvmDYPVrSV6rdy6ics6BwPo1brXDUAh64 -tz1P8YsCFQjKZdUGJ66wB155j4EtT1P5Ze2i -tz1ZiTQEeAGmJAp8bMfq9ZuHRVhXrdZZauC2 -tz1UiqZgaSVzkDfZjxtUYSjqFwanoZDiPHr2 -tz1S1mD1MqKwvPY9j4cajxdLRfd73DiL868J -tz1SypuoS8ZTWEZ7nUtrV6ELgvMq3fj9zyhv -tz1P5bbr5juwPbZ6S3xW34HU9NRUtPYqYtJj -tz1Rosu8Kai9wptgZ9SFyAGAeM8RAVQKJG36 -tz1NACuUhLQpu5AVtvfweEYRtPMhFE7SFzSb -tz1WgkUx8xVwMC368LVjQmSi4fzGHC3gfqZU -tz1gAKq8x67qwZ282M4xDXLsNhh2m8vVw4U7 -tz1Qa6fGUbNaVHcthEyGqHxBx26YkpgUmspq -tz1ap5TChmrLRhu4E4fYMiRwRDfzUxJEz7Ja -tz1YiDymncR99nq8r2xHuBgHrXzQC947D8az -tz1hSnYas6mBJYV1SXMFLSHKwqB8Mqntv1j9 -tz1Ug6m9A746wwMziVQhRCTvzKc31ktW29Ea -tz1d58JosKSM2zyeWtrfWEkzeefotMLr9PBP -tz1NhJm76jyeww5MXDWi85Qi69B8K9fah1BC -tz1TYymM7qUsCyLcopzCHSokPCjkYhPqgJsD -tz1MLxFbYiS9fRbRukCKcRsc1ZRh9xruGSCM -tz1cvWnDkyg5qY24eU5TKi9MwjtajugmZ21m -tz1WZHfrnuekMP5ptgc4LJ6F2ED3gbmecTmG -tz1Nb4RjfhtYJ2FThs7WBgHaPDUWVyeqxk8g -tz1ReActixmY8JYoyBFx8wSCnRpfMEb2Vp6t -tz1dFZNBVEh21miMQXJ9nf6U3sdD6rAoTzeD -tz1bwCU4wgLbbFFteBFJkmZM1QNJawNx5JyU -tz1P8PNyPjytkhBYwjWPvkSyS3iVZmHntBNh -tz1cJxHia6dcBuTME2JXn6tFGHhXDwVYDbc1 -tz1PJCJT85rrz1LXfej4aa7jVe3AizqqdD7i -tz1MxiTFaD5YwnQRGD3Z4waEGahgnJwM1dM2 -tz1btMbgboakuhu5vA2RJJ59TixNbKCHEun6 -tz1e61seqymnBmGBH32w8ZDMJ5Y3vkFu6uPp -tz1Nac3L1eHzEVU8CrdDkFkEKTN1FEb8qDuT -tz1hLqagNtrVeqb6PxpRzV1cJjdNehoHZofb -tz1gks8xCGVgAMGi2NSQNcgn8Zc6HEzSds9v -tz1LsUXYVGVrQJ4ZeKsEMEKqHtsVzMbaLZBe -tz1TaHhgZomm1S3VrfLv9cP9qn65UmAddMeL -tz1LLKGS6JyrLDeATDUa1oivdQQptd13nVVH -tz1MoC5gE7B2UCzDtcafkGrpKMj7vghdSTe5 -tz1M7GgEDxFU7ciBUBv9YXzbL6XseWgtVmKC -tz1NnvnXfNDJLgZ62LgGmhQ8Q77tMV4C999d -tz1Zp5FebgUKxatc7EPrBcNP8Qf6sW5oV9uD -tz1RfPkCHHP2ZLixorq5SzYCrhzvxh2ECM9i -tz1SdZNyw2dLZLQirtHxCD4etC3onrWMFRAu -tz1aMRhyrVzrtgScWi68sCN3wPFZ8EWLgaSR -tz1RsEv9sRg5DoyTUA51DD2f2QZrbzkEkPxJ -tz1PhzT34QMViMz8NSsvRYSqEsf3NNyS4AH2 -tz1TUaHMsUTjwtLYjAC17NKsxFzxdaTB4ye9 -tz1bEYTvyguqJ9FbtqAWvXVPHZxVDyMBDGG2 -tz1XCXr48xT71qDvPyLJMf5V9BV6Rg3WbAHp -tz1h6wmHP8AbfY5QaVhYTavWw2HbxfahqbBf -tz1LafQvZ648tkcwzPL3YevCGBVB2o4DPh8M -tz1QctFeb5Y3d8HxaJ6QynfR6Kfkd65wpbeH -tz1duyv31WpCHdUBDM2QkdjrijsNrAeMbs76 -tz1iUavf5w5X2dBRnuVgcV7Kge4uUdVPT31d -tz1UsJgRPJip6AGwfZzBMcSvU8cDWuZc5icH -tz1gSkxWSpxZch4TYxHk4TtZ1whGVrZ1u4rY -tz1TLJbDCNtRpYTrZNHrQ2knAkTjMrWpZ7sn -tz1hAVuTuCVL3FCwzbTPJfhF6FMVxL6vECB7 -tz1Uf4aoVfyh5XPrKKErzdFHhH8fE1NV4YDj -tz1XPJ9J48ncECa29SFzqRQymod4ueeVWCLC -tz1ZuMYQjFVv4AD652D9uvwE2uVfUu6bE7Xg -tz1U7jBgZn7fuJqWHkYiHrhHrPbcmzfZB2BN -tz1VnxN9ZbmauTG78fSRXDssRuu4kaHs8D43 -tz1YnZHUzJRakZd4ANDrMHf8CeawU6x5GMAs -tz1fq6xekpHD21wWTA18ED3Rs62CerNazZnS -tz1QbCLWADJJ3tb94RQ3GKuwXjAa2bYoKZeN -tz1MvxZuoY8K3v4ESNxLjhWLmSxd6McSKpp1 -tz1cTQDSiAuWQFnbwYeBsBPGQU3ZemGwnjSm -tz1bcTzwGkcgtha3ebVKjnceVS5GxDfRmENW -tz1aGNwurpzPaXw1NDbo1YQjUq8tWUfrN4jt -tz1gPuU3MK4qY6QJaaNVsxMRj54V3k5Gj5qj -tz1egdLMPhmYyGz1t6iyNNvKn749BrsTxcvF -tz1imejbcN6moZjmqNrLPw3t24j2Ax2cy62n -tz1PUGJPRuCCqLJztWzjjThVRH84TFu5ND4r -tz1aXS7qeg8mzfsySKQQXVcEub922oM9FPho -tz1ba7tLHYE3DGJd2AVy2ZwntYKi3ZEaFH8t -tz1SCyvywBoZ7ygkVwcaNpcRQecn5b1ebZQW -tz1NteP6d6AijBTe8wQx9AXovePYtKw8jpmT -tz1PFfsonNiJgV8cu21Nq9RyprgE8ZCoWNoS -tz1YfCJ558hUxtwDP4SR31RHiTRLPZ8A7nVF -tz1MoPzx3WBzGnStKbZD6modfvZDg3rDdh4R -tz1auQdZLaRWp2zdDDt4Vcdii7SStMb6cQ7P -tz1XudWyW21BgQuB5GNPBGv5TmW5gs6VZZfa -tz1UwcETgMQFSBTgo5ZxQYny88WihAjKFuG3 -tz1UR3M2VfVndTffu5HVKfJ52D3xqQKVN5qz -tz1RD37qcT39zwFA3cDvZXhoK4UZcUyBmRHz -tz1Y4GdYfoeDfEC5YapgvGMtmzHECaxqsHsY -tz1TvqENLVdDkSQcWXMctgEpFsZkt5qb5njd -tz1aLLVDnVhLrpsNj18rqhyEd371wPRHW6PZ -tz1czjmoFQaeZWPmNtGZ9grkhjJQDqduJ3bu -tz1ZKkCnas31EgQqt7XGtVpf6HGrdBZNEmdG -tz1MQSF4GrF5foNomfKb5QKbqVXTgJ9jZRfM -tz1cYdwVcncPd4xBvmjuMfEGrYVCVn44bF9r -tz1bkHv2be7XaZ44EXkssYdTJBcwkSwXoGL4 -tz1bT9qVw85mR1USMxf5Ep8TLoEHukFThV1t -tz1g2mcu4xS6FrvwprVkznvTPGe9JZfVUiMb -tz1PvyEMuMkuQVd9BviPnxDJDYncWL7eut88 -tz1dbCehED2cKGeJRYHT9s2frNQ5Ut8ic35q -tz1d32r5oozhvywrUhEX3GiZX93goE4GdLTA -tz1NXbyrMKJzi2BZJbZ1Gciu3Q4fsUuh1C5X -tz1W5xgxvstXNy7cQGbNb4WnitvxjE1d11kz -tz1M6sSPpsqBNhPgDJ85hEhwf7FdV9vyWg9q -tz1TG2t1bG2ePQSew4wyVwsdponJEiDrJDcP -tz1QFUAx3WsTECvaTphQwXiCtm4GGuCyNuJy -tz1QHCPo293wBVRA8qpZe1gdFehHWRrAGtBB -tz1SBTuJkg6yXcLqy3tHSeMEUoRgV9GBiRLf -tz1TJRGzE8b4eoNLfuhFSVyrLze6AMij9oYu -tz1VhDTPtuETX5JH3akM7pWrnK9xUQ1iPZJN -tz1cV215paHoKEvHNAMMfFpi7c12C79dkkEa -tz1XWUi2Szmb1zMdMRMZaujL6cK4aGnDNs2W -tz1TZv9QvcYPx3UP4EFDkQFyteSzYEvQVcgP -tz1fwXJ5Z8fce25PhLTVbUR7GwAsEW2cRwNu -tz1cFn1ufcejXmZX2B5P2YW9voCNJy1SH9Qe -tz1RFed7L6q25Lqe8e9dF34Memm3HKQuZJSC -tz1VvTayVqrti272yyuGUkKcytaDsxmzTsSH -tz1US6XydqY6nhUQMuQCrxuSvuTiZDZUGgAa -tz1PrKodeKgC32eP5JC1XAZAE2qRJYifPUX6 -tz1MTY7GhTenHUj6jmQFMHfUmqtQ16g8jjWT -tz1Kte5PM1AdXNaijke8tkuhjAzCm2TTGQS5 -tz1hP2kstGxZXwUszXQjfQHJ5RoBWix53B8A -tz1cdFCMDWLoDMxf8W6DR96UUFidnrehToxG -tz1UtpVtLPUjj9SM5H3wda9ZyfKnwZskCpja -tz1RqKXtpDHFoZFfykBQsvSqya8pzcda4DJg -tz1YdJfTFmnfgCc3PwCo1XxU6ootBhWFSd1V -tz1ZMR7LANmfvnRRYuHPtJ6ZS69EhDhRjtzf -tz1XKirznvXgPZ9n7GFE2DBFG4f6P8bRfC9W -tz1Lt74cnv73MSJP4t44AoSLbcne94CbrDBJ -tz1igiJXjHmBDM98hqxNqm877NS9jKWHECVk -tz1NVnDf3v9nc1p2KWB9Boo8yiBGrk9mP4uC -tz1LJQJTQZHw5uzXdj9nG8g6d8AtgsEQoDgu -tz1ax8sFHkDoPffAiTrzRoMLF3CbwGxJE984 -tz1cwuyF9FKx7ejDUK6Ve3ASRWBcnUXRqjv3 -tz1f8vY6fktHRreoDKKUFFQDa9xsKDJxsufm -tz1a4vaCNErQ6a6bh8o1szWd2fbomvFUsk7r -tz1ZSpRGHtXaLqVh2AiHfF31Mi66LrqLUqTe -tz1R7NYWok5BXmBmqBCxMRgp3fjNMZYNLQCU -tz1ZuQu3LdYYTKNwP8DhhtTrABKkMyu8wdcB -tz1ha14BAHyVguH5K4LYLudc8N2UajEKNmJn -tz1LD5vhBGWU7sTMDJRXLSHKSTTEAZBCtqyc -tz1a89854P8APL3zyWft7dLVevGhiVmG6KhP -tz1XhW7T45VXjPvKTQNDVuiyiRxJsMCpEVad -tz1bgKBrC3CVCnM5uDvcrQCWmsM8vuM65foZ -tz1aJP7Uf8DkJap4oh1jirgGgaY4L47Z2NBV -tz1Lh4mDPNPWP3gDPBvs3XhrFsPSUdAHUFtN -tz1WdyP2CYfTgsJMMSpWLsrkupf4bvgqqMip -tz1W7cGTmMMML2TjggV3JpMdLUveKVHhtsrk -tz1ZZ4V6LEpqRwpZ3VkHQyNaek1McomR6Luz -tz1b7a43cjdg9LJTZh6A8t1n4zyVDbJAUw8q -tz1VcvzbYPxHHSW5KaXaksjbYMpq6LGdtL8f -tz1WXSnDN62DAvokUJ9hv4SsKJM4vvNQDiyj -tz1bPiEVifEnVvdSyVjW2eazz7E6HFmkPgnp -tz1i1K75b5Dgah6SxwSqD2STTcSVWJRveG12 -tz1hqVQRVvvR3EUv7oo3CtLFvWyFtSqXuMpW -tz1VeSdRX2ixLHDcwTUMYRobh5XcR4KjVRuu -tz1gVtFn2dJp46btGnsZvJrv8WAVZo31Q3sd -tz1W3qH8FCLeqWFRYgE7Di3D2143HcEMdBpc -tz1QN4TXqt81f1ePm45fUquEH646mFTFNue7 -tz1c7FvT1uDtumQyLxTMgkqQyxPnwUcK4Ne7 -tz1am2RbhcggZB3h7SBR6KVhNrGaKSpE7apq -tz1hZgU4EY1a5UPovkkvUfM8fMqKyJYAGXuK -tz1Lk1aVBSa43Kf7gyg39RduUGEm18V4yL9H -tz1i3PXvr6ySpdQQDNzBQwRrMaLwjMne1Jrg -tz1WBKqp7hXs6wUWV4BaSQcud3QuzWYKJSsE -tz1NK4fmm4tCokjaCnwffTHHHCoxpAhiAKM7 -tz1L7g4zYFK6DDPMeXGdZm372b7EwDASkXPT -tz1QepjbTuYCLZ2yqT72dQW5KQ4EtYoCysr8 -tz1Qctp7iumLjGoHHfiwbCcfTYQxSCrijDZy -tz1THPGHyMinhDmjhhJ6rfnyDqGdxf4CuKQv -tz1iofVKHxnnZyoAdvTYCydv73zSbHBKTVN3 -tz1RtKwyVd6mVsSH9rGzAKtw6x92MHs89YxF -tz1LkM4gEnKQD2rbU11M8ca5Z1MCnuskAGgB -tz1XpZYFSgwocMyMhi5eCtxN38nGfaRxE5NV -tz1UmU95LabSTVoRs7WfVn7pfhYAhUmz7bre -tz1Q5Ttq514hsVZBLmuWK31zue2tj58jFyb2 -tz1RKciYQAqPGLY24TUJCrNzRkLZ3wxtvvyj -tz1heEUus46RU7Sd8MiYTdxQq3SvnLUneqwM -tz1V2Wnzwz6X7g2vDCpB94uWBRFhDDP2J8Rc -tz1UCEMPrkv4nbEtu3ymb2NyzEkXGasomMat -tz1Wa9xeUn9Lk2DqRurM1Jk9iCkZwNNGj7aR -tz1N4pACzQBgtbyzXEmQRmT4cKwfHhw9Zw7S -tz1fxEV5raxvHSNAdLFWMWnc6uAb3FCcGEgq -tz1hA3dSQUaoiGGdpakDJK169fZRRMVvw1TT -tz1dxeg9L5eRHToFSboSDw5eLiAjUBGhiJ5u -tz1StzPNGkTnsyvxG7MmXgcKB8qce6FQobTb -tz1Qr7F9vVNHvJzT3k7LMvLSZdFswwJnywnG -tz1iAA8d6pdigFBwS8bfUk8VXwmRGWXLmpP8 -tz1MNCfzZqFbMGocnrMctzYecqt13iJFj8hk -tz1XYFZ6DWQJhuv7j3V1cbhLzFhJxuhZQGgT -tz1QrmMi8E9hAGMVKtKUgsgE1s4BvMETb5gF -tz1NQY3481XsyHpmsUsniw8GkBPFCAnzjPZx -tz1LTmh5bihzYXTzSAiJtCy43fMQS75v3Ero -tz1RAxb6PwHLM8mSNoGDVt6R1gMHNaoWS9sW -tz1XthKdRMEFBsNqvoZEcNMs5FCpkg21wjCi -tz1UzUoNBqv18eD1WGk779yX7UwZMqn337TT -tz1cXBjL9e5yyCrc5WLrz5TekywMvAUbozDH -tz1WSME3CD1zAbmXax9s1DPn9x5aaFJBZVz3 -tz1T1TsH88zJSBthLRxtR2Bajey4CAywy3XA -tz1QwjvzshqQiF186xcDiVxpRMg31Mei1wUZ -tz1YfpzitXYWQAxmzMBBJMU4YJVsH3VZ3JCz -tz1QjYtaqFhjYfF3vfWa83CjYFTKEemtAUvx -tz1NLybucYD8QHKT8tEwe5HjnnYpcWPgB327 -tz1aMCRfHwomqahcfLeUc7nKehyNEQydafR8 -tz1RgcqacdhaavKyTjGoQRD2pJDqWVfshcJt -tz1QA8Li8C3nU5XBchpDt3ch4GLWAXBaaKGs -tz1LRK6bMcCEgCgGFGW71KE1jk3H2aQHoMUu -tz1c2ocqBmgufEUN6y1XXQ4SzK2iwsZ1kEZC -tz1dbzvRhADMsS4kSm6Vshy7CpRbUTkH7uuS -tz1cjywEKqfcNJqQW5FiyyCSRyJ8zpzF2aaT -tz1Z2tg3KuKqhms7J7JxBcNcKU3opHeie4nj -tz1W3VDDwPBJFXVzPHbh2AwkodV5QwMim2Dg -tz1Q9jg8ntUp7HENhcxeq3YCgPnWJ2KX4639 -tz1Myre1Gp2pVt3zLonwk5HQDnKe6tFiVw3C -tz1f8mkmV5rbY9e7hJKoKcLY7CxmfCaC3MHD -tz1PewjjNvAJwmA31bv7YWuZFZhz5qaPFqB1 -tz1b3txePJFo6iC1K2AimMzL4tqh9f2Pd2HY -tz1VjjEeomoNLCzzvJn9J6QkrN949xMrwdJQ -tz1hL4hs7whVpNHukcG3FiqLXrJU5ZVVDVwk -tz1SKsqSTFnWRuHRc97yCdwDQi2AgajdwAZX -tz1VyEbkSwudUkxSzJUk1WYvqmERs1WpuFBb -tz1LX8YU4NkJWQyYzwTpixt68mHndivpoo3K -tz1fGJimKrjZYxSyNbG5FZzw3wPYBCvAXWBW -tz1Mr1jKGVbBDvRnGAzm85yWSjtW8eybSSm1 -tz1ToV4oMvPfUPoYPbmpXjafZUETJ3Lt63Mk -tz1i7MpW3eSouVTMY8BXhDdAwqRebYEWsUU1 -tz1T78NaGPUfrjp8jWi3FkSStpiB6SqkYnKG -tz1gkG6r84XoHceG4JMDT6sPXE4KjqaxnC4o -tz1StvLkvNdvbW8iPQiP7zeg65fESYYuUgPz -tz1duR4ZHZjzrt4dRtvNjMTkTvauu3LhsH9T -tz1ZQSGP8p4ij47gCa2bcD5HAbnjBp2UDR6C -tz1Q9GakN1BBKfTXhzffGKRNWpwMQZpGzkd9 -tz1MLPmqWrSVmkXtT7i8dcNbDn5aVH518aVx -tz1VPsJTNKDkqvDcidTgTbgsBJHrk4Wq86Mb -tz1REiPS2zxoooXX1yvTkQzBPw4wL8nG3WWq -tz1V7GsHxkQtCLaVKCr2kYukULfqodBYFG9T -tz1gXX3Vgb9LP9t2zpgq6fmGQCbUFZee89aR -tz1VHh5xBR6hp53TWrDFcKAhFUj42w8zYzuy -tz1iWJ6b2KKqgfq54wmtdWFUFwYrD4oaQrEo -tz1fQoA1jWztZQqaK3ubxjzTFdcBdumx1azm -tz1UQPKb6uWVXhhsZpZD9peG3FioPnThw8Ee -tz1TPqkvthGaqPMQCJXvtNgwNv7fjALtodGY -tz1PbH2AGU1uv1uB7NiwLp8VT3bK5RxJPtgF -tz1Yb9cu4D1Bd8tgC9QvTEfHv6cSzE1L7p4C -tz1RuRsi1m8dHeFo5QcfTXwubVUk8xkckbAk -tz1fNSzUxiZs1wNUCFHnRedZuyKsbaiRbnKs -tz1NK8xCMQGCtHN2yDqUtuCDv5ftDwsY2fMW -tz1NLgwyCzUe2cYArYYU7R3VvfZganopPPr4 -tz1RC1X4MB9SpzfBGmnUAt41HHjvqMSXGjb1 -tz1hG9xZz2i3sCzyGqjPbSB1TGGbQytMNfA9 -tz1LCjfKzTDcseeR4XcgKqYT2kKmAi3aQdfP -tz1cFBAVM4KVpDQz3zowYqUeddHpz9WfKpnR -tz1QiSPYAW9JEC9YwSNJmGyABZGhrxeq8UDE -tz1fmrqMmpU6kVzaPSj89L9HRKjZw2EQD8KX -tz1TQTcKAE84yXdVL4WhG8yr4ojqH6xHpxNZ -tz1QPLQck5TYBDHQNJknJAzsK3KZH234Qhjj -tz1curRQmfYvDGf64wcDJYbcAf1TUR2NgAYA -tz1VBPjz5NGcvUj1Fe6XKt9VGCQMCm1bt9Yb -tz1P4Bn1f1Ca7PjJPAXQCz2cReeQC8RBSknU -tz1PYUnGi3kDZVBCTCje9amh7oXDCSE12mUP -tz1U1BRq8jvt4w9R2gzEGGZr77TVPUxAWxGs -tz1THYEqgq7hTCSEDhJU4ctqAUQ5uV5uYcvB -tz1UvG39mA3bQd7bPfFD4h6jcmEZGy2Rqboy -tz1dDqFeWaVsaGvGmYVPakZeZ8qCwGUndYSn -tz1dezKXRF5hJwccezqopuoGSip7m3HiK57a -tz1dedfoiG3tkY88wvg8WFFsA1kVE2Hv2o3w -tz1dyjwTYZbmyG4MsmKAzxHZg5L1iR2EJwFx -tz1ftyZajWLvErSdALvoJcevERMfsAcCZNBi -tz1Z16djFmxD3RrYsA3Cp2oSPkFHvM8S2xtx -tz1aqC2nhBYP3NMqnapL295jE9WjqTauYbVZ -tz1Pxc2fSXiBs6KRQde3xvWSaQpPHPmb53wz -tz1gYs5ZTZ4RSewKnntpQEWWitAJgEMCyDd8 -tz1hHkHDAXi7ozC9ZrRvgWDoRnWyGsk6z6kC -tz1iMgHv4xo4yqcH1oVmqeiJUvc5d1T1Avm7 -tz1XFFDVgEw1ybKtHHQ9yErwHcCVBjwGpB9H -tz1cWUBvmrfKH8UA7nejxP8cM1Fkat7D3e7D -tz1T1dhm4QaTWZjWumdyGPHd36qeyZHipWeg -tz1bE9mdK1pdFMEmep7jTFKbyAYZ9Sh9pwfU -tz1XZbCWe41gctnfBZPw4K13r5w7oweqmRTd -tz1bFRxgzzJTWuoDhe5JB9aA8VmQsqJp5hA2 -tz1fTgjEi76qWcCUGkQC9tCyT365mQZa8LTX -tz1LWDx9Q6FVRFxg9ESAEL7ERmNj4GLf3Xx8 -tz1QWnX3WYtnrxjwJgB9vaHteR9X5PbRx7wJ -tz1MAmBF3rgB1cSi82mVacsfwmQ8vdYaehYB -tz1h58qQMY7vzEeezTnhWMG5crofA54ZcE71 -tz1dvruRMCwkcaoy7i1cHhw3LdZ8R351CRGo -tz1Lnmwcro7ojNKBGu2cS4AUEdsdE4DZyfjN -tz1bGPcebg4doH2GJvoihAA15LvVEDqADJ6Y -tz1fCuitszmw6NCSQV8iFMCzVWJRtS29PJUm -tz1LYmYxN9kvGZ9LKtAbTcfEWpVdaUVksZpv -tz1ZevKvrfRgu96W1BcK7dVhF8eruLuGqf1L -tz1cgz9KekZVME9zZHC2RJr5GjTNm5bUSZrg -tz1gERjktUhyqmAf2YyFgP91FiKroNCRFuT1 -tz1dXMUoXPuSkR4MU1rxit3WhXkyUKZX5Yi6 -tz1KymbdCdH62H5gHqmJn2XityghbRKXBFaB -tz1iea8utvyARjzV4UTHUVNU4xgSJCxeEF7S -tz1c9gGxQu7DUmct5gYV635jf1X21SMUmCwk -tz1bRgGK1TDjbRWMnyMeRWGhYHPCBkhVRuCw -tz1gh4GTrDBXj7TNSYFB9S3SYzKGxWphNwqA -tz1gJRTZv3xunPwJimbpK1bZGF6dmPk2u5fm -tz1T5WVrMKWsRNFmNRhBk8wp9rQ6exbS21AZ -tz1ggRZcXJdam2ADqQq5ghm1rwKyVjyvwZaa -tz1Tgbx1aaM74QK6hPdcmnSVGGD8w9wbKEvy -tz1KtPLi2fRHF47k6fvF17L2gmC9vchUwiDq -tz1Z3iLiKmAz2MRaSurogtw9vUpxyRDop9dY -tz1LtCsv3SgpG7bM8EPrKqsxZEnYB3EKbU4R -tz1T9Cv5j6j4VzDg5EA5q71xk4UAXsu12hhv -tz1a8kCVkUoVJ9S8NKMg1qEfWQkgBcvN7GgG -tz1hTCiFDQVYxViWhkxU7NDrW5wfeqdiPfne -tz1MMWgc5TMXhXXBMR75c3RrY1ris4Gaifud -tz1VHFc8jYPm5F2gC8ZExVNDxutb7nDLrKq2 -tz1QyuH12Y5xtg2SE23ntGVwtWFAdjEaeqNx -tz1dvh4EHsBcumCRSqz6MaEzAggmXH9SkjWW -tz1gLRydDkHNY3WsLY9YwF4QQBCnhA6LrAQH -tz1bahXYBJT4ST5UJjg1Lrnrvot6U4NV5ru4 -tz1XsbMA65smRndDzeHUtVGZRQNLFBhkbzmK -tz1cSTkmucCL75aEhjGB9NyrceRANUtCygaT -tz1gMB7EfAqxQwhgPydTED7itwySGhJpCm3k -tz1UNZwiWe9oHJ9rzxmEQxjQHE2fD728rqnX -tz1T3jXsw5idsWLrpTcbog7Xk1mgYR4oPd4d -tz1b1sAWnfJXWi7SCMYopUsU6LddRnGnVK6B -tz1SyFoMd38pWFgHKWuF1kBcLBrghKYZsV9G -tz1iM7TXgASEsHV8sSiSRi6wpvZnwWkVQtUP -tz1XvStNxrR2SoSoXYec3g4pL9fj7hW5e87Q -tz1fsy6MXXR5skwXgGqLoDFinX52uAo6nh6z -tz1XfLfrSdTyg8rbTTx9LKbFtFfAhBpvfWGm -tz1iwKxPTFr3ckA311K26MeDKJXMMUZpGwyA -tz1YuDapzVR4g1c5C6mWgHE3Kr591wM1esN2 -tz1KfsDBnFLs7Z6DvoLLckrRvcz6ZHQcfPbG -tz1dvWzJ2F36dHNoYEvyMDSZ1pwPQ9jAGAiu -tz1PQ96kGUgUkijsBtPWi5xmkVQXgX4suPNY -tz1SUU754v7VYizQe9g6wXgTzq7VkmoghL4s -tz1RJfeFpGYQ5r3DHPygTdd6auNzgbNH4ZHK -tz1afhQPYTNS6CN75w7cy6ZGgCY4BorTWUtu -tz1ThZAA9cwsEL8eQXSygAZyD3eHYNhtTnes -tz1Txy51wNMwiNKC4NkgSpuD7s7cdqX2Kv6A -tz1ahcAF6w8inZk2HRy1YzNbXAxJzgpKwnss -tz1QGeKeAX1mDcgUxYqdS44vw7gRQ2wKig83 -tz1gNoWB9w4nWrRs4ReSS4ysL6KzPmhiXVfW -tz1Kp41S4CoyeMLgieTKUbR1auVUggJhZwXL -tz1QDiVh2FxYJuwxzFf4EzpBMcZ5E54zGUGQ -tz1PHLyj6maUmHK6MJ9cQeadzXTbH1LpR1pq -tz1UZQ5PqhE63yTUGSPCb7Bsj1Y9Vo41yCxf -tz1ckcG8kBP6qiAZuqz5VMTQr8fLj1RS78UE -tz1aZ8WPLEUTqnSzr8hYacfxwPpCABJiEAZA -tz1MLZpS47XbscCSdFeKYmYiWXM7hsuYfT7v -tz1MSVD1uMaD3dyNTKMyKce9HugvjkCvkv6D -tz1gUDKHz8LxWak5nygug8XDvKsYSAMQb4Ym -tz1MH2BgdHb5LhKZNNfrPYBK8A48ykaScxgz -tz1cd13TuuZToozqNMqRani4Asn97ggYGFao -tz1MeqdNfReA3NQv8iT7gy2jZEV2Bt2cSoSY -tz1iCZmWJQ1zqG1WkwT13vdzXAiqDcA3qCRu -tz1haCNPVGiiUsXttCWM38pmQH9JGgMwQfbM -tz1RJzz3dfzoeDrosi5WyRWAUz1XUEfCYcxT -tz1RWnj21urqHuBFvNqJ58dB8HY3FajzowCF -tz1dzP5a3bgF3Na3eKfEEcZ1GPz7dXXwXYHh -tz1d9Guck43QchPYgTtg412Z8fpMvx97BeDn -tz1TC2UeEyR5qh1J1NbhY6T4RvsPRBMoUoQT -tz1SB44VMctTGbUxmpC8CqpuTu7ZuY6CFqkg -tz1XAf49DUcDwhy6wg6TApbKpgbzXNKR2jhj -tz1RfBDqvpoqq2oT6sSe5hHQgh17VMgNMtkN -tz1MECT6osdvbho8Fd3YbiPFGLsrwPuecqLS -tz1a43DKMiRgQbyA3VDSJ7UssiCJi64PwNjC -tz1gnZzqzAcbjvZCSP4W9j6inExZt6B6PhtB -tz1P7W9TfwZ8F3srLqFvfMVkGXN4kbSzPGsm -tz1RP5fNumGrbhLWN6RFWQywtBnVjW2m61za -tz1TpsH77VmL4bEMPtaLuLSVFncoZdCZTyZp -tz1frjCNjx4nW4bL6D2b9zrMDuC4in9Dxaiy -tz1SkhMNgFkSqfu5ya5jqTQLTdwRvHtT8LUa -tz1aS9q7xutdVbCcJdfSqN5vUEFDjsEUzo9x -tz1exNs4QYkTw6HrnNBfv3PPgB5KoXhcyYpq -tz1WVu1cGmJguD2N6YyxWuFbh4xgj1FVmLNA -tz1RMDuZRJakkKUUQHB3qKAvGWMqkLBJKPFW -tz1SR1w4aLVLrpuVSMm8KH9DxJCdCEYB6Y9v -tz1Nt4WKeXnShCy2VCdY9zkvGMarfpWRR8a1 -tz1dcQMSRqaoB9AsfAePkoB4LS2SovyAYbpx -tz1fTvuZqgtQLRnmeUAzT8m8E7W2Vu72HkC1 -tz1U8zEc8SxrqnsHd89G1Qk8UrxCgRmJoMy6 -tz1RomjUZ1j9F2vqE24h2Am8UeGUpcrf6vvJ -tz1b7HkhxAmuQBH71qG4K1hY47Rpf3maCdjo -tz1YM1QLYj3vu7GrfDyrgU3gosvLGx9ubpKs -tz1aJKQfhaTs8cSgwH6Ak5kw7g4MRGCu6GU9 -tz1N6rnAukWSvFkuaxwgQnT7cMZi833cBbiq -tz1cj3pMAsmW33dpGNdjWyYnYGQ4p3PisAe3 -tz1d6gxZJ8YZN9xCn9QnFXakP3mABfi11Mmr -tz1VKt1fjarunv5UHTQf1fdaa9PvVFRYeZvD -tz1cGPxtDhf6w9Ef4YHHkUzjxfeE3WAfLdG8 -tz1gdbc2QNTki6GgL3K1ZLmY9UYQApnJv2MF -tz1dze39gaC5XqBQJgo755wdcsYsnuq5WmRM -tz1RFd7tGgoDsKXhY7zjvvLjVWkfHNorNfuY -tz1LjxpiGedueK5X98cUTdPgtYoBKC6fdBw6 -tz1c72xr1ZgBkjBDNDuDtzdJs3X5DCRMmFs5 -tz1bf6sufQwnd5R2A4XBoa7Tmtv6Gcw8gtpz -tz1SGxUyzHGk4FSXtpLPaejtSCb3v8jgRQgP -tz1gx5Z7Xvc6a1dcaxA7LzHRYJ88TLwzzY46 -tz1hVegLDjdAEjTmc2z5sgzkXGsjGFSyVFqm -tz1QEN4bvdRZx1GbQGLUsKD6A1zcSkH5Ch5J -tz1hvdGdVRffMcEyHJFuWu6qiKRA91XJXg8N -tz1RZuzBvpxYhRgHuowb5yU2ttVKRcC1Ra1T -tz1c2qhpqBFFF5xY5dJqMPPGmM4SVW7Fo75V -tz1VFLhmjxv1j21NTeSxghKXa7SvdV5EBpnt -tz1TA2Q1oP7gvfLJsjoqZjBR9VADeMUrn32u -tz1VrQHu56fuquo2nKewbWX39mmKmQUeP1ms -tz1PW543Vciq6HVcH6auir738ETWH5ZSVqTv -tz1MVyWi5WSNUUkRzpTNDHjuBkZy11UCDhyF -tz1doZ62LHC99WPAetioYKteTRnLgA8T4euM -tz1PJoNo8zXHv6Tqc9XPrMDVXJ3prcqZusHT -tz1bsqPYf6sPcDYQdJ7uAkv4ypjf6HKS7THe -tz1hPNLn6EiHGZddMKDQsS8ZZCad42NNxnwK -tz1U4fFkeEdZdJP8iu7y4DBGtKvSEHo8ULDR -tz1g4Lry3ncfTdznZ3CnXnRy7UPuF6hnFFbq -tz1Vf8qMFkox5C57RuS9JQHZFjdzXjy7SVKW -tz1ZG6vyRRLaVeMtgJXN13S75XrNYM6o51T8 -tz1e8mY1tbtBQ3CuxfrwMNmq1pM8tWZfzCjL -tz1b1FYDTDkGgAm2qS2dbv51dg9UcmhQxZbr -tz1eDzE1YBbyCJSis3zYg5hBoaNrDQNPR9NT -tz1QJ5yFDo2T3eHUSdN9eSshwqnfAUMyAv9d -tz1fzD1Pg5ha6HrQnoqyJBCx4G1Gu4Rctjo1 -tz1S1oDRRG851BtUvGNJC1XwPYyUSvtctGWB -tz1LgUKBEXzPtRWTK4eGDZ9eGCTXbAmWcT1o -tz1REfMf5bTWZkXAHap3YboixqfEV9BmGSpf -tz1Sg759qaekzddZo78Seo9kHpqb1jHfaLCP -tz1afmycNV1f8MkGcb6P7yzdUHvkp9TfbDee -tz1YAaV7TBwesbW8h7xgyY4cyauN9FoboHnX -tz1aC8qYeu6KizkBZqLsSoS6iHfGsSKpkqne -tz1Rjgqj8pcM7hcSY3NcKfHp1LyUFC7XA46t -tz1bKHhA1AwF4UBMTxucKL9zKQSmfeHsQ4CZ -tz1VxaBWBLApUgRytSiDMt2kyZZKqhe53wCk -tz1QzKoETySu8dpKQ3Cx7JJuTwVKVLEWBm1u -tz1bhwTVYB7tvY3B37v4BMv9tznRmF4iBSKi -tz1VjeSz1hBnQCj1m24syQ6hP9dPq3keCXah -tz1ZGCC8DZNqbv6MhARMFbhgviMu9qku9TfG -tz1S4VHn5CxuZS8QLeptfvpgTpPu556E477n -tz1dMrcN27XCrGgWfwX9X298K74MNXkNtM2K -tz1NW1Gb4a3im8eFnyFHhw5DEZVbno16Fixr -tz1WQ2nHoQwJkD2w9Z5N9A8jijNRg6hDSvih -tz1fZ84cRZ3kUk9DyATH1VJd23YwPPTKggdp -tz1d4G9cZqV5mzWXXF3GFzH8TqFCuaa1Wtej -tz1ikQdVJbekp1wAvUZVd3arsCURh99Bx1Nh -tz1cyqmbfioSXerr7yLXobimydL16LfEchMg -tz1cKjJihS2xheQ9Pg6DfquESuJC8AZLdwaY -tz1hxZkrkpGEZhFuBzrcbaoGYY7i8c4gZh3L -tz1NRYEZMEDEj7d8pEnCwPYzA656ZsnZ7XH4 -tz1Tn9R3p765fNwPX31CZnop8sq6tCRTJx7o -tz1NuuRNGeqSYrQ9un44tVRuRfBHZkgfUSK2 -tz1bghfBrnYfCoT1gTRoqv5LUUrpfJn4rRgt -tz1Z7wvaB15HEcZLC9JrJaXjZfzX8JRaHrBc -tz1Rh1jTTUo2pdFFYhgjQLMCTR6jgXLRefEo -tz1MJh1ZzfzXaad4j9LRBRukwtQc3CjcpFZb -tz1NphWPsq3D4ijZstthc5LMfgqpiTYarTMH -tz1eqhJSqYaLuEpNkM472FMEdHpSw6Khg9t8 -tz1M3hVayV9rLu8KHFd9PDf8VyJtUYP86PUd -tz1LzFs3iRkxwQongUQmi18so5kftxLwrCFB -tz1hvKN6cZPQKSkVr2qaTihdqoYTLicVcRwH -tz1bn6DM5XYxCK1cnHkjnQRJQaZaXataKcU5 -tz1RSZJc8cz3x1VSnFaXG2xSF8rkP1T9DYka -tz1UqPj3wupjrSUCUHYVx23tdRp7XP77fqT9 -tz1Vsd2Bxem5eWE4itEDK3op1DYBdNWPQfvV -tz1TjfAJRAfJUUTPb6Fo3GYYz7efvmF1pXgM -tz1WnPWEprjxd5KtfebuMmawzbcPqR6Jno7z -tz1cm3Z5mUtch91WUdoTDvaH1pQsgHKVm67W -tz1KsGHDmozi11s8auTbYgQAi6Ud8K9dDDQ3 -tz1hTKqCZv6JuH9igJB3mgCco6wykWVfeNmE -tz1ccnezjJQeVdiK8ZnWGBn4r6GC5xRoFhjX -tz1iHA8Kjsgx9KAbH17Hz5YrGVTjC2GTzeyw -tz1TVxjx9HFgaQXUBrTCcnQmG6eZMtz22pek -tz1hme1JbQtugbJJ7R2XYqfNQYUByQ9Sfo3h -tz1gyrYXcrW9WJtQqFMuSyyKmxynoAURDQKk -tz1YC9Ch6z3JTi6GHfTM4AhndDodQNhikD4A -tz1fKoq5VZymGTPxK2xNgLWd9QYTipMx9eX4 -tz1XxPzc97STKZanop8GGyo9rqnJQQ4bgsM1 -tz1Nr5TWyE8KmL53r6nMcrWHtJwQNNJNiepD -tz1fbzT5rbQoadmFqqPee6NKbLjrGT1EPWeb -tz1Z1hjVmfUqPEgrNs2cYsDLgQQfmC8QEqHM -tz1T7zPQ2MSeqi1VC4VMWMwYoQi3zJuxZHdR -tz1TXPbPh9CaxAby31PcTi52HLhdEDEtpcWK -tz1aREzocyJFYW5ja4JEJzD8PW9SMKdSnjH1 -tz1hwxgYXnbM2PMXAswRwTvNpC2THXKFtFe2 -tz1XbvQQzvRgEau5Go4aExKSk5Wht8dbeVyt -tz1cVhJ444Xsed4pyZKHSaL85f3Z9hFV5b7K -tz1Sdg6knC9qNsDCyrfuBhSa2M7FkrUHa6kG -tz1dF9egtw5fAYxZjYi8fo9QicRXhJ9RSipU -tz1P6nTaytuna92UpqqUAhbVm1FsPGahgxQk -tz1NrZKX4yidzXMvaVBdEc7k6f3P5N9Z9A5V -tz1ZW9mYxVzs7VoftBPt8yDs312hPuHQ5oh8 -tz1S1RwjC9BWFWbQz7sDpvKReZ1TkB2eSMCy -tz1Pd6upKxPPJysjJXxk1J9LSq9jYU134TGA -tz1i29U4HGLAKqhHfkzhqE2HYd7tvFDvpPs3 -tz1QKCKsgpikmRvu5orqoUEmyFcMtBE5g4E7 -tz1QjVVNu7yeSbR4AxqQX13eBqEEGVzXuUCB -tz1MNnTV9iMfDySxwUksdyrJbeAAN18uEXbD -tz1Kt51UQ2VJHSALp134E5Aa2K1Kf6wBUbAD -tz1gSCubc88Gm5BzsFw2GFTEnms4A5hiWRCG -tz1Psye7MC8ofuCPA3r96DifjaJiUeX6ub7x -tz1gKT88WRvdXfTJM3zdz8CM1gdMbLQJK6MQ -tz1bu5tddjC9EhPqZgdCzEumqjsJDrVZpK67 -tz1h3ffwSDyrAj788d9sRGCG59EYXrpFCBJ4 -tz1XZT8igQzBwhb5zzK4WRvDPHQaZ3w6KCnP -tz1XELbGWKiwExm3FuAVB2WEwiZ8cmh7YFiD -tz1fPkDYg991Fy8sVgADYZSLiokWG2NeAgb5 -tz1ScUi8yPqoi3iwk5C3xpuEyXcNCBHBDWze -tz1S9Fu94GznLXqmRCqdtNyiUuu8MTarggtr -tz1fLkiQ7u8rAHdSmBxpqnqMCCSy2gTbBwek -tz1VA6TEpYH4b8HqCdxxwUTa9srdpAgzm7B1 -tz1bJEJ48uartmHLusbkvxiLh1FTcGg4qCQS -tz1VLNkPYmyoFBKES6NF8NWhkMP8bVrzBTLM -tz1eVJVEAG3sL3AkUySrQzzeDfMgtTd4So9j -tz1KjyHS33ehB1jffEbNhG4tYCKgNf82Uu2a -tz1XoSbetAtT1PzoCgw1129qZ9vJb9Fx1Ged -tz1S4ZQH8q7ueukRNxAbJodUU6wzryXGwKZE -tz1ibEz1c7guWEduH8oWNYqr8Qim1zTqPiyi -tz1dFxbJhWkqqfnrkAvx8WPrscqF8reCj5BD -tz1SEVD2WLedgerH28X5hXi3zLcRkjW6WJb8 -tz1UUN31XJes581rbVvHrD4YnbJ6dK9K4t9J -tz1h57U6A9zsUs9vpbx1Z2Qwzvw8waDPxf6X -tz1XY9UiGmBdZhvSP4zU7U29BmbL4gjynTac -tz1PB27sPwmZ4aEGM7cXJDb1K1ypsiQuAF5N -tz1UMHKyrwdRohZp5TphJrkHJcSNLVjXkqiM -tz1f21XJLxqte3EVnCQkEAz2kqfuYQg3CzCs -tz1N2ci9ZQSSGrdv6oqutp8EZQD8pKRGLCFG -tz1NSCNf7hibnv6e95Lw4VASPdxYjQb2JhZ1 -tz1YUqr8tcRYv7fpZ6kQP6GLv6gYYA5Nui9Y -tz1P9b1pwteWwnHnSh7Lqq7Q5WPQMwQN47Bv -tz1PUfQYMNBCVAeMYiUSYAsjA2RgxYDbZs1z -tz1NDbACaCQkdDW1urR449MbueHF6nP9yLk4 -tz1aeU24r4Lrff5c6tJtSV2F7iigaL6wfrdr -tz1Nza1qDxuFdvx9xq6WpjjSv5WQELNEbET7 -tz1Tipw8i8gX24Kever9M7KwFbPoTLhLffEh -tz1W5qbSvXFz4q783rNfDDtKBonSKcG1pQwR -tz1UppWjVPh4R9ENSsnoRjnQfJjj535m8dNq -tz1PRxT8BLwPWcJtz4fmz5QskJfKYgFQgomC -tz1W1RGeq4oh1YnrKa1KYcAccUWXP4VyjupW -tz1Ucn375vYfBP2pbT2W6WiLnH2K14PjZ1uZ -tz1i5kYGKBpjkyEBRJj84W6zJe21EhiN3qzV -tz1XjFQw1RP5k1L7n2M9VZL55ZzgpxpTn9kQ -tz1R1bModU5MwrjNxPMaooxvhNGQ7JA1HSMk -tz1g72nJvSEhfaH5VjMzSGHAytx12CxNcmLS -tz1XuRhPwCX4wXLv3YkjpfoU68AwGwZepKBL -tz1f6Vk8xEb6wnLKiH4AbRu9GK8HhTtt7Wzv -tz1Rpb3wskZRNKoYKfByaKVr18yzc8RfNmoL -tz1hY8Eai1HFU5EYrx2ZsUxKJnDGduLmjDFN -tz1br6Zdzem5MjoCMoQyxekZSsHKHxr1FdLr -tz1PUYTDS66DtqkDA3K7KpYkfdf5Nv2esJsM -tz1gceNSRjXxaJoegqsv22ZYEWoMMVpyaG5C -tz1aiz58ZpaC1RGDYJrc6WRkwfFWvkVZgUfu -tz1fYodb5VCtAmkYGYLDfqfenKsLx7pFRobG -tz1NASLyyHDve23G4eHjL2dkL9LBzHrfTgTw -tz1dcMBeQynjpHqcjvyYwKhEEAaNsBWWDiXE -tz1eqw41pBo5wb5oiyiZ6YKnbxWXfdSmmXo8 -tz1f6TugfSajTMD1KccMyLE9AFTJJeco5F3B -tz1Q8RnBHtq3HvU8GezzFfeXBkQJsRkCSfge -tz1groFkCQ75yurrrxv6VXCAL9DCsc2PHzkU -tz1ZC384Hn33qPLuarkD5AxgQknGeW4AHkE1 -tz1LtX2Vkfz46kB7KdEdkU6mjTcjkxd1ZbZ5 -tz1brkhVrMrsTC4dJtpjzyvE5wGWETjiFDyG -tz1LELqgedguyaWMEbjMag4PwE7xiHk9GS6w -tz1MH4Hhk5CFYc3mCTEcKCn99x9GN6whGzQs -tz1NxqpzrwW5PBejvj8hxf1opKqk1dAT5tzi -tz1RCuADZgdipVaH662ZRPbYW8KHoVyawTfp -tz1TSNF7BYHzGQAu48VmzvuPbMXKTBnUAyWb -tz1WsXtg7LyaEC9QZ7bDTYrW2SQqAChk6G9o -tz1M4uFdztNvXwKZa6QtsLTf3jMpcDjJLbcm -tz1WYPRT5Naz7ckxZbe8SEnN7YCLdsNsNW3F -tz1ekzCpTB9qNxk8S8T9YqxBDpLqg4EEVDdC -tz1Pbvfwcra2ztc2PUmreaNK5RjGjigvuuPC -tz1P66jSg9Ewd5YCRhu15T2crWSXdRPXeJkS -tz1M5VzQD1Yq5oa23niNTi2BqF3gUXKrxoLs -tz1T35tFLGVZ1HCT2c7Baufyw7ZSCLjb3H32 -tz1QfdF9LEoq5tgUHTr5DozkDpNtgE7E2EJJ -tz1MxbX7s2ELbYDhAAdxwjJFXPGUAVACVXPo -tz1PH1LQmsDTB6Afiipkrchr46HM4MHoYyDP -tz1dMdzU3B8no2U82UiWht6JiqaJCPS8yZst -tz1UEaTkoRSHr6btossShfqxqh2WQa5HvqxG -tz1QpoXgsd9jtR9fkV3ssqsjYnnQuB2RC6zp -tz1hrtQDjqW5JhXCPHReZe1yLRw6SYYsrkiq -tz1egFhJRAH4Sv8914Scdbf8AKjQwmFrpA9h -tz1edckWxLKeYgW8dgkRBREqcLRK1MKivuP7 -tz1Uz3cSu9ydLmixdasn6Bp295vTzA84ZXdp -tz1RkhaqTjY9taXT9vp8Q7YEbrJbVJrmpFXF -tz1PHhsKCqL8hGXAkhE1qXYxJrABedWMWEmr -tz1LoVuXcHP2y2uvUVqKFq4WHPooNhkBnG9J -tz1euKoZ4c7rr131neLSy3CQqjnSGoRyMmAv -tz1YpbxE9x5Si4tGoRMGVpagM9txabEQu4gT -tz1PbGeWGc3aMEjDNZ9U2psh96zF9t2BFyyi -tz1i6cZCHcGT8xP4HD1rYyYfdtW3f8qjah2L -tz1WrbyGw1beSDv3aCCo2aV5fQ9Kvo2HtkeX -tz1N7nnaGJjRWc1sAcgaYNqSJk6ZXLnqfsD9 -tz1UpvxTKn8tD8yBWeJqcumrZYhLTLRhMnJg -tz1V6uHhdQaDz5qwkStsbo2Y67XnXuEXX7hp -tz1SjqwrnVrRQx3kTdQX9dqPxxwnuWi79SRr -tz1ZWDsKgQTn1ih19JHm3HJVpKcmfjexZxkd -tz1UkyAdAaz7jNrbJRwvVWENrdoNcze5a5sE -tz1X1jScnTJMZCa69GyCN5QEeY4vxWos3FLr -tz1f8Y9xJcmEn4SihEtGzvY7kRSe3cRpcEwa -tz1h8NnDCGY3T29iPzheL5frEzm4QDtnS9TQ -tz1P1TXkWNLXU65fAj8sJyM7eVFQGUXuPss5 -tz1hB8eoircdWQqZo4tuuX7CpD2Kyp55MgXx -tz1V99sK2sqLUVngCtG67k8eqTYRw66nyKXr -tz1XLP5XTmMZW1U3fkS5jX2jEwXG1WCgpJgv -tz1SsjSVkrq4731X2QUpcnqVnSq5pzfMtyKB -tz1UxKrpA1UKH2GsgSZxUgqbqbCpUy8W4W1S -tz1bETwQaitW72pPwsocA4FraBqX7vG45LUj -tz1d1qk1NML7nj927FG22V5pMfXdkxQsWo1s -tz1f6nNHknqgUArRMiFDXfnXnpMHsdoLK5vj -tz1TeULx63LjRsVZHCKoFMJLiFoJpR9VvhiX -tz1hY69NVAoV5BGxHPia8zPw9U7LG2fG5yKw -tz1W2esyEH4T8onYuKMhqQYdcHXMP5HjLpDE -tz1YL7jCFrTEBaCpqm1LP8bw1AEvb6PEnPfx -tz1XGTWLAkSQQCUm1fq7abKhtf4Ho1kVN2Ks -tz1P9QAMgUdMVxW84TKK5xcQnekhQRtkbfcN -tz1SsXpU2vXWWbvwNxGS1suUbQoUJJJigLH1 -tz1TewJvhyZGtv2Py9aQVHKJfHSUic9a9XP9 -tz1YKJs8ujt4b4fPTyTLM9TUcvPhobPCsiWg -tz1T11gb1GW1vaARL8okMDtkg72EKMMKK5kC -tz1TW1SNZDQAVejXt9SFjF3B7QW78je4waw3 -tz1VXJv1tC52jBa3ZyDzH7MfxQMSR6WVM58U -tz1WzWDerFMaQ98KaM9Pnqgrbmqo6ckbnH4r -tz1ban7P7LdQrAsQqXDiQwYu1aD58rTLCSMX -tz1d8bQZjhuzzv9huJB2Ls62G43yXceMnR4R -tz1cVL64Y2aaS4q5PkmwvmBzbAKhpkTPGCNd -tz1UqsbChbYZVt4vZVEBoMBZKRX1mEFVqGg3 -tz1dbNzTE2jZW3SDC32G9buhF1JPxFR1eBHd -tz1fxwQsRizE4gHqPQuGm9HBNUbfqQzUy1VN -tz1aM3P88QnpDxLAywgs72Q2fivJBEAFwjm6 -tz1TkFuCE9EXwxVdG7yvJnoUux34gDET4QzN -tz1eqv2xwJeEafvuhtJ1SsFb4UNdcgYc9UVk -tz1cJTjbnLWKMKRndG2TmHmPBvuMQmbYXeWZ -tz1ZYuVZfQLJeeqGedQ64gQy96BHEjHw1CYN -tz1ZTM4zK2Xnt7wv3i519zPjmWoY8UqnuASo -tz1WkiusgnT2TgHhCCiZ9tXB2LFqLixHARTh -tz1KqNwF58K2yG5T66j55uTJY9at5ouXShwb -tz1ZgjCBLsaNbMHWsmbkSUEXjd1zoVjpjK6s -tz1cHaW9XQZpjPG2kfY1ddCDkZEPTK1ZXtVU -tz1U8uQ8Hc5zcqagYnGWGHx1A7HD8XsmRCkf -tz1Uorivnw2XEgQ8TYxHDGYyW6dnvn2fGyEE -tz1ioaTRYwzPfbMQXMfZarz7oNeF3vx7o2Fe -tz1TKD1qj5ygFdbpXeWAojP6cUP5ttESjz1A -tz1W8KCzV2geGZSzHeAGoj61CfKeB9zkkcv9 -tz1NQkd3NTf2QTQie8ky6CyrHLzgCbpy4WG5 -tz1MtT9nBy7VT8PvTXbWyPwQVtV9gWMmqdXE -tz1NBZsJ1PV1CPbgVBJNzcDBzhr11PEKTWsL -tz1QosPQ7Tbw7ng16ywgSfnEk5Q2xVFW5xPm -tz1PotP4tfGckSCUG9BHTboQydPS1NcQann8 -tz1dyS6sYRsekdFgUcL6FL6xWpURMjy3kAhg -tz1UHqejri6G6asno35ssfhaFTgvGgmXZwjp -tz1Y3LXJErgJJ5jzRo9EW97SSPpFoaRjhiVn -tz1hntEAdV5eWJjhKS5f2vpu5SyabZBLfaAs -tz1VaV1FeBvAhXobFy9yrZi7FfcP8gU2bHnS -tz1VZoMVDTTFCnSbfBJ8mJdLmViY8pZS6vQA -tz1aqfJysyRVcbcJwjucraZnBwriJfT1so4t -tz1i7yKxKB5WmWdNbh7XasxRvZnuNAQVLpfM -tz1V68wBy3GbnivvUo5a4JrRmjY18Mehk67J -tz1NiU2qMFCguWtXvsMuNudRQETsd7UzkFuG -tz1M6hF1mh8ynTJRMBYYVc2h8T3htinKL1Wy -tz1MHACjaWuRgSPHhiQF8y96GzH1uhfdw88u -tz1XSkfo9RQrrW8GwDZ7i68ZqMUoUrxatUbz -tz1ipaGAcahU1qDiN6zSUW4zmbt3nDBSSLYJ -tz1Ld2XJ4PWmHjTfxNaBSjs8gFP9kpeQ1idT -tz1Z6TRQ3B2xQmxmfYKZUaizd21H2ZKPYJio -tz1hjuJfFTsY3wtDFbcQ1M8BvWvuKmyPcDrQ -tz1KuJW5U29VkvnfqLP1nEWZCm9uYNfy5EfS -tz1PrPpGx96S2XsSa6cYPQRQN2dPCbPtWdWW -tz1egtRxjhNLFCmTTYLACTzLM7yaR2BuGj1Q -tz1bqFf8jAwgMFQ74wHQdj3p83GCZYGsZjCs -tz1QvhvRJuauPMreZLp3Cdbm9UsyigbuwBsR -tz1i243RtJCEdvXyiVcRbtSRWEQm92Sy5E99 -tz1NHLRRrQxJ15zxBBKacGgeZKct2yz79vR1 -tz1gWSN6LxEPWByqCkN2NUrRXXvAEYQKKrtB -tz1hvXXQzsdehvC55kMdMm6LwBnmA9NXFkD5 -tz1aoe8AJpoYx6vrNKneXsrkd2DQP7fA31fg -tz1h8LRBepHuech9JxjaUyyH25dsF772mL1W -tz1Wdv5bvY7L1Eg38uFsR67LBE4spvLBr7zk -tz1UhsxKuNYZ8RPmjJ71LLN7Wvza6ihb6H8x -tz1e8tSm1w35SbQMfyjXt8vVfCaVFR5dJZ6o -tz1Q6idUhYVFoGfvgrgF6y87V9XQqM343oZz -tz1NfLhyUYy6kab8jU82VTSJfNXjm7zgFPTF -tz1gPc2To7moKDtdMxktbGU6BV81r92M7SUk -tz1SBh8WofJy9iUWtTFEZ7siGQpjkwNc7HTH -tz1XXxm7Y4UPf2KhRsWZFF2NVMpQCSRT5HzE -tz1bqu9SLCPfyFKyAmg3jmwH8r8YFqa7p8VD -tz1d4Ky4afaFzgdz1sTrAgwXqsyaD7dYyVsj -tz1LRvJpoySbrNNvShriUfVjUzvYJaJ8fXHZ -tz1eM8UT1E2QhnxCsWrZVa3GHfS8FyRPX1wq -tz1Zk722WfYbXGNcyAH9rEskwk2hD2Ba2UEz -tz1gFV4xHXdXi6zF3C9QG2GAogyaFx5uoGyS -tz1emZxDhk2w1duHHwUZkYHZUNQWmiaXFM5V -tz1WwkeBphixY4RUQ7E2q56sLMvbCiGRfrTT -tz1MbMoZDRmB6JMqQzBhtMed9mDW2xFA9eAi -tz1a77e372RbDcABpLZ3D26iQLCue2F6YSUU -tz1UmUn2FaYrHdKzotkhwvaiX4NV7BknuiD4 -tz1THAD595HcURn5K9aK41nBjue5jGa7cMCY -tz1gepxVRCu2VsyhHnkuSJxUTv38crdc9y5W -tz1WwBgw1CRuwfNYZ5KpJEmVDDUPRzuPH8Vy -tz1WhnmfAyX5VrbGhcJGr7PPBAXDV51jRGXe -tz1RQ2smm42WpKVvi7zvEtPzNBiYpdpqPrEY -tz1efW5oyzW7KHYP9BWJvMt9cxYFUgATfwEu -tz1Z41AgsofNM8jYHSx4tZ5yt7KzuGDF9KE2 -tz1itZyzFSY5nF4EiiwVxJxVHhNLUo6nZ6PL -tz1d8TMBfD9xrFzKkqEPNaJQqR9X257WT1Aa -tz1YJhEMScYhaFnNLzPY6rXXLc2mzME5Rrpx -tz1YRguy7QY3VjNQLBL7bRR58ptJ6sc5M1pw -tz1XbX4NtmaacZggfrqW8SaoVP2qqRvnzT6j -tz1Yjd2FDGw978i838DVSPDrMU453Pr1stkA -tz1NNx9zixiirzi3ymrv4eWNbrt9oewdFb6x -tz1bXrepnHjSyLLCky8rmWEuyKyb96APrSUu -tz1gwRGLpYBbmZVKzkPxMibv7ggmF6o9ZShK -tz1iD7GErJyfuSKT5UPoyvvxZtDRKvtXnGj5 -tz1dJmDNS3tt24LbuQNg5bRUKd8zurkvaSuB -tz1PW681pKuTsQe5gv2gQVCUUEPPxzqn7SDy -tz1SVpJY65SxMggMpWq5zqG2UDRKWaoRsbeZ -tz1UW1XmtpVqwRvAhWRNmTSCQD8AtP6kMBgJ -tz1g76LEpfZwmJZRRMHJhtWn7J8gsDCLRFta -tz1U2BhV5sBytH7nB97VKaFY9c8eSWtUAJf6 -tz1VygrE856CT5hzfGaEnxsimyZXS7CPMt32 -tz1dWe6nsjvVLEQWuxrvEucnJ2PG9TE8KFCh -tz1VjqYnhrwQFZYr3MRg3MrGWJC8yWC6x3mM -tz1bHH4QegW5Yua1nVSAKm9yiy5Y7pvZRgxe -tz1VWUzmpM3G16WRafGk3CqS45sh6aVoCDJZ -tz1LmGsBoPgT3yBxVJzpA49Sy5UD2fXAW8sE -tz1ReAvX7wpBV4JrPj9ZPypu9FJ5Xy63QX7P -tz1XHCdvepPa6RyJAcwYVYGFG4xQSrgPHQGL -tz1TtyVrMrdfM2v2i5oT8iUhFJDqC7PaCPrX -tz1Rn5LprmJF4xgNbhLsPwNXUDjyovVSpLu3 -tz1di3ZcrdUz6FtHaoPPT2xk3GsmNZwREuHA -tz1g6o93bPuEkWpRuoeNE2XGomxUB4rcm6GX -tz1V5NFYjtJ1mM2BWeYFVKWAUaobNJaRLegi -tz1TmkU5XgAhDzveageftAvNbMxVgQ1PPfsq -tz1aeyyhv25bvUtgHEHATP6gaLUghZFd4cbr -tz1UMVXAB4VwtGjVoXPFp5vTaDNJnY8WTo25 -tz1bit68hAKHC6XXAfpwVsqFTX7ZbfUVzWjf -tz1VAHJV3vNfrMWLZdxvLAFfWTHc7qsJBcTs -tz1fs8UgcA2X6GSwLjCoQkjKhWoNU7V1TCVo -tz1eZDNvEiWLGuuyGce1A3jfMpNXb3Fnr4kx -tz1hoK7Z9L3r4nKc22XfTdxxJJse1Bsk4NvV -tz1f51jdww9nFUcfmjr3ZG7gVtyCWB1Lizi4 -tz1NuP9urQXpskVTLo347wfK59qmwBgFAfYs -tz1KgAPLpBGe4euTmAfv9oMu8nSB3UVPVoPy -tz1Rnme17PfEPEq7GV1RUsiDSoVQCYpg6hTJ -tz1M4cYmhVqWKEPJJ5DKPQAkoSnGZh636kKb -tz1Vcr41btViVnoqbxVq9sguaNNU73HPGbFa -tz1RzHsNnjiWwYi56E1RXtmVf7U4t2kPDKL5 -tz1ZNLNNn6rHgbnD3cSCREQsCmdgbs29s4R5 -tz1fG1hzvbhNWU8SgJUDagA1dMUKATRY4trY -tz1b8u7igWushas95XU2WjZxK34rGJQYS7eG -tz1abUcTmZ9wDmE5kERfYUohu58ehUbL5XA1 -tz1UH7gQCoQecUBHLQWRzuFMDK4DVcxfTi3k -tz1UDNMzByKi1SsyHevUKU9dkHZVAmspU8j4 -tz1Xq27RqjZzKR6jmTDvgitqzJUMgbu2HSnA -tz1aT7WJehzKvzwba4jrTHcSuR4gA7CBUqgd -tz1T3WA5dHSeX1eHDKFCMkqzZUNjRSrHRBUz -tz1irY3DQ9PPQAx5YEeH8sAHJuykSY6MpyU5 -tz1f2ENzEkMcdrXdcnk2ZNs6uPfC1rrdgNej -tz1WTW5LV2Qms6VjUr9usXX2LzkfSCR4eajz -tz1Qv3PCxGH8t8staGsznuFLcKC9sevo9xBG -tz1NTMaYTBUQYG5SdMa1tuGgP61CkrJSmwfc -tz1iw8W7dWUxVvoC7Qd6Q6sFxKdDTazBb5bC -tz1ULZu8wt9Ac4agF8sdZutQjjZCw2HcYbts -tz1gK6kVaU8zcTRL3LiWx4uE7dTMiHDKz56M -tz1WSxYvGP9BJExEnnZpG6PZh4yFcPjSMPdg -tz1cRWHH8zYK6RhzwMMNrTwXsiQ791pYDVbw -tz1b74j66ibkbdgZoyfguPUbswRDhDbXF5Rv -tz1UuXsJhQCfceLeZu9pWM5JAN7a8NVFXfuq -tz1U2t3eyhj5cWHXwxKNN5RHFihEHdGLY3Yy -tz1VRsk8gPEWJv3CgY4QSLR5ULEX9t5UVe7o -tz1cCw6qYMT9ZGv5bcEJZD6HdsYjtRBdPwHu -tz1Kh7LRShH5eBzCVe21fuJoQHMLgPrAXSBu -tz1iiviVgtiq6pQRb3SAb9CMxTMPSeB4GJqt -tz1c82HrEHFRBzpBHBbLeEZJCJzw4dvHQo1q -tz1MR45fYxVhpdhznKZz8XbDGTPX59sExNxW -tz1MNFfGtbG9no3MHyfkBSvpNE2ezXduSw9m -tz1cjHDv5wcZANhGt6gBWZffZj6aYncd1aXD -tz1UZvHPXCJzrsZ81kughtSo1NJwC9mCNg7U -tz1R2CiMgKqTKhuKUh8of4hDX311uqUzjQjN -tz1Mwed9Rm3oVoFt7WDb2ug28RLDCxPEoxsq -tz1XDPpmJsW4huRJ72AKsYSL6hrECUjSBTaL -tz1WMuxdS4ezFXWuNcTSD2PDwKdBJAakmrdY -tz1edTquGDJjA4qiJVjhAWcNSJkzoJjcS66J -tz1XTaR1Dg2oHoKaNv999VpWT6JiPW8hQsKg -tz1e9L6fSC4TxAsDkNkFccXUDX36vyE7Hx6b -tz1YtSuNNjvDBDD1pHgwPc91SPwyyBNMLXmc -tz1iEzwx2cz9QiPJuroP5rGuJMCn5M1TNrTC -tz1Y7tg6v9mgGCiGvWKgSN2i9yFkSAM1uThH -tz1iKAxB9uS9ciZcWJiDLVbSXh4XboAsXRcG -tz1Y2QsyvFvhj4YWMZwE534tFdYezBjofdGb -tz1ffzjnMTc7n6v42ELSGAU9nepa5rerFp6R -tz1WWcsguo12EofgHSJzaFxfR99VDm1CY7KY -tz1Yw5QjnCCEmwQQJ7mZiAo9m6bUJdqCpXuf -tz1ZceDzhUF4jdS1ooLA4uMbSMmU5KLcA1Do -tz1NdUB2CdT51VJvumzptv3CzkJ422dAmvtV -tz1Lbm32QjAAJcd6HkrcvKYhptpY3ZnHFYLg -tz1QRbThYdyoFMHZDHv7hde9eDZVp9hCrn5F -tz1SPCB7aopkHShh6BYPrqBiJLbnhGWpX16J -tz1YP2doh3eGsyh4TExY722SzEozeUpn6iFt -tz1XrCypZFJWjLq3Ky8QCeHXgtqZomtNk3YR -tz1XFMaet71sawjaQDqjdarYJfEZ1ES4kJBD -tz1QbEafemGrXpv4MQp54asy8HieGGF4oMDb -tz1aSwsyEbm59GrETUKoK6BL2zNyuG8gphzH -tz1dFXwoCiqzB39mdQSxT5jHqVVmuKrj9wpi -tz1eZW8Xq8728By2YyH6atYfP5r4TDejLxA2 -tz1b6yV8jsSdAmx3DzL9kkPadDwaVxNkH2n9 -tz1QabrWJPmwoRhDXsMwSrTTvzNb1QCXFcLr -tz1ZagbBXimEthJ6tabywrZ89GXtCoTcULdq -tz1fbYGfGyFURZx9vxBSSbJCXJohtcEs1aXL -tz1Mc9um6MdFG1Vb9Wq8eyDKXoWWpKfXbfiA -tz1aJ2YStNPp4jSKwLDwM1aUXs7RjayKZPwJ -tz1LdULRiFgaUAoNJ54Rk5norMPeBY6Yzubi -tz1QgwTVgPDV2qQQAe43h1xVLjKi8Xwtr9cq -tz1Tr5FJkaMin8T2LwUDs2xp4LD5jxf8Kpn4 -tz1e2yUW2LfVba3ESSFVZyuuiXJZ2wgzebQ8 -tz1gEMJyhE4SvocGtmh35wBEuMsffxAhN3rM -tz1e9JJ1QZ7aoac8XHNHDbFe8GBzk7cxkMm5 -tz1TXXpcjQ1hx9ado2Mm66L9CiwKEk44ikc5 -tz1ZeMzzedXZUGZmQeJkDmZCKbMQskuRhDjy -tz1Qs9TkkDozT4aVXk625K2qCTsTXS2YrsTc -tz1Ra8YPz5R9NJQZxRTs2GMMCrhZuGX3zHy4 -tz1LyFRygHQNsJrJPiZTAfDJTtJPYN73rSmu -tz1aEwAVXHh1jcfVsnFLUtkagayjtwkkGzmP -tz1hoc641sEpbJVgcEv25YArjokfSxN1xspn -tz1T5FMpy9skHmZcTgR9hqhZDCtUyxKU8pFG -tz1Xw83U2seD1YiXeSCPnDYbCnvkQ9W1sLVj -tz1QzgRqDW3SuTSM2oCFMP9tNLkgy3CTibaA -tz1RPi4m3yirLUx5GwDqyBuVcC6pZbYi1TtP -tz1MAWaxd1xZCN9zZzmrAWsc3WaQ3Cbh4eMB -tz1LeScqqaBug6N6aTSMGGEDpr6Z7Y13jtPB -tz1fPXZjz6GGAjEX37LcEETBSUqJUScYRtqV -tz1bwMFSeQP6qs3q853kknyybU6ZvHd1VrNg -tz1bbPJ7sqdM7o5RbETzWfV5uEyzKnBUegLa -tz1QfPwKu2yqzGcCVVNjrPaVxC7QMXQkqwb6 -tz1gK5urXwNGTWYFtYiHTc43oEm29K4CDjLc -tz1gZUmPJkaZWau3p9qkXnNKeTTpZaRxy37X -tz1biJmurxfa531AZnYvQJEsPTkzvrNiJYi7 -tz1bDtLe5Js3Y93p28gWTwMfxaTXhXyMTR72 -tz1Zx7iEeUWYKDxPuZ16VevAm8JkiUd1EGMJ -tz1Q3snWWPxxf3LaMJu4NFgz86RMmUcXcR2S -tz1VzS9q2wrNwHHe762KBPayaWzEMWXYG17i -tz1NPCxegzZH6Ej872qmaUdS7tsrpmdfdggm -tz1bPBXArNnU6MmgHDQXEqcMSpzYDUnrobeg -tz1hdAhYWb9N91NnAZrQoGtiTmm7dEoKxd8T -tz1UL1ogpB5QTCZSnTXg4F83wswgbd1ZNGUv -tz1isb8hhzCGXBAFgwZ2gWGhvu6YFxjT3Deo -tz1KeD5d7AwhiHkQiRhtnWgJuEawe5Fnp5E3 -tz1cahwZFmHNJj33iKeYpMacS4B3YWpqbNV8 -tz1QREhfNKMNbCDZTqsgbXMdpbVt8FY8a3GF -tz1PaWtxGkpEt1bKw85j7dpnfeVvnM7TFuC1 -tz1YFejn7Cc1Mnw3EktehF75GnDBDPAdTnwz -tz1MdWD3dq1AKLaV8qG3vHqexSduuwvehFxg -tz1XMZNHCtmVTbhXAqphA3EFGpjtNyDgfJNn -tz1RXxcodT1c9sXuAdN9WSXLBhoN5FUX5ENw -tz1cdSiLrZLnVhXFsHRPZXHd9Wz8yBmot6fa -tz1Pm3FMdnWXLKF7K9jAR3ZWaZzHtY5aSvCN -tz1eBMHj8Uwaw5nJLbABQah82drsGe9xX3pP -tz1T7NjB2LrjsvSrD3vWW21yDSHiPk4za2iZ -tz1KkN7MzQxEuMZeq1EGwHuaUst3LYrtW4Tu -tz1aTVpjyyHcXvykQgGBib6KT8k2R1NCe1SP -tz1L7JF1ghvTqoAkLiHD5Ze5EonsYAaD3pv4 -tz1NJwZvBnou5aLigAVxcjbTh5xurNJZzq4h -tz1fJaExcFLpxK3fbwWsEsoaMJqptK1iSk1B -tz1YQj68qW8dJ761fmATdTfHaYJKDJqbPek5 -tz1a2es1VN81msGcxd3SPcUHT7Ta225U9G4J -tz1fponv2rP7VJLRpd42pTStJ5gRk2eB75My -tz1Mub6MEZM46P8ASi82tebYGBxfoidcrsvU -tz1ffTNXPq5VWFk7uLJ33TxHW4K8tEQKzYSp -tz1h4EW4AXxUW1MHARDDCgLiQWFpP6sg6rgv -tz1LkN2nNX6kQHBm1HeCyGHWyKbQN4fMbnvQ -tz1V1NeWb4MXk3UbvXv6HcPuRDDc6q8T2i1P -tz1NHQaoRLk1RmeEsDo49Kw49XNvtJdyWUQB -tz1hNWqdLWJdJP5y7JZ9nTJKeG9M2kWR5wcH -tz1TMtLBab825RZzo33imKrWRHPRzKS6E3rW -tz1ZiywenB8SowH3e7PRKSvLs6q1hxiQFWXV -tz1Z9MTGPve65spdAzd1vEXJNnF5VaaZ965a -tz1TAstWhznqq9bgpbVCS2b8Wc6oTanqn1je -tz1dyvEdnWbqCpgKEzQngZ1VXBJVp3cLnM9V -tz1dc7ZzA1J6pUx8MdndNXJgA74CtZQuL8nD -tz1cmEnknyxvHKeVfmS55GMh2s5AAritFEDJ -tz1VBxagsr9bUvPEDEZFzm3zJCowQhuuqTmq -tz1Q34HVeX15YDMhSNQBbBqhmqeRGCSjUMjN -tz1XgVgM5pqxDwtrfVK8wJxwiwhXcEXnnWES -tz1R7Gx4qngucPez89BjceSmKj71V48SY2ms -tz1V6JYkmZfAf2gqgrKP4MeH5Jzt6bsFW3j8 -tz1Y5rL4AevG8trCbsocy8Ph2xprdwh14ot9 -tz1XRKCbPsukT23EzvuMs5PB8AsrtdQcv9Mp -tz1VTBBAXVVPy8mg6qfZzTER8LHsacpajkHJ -tz1XtFyrNx5kEfr2fv7pZ4gRaNQiAKk4Xc61 -tz1SVK8L6kj5RGDR7RBveTVSAr5C5nVjakBT -tz1iDJQXxAUcLYcoio4Yf1NktwjdPHUXrJZ4 -tz1TsrKcN52rs7SF57gengNbrdkq4tZFukaD -tz1hNecCRxJdwaegUBjzgRt4ve8mP7XWjrBv -tz1gtQJHddh6ptGNb2YrwyfAzpwBYRthJV5P -tz1gzXw797r5nqg5LJfa7fG9yAcmmtx2CLbx -tz1i87tKptvk6mYWXG5RxKfy2GP1Eq4Cf4Zm -tz1LDBq2Ca6nS8J3sLoBCbHQ7ENSYGvKNFzR -tz1hPtjbeMf1Qw86fMRAibMPeUfbFmTvf6UQ -tz1LSRaeHWUfBWpyi5FT7ou3HAPtU1mevU34 -tz1Rx2VkMovqexfDvDm8PReBDMciTjn8oYg6 -tz1ZPy8f5g3RBZcV1vxP65G7U1n8VKMD4Hqg -tz1Wfp9RfuKeFfEbDvLF36zXHkGpxJKWjtQK -tz1VoksTEDuYDwpwiy13giXTmDBwiw2D7Qio -tz1M1YtEVBz37gG2NGUHeJG1TQF4ZzRts96u -tz1RHZDqr7p2yfyrjKZFkMasgqpfZxEoqi67 -tz1iYs5c51YVhPj9N28ApLCiHeALNitwjoLr -tz1bFVzxVisNtBavGzvKoXzWaJmAbo9vEDHb -tz1VbPAd1tYmeW2eoJYsskaEfKURpW227vkb -tz1fQXPpi8jB6ZtUY6MejjziABFyjQtBA5Z3 -tz1LCQSsEjZ8P3uUCcyi7YZt1qLjzgFwQWsG -tz1RGWfuxutBX7pfUGSfJkzVxdEbvGj9SAmf -tz1cPcvKqBy5M3QtVMFmP67D5SNg9TTSsv4y -tz1YqLi5a7b56Tb9XLG6LfMb9uTysnMScBgt -tz1bHx8TXKdNz6P8KwDjZk634rSpY3mAsmPv -tz1LmCYbhDdskghi13aWcXeBdRbBNKiQMgYf -tz1hwZbEvu73Dfyh1wrCqa3U5Fx1uebxpwWE -tz1P6zsudvPn59oymHQVqXURNhamDh8h3DTT -tz1drg9Ra1vJChrdyVCw4X2QxNh4KFsfD9vS -tz1YscsK9ELGfxf36NDCnC1szw2gNMoUh472 -tz1hTAppyjfvj57ikHBYcx6Lm1mJhUVotxNr -tz1QJ9tnvcmwTGBet1A6fLKy3mjLxuZhFeT5 -tz1YKD9kLYETMMH8soeQ3g39e75ZPCK89sCN -tz1LwoCNe7Br1adzkE79RPahtDna4HYri1yF -tz1RLQMEdQiyWYsP5A7CaoSiJRQuTbPzWLX1 -tz1T4eotJz7BnERhtnaEKdYD86tGaMJgtazS -tz1fCB76PppCqvp4fUrkLqca9rVuKKJsZJ2a -tz1MknseqjiZJgCRzLmvBCndZ1mmG8ECvuvy -tz1YtHiARmkGadnNkYMrwmn3JY96LwCQnbrL -tz1MSXudeg5FCr9qvthsf16zT1daBnXPytnN -tz1dwHHqYC1oHdkqdPKFqUwyvWVE4e6jcqov -tz1dtJYuGJ5TQrxw5Vscp14gQ4Rtw8GqfLEn -tz1PjysHZdrPeK7PKsmehoeAZx45XkyPrDqj -tz1UVJ7RamyLeWsTE4L6N9wY5xz2U8WHJ36d -tz1Ppa4poPahc4p8StttuSpA563DGRdyaE3D -tz1ge7YCeMTtkTPgeL6MNDWuNxq6w28JcypV -tz1MRXM68hWhEdEWaGC7N2jeBHFSZAt1uxAE -tz1b2X1eywopKZ17EKbPXdsfza9bGPh5bPuv -tz1hSP5kWGU74Gq3Hk47j6w2dTZpMsvjkv8K -tz1XhT75rSddqP7Nb2nRkeeCcAqgfF2sS2Wm -tz1Rp3FfdZ3wrv5gBySR8B3SGUk66DxQWr4m -tz1PMf6X7ozW7mUncPHgh2ZxvCDqfugB8dxb -tz1heh5cNnBUjiZsa4WNPeK5iHWcW9GiZcgb -tz1ScoaKC5ZQcwcHb92QZYJpMPScCM8KK7vw -tz1L8kYmeCfyqprS68bGLk4ymoJy7PXMo3qx -tz1UjVCpbJjZZ4yDEBcGhRkZ8p3HaGSiDa83 -tz1hL3ZAvQ33vxd29KduvcQh6qYXNrwowYFL -tz1SA9qAFhTak7cV5xVswjh78hJAmUpqEADU -tz1eJ4VPbNBNnqhcxKBEpQiqUfWDT9MBNKPA -tz1MdsTmfWJ6m8RfAiQn2nAgkG8yai6tQDxz -tz1aecx3chbgE59jkzpmd1h51hKW8PnQWiX9 -tz1aXgpaPcVokkoDJznuQo6eZD8tf29v33or -tz1f6AqEDVsoDQ1ZNebw9Kp7RdeFmpmwoQmA -tz1RWCadYuMDoz3zNWg4oPQCynzaGVB6PZ1x -tz1UFxKHSLMqjQafPSPbzSUN9XTXJN1p8mmQ -tz1iFSZ16gnhtuK239WTQ5YHcfEuTJ6zu6P4 -tz1Zg1Ly6RiKKawxDmubQX3LK59FmAXuDjbU -tz1iDzTD7Ui3nuyauJg2CtCNhBc5QjbVzAnf -tz1dbnprwdNynBHkV86PnnJ8BLA7ebdy1JTn -tz1fB8eYmEtoDcFa1ewpqZK4Q6mGiGtTD4SP -tz1hEdMArNHnjtVt87AC5rD8BqRKx8uvwJ6U -tz1YdbiFvNde1a8NAtjDJXkHA9y6AKx7hVqS -tz1cPUjiifmB7gZd52HKFZnUrXqTatfTCPKg -tz1ioPor1vRcTJyKpaXJzKr6KZQJLV6pGmjE -tz1R5rGcjmmah5QHZNvrQXKZJP86eUsLRcrw -tz1Tw4cfib6D71ZzNR26PuqW3Yne2Aa9c8PR -tz1PLoLP1rjMXdKB926EnxwAMB2Pjd3rcTtp -tz1YwePiNUT2bCWoTDCx8o7jyRy2eJmUBV8j -tz1ND276fmKdhLPgAx8kDVbc4g2HXuujWRWW -tz1hCXC5jr2dUs4cGay526ShAZxHNVarkHFh -tz1NC4xYfnaepjkLR1DuQ4jGAbzE3w1JVdNv -tz1LpUmbjg36b25yqaoABJeCZUNRG6hXX3o8 -tz1QAhC9zTup4KqAoRjrLQqcBzz7d1enBRPw -tz1gLsyizESQgYn1ANbTKw9Dnv4FUHBDTSh7 -tz1aR71YjrsNhNQLWWjvFLRNccBopqqXAPuu -tz1fc4DL3RUNaJTbR7QsBMY8qUKBfLe8xRwW -tz1ZSotY7zw6uGP5KtTNpPRYhxS9tShneDJi -tz1iKFtQyjhedDDNJgqAGbqPKdbxAWaENbBB -tz1XWaeuLAYaD9CMJMWJxnTGW5GhJ3HoVa9p -tz1NMBFpioTdFcvZzuemuDzQ5cxgoVLNYc2v -tz1Sz3P2rSejHqHBiXdKHSTkDZMyRbWd6Ve4 -tz1fu2gjweRDpQD6vBsbSYHBMMK6tjajnS1c -tz1YTeRbWc32qPokmJBbW3Z9mTE6885yEKv9 -tz1XoJMYZAohvA9PaWyxvy6QN6Y6kp7Y2YGW -tz1RY5wustHdi5p7XX2c8oKcnuwfr8qx1sgL -tz1fCmTDA6gvFucPwNjM9KLsvhDsroradxka -tz1hfeHYustiwschxwnX8sqUpmb2EWSAwzEP -tz1cd6Q6awXF5T8mXjNTayd8cmTD9kj2Bdin -tz1XBKREYjXKek8myeAcb6aDaDBCW1QQDYiP -tz1f7xiiLY73CG5VXgbFuo7c25SbmbjBotjr -tz1c7osCE4fX8rUPu23wpzJzJgC25YeR1Q5r -tz1S6Qj89ddqwn6iwKkvZoZ5ckxT2e1hdrSK -tz1LJAz8124DTuAinqds9U9PhhEi17LVdW3w -tz1L5p3G7rNpWH1EP9vSwBwat76vrugUkewt -tz1XVoGqQnzWPW98hoqrPqHT1e2vyfq37KBA -tz1hpbeS1TgavL74RVK9X4ho879c3iconumH -tz1Y8fBtFLd9uzGUKEqCM6r4eXFED5St3fJH -tz1aqMjeQKShjGsQpWm2TtwpNLnhm21MTf9q -tz1MyGPPDeFup1eoxGZgFRN6yvy28HrDXoHk -tz1bYKiQsfyYnnKoBij732BG9ujBHdRptiHD -tz1g27oAQsv68Nb9VV6LA4CG6EEAHbq4XX1J -tz1NvjLJxnWS1NSe11Tq769SjEd6SnbXR6Ef -tz1dV5LSviw51XY7E11RLYicajHcAAm6nPn9 -tz1P1Yq3ZJvnjC8cjmkfRCY7BrXudQDHriTk -tz1efN9FDnVfBXHC7xz8ArxKVCKZzCrQxu1D -tz1T8xNo47reVjxr6PzvFN6XZcEXaSng9Hdg -tz1Ma7mXLT82Rn7Nsk8oEEWg2rffJUX7AhYp -tz1hwF5sdF241bdPE34x82WzrEHciRmSe6h7 -tz1d4QLeaDJkJS2ZZ26vjUMbR6m4eWg8g6xZ -tz1S4YQ2S8pu8VkWEGfrPdMJVj9m7Fj51jMi -tz1QzePZzkmJUeyMEBoRs19i5bV9RB6AdX1f -tz1LavqcobW96RoGM1yyvgtrbFA8qncoM6po -tz1eS8fAytcwAy1gEoCoD61Ypma1qsnNySiu -tz1iwxfvYJNXgim8bo54YWs8Bc1JztxbxqBw -tz1R4mRv6X3MHjiF6ctFQRLT6Ze4Bp7nZRE1 -tz1TyzbJMnk1XELYKbjQQk9Uat3Zmzxz6oQp -tz1Qixq7Y6dutroMfYGvGo4Y5zGr1WhZSpwn -tz1QfsTCaMmX6v4PaS8HQBfYNBDtcQssXnQY -tz1YFu9EbPo4A3eA2cCgBDVvjJZrCsQzt46G -tz1Lkjk6RxDuJaYnkXWY1KXfrXur2RHFU7Vy -tz1aLwiDmLtLup5DfMVcEvaKF815F8Q4JtoP -tz1XPwW4Rwi8cZg7d58GUykfxUU4ZKFVMj4D -tz1VfHnqQ6V7DDCfmcDZEExRo9yL5ar64rc8 -tz1XJmGVTjSHtJruNt6s9acyKV8fCKjLez2d -tz1hSn2Z1zRhW6crmcgiWJKQMEYzXc8YbRwm -tz1ebhHswSfQPWPj7uPrarBjBGTXpu8HiozU -tz1g4KCqfJ6b6X5Baoc8mFQm2uAQcxTVKrDy -tz1bKY6g8KSc3v3s6GwBbwzM68wcTNvWWSPz -tz1daTM6XLxALXMLxx9zNH7VuwzEmWwBxiym -tz1RRKZ9dc9AMqzRJAfNi5q13wGrMbHgAVPJ -tz1cW6MfbcoTg1HVh4eJ1nXgUAKvn2L3MV1j -tz1WKnXNtMAngN4QhD9TA5cD4dWvbFbV1H8t -tz1fXdUSssQjj36n2mXrkxcdJS9USnMkDA3h -tz1dVxzTpX1XZFuTuSkM5FM7gz5oPEQstGFt -tz1TqBYJHP93YZo4V7VbThNhZdkyvL6fAZ4K -tz1Xbmrd3h7eVsThaRNAyx2m8wUM9mHdxs2n -tz1d9nfGdFgbF8WTGziqL2nc2CxxxrgSF2Zs -tz1NysvUrMGeuLcudYuVBsiNWmiWfW8xtgjX -tz1KuABea8BKH2LZ245skEWKdYxrxekkQyRd -tz1eEyh3VUvN9m4mhTqwCEsm9gf1Gkm3CSXd -tz1NiomjUdTpVzowGNXT8GhpdhEuQmNLh2gz -tz1KxCBTRQRk7tHammsvTpWwbXzAyiNDgr1g -tz1LyQozX4YHEFJRDa9b5fJB57pobZvZCsEN -tz1XpWFPkMWhUZP2W8WVv9Uv1kZXTMAyv5WM -tz1WoNg1CrAFiViPFCWtP5viSuSj7BmeoDBc -tz1etZAvBDmmuvPqVVaG9vjvy3sHKGu6VyoN -tz1aQJGkRbcMZnzaqnY9xfyHhgHTxUkET2bZ -tz1daaTsJmn3UNXqZjPGNUtc4DiReiXXxBon -tz1SHtT1FpEzWTf86TMuRtfxvEU1NDhG5Mef -tz1N4oNBzQ6vnVENTozyCXBf9tBm8gG1mADM -tz1h3xcHn8gPDjE1BjUM7nJdhcTi1ipwz4Pw -tz1aWGgB5R345wMFTGMXzgFPZJ6Yz99QiRQm -tz1ZGZBaeScd92kU9ptByYyoDcSP2iWyU8gY -tz1YhVJurujvmstu8EiBvnFgjbTVeFFpadUc -tz1Yy5kcjxj8HkyTRzYCgB6qBfKY6ApbyxBt -tz1PD9zZTHXUEGTYHyDsDdURX82fjaHhpstD -tz1Tbt8A6RYv2FC1BVr5EKdEw1ctayvdFY1R -tz1QNoDeVkd2wBM5E9mXSW7sCQVSDcbz638s -tz1T8Zhhxg6sH9DkLUvyd5esWshgka3sFknK -tz1fNsm8nUUfvisFhMYYsyzEU7p1x9Ns5ibk -tz1ZGgr2ErTFXLZd6gnbmrZY8zaqX2d5UQn1 -tz1d3jNZ1bzMEVNjxncUw3Bqd5ivt3LJKiv5 -tz1dCGHVkB4e4mKSF75M6HqXKA3MB6A82WBE -tz1RuwZnDBQ9bR7Hw6cbkmYpL5fFLnYmfSV7 -tz1cHkBQq9xLDoKSUCd2EjpjpwJRd9FRG1aN -tz1SZDLdKzmwqPb69o53CPnv5EGx4YSz6h2d -tz1L4hoeGQdEbpdL6Yutdi7rru1teZc6M31A -tz1X8taQFXJ692gCyLHeJR37wEZSMQEVzxxe -tz1hHdisBntRG6RiDLiGaRsDTtHPUxvbBUaw -tz1bE6dCQx9b6td6o75fTHsdraHin8BdVnQK -tz1ZZmaJtBQUFVMcrabbAD4AqGzho37iBx64 -tz1dMJK5yp6BLfU6ECJdFkai1Dy8tHVFjLSS -tz1iHZho3gACmbqu2JSSJxb9uTaKyLuqseyv -tz1QUzKfmnaSg8FpJd7WGwvs4fpANMiokWBe -tz1QZq7aVeyYuZVH5MgB35Lxu16ssQE7SgPf -tz1Upqx9a1EVPU1WPCNXErd7MDPJhiD1zQZk -tz1hXfR12q8PMMAH93TWKsrgj1b3993Wwf52 -tz1h5dCZdkZDw6iMSBheuZWsY9i35DaN2chu -tz1ippzowaroQiTtSTc7Xiveim3N5xNz5x7u -tz1TtVLncKAgY7YEEBarm2pKHnPb2B9BCehV -tz1T89p31jp7ZqB32BRXKwMUkBv86NqFR9c9 -tz1Xgt3oKPEAqkLYk4Uefgy6KCtooonacULa -tz1gq8kY6HBSynZR3gsnnG5HyihpFDuBiz6G -tz1f4R5VW9GtNRVRzqkHyBv91PRQLJdm6DAD -tz1P1TLhYyzdyrTm4xYkMdy9CYwbSUyh7dSS -tz1ixZjyusyMvsFp5htbZGG3vRSqpuuF136Q -tz1V3M53Sha3caxUMRFZTxtcMFDNCTKAFTZK -tz1dFKV32rpcrQAZb5aqokTvEgkcXWQgpA6e -tz1bj3KWVrTXFTfAiLdQcz9fBx9LRTgu19T9 -tz1Trkhee98BszPfKACv9qQS6iRZLvALDV2d -tz1gquuuYE8ypX3reEBFmN8NFDnFni7KYDYM -tz1Pc3jq35h8MKHtBdTDNdLTEti91DKbnZAe -tz1iF9432ic5AZFi9DYuxXSq5ysvJtDx9Jgz -tz1QXkTH9jh7jKUkPmQuE6z3hw4P2uQUEmT9 -tz1i6NmDTeZ21NuVjyYu22TAUXiXsbo193SV -tz1KzUctx1gMxxjgBEqB52paVMVqZ2GpgswA -tz1X3x6Bvrg2B8BxgH1m7nr1KXHiDwd8B2cT -tz1cVgePYhXaAsw6HQ4c1JkEzVoXDKcDMCVz -tz1N8mPjQRSNG6WGRbUXi7HctSn8wibEcjUt -tz1RHR7iasBhq2YYM3SZMw1vBhtHTy3aDfD7 -tz1PZsjUpfyrWhMVWLNjxVPYQUPrXQbdQu48 -tz1PXmitijBgVLj9tqfcFBuR75JPybeDpzeX -tz1RfPNgiy2AAaaqNHNw92rA8Qs4RQ7oFzRw -tz1RcmFoQeXEe6Kkwe8GpitWSvbsn1udABLr -tz1bXuLr3JJk8EknGLJPNBSp5WhZG3EvumZN -tz1cxUkq99nff3ADAfT5Y1ZvPCYqmgpoHybH -tz1fwooVTa6jgny1xNw3hpT62sdqaV1s8uho -tz1i5ASXC8ZBfJZ4HcZQopQbd1T5Smk5TQak -tz1WaZJMi2GjQyx3ontdRUfn3Ksm42xfkVeP -tz1a2MYkUZs5dJVJn8kxQ8rFwQJZjD2NK3G9 -tz1KtXiar4FiECnv4MjDLjwS71QNrdom4Jss -tz1MQESCE5gLV7j4QLx7Ui6CrQuP5owUw5cc -tz1Rto3h2Q14GMiiorU7TfSKjGS75cNpVwCt -tz1LGoFdsGMatpyEv6D3XV2cGjRFRktiZXDk -tz1aQ7pGEHs6ySanKKFVfW91azJmAA7hrY6n -tz1VFxr51Wgfk2w7oGaoHGZigwxu9Xrq7eGk -tz1PHnLwUZSsxTh4iAP1zXNXEE6ux6CqQcCC -tz1hcX5oByfnMuzsZNmEKTFf6hCRrasUEqtQ -tz1MkavJqEzUir1Ln7NNVDeRki13CWn15SMm -tz1Xme6tcuMyBeUcTLV9MQUqyDyknDhmmxRm -tz1Wp65QG1PjXP31JoKFqaWFrpbMUZ2tnTnq -tz1g8xBgYNytkXiaNu78CeDVWLp7ygSLSrD3 -tz1YimnJbHS1fMWzs5ejNTVWmHcubdD6dEz9 -tz1VgvgSHsZAa6gc6yA9J6Lhzw9mU3qBCKe7 -tz1g1icjMe6daW3B7DSua5cBTkVgQbneTN8U -tz1Q4pZikejnF3E4VaNEywGt7YMio4VwhqqZ -tz1fRSCHVLo7a2ogjUjA7U1UEwfdWS9631LX -tz1V9X91brMLLqkyz9VbzoV4vAjBzDJdwpzR -tz1cbmPqAYdAexpPADEYaVKshmphPik8j3cw -tz1cAuzpCVwZ8PWNZvYeK6NnvWgVnnHnhq5S -tz1UN3mNWRLo9AG3D8iQE9dv31uLokSbvxPo -tz1iCiAg2MDZm1KxBCJ79DTDysmY1uZmJ24g -tz1PtpDNnw9gdcUk5AEBNR7W1nboasfLzSan -tz1PAXb9zeJ87V9AqqfA512W8zNr7rEh5UhJ -tz1h6WyAFEqtLHqJCGzc2ePVAP7QstYhMrpB -tz1TVSb39Zr6j7Ahhd8uPEon2Pmy5xSqEhhJ -tz1WSns7TcAqsdpkhi1qaZWt5g4TazzmBKY3 -tz1dH3mZC9bJ1G7Soz2FSujmDY8BqayNh9iP -tz1TkQCxYhhpzMop7Da6g2tpa1Z2giUbPdqv -tz1P4xQbfwDN6VQf7AdtogkkqarVUgDiRCqs -tz1fMDDy9JTmej7WiHMjQUT5T1CWF9ns6pED -tz1SKcvpXcjMzcfejCPRmgBXPjTQrCaMEoob -tz1XJJXrZWrrMgHH3QNirJx2BVj4cwASRcZx -tz1MfBYMyLmaQXiNpCgsGMKAC5Q7NPN7qKek -tz1deTc22gYAwr3cGrLrhEYXnt7C7hGYCemE -tz1b5X8rpyxEjbzqGPPLPxad2L825PpNH8G4 -tz1gR5AhrHcBxTYASyi5SKpSf9g3Vb2h39zD -tz1YmhnQLcd2qfKrRtBNNn2LUpkRrNLRZbTP -tz1MwtjBBHF7kDKn3i1fXkkZ97dMmC9nwWZt -tz1fRqngVFeYpMiSzqKLBaKBc7xKr9eECg2C -tz1YmkxtdFYK4v9TYooW6yeHH2aLEyUbCa13 -tz1LzcR9q9vzeDDEb1a6WThKxZB2o4EQZz8t -tz1W6nNzWfMt1V2PQyuUFJ929USbMcVE5PCj -tz1e4sDbiMV5xWH7idw1CkDAw7fjbrCBp91E -tz1SvR9kwSsPS6f8AEtSVXnyeqnpgkDrgaNk -tz1hphz8ywUtxiwG3kpe9oiMXrobRqFBzoAQ -tz1NTbir9ieV6PWCnbfnaDAevJhkm9gDjZ1f -tz1RrVn8PvZ7dSit6L4B1H3LKf7TeMa6gX3Z -tz1hwPvdvzU1u2MvCH1NJDBrkMXBCr5Z5GGv -tz1P7zKDLvdjRyM4EgTSp6jaSK9xTPZhxdaM -tz1X66KEtTE3E659tz23zaxDyfX4DZt3wMTQ -tz1akjjfuQKfnoahB8EN8UmSyfkGeVrHkt2y -tz1X1px3cVRhtzvQpavG4bsehKFGVocKByCD -tz1gbRcoWeKnxM3JkRfFop8omKobkWnGn9Dt -tz1f7UTT96U8LdwYqjKQDwFvbmHmFGoKwCT8 -tz1RumqZbBEbcGa8UdLCmKJNssVRRLQfiW2X -tz1V6vVxAT5tvULhWbUppce81bv6ePsJP6Kd -tz1Wqx3zPbj9c2i2UhLQeAW6PwHavdwCApnB -tz1enGRP8VADABVQigqSZ9GRcM8mMrEfYBZD -tz1SJCkXQbdB7zDM9d8CZssfxrZSuAspGexN -tz1ZW78Z8LpxGstKVuJCSsT1t6Cnns9C4oEo -tz1XH1dfdqQRoffSN249rpYnVTHRHYyHfiK2 -tz1bi7Zm4Yof8HFfXDAnCf7S6t2GejzxBu2L -tz1dBkcfyR2sqtcNQVYCr39CuPMijbhZsGQE -tz1LtbGdNSgwgmF21Mj2tY6D7bG1gss3FcDM -tz1ZM4YaW5G8Z13P1XtwdHVj92EqUsSkgiXE -tz1Kwr9o3UifzvgjewuThZAkDC8RKam5K51t -tz1WZcpbeYAhBgcC9iCMQSSQJjApeskjYQuD -tz1ViMko1NbNUgwg3WRP87UGSyt3AWQszikH -tz1Y8P2sVsqbqvyYaxLxLa49bUT6rEyjJaoC -tz1gRnJTacWDBtACs4Fg6WrGDRtGy1GkQ3PZ -tz1NL8qKtrWLJxUKK8LZR1oFLD82tLYTyXAx -tz1SMYQHy5xu2wJ43BMFS55JH29oxLCLngCw -tz1gLj1982daS7uksKcY39NHEmTaET7XvBzA -tz1i2zAp1TCo3iGaC266c32Y8jmgyExTZBXs -tz1YNjCzWTy6rxwj5gc35ykqBfUF5XffvLL6 -tz1Ykiih8LTFQnqt4ZS76KwcLAbAKj6daBwB -tz1TiT7WyE3SGQMSdrRnw6vuAWwHLMnZXmVR -tz1WieDouLM3BG1rSXdJv9mR2i4Mose9Zwny -tz1bxFfbcr8Xm7N9AdrqJWewZCtoBTUx497Q -tz1VVdRzug6e5NYNewt72f4VSK2VRo49pgtf -tz1gQe99Tyiva1XbhNj8F1w3oAn9GmHvSaDp -tz1MfSbsqsgnhUWK6xw8Y3wkgRsX8wSKTwHx -tz1VKsrZsLfXdg5w86LaDSVANYS4ZQVk1Ep2 -tz1gxPKHdYRYgcnUo19ccEJZ93sKh6j9jP4w -tz1eQ1kqkAFuXgmajZ6tSzkTvsSPHDMfKmeG -tz1NRyRLTh4ooLmLdwChpfgfYqKCo4zZ9UV3 -tz1USxPpWhEa7ub5WnUdE9di1hxZsTXru7fu -tz1VPr63DjmrEgJHHyjHrXaUyLh6xuQySMDg -tz1MXaduA67Le8MGUowU6n3K99QYLp9cZAZV -tz1fcKBDpuHYkk5ioW5vbReneshJA2HbjMfg -tz1YTqj99YFDKaEvR6S4ccxZKZxfVr5auAHY -tz1e1hAAGyZfuseYbpY3Vo7TV4HS4rayH7UW -tz1aGkJ8iei7WRYv5B9X8jUREXKPkCdWBZuw -tz1MKKAreJz37875JqyWUTGhwErCaeMWyvcx -tz1PjAmNau9Rq1ytMKqT7bw1oEFvhfTQMwgT -tz1RCniCuf4J1SVUmHDjC1xu2wgi5vyjSzWJ -tz1d6UvJrPmo75fziN99ZigQ4FRC13yKS8xa -tz1cmzzNBCH7JA8Dx8xrLrEoU3Y2RYwNccA5 -tz1Rhw8ow12LErWwHtu17fwssbiFVeyvJr2m -tz1ZJRwcUTh7JvePw1RCAEyLe5ufCtyoqdvz -tz1eehyTkmYAnrwpA3dFiDeBHNVmLtFvw2vp -tz1dMX7eBKhefdcgCWZJoakC9XnTY29ydLe5 -tz1iBPD2xWQ356espLtdLmSoCq35g3LHhRpo -tz1VhPzQ6EM1jvt2jULbuFLRqFEmCN9SgQqR -tz1WqgaMYpnDsFAvNWPMmJNcCBiRZn68wzPi -tz1YVRfzrDspNKBQKVddFGoUZ3r5p1x2FScP -tz1eUPqmouyeFtS5pcww3u2X8bK14kNYKBnG -tz1hSDHHpP8sgY3itb9gSQronSGrf8i6nxFv -tz1goVzKJS9DEYHu67E6pFBDw8XoMgGtXg5e -tz1gSPq93txBeKxcE3Tk2eLPTQHLSy5syEBw -tz1QDfytyJ4nUpzxdDMvNxd6CNhrL6gurJky -tz1LomHhJVcp7VGNxZoLUSQ5faUXa8bC1ZfL -tz1PUDeX8HL5nL8gfnvZdTyqSe9ZBfAN1eTj -tz1hduoS33GWcBSC6YaxD1cQTyCNp6MrMGeB -tz1ZLmCmB8vMRDe8JJo8czojaRBdE6CnDuU9 -tz1Yoaf9WDy8Azw6rm6iUGJphZBAJVzbU3ig -tz1TDRGJMVA2JJUjzbiDjB5P237vdS3gpquc -tz1dUd6Xu7LYXpv2kTzCtRBeuWgseidtfDP9 -tz1SyQKBAMcZr5fB1JUohX9JxS1TNxTq3Xy6 -tz1bgmbRoHPpA8eY1ZQQn4kwa5sMEPb5vJjT -tz1Xs9ZsY3RpembyHdS3PL1NbqwYNaivUrA1 -tz1hTbsNzqfZxysQNXztZVVF9QXUoBJ2NhZB -tz1U6AQ6VUdJzZSkeC1wGF4P33ocimqcR5Xc -tz1gHwi7A86PEesNHwKvJetKM9iEard9zCcR -tz1WGXssLSu65ovZuGcMuhbcp3Dw9FN1C6pS -tz1RtXezb4BeCVRJZFRksjU2JaG43gPWXGg1 -tz1ffZRascVn9sTLaVPUGNW3MLwUdMpeeKj6 -tz1MmFsfUBeiYGxiQHUNmxRuizt6VHssczHF -tz1cTA21hKP9c7J1LkkKh1qqSP5m23kKWQZJ -tz1ifQpxaqYmKCJwz5Y3tyATT5vCKi9GuPDf -tz1eUQVv5FWNv5CUJxNR4fTwimxyPupXErwt -tz1iMJ7JBGELP8pLUKrguqfc1Bv2SUHxiuhG -tz1cSJ6wmcJLP2bF7cBw3EByvRceZXvcnm7J -tz1dRjb5KL4wXMmoyxragLm2DwbLpVY3gypR -tz1Y1MhPRqRbLjvJRoguQXCe5bUKp43vvqgN -tz1WYQUtwmhcjC1Wwpj1RTTDpYMRGaMQPgcW -tz1dWaBSe1ZQqBPGh4196fYKeueEV7u6gzYx -tz1fgnmrJhCJhVa4AxZvXYVHNxXyErUnw9M3 -tz1cv5UsK3rztJbdjkqtcoywJ9a9xWKrmrD8 -tz1fDcAfc6uZFMz32oJFYtUrpqU9xwXKLbND -tz1KxdnXcMdNfGC1gsJYFLAgMXTw1KovnsN1 -tz1LR8qcxMgZd7HVeRwvff9SGEsY1Zv4t4cU -tz1bXpjStQZwm6hBC35icfnKJXMjCqKtCVPf -tz1LMFQtjQVbFg9rQi4qguwBMY5VvKc97gYB -tz1c9cxHUd5tnvqzSVYPjXKHeFasiSm9zpDe -tz1fxxno68pTsZ5dw7mw6T6mKPEi8AX2d2aJ -tz1PNdhFxwCfWPTf6UAHSrQ18Q1iTQ7zsBrK -tz1UefUGHzNAS3pJsdtJAbSBKbcv7pgiLvf9 -tz1bWzbRVdzVJzxf3gYTrBNax1v38x6u26K1 -tz1ZbMMLFaBSu7ix7xwJSPHKS9EowUNvavqB -tz1LnFTXgs5xEsDvHMcvNyKzCkZbkaujR8Fh -tz1UBwJkQnQ3tsTXB6rL8xsSpeQefm2TTM38 -tz1ca92Qhrew7cdDMZpaWhzq7umwJFVjsXKN -tz1R1Ze4hbHwbnXeLDnxCTQTc1fr7ny5eQUX -tz1RgeuQ3Jw8a2DN7J5UNJPgh8ajGJaCBtmu -tz1NpeEZRNHyJ4zV8Kf53dPwGSVL14E7xXFR -tz1hrGu2a7onvxsimE6zxrPKDEG5hrqnJLbh -tz1YEWWKuj8cwVdY8sihxmZyFnbXUwwZ2AYi -tz1aCAHFuoxVDuy3E5Yq3YiBSm1kEcys3uKV -tz1iScX3NCs3NagdGKbmAq1DQuRnJbE8Zdek -tz1LtGuRn5u9VjDCvoiyQBU9Tcq5yo9E2o5X -tz1gG5oVzfDdDK6ZTDpAf29jRFGAuxwWncMa -tz1fwL6Zdvs46J5bZ6JgfUt7BoNXH2NfcuDb -tz1SMMGB879PtDrb9tgq5ZNAH6nryJZjujR3 -tz1Rekf6bZQDrJLtKX5XZJDAjwT8NDxcqg36 -tz1WfJ96eyJJ874pHRPtjBM1kxYHYeMiumB9 -tz1dfQPbtZbXVeDKMksVbHL85ACR4Q7b6YGm -tz1PUA5DASCQ4Wq9F6SLG2EBJp79CbuCtprW -tz1WnmVBBGLhPpwpcm6saCp3jMrUfphzxzXt -tz1ZyTm1WRbK5zkcwEGYENBaom3cUr25Qsvv -tz1UvBRQRXWBrjw1hvFiCo35qYwo3adv4Dh7 -tz1Pkt4X2ayBsqpbx57ndkJYZWLXLtc6A3NX -tz1TwrD3DoCBYBaAkRQN9BREP3JVZ34gB536 -tz1hdcrZkkwrktFBmBjCWbtKZXWKmXG9wUAx -tz1c8qatb5XN2X24G6RJMnZ9XmjC3rU6XBEf -tz1fw599XnAPxMvMdDHDbkbvXHifwfSVRGgp -tz1PoxHUPtodSK1bDbfTfq3km4rKFcj7tUc3 -tz1M4vbaQQE3y3RodTqC2W1BpwqxJmH7NnGi -tz1cxc4cRfy6dvo3XGLZ4bjsvJ1UQGrrj1GV -tz1RyEaRbHXezCiYzAGVbFgfxcpqi7uz6jYg -tz1Za5dKCMtKGHdz328TFeHh1gZdFbcNW17G -tz1Rax5qgCZcS7TaCvvnvL7dwyBzi5MCz7h1 -tz1QintRLa88XNh5pkNprGKmcHGeVo8kEFN5 -tz1RSJjULhBub4GAKtnqdqghhHLNri3t3YNa -tz1SK8tXow3CU76VbLoR8jggMC7xkxf2MoiH -tz1ZUX2fid9EVmZqDNkMk8rCUAnHCm2UJSDe -tz1UkJy1WCeKx5eHyExeFfQrq49VqRNkr7ZS -tz1VeyZFhBgzTnMAQWfTVFXUXruRkZMDti74 -tz1fozmGChKZ4J58jKt8rkZd8bRMAacgS43U -tz1XPg1AKbW9wCsBba5PgEDdpkrTCzZA8u5k -tz1a6UGyuZYghPGA9N1drh6bAVkF4D2wKpwV -tz1Sdxk5KF3prCUXNstHGAdDabiJoSP5bT5h -tz1XqZQBnGgyPaktfD2hpM21vysXYmb7bCEQ -tz1VMdSdExepP1jAEiorksyw2BphbrpfZEyX -tz1X7pRmeMcpmH8W6rPuSq4PL1ja14zjX1Xb -tz1LThF56yPg3TBjs3rmRe1izrsERftp9JE2 -tz1fVr39eQYJLCi16uYQ9hwGAondZajf4PAp -tz1iWGETZuZ5p47hugHYQSYMFuiBLgqoZL2F -tz1KhcVavtocTSuNFvzY4griKYUEjGDzLujd -tz1iWuLGL8d6qpzVMNEYwGyD8XqGVjedCybh -tz1dyL3kiUnUS1hDwE3XsqXZPyMtEVb82ksz -tz1gpYcWpxXzSspZVrkWu85CY7iuLYztius7 -tz1PQJxasSxamkdLd3yjHsnUyme1U8txrc3k -tz1LCZpAUCLHv9s99reNKXeLtLBfCe2A4paY -tz1WmBM46k4xgZAP2zsKgDmttzw2f5YmqLXf -tz1Z8HpikPTFgUobnPpgQHazkaqrCDCAiC1P -tz1SEK7NK9jfmasWy5Zw73P4WxnkHv5XkqDQ -tz1PjtkFXYkHC2nqZhxR3vftuNv37g8yEWXS -tz1TX6HPDCiH5dWFmwNCWtzjvMRda9Aj9v12 -tz1bGoTC3o7tYkiqYdRWNyBzqBhsdAD82TzM -tz1iAfUoE2dvUwyBnHd852T1cDbhGxFehfKX -tz1a21f3HKnYXatoAnygURYeinCW7yo6UrdZ -tz1gHHDNPk5459m423vtH9iNJgtBvpeA8gir -tz1eY18VF18BRjZ55U3kJYqjmYej65cQsw7x -tz1SsmKTCdR5dcDmfXSbQR2d7p2k8uwTSu6Y -tz1RSZEEpqBXh4R3VKBcEao2czKoHbiH41jz -tz1VzgEeq4LYWMUj3TUZgS2he6DCnm1q9hXJ -tz1Y3k7rhpdGeoq2FqMKEW11t2fjuWM9vSmf -tz1bmMKcg8jqBgigf2cjPodjAdQtycFZrnQZ -tz1Z36QdcDA6JPoNeMFreVWLFrZnQLL9Yndu -tz1Sf5H8LmykMeTme87ffRzLs9S1hznPYCk7 -tz1YRnAjo2Mxtu6vZo6rdzc5QdKJhe9SktaP -tz1VRn7LfTznGN1xspjvh9AaAfhtujMkzkbN -tz1fMBVgPmFSgiZwXTi1Ev7hv93xg5XcQn8F -tz1Sk33yWos8F39BBrmvQWqw1368imV6NWDD -tz1L7DTxdrmK9SWpooq2dDpMEYavVHNEFJ8K -tz1MiY9bHC5Ux3zVGNtyoFMn5B3XmumMUpR8 -tz1WYDC2BKajfCvXrYp3uuoNYy8TUtob9Mmy -tz1YoFP4wKxDTm3hioFfKBPkCgiBpZQm1jVz -tz1c9TaSgTgEE3Yg2uvyjMccBQHc8Y3PyNyA -tz1QLadnL2sQapvjhnhanDzKuBSjaEvvsdRb -tz1NzkiiNdMyGDfwcidzUbBGfgGu18SkcnJf -tz1W3qafBdXGTU5ZTCqKP5n93vt5vTLwnLbE -tz1QsbkkVxX6VHJwhgj98obXWx1PxhRXq5Ti -tz1Nk6C9R4frtzBe6s2rN5HtKe5cDdunnR54 -tz1UdsdoGZnMxwiYRonpgZye1KqBXXpGM8Az -tz1LyiZLrj6NTUEgpc8rVsKgyEc534NYJtoA -tz1P5aXZnNFuQJiEiv7z5MwAWBrrauhdgk2t -tz1TzfjhfqyUqESWx8bo6NzKveBg5fPXGwe8 -tz1Td5kawDK5urvCBYiFLasTAQzCR7rNZtqQ -tz1aBVuUEHiauz5Vytt7ok1xaAYaeZ46JsAZ -tz1VeT6HJJg3kUs1Uq8nLpgRXN9HHut4Z198 -tz1hNwHoBKj38EKNj7QPotfhbF1cBYGFtgQt -tz1U8BF5YywZfiizc6JSRjh2463okTT17SMQ -tz1Rm8SG9ux8K1PGgz1jqvUbz9VLa9ae4HV4 -tz1SGE3hnRic88NX8PTDW9q4wWZojNYPUgxq -tz1VcCkYY2nRuLYWyywKAwj4WkYeTZP2xSm1 -tz1MBQwyLtroGRCcjyRfF1naeU8exzqNFR76 -tz1gwBG299fU39aTkDARX96nDsBUeQnMjqCN -tz1QEirb6V2ypgAH9C1ZmEuDK8zVpJWBmvid -tz1d5Cz5PZSSbpzvimBnnmX6H4m1JexFUuSa -tz1XiAPorw2Tpx1HzCZTm58HkUUokBPovSBU -tz1PwNGeoHJpRgVP8XuSfdTJQPMWkf2HYgER -tz1ZQ5kqi35UsV9rJuYXR7r3WpWfimcKws9B -tz1ZWkcamvQF8dRwj3iBPHjmjjZgmoB8o3q5 -tz1ieSCNgbkrC7s7deMz79H49REhYEvDttwh -tz1cntLDjhBUzZL2TKEudv4YwYdHunJE7geA -tz1euTS3G3R3mD3aiHqmk1FfqjfxUbcMnUiP -tz1dcTmwSeig9TwKbEm91X9BBnJtbPHmc2Cp -tz1dQPPUFca1sLe5ZFF7WepQFcM2ueJWf7ab -tz1ZnBWJRunpi1xDECnPuCxP1oqRe1yYgN1w -tz1hDKQzz95j7yEamZJH7WrUDNHXi6PRF7aR -tz1eRXza2AfjX8PUqLbqt9R2HFBwWU3kG1UJ -tz1PPZcxF155AjQxSjagnvnVbNwE5KGAsmiU -tz1TFHzyUbQrUecwuyYcFZA2KhkVNHFxBSzj -tz1Wqd9ET6XmSM5Kdxgz7TMdhnshyLY9omfS -tz1hAVBVvccRREuFJRhfZQf596JAXbZBaK1J -tz1SPkayqLXJJ8qKmT6T9bkfZZSVPUg367F7 -tz1URrPNfjWVdK4NMJLEMzovCNbWkAqgFKHj -tz1XgdV3rHh8KjfQqGRHg3sJip72dVKunfQ3 -tz1bDSB9Qa2yvcwq7SwFpf46X9B2YNVc82CV -tz1ge5vtEx7zUmJfULHfQ1meM5D43Z3965rm -tz1SuMwciEZp7vgsDzQVUfFmmsMjgaJUCLj3 -tz1cJDuytrPZkkhm8JYaaRVEwnB2jXmPvUzF -tz1ZZjDyssM3iQ3fz27TX9EW6ZvKFM7gCNrP -tz1TxQNE1q4WEjYbJfek9m4mFTFjMBXQgEiC -tz1Pw48wJnhfJ2RfPYwNujbHP7wV7PcepmLS -tz1ZdGpk27MbxcBKySemxo1HGfvtz1qrVo8f -tz1dcgBAWaC8SoGZCM9y6xtjvKJxYQLuqYAt -tz1VF28Vuk7DMDVvrhNpE7WtZXM2eUTKkra4 -tz1ZWxszFNCZCZ1JWA2BW2haGXDRDHGaqMVL -tz1S9BWxJMCyvhWBbADhvirqxqnYeGv19M9J -tz1Tava7GHAaz425Q5XYysAmD5o8f3bL4TER -tz1PhrUThtu1MATZR31Eg7PX7Kqjq3tZD6Dm -tz1XuiAZCSz2cmWe5EUuYq52sanNCbX8qB2L -tz1aENiSMLcg8JZDQ17qU7Ksy6w1zeeYcxLu -tz1iZzSRHSwppGYxSFa6p8KxeC5abggRcCgk -tz1ig2ca2uwq9DX5tTogkB6n5dcjGTvCH155 -tz1MyWCRLxBLC6VQ6RXmEBFPMbo544v8druF -tz1L2DftpKmgEaFNDUMTyjPDwdhZ4nDbyRia -tz1gbs4t7tG9fxB2jiX4AFUDg24zodjmE3NK -tz1LRNpaiJwNfn8UdjVUZg5vEEpc5zQEHujA -tz1R3dV4n8KmT6c2oEWkoBS3fDRa69MqWtSp -tz1ZqZGgm7KbugeEhUYd21Qf5iyZEgqZVBwT -tz1gDtkA8TFLpMuNCtFHLh9HukqSoK6D2ZM9 -tz1Z1MGA7X72Uv1kDsvcs8WmpJ4mcHVxgr9b -tz1cA59y1i3VfcffByHvTMpNCHsTgT5Mj9wY -tz1gXRbj7XPvB3ZoASc3XePtexkLBGQSuCUq -tz1PXDL9bAzM5Ku37Wwr2sd1muSjzGn4xvZ1 -tz1cXrYRFqWPTjY63QcHep8kfdc4bKBdxVuC -tz1N6WzCBJQWwQHDDKm2tP2gQhTjzSkTK871 -tz1bvtdJ968RLyzLWq3gJxNELbpUsPknUTMJ -tz1Yd76P2xH1923kKtBTrnAL9tzZQzDyv8Eu -tz1bh35QmjFz5TZnWAC9LNPez1KUmbxbAhwm -tz1VriP18fpHuUhxSSjxDHiukTfc16NuBX1g -tz1RjsbGewJUcyBMT3Eu3tXmSMTs8WuD7yYH -tz1MuSDnXx2Z4ttTPtxFp5uRWw6mUGaDSxSK -tz1hsrswhsYLH7LdrGghSLoWo3VRocGGU7Pf -tz1Mswgnrd6tHhjhcwj68x3TEUxaazf7WBXE -tz1NjTtiztMW7NRBus81RAxcwtnHaSivPRHR -tz1dyhHdK7vpLvVxEyojtoeWvrkMJ4D6X7pt -tz1e7bwhUgAAcbyUZUkdJZfgYwFCBvpFe2kr -tz1bA7do9wixcicfWdziqohcDT2xQ1Q7pRfL -tz1MF38rFTyAdDDeXqrENVmL58ZcvwunDZYe -tz1XrKduzWhi293q5Auoa3trCRDK1YuD5AiP -tz1U7y2gi5G5GDAj5PVxcmw2EsvsmW1awfT8 -tz1TzqziW2L2oBaD7KJ5Qg3ptyXtP2rThFMZ -tz1YgTLfyCNCqLwNiguV3xJxWfJWt18ojHHY -tz1SQJJJ7qTYK8Ym3tqLoPerUDDTLvyA1g5b -tz1gvyLZ5w1nsniHsYXH3KY66RKxioXCQCSy -tz1Xp4txo9nQuNyGCwVdBxKkVAy16vFDTxeX -tz1bvddZ99bdzpGN4zsCeUZJe62hZXpbpvs3 -tz1hzcDN52anpF9afAyZVjY4jct4cJGASPKQ -tz1f5JX7nEAsRjGi8Le9WpR2SRjy6gDarRWX -tz1Pn96L1zwi5stbBLaCxZPVdq3ZAURXKxmc -tz1eQMgv6JDWG9k9ebibi2i3cPiZLZXDUAZU -tz1QEL6WtaZxGxrXQEJZ172hWEn25fywB4Np -tz1Pb9rEQ66cQSTQweZS1FctPZ41eWe63uNF -tz1e5epdCV8sepyfDXScDPCfVpcAfbYt7NQo -tz1LoeWxYkNun76m9LKykGDbsVhyv3XQoVq5 -tz1LEC7a7XccGXLfhsvLrPCAV1Sg2qLWrrf5 -tz1f7ybJ4HzFh39uTz5FuaQNxHu2dxU4Fm24 -tz1LpPEoBU3VwcYQazVEXH2buPyYv4MK5ci1 -tz1XiobpiDtLKh679WuMNEfMDmmeGaTNrPyk -tz1Num8XJQxUtscTWp81PpqcqrMqN3whqBRs -tz1ag11k13qV7fDSxryMAwBjCFoU7sShYA1q -tz1UivQ28CwGcrfwgjDVTUzZK6oc8AhLmhBh -tz1fKqumPpcrAmd3AcuXVXELg359HfbE5tPf -tz1Yw4TMaBWZkzHR3w5TWjEyBYprPEcHusDW -tz1XPxwHdU1v4x2Ucxqsrsj9b6EmS99MdYX2 -tz1PEpDdrPgDdeu7qMuJea531hoQYrGyVtDF -tz1S67ro4eDcjLDFW2D2iXCQJesqadZMRwvy -tz1iferkjKpi7tXaSGopPkG8X4zRSbLDNSTb -tz1dsubaWsUoELdxYteaNVzh9n2fwyuHRbAc -tz1fAuw9hg2bUs4rUMQkYDwvEsdKGjNfs6DL -tz1SWEMm9kRAbKUKitQZJzjz4FeCugCcwKhv -tz1ibTcb88xUEcT9SpqpvJFhuHSHQ4tNduLM -tz1g94JXxQ8FzBTwdDkCeenQVyJuxjZNtjzf -tz1PQpivBeJ5AizyfFWuxXRNbsh4kb1Y6kz1 -tz1ZSFWjSHPVVZcWxkAp3mxaVpDtZXKPsQU5 -tz1gsUaKLvfPA4VAjTmxWZvxkevR3UBVMUsq -tz1QVwnTKrHJvWKKUzPqunuHiqD45dDungoV -tz1WaW9YtAquSzBQjpE9SLBRFuHgDWQKbpMH -tz1hSr3orNKuvtoeJkumDJ4EgWicsj4moG86 -tz1Xq3byiKPaszeC5DN6PNApk59rSk73mL9N -tz1SUmvVK72UpMzKj6EbAhGor1JKSV8UQj7U -tz1Urg7cyyEoqu7EWkQULDZuBmbMGFDcLDR8 -tz1N8b9NNZAQGyry9YPJWHuFNPXhdi5houTF -tz1cPZkmssnkBFofL7XyPRAoF8rZLBkF3BtU -tz1LUqf48DsY9G1gLr2pAW5mr7xRNVRyLSNR -tz1MccydRqhfHCuEhoANu5gaduUoUzFi9gMP -tz1Yjjd56QUv72EX6d8WsbEdtW2HGnfsjKuz -tz1TKPzeCkdf8TXVx68aPNKif8AoqYHF1tAM -tz1gaXugpRyc8uD7xZaniPUoT5wMyMB1hxCa -tz1SkB6ogP9FWq9RyHmmCh2wRrDkR5xGmwy8 -tz1M5ThJ9QgVC5X9NTwf8kuhu1WZ1QW2zHdn -tz1gtHKNdK6e4CmqSMV8hs2192wervZkvNGK -tz1Y37kgwjUGP8d4wy7XBbfLWEo9Ctjg9kEK -tz1ZMb9Xpvufux9JVWsbDMMMCnw4vGk8Xrhx -tz1cRuP7Gw1XUAiJnqHoYZDhp3b3tD1aP6aX -tz1hNthobMJkKMkLYWCkT1Tvue186uRUQpXN -tz1dqxKRg7P9ynMzVSE2iHpYQ3g478Ud2ig7 -tz1NFw4eFwNyFWgH4yWK8jw5y3mRv49kQ443 -tz1YH88aXhG9dbAAP2PHCUYWsTa4wkRhvGHM -tz1d9NXY5zcC8CESNGTmFgEG2q5pHVxEMWUN -tz1TuUkRgcXKRNohSsgfQiSSq58JsUFgBE1m -tz1WHKZmoEe9FENvvSSaGCYi6ta3CQxc9gzJ -tz1b4xFP4Ur1iDpdd7g6moCcSaC1ERwenFh7 -tz1PvJwuw9hFxkDjYJDnfre1kDqHNHpDgLat -tz1XCJe5YB8Ck3LTdanCQWvEMAaugDiNTjet -tz1VDAJ9LwizwZyvJAuYUwrUVty9VBKcTpWE -tz1SxjtfBoUAnQx79Bj2me3YYwxuWRVY7FfY -tz1bs4bWac7GujvmNJYpgH8P8NU4KXG71yL7 -tz1eZPUT29viRULiW5VGyCQzn7i6dcdbdKtC -tz1VMV6Ja3xiBFcGrNv2UuvezHNqFLKVCGVt -tz1RMcbj9QC3HBYY423Zxa8Fd8gUgLLa38J9 -tz1fqgwVV5rDHM3ijrVhp5DJHrkuaXdRJDeN -tz1bWdTWjB94ZVF9S4j8kHjAriFvSFH5VenF -tz1Uisz64x8JLudmziHcMZbFBFjyFkX2YiiE -tz1hqzd3hB3LvDjLz5kWW9Xoupz6umN4mkuH -tz1hSCsc2vL8MdTC4bJW3yH9AEe3PWw8AfWM -tz1XJVQte3zuaTcs1HqjCjxqUFPrSAviHSVB -tz1VrytGeSUhrnxDozzKPMLLR7asvS4o4YUF -tz1bkFQyrfWVXAfuxhmgAMmj1tHpJfWCveZW -tz1fF1poK58u1FVyaX6WpBTzhFU83sdwMBEg -tz1PB2CkTUhh5rrN9QHBz9aivqTQsZ9MtXY3 -tz1TcvQ5ViVmXC4AtpuPCs3AGVxvMbeTbcvk -tz1Xwyx63TsrHPozRs91KvaZkYLP5WLMbeHo -tz1bGXsQobbjSFaGh1wDjWEpNcfJ1FGi8SWg -tz1Pyeff7HgzBCfMubYoEq1VVFLAkj8zWBsS -tz1VhEinhtpERyompWzrqnUGUWZidz4UZkJ4 -tz1bjiSiH15nmszkDbPBq7MSK6KSYBLPvZnV -tz1QSgZzdeqv9CpPYYKmfXTKiG3aHxZEVvxk -tz1ToikQWUxnSiMoDoqHgWCXCUAq28XdZySE -tz1dV2BZ3QmezNU2JdFHwUq5uGT4Hkhne8R1 -tz1QkppoJAGTyQ3ZV4ZE15sHDyKcGb4Cir2h -tz1RKJrwVbrDEhdsLig4Z76MgxeMxfrcEbid -tz1Xrydj6N2zoM1vJeK3gyWFkaMF6yEQymx5 -tz1afvHZFbbThtgmvqXxA4ondeDr5DtVMC4q -tz1b8GvnZANqrZpfku3eXb82jmdAAn9VnLUm -tz1gWWsEetzBfGeEdV5AwvT1bZpfVLaxjo7W -tz1PwnpSFhUK8gkqhRZRms7WYp7Dij3hSXBh -tz1LtJFRAhhR3cEJZEXt2SK8xSyro3U3p5QP -tz1KwFFDdTpKT3WY3PPwiCcsJ4f9K5aeSJim -tz1RAVQT9Krb4G8ui7g5euGKLMNvC7jihitC -tz1NEAjUn1jk5XzVVStDsSZ8x3NetC2H3yRx -tz1iAgq38UcDra99BFhgniqw11HgFLe4qncm -tz1ShrWTsxtpGy2w1ed5DHxfnVUHekUsZan2 -tz1fRLCgvDqYrDgK32mDG3HpCo8LXFu1yZ9U -tz1NRYUkAEYxCm6x68AEMqwESgR3vskwcV6M -tz1ScRAhANWQhD68CVQ9UUDstiU9CSav7mGp -tz1NY3y7yaoxU5CPHLyqXuwBsLcqQiZMse2x -tz1UKr5GNv9bqez4d31vS9QSidWZMo343aJe -tz1Xv5eG5mCtY3u1wmYBXLXyeYfqBdmaum1b -tz1cAXKbubAzioGr1YFC27sqqBwFGZeZJBh7 -tz1QuxaFQYQVoxoJSwr93daGigkupLeFL7u7 -tz1aBWG7UNYAMLcE6kUkkuuB3U59VC166d9v -tz1fyVWA8BCHAscsYC3CH2u2x58N9Ue8TE2H -tz1bDCi6CWCpUwMdBLTjx6uRjmuViYxmVd1i -tz1egxFHTs1PPYB2ThzLn8Uw4ZJ3jdjcJZj5 -tz1gPU7635h9LEVTTwNb9eJtALBbFsFhDtHK -tz1ZrEtg4tABx2VAD3vJbtZo2476hx6EYu77 -tz1RKjA827nkMw38UwX99LPMApYRDdsfNti6 -tz1LhPuQUCaHB1gTCMfpvn7yVHv9UXV8Xanf -tz1SwkPpRnz7wxSdB9JP3zNzGHwWhFXJYRm7 -tz1hE2Zko3AJXqy6k6m8YZnyRZscC5QMDeVR -tz1bJ3LpzkgpaiUGm37zfAXqGLP4jXRGWLxk -tz1d9PaJS1t7ah4W77ANGRBU3bP9FBQXTDr8 -tz1X3B2VaFLpfUPniXrbKJRJ2dryTFKXMhzA -tz1imK1UWrmvcK5tbkAyDdMbGDwTTgmWprVb -tz1SsJLBa5QNGASKvzTXXL2CskkhQLbeJXN3 -tz1Kk9miCVPQtSwpZFYPpXzvp6Req3kSjj2q -tz1fQtbkXeg2kJXhbSDgkviHx9oqUBMmMBsb -tz1MsWkCYkmGqvBbjTr6GPxZdi4Yz1m4244n -tz1hSTv4b4dQMHE1cMiAB5eXs9aLu872EB3F -tz1e2tJzKz58KmHS4eHVWUPrWsU1vdWjBJzo -tz1WoPkBZkQgabbSFfU2Dt3fBvLnCML8b8D8 -tz1isrtbia95mEJjDvbjVK9VtYDvjstpQ5Q6 -tz1QHnaEERDXeEVv3jjBDQoF6qRwEfaLHJ1X -tz1KmQjVSBEt7Xa4q3ixA2jD2EaxUVSqWJVL -tz1Sw7ShkUDv8u7U9No3Pm5vokPBpWk2YaEC -tz1NeciNfkTdpbdUqCP7WWUf8cSaEMWkF38J -tz1TiaCi1ii1KM7EuAf9Y8BvakJRHDHqiXTh -tz1WZ26jGBnA1DjeQKgNJHcsQR5tqGxEspnn -tz1UYZLsrx1otBTJvgG1adLuZtrUedrTqz11 -tz1fNf4AQfoYyX1aX2uqpi67LqdHk5maQtAF -tz1PQGxJnQd43Eq6tCPGex2XW5vJtPfwbgu2 -tz1Kmk7pCUKGHSKh95bMeT7VznfqXCzrCipS -tz1gFSxubG4fRZTUctA5pe6v9qPEJRfooLS9 -tz1VDbPTE3nW2dQuo2g3UxHmrLN6jy9M7ou1 -tz1cG6eT4jp8ydWXgf2vwFpYn6niGSBpFn32 -tz1QXYvjH3viZS7veuXQR9HHc8XL2NCTFZhL -tz1MiKptCXvRSYqHDyYkKRN2N7ahPzvsoPBu -tz1fYaRMhqsPaw6mw4dPLsNFBTkhDUHLCEUt -tz1P64xn3tar2q4W2JP4NHYEQkPjtG5wEHYa -tz1R4BVtCHz2nTzCNrYASbDdxQeYQQtsRVNi -tz1NwbCsSuUDmdumDbJxMMcmsbAF61aYHNNV -tz1QiNMmvJr8Uaaxds57Uadz3pjfEKV6UQCj -tz1hJwMwJZ6dCzStVeDPrb3gisvSG7e5wtFm -tz1cgeXWkmByQoEnrdxEEVrcXBbjED4DhChn -tz1MYCwn7iT5r6e6RWUSueUgjD3nawJmPjsj -tz1RgLTTFpqB3socRWztDV1TX3TkBAFjqEST -tz1cXPyU3QEethiESF9pEzPNPXGqWHRNGrTd -tz1ekuv7WrWwyHJFZu4LT12KJvV5ieeELXUQ -tz1ioC2HmQfJhFUf6qPnmAwA1X5bZJsaydpT -tz1YV8RD7iGWo2Bk59K3BAnhSXhcjBeJqixB -tz1i77xYHMkr9saWMkWVVzPjSCzBpVhMNf1j -tz1WVHh7vJLKvnnwnFUTXjcq4RH6jWH1cJpk -tz1eo96ACVLsm6rJ8sZJW8gj1mivJJp6TH6B -tz1gh1hDxmKmyR7pa7erWJk2hFz4h1suQ14S -tz1coDLoJ9VaLRNq7KAxqGH7bzDjLE8kMo6V -tz1eNY24RuEMh38BiiUAxc3cNeXY6g7M475T -tz1bsAb63J4KMaSbUdMH8gKECHHbzxPyGdqe -tz1iwwr3JjqQhsBoktLDeh3NpRneSmUEKUM2 -tz1iyUU8STgeX4kevDLkLjuC8NQg9xBncGwy -tz1drAP7n6C3tp5Uidn8T2pk9C3ZJzsVf2th -tz1Xh6GjxKQ1VbeeV9nqxDkW17WeWmdRTbtb -tz1UzXzMiANBN8C1J64KjSFsqo9gxdqKPXge -tz1Yzit3N2uLdQF3eUNGK9JvSNjJYMudMZ2t -tz1Z3cthRgFYaY9YLAKFHJF4kUwkmAk5PEW4 -tz1aWY2C1HyRRc38AgH5LFiGwbsGAsnpTMuX -tz1YR1VZzAb3DLLj4Uc7bBMGAC86fYsPEeNL -tz1aVQ1C7WQAWuYBJJpdbpi3vhk3cYsKvsGE -tz1WXx1KGz32UR2Mni4QWvwJBxSLdyi15sZW -tz1Kr6sqnJ9jrCxRUmYBpcZ3WJxtJPUrwuee -tz1hRa2Fz8JqiZ2Cbfdq3FMS1nATBS7crbB1 -tz1WiRXAP5JhrgTWxHYyWKi2p2ezqb9R2n9s -tz1MkYUrLtHJCEng3XDKwqjRvHc84YFWcueV -tz1ZuFDc1cesgwHGXKHs6CeStu9mKtV9uCDo -tz1XNSXxvdMb14n7hXuVVw7Jp72h6nzb31hm -tz1PinUFHsKfcNQZTDMQjptnoqQG9rJ39HAT -tz1h5kSYoDfxCKAPvsJjJdT2wMt8Z1KPEDkd -tz1RWAfQmSaXxvkt6kgbYST8aUoDAaNrarK1 -tz1gtke33w2Mcdo4RJfZS78T2TnHui7rLekB -tz1WyxK7xbKDazVYQuXYbsrCVRK5WE1xqWAZ -tz1bJagnqCVSb2zNDX8bNHbPDbo7iQD7nkx3 -tz1e2m7PZtin2AsiLT251ADZFFUBv7CPRz5p -tz1e4R34B63mcQ5AaMU29GZ1wv2qGtvp4RPV -tz1MQodqkwMPNkcT7ddbLQ8fjGLBszekwaYY -tz1c1DazqBkE9jRva3Y32uFrtoyu4CZ3DxMD -tz1hSJAjhQgSXXK3WkikjjHCn5p1murc1qAS -tz1Ze9Uq6akbB57ZgoS2e6rirWMxfpR7H3QJ -tz1SFgSkmXLDwsrVYG2bPAcTaJRGawXpHWpu -tz1YDheKDPMyKMc8KhLMzDM7tZzjS65MWqyQ -tz1bw8WgnHPcFTKQixxzk4XLYbLP637r238a -tz1MVajibmfwBcn41tJi1ZKBT8qEs4RC1QTa -tz1dQKAkdQNKDCL1F6TDFNkJBe7ZM4KYzP6f -tz1XGEpizz9n2d2M75iM7RkL8i7FaftU5zp6 -tz1TdHGccgULLt2wBybgKLGtpiWHXxksmaaA -tz1TGe3C7kqTVS5JPtJi3Auc9QD123xkRfgp -tz1SozGNNmkW6rPWHQVtkLVUnxeL7UhW4zu1 -tz1htpEw4tkL1jAF1R38JVAcXHiP8rPHaEys -tz1TKN3kcVtdKYrSHGmAm8pkJJHQV6zu1JTm -tz1fxK4pdx3p2E1vj2rSxxMgSevH9UMmTprD -tz1XqtoDRjci1aWwRDQ9own4VVUPzo5bnSj1 -tz1aUmYd8z6uEM8tZLv93v9GgNCLanr8tKpG -tz1Nsgrx9EKa69HQZeAJM7AHQDdTNEYjEZwp -tz1YjnTjjLVXcxREopu8XXioLJmYJxLvsgn6 -tz1P5Fb6YoZXAfvmca8n6rPZgRYBj3Vof71i -tz1LzWhP6tfwMUwJBV5qawTciSQuoWT5aMei -tz1b8z8BWfEmk3hDUF4BH15ViiuDzYgcHs7w -tz1PhznpqWEiEeMRMMPrdctkmE6oNdPMutcg -tz1io7ut78gFjW1UzNYz9ynsbYTFujPE83TX -tz1TVkJxKGvspHvfdxWUcpw5iE9pbFmkc3L9 -tz1eEbu59FBWYaasFPsNKztLxUCGq2e3s6x8 -tz1apwLpeHgAw12tsNufM5UotwHD9KT1MowH -tz1VjjMx7T8N6RdzjaSkXWdzRPFj2rtfjycP -tz1aKntR3ALtsFJeCCaL3U3pYRxZ471xp2Za -tz1QBgsQou8PevtajchWbDmLi9bexuc4Ggas -tz1YKJUx3SsVq8SiwtZWbjhG4E1XF5XTBbq3 -tz1YezZzZWJv4uVJ1zKW7BhTMDCdwswyDSyt -tz1UyzDLiWZjBvJTaVTWz2p4AwQm5Xmp8t1q -tz1NKH6buYVgMUEbxAxyS4i8p1LcRnhdJdeF -tz1bf9m3MD6JeGo72XZZjZ5x4fGukkx2rrt9 -tz1aTyTjnNksiDMS7e9cixHKgEpUSwuan6dV -tz1PpCFbuXDPs8GukomXCD13UyrqNLpgkSoN -tz1b1GgN9UiCsnBv7m1nB3kU16MwatP1N8Ha -tz1eXTZkxrNjwUSncSsG5uP2LPBkjgufbySo -tz1bHuEkWoYwtjfkzGLs971uf1pxxQMNcXya -tz1bAFi5iD2Gij2B89XRcnbyo4vFzHKPPt9A -tz1MkwcyqpxzYpZTS6F2ewFbVXDHTwkTy5Sq -tz1i6xLMELuJRJMx7jWe8VYtWyHAoSoypkho -tz1b57ei5T8t6bCw4ybfUy5EMtpbPiMSSF2n -tz1XXxNGE1XsKt7C6MbHNia19mRHUTUknd99 -tz1Zx1ShTKUmc8nXHVAiV3ga8xYn8tKtxbwH -tz1gTgja6eqZ1TvULSvArrtKaExHqr9dnb2s -tz1XgykuYrHK2KJJ8pyHwGB6eGqtx4xP4da3 -tz1hgxxofVuYC54kTv3f91SEw3np4N2w6Ck9 -tz1RFJSHDR8fmJto1B7A1wMmpvfgGgbucRKN -tz1VLxwjRTr63zB7NhcAXjLzZ2vzMdWtkzm7 -tz1hRExmcFs8kUC2GWExW7HoZnJBwRvBTsez -tz1bZaySyPzYpaJQtYfs7JyYyhJoVv3x8Lr2 -tz1Kw3RRPwiL2bT3prAcB9qfWe9ME7xyhVEx -tz1RTShALchNGVmuLL2nKh1KqV6NCHpckTZN -tz1YCd7wRaMmGehszoLVvu3EAfSNQ6N3oq4g -tz1PtPg5maDEt1BGiQX95FhQgstf9DkNzrEw -tz1SAfL2WEtkeEZBVdHgSnA4Sf8nVy5X7as7 -tz1XK9JAnouCkv6nJ5S5Dz4wQT6fynGNoF6u -tz1dvUZf9TWfqyRff7KF6WmUVj9o1d4xkerG -tz1UjdiB1jiskdxTRbj3heKCb1bMfR6MDdPM -tz1UDuo3zGmTudWCVjDR8vYtzNVp7tgYAn8A -tz1WSJVYT2333LYKroDR5dmoCKBssRyGetzK -tz1ZbhAPG19p2JnmyZE4NAZjNQTJboD8xekq -tz1WNy4j7bhE7cZ2oycmL49mQeAfDdiH56ZS -tz1LAYcAg5okn1HdTSnZksNrbDMTyCex36eW -tz1S3EYypcaSDzEiY4dekyhg4iQa6DR4u6VC -tz1UZcDWsTva5zaKx6V2vAP4eZ1TtfYMaoXe -tz1dABUc8iN1q6CWTSLphutuEXHNBauqjHk8 -tz1UXFtFvQGGTt9TYzf9bmN6eFf37WpZRP4S -tz1bMuczhiMPYVwDGpjoL6EYJx9Kz5rqYXV9 -tz1TQd1DDqMJJ5D46uVPLZTPJzUvpVp22VMX -tz1hZe8DJ6TuS3rmdTTUbax2VR1rxkLiECg8 -tz1e6CFrojRPaxoA2PBmCHC7hjgPU9DdBCbc -tz1ai686R6ph1sdFtY8oWz4FV7GWknNnFYK4 -tz1QMSXo4ZXNnm47vpB2SZCf9BQVzkSU43Y2 -tz1NpRRcuZR6d2Ps8vtqWXLgTwpewMdrT5Rx -tz1btjvK5nX8CRNgucuYwqxDtqCd2VmdEmfo -tz1X6SXbgQ3tEXHFYtj3yTMh4VTGaaeEoJz6 -tz1XpMWj9eLJQK3s67FjrwZBdd95yBxrGoZc -tz1bZHPnxhJnA9qAoDHpXL4GBKdVm8sZKJgD -tz1YMinV4xkYojfMgaRLbRcBvzTGViiYANTn -tz1W6T6HUm4zuNRz2PiPmNLhLnnHtVWXzhcG -tz1M1wA1cF5RQkzscXVGmL3rGdhN1RgfSKrg -tz1LDSarz8MxQrmhQoTV95vY1uRpMFWLJsqS -tz1aUdU8pdhoNXt5U92JNi5FL8RJNrLQa5uU -tz1ai332apUuuyFu3saQPKVE114Mcrot8pQr -tz1UPd9UdBQf3T4MUHUbMN6tcVpuDgqYghP1 -tz1MPHEyEk7fKQ8Bha8tR1oZP9TyvDmfYRGC -tz1VXwWCGwmC1DQu3W5PmsB8hdisvMKPXuxQ -tz1iG2FWsk2psgXnheFSYKdCRVgQ3SSUC9Tz -tz1i81P2GcF2h4GCaQJF4Xyxb6ko14QgAgVj -tz1foW77H26d1VSxg4vBAnFMkgdoZrAYxbN1 -tz1LAizZhtHG4wzy9Pyp1YqEhsjBnJV6oFXr -tz1Yg8NF18toyWGWanBR9Z4srrfd5UkFWLEG -tz1hsQkM4bDwuLVxURnNPPfsDnDXtDmKRSGA -tz1fvSnBdx3an6rcfkzGZ1EK9gXgnbLB9sDR -tz1SjdALavhRuk4kVimrT171PgkhvUgiqU2z -tz1NZJDXmQAt1Mn7wrQx9JtLDHj9rgkaNLvx -tz1TeVdJQTP3mqLV6WLUPPVGHtEKsFuFS5S2 -tz1LTtktoG5Wx46qe1T62Hg2uVMZ73xSxc4a -tz1X1UbmNEpTmRWADm9U2GL93cbB772Am97F -tz1WNxJRGeGBAtWPDJwoEwymVJ7ZzFVVnBZS -tz1SgD8nqLZxGZvxRtH4P12irjDYSw6jaR13 -tz1h94qMFWf7GVDEU7FKUudKH7DDuxLPcLj6 -tz1UD2soZX97jqfgtZdWxwKWfzDsTsp8HsLx -tz1MHqkYFfvTCPgB5pxjmqWvpqJ5jy2aV9pz -tz1heNHsGUui5jjAopmEYuRTWAdngkZbZfiu -tz1VapeRLn9fcYjSSeioSVY6ZgmSf1R8E5co -tz1ZKP344VG8Z5L1eGyaYUTjxXReJXWoRYMv -tz1RgGkk7H2S1aU3dvJRmhjSJ7sBZoiGwMJY -tz1MLLmAKHZz1BEEvMCv2myRW6AAVQdo4fmQ -tz1bdmdU2X78YRHUk3DTXY6PxbiqEAEifbDX -tz1bTpceRJBpcBiT2cjAds8ABHDGYPzFKyrG -tz1bexLrVHkvwK3bsdUcYCdr7x3GeefjkjpZ -tz1MJV7UmeMMpGqNHVUzNpPc38uSHoWjfEEx -tz1gucnLB3qUQ99UQcWUGDd54QD5g8TWnaxU -tz1bsSyR8f1oHg8T2uvqmP3uVZ7e3ibaJ6Mn -tz1YaKmVCSrTQAbwyAk1iLVxGUNPnw8seza1 -tz1THszwkqQ5PTKVvLYSc6XWuRNoENTsVf4h -tz1XLA8sjUoZi374oyg7LxpEFARBoDfEATUH -tz1LnJcwEhMEtjvV5Rt6GQdZXTMc2zy141kF -tz1aqJBuV3GSWUW3ePEZpQyNZqF7S5qMzroa -tz1bm1AYBwbFPW3JLDPDJakyxY76QzRURUCC -tz1Rq7fZ8CjrzMx9NQzykZpracXz9SMZSqz3 -tz1Xj6qSZHu8fpqWB8n5iBJaXZWZ5nkZdJwU -tz1RCDaNPwTU695sPrMnXsuXjcEDmhns11QB -tz1U9YAYd6DC5Em3eYNPJGBk93yHoxocVyEa -tz1dpxt8H9i2FyFmqkkCFZMqPSfxXA1QKUfr -tz1MLYVqQPtB7KowU8G9KCsp9DrijCqtyfV4 -tz1fMDvW5x1uU44Lu2UAWGGhQqDPPmnggp4S -tz1i7DPmuAXZRSxB45wLoxTRuScj5UAQ9kUW -tz1XCgNaVuTfDsTXufnT7BggoEVCLt89erEJ -tz1VGjHoomyLdtCAdsbcPCVHXzp5ctGotGor -tz1TaLzBu6BWMZfpWsXyuiPE48X6toMZD8cT -tz1hHuJ5qjgzpGNCfA5gaBdkYhvzjvbZ9MzH -tz1LUjAFjcFTQ2P6KKQriFPDsRbJqXSj3yQX -tz1VDR5uPfWpYCP46VEuExwW79yoQvdfpZTB -tz1M2ygdp2H63Z8sCVhQd5zz7N8B9kSzKNex -tz1ZZi92yMoq9wTBPyDZDEufEWFGHBYzpspQ -tz1e16SjjZC3Jbsjw8V6s958cvgxdx9qYgWU -tz1gf9GenSXtFGfjAsfxApY9tKNqeuVFPjio -tz1QX9YEREfYFgDreN1T14V93ETZtyZ5eDye -tz1g9Ui17npHy3Hpm5W9C1wXTtjcrQRovjTQ -tz1WCf9npabzwcDaneg2ZRv72scxWpkghGhM -tz1QjEDqKR7myvn7qzYMksn1cyzB3ZUBFDNx -tz1VjqJn9DZJX9LuRVu8HedRdzY5ZLBDq13q -tz1iKVzMxBgzMcux2HyvHZpSd3NQU8AjWt1h -tz1irqmC7pn1kx7JknNgyeETSCFBcNn1nU8E -tz1YfByVMMq7qR2gdp5ArNwTPAADwUUL63Jx -tz1SmUpPsN2eYeXJvzfksFGPdFLaaTgqPFm1 -tz1gbM7WWWsqDo5hYdDSzAzqfLk7sEqGK1G6 -tz1R6zxE3wRTWH3m2UH54stfSqrik1zBFMGE -tz1TmGDyo9uHHo5Q7xT1QX7MQV6Wys6TP3GC -tz1YKFxd1hciDa1FdGtPM4bpx5EBTrFBnzqi -tz1gDTuvqsQkm2d5UY7WvzBLCfWQcJyGvijd -tz1irNxGQagPYqetPfSd6Wn6WnNRZegqun4P -tz1Sh8PaaAvSTHuw3zMjdDNNTC7RUa8b47Tv -tz1ZJ4fVJbVWoJHF6jR5ojwK2Xsg5qMSFuMn -tz1RwK4qhXqPx5WuA7oaxRKgq7M1GBf1mDWf -tz1adZqApAdzd6q5QkPwuyk1oqs6fDk4eZaS -tz1Z2qgArGbLvt4fydMcGFTjRUgDpmev52bK -tz1cYTmT9w7rZVF7pppczy7rXtKKP7YaRzqf -tz1WZJUNz87odXGXS63EvxX58PyyjMniJLVZ -tz1UUEwZ4xBmwsP1EqthukSw3f4fU12qa3j9 -tz1fLBFEeCEihVDyoEc4KgkdB4x4TF1ZQXUt -tz1YnjDEWTqBrZcCGEhtR5izqcVCu9GHG6Tr -tz1Z6aBfEbXFMWjHB8qXF2rDbSwBP16HcXGT -tz1Vvpr3qSybQQzAhfAxMVqKrruARhADh8EF -tz1MifsbR8a6mhQtHnjndNVbUmeJiChPkCjA -tz1YpDmkVeW1VWLguQJBBnJiZUyKBf5GHZAp -tz1amxW7gCq48cRPEqfU9Ti56pP53p42K7KV -tz1aHRP5akoPvMHihtaXX9WmxwB8vkGVJ8QX -tz1WqvPbxEyTVonWpJwg8GiJAs4gzPMLFKhz -tz1ZwYByeVhiYmjDrETL2qFrWHGm4p382xau -tz1PfnMeUtV9mxyQikJh8SjgaSmLVCzWF3Uj -tz1aZHR75qBEErzwaVRNaSaCmmwCQkx84dWZ -tz1gXvwtAs2KBrCPDYPSBbtxK93zoBbxr1Zv -tz1Pz27ek9vcSS84fE11frHMkAPcXztJZKyX -tz1ZFpJGFmBNcsJRZdgH3sBiaAkRfMbUvnuq -tz1bZ9S8dVyEjytYpHxJY4ZzpLHVdtmkm9vz -tz1NVLodKqgf74WJvCxjCpEUeYJxxqtY8vkV -tz1RKFCyxCBZiR3CdD8tvXrQpkntMGai8X78 -tz1bJv8QN1EBg3kzaRjpdgBmBMHS45CFPUtx -tz1TWKJAa4aiSXHFkLU2mtFB7fSP3Lg3G8vd -tz1g82wkChDHGxNoFYB8Z2CTNQthnFP15tZL -tz1KyGzWQqzTPsEnfANfMFuwKnaxL1JJ9cY1 -tz1Sjk49HmwrStFY7LEb2DmR9FjSjKcXcMAd -tz1MvV6BDPT2X2AExw7GXrwQnGzf7kqLdwDV -tz1QR6XQk6oy1eaeBHTmwHuGBjvqTwdsjJwQ -tz1bFoSztinpJpyEH8qeiqwWejUh7jbvrXoE -tz1UTjSvh6SLUBUXASuvf3TkMP4SAqRGUC7G -tz1hYRjX94tNfYjQo68fYroEiuYLmC3Ahecx -tz1Vx8P9AdWsoQh9xea14XmHrgCAFKqdNxHB -tz1iuenZn7TqNpSW6kP2W5nKu91VquozfL22 -tz1RRt9As5vxNqDCt3xFjzzwtvtkL1j7CKvq -tz1dwx2W4iuM5gevodjDpJBioZPWtqZLMa3f -tz1a13Tm1QjLkXwuy84L1H8ivWMdVa7RBeBU -tz1UGfSKSs9jjqgc6qcvFgbLNxrjECuiHrUU -tz1gveh1a9Vpufk74xaj56ueegMVFRLyuxpZ -tz1fkyjF27ZVy3ZDxUzFEnoyHFsfd5HSpufk -tz1Yj6cq4TgZ9V5t1Dp8qPvz8vwtNCsai2Ad -tz1b6LdabGK64H7D1NyPQEohiymLwrGess5B -tz1PYcsZk63wcDdE6SGLTduszREjM2ZATurM -tz1TZ2TrqC3KcWvdGBhe5xdXLzkh1BxvRsBz -tz1fD23QmV6wDrFrhzdLzG56CVVA72hr8xYP -tz1YmdWGneL4MKWxinTWnWdeGiL73DeQLd7K -tz1ZfJwCRiaiBSrYEYTdTtEjjFPakgPCCkkn -tz1ePcD1yv36wGh1QKDjCsuQcdzY9XkmDUjA -tz1RrYMnYxekZpinhhJWsjEPJ4hQMhaMGf9T -tz1abczQihua17qGrsk6ENFyxUN6WLbnMekC -tz1QqccaGLsNUVuc611cj3cmip24RKWBRLDV -tz1W3gfvosNNBtymUcffV7WcXys6BBSmHtPY -tz1Lh1o8ur9SDJHayf2hbYSAXNH2psUMt2YA -tz1XZ6bsVJ8ahjWu7Mq3xRSwtJRpE3HyuCZv -tz1b9w2j1ckBk14PT1fMWjuSafSz8R5Rhhpj -tz1RoesMvqeaAU2PASRbnYNoUDzDa51cTmeB -tz1Rt1sBWvr2RvD6YaiDnkcSfsyLSx4uCbJ1 -tz1PTyFhuGJSCo6hWjYbRpUJoWD5Poxe9Giw -tz1Y3H9eZk8MKy9kbENEgks3cPLXUfrR6gcR -tz1NBezgXSBdNh7XprbV7ff8zpsyAes8qDz4 -tz1WM2VzTqSmK6gVEVZPxhdr2emPpGQkutzD -tz1LLanAXv43LAiu1KLDLnbyXw88FAEiZtmp -tz1YHzrwZeika7wMYe7wtDaQwCGTn1DzR9j2 -tz1M3nXkuJC76YAp9pMreSra8LTajmggjdmj -tz1ZmiXTWY2H1trRMdbDMLrbyFAA8BreAkxm -tz1XyMqhog4KrnpoW3pvbedvFrhaxMw5u5ma -tz1UwqeJcdMJpZtCSQEP9qGiZEHt6666BLtn -tz1LysfUkJEikvgfyGPg3DSYodUb3pSZ3v8S -tz1YJao5aoHi9yN76Y4gGZAKJDZPK8aP3bEz -tz1NWjgNPQTjgbXTtbX6D6hPdRNxXWaiUz1D -tz1Wcte3xLGMQaRZcaTWkRZGRvZNEd3s5CFw -tz1c3XiqVYuQ2SxcCoY45RXAVT1MiUoDHmH5 -tz1isB64xmJtu5x2eKupxNuNkzfauKnaEP94 -tz1PTmhCEk9CkjP4ysXtuuuVbjgqyeQYpvnA -tz1ZKSkkuzF5CQfDuGwYb9t28aph6E4LvewJ -tz1eS8EFWRvSFfo8s7uBFsB7629DmvWcuU7M -tz1cMscmQxDnQTzJSf4L7Q7mW6YCTt43Hfae -tz1iGJ5jeK1qD9qXc5Ywy6vqMuYTW4hypB8R -tz1daNpRnbj8kWzutAHxRTbi4mhQQiQnfitD -tz1QHnz9hrrhCNdQUJB7rRkkue7b2owbr7Lm -tz1N7rVxYya37aSVKS4MrMkHEy1NGqkv8qCH -tz1fgHFxtF6TcmmJMbhXC7Bm3pBcE7wa4rwn -tz1QcdsKkZzEcskFbfSFsofxVLTjRwn7nten -tz1ayFZJF4H9AcyhmVT9iqjib6JQ9GtDUvBi -tz1Y35T8A5EdVsRS1wjofbmGGrVXNujowjAk -tz1drRMZrk6oUyNhoUtn9RhbZAfGjaTMpkmw -tz1Vng8aSn8gQde4CSGbHymKKQHeR3Dwkkkx -tz1Yj1QHebfGfZ6PtM7xHZDDEC8LfAkxKRyq -tz1dN2CPZcUzZTSHNGdotcecFwwhjeP4o2Kj -tz1P76a8NeYoxnm5CuwvCKnsHdw38V1WiM7H -tz1KwEcDfguqLjEQBvcBavw4UMEKJQECtrZK -tz1cVJg2x5zGkgDnNFTo5WD6scBYbGc9owfB -tz1QMDLRpqYaZmk8mUqJzM53sfX4TeEUT7oi -tz1bgmaxuFPzZHcmKYy3gJCi2JvBNQqCiNK1 -tz1b65RUsf4Ao4JSYmCMKgptp6Qy467vfd3m -tz1RgaVgXau31JXy2v2tCDnxv9JsWsTmAuz7 -tz1ZK8mW53WzJpkXbag98BnGJRPeUrWNwpWM -tz1bXJuF2jSwEfW4HkcuHDLwC3LCUADvBD8r -tz1MoDofq9e8bYdcmJLBKJxyY3hdiks8dhz2 -tz1Rd1mszgfKBpF8DSzCZ4pYsZK591Quhxq1 -tz1eD8TTyJCUqARLav7Q8Z15u5si7LUAw2Dx -tz1RwYZVGWknZPV52VwSYQuXrNseH7WSDJK8 -tz1Qf5EPJEFFWavDrwxuMGPNshWL2k6b5g3R -tz1ZcZ7ydeC7SKuj1MFEL9dXajrgLzPDyZb2 -tz1Ze6rAsmWbk5urVXjqggtnLbcFE9nfoFqc -tz1ZrheNmZdDPXn6BboNz7F5rn68XHHxd579 -tz1YKUVV1o3MYtCEqzejXzviBPNc2BXZHCkZ -tz1chUPWzPHvaWyCdwvbnyesPmZoiAQEYP46 -tz1dqB94eBUL53cHax9V8aDn98ieV8LUJ8ny -tz1fAiVQARFDh33toYr1QvHc5aXDNfrQ4rSb -tz1VFQPyexpD6tEmHfJMiRtoS96ozVALf7Za -tz1MQN3vYmGz3mYfdWUZvLLA8nwKCaY54Dib -tz1NKofgqG32HcKo4FEhG7LTixn5tCPMbpyD -tz1cjt6nWNf6w86bbgPxaFgWf4gXbbcn2W1m -tz1gKXPEqvNe2xrHhcAr8HUEjRm3in2w5679 -tz1dkJPHYLgixd59y35NByJKvzGTiXHWA7or -tz1UxaPytZ813rCbizGYF3uUKLeustvRmy8T -tz1R2Q9CBQFKKjuxH8qeuTNs9ssBvdNTXsCR -tz1QHhXyuNLYPDtd53ESgkTJcdVBJw4tk33R -tz1fBfeCkuiXz3DJb2yhfqG8dM6Az1E7o2ZP -tz1iQgYzAmaZbQKjpH18gyZM4zBcXYachaDC -tz1fxy1E1pnDJADhyH8fb7c7gjuyZTk8HGjz -tz1dcW3GmaJNV2cB1HTiuAcP2Cc79VgKwPas -tz1bHJQiRFyqixCwWa9iPe3NQD42Wa6pF1TZ -tz1YEDTURm6xu3RjgD7w4jtpzfndqwtccTB3 -tz1gqpCuQhbRrVnzT9mGKmxwSyBRbaqHerkK -tz1i39zYwEStaaUvXkhFUqa7rLx2PYdP9AsQ -tz1bpfbz9sgqJrzPdmuvWCa1ntpzhX7f8rNP -tz1KroYxNzyDvoqA9ZgfXsBxexuuLmaEXncQ -tz1bpKGf6R2Njjcuswc8UaMGw2LfiUCfHn5Z -tz1SXDQLxEP9f6Db4GHQS6YXESAa61rPJ5Wz -tz1aZisqVkEh7cFvPfMKuFGY4CdCiJ4PAveP -tz1ZBAFZ8fveB3dgvco7gkKeAtemQ8LWPVLS -tz1b1ET8JxYqqbkvTWmxxSeA59uUz9uEG5TM -tz1gG7GU2dcW6M1Ggy1ZRvB6P7UtS8HwgN4P -tz1h3jWC8MHRZ2xXy4Z8koiRXRSBy1waGGKy -tz1Lv9X9kjbFNKjZhb4iDxqzYEubv5vUufUP -tz1N8EC9L4kLMAci1L9LnEnAwo8PJ3NGvMVT -tz1R5jE46aBxEurRZDswMUek2zazZACXE8k8 -tz1cwTUHacepqP8P45F2t8BUd4J8x6bH9Ntk -tz1fhaE1aW5kcqXR3wWha68oTW6A79K4bR7f -tz1fvgawjKaTffVmcGV4ScBQWtGpqcPqjzdn -tz1hez7PxARETAgDwgoyicE5DaLkuKpKdojZ -tz1iPPSR9RHrpteeps6MY7WjM1KDNUxgHrPf -tz1UMd11rGatdykgWsRYeKgpxRYJ1CKrkD5Q -tz1Pyx5zn6ndb21D6Hghr3c3sJ3H2PemUeoA -tz1YprEGfyXn9Y7hV3wsdNpQ23Ahz63kN1Gj -tz1KiH2inyq58qvcBKEzGCf7PJ2jyM7v3Xp9 -tz1dDoR6dpduK6Y5GM9vPzFvfNuBn9Qfjgtu -tz1ZGa6XYL8zwgzmnMk8oyGD3xhN9UfA8GcX -tz1SC1w9VyVKMTz1ebNAeCqyAvMqprgsfPi6 -tz1Qk2S7fh6UZ5hhQibVxWCspCAfMehHyTB2 -tz1XQPvDCgVXQEmhVvVeYmXKUziE8k7Zo5k6 -tz1Tg8u5wQaW5GGd8igPBnmn9htaonhmc7TN -tz1cNj9QW3biLNJ5aGuxVNPYv2bykZtoKCNp -tz1NU5Ra6eTMAgZDAwoSoiZfSnMRjECs242t -tz1Wko5CiuDFDhikyP8huevBBnurQMJ3LyTV -tz1TfhkBd6Y47E4rQTYVoWbiHVMahpk4w6kA -tz1TG9S7sBNSvmbHUfPCHbMUg1yUbZf4fLrT -tz1dW666zmUomBLpGTg3hcM9ymGz8fM9CPgZ -tz1U1Sq3WhjWuk9KxoyGAp7JUUmjA4DddQt9 -tz1UgK8LzkbFHM449FA3T2KhxTaXBWn5S3Pi -tz1dGNZXBQD1wzhjvRMoFvFQhdmtsr5YL8SS -tz1Q5AzgKH47Z2aj4dZjYedDpjXBxE7YFKuZ -tz1TR8RDEvaa2t5EazCgnoh3JsvmE8FhK4dz -tz1WtsLe8tkBtLyJqLw5Nf4tDTthXYZaJJzW -tz1iu78GGSB3SnD3ZoNxixGurX8brjj3JeEG -tz1bjZfyM73m1Exfhb8WRtNsNk13Yj29CbFa -tz1eQozWJfJ6LcKbUouSt8xbhVR3byC9ADPZ -tz1LPAxMwEca7szHhTL9rr6xDCHM3drzBXej -tz1Mb86sXcRcaShgMUtRNUetyDipqXgbnmXe -tz1SUvRa6de2psnuhEarRYnxbvQGnN7XP79G -tz1KzYo91b1i1wztZTuu6616tNzBv8oDuzth -tz1ZtwDoZ9tngpwzfHUZsoz5mVjyR7PBuXre -tz1YLWS63QJyjZsBJT6qbqykbdk1wYPUCXyA -tz1dtjBTSrMSAfu7bQkNPjNNefBrWuidnLQj -tz1a5tsjtrJk7BcZVsNR2REfNsbCUUxjv9NR -tz1WnCsfNRin1KLDCnu9sac6hrnmsopM38on -tz1iXgADqzLf54Ky2mkTUp8HQsdNS2HDeoQN -tz1dTDnquYPgthJx9VPUd8r8dZW67y5B8sGZ -tz1TNZuw6QNBhv4opxoHSS2vsM2z5SDeNPLV -tz1SR575JNi6WP5gfZWW4sgifdRWo5FWziGw -tz1gUJKqKixmvVRDe1QPCm8oRLvrjky2MM7P -tz1X4zX7oU2vmBT3PXvKFghgwd4LtcxM8ced -tz1ZKMrNUudMVggS56beB2MroQeQPTp882Py -tz1T61MQfAsy1rF8BGdqNay3Dg3jwEVvTaqg -tz1ToN6PrFTRDai8hH68aXnqvDdHGgP55yKa -tz1UU8dtu6F6WTejSYostqJBAZN6ZzHapPC9 -tz1gp1JPaaWrBoZ7mvtF7bdGRup4fspwrh4E -tz1gzXQLR6yUXoCvcwAL4XDGkgKGmpuVGnZ5 -tz1NpF3VQTFqLbBVzvqKSFZAtS1KDHiVqSJU -tz1W8esZ8YBehvfjtDjCga1zaUDm1ENfkjCg -tz1eRGyhDFQ2G4Rg2ZriZwc5CrswLr6iJK66 -tz1aSDRVHdmuXrW59DjnU3jSvRzU41KfdoG1 -tz1fSh3q5tSPbWYGTYyPMkFyvostZjrtx3Go -tz1R3BY5UsAdsktRBUBPED7xNYDtYCr1zkJJ -tz1SdMu4BuX3ELrfvBVRxCcR36SS2rrZJmvC -tz1Y5BxU337hqdszeYSAb3NgSMZYnCwbyxy1 -tz1XpHARacpQpsQJjpuGcRAYk254oHhT4avY -tz1MDvzs26z83BsAoiUmw1NhjRuh4mqekSmJ -tz1hB3D5hhcrCBe7FYsiJXdeintHf4ezuAQW -tz1XBQv7XD1YvUfCBcnCsiWCz1ehgzwHkavp -tz1fG16Hu2YCninap4B5ug1UD33wEk69b392 -tz1YR3Q9DifQHu6dfeAB57ZUYkWSoey2y3fy -tz1N4ywq7Jvgtn3VG4fjjDmDULVJmfnqeL57 -tz1hYQwkrGuzRaqtvtp1AfTE9xkT8NfqB1C4 -tz1NdJf6N74Tgmyryctvu5ovKWy1Jk2EFo4z -tz1LywyWLkpkzaiuAb1miqLM6AYqewcZ3XLk -tz1NtECfhTKjd8qYkV2n64Q18XAZgyu8uN8B -tz1ZzkoBuorFEqirMBBbDaeeMk1ZGiU9kMpi -tz1Uy8tY9uMd1gJjXsPdDn6627zojCyo3pWF -tz1UxU8o3kLhSbC596LfUJndwfR1o5RQbwXw -tz1NNj9suFYsDpCfJGkQwuATSLckqBUMrCxP -tz1MUB3F3RbUDQLXeSiX8APg51rJYq7u4pYK -tz1gjYqyik5D8aE45nCqrixYmcBZ72XhfhVX -tz1QQbxC3j1PCZr9VjKSatFXZySyEvVtDTAU -tz1MEfp9xeEvvKorFodwRkxSJH2hfyDdUU56 -tz1ZKJsez8dX6ogL3RYbDNN4A4LCyf3BHX3v -tz1MoWeZnrtxUg4HyXUqJvSkuxbWcT3uyixz -tz1Lu3uCbi5vZYqVS1bqkaQe3Yp7XaSCdq7X -tz1LNC81LykrKherVm3eAwNe8toaZQ47fxxe -tz1URvWmdznrv2V8C28Akq8YLoXCSN9s8sYc -tz1ceXQ6VZzGPHNoK8sDqjqXkm58HQuTqyRZ -tz1dYhHgLbLtvLthUyozrNcb7BcDUxKHvs98 -tz1ZsZqYAM7mHkmAjaNDyBxmEypWXDoYn2gt -tz1W8TfnfDxKSMk7Lm3knmKcVeuFUdMSDWUY -tz1QVWWVfKHFiSYxHPVqtUUsbh6tiHsmSE4a -tz1dNrciezpJWdgWERu3vn2JFgLUhf9fPzYG -tz1V6LhTzfHXvznFcNQBGctHo1c9nrvWdBjU -tz1idqkZFpmbGpZtWpT3ZDLv8KrDq2t5VYMD -tz1Y4zEkUaJ9X6gyz15ua2oBevpbmXeqoopL -tz1b7csg6QpGYcZwNv555nBkg1TLuvddWFmh -tz1S9cuVge2zY82DBnCqtNA9aTmMscYCpGmc -tz1eQJRXosBLNDzsdXUCxHBZKKCHE132kfea -tz1fKB96qRWVzLfhBQ6JcjvaxiB3UDxcaPVo -tz1LWZzT94JhzjTQ4hc3jvfkmHjy7ZRnCVfT -tz1YJxTtQ6PsXRizgfvcD1w11PnGwa1tfYE5 -tz1QrFCxuP2pT3gshBinRumiH86CNJRdEPiQ -tz1V1z7hGgDFgdqFF39i5Pt7vaeFARp1xcg5 -tz1d1W4xQSfB4eEfed7DnwLjegeaw1kX1i9S -tz1giCiMGAztSEMM1tcjWFwbqdvHo8uZs49Q -tz1friZTtLLsWFuvaT3EFhzC5siLh3RUCdoz -tz1Ucyqu8S3udqCQbZMuZ7AU1Qzb7QJMMfXY -tz1eR8AJ524e6NQCcDAL8s3LUnSmgceGkdf3 -tz1RqvohbQQ7bg3oUvh9Gdu68vbWnjsyTPq1 -tz1NYU2Ugm9R4k9KWGaZbd2dpipQ3nuHdXDv -tz1UNm5kSbLrqhCZDEEminefgdfQGkictVJb -tz1ipoevBSanxyrSgzZg7MH45vkQWiLTT3mC -tz1bxhJ5v2o63Kd8zMasP3GRirKiFDcMsqtu -tz1YRuM2FXb7XndaULwjK49GC5VSE1Jupfun -tz1d9HAmzWKFhBTvN6eAaiLfmbbr5WSdy34i -tz1T9bmxV8iDe51PD38LAMfAZbF82kvhgX1Q -tz1dqBqkgDfAKFEZahJpVd4AYNoYJr8WKET5 -tz1UHvHCZjMUy3qYYSBnaHveVK5p2KF6pjg5 -tz1cjUDGTdHHgeq6te1rf6sAXPAP5hWq6G93 -tz1W8bjQkjgbwY6iLbhkNLV98TZgaweSBRsj -tz1VTsWqg9JWYrVQEXtPQwhYSiCp97jEmyzM -tz1RUxHS3R9JCN662LaBMwUp48AKnEzzexJx -tz1W756DaakGVvGBNEtX4RgxkJN5nY4rwUg3 -tz1RyaepPFZNPJ2ZZBDAvEYDuacPDj9fk1k1 -tz1bknBv4A4eNyBfPqY79d8w2wU5bwpgRoth -tz1ehhQ13YEBUyPM4cAFvR8fc8GRFEtY1PuT -tz1hSaxHjXJo9Vnb59mCWqBYBzp21xwHZUAw -tz1T6DSj8w6gdMuDbyqgAdf2vvY5dR3DJY4B -tz1V4ntKjwftneiRB9uizsbcJpiCNRqFySGc -tz1NcGpMM6tZp96pWpUxxFaMNTyoWQSbWrep -tz1QTDZXQjU1o6bfwnvPY7r8WviWEx4j6nuH -tz1dBoNy2EvC8iCfnSyWfDuXvxNGXmmkGBtN -tz1XzRRjeyD8FAMxJaJq3kactFxjQHWBC315 -tz1VdP85szEDMNQ753gjSVLvfcypENcruoes -tz1PHBpKAk5HNskkWHoRqMZrrdBS4AyoRmYF -tz1U8ydokUCnfoSUEM59Q3SwppKFP9y84qpn -tz1Zcu7H5YJpLcNdEkiNkh4igPmKv8gY5FHn -tz1RvRyAJrcRJtnr42evdedaDU51Q4HrtjKv -tz1aw5ooaBjFQLhHmCVBCWX4YtypqKMycNYv -tz1UwH2tChqM4CxDNyatMvSRdouJpjysiiB6 -tz1b2fv8NF7FgvqhVjhmpyuJccR67NJhoYRK -tz1c7cd2JHbWUcmncaJnhjUWBsL9G2BMwpm9 -tz1QgRrpGHrAo4k6TLYncEPGsnNiVCkfi2q7 -tz1Vrib9UabiAEx8xYVSAzhq5Me8BEBh4Xpz -tz1ianwyzRQNKMHX38bWnpX21fWd88xFkWA2 -tz1MTJMxqfJgHabWQZu3Ae2UCHeb2RaKAMc5 -tz1U4DTNGekNbUDUtseykkVJLXfyBKjNx1QL -tz1Md46HsggyaAiCDrxyGzV3h87mo8WfnfqZ -tz1MpNWFtXokj6RTr5GckPyQZxL835oUwHys -tz1fe8afrN4PMyfHW4mcnjTz8Sfnbq3CLgFH -tz1N1dbNYoBbrZjYX3CXRRYR9tFiT93o2HBF -tz1X7JPGmqARxdYPKfya57yvByoEUkCDJUbF -tz1hwAsKNZSgc6hfu82LiVYUXDfdVTxKNiWz -tz1i6WukuHcaFnNHXeqbc8K9vw7tLQqNPgrV -tz1WvRNrETctwjWaGaWS2BE2A87WYP1uiBUs -tz1X7NvT1tGGjXSFuNBFK54bKHGTb4t94hsk -tz1egkfp42zwTtkkt2gWsrrA6KZYJ5YBTQR7 -tz1LDKFoACFFKdtktc9K6hE7qwsMxwApmLap -tz1VqnbfeZf3B3SkubkDKyoSZJDyWhUdqPUU -tz1YGnRCnd4T9y9pPGUYw2DxhSqwKgkVtrvy -tz1cgnS27hhtHFeP1CkvdXSk8VKNMF7VfjT9 -tz1bn9mNzvd8cQucbzJxJBAYWR9eYHe8h1sw -tz1ew2RUdGBHUBSECP2X5g9XjmZg438AngPu -tz1SJkv7mvcJac2sbrqgC3EzVzidS1akCvB4 -tz1UTxhYQ7XMfLguAtQBbn95dpNZHLN9cJoj -tz1Zk49twrWdd6EDEx3hcSqTNThtPrbV7vUJ -tz1VqdVBBnhfxSviixUqWeDAG5SNwijvsWKM -tz1UrXRmzEFRVdpPjiT7bECFXtHuFbS3ZT6D -tz1ephBJniBxfkDNb9YcoLGMYhuyrZBWzkKZ -tz1T8tLerrLtXo7Qnx4buWquFFzujXvhkfsi -tz1auWRnBuWC6zGSfH5dD6JJAnkVkKC5raDk -tz1PwvnptwZDvBo3AkSKUGe8qoAuJZcLSuqp -tz1ebifdoor9yskNmUXs51tta1ezGbbhjo7n -tz1WEg3Zw4FUpTkg3Qw1UqyF9ULPFKf9E6Xb -tz1YiRGnAovByLBBJvcJdbGhGyWCMfprDjwq -tz1VbvV9TLYNQMz6v3UqCbVV9Dn5tcJwKryB -tz1WJth2k6ooYW96kRfvpubye44TnA1QWDHj -tz1NMUzMuozszoaZ9i8FLVwmXAHoeHadF9mm -tz1gGXrVfkQmivHKXwvB2obRy5B1dgSBvgb5 -tz1RcfHjmG8dxUMGpJzKsjWv8zTFB3E6ePyx -tz1ehyVHemkMLaCSKUn3Kun6VL8X7BD5LHXK -tz1KgybuVdn8Xv2nDbd8dmxMyUjMTYBGB5ZT -tz1QCNGDHqcghtqjg7n9PQFP6oUAjuj1CCKR -tz1TL534G1apVam1JeMqaSKub7MWGUe2SNxz -tz1VPh2m75ebpqXhT7HnfecA1uhaAdTx2s3q -tz1Mo7pqhM254ACVd72rbMnhBG5yRpLuSQZu -tz1btbm9fbNGh736EBKw1E37Eye34TGBgr27 -tz1U8EnouFFuE8xr6f7ApSucbSwWc11tx4BV -tz1bka4rrUdMzcpSdBkyGJqeTJFESb97YnmK -tz1a4wHp4SrY4Aya1njsnb4wSrh7fRJ8TUNH -tz1ZzQu4yr4KJ8LAPAtcAXDr7yUAdoVjejpR -tz1WrhpkSuiyuHz4a69NBgiCvbQgjknK1fM4 -tz1RPq9SL5sdSdiUZApwFwFfNEEgMgVZmRiT -tz1LMtAjPAwMFmnkAau3xdx2yRYXmbRpQuty -tz1dbz2HDYuVGhR79GMAbTP1Gs8wekJoQTbq -tz1VFBQkHv5iEHbPbnxUBtAR3TFw2Yf8Gj3Q -tz1igQvpq2ic4YjAVjqh8aTCmXNpN2f1EwJc -tz1crEoJeHuAFxjN5UDCT1c22ozZc3BYHfUj -tz1V8i8fD7NaYRzZzARsiH5Uky1iZCCUVzDA -tz1QGPm7r6uQNQcWG3g2z4Qsy1WuQNN1ZFCb -tz1ZjMB55K9cCWLh1TgzTe5NzNCTa28f212V -tz1PkQSCB1USnNrA2EP2oWQanBrUwrSb9EzW -tz1T4ARE3Kpp9vbwGLyNWxdpTotz5W1YKuyj -tz1Y6pADrApKyJKQMgg1MGneFxvsBgko5pf5 -tz1YozV1TpK6fh4VUHzc9MnAVEy1DKfcyNxj -tz1YhAm1Sbgugn6LKqXM8fAYCno6VUm88xqL -tz1VqZuwKv35ksmJrRho1qJtsejerhN2D414 -tz1gQ2ZbT4nH6qcDUbdkRoaNR53u8o1hm7No -tz1dLZf9b8J5rWEL2ZkLpSQCTgUg6oNxqVkB -tz1c89YANzgnKEbaA6ofD5ZCZXGQQrhXhyW1 -tz1XHm2fePzedMV9rPes9k5d66o8YNyptGy2 -tz1Sa2YqE3MKdnVcJp99AaXmz5pgJ7s7cSAi -tz1cN52jEMA3BvLFe8VdCARTop3u3dwLHKaT -tz1X4Qt811aDDttGp1BCLWbUwRGp5MYWdGib -tz1RCxAyPGeUdP7ZPdVxbjbwij3itpv8BMDb -tz1ZgBQEXaafjFoTaFtkuZaiRtpVTwdC7wc6 -tz1R4x2xjPa25NNGyKsHXw8NxioegscrpDQe -tz1LMsap5bXac39947stHcSCULxaXLc5kyMB -tz1VSMstGpiZQLQkr8Xom1aYq3QEq8BFjUqo -tz1YKtsmUo2aVW5ctufpcudGffDLSMFvj4zD -tz1b2i2Brv15CdN5rRcCYqByAGxYUc4DX3Ze -tz1PzcurZmJR1hUGS4DLEq6aQALMUUBaspLs -tz1QDPSjs6mtdAVnGAexfKLjwoS2AXgKYVLp -tz1LzEa13Pyrae9kLzCWnt3fddnvaSGP2dKa -tz1UkKJnVbG5W1ryLyKYWZ9zKRApXL8vDpo2 -tz1WNxNc2TrUroSjiNn8Z7wbfgeKJL8Gqyn4 -tz1TEniC1iK97iSppvXfDWnNLE6iPAkcLYbi -tz1TeihN8akNs2uVAmGh1TJfi6dZxgjLfXDh -tz1WiCoXdqcRJwTRJQapQCid6vy7FWkgahq7 -tz1Lq2MG1pXGm4bfN28Y51XsxDdRgUKCxVjF -tz1b4tjvW7cVGRzQQBwS7WMak2vEtYxSJt6Z -tz1UBCjmZ7Mp4rDwEGLBnKmiert7hZSgJn7f -tz1bS6SfHLb6bMwzMyG1EyUMhujb2742LWCD -tz1icyiUP5h84GWe9QENdbktWi6K7XiL9Lb9 -tz1cs936SmSbgje6Ai9emQwpxmSbtxghcedS -tz1RdBjtnj29RKX5zC4LLm3ziT3HKfBEayki -tz1M6MNsywQjUnZn4A5Cp56TgwL4Sd2hC9Ph -tz1fsookn6epyaJ366g6ofMS7zyfhsp692W3 -tz1Q11U5RqsSE3zArTocALhQpPp7frG4QjPR -tz1LKimp1T8cjPRpS92FQcrbndaxwmTyTbxY -tz1P9PBxT3vTuiBZpjpCQZEfSXjwRiLWCgju -tz1Qv3zk9HA3XguZ5KBLKuo5T8SjVMDfcxDB -tz1Y6iKzabAFfPhe1XD88dWa1QLeeuwxSSah -tz1dpZhiYU1LgmGTg9DVUyR4tcccNwzbecBi -tz1e6qNvrFernMYfMyUUJxLX32GmFJnBLfmv -tz1PUjGhcQhWJSphf75yExb96VHxCckEdcQz -tz1dYRhbNw9HQ7j86TgXbM4c1cZYzZHsJgHf -tz1ZMm2EAXY4MtsKehgCvHq5kbRjmZaV1UFR -tz1WuwADRyDybsYbpstm1s5KUjxQe6kDXoiB -tz1eiAonTWNhS7ZeLw5MTmbBzDdpArW3foCj -tz1WGD6psq6SPrfukdxGxiQMMVMFvshFkjbL -tz1MorGaDMuo44g6r6FMPeT9wevaLH4AiAeY -tz1U1kbecNSdQLUxQxrP2CVyc4frdiUwo6J6 -tz1TfH2dFFoHJdA91NKH8GTPXCHWYNy4gKhu -tz1YDxZeJhpG2nzJsHMSNYcXJmqUdkEYhFkZ -tz1QygPphEtusxtctX8VCAHAPkKFpqpkDxjQ -tz1cgpFcZ7a8nvfUq63bZG7xF1SqKmcGg9aH -tz1WQM9o7tRPfL4GZsxgqRE7Nv8woP1QFUKE -tz1cEzAnWUPYc7Lirom42tCbJidzYaYnfHn2 -tz1f97xCUXuJSose1srBcNc3gRDP86CofVub -tz1RL4NkUrqZZhmP9JPvy5x7vU7bkCqus6zH -tz1ZtT5rvaPUGN2cJUUxUxg9aE3tojL8WnS7 -tz1SAWqL11QH41BtfUeABj2KXW4jxYV8jLos -tz1eDzFyJpJa5NHzTjRwhjwGE5WyQ5Qwm4wd -tz1Wc7W9Bwa3H2umLtsaXoZU9DC6aSsB5UZA -tz1UCFqyQKHsePW2frqyZ4wTQU9DYFjiU8tD -tz1aZhmnULtz6iTXhkAaDtN7x2qknpVQoApB -tz1aUqAMSDNWEnTjxCpkToHzdPyVYD4RyUAf -tz1Q4xLnLX3oKLLQf22TqXNJimsoXcbSBzve -tz1aHynWgeVNoHdvXEtLkrtmQ6m1XwpF7Qhv -tz1fNLzGaapGggBnAw33okTFDkdqQ1K6prX5 -tz1ZQ6eUzdNcyomdD9K9N5zFiiq6AwaUxnab -tz1WNX2gwa1kmi6WbUwXgfLtUwEvk22BumgM -tz1er3FkbHx9x8mGFiratisPNV9jDacWZ7s1 -tz1ayyiwj3N8QSNmM3H9tmu2cW7y31NM5taF -tz1djqDpmGtRM3timGPcJ9p7RGBuzEBjLnEW -tz1NmTtUtsFrgS3wwMoYw4oX58cd8fBWAvMK -tz1i35MFfXsjjTBCCcsGuDZDM5fmgK8byqFY -tz1cQBGBDTLZZh4nRbtKfXH1dnt2JPYEieLa -tz1grAfkffeZZ9KhBoimhnUNLkq4qvnpNycT -tz1MX8B8RSBeFWd9UcCTKKKCjZjqrvpcBREb -tz1hsKNxDx9RJQUJrU39g1m1JdZWonimCyzd -tz1Z1ZbDeQ2c1zqoyoukB8bRdGwzPU86krtt -tz1PTi91hj6saUiNUCMJbZWHoPupujg4CLow -tz1SziHU8YFohfbi6kuYao6h8CAziT5VUCYr -tz1VmrrWNHT6wYyb63NURDzfPYnUmPJcnhDZ -tz1TagcdqSgvGuauRdKmvoCBzRMY5PCFnkHs -tz1YBjfhkNoT5Mwm1Kkavb3ejfE1dAUAmaKB -tz1a5EZjFTniJjS7Es2ez18359skhQ2nQEYV -tz1SSnAhL38gibFyZc7uwbj1JkobSvxNEzXA -tz1RKsH29G8YAocneqZ6LkTU3QcrvXTieWSB -tz1Zhgdq4TLYYWZaEbJbpmo8PrU2Mn35vfZX -tz1etoNu41MThsrPCgwgCRkLMNAXuuuhMnqF -tz1ToEyHGX6w1BwrRmZLbghWiPm4RU3tVTbn -tz1LSpMneKRhCCCxVS2YYyCmPuLkoHyHBEnC -tz1ijM1TJx3NRLLG2RmRHaWphFtBzTPyJtNV -tz1PBLN2Tj4Tjer6ZGmZpYD43LwS97LuARUt -tz1Ld23yNZZu8iHpJ8VyDa4sHsPE5ZQX3DtF -tz1b1MZkRijS1DHvXewUHzWnFKGmyD14WFEb -tz1cvKCC1y6qAEr7AZbEDthhYhogAWFDjr7b -tz1U4i4pYPVvqMJR3ahzVWk6ib5V5JoTGGRq -tz1Rxkr7x1ZMM8gBkH2QzUdhuTvorfozLpyZ -tz1ix3Z3iMLbK3Qa54EeboV55jNVmGLyeZKy -tz1av5WzgDEaAhNgDsVuAaK2Te7ZuWtFmSQu -tz1c2QuPSXpdKXtAFuzb4n9WF2d9RUkeFkTj -tz1WVahnNwA8PEvrvsisG28apVQ3XaRSBsk1 -tz1MmtSN49adorZvSCvsAKUGZhn3pjw5r6ma -tz1R4CFhcPYzqkFxqEwnNpJZMDDJZcrdq8Ws -tz1PoEegfwStLfHPK8RCHJrcuX9WLLoitpJY -tz1iTk2vUaURgprTGxEs4wBFZTDoGbWeVUrm -tz1LNBuey6CZzSRFpJNQNxt4so6PMjDA4cZw -tz1QHfCvKchVMadCasheJwpXVVXofn1RNSGa -tz1SJm8HnHvhnYKCMdJMF7nbDijz3y4RDeWv -tz1PZRiQyzLdFFh8oiSv8wV4PdQgPn3r5XwG -tz1YXPU3nEgwubMfvXhYxYCFbc3HAJEzwyv5 -tz1NqQRSYZAK2kPy56KmafvBTGDABhMkvFun -tz1f5FkJE8WCTuurx1NvUwxSggNf9D3aX9dL -tz1PRRZ6kvaUDf4p3VUudgrWjhf9Eane39Re -tz1XFRtHCVkbYbSugtHEFktUa174atdJBqYs -tz1Nkmp4s34m1vkGAUqujptdhu4MN2zvwkN1 -tz1cfR1qWXGfTzWTUAbEoLk1eKegdQk677wG -tz1fU6kDFTfNoc4xpsoFPwYmxkWKdK5pmHpK -tz1dST6SzS1igXn8w8nyDAd24XWGtNrc1B6h -tz1fERhNPM2s9WLQdxyVwqRX3Voqzaq9TbwV -tz1LVKUZzmZRig43rG88DMSnrbgEe2rLBNTN -tz1ZgK1CNtZXFsYMTAPAogkoob6rtFC1ZJh2 -tz1h84b5bKnQgd6hhTRw1UuMoD4qSMBtxJvs -tz1fX2LLR3FJ52S6sUMXzm46vyq7WyK2CJA7 -tz1Xnaxtop924gXAdXRVD7KwVy1K8sPHMtBC -tz1NFpCuCNXJn7gpScqAwY7i8488ZfRwpgiM -tz1d9KW4SHHG4oirfsjRso7XRntwznazg3jW -tz1N8DeLfwQYack8ddp7j4Aiqnt8aPGKSpyr -tz1NAd29KK6maQD2Wf6CYCwuvivxsj5h4bHW -tz1QLrxBJ3PdA9mfL4B8cvyQ5fm339BiPVh6 -tz1dhMkqgRNENDR8db2RyL7JA1mHzgWtHjam -tz1VDZfNJtCGkRC7yRcEVfsbCcHXg16Ze65j -tz1hxrLCViBmnSSvMfr1kwNH1CH7ZdGYxo4f -tz1TqKvQRBGKGfEpmqWYQ58S5nyeYDSy5ZAZ -tz1Ug7u7JGeAbj5yaiAVAKWy5hv1hxgzQRmK -tz1daLUsC5DHZfGWJUDS28XBeouErWizmDwp -tz1hXLqVasfiCmf8TdjztQympWopkdqK4pxQ -tz1h8aQubvCZkDmazhZ7iPqkK3bzCnQV8mk3 -tz1dJMaNZqj6J8KWeNDxSetHd13p3ae3bvh8 -tz1gh95ciBLkARiPyU9L8kszQbEFANMwKmoe -tz1Qih11Qjgep8gF2LRSDUBTz2fA3zQZmqoy -tz1LFYccDrjCjFcvHvy1rBtzBDUpYoLXJ1No -tz1Wq9Rr67KiGrf4GMJsLcYMBCD8WJSvLGVW -tz1RRYhsaZzDHQG4e72Po4Ms8MgwroTS36AG -tz1PEuvS9MA2LCnQftcffwjTvBCxwmZrakCF -tz1dFmZ6RRnZdx8RXpTuy8r5TW6YErVLsg1Q -tz1bXgHFdh6UYGAYZ8TCjNBjSCddBygC5Fcc -tz1ci3rprnitmvCd6W7kmN8nrvtCmRMGdc2H -tz1UrNz93qEhSuhx6hbAfnLz5D8Axck88CZa -tz1KnVCAHBXDZ36s2YKPWqbxmewggLHikdfJ -tz1UgsnPTDLrW2pDMqczfxCEhdYscWS2DxmU -tz1Xt7yymEQ3XdaB8KAB1Ho5hJSWtZAiWxKM -tz1cRX4mjuqopAeFmyU2YrebdMrkmMiiGZRz -tz1RfM2TsCxvceE5rEAKJm1LVDusahf7Etbg -tz1LnSjC5eSUpwCGxH18wFwdqZhJhTBEL6H2 -tz1aYhuKM2b1nYPoCb9LB1UDjbJ3tmJcy3H1 -tz1SvsxsbDD5zWVobapG9ZQ3eS4AxqmmzDqY -tz1RMDU2iWicfgk8am3viWup2Vo2S5ewjtv4 -tz1ZqjpjUouTUoWxvSEbYi3Vk1yJ49ihjmZ3 -tz1avhBN4jnj51Ebdpbc25HD3xAkQkKjbNaX -tz1QkjD34QBXEDoEg6SNenZVRGJ8T6YBZHKz -tz1gjFxgnhqahJkUNet8DTqAZwzTquroQogC -tz1MoXB4tkdtDViN6Wq7XQfzhu2fngFeNSqk -tz1RAUr15HFDXw7T9Lo5Q5zqhXEp9WgpGvqi -tz1UkVpUKX5JRkpqQrKEpWWvq4KiGBbuTJ9A -tz1bhtsr1Wq19wfv9j4xjpK9Kt6YJwH6AXZB -tz1Pi2jrWXqno7QjPUyMQYJkhof42j41jchV -tz1hUhTG5auzSnH6ArRSnadQyPxEw8FURAwB -tz1ZopWTWPJzk94ARwcbjBp7WZLRHh26unuG -tz1U7Uf5QhvDrTQ4fMG4fSxBdeX7P3aYRfzm -tz1N7g3ZWRA2enxr6odH6qYbPAuTFEFgqL3u -tz1TuFUpDkm1XB4H8J2urFEoJ3d43CEtns1W -tz1gUbai75BKyRJmZJ9yqNqAPxspi5bkiz9t -tz1R9xnfXmYEjGs9oEB3LRwxzT5qyryQduEK -tz1iyBaGpFN3NxR6k2iK2n2uQMMkTTmxYJQZ -tz1fDJVxoqkw39e5FbANbfUZXT5Wy1gGoNAv -tz1U64FNpZQxw41ictY7BVvxGRXgfa9qVnWa -tz1feDiikyNw2aupiXH9znTMczQuVDGAwLLn -tz1NwA4Ppf6hWTTpxaJisDDYPv46gGktu4io -tz1V6UcrD7ogMVybntqpgQVA6o2De1ozZKG3 -tz1QdPoCCdTNgkHc1WvQGbAxPLwhv5Hu1pTh -tz1S2GGpPUDgf4NJnkRaKoF3PLohd9EPdWpW -tz1U2NSGduRj8n5DK4YtoCLKmPs3C6BSpWLp -tz1ZKaZ4nP6m6J9PpEdp5bRDLsUMqTWpK6H3 -tz1aijv2K6ShXDetALoLAdqKLyNRVGxkxZPk -tz1Lp7SHhaBe9gP8RmUAZz1Y5Dy5WY1gwzJv -tz1WKqRRyeTLT6cukJM9mLu8fpyxQ7JA6rq6 -tz1VmmuLBddfYvcwTbiUKdxANcdnGDnR8GFJ -tz1ZhBMAnCjSfPWobxZYk8qFGzz3bYPy6rnQ -tz1Q8DNMJWiaErfkyTB19ZiqXtUsFKyNnzib -tz1TMY1KC3ExfD3ykhfMz4HHkEUTUScGzxYm -tz1ZKxvQ52BtgiSAtNtJHTWrP3jpR6dp17NW -tz1iGnYu8X4XJHpC73yUVYttsVWo6o2W5WCm -tz1d1ZWoLFt4Jxdi274wUkZd6YjkzQEnNBvJ -tz1RfcDWeERNP1Gj7ZapY2Cjqhz1PR23cpxT -tz1XdFVnFfue6MsNFwGYeUNTgXuhuEmo9n7S -tz1WBes6nceFCrsPYw4sEnAVZFGVR6NsVT7r -tz1Uf6uxFZreCDQcRSmK5fVj2kQKFov5taQm -tz1dq49tP8Vhih7wEMX3W1rdR4SwGRwaTszB -tz1WwapxoPYYLg6X9vi1n9eaEQZ396G3GgpV -tz1gURMNvG5VkHWmXdRjsne973DFBGj3SBCV -tz1WxcjYT1oJMYaP4RFnaPdZuk97CVAR4QRh -tz1hsBNd4Eyx1cKVWh57tmthNWj8CYyLgxK2 -tz1WUhXLJFxTvy891JefRHSEGXxFdNY9RV3T -tz1SvDeF1BzFg5pT9jY6VgF3petrn1gGQ8PQ -tz1dAG5bwp7e6M1RLeNXAguLa6WFW75o1nso -tz1SWCz4EKqNYEscRLW2YB7q3svsxKSB7NFt -tz1V2MWedRfuPYFWpLuqKdGqL2bj6aWjti1s -tz1PycR7YDdEBvXDULsAs8Z41s9HR7cHd2bT -tz1LYcrK32dSMZATMVK6zfN8ruhKL5UVVhQs -tz1NmgDpqvEtkeyafF5J69GLCjo1YSYwmW9J -tz1L78qi4MaivGKC2HpNE4GUT1arTuGaNCmr -tz1QN4ppRGx6STP18GL8UzY1Uzq3DsM1voZ7 -tz1SHajMFzsC26Mhespjj75oiqTgd969Lycy -tz1iAJ4LbfWTpsE77YXbuxUS7suK1ZCDm5DB -tz1U3hHEGGA5sXo33oA4yaGY3atnvVK1MLLU -tz1QATrPHSdkH9WfVE9mby9zcni7atb1CWd9 -tz1gs2j7UKGkFg463WEiwJ3BQzeHhro4wgao -tz1XRiv1W8kbqoshU7eN4iL2t7RCrv5NSY6R -tz1MzLdRs4zfvzBquRe9znq7Q8GZMCWW9X1X -tz1SquX6WBkXq1S7zEQbhCBavnDr42BqGSgd -tz1eYXbiYAFJ9TC8RvmhX2nmzdgRabm8Cfdr -tz1aMtRu2LqYMJ2cttsufduz3FgwqDMyQ5ma -tz1PRsia3NpLTFZZ4SJbdxhJQtmRAnBQoMbq -tz1fjABA3D76nzZcWURGEoBJtN897y2TNBzc -tz1dRzFg71DV2qpso4JZJ5eksj9Ntw7XKC1w -tz1RUghy6MhvbCCXUZq9wrTjfRFbvJRduGp9 -tz1LPLEExXFxysx8eSQRBZsyG4b75PF7iPQf -tz1QMpagCFKmTVcLpZeCfUWkGEUNwaYR9HGw -tz1ie2UbbNKSCNcBJnnyM6rc43ac92Bz1nXj -tz1TLy1LhDKV5q4sCbNAxjLrqqMWz4morgJd -tz1ZiyD9dTSiUTJNGu7QaX6UoX5LBkXa7JNn -tz1THnm5gmeitKLYEsyfZbnh6QiAfMxBuMY1 -tz1XASMoG1Vqk39uWxZUK9Aa1HQnnffNwYKF -tz1NJnQp2RPNTi6o81irPbBFML2C29gCStfU -tz1Kz2Bf2hxwcMtkG7QZUGGwznrA9txBKkYE -tz1fSEYB5A6PXbFVAFshabEfvrBteEjPJcrp -tz1a6hQpVNLa5JAcubfHNWFheB6y6qhoDp2F -tz1g6dZ2rwJTqeaQgtAqPuXgMS9DyH2HbSgR -tz1dm6xJN8nGufmuEpZ4s3bjaX93c2LVdNtZ -tz1YWpBonkw49fn1ogVN99WkqytN7Do5pZWy -tz1XEYyqJdiX4aMkMuEyBLH3QFfDeY5BtZPy -tz1ST6yioKhm7jHRnNPLxogAkZvNbSWGrTWo -tz1V48hcuhqSHXazMX2sCK1TKbxCBHLaeKCX -tz1M4aQXUzNv3782Y7rm9XisamWBxupFopHL -tz1dzzjsL2SFjCVxGW9RrLcRTKR5yhVe72bf -tz1eyQpYJuP4xKW9H4wUJCP6GzF9zxhTJE46 -tz1UuxtB2pZfN98mrKWnFvUJ7zRfdF5xpzQv -tz1XArTjLz9BUZYwBEaEAmTMURmfzSSvq9JW -tz1VnZ7R3xCinznF33AyaRzusphgaX5Lo4tU -tz1KiynfPmTxhcTh1CJmb6PVgbm1yFioDgVH -tz1TZkifTaDWE4kSeGVbKpFsm3HvhVoPc9qf -tz1Xici3tAjkCxSskdL3NKFLj3J8aTqMSwmk -tz1RRBBdUGWRgKTTMvew7sikDBYvatvUVtXK -tz1NUdm4j8yyVT2sYB2rSWaBwLmt5wU1C96d -tz1KxhCJakwf9DcRtHaiFpPTQnvW5dajiGya -tz1XsJmepm58wPbW9kmAcE9HksAVsRGDcywv -tz1MrtR3BcfT3pQJiu7c286Q7YorKys4SEtk -tz1b4sqGa6YWiuJwQjgqAWjfCamZCDrRq1tJ -tz1UZKSqV7QNutovDLGpH8kkU7vD1bDnDRtP -tz1fnh42XbSZejTfFdqRmjj9G89tFPKUaRPs -tz1YAMHG2scbji5CaSmUW7LDpcvk8dYWK6Gt -tz1dfhS8fzxrZd6cxQ8oQ5kEHxdsXdzdwkjf -tz1ae22kSWcruPRd6nqLWJjR1jvVmQPZ2GRe -tz1PzuEc5zQRGLGLVzULiDALkCJ9AYSrYUS7 -tz1NC8a3zkqS5kDBptpAt7BN7iKKz248APnN -tz1eXaMNW1vPUqoC5EPmTsMhxg8GVKXZJbCS -tz1Q6UEsp2NZjrYwoW7BDi3UWpNv5XNqz8Xh -tz1Z3yeVF6LdmubbM2Vii7TU6VyDGwexbxaK -tz1gMa6n5qNMByGz7SPBticDzKLU6ZYvMSSc -tz1aB1WkcRNUAPp6MyM17wG4CKhoQ91vyRN9 -tz1Pr8L7m2RLEj2Lq6MZ8AdPyZtHHdW9YzVu -tz1RZuYGc3CockfFUHrRNxV6wwSuP7oar3Sj -tz1MUDK2j9e6xsqAdpzdkEsMrGnnf5AZfkU4 -tz1iLr529659kXK15LQgbUNx2GLKyEek11BD -tz1hFTNJ2NhDrNXqvMBLcBaoidpByG5QSe49 -tz1KqdD8QtBgKwiRCq7DB77j2sb4R7pHJxig -tz1MkvNZKNUQ2jrUcewbgaPeb6VupRZDKGV7 -tz1KiShRHtsHCSsrrhiU8JgLZFvgCjY5aHoE -tz1ZYgLoRKYh5Enb5AiZ1JraZfS4N192f9Tz -tz1Q4Q9ETQiqMqt8zVW78a6yfLYgF45fyTMF -tz1UaxTs4xASwFQLRLNsf7xBrpf4LJWNJNUR -tz1MsZuNQWXLa9k45ZRPJ5CcC29eFkmB2eEn -tz1iDMXGs6ZQKjJtBoDTDjqLos9qavMYw31z -tz1N4Y5zBYFT3bGRuCT5oFL6VYBxUfy6RHLG -tz1MA8sCgVW1nV7Ct6RT4Uo92cUQWY6Em95d -tz1YQ6T9E7WukE6Ww6pVNqFYffqkQA84AjmS -tz1SG5M7qTFZFvcd2eumTpXjTynhDfpHkVr4 -tz1SoQW49upVLX7yuKmtvsjajmnTUf4Dy6jC -tz1PgosKTyEFTZodsFXrFoRDBbn2XuU6bem6 -tz1e5GDqWFRZd3MCtrZpHJcDU1qRbvQmSZn1 -tz1WbX43SW2ZWdnjVNeH3P5gGsCUmjepG7Rx -tz1W1VmpPcX98i5v4o5fCzqS8ApaRiAXteNy -tz1UhPha421K11GsGuasB4wS2cGtEv3E2tCk -tz1LqoDZ5GtwReH8SDv6kVW33griYn8DaAxL -tz1iUyexdkXMMy6ruKWb7nG5J58SgoGiU7J3 -tz1aNW98QPGehZd58yuy5G9sGESZkxsCwmEC -tz1di8fNMUAwecASPW2tCLL6FDt13DmsMUyC -tz1ZVwWUUHNGDurt8aN7qMdgxtkZDYSs6GcT -tz1ZJgV2dxr51DAJpzLAksnRjNiBwiQhZJN4 -tz1N1te92YC4AbeCUEqQVrbYRJ2mEaTxxqPV -tz1RNAakmGigJabt3Qynunu88Dh3xTVecUMG -tz1Zi1YmWzeCsPqPNnvGyaSUuExHupyUofo6 -tz1RgvwsYB5Bh3y9raKwbQDc1HjCK4kX8mgy -tz1VBR3b6DY5HSJsCxoCbqdTkPLZhUX659Vx -tz1cmVYwFH2p7a2R6Ejn11rBkUNPWHYtMLCt -tz1dYUNtng6zDotzb33mL7gKu43M7EZ2EH9q -tz1XjTFsyFAM2zXWLdkLQsvzjq2HBRJJ4vgq -tz1bTBt6VwR6q6DFNTCxd5bNXcB71Vg9yJ8U -tz1cd4Xghw1wpwkJsyF4frr7Vbb8M5N6AhoG -tz1QrwgASeVXo95f1VdME8czEpE6mxghwPW7 -tz1NRE6H9Y81fNfE1tR6ZKkUJ6jaTAjmGZDu -tz1N8FqnLZFcvTBntWcUmwEUqwiVQYuqupEn -tz1YfMpMRPxsMWeWBedJQ5j5CQC9AcVycFyQ -tz1RoPTeF7KLErFqPJZzpNJ3QSpYV8hu9yWd -tz1NYnbnYDosKEoKrNKWGwauVsH5VrU5hziZ -tz1gKRmUmRbL3FrGQUDSaP2LBYWKKUgHZb6R -tz1i9JQN6o8fnZkG9Qv72zeu3GC2h7fKHARg -tz1ZcWSmHBSLzXDVcitENSL7q5AkbPJScYj4 -tz1SF6s4ZcAzAHfjPKv8Z8TPmmH6Ew1KKgqD -tz1aiJfPpzvBzrQcL41cWfDihEFYjDm9XGkK -tz1VE52PrsiGtpGq9YihZqHhgMpD3nydNpB6 -tz1XYKYV7MXAEJLMzZqXV1yM69gu4emaxFCA -tz1ZdKvgHfh2qR9kjwyFhzRxD41mSH6UFYqQ -tz1dhoyui6wWvYXhswUPhmvzq6CAXiXf7VUA -tz1Mow8Uy3X9QSfURjEfJdKGWYLCPrBDZUhL -tz1ijeRZAyHqauL5j4p83hbDYChytJ1whsZf -tz1LvSVbLz85pog6BN5gN73kXxxAub2nuQu1 -tz1S6uEQXkkQFXH1fZbfdZiZmq2rTtpg6cXk -tz1NMYSG5MCK7h9gWjwZpn7ykijffLqt1gSH -tz1eEX6NbxqbKKMwzW5zybvwKHxNYf7cudCy -tz1LKH1D812giLrLTEU8ME2dnGhiy5sVbSWU -tz1gLRbBNsmjrgGvtUt4xjAHwgopnHptxZN5 -tz1UrHG71c38biycxLYFKD2FgNs177qTEEkh -tz1dhS98aVDzbhhKRRgJ2VttbD6iLdccmxYu -tz1KrG1SFjp2PpNFG5NFijx5S7LngUPkgwxX -tz1V6vXr8DHgbp46PGYS3CU3jhnU2zA8qwkG -tz1UzY3pKXQG7N8SYTZ32kfbb2CcoM1J2YTM -tz1Y4ddGzcmUbBYGmJ9k6CJxA5PEt7oX9uk4 -tz1RiWcwGxytk3XGntmKpTYyMVMLZva6cBqV -tz1Q8FRZGSfZTy374Gdkz6ipDgTtNTU2eArC -tz1eR5c6ovjbcdfYXpESfNSFskDoE3Ffbsfi -tz1LdMVvmK79toEhV8qGUbffUxW23BMc3Cpg -tz1Zm7p1atdona2FFXvA1CkqqwqTdStFA8sd -tz1enH9LVYsXTwJAdWBH6J9ghGWNki8DJXCt -tz1c4J89xisuKLK9cYVHDYL2EV6dqhUmdcte -tz1c3a3Qk1y4o9jsZBm6891gHjLK8NUYGELA -tz1QVwvUHCHwTgXSBZeL3kDs1LULdt4VPkpr -tz1Xq7gEPAJSKjjLhL4HaT8YzhBZSQ6muTQK -tz1KfpD7KWY4eYAJdLSJY8gsHC8YZPyfshY3 -tz1Tc8mJAu2bz3d1etvFgMkhdVVNRhRdTw5R -tz1QXHa6eRtSmieRTodVPc7vKc5WUaHUKoAL -tz1M9bWJW1FXoSqMhTT525Vp8r5dGDwGBXp9 -tz1XRHsMs4WXvybvb3WezrctbnaCQM7e8pvx -tz1KwiYJxG2erKwu5Z7Lqs3jT1Yg5ksgtUS2 -tz1hPhWYCf6h4YxFNAjRu5RAtfQdKr2LRY8L -tz1grK5UpTEPa1csE3w9z3X8BdyaRSyaqbNh -tz1Y5o5VWxAbDMtunSpaWaDwTUvK3YHdTLrq -tz1bMXGFgmDsA1oTBTMGyWWVBGRiFuzDYhJN -tz1TEwpiBNkXjNYRg2A7j5m9BydrM2DpZX82 -tz1YPhMZJW5PKDw1CuiSQup7kHcYayXZ25Fd -tz1WdoxyfBaFwB1NDosNmi4BiBT7Me7oSKsy -tz1Vr4HrbXiYD1WGMqoxb9JzEDy6vzFxgCkd -tz1ckAaVASCcp2F9hzYhBoc3RzQqyJmcf417 -tz1NkXfaoreZXAzXdwAdkDCZa1fACBr3QBJR -tz1fN2keggtFQMXYj4Bf1ZKiZ5iPTbzgk5tV -tz1RAeXM1SbUwDD1XqNdUPU1yW7NZkhMUQU2 -tz1gPL5u9VzuvpAU65ndQJRPqJKGyh9VyvYP -tz1WcoYjv5nChW4tgmrJwyf39RFvWvQvjcxN -tz1gCyb8t6b8iDwsNFxNAFdu4NDttnexjGQ7 -tz1h8zYgCRzw5U4VM8MHCB5TBjP6Za2fHeAe -tz1ifERHkXqeTwAHnW7MFCXGMzqwfmeB8UfP -tz1Rm4DL4JPKJpCtR6tVK3kdYiVyys76Rc2L -tz1b5xs2choeu8SVNEDvcdVvQSLh7mNC3Z97 -tz1KxG9SCz4hCdf9GaEty7sDw32PQr9G3dYC -tz1aFnWQ57AZRbSuBj9yc7w4mk7BzNut5C1Q -tz1UCzwDi396JwACk3FMP6E8W1Sh5m1eZqnn -tz1iJ1xCg9LsbW7r5SSXudmmP3h9xrCAz3Sp -tz1UMLBVEH32mgrVSQNmTHvvyzHNwwaWqsT6 -tz1MtsVBrjGPfNhnG7vnQdYJBxhfGPE4vWA9 -tz1aD5x5rhzsfyrxUy5endKCCoX3hKbheghp -tz1hx6wEENY9e6Dw7BiLE24x2Hs7YXLsKwWs -tz1cZEXPJnkC4AoRbAkT2sW3G4nuih4Er4MN -tz1WfQmR4aNeNTmDrmRJjiS1uCQqnJkZkk31 -tz1gTNLuCim7rJnEHqZJoujTwEtTm3hon5bm -tz1Lrn1ej5jXpMmhWTUcTz7CRsvcmi6MiigZ -tz1cfF1orvK4i8bppNm7Bz5K8ZvzEhAkbLEh -tz1Zmy1x7o91QBzCd6zvPx9Yq6uLW6w1oBXA -tz1is7Ucdxn2KogJpjg2h4apkfW4Gt3mviot -tz1aLyEAJkupHE8RZjQEx9mYc2hhrMw5SnSF -tz1UGDD2hUuqxWmM1tPPpfFMnVqPSZRSkG7H -tz1fUrJq15MxiZbtDTPtB2AcCwBuXQ5B1yjF -tz1Q7Gj3j7QFLYDmXoCjf7XVJX5mEzb2QmMv -tz1VwEHRvHiTfSkJcvZX3LcNo17Szk4w4KWK -tz1f18FayrWkxjtx79fJGLBU2N5UdZcSby7s -tz1hAu9FnYTmat6XmWpGgXCuizFXkwZEFUT6 -tz1gWC2VnwDWmjgnBksVLM7Eq1GYfrgVniny -tz1Yd8LDwzu6vn1d99FnnewNUF1mY4iRSx54 -tz1bZPjkVfbQwEJaT1KmbNtRwVRcN46Ve1ed -tz1ehwDTVPbwxjnsR6kdui55UVWBfXrjHWQP -tz1P4cG62bSZqsJRjGTVPq7WtjG9y7y3xLMq -tz1YTE9WLh598sMNmGdhriSz2NqJqSNo7sJC -tz1Nz9tmmqvBod42UUSar5yqLoWfcofyTKxM -tz1fpzGM74h7koag1SJGKS8oufuttYDvSCJs -tz1gyDw2zhHg5VMUocDYnWa27KRRrCQbT8kn -tz1Ysqnr6hVyTAQD4z7VfrmrXmvWgo5qo7yH -tz1XXUfGEsveSzBZCfT8bUCvs6kxvRw5vhLY -tz1bJnic8fHe7ZhFHWZ3degx3d4yJA13bafK -tz1Znnm36Aa6HfgMaKRkpst4VAFxwmbdRVpt -tz1aFGdKChT5Zougv1VJTKkHaaKjj9hD8BCc -tz1VAw2g8T1NvConTQzt2hPvKVQkJxPhLmqM -tz1V2s3wJMjKQBXk4WMGfkKVJr6wQcLCLhv7 -tz1UV999gLRhsrz8itahhagrUD8t562FRamT -tz1QZuqQxnojok3Qmb1M4G7LTAN4Z5V1pkQn -tz1MC3c8TSbpa3AesM76u3L211pTon5aVQ6r -tz1bL4miXT3J8AFNVULcAxdTsdKRgbZFEbgV -tz1P5mEpNZ3duenusQh6x1V2ndvKNxLL8692 -tz1Zpi64KELYhJyGL27V1uqLfcoMxNCtS2VN -tz1cWPM7vGyE3mVoqzPHJyvQvvUbZrQcno1A -tz1g3fedPJDo72hfeoZprw1NjAuxsbRV79RF -tz1UukW2uthxNxYBoXyxNfM6LYeoxNi8RQwM -tz1MHm2HwCVpJUQe579Uxy9faGosdShmHRCM -tz1XKJjYQt7z18yanuVot4Epew19SCPgqcbU -tz1SCWHtzXCA3veGFuq4k1qJ5UmD5NDtpT28 -tz1WB3EafpbaAFZz9A6Sc3xGndVmM9Kxs6jp -tz1T2ZZMN5WaCeqTFvfsPxdMznvugVXzo7ug -tz1afWYfiadzqoGcGGz4hE3dHPmFfercQWj6 -tz1cs4rB2Fx5S3ACVUhwKCTfJuecL2CuMvB4 -tz1TsTmn9EhgitaiPH3TXezL4BPtWSiTFWzz -tz1P3erjQfe65urZFurtfyqmJDRo7vPazC87 -tz1a9pbJa9saDwnBTUrZhcdBTuKK7sWmm7z9 -tz1WRdWp969ctnaHUwUvfkrKFUtJAaAvwj17 -tz1V2hu138sQJ4jTV4tQPrHyYbWv5cDKvVNc -tz1hKkd3ooa11LT441KufsoN4Qg1vNSTXjdn -tz1YJH1bQBYWkhHWtbdwpc1qJLyagDeNL6cV -tz1fQqvpD4Dca16zyfTFyqjYMRPEv3DiEWLX -tz1bL5quBz8oFCndf8fZXywLhVfYYR2rLmRR -tz1Pp4VcoXa8MoSsDy7P8VpkMkq3co69GDZc -tz1UpLHLpYWvuR3YaiCFKhPWHZA14GVPtYV4 -tz1MKoXuXXkXcKDtbSBgpwk91nKaqzsKWdBH -tz1iM992snsBkHkTeEZBzAKujofp4t1uKF8G -tz1T8BQzn8B65Pm5XKjVwKTBZgk37w6EPjGG -tz1Sn5NabPMsEyK98knWi6vkwnS4XAyK612q -tz1h3EsQjG6HiR3jToLYiZPTcYcJ1DZ235Ed -tz1RcRLBnPmaXrjYEGCGeb7za9UtGthSkPb6 -tz1bfz2LH5szD1u7e9C9CmTi3MUEgp6REBZw -tz1T7mkizRy72RViY1tEme6z6JrP4xZTXQaM -tz1e79YRYSF4RQXZAJh4HygvBnyQCBX6E6rP -tz1VQHR9gNpxsEywkMFVchXxCJQvepVbXhq4 -tz1bzjeMzygYRa2TsqD1U3P1TX42CUUWrHmp -tz1TH5oVLzfvyhGJh7DUhoHTkVAL7cWpvTA3 -tz1fEiH21ADuZtguQb37Zr2KxXVFPahgiucv -tz1SvbTbzJReQKZ3Dr53aGJ63wkAwSbfbw6x -tz1MbZ4efgUeDz2HgX5ZKCQy15hfAL5xVZTw -tz1bEhHcuGdurrJFFepKEBhU5RwdcbUfDq9E -tz1ff32sR9Cg38FC178CdPex1WsoUuysSntC -tz1gdDDRHVbrT3M8eQefFrEgCiwXuwWhWW6B -tz1ZFniA5ExAdvcNWcdVgWibc7bCRjghdKXH -tz1PuJZXoqfLcM1zDDBoUh4BaCDPTtiwNKqx -tz1ZUJCrVp33FW6ZrqAhL95kfS5CBm82CnSb -tz1PXfrd55GAjQMkWhzwDLdWL5L2KqJttoZe -tz1cM5sPqAz5fLm4dzt1M925KpzuexfZeE9L -tz1dcxedXNu2u44rfAWKCTs55rsSjNtUDJsA -tz1ZCLF9NfxZd41ikEMUBZrxkZkFk5dpbqbu -tz1VDhvBVAvaCPBzAVe6T1muCGGpGw8Zznga -tz1ddx3Attd5qXe916iRCet1PeN5vh8hXY7v -tz1gmPPFcsdSJ8iEWHv6JNQXuMHKXuuJYB9Y -tz1dpUDC4NjkZYCSQi9iUS8rA7UgHZcXD4ob -tz1ateBSjsdubPYnUuy43CBfhiqdPXk16jkK -tz1MULV5DR1qbxzh3B5UfMUD6kvsb7JexXmu -tz1cFmKDuPyEsEwL8ZwhBcQwyxwgtHUrS8hU -tz1RPgF6RvQsmanBpxh66wJFcrVfzKmcjzDt -tz1cnSLDHd56MJq4vCzNbYxmWqyvgYs6Pi5F -tz1bt14rENoC3QXzpwaNVpmJsEeU2dp2nwDF -tz1UFHhZdp991Etu921txmYze76UHfsWKNrF -tz1LtASpu3v24LPeeqev1XXYFrRK43R6qXbo -tz1hrW6JosmeBJbdXMyfVFnXGPW3neiCHDnN -tz1SsstVAcLghJcCobVwot5TnhRpy2jT3axp -tz1aGBcNcFn42JjSiBtfikLz7i7auYbovhHG -tz1Qm1oXUg7d8sqdKNjSFmUszf6icpcZnHyc -tz1iy5fqohF3SShU8SqUj5RM5R2C3yDVkYmk -tz1cwyS9gPCygiyMAjvpAPxw6mkvEJKH3sPK -tz1XPnT5RpvzQoQxMRYrBHg8kabeEDwz2Uq1 -tz1MqWAqmizz8PY2dXbZXvppWXrg2zV8dLbr -tz1L9L67PpVuKkZqbuj9bAZNEBSp6FtQ8Y6p -tz1ZqKjvWneZ37s1hS3vkftzaGDaA1z6xYNF -tz1dp6y5quF6GgyaJXdXrJrsJXXYVHu72CJy -tz1dYEgMQi1x9P6pNDWFR72ZH9c1PacEpYfx -tz1Lg8BPrLKsKdx42HVvWaP9eMsjDdhwUB9f -tz1ajg4Uu6GKQrzTA3PK2YLhiy3ETbVttAKN -tz1a7cEnwDZHXZL2EVXw3ee8ZKegKLQRBcTL -tz1Ym3jS9j95C2FKZM6eu2WRg4ajCQaHr7aB -tz1VsiwNd3FAFkUjw4D4cAA49r6cv4qEWBdn -tz1WjEu3eCxqUnSov1vX8yM41zS3us3GucTX -tz1WFyLKkr5Uuw6YhXTovjmTNJXzNprf8cJ6 -tz1XJ6ogsw3jBjvMqDf9WmScbY8MtTH245XQ -tz1ipBfwmdooZMsdbXG21dBSKtkhjK5qeYzZ -tz1LKumkuFbg4sU9XyBo1zsTJ6x6NLHrbbVz -tz1g4zgSe8AG8rqU8P3Jn5fBQpmraND5HRNP -tz1VKhzqNXyZ4YmRh83tC2Y7FGje8NUBRJJk -tz1bGSiUs3cytHmkbtjvqmHAQbPsMVnwvKZh -tz1fGUbGiFWSvyJTA61Pt7CuYBSNso2UvWxQ -tz1YAVsexqQgZSXFvUGAfZ8sPcc5qCYMSFWd -tz1KoncNRnjT6D5PGLJYMWHH8kkEM2vo54b3 -tz1hrX63TgSuRzrt31U4JUgaNW92j8uJY8zF -tz1W7vHEQUqApgshRgJCWZJFCY4NTw133nHz -tz1hq5LFujxaKJoB3jsYS3DhRerhNH5QcDHD -tz1hBAi4ZmbFRtQ9tAuq3frqZUp8BGdXd87H -tz1PouqYn2Sr3jZ4Nxs2Amth5UrrPT5AEcwL -tz1UpcfEF6ou84bRNrUSHeNmsbSNXwqEMTB9 -tz1RAYpRoAseQpoUs6o9mpcr6fU76pjm3sm4 -tz1Rcc9KA7LX5yCBCbaJzRqqtwfwEqUu4qVm -tz1XM8Ux1PVPzoqGDXspiozSSqByWu5fjCT6 -tz1LoN3pn8nDdVLbuDzA86rr9G9gkJ8C91sg -tz1TihoJ35JELGENGiVy65QFx7DKQDnbhFk3 -tz1dBir5KwnESLkkP2V1rmiq5j9AbzUTL8kr -tz1QTYAgQ7chFsq8phDeHfou9eNMp1xgW3xi -tz1UAcCxcBwUsR2cYBmSWQtMDEdxEye18Xsz -tz1L7U8JZWJNwip8TgU1FYKnXgEjSW11QNiT -tz1dyYpETk41k2PLoqQRrxcaYCEZnKkTerZh -tz1euVsRMMYou1EtT5HZxPcNbgThGhvzK5mk -tz1MdVq2DY3ydGT3GZLTxc16MSsVo9DRaJzk -tz1edNbJG5imCad1MT7bKCrMg4HXrkkXpbZS -tz1NuFexr8UqCMdhU7E9NeyALfsWP3JvADu8 -tz1TG9DdHQYsnMNzEhVpZqHwz7j1e2TDDeeP -tz1U2BnKAJCSK3RmRu1tWzJiifRzkjzEc6H4 -tz1RHatFaGUZ5GYVcUq2UeKzrLMepzZVG67S -tz1g4hrXMd4R3mtVKWuioEeuxAn6T1GsEEqY -tz1Xp4YBXHnxq3csLHXP2RVouyUdV1NdKUtQ -tz1coXxSS9XWLv8JTspsj7VAbzDiLWfPgbdx -tz1XLFPH1Kw3aNasxng3VkF9qDHgpRXBSF4B -tz1chZ9ufck5MFaKd1wXvcdFPjGs3g5s9hBB -tz1dL5kmy5uGKV2aoJwqxWavdZQAHHBqbPiT -tz1Z4VwNdV2LCySdkSAjbc6rj7d6KSiwvECe -tz1UJH6NoYtK8kXnR8GCGEZCmiyF4R6kGUWJ -tz1UaLoXbiBCUh8nGXyk1EL7wXYNFGKTUDS8 -tz1UsBabkLPxRTCLfSY2FoYP29KF2xDRYfCM -tz1gjBbb3kQPAVZL9ouJR1WLNxSNte5VDTP8 -tz1h9WAhmw6ddEpjPsuH6NbSNGMG8sQZnYU9 -tz1PyTd9cWQk4ihaTPgzq3jw6LC77yrSke92 -tz1eAAJLAZJpTCe6C8GjwptAWcCptNf4XdJm -tz1LhPwdKguxeLnDdzameRzrHwg7hLCtpdd1 -tz1PY8K79G4R89MY1ff94UPq3YD9kTyvZJsw -tz1i4zVwFxaArAqUjWn6QPfLsRyZsUV9XQhC -tz1fYUmbc3hrXLADt7A5YXoHJArHdo1MBRcd -tz1etfFvAH3snW8PVx7vBYEjVgLCTZ4PqTYD -tz1bf4pJXQjTTfjc8SJtzGivaCubJ3JDpLdP -tz1LjKJxGZve7admbhJg7ARM58YTQwt4gU1h -tz1hGhfxdvmtTgJjKsD6ortcjpqKuszt1dfw -tz1RqrzLod1XBJwjvvULJL8A5yT19gsPJfJn -tz1azneFUPHXhmdf2N1HEreazAribrktCQJa -tz1ibHFuDSNFR8GZLvt9j8QoCq588Pnzbger -tz1VTCYum7nLTmT7jD9ePaqhQdm6R6yxTMDb -tz1SEJEeJro8ron87FkA4x5iGb2BkienUnS8 -tz1YVVB7XaM9UN8H5Qz9DmC1CNSh2Vsb84uG -tz1TV2ZbFLX67zJWntMFdEM1XU673w6rQqeT -tz1NyoTcYttVGzpxBhNcNWw7woAtdff1mA6y -tz1SiPHF7HVscvR9U8UidwZGtM2UP7a4w2je -tz1L4ZEYoBvt4Khr4ndHTR3Qv9hDEvdFRjbC -tz1YVLb9k2vdo7N7BhWGpqr4fAQ3NHnMqpeg -tz1gyKygT1rJSK5LM22MNxMWYsQF3A6vsDjS -tz1UesP6osk78a4sTSrfHFg8RVkHwEv6ARnu -tz1P8sZVo2QWZVVoVfyGXWgvWiTnFApVEd15 -tz1b3QqZRy7YjfnL3tv9C6KFTNeBZCNZHLhV -tz1XgagU1uXAj7qona4XDBbBPfzHBZX8Seuk -tz1cxBcUedU48BP5L9zhS4f7rRFcHZHTNzrm -tz1aib4xt8MXVY5thN4QQXQHP65bZ1JZ6vP3 -tz1X1i4JDKDyBPWWUkt6C84YBSfCP3fUX1Uu -tz1e3Nph13RFkmHad5F1vsf1qJAvSP5oBFVU -tz1T1SXEYU9KjyAieJoYougK97cnCSfmSmYG -tz1W343durh5ysai3tebSwxfwWzMwHrVQ1Sv -tz1bVJ1Xsn5Ntyp87XStMHZzZBdNkjs7mS2v -tz1TN51CLB7dwTsh9BQCssKvyp7gBw3X5WZc -tz1icshofaCpXSStUxuMPTWGYDFMJofKKXjw -tz1bTq3VARKVhGc58Ta2U12pjHCCtJwpe2rh -tz1fVTQ6fJz5dXKaBs9B7hcMEp7mBg33HKz5 -tz1ieNKuU4RaVZjvERjeRtTq7q2yKpUKTr64 -tz1VenEvTvjvgeErgZymMkGTodX5dAjkCo68 -tz1SqocBCuS7KtAdrmGCiR99tirFhdpBy51n -tz1irdtBtDRR8UGiSnE5zNPgFGBsq21Muqs6 -tz1QQ2wg67vvmvMs8WjzZJYmcw4Nv2s2WrXa -tz1WTuc1SyVBgUqbVhBAs1VGDZr9d5NMAVe5 -tz1gFEa7F3DRhnU9La4K1sBE7jHJ452gsYeu -tz1U1McE5JEVpkCr5ofmz6htwiGzCzYJn92C -tz1iWJNF5eYTcTVczDmcg6cvbByDHErBVQb2 -tz1iP4ZyMksx3xWdCed5MRGFhUEu2HUoQBAZ -tz1L1iswW2oMX1S8e4EdpBsAJ3D18kSSbSqU -tz1aifry7xEepQUP6yHDJQnF9NuPR8gUDEw3 -tz1hrTbXrK4LbdaNoVAQd4Xv66ZhacviDERd -tz1Qe5uKRLVQdFqFpREM8uyL6A2MiXp4dZR7 -tz1abqNYA1pkfgqRdV7SCHDLgVjppHiuZC3L -tz1TVV3nhfsfjnCKgrdi9QKWdPeerRobL3RE -tz1fgpbafWsFA6Zgt5y7BnnQMR4r2iF4cmtx -tz1RJ2w4jGa1nkFrV69bwHTx2citT51Xkq67 -tz1NSm1KBmGNQPX3LUtm4unvExyotnhZdG8Z -tz1S79LMqCKnV2y1yehupePFD7822DcKKnes -tz1NdQapDxkvApMjHepL6cSdNbaTtHEbNe76 -tz1MwxHWhKjjtmsrRQRYkVwsUfhmSjzePTvg -tz1N4hH9itLMzmHAaUZy9jAxqTuAdudtzMHJ -tz1QQ8QWss837NBTPv35rfzupRexHX9m32tC -tz1QMkV2AqxXbPuZTz9PveYJc18cEtZrNTgp -tz1dgSweMa5kHQsQK7pHq6nVFFY39c1BGJEP -tz1TGMPFU4S888KaV28dSU9WW6cP9xin6aFh -tz1VD2qeG4s5uKUD9xyxSipnzhQ8LKhhRTwy -tz1hqgSs8BVvF3gwVeobY4Nbu1wLohHMt3h8 -tz1Tn5UfbHoVYQeuUFsXwmoj1eY2KhpWe7kf -tz1aSWwCvx73YGkhvzkWg34huS3aj9xhRGyR -tz1cPQWpM5QGTAvToB8VV1jzduJn3PXFPwSn -tz1SBZNj3H6Lkq6P2z8EPPT2zbB4nzYYX87o -tz1Mzz1ThZrqBJ8vL9kWe2Xx5fmhPiv3Uva8 -tz1a38AqxADTWTzDsYiUQsS1iGkzByxuX2KN -tz1hGzpsPDC77zhPsW2eVJQqoCVdVcVRnxSB -tz1SQEJs1C8PXhnH7BnsoVgskzeUY3Wc5LGR -tz1RyAwHZKe7ymCrUMfiUdVQ7C6ZWyZAGAKK -tz1bzzRMi9DG2gdeGwFYUJ7hWMZYaprXRny8 -tz1YvQuiStxGFxA4Fm3aKZMpUudDmapttsNE -tz1XUvicFwnbZ27e16UwgTinBhoWqgnLVmu6 -tz1gQEmZjuJbeGfBqX2zzfXM4uEFZYdsCKaC -tz1Qt1cqHNdzmtAa2Tgs59Jovh4VNrotRYnG -tz1MgaTviDoN7RzUPQeYUZioV1aqxKetBxeh -tz1LegdspphXA5j9Aeuh3uv2mY4CGv5jMCQe -tz1is6jVJg7AdqgbADbfucKayaQpK9rEgMsh -tz1QSeiSGbsTciE6eEhWhU41tPu4b3XWKDq5 -tz1hY8D9ker6JsrgnuAxyDEZvEXaEXPH5KdJ -tz1XXwHtDysfYEjFCr52JQXzptBjWx8P4xAk -tz1hVDqsVdiLDX2BtGU5DU3xdGwjgeD2Qhc9 -tz1KgVGGDY4xBfbg6EfhY7YBHABrgFWwtc1M -tz1Nj2us9wTXnxgJBHrjdd11vBGbaVaw9iCf -tz1esKMpTk2sufvKSqfDCbLP3xEzxNnvSgb3 -tz1Yb92uQR9rqYcvvgz5iHh1B7QCLFt16jjd -tz1gFVVJ88QNDKAfDHrqdq8v5jr98yQ7T9cn -tz1VfeUMvnR6RcALTWGLcmGpDeEZpGMLedZk -tz1exgCpTnobboasqVErSTSc7zc8ZzBNTHqB -tz1VQejZRww3KX7J6Zq2Lc3Ttgh9Fch6ML1t -tz1QkvMwnDnvYKUSt2qg1xVeYxoxannEQkwm -tz1iP7UbD9MKh9qRL7zvQViG4JPjD6QKpKvc -tz1PM5kCjuZBsnZfTTkDdXmBEcbBP6bob1yD -tz1bBo7WtvabDi5DjdeZMQREfeGPbC47gLfC -tz1cM1dcXuEi276vhehQ2Yk8MGD6pCUiwRmn -tz1Q76io3yucSdMaJHjVizuvzLC23V3SLsMB -tz1aLGQpEqgsjS1WTwApwhrfuQouUA5meGYU -tz1RSRhL1F9hkhM8wyxDKTMdR42vdSA3KijC -tz1bucWNGoYkJXryRqanC6LyKFLqwzBjtqnK -tz1coi8TFwEPyQa49tdSHynUJCFP9ZV2b5Vr -tz1W9wxFNjpfSeiAN3XaYGozWGFyvDmjdpaC -tz1WrsZTp6K8UbWEddUBNwgzoKKxJpUBCJgx -tz1aR4UuUCHx6qDTPoCK272bwdLVQKdHCjov -tz1PZ2vR6gmcEwTbFGNAWwcLx5LnqrRC3p8Y -tz1i76EmCz2r9NXfxFz7VXqzcbRfUScUkWjU -tz1dazyKEQ6n2nD7YT2KEU8SDsVNWqjA4hTg -tz1SQsktppsUuuELEU16BNEC1RRg2sCa1zcm -tz1RcF82G4dDw4HgeSjBZZRhKEGHwMEGRn72 -tz1e8X7bUyGp4JXNZVLhYGJ2zRdzW1XTBV8f -tz1Swft6D2xsoSGgyjCtwohtGP23E5twDEpj -tz1bWGvisuR7QFYtc3voXUvGXaJShCyauwZV -tz1PQxt55bCYV1H7H1L3b8MN5NothAfjca9Y -tz1iTANQ7BMbDhAiHTBPr8qt8GTzTMczas6c -tz1fhmK7nGxnLexAmtR4vubALsgKmBBwKdH4 -tz1frDW2TiZ8rSQEmVCPXQg1RuSdhJrHeDMq -tz1fqewrKRZwmDdHyxFJEhefcd7secr4j4g6 -tz1RLAoW3kgqKzvfbS2P2vphZMyMPcZmg5aE -tz1iVZCFQcWQxA3s8Ga19uC54HhwYbiytoAt -tz1VuPzZwJu7MRbNAHntGtLasV14BUxuyuJj -tz1Vrj4PJjyyLWLUMX4wzu8rUjPAY7grYfwF -tz1RN4myAGAzTooUHyL9n1mYSqwo2Sq736xA -tz1fwcfmKKBpMo3YqLMicCjLrm7Fnv9mkEEW -tz1Vk8dSp2UJUaUNcZ9iVNzv5q8M8RZosaVZ -tz1NkFJ2kn78fWDZDqB7RnyeT4mdUbz1dgmC -tz1iXu2xF7h11xhLmEjZqK8dNMRhyRgF9cq3 -tz1bvxzqjfeJSN43VF8uWTZ4yE3xBrWDyjaQ -tz1cZtSaoJ4y8RMXixBmAnPyvTVq6N7fsS6d -tz1Lvk4p1xzpf76MDW81FLChuszXvauQ98At -tz1ftGPp5LLfd1pU1nWkhsjxHvPDy1v3tFCL -tz1LNmj9AyZJBo1aSWEEgMYpoLAmKFye1JjZ -tz1bncJzoJmpG8CyGkjTkzsMLXjvaxiqUmHq -tz1PYPo1CTL6f3iAfFCM5hwCpNvVJgTjWoW2 -tz1TvV9sWeY4pvoqRhXFM9nba8fvDxZojUfH -tz1btyhSgrWFJCCMqNCPXXp1dG7kSGjAjKUY -tz1XhEdMYwrMCCJuCE56njmdFWtP3Ay9PbHh -tz1bcHNtY8PoLYCcViRdBUC8wffSPH4r2u5G -tz1fcTjDG2nBwxmsQ3kz8dLLWHSXCrvErkPD -tz1XUTfGiDQ4ehpVwD8kYVM6zxwqaEhfPV2M -tz1fsXkHcnup5gLKfgTyrvpL3JgW9JonGcEJ -tz1a5tg74JeD5sx5wqyvqP2esMknvH48kFwZ -tz1ZvUFCcQy179NyYTqv1R4sxtGPntqdXvjo -tz1WXi5Lg9sqTgUEgbDsyupqhZiY1Li9jUhk -tz1XjA2nrDGALjzs7Y6H6UuQg4f3azgGwtyV -tz1cXPPRb1mvyC2HkeCHyFEqNUEerQJoSHU8 -tz1N294WqvbvVnptbeLGExo3SJfzKtbuk2pq -tz1UQxcZrQ1xVDUnnpwTeTQsArTy9wH39kRL -tz1X2eTuDCnXL1fwJLx48uG4769Mi4yVU8Mv -tz1ac8R3d5DoadDujCK5vTCBL6oENmbk8WiA -tz1a7Vbmi1pyXeFqNrbJJPD12DUHwWA7WikS -tz1iMYBK6b7CH6kVeg7LcNUAXYAEksvejtnX -tz1R7fwe1oiPeafUvRJpWGMy1AqXaiWbUYcD -tz1RGKL3KfXbMbNZVondJVFU3NQTj9d9teqC -tz1g2XBjPHj7nkR6BqSxZpJKNitwkd1bEApq -tz1MAzChZYrvv3beAbArBr4RGsLwVKufKdb4 -tz1YNsngXSiBGCEHTsn3yZ3cU4BoNsuqQxCY -tz1iELgNBFdDf27JgJeJervaexJPTdBuFafy -tz1LF6UML71FNSKShvvNd4B5ZhimqCme8wgE -tz1MQsYoRWi75DpCExKAoh1NsVtaEMJT7tbs -tz1X7fCRengwqAhcJNXJsHhXm7p93rZNvUpu -tz1cxmJcgy9WJkfUUHkGFfUxp45ePjzZ2dtJ -tz1KhQCFFwHmzSQ3RiSAJaY9oRhFoeP2oCuf -tz1iTu4A8rKQKWKmg5VQnJvjpahtAZyUWEzz -tz1WhB6u4CTmVNd7GLpqVck87nvmC2hNqwb3 -tz1dsi95L2RME3uccmRrBZYxCqMFP8oZC4FH -tz1Y1gV2GEtbytVhPBs7GXJJhwo5YGbQzsfY -tz1bZ7mpjJH2Fmk6id9DKzKMHS92BBr3RDoZ -tz1bEWotGVse7gbXM5QuKQxjP6Yu9kdfJu2B -tz1YFiMrL3phq6Q6L2EDQQM5kaB7AtqXnbCW -tz1MhgJfbNXKEU8SWn9LoxF782xZCNB4QsnB -tz1Xugmz4GtpRGE9nhNzwoptJx9w4BGaUQYP -tz1XFAXrn1tG6dt6bKrPQRLpy5grRLfVXjij -tz1M1RVVmm8tG369Zn3m9kxe8R3zMMLW2c7m -tz1Rp1XsUoKQmfyWNEhWMqcfXku1vAmJhsTK -tz1ZTMmp9mJ5FgaEUwkgVZPqSgDX8eNvvudk -tz1fYQYmdK4ri86XYEjNMYKTNx4Uv5WfPvnX -tz1Si9jrqxowP44sQsoLSrH9ctiDhaAbZyD5 -tz1fCPCQ8Wzz5Cr4r1gfVT7v3bkRWUQcniuR -tz1RzaGLXDSHnsoYvVKU1ACHTRJXAjXinSMi -tz1eZLHyamfN96pjrKXj1CcdxBsVKfsX317B -tz1L81XDXrhmzWwBNqHqLZ6K4nk3mUjX7bxg -tz1cmMgjUG8mYFXjnqmBFpmAKsrzVBGgFGmh -tz1gdifKNhmB67S8U6NwgbvnbHk9XWVSzXn7 -tz1YvoqGqyneSaacBKPhUDQNgWhCUe7WrMPU -tz1gXmZ3p6Jkn3AH72SQyNUiW98kTTGhoayW -tz1gh3pfihyw4VE1TYai6XXCZNpJr7FRKj87 -tz1bQghTQ1qkNd4wRocNyxQ3BfLTApWMF98r -tz1gtdT4i3CFgD6aNbqFdDYTMU8dEXzCT4wM -tz1Qw6n8gdkNFD4XJ4YMfZE3RzmfBvvAsm9p -tz1RDzXLm6dqq35vQxbY8m7kBJrtzvibSqN6 -tz1M2gK5erhpxUNrkvnUWBSoT6r1SruQGgZa -tz1ZGgHzimBsEmVxXKVjpU6NGsC1iLTtdteq -tz1SuMwmSQHwPruksBQ3tiJ91Y2JKk1EkfqX -tz1ZqEgYun1iPL1ww9gDPMGN74ZMaiLUeqdf -tz1cZe7T2Wu6VmrA9JYnJvTaAXg5tgwzdoZD -tz1MABN8bcMj6nGuResmXBUijFCEPrVF25HN -tz1YQogPovK72xqCZwDDecCWKm9Jgh2CYibf -tz1aShmoPmXxdJpcnbBmyjbgm277ThYcibYg -tz1eYw5RatsFaw5Hzxe1d3QUiXbQhgYHimty -tz1ax9sm2vBYvDVgBmsNKbd7DZeLVwxBDGm7 -tz1aNuALhrfnz4QxGaEtdaCWbqbrP8nFo9d5 -tz1eLxY2Km1XPDpb1KfgP42Qaf1iaqSC8fbb -tz1eNejSGG96Zy5UezRbpkLa6FWJVa1PiBe4 -tz1cbtkCXm242FcRiAiioRpxtfd1598f5MWK -tz1L8m2QNNyPvrN51tAwDX1ToRsQhunnMM8N -tz1bQ1h85YRkAo6y7TsTGwk35Z3pvedVrup5 -tz1bYEJFytgEePZXbuDC4jsMwKMs51FrmzMs -tz1UKAUAE9CXAvYLyzUWFeRxgjJ6DpHLdtHj -tz1XcxDxuGPQqRuGii2XBxXf9VnkZJJrubAQ -tz1gkdcs2ERbZRgA5yGYUygX5h7QUvr6fDrn -tz1gG4fL3BBwubgcd23mxc1Uv5MN2UY83sEo -tz1N3ABRpSs9CTWnVnPEV5XFWa7CiaSio5ex -tz1VbfQAtPjgVm9rccrUTMnfVwX83uX6PdJY -tz1XzN9ayKLHYgapf39uNxbxF5ZA3AVJGFcA -tz1RjC37dXH48Z8UPPLTeth8VWBnoHwB5CDe -tz1WkWEHnAYT1DiEUkvgsJ9UmDMaiV4LAVWK -tz1hYPRxmsPWiwoueSvfDBvLzghvFtcVAQWj -tz1Yp6ZrUHwSEjVevXTbZv3GVXzY78qbGaFL -tz1Vcypbj1W4WrkeKeCE178GAB4q7rgFi2DQ -tz1NofSkTZcWuCQT6kbBi7EFtEV1rNagDKWD -tz1Yiig4uf1ikMADNgZQhwQGGBn9ieZdP4uy -tz1iwLXhzUVkkgm7bvo73zg5AFCVGvxdhWRj -tz1TpCsPSxCiouGEcG9tStpMKrFscBNqXaGn -tz1UxdSKMqU97SfVrcr1dkubYfxELowsWoJh -tz1W7ZMBSU49iZMe89D3DMDXCv8F1FScmgyo -tz1XSwAXT753CGwgwwinUAG2p7eJrJPUBhru -tz1TJAEyEqnPzAyTqFLD9riaFd4CqXJ8bk9z -tz1TpDnNtwd8gciYgEkKconLJoxPtf5GCpzi -tz1XDM4WRbdWo9GPAbpxWY8qhKbyphD6puTQ -tz1Uvz9yBABcjZMx9jdeMEGt6fWXMwpp35tt -tz1Q86tz2HeTL6iwHVcYe7nGUN4zSU545nWf -tz1NfVvrmuYnGa9kdhEtgmpk5BRCmkqtcPE2 -tz1axaQiqxuwinCtGDivKfsUnhBYHAYuQAcA -tz1QowxMwe799ihW3AaZphQEiGzNUHrSysjw -tz1epR34NjEHYWKUmAgFoXDq7BdbbCJsdxSb -tz1iUqPyHMtjZFya6NSDim7LsKxsVWuuWyUQ -tz1WbRYt5D9WGfQi1rYunD1ENE1gonrBhQ7k -tz1eXHfrjNHR5Mzh64z2boLmySCUvieSWnPw -tz1b2NbbiJfiKo2bFtB4kScP1zjkZYuHShYA -tz1ecd69TB8zNjc2wQH2TnXFvqcK4AWmovcy -tz1QEynBdidYpJwHCXL4AbvszrH6zJQvh7gT -tz1iAUfpuhLPPAZMzxdzZyLG5M1Wa3Nh2BP3 -tz1T9MoKdgv3jf9PiLUyt1ZoGuYwbbDiVpLx -tz1WYuHaZqA28eRULbktHUdNybU9L9tcwce4 -tz1ctrwN25JFbPJpUiUVKfPrNE4Be4PomMCz -tz1UPCGdVaSWnRY5Z1vtZLs78zxcn9MVawzq -tz1dVaYCMWj3pSP8hS8KK3ZiGuh3L1TEsVkJ -tz1ULfZ3UDYjrHyPtthPSRGfCDJiqQiXxfxi -tz1fKvu5FhFns9Xt7cxLaBNEDkSJBnZ7rQDL -tz1Q6qmxC3SaQFhJE8MtAFKnErUzUMu5NThQ -tz1Nt6ojj121LEoAhzXwop4LFWoGod2FENVW -tz1fQ1mCQMSE5kgGramPZTzmULmcQir8NSMn -tz1SJFvUXfgAhzx4Qaw8gW9JuKVp9hgi4wgr -tz1TVebZi3rDKx8NQNPNYwFfYhDaB2hckmY4 -tz1Xd3iC6ErjAdzm7Cvms1h6BjxYgq5AdeWq -tz1crcM8nTWjuXqjRAW8NZpb3LqVN6v48z15 -tz1Q6TTd6Z6Eu2EP4EL2hSVJuNC89535KC6V -tz1ad23yyTJCELk3j7J2DueKt4curKGAvbn8 -tz1YsNCF98gv8XkA4DQNJz99v1C1LYqPjk4t -tz1bHiTuAKD5wV1Ckb8xhhJPddNGuUQtVNXS -tz1h6uEeYVVK5hHPEuvYyy958AZK5kqU6Q92 -tz1L3ckacjTsHsr92drCyBBdrydsZHxx6UXt -tz1b41y9DWvKBiY6ABTe65BNS2YCazVsiMHg -tz1ctSgvixQsouFw7Eq4fRVMo4ENmn17ed4C -tz1SgXYyhiTv5GzqU5Z5YLTr9GMjRTS2Ltyn -tz1NQRwxnooWPj4cWt4Ye6UD1VuKvZJjK8wC -tz1YFN96UxJdtSeguUtfC74FDjoYVYFCgAKa -tz1geC2X2v5ufBXH2RFSgD4SX8S5hg9Xiqm8 -tz1WPZtfxAoo6p97ZRvTghgHV4hd3L9743g9 -tz1PgLHNAdhBwrfDT5LDK5ZnkGNF68tR9y3o -tz1QMgZGXGnMuHp7Hdbp4M2c8xaYNwna1xFy -tz1YUCiDpdBQU8gFtMtuFpu6xf9XtcnQRBoc -tz1Sc98PysEj3GqqeqjtvAXiervs61BNywSj -tz1TTtqWGAXr1zr5AF9HX5vf6BdHT3pz2PLD -tz1g6MGx8sza3t788BL7hnYTNYCfKq4CHUKm -tz1a9YaRwYppybG6s3W9NvWBGNWvRtM9vCH1 -tz1QUwhkNGngsSFAMDxoBA8FaeFhg4TiRdxt -tz1hYR775ApVC9Ng5prq7hQVBgEtjChDem4W -tz1e5g7nRkfNdnqnubK95EdtfCVPZVaNPq3j -tz1hMvBBGM2PsCQbtvDaFBPZmoGAXFTKsVDn -tz1UE4DjvuBDL2BK1z1kh8b5iw1huhXZazDo -tz1SRmQvyLi6uMdMaJS7QyEQodz4GSLUC5Py -tz1YFm55fhsbVDvkUFsSyoFUm2zgpZH4MMwf -tz1VSS7QbUhZWy288pAod2CPCkUvJF3nkC4q -tz1e2VfYnfXejAah1fKciEfndj7UN13P6CHR -tz1esV8vwjTAGLFNbwEQ9Lm6eEEsWBQUonKa -tz1X39QQ528RxQZppxWk94bpwYocS5axCuCY -tz1W3vo9w128KcLmLgudko8PbHbgoxK1DKzT -tz1TWFWcmMcxBbb2nUH6xHjdh2U6siyvREqp -tz1cdWT1TZc3Sdrxdz52EgQrsjaKWQJRzUQr -tz1UPrV4ReNERDHZPZcizsvxyt5iAPTymghK -tz1dY7cxvPBhkoTP5k9g5XR8wNi7R9hY7fMP -tz1KgmaE6kfzSrvb5MGjKeWRw19hLpGAFcmn -tz1aicmq9EKw3u4fNhTqYDreUufYjfd5wH6j -tz1Wpbuyb1WCUW1utKDXEWaAsdMCcuX7jQnp -tz1YfGSCLrH4FTa9vmvmC1AX8cXdFnsiXKPP -tz1M6D3gCFXW8FsaNFeiHyQbKnGqLYuqrJMq -tz1ZErdncdT4onys5Yeg3xQrDA5Ti6CcduTR -tz1Q7Qo9gYff4AtxVGzk5FpoGeW6mBuHPCxJ -tz1PrjwDiAPkcn8fukd6k2Cimcyas8EhmJBd -tz1hC9haHxQya2du85CJiKgz22VPdfPfaDgw -tz1QMzqccS4eE7YsdthXxa6jwn5M53dutgN8 -tz1WUFfTrixqczbVyLYAShr7DNrzF4c2sCzH -tz1T3Bz9haegNxpf8iduuPeJCYRA2HBANwk4 -tz1UX3gHNx17KUzmFw6Bigg5Voes418hy6jf -tz1V6P8DJSDDbMofdxF1qTRT8j8Ny4KkJep2 -tz1SChfsABr83UEzDuEvWMkJ3nYKUHXD6hoe -tz1hbQFkMe5kJcvBD1FQWbQTQouUrCM6BKos -tz1MvMGYvN1BLX3Gi46A3zDDm7j4qnFztMnD -tz1TCaMS3VGzDr18fnHrSsuac3HGQi13Zvwg -tz1bkaH8jEKEXKnKMR9ykKrduEdGNpD9TbeE -tz1RYj8AgfRYgAFGM97EZPFuqwvDe9ML4k9r -tz1e4AEMhA2AyUeHdXoP13CDYUsaAGsSoqSp -tz1gi9yuoaHSdnb8sVyw6G6C3BTCydY7SjSm -tz1SShxrTTGLQ4Gtk45e4gwibZ7dYPPH9TBv -tz1XG74TeSioynSqPkuzSFMQ9wyLbhpx62UX -tz1akw2po4e7jUQgupE9drruXnNAKUJB3XiT -tz1QdLCRaZVZU9nxivbvEYX4jTpQTCPNFVQW -tz1Yg5TSkwPgJsjARU7YcHcHXhuVtWC3NCMJ -tz1f4kQU14KaV4fSPncPFC9bdzhy8yhkhQTU -tz1M5aSVyaKtkKvLs25tco8ovRGsebqcFzJo -tz1hmLgyVete5zefNYDhYruTPBNMhUFTZ8RW -tz1fsWG1hiPQsGcCw2stH9KbuMwNTnsA16GJ -tz1fjjN1McC8ptq2cQGFBMkqcMcVhxJqyYYe -tz1gS7bvpt3RdxRKX3K9pVCDAULusAb3NoQw -tz1SWJXwck9PqTHVYvoA55sfxKAwEBVKhL1A -tz1PtBDWdJhqaYqM6iyJBGGKEJk9z26dRZsT -tz1gTDxprnwFXJUKC6bQKrdQxyDVdGSQmM2X -tz1R2C7NdBFvfZ7QpjsSykGtnAFtrcDob7LW -tz1RnkVCS1gaEafPXxWuSUfKXNB8pEfuJiiN -tz1R7UMXWi1ZBqPsLWxnjSEKSfBRi6pGxFkF -tz1hByM1emi2RgddrUWgN6nP9h3bdWMFfuGJ -tz1i68WKAhbWvrEjJzWUH5nHUiKq7DKsDTK7 -tz1Q2VWZKV5DgEH8hWaWT3RT5TYicHMTyxMX -tz1VRxvE8FfHj7NRYWaDo9AFBXgwVtBQb9g7 -tz1bhE78YyDKzB5mNhAo6zXwUQH6e2sMtEYy -tz1aZGdaANF64fHLVxK89xW1pGeGSzafH7j3 -tz1fRiswrEWvrWWZXTgSGnuYtfoahboRo3Ho -tz1gcKFknBG7rGH7uEKvhgcdLAZ5pgivDYYw -tz1aQ3X4wG2yBeEymxa8Q1yuFq6uz8N2Kq8E -tz1NCT7LwjVXQCkCu4VjMVdHcSGFj6UhJtrt -tz1QHoojbL7ZwWN359Ji5WhvmPKtkku9fd2z -tz1Yugx9j7QeZhWXPkhmH8dRtdoTNfPRYrW1 -tz1QowxW5tsmUUqLD7knVj2cghCeBxbph55f -tz1VzGRiHnvc9y6HRhrkKAbMxishKWpMphAy -tz1VYg61U3xCPRDt6nkk7ccpLpumEzSWigXC -tz1LiBPqq28rc1GBUHeC3gwZ2CZC7kiywQbm -tz1ch3Ch7iTSr6VaZmaSAyfmMBTnF7qP25sx -tz1Xm1dCmuCQGgUq6igsegs1T4uWWu3hfcn1 -tz1PaLveTfUar1XeX1gZHxEb5FLvn9WhMYPP -tz1QKmvMAfE1VWF3xSaPoMgoQF54S59FAGR5 -tz1RGJECiYuVx37jxvwmBuWQfZdxAPpsxpTp -tz1PBVs2DDmPyNP7VkeAT5F4zrreZW7fjBB7 -tz1ckLPaz5zvapD1hQLFNrC1EzBnwqjmMv7W -tz1Tc6fV9SdVT9oX1Ddb1DVSkXguTFiR1r6r -tz1aAzaiLX2ZWDAtbMDhU4BDr3Bta9VHVzEH -tz1N8QQLotV2z6BQTSWAG1agicC43p7i3kVm -tz1ginsMTJnsVxdQ7dxq7yZUWF1cfLwGhX7j -tz1iGwYBTcBpgc4E81RqP39W87s544DXmCjx -tz1cKBPY1yrezqAqg6GSQjSxmDVaYUkLUyof -tz1YwLxza8FFxrjzq1SzhEd8Sj6L5V3oK4Vo -tz1NPs9zhw259EZqSCFgcjUF7kdQKsUfaGHw -tz1Yb98bg1r5M12dcTLC1KXvhY25eb3E4XB8 -tz1RJkepDPJ7vzEriMMMCdWnkK8hjA5jtSt1 -tz1af94SbVRUh5DEE1fjozqUEeTgSzHDCYmD -tz1btSqGr7fKPYztpdsDNKsNdTkrw1JMSbdn -tz1M51m3BDYasnbDuWGtBkQ8Nv5Q4jFdqm5V -tz1XbikyKeRSktsEMTPa1URL69QTHgSsT16G -tz1coyqewqvBUekb2iPRF93DEpmhGf8HTBHo -tz1cTi5b19vLCt6EYjMEDHy77u51ogbcLZCf -tz1WEtyAEM5RYfBsJjbVG9c1feaMj7MEWEhx -tz1e8niGpnq94ub4dtHRish5EjHDm4YN469U -tz1VT9zSXQ8cTwdCaQ4ob6vENYbFMrwdgKFK -tz1ZtdMWhLUwd2SL6yBwLNVs9Rz2CdHDqRun -tz1cuAxsZofZQYsCpXxXCC15BzE6q9AHMLez -tz1eMnCXo2aqUemMak71qRpGBKr5BBtQAJuQ -tz1c4mM79BiefGeqP9bWaCVPQw6C1ZBhWECK -tz1hPB1JyZ9GPyxHRMa5xmmCQjvM3nJtn3G4 -tz1fNmLmpNhY2pgzmrBR7m9EJUT2KsF5F2ST -tz1io62ZX2ozLFEkjkyPKcGLM2pQXT8J4Hag -tz1Vu4vFM4J94gUJv6jyNpvw4FPzzYpqX3Z9 -tz1Xn8HiQULrx7ScmY8xri9JAW4K41fJGqyQ -tz1Wwv8j9wguGDNpidfx1KTUA7VhSjXrnMSz -tz1epFgJTgHC7ixu9bVQfRo89DbwZNJk4JwF -tz1YYs4tENxGxk7VZ6HZYmEeQpnF7kaqjEZm -tz1gqJsnSFBiQrmUpmTdithhBmhigK5cgaoG -tz1Rp2pUjUR166nPMRN1z58ZdsRyABoNtZWo -tz1L4ojvsBVL2kRobJjTi9hkSpmPGpyVFD2A -tz1a4PiXT9pTdREFSBzwnqG5fhfyYb3RjxKy -tz1NE93kzrcdNfKjeEFkgp4g5taWBZ6LG5CB -tz1fboxwg3cCniNsr454Eu2zoeceEdba1Qmp -tz1NAihKKaRwfxQdW1qh3yrxEY839XcESunh -tz1UmnrR98jYCZdCdcDNWpb8Jga8QDFEgfxG -tz1hT1mFEsjBx4uuSvwE3ZZ2VjxBNxkWFsmG -tz1edUE6XL7RzEuQAxcK6NWLakN6VqwQCtto -tz1YRXAfMqVnEPcujrLm1o7Sqh8TZzbxXn12 -tz1WhQUAop5deYshq5kJ2DxtUsuaEkCdgG1D -tz1fbP7sgobLjJjNPvmMukFofBP64V7j2YHx -tz1PoqzgkpnhWuqofWtby8ahspkWtiGwzVE9 -tz1YUZygLC5aN4rxwrobNNRQxfLmmVTKHrcx -tz1VLAWyQGfYRaFB6zTRTSjuYHwNc1LWRjTa -tz1R5j5SqH8B6rx7tLZFxMho61byZyN8AvN4 -tz1LVYGU1gfNM9DozTzTE2fpULtSvAsmkwyB -tz1NPdqUR1gsmimSURomj2VRLZ5yzAn97rNY -tz1Vy39Moq2AUCV97hz2eZw5KQNKkewXN6b8 -tz1hsUzQrVjoJEcKcdQ1Qf6NHMcWYoraM7ga -tz1bfhPkhE4ufHq1urswLijXB2CJZCSLXF9Z -tz1aQdZK9N2aG6WfHaNXondjpdsSBWhaiFSx -tz1aNoXEYCQQ92MDm6Z9TNxpMyapeRyW4rdG -tz1NbVnpS8Wbp1p1S43E8U6hPTZTp5cGYmna -tz1cpgM3RvtJnaJ8tjvyXJfHQH8VFeT7oCRT -tz1i5se7nafHJUR7pmxzkK1U32cXB8NJAMaE -tz1Myn4NF8KHtDVe3HVNXtgDfARRUm4jofii -tz1hzgWbXxDkqLY48RZ5oVyi1XMb3aGsBn6p -tz1QSatFd7dbQKPiSerNyM1akWnUfSLP6yKu -tz1UueY9HnUUYGMgA44APa42y8kfbBMrkNqP -tz1P2Dwfz5yX72efYifqvJbN3Rb4BgZMRsGU -tz1eCVBYeRD8HRLv125Ry8AwRKZo5NCHc4hR -tz1Z4jhjBBfEBqJbQmBhDTfeQhDjjQWwWYwP -tz1PnqzW96Xsj8juMPcBJSVfxTTrBrQriE8v -tz1UrY1RSHCwaAXSsCcPvqzC3TQXaBN9Jnqs -tz1VVvavmQJjfxNJpV6KKQn4TWvvm9pkw1SQ -tz1gPPJqoRyJZ8LBAxqfxeegzMCALH6AcLT2 -tz1LQyFYNXPnXSBr6wMw6Ro4F2uwRQuvxi4i -tz1bsLyYGePc1iWs48SesxGPAULmX5nqz1n1 -tz1Wb4bK4K5UxsKL934skPSQ2CMeKKUxbtPH -tz1gLCYQq9V9NveeR2TJhTi1Voa6XCaiZhcX -tz1eaZ227JqGYV1tpj2aUw7RFwbUbdvMjf9x -tz1aEzGVczCoSWEuG1WcxZCK4u1R8Zuuk1hd -tz1X6AJSnHQSwv8s3ixN26Fk2KnMwCZqNtWY -tz1iM536m6TUk4ApSK9Nt4CV5Bi7GiDFMwok -tz1dnjvZojNWBRjUBj8xnYuo5WkPyXc712wW -tz1iew6eN3mbiZrpe38euij2LzHoboPYJNYH -tz1X7AEzjC7HZXrQX84TuHyUKNTGgRqCzXaS -tz1NZ9CKzxMCQ7aCiZN31J8rNsvC7rSP1rEM -tz1bCcagL3HQorSbh5pJwubvVhCP4aAGWiM6 -tz1gtM6MRZZXDP4BZQ3HUsicG2iY54cBvDuu -tz1LecEBcmGxZUohncwigfjAFgh8txbX4qnB -tz1fyc2XPvzViACKkbXLphyACLBTqdQujL4t -tz1iNk69qN2EXdT9Fx62h2j7zSfBqsHRviNv -tz1ejFrqSYoLnufLH4NgcCEEjURY4mRNYBR7 -tz1URf1RbvMKyZDKtZ3BZQoHpPPrrUhG37Kt -tz1hUpP9ENMYjBZxRFPWy8rcNVWPy1K7T433 -tz1bJ1bkN17JjPRhPd9NooeA4v1WxhaFCq9r -tz1PuXX1MzkkprFW29dHoVv894LyNbj8Vz46 -tz1UQHd1fugxJS1QwLRVsJV36Ev3p2d1wJyZ -tz1ceZxTpzsQEfDMJPjzK4hnggHibrF4oU4y -tz1KojUTCLJr98VjPiBjfPM8n9Y9E85kvpSH -tz1ZF8cNZCSr1Mb6ZKJKj9p5cQhGuR1c9R8G -tz1S4nzg4MHHkrLNY6wRruQWZvtV5ftjo7qc -tz1VDeLJ7ghNhwWTnK58foSmMzoDR8oqifrr -tz1aYZQWqLS1gb8LKmjpoSbzhCWCVC2amRc4 -tz1eS1b634paQ4ycUN8XMjuxUtN9tMQj7jAU -tz1XVCTAiDBuJVbEgcv6YKJBgZqwXuxUueAM -tz1RDRi3noChm6nHDQvFvz8P9AHGbUu8ifM2 -tz1apJgQd1HsabPdBve7geQrNgQpcn6da7rz -tz1P2Fh3HpZ1HkPFWXnD8Nv1pbjuq9eAGmtt -tz1LA9akYVPkzQwXasYQjonaugnPz6j1EYaj -tz1eAZYdtzHo2DYi1xunxtDHEAAN1SfhCPjg -tz1iCH8FLQTkwhUQDd3ogJfPBWipaKDV4qH4 -tz1ZpaaZHEBcWSoZuRxFxHR4LM6FiHGpqzhH -tz1biJUWCn9xg2ffdZThJrzKSnykqiWYfJ1M -tz1g99KETPNxWmowbBiLJ3qBAU3QmyxNPd5n -tz1hBP73SHyxpyQCvy5ofM7EnAqRy9DX5rUj -tz1b1c4p6WZN9kkZafNLo8bGsRaHiEsJqQTC -tz1g2fDDH3w3zVVy1j4Qi1YqfyzT8bsBadca -tz1LdKhNP79DJo6PnNtTkAJW8q46Ur7UvVrj -tz1iVfDbmFRMbKyMZWEnbKyMxHcUu8EMXrd7 -tz1iC8328aPpZirwc2YbhN9pVhrEZ56YquJ1 -tz1bpYZHmAGGTACzkCWFL8JkdFEk8quDzAvb -tz1M9ckA76TkqrgCGkUZobdZWAjsopotM9CX -tz1MfVtRbfpGMVKunBTdDd9fHAt9mQvWpmqN -tz1aGPoLvWo6cVqQqfNnfZvdNdoWxmrrdXmW -tz1XsSq6nYaNdUMDkB62YNnjW8Jp9nVpwFbq -tz1gyyt7AjvFyS3ihzYafm9J9zkafEtjqjKu -tz1XsBRwR3yXDr95E6R7SuiG3aCV4ZH7EcCG -tz1V8DBCuwFQanJZ8KV72y1Eb3uRooCGdhJc -tz1czJup9EGwAtuKAKvo3njvd1Erk9Bx4iKu -tz1eNXuPxjP2dpECotRbkE6HCeEgddnYKLWF -tz1UrgRRcUr2ahWTvAMpqBcsmDnH6DbrHK5Q -tz1VDPcq211Sn6iCjQeY8G697Ws37yNLgxYC -tz1PrkBBnGFQqArxVLGTv8GQXGjeCWty3XYa -tz1XUWPVotSEeGS6kxZDW5yYwFhqvBQvDpfT -tz1MQJ35dH76GyiKjJsxfXaQsprX2d4D65F3 -tz1S7Kpf6u52quyVEeGZu4YpGQ5WYWU2f1Go -tz1YKwTH8rQwPCGXp4sNsMkKrxDwup35V4cm -tz1QHGq4RTASpiHHEJg7tHpy8Phgjw77Quz3 -tz1gDdveJTjH4pQRnF4VzZVxnNkaifKkShuR -tz1bt75S2diE9Mh6FJoka8AEorfgDX4RGS5j -tz1gVB6oGhzwmqDw8m2CDeXTMMUHuUo6EWXR -tz1cuu6QDZNddqD61aprmt5kqCGygvqoeAbq -tz1dQt53yPNRL2U5GdpruzgzkKdZ9HoCxhhm -tz1f6VQ2WiywgDpCHtZsqrhB5axrqgS9YrT7 -tz1XtHQVjTHLZuDPsGGZ8vBS6H9wWDXzGGqQ -tz1i7vz5JUhZvAVyxV78LPWLNSBWetXSYo8h -tz1i6zy48PN1eFLw7Q1SfAqbaZaRBAjwTdFm -tz1b8VeooxmzD4hNwi2McqWPm1ouC8P5dic2 -tz1PyKJkJuVRfohovymyLATT7VJNAEPyLws1 -tz1bk49mUAofthLK2mGy9X141bCPA7TSRJnX -tz1ZQE6EtRc5zyrjKKfN4o5Gmze9GZMY6Fic -tz1SFWB3wJPoF72iuWzN8EetBDxqyCi89Uga -tz1TG5Q1wFfx5bbL3skGLiieWUY9XwXsqpNu -tz1USajFCVFLrnAuWDxCuVHHn976mju45uvp -tz1NA5PnKoYACPBwu6CbMKW1rV8jigUxoY2o -tz1gTgPu1SiEoLkNbKLDAFs4xZayAG51oeYT -tz1NqcN6bPr91GzvzcUCJVWBuihMGrn9HXuc -tz1a4fF2ezDFhaDSXFGdrySatY9t32k1ErMM -tz1iemaEDiNy14JryxsYYXSzkkLMVpcVdc3h -tz1Mn69sLqZjfswuRUW2YY4fLj9NcUyLDLZA -tz1Q6AAwnWjHi5uMKZHjCxmJbsn7P1H8atNM -tz1TDHkiVSbjspih1uJZLdZEWtgcCrB9mo13 -tz1R1JJ7UrDG76pHxZxsM36pW9zoGmWqoo4V -tz1dhRkYPKfkHtaEAh1uTfdA8NGwvSX5cp1e -tz1ZDSRi6kzcmumC5s8NoMXutsnSZK6a7PVg -tz1P65DQn4ikBagqofrzML7j8nv2xX5gSyVq -tz1i4DFtCPuB7Uyc3ENgiAimjH8dyoApYSuY -tz1UsfQoQbVdVoNaZTgAZD8zRL3FPnyFDNGd -tz1hXBioewm4xiNKkumC3i97QPC22nXy8wen -tz1Yx1tLEGE3Ugk4khefdUZAt4zyKDcvb5xX -tz1ZWjg6kBUk792xSNhU51Y8F5seWQHDauBJ -tz1ZkY7JKHjGvjNL25AhJuVsnjMdbZLW9PKm -tz1ZbgpHPXefWYCqsripm928f4AcLgSU4zYa -tz1bFgrUuud99XDzsQiqiYdt4FCVUWnNw6dR -tz1a5L1PUzQGyFZ6RwBgaZtPPsnhY9LvLHVs -tz1LMEJj4zepBKkFwjSMicS7ET8FkX4q6xrj -tz1acZF8LxRDsQ5T28Sww39bGwCPCNYHGJMm -tz1SbrHNhigb38WhzBvKfWGw8UZrGXwBvWN7 -tz1SwxMSA8idLhohTRPBvnEvnQnhfwsDaE1P -tz1RYFcJTrFfZjpbxbVET18jG8xUGWawMnj7 -tz1iCR4CLrhCagXukb33UggRGsi3uGDRk8ic -tz1XyF1ay2PMq3dDkWiABJWxPtxT7k2byJUB -tz1Um8TTLJ6mvP4ZDhGCYZZ33MBcmWFTAz9C -tz1b2GABbp5xHxBFYUBZ3G6nmCzvhqAPXvcE -tz1RKheX3sAnkhHi8RHfMoftZzHikf9MqbTb -tz1cdkaP2Zrs8XyRjSh14wzdAFStqd2Fuby9 -tz1iomvsbcMftWPgAJ59ZBQuwSmWL952gcx1 -tz1fWN1epQwWnqCpd2Ma4FdRtRVY55sSamDT -tz1RRam9ogh2sEhoKtRU9gGv9aCFioRbLfnU -tz1NMZXCdzodiemkDtiNPK4Jhq1GFug5s4gf -tz1etB3wjVXFyVZY5LiZt4HCEBWcdtKRFfmo -tz1ZMAwjTYaPaxkDfRfwe1cTExRU8WvGC49g -tz1Wyq68YNeS6zg3yHhbbz1sK3er8BFcKwkX -tz1RgevuFEHQLiTunRRxzCyp1V5TGrkdo1ed -tz1XseBYkqNbdtZDRM8uEaoHGKxxP4ELq3F1 -tz1ZyQdZdw55p1svLKBy84PC3ujet9t5VANZ -tz1Y1qS592sG4YDAcQJWVD7f15t3qgMji5uy -tz1Q3f4NarJ2LqToef85AmAQ1EthyUKALCPq -tz1TtjJsnFVTNstsv9pQWaqGCsJQmwMWxpji -tz1YwrdmCp1bQJ3Pg7bENJyr9LRjm6z4AGqa -tz1XURG5vb3SBZPMQ9JYHTahBc9rTHarRSqW -tz1YYMtpE2NTSnJzYKjgnqaNHi2RFD11KGSt -tz1Tz5PgcVRmaHB2oAZ4HKC7vk8pHH1HtN5i -tz1YsefikQ4i1KunWkXoozeUfYpDKxXtBzac -tz1doM7TLCCRGbKFNPvMxYB1mSmXyyTAEsJB -tz1WSJTkTzzanasnHuC2xArRWkfcYGFM534H -tz1Zf3kXyMz1FKfAdC9V3SPW8jt9Q7RY3Hba -tz1iCuQKyn8qu2BFKbA1PX4PyamrfUdCsHKH -tz1hGJvJVFjhGUFdmaiThAyvHxLqVQyNtNx2 -tz1WWHTDZ7D1hwJ21vQ92m8xRoKEMYq4DLDS -tz1Zya25zMcv5a5UbYyLYVuES7SA5eWcis5b -tz1doVbQnAuuQXSx2giHrq5nmqR5rmkyvHXz -tz1SMWqc1v4v7MWE4QMjtshF1VWhuka5keCK -tz1ZfXNLtqxRWKt5fY1SMrUjM2si8DDxsxKY -tz1f3ARBm5mxFPZiiZ2v4YAX1Y2TCMvSdwpi -tz1XEvoNL1FHHQw6cr7j6QTTZrYkSya4ARqf -tz1gJDNh3UZaT9bTB22cH8hNK3m341oauDp4 -tz1cdY5dJakKy2jyq9VNAcLcdHTnGw6WgGns -tz1dq7TFK8DLWgCiLmEBCjnTAfZKbHa2WPsG -tz1NmH29Lmis4ivmTDU7wXJKvBxBKcXQcEa8 -tz1hTbMLR473Xs58h8UQQ7TckQpvEpiBN84T -tz1YRhiiSGRAKuxPEBnBeCi9Ygb5DWhamkmE -tz1ef5Qd3oTyA9ztowP88muxmfEKP8e311rf -tz1VQa6jSRpEy6ZFX7BhkkYcUPQdvCnV2tcZ -tz1hwnuZnqL5kDvrkgKD6jie99x9QXSVnrHc -tz1MJa3MhT5KmKvKj7NHFmzQ7sdq4fCipgiw -tz1LhfksuYukQPN8Pv2rZy2AXHZ6jHPKWeUo -tz1iQLNmGLdFF3sApRjKhrahXAJBTdG3goGc -tz1WYZrE1Lhd5cgh4vzUhJB1UBNGEdekbskQ -tz1YjahMjE7nBu3sAH9VNpofwqhopGWkDazX -tz1PMNF7AWfVUEKgqQPFLFPkAP1NaaVVmNQx -tz1PRt7muezToTTUDywT4gPSkxX8dU9a1q55 -tz1cNARmnRRrvZgspPr2rSTUWq5xtGTuKuHY -tz1Y2mymBW3dzYNzyzct1vchPzJ6BRvroxyd -tz1c5q1xLQ6kKV5Lgk7DqvVwMVWfik7ARQP4 -tz1cpi7ydrPb6bYX8C93Y7YkuAUALRsdQ7kR -tz1ae6ZQLBDXEZveMbDf23o173sAYTKWGaP4 -tz1aTuSko6LSnUQrBw4CUPVSGkg24VYJCH6a -tz1Xfje9e5sY2P16RArUeeHgQDJHWJJ6sMAE -tz1QdKEvmxyEC9Rbe9NSYoW3ojHajJejYoKX -tz1V5fGSQ2YBfTHQFXL1GtmM7jPrVYqLLF91 -tz1iJmJfi6W7xaAVpGTJvC9i6SrVdvgFDLbU -tz1LFtDnxJik62tPeBMWcjHkWBj8PQxLjt4r \ No newline at end of file diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BakerCycleCommit.cs deleted file mode 100644 index 258506253..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,541 +0,0 @@ -using System.Text.Json; -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class BakerCycleCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply( - Block block, - Cycle? futureCycle, - IEnumerable? futureBakingRights, - IEnumerable? futureAttestationRights, - List? snapshots, - List currentRights) - { - #region current rights - foreach (var rights in currentRights.GroupBy(x => x.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, rights.Key); - Db.TryAttach(bakerCycle); - - var bakingRights = rights - .Where(x => x.Type == BakingRightType.Baking) - .OrderBy(x => x.Round) - .ToList(); - - var attestationRight = rights - .FirstOrDefault(x => x.Type == BakingRightType.Attestation); - - #region rights and deposits - foreach (var br in bakingRights) - { - if (br.Round == 0) - { - bakerCycle.FutureBlocks--; - } - - if (br.Status == BakingRightStatus.Realized) - { - bakerCycle.Blocks++; - } - else if (br.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlocks++; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - - if (attestationRight != null) - { - bakerCycle.FutureAttestations -= attestationRight.Slots!.Value; - - if (attestationRight.Status == BakingRightStatus.Realized) - { - bakerCycle.Attestations += attestationRight.Slots!.Value; - } - else if (attestationRight.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedAttestations += attestationRight.Slots!.Value; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - - #region attestation rewards - if (attestationRight != null) - { - bakerCycle.FutureAttestationRewards -= GetFutureAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots!.Value); - - var successReward = GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, block.BlockRound); - - var maxReward = bakingRights.FirstOrDefault()?.Status > BakingRightStatus.Realized - ? GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, bakingRights[0].Round!.Value) - : successReward; - - if (attestationRight.Status == BakingRightStatus.Realized) - bakerCycle.AttestationRewardsDelegated += successReward; - else if (attestationRight.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestationRewards += successReward; - else - throw new Exception("Unexpected future rights"); - - if (maxReward != successReward) - { - bakerCycle.MissedBlockRewards += maxReward - successReward; - } - } - #endregion - - #region baking rewards - if (bakingRights.Count > 0) - { - if (bakingRights[0].Round == 0) - bakerCycle.FutureBlockRewards -= GetFutureBlockReward(Context.Protocol, block.Cycle); - - var successReward = GetBlockReward(Context.Protocol, block.Cycle, bakingRights[0].Round!.Value, block.AttestationPower); - - var actualReward = bakingRights[^1].Status == BakingRightStatus.Realized - ? GetBlockReward(Context.Protocol, block.Cycle, bakingRights[^1].Round!.Value, block.AttestationPower) - : 0; - - var maxReward = attestationRight?.Status > BakingRightStatus.Realized - ? GetBlockReward(Context.Protocol, block.Cycle, bakingRights[0].Round!.Value, block.AttestationPower + attestationRight.Slots!.Value) - : successReward; - - if (actualReward > 0) - { - bakerCycle.BlockRewardsDelegated += actualReward; - } - - if (successReward != actualReward) - { - bakerCycle.MissedBlockRewards += successReward - actualReward; - } - - if (maxReward != successReward) - { - bakerCycle.MissedAttestationRewards += maxReward - successReward; - } - } - #endregion - - #region fees - if (bakingRights.Count > 0) - { - if (bakingRights[^1].Status == BakingRightStatus.Realized) - { - bakerCycle.BlockFees += block.Fees; - } - else if (bakingRights[0].Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlockFees += block.Fees; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - } - - foreach (var op in Context.DoubleBakingOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleBakingLostStaked += op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleBakingRewards += op.Reward; - } - - foreach (var op in Context.DoubleConsensusOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleConsensusLostStaked += op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleConsensusRewards += op.Reward; - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.NonceRevelationRewardsDelegated += op.RewardDelegated; - } - - foreach (var op in Context.RevelationPenaltyOps) - { - var penaltyBlock = await Cache.Blocks.GetAsync(op.MissedLevel); - var penaltyCycle = await Cache.BakerCycles.GetAsync(penaltyBlock.Cycle, op.BakerId); - Db.TryAttach(penaltyCycle); - - penaltyCycle.NonceRevelationLosses += op.Loss; - } - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - var bakerCycles = snapshots!.ToDictionary( - snapshot => Cache.Accounts.GetDelegate(snapshot.AccountId).Address, - snapshot => - { - var bakingPower = snapshot.StakingBalance - snapshot.StakingBalance % Context.Protocol.MinimalStake; - var share = (double)bakingPower / futureCycle!.TotalBakingPower; - - var bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = snapshot.AccountId, - OwnDelegatedBalance = snapshot.OwnDelegatedBalance, - ExternalDelegatedBalance = snapshot.ExternalDelegatedBalance!.Value, - DelegatorsCount = snapshot.DelegatorsCount!.Value, - OwnStakedBalance = snapshot.OwnStakedBalance ?? 0, - ExternalStakedBalance = snapshot.ExternalStakedBalance ?? 0, - StakersCount = snapshot.StakersCount ?? 0, - IssuedPseudotokens = snapshot.Pseudotokens, - BakingPower = bakingPower, - TotalBakingPower = futureCycle.TotalBakingPower, - ExpectedBlocks = Context.Protocol.BlocksPerCycle * share, - ExpectedAttestations = Context.Protocol.AttestersPerBlock * Context.Protocol.BlocksPerCycle * share - }; - - return bakerCycle; - }); - - #region future baking rights - foreach (var br in futureBakingRights!) - { - if (br.RequiredInt32("priority") > 0) - continue; - - if (!bakerCycles.TryGetValue(br.RequiredString("delegate"), out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - bakerCycle.FutureBlocks++; - bakerCycle.FutureBlockRewards += GetFutureBlockReward(Context.Protocol, futureCycle!.Index); - } - #endregion - - #region future attestation rights - var skipLevel = futureAttestationRights!.Last().RequiredInt32("level"); - - foreach (var ar in futureAttestationRights!.TakeWhile(x => x.RequiredInt32("level") < skipLevel)) - { - if (!bakerCycles.TryGetValue(ar.RequiredString("delegate"), out var bakerCycle)) - throw new Exception("Nonexistent baker cycle"); - - var slots = ar.RequiredArray("slots").Count(); - - bakerCycle.FutureAttestations += slots; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, futureCycle!.Index, slots); - } - #endregion - - #region shifted future attestation rights - // TODO: cache shifted rights - var shiftedRights = await Db.BakingRights.AsNoTracking() - .Where(x => x.Level == futureCycle!.FirstLevel && x.Type == BakingRightType.Attestation) - .ToListAsync(); - - foreach (var ar in shiftedRights) - { - var baker = Cache.Accounts.GetDelegate(ar.BakerId); - - if (!bakerCycles.TryGetValue(baker.Address, out var bakerCycle)) - { - #region shifting hack - //shifting is actually a bad idea, but this is the lesser of two evils while Tezos protocol has bugs in the freezer. - var snapshottedBaker = await Proto.Rpc.GetDelegateAsync(futureCycle!.SnapshotLevel, baker.Address); - var delegators = snapshottedBaker - .RequiredArray("delegated_contracts") - .EnumerateArray() - .Select(x => x.RequiredString()) - .Where(x => x != baker.Address); - - if (snapshottedBaker.RequiredInt32("grace_period") != block.Cycle - 3) - throw new Exception("Deactivated baker got baking rights"); - - var stakingBalance = snapshottedBaker.RequiredInt64("staking_balance"); - var delegatedBalance = snapshottedBaker.RequiredInt64("delegated_balance"); - - bakerCycle = new BakerCycle - { - Id = 0, - Cycle = futureCycle.Index, - BakerId = baker.Id, - OwnDelegatedBalance = stakingBalance - delegatedBalance, - ExternalDelegatedBalance = delegatedBalance, - DelegatorsCount = delegators.Count(), - OwnStakedBalance = 0, - ExternalStakedBalance = 0, - StakersCount = 0, - IssuedPseudotokens = null, - BakingPower = 0, - TotalBakingPower = futureCycle.TotalBakingPower, - ExpectedBlocks = 0, - ExpectedAttestations = 0 - }; - bakerCycles.Add(baker.Address, bakerCycle); - - foreach (var delegatorAddress in delegators) - { - var snapshottedDelegator = await Proto.Rpc.GetContractAsync(futureCycle.SnapshotLevel, delegatorAddress); - Db.DelegatorCycles.Add(new DelegatorCycle - { - Id = 0, - Cycle = futureCycle.Index, - DelegatorId = (await Cache.Accounts.GetExistingAsync(delegatorAddress)).Id, - BakerId = baker.Id, - DelegatedBalance = snapshottedDelegator.RequiredInt64("balance"), - StakedPseudotokens = null - }); - } - #endregion - } - - bakerCycle.FutureAttestations += ar.Slots!.Value; - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, futureCycle!.Index, (int)ar.Slots); - } - #endregion - - Db.BakerCycles.AddRange(bakerCycles.Values); - } - #endregion - } - - public virtual async Task Revert(Block block) - { - #region current rights - var currentRights = await Cache.BakingRights.GetAsync(block.Level); - - foreach (var rights in currentRights.GroupBy(x => x.BakerId)) - { - var bakerCycle = await Cache.BakerCycles.GetOrDefaultAsync(block.Cycle, rights.Key); - if (bakerCycle == null) - { - if (!block.Events.HasFlag(BlockEvents.CycleBegin) || rights.Any(x => x.Status == BakingRightStatus.Realized)) - throw new Exception("Shifted rights hack doesn't work :("); - continue; - } - - Db.TryAttach(bakerCycle); - - var bakingRights = rights - .Where(x => x.Type == BakingRightType.Baking) - .OrderBy(x => x.Round) - .ToList(); - - var attestationRight = rights - .FirstOrDefault(x => x.Type == BakingRightType.Attestation); - - #region rights and deposits - foreach (var br in bakingRights) - { - if (br.Round == 0) - { - bakerCycle.FutureBlocks++; - } - - if (br.Status == BakingRightStatus.Realized) - { - bakerCycle.Blocks--; - } - else if (br.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlocks--; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - - if (attestationRight != null) - { - bakerCycle.FutureAttestations += attestationRight.Slots!.Value; - - if (attestationRight.Status == BakingRightStatus.Realized) - { - bakerCycle.Attestations -= attestationRight.Slots!.Value; - } - else if (attestationRight.Status == BakingRightStatus.Missed) - { - bakerCycle.MissedAttestations -= attestationRight.Slots!.Value; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - - #region attestation rewards - if (attestationRight != null) - { - bakerCycle.FutureAttestationRewards += GetFutureAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots!.Value); - - var successReward = GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, block.BlockRound); - - var maxReward = bakingRights.FirstOrDefault()?.Status > BakingRightStatus.Realized - ? GetAttestationReward(Context.Protocol, block.Cycle, attestationRight.Slots.Value, bakingRights[0].Round!.Value) - : successReward; - - if (attestationRight.Status == BakingRightStatus.Realized) - bakerCycle.AttestationRewardsDelegated -= successReward; - else if (attestationRight.Status == BakingRightStatus.Missed) - bakerCycle.MissedAttestationRewards -= successReward; - else - throw new Exception("Unexpected future rights"); - - if (maxReward != successReward) - { - bakerCycle.MissedBlockRewards -= maxReward - successReward; - } - } - #endregion - - #region baking rewards - if (bakingRights.Count > 0) - { - if (bakingRights[0].Round == 0) - bakerCycle.FutureBlockRewards += GetFutureBlockReward(Context.Protocol, block.Cycle); - - var successReward = GetBlockReward(Context.Protocol, block.Cycle, bakingRights[0].Round!.Value, block.AttestationPower); - - var actualReward = bakingRights[^1].Status == BakingRightStatus.Realized - ? GetBlockReward(Context.Protocol, block.Cycle, bakingRights[^1].Round!.Value, block.AttestationPower) - : 0; - - var maxReward = attestationRight?.Status > BakingRightStatus.Realized - ? GetBlockReward(Context.Protocol, block.Cycle, bakingRights[0].Round!.Value, block.AttestationPower + attestationRight.Slots!.Value) - : successReward; - - if (actualReward > 0) - { - bakerCycle.BlockRewardsDelegated -= actualReward; - } - - if (successReward != actualReward) - { - bakerCycle.MissedBlockRewards -= successReward - actualReward; - } - - if (maxReward != successReward) - { - bakerCycle.MissedAttestationRewards -= maxReward - successReward; - } - } - #endregion - - #region fees - if (bakingRights.Count > 0) - { - if (bakingRights[^1].Status == BakingRightStatus.Realized) - { - bakerCycle.BlockFees -= block.Fees; - } - else if (bakingRights[0].Status == BakingRightStatus.Missed) - { - bakerCycle.MissedBlockFees -= block.Fees; - } - else - { - throw new Exception("Unexpected future rights"); - } - } - #endregion - } - - foreach (var op in Context.DoubleBakingOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleBakingLostStaked -= op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleBakingRewards -= op.Reward; - } - - foreach (var op in Context.DoubleConsensusOps) - { - var accusedBlock = await Cache.Blocks.GetAsync(op.AccusedLevel); - var offenderCycle = await Cache.BakerCycles.GetAsync(accusedBlock.Cycle, op.OffenderId); - Db.TryAttach(offenderCycle); - - offenderCycle.DoubleConsensusLostStaked -= op.LostStaked; - - var accuserCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.AccuserId); - Db.TryAttach(accuserCycle); - - accuserCycle.DoubleConsensusRewards -= op.Reward; - } - - foreach (var op in Context.NonceRevelationOps) - { - var bakerCycle = await Cache.BakerCycles.GetAsync(block.Cycle, op.BakerId); - Db.TryAttach(bakerCycle); - - bakerCycle.NonceRevelationRewardsDelegated -= op.RewardDelegated; - } - - foreach (var op in Context.RevelationPenaltyOps) - { - var penaltyBlock = await Cache.Blocks.GetAsync(op.MissedLevel); - var penaltyCycle = await Cache.BakerCycles.GetAsync(penaltyBlock.Cycle, op.BakerId); - Db.TryAttach(penaltyCycle); - - penaltyCycle.NonceRevelationLosses -= op.Loss; - } - #endregion - - #region new cycle - if (block.Events.HasFlag(BlockEvents.CycleBegin)) - { - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "BakerCycles" - WHERE "Cycle" = {0} - """, block.Cycle + Context.Protocol.ConsensusRightsDelay); - } - #endregion - } - - #region helpers - protected virtual long GetFutureBlockReward(Protocol protocol, int cycle) - => cycle < protocol.NoRewardCycles ? 0 : protocol.BlockReward0; - - protected virtual long GetBlockReward(Protocol protocol, int cycle, int priority, long slots) - => cycle < protocol.NoRewardCycles ? 0 : (protocol.BlockReward0 * (8 + 2 * slots / protocol.AttestersPerBlock) / 10 / (priority + 1)); - - protected virtual long GetFutureAttestationReward(Protocol protocol, int cycle, long slots) - => cycle < protocol.NoRewardCycles ? 0 : (slots * protocol.AttestationReward0); - - protected virtual long GetAttestationReward(Protocol protocol, int cycle, int slots, int priority) - => cycle < protocol.NoRewardCycles ? 0 : (slots * (long)(protocol.AttestationReward0 / (priority + 1.0))); - #endregion - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BakingRightsCommit.cs deleted file mode 100644 index 04831d578..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class BakingRightsCommit : Proto3.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BigMapCommit.cs deleted file mode 100644 index 5c259034d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BlockCommit.cs deleted file mode 100644 index f25e5cb02..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class BlockCommit : Proto1.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/CycleCommit.cs deleted file mode 100644 index 83e00bdc5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/DeactivationCommit.cs deleted file mode 100644 index b52566179..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index a91ad3e8b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/FreezerCommit.cs deleted file mode 100644 index 98f5acb44..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class FreezerCommit : Proto4.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index bd1bd85bc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index a1d36c07f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index bfb5b38ee..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 3473abf3e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index dd84d72fd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 95fd85ce8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class DoubleConsensusCommit : Proto4.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index fa8567a9a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 3a68137bc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Text.Json; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class OriginationsCommit(ProtocolHandler protocol) : Proto1.OriginationsCommit(protocol) - { - protected override IMicheline GetCode(JsonElement content) - { - return Micheline.FromJson(content.Required("script").Required("code"))!; - } - - protected override IMicheline GetStorage(JsonElement content) - { - return Micheline.FromJson(content.Required("script").Required("storage"))!; - } - - protected override IEnumerable? ParseBigMapDiffs(OriginationOperation origination, JsonElement result, MichelineArray code, IMicheline storage) - { - return result.TryGetProperty("big_map_diff", out var diffs) - ? diffs.RequiredArray().EnumerateArray().Select(BigMapDiff.Parse) - : null; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 60fa5f810..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 843db481d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 5729120b6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System.Text.Json; -using Netezos.Contracts; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class TransactionsCommit : Proto4.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override async Task ProcessParameters(TransactionOperation transaction, Account? target, JsonElement param) - { - string? rawEp = null; - IMicheline? rawParam; - try - { - rawEp = param.RequiredString("entrypoint"); - rawParam = Micheline.FromJson(param.Required("value"))!; - } - catch (Exception ex) - { - Logger.LogWarning(ex, "Failed to parse tx parameters"); - transaction.Entrypoint = rawEp ?? string.Empty; - transaction.RawParameters = new MichelineArray().ToBytes(); - return; - } - - if (target is Contract contract) - { - var schema = contract.Kind > ContractKind.DelegatorContract - ? (await Cache.Schemas.GetAsync(contract)) - : Script.ManagerTz; - - try - { - var (normEp, normParam) = schema.NormalizeParameter(rawEp, rawParam); - - transaction.Entrypoint = normEp; - transaction.RawParameters = schema.OptimizeParameter(normEp, normParam).ToBytes(); - transaction.JsonParameters = schema.HumanizeParameter(normEp, normParam); - } - catch (Exception ex) - { - transaction.Entrypoint ??= rawEp; - transaction.RawParameters ??= rawParam.ToBytes(); - - if (transaction.Status == OperationStatus.Applied) - Logger.LogError(ex, "Failed to humanize tx {hash} parameters", transaction.OpHash); - } - } - else if (target is SmartRollup smartRollup) - { - var schema = await Cache.Schemas.GetAsync(smartRollup); - - try - { - var (normEp, normParam) = schema.NormalizeParameter(rawEp, rawParam); - - transaction.Entrypoint = normEp; - transaction.RawParameters = schema.OptimizeParameter(normEp, normParam).ToBytes(); - transaction.JsonParameters = schema.HumanizeParameter(normEp, normParam); - } - catch (Exception ex) - { - transaction.Entrypoint ??= rawEp; - transaction.RawParameters ??= rawParam.ToBytes(); - - if (transaction.Status == OperationStatus.Applied) - Logger.LogError(ex, "Failed to humanize tx {hash} parameters", transaction.OpHash); - } - } - else if (target is Rollup) - { - transaction.Entrypoint = rawEp; - transaction.RawParameters = rawParam.ToBytes(); - try - { - var ticketValue = (rawParam as MichelineArray)![0]; - var ticketType = ((rawParam as MichelineArray)![1] as MichelinePrim)!; - - ticketType.Annots ??= new List(1); - if (ticketType.Annots.Count == 0) - ticketType.Annots.Add(new FieldAnnotation("data")); - - var schema = Schema.Create(new MichelinePrim - { - Prim = PrimType.pair, - Args = - [ - new MichelinePrim - { - Prim = PrimType.pair, - Args = - [ - new MichelinePrim - { - Prim = PrimType.address, - Annots = [new FieldAnnotation("address")] - }, - new MichelinePrim - { - Prim = PrimType.pair, - Args = - [ - ticketType, - new MichelinePrim - { - Prim = PrimType.nat, - Annots = [new FieldAnnotation("amount")] - } - ] - } - ], - Annots = [new FieldAnnotation("ticket")] - }, - new MichelinePrim - { - Prim = PrimType.tx_rollup_l2_address, - Annots = [new FieldAnnotation("address")] - } - ] - }); - - transaction.JsonParameters = schema.Humanize(ticketValue); - } - catch (Exception ex) - { - if (transaction.Status == OperationStatus.Applied) - Logger.LogError(ex, "Failed to humanize tx {hash} parameters", transaction.OpHash); - } - } - else - { - transaction.Entrypoint = rawEp; - transaction.RawParameters = rawParam.ToBytes(); - } - } - - protected override IMicheline NormalizeStorage(TransactionOperation transaction, IMicheline storage, ContractScript schema) - { - return storage; - } - - protected override IEnumerable? ParseBigMapDiffs(TransactionOperation transaction, JsonElement result) - { - return result.TryGetProperty("big_map_diff", out var diffs) - ? diffs.RequiredArray().EnumerateArray().Select(BigMapDiff.Parse) - : null; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index 7ce6e70b9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class RevelationPenaltyCommit : Proto4.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index ac394dd8b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class SnapshotBalanceCommit : Proto4.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/SoftwareCommit.cs deleted file mode 100644 index 823cab760..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class SoftwareCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, JsonElement rawBlock) - { - var version = rawBlock.Required("header").RequiredString("proof_of_work_nonce")[..8]; - var software = await Cache.Software.GetOrCreateAsync(version, () => new Software - { - Id = Cache.AppState.NextSoftwareId(), - FirstLevel = block.Level, - LastLevel = -1, - ShortHash = version - }); - - if (software.LastLevel == -1) - Db.Software.Add(software); - else - Db.TryAttach(software); - - software.BlocksCount++; - software.LastLevel = block.Level; - - block.SoftwareId = software.Id; - - var blockProducer = Cache.Accounts.GetDelegate(block.ProducerId!.Value); - //Db.TryAttach(blockProducer); - if (blockProducer.SoftwareId != software.Id) - { - blockProducer.SoftwareId = software.Id; - blockProducer.SoftwareUpdateLevel = block.Level; - } - } - - public virtual async Task Revert(Block block) - { - var software = await Cache.Software.GetAsync(block.SoftwareId!.Value); - - Db.TryAttach(software); - software.BlocksCount--; - - // don't revert Baker.SoftwareId and Software.LastLevel - // don't remove emptied software for historical purposes - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/StateCommit.cs deleted file mode 100644 index 88cdb5990..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/StatisticsCommit.cs deleted file mode 100644 index a86dc54fa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/TokensCommit.cs deleted file mode 100644 index 84aae89bd..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/TokensCommit.cs +++ /dev/null @@ -1,1061 +0,0 @@ -using System.Numerics; -using Microsoft.EntityFrameworkCore; -using Netezos.Encoding; -using Tzkt.Data.Models; -using Tzkt.Data.Models.Base; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class TokensCommit(ProtocolHandler protocol) : ProtocolCommit(protocol) - { - public virtual async Task Apply(Block block, - List<(BigMap BigMap, BigMapKey? Key, BigMapUpdate Update, ContractOperation Op)> updates) - { - updates = updates.OrderBy(x => x.Op.Id).ThenBy(x => x.BigMap.Ptr).ToList(); - var ops = new Dictionary Transfers, - List<(string Address, BigInteger Balance)> Balances - )> Tokens - )>(); - var opBlocks = new Dictionary { { block.Level, block } }; - - #region discover ledgers - Dictionary? pendingBigMaps = null; - foreach (var (bigmap, _, update, op) in updates) - { - if (update.Action == BigMapAction.Allocate) - { - if ((bigmap.Tags & BigMapTag.LedgerTypes) != 0) - { - var contract = (await Cache.Accounts.GetAsync( - op is TransactionOperation tx - ? tx.TargetId!.Value - : (op as OriginationOperation)!.ContractId!.Value - ) as Contract)!; - - if (contract.Tags.HasFlag(ContractTags.Ledger)) - { - // there must be only one ledger bigmap - bigmap.Tags &= ~BigMapTag.LedgerMask; - Logger.LogWarning("Multiple ledger bigmaps discovered for {contract}", contract.Address); - } - else - { - Db.TryAttach(contract); - contract.Tags |= ContractTags.Ledger; - if ((bigmap.Tags & BigMapTag.LedgerNft) != 0) - contract.Tags |= ContractTags.Nft; - } - } - } - else if (update.Action == BigMapAction.Remove) - { - if ((bigmap.Tags & BigMapTag.LedgerTypes) != 0) - { - var contract = (await Cache.Accounts.GetAsync( - op is TransactionOperation tx - ? tx.TargetId!.Value - : (op as OriginationOperation)!.ContractId!.Value - ) as Contract)!; - - Db.TryAttach(contract); - contract.Tags &= ~ContractTags.Ledger; - if ((bigmap.Tags & BigMapTag.LedgerNft) != 0) - contract.Tags &= ~ContractTags.Nft; - } - } - else if ((bigmap.Tags & (BigMapTag.Persistent | BigMapTag.Ledger)) == BigMapTag.Persistent && - op is TransactionOperation tx && tx.Entrypoint == "transfer" && await Cache.Accounts.GetAsync(tx.TargetId) is Contract contract && - (contract.Tags & (ContractTags.FA | ContractTags.Ledger)) == ContractTags.FA) - { - Db.TryAttach(bigmap); - bigmap.Tags |= BigMaps.GetLedgerType(bigmap.Schema); - - if (bigmap.Tags.HasFlag(BigMapTag.Ledger)) - { - Db.TryAttach(contract); - contract.Tags |= ContractTags.Ledger; - if ((bigmap.Tags & BigMapTag.LedgerNft) != 0) - contract.Tags |= ContractTags.Nft; - - pendingBigMaps ??= []; - pendingBigMaps.Add(bigmap.Ptr, bigmap); - } - else - { - bigmap.Tags |= BigMapTag.Ledger; - Logger.LogWarning("Unsupported ledger bigmap #{ptr} ignored", bigmap.Ptr); - } - } - } - if (pendingBigMaps != null) - { - #region load entities - var ptrs = pendingBigMaps.Keys.ToHashSet(); - var pendingUpdates = await Db.BigMapUpdates - .AsNoTracking() - .Where(x => ptrs.Contains(x.BigMapPtr) && - x.Action != BigMapAction.Allocate && - x.Level < block.Level) - .ToListAsync(); - - var keys = pendingUpdates.Count == 0 ? [] : await Db.BigMapKeys - .AsNoTracking() - .Where(x => ptrs.Contains(x.BigMapPtr)) - .ToDictionaryAsync(x => x.Id); - - var txIds = pendingUpdates - .Where(x => x.TransactionId != null) - .Select(x => x.TransactionId!.Value) - .ToHashSet(); - - var txs = txIds.Count == 0 ? [] : await Db.TransactionOps - //.AsNoTracking() - .Where(x => txIds.Contains(x.Id)) - .ToDictionaryAsync(x => x.Id); - - var origIds = pendingUpdates - .Where(x => x.OriginationId != null) - .Select(x => x.OriginationId!.Value) - .ToHashSet(); - - var origs = origIds.Count == 0 ? [] : await Db.OriginationOps - //.AsNoTracking() - .Where(x => origIds.Contains(x.Id)) - .ToDictionaryAsync(x => x.Id); - - var contracts = pendingBigMaps.Values - .Select(x => x.ContractId) - .ToHashSet(); - - // transfers with no balance updates, e.g. to itself or with 0 amount - var pendingTransfers = await Db.TransactionOps - //.AsNoTracking() - .Where(x => x.TargetId != null && - contracts.Contains(x.TargetId.Value) && - x.Status == OperationStatus.Applied && - x.Entrypoint == "transfer" && - x.TokenTransfers == null && - x.Level < block.Level) - .ToListAsync(); - #endregion - - #region preload - var blocks = pendingTransfers.Select(x => x.Level) - .Concat(pendingUpdates.Select(x => x.Level)) - .ToHashSet(); - - var targets = pendingTransfers.Select(x => x.TargetId!.Value) - .Concat(pendingBigMaps.Select(x => x.Value.ContractId)) - .ToHashSet(); - - await Cache.Blocks.Preload(blocks); - await Cache.Accounts.Preload(targets); - #endregion - - #region group - foreach (var tx in pendingTransfers) - { - if (!opBlocks.ContainsKey(tx.Level)) - { - var opBlock = Cache.Blocks.GetCached(tx.Level); - opBlocks.Add(tx.Level, opBlock); - Db.TryAttach(opBlock); - } - - var tokens = new Dictionary Transfers, - List<(string Address, BigInteger Balance)> Balances - )>(); - - foreach (var (from, to, tokenId, amount) in ParseTransferParam(Micheline.FromBytes(tx.RawParameters!))) - { - if (!tokens.TryGetValue(tokenId, out var ctx)) - { - ctx = ([], []); - tokens.Add(tokenId, ctx); - } - ctx.Transfers.Add((from, to, amount)); - } - - var contract = (Cache.Accounts.GetCached(tx.TargetId!.Value) as Contract)!; - ops.Add(tx, (false, contract, tokens)); - } - - foreach (var update in pendingUpdates) - { - var bigmap = pendingBigMaps[update.BigMapPtr]; - var op = update.OriginationId != null - ? origs[update.OriginationId.Value] as ContractOperation - : txs[update.TransactionId!.Value]; - - if (!opBlocks.ContainsKey(op.Level)) - { - var opBlock = Cache.Blocks.GetCached(op.Level); - opBlocks.Add(op.Level, opBlock); - Db.TryAttach(opBlock); - } - - if (!ops.TryGetValue(op, out var opCtx)) - { - var contract = (Cache.Accounts.GetCached(bigmap.ContractId) as Contract)!; - opCtx = (false, contract, []); - ops.Add(op, opCtx); - } - - if (update.Action == BigMapAction.Remove) - { - ops[op] = (true, ops[op].Contract, ops[op].Tokens); - } - else - { - var key = keys[update.BigMapKeyId!.Value]; - - foreach (var (address, tokenId, balance) in BigMaps.ParseLedger(bigmap, key, update)) - { - if (!opCtx.Tokens.TryGetValue(tokenId, out var tokenCtx)) - { - tokenCtx = ([], []); - opCtx.Tokens.Add(tokenId, tokenCtx); - } - tokenCtx.Balances.Add((address, balance)); - } - } - - } - #endregion - } - #endregion - - #region group updates - foreach (var tx in Context.TransactionOps) - { - if (tx.Status == OperationStatus.Applied && tx.Entrypoint == "transfer") - { - var contract = (await Cache.Accounts.GetAsync(tx.TargetId!.Value) as Contract)!; - if (contract.Tags.HasFlag(ContractTags.Ledger)) - { - var tokens = new Dictionary Transfers, - List<(string Address, BigInteger Balance)> Balances - )>(); - - foreach (var (from, to, tokenId, amount) in ParseTransferParam(Micheline.FromBytes(tx.RawParameters!))) - { - if (!tokens.TryGetValue(tokenId, out var ctx)) - { - ctx = ([], []); - tokens.Add(tokenId, ctx); - } - ctx.Transfers.Add((from, to, amount)); - } - - ops.Add(tx, (false, contract, tokens)); - } - } - } - foreach (var (bigmap, key, update, op) in updates) - { - if ((bigmap.Tags & BigMapTag.LedgerTypes) == 0 || update.Action == BigMapAction.Allocate) - continue; - - if (!ops.TryGetValue(op, out var opCtx)) - { - var contract = (await Cache.Accounts.GetAsync( - op is TransactionOperation tx - ? tx.TargetId!.Value - : (op as OriginationOperation)!.ContractId!.Value - ) as Contract)!; - - opCtx = (false, contract, []); - ops.Add(op, opCtx); - } - - if (update.Action == BigMapAction.Remove) - { - ops[op] = (true, ops[op].Contract, ops[op].Tokens); - } - else - { - foreach (var (address, tokenId, balance) in BigMaps.ParseLedger(bigmap, key!, update)) - { - if (!opCtx.Tokens.TryGetValue(tokenId, out var tokenCtx)) - { - tokenCtx = ([], []); - opCtx.Tokens.Add(tokenId, tokenCtx); - } - tokenCtx.Balances.Add((address, balance)); - } - } - } - #endregion - - if (ops.Count == 0) return; - - #region precache - var accountsSet = new HashSet(); - var tokensSet = new HashSet<(int, BigInteger)>(); - var balancesSet = new HashSet<(int, long)>(); - var nftAccountsSet = new HashSet(); - - foreach (var (op, opCtx) in ops) - { - foreach (var (tokenId, tokenCtx) in opCtx.Tokens) - { - foreach (var (from, to, _) in tokenCtx.Transfers) - { - accountsSet.Add(from); - accountsSet.Add(to); - tokensSet.Add((opCtx.Contract.Id, tokenId)); - } - foreach (var (address, _) in tokenCtx.Balances) - { - accountsSet.Add(address); - tokensSet.Add((opCtx.Contract.Id, tokenId)); - } - } - } - - await Cache.Tokens.Preload(tokensSet); - await Cache.Accounts.Preload(accountsSet); - - foreach (var (op, opCtx) in ops) - { - foreach (var (tokenId, tokenCtx) in opCtx.Tokens) - { - foreach (var (from, to, _) in tokenCtx.Transfers) - if (Cache.Tokens.TryGet(opCtx.Contract.Id, tokenId, out var token)) - { - if (Cache.Accounts.TryGetCached(from, out var fromAcc)) - balancesSet.Add((fromAcc.Id, token.Id)); - - if (Cache.Accounts.TryGetCached(to, out var toAcc)) - balancesSet.Add((toAcc.Id, token.Id)); - } - - foreach (var (address, _) in tokenCtx.Balances) - if (Cache.Tokens.TryGet(opCtx.Contract.Id, tokenId, out var token)) - { - if (Cache.Accounts.TryGetCached(address, out var acc)) - balancesSet.Add((acc.Id, token.Id)); - - if (token.OwnerId != null) - { - nftAccountsSet.Add((int)token.OwnerId); - balancesSet.Add(((int)token.OwnerId, token.Id)); - } - } - } - } - - await Cache.Accounts.Preload(nftAccountsSet); - await Cache.TokenBalances.Preload(balancesSet); - #endregion - - foreach (var (op, opCtx) in ops.OrderBy(kv => kv.Key.Id)) - { - if (opCtx.Reset) - { - opBlocks[op.Level].Events |= BlockEvents.Tokens; - await ResetLedgers(op, opCtx.Contract); - } - - foreach (var (tokenId, tokenCtx) in opCtx.Tokens) - { - if (Cache.Tokens.TryGet(opCtx.Contract.Id, tokenId, out var token)) - { - if (token.OwnerId != null && tokenCtx.Balances.Count == 1 && tokenCtx.Balances[0].Balance != BigInteger.Zero) - { - var prevHolder = Cache.Accounts.GetCached((int)token.OwnerId); - if (prevHolder.Address != tokenCtx.Balances[0].Address) - tokenCtx.Balances.Add((prevHolder.Address, BigInteger.Zero)); - } - - if (tokenCtx.Transfers.Count > 0 && ValidateTransfers(token, tokenCtx)) - { - ProcessTransfers(op, opBlocks[op.Level], opCtx.Contract, token, tokenCtx.Transfers); - } - else - { - var diffs = GetDiffs(op, opBlocks[op.Level], token, tokenCtx.Balances); - if (diffs.Count > 0) - { - ProcessDiffs(op, opBlocks[op.Level], opCtx.Contract, token, diffs); - } - } - } - else - { - if (tokenCtx.Transfers.Count > 0 && ValidateTransfers(tokenCtx)) - { - token = GetOrCreateToken(op, opBlocks[op.Level], opCtx.Contract, tokenId); - ProcessTransfers(op, opBlocks[op.Level], opCtx.Contract, token, tokenCtx.Transfers); - } - else - { - var diffs = GetDiffs(op, opBlocks[op.Level], opCtx.Contract, tokenId, tokenCtx.Balances); - if (diffs.Count > 0) - { - token = GetOrCreateToken(op, opBlocks[op.Level], opCtx.Contract, tokenId); - ProcessDiffs(op, opBlocks[op.Level], opCtx.Contract, token, diffs); - } - } - } - } - } - } - - async Task ResetLedgers(ContractOperation op, Contract contract) - { - var tokens = await Db.Tokens - //.AsNoTracking() - .Where(x => x.ContractId == contract.Id) - .ToListAsync(); - var tokenIds = tokens.Select(x => x.Id).ToHashSet(); - - foreach (var token in tokens) - Cache.Tokens.Add(token); - - var tokenBalances = await Db.TokenBalances - .AsNoTracking() - .Where(x => tokenIds.Contains(x.TokenId)) - .ToListAsync(); - - var accountIds = tokenBalances.Select(x => x.AccountId).ToHashSet(); - await Cache.Accounts.Preload(accountIds); - - foreach (var tb in tokenBalances) - { - var tokenBalance = Cache.TokenBalances.GetOrAdd(tb); - if (tokenBalance.Balance == BigInteger.Zero) continue; - var account = Cache.Accounts.GetCached(tokenBalance.AccountId); - var token = Cache.Tokens.Get(tokenBalance.TokenId); - token.LastLevel = op.Level; - MintOrBurnTokens(op, contract, token, account, tokenBalance, -tokenBalance.Balance); - } - } - - bool ValidateTransfers((List<(string, string, BigInteger)> Transfers, List<(string, BigInteger)> Balances) ctx) - { - var dic = new Dictionary(); - foreach (var (from, to, amount) in ctx.Transfers) - { - if (!dic.ContainsKey(from)) - dic.Add(from, BigInteger.Zero); - - if (!dic.ContainsKey(to)) - dic.Add(to, BigInteger.Zero); - - dic[from] -= amount; - dic[to] += amount; - } - foreach (var (address, balance) in ctx.Balances) - { - if (balance != BigInteger.Zero) - { - if (!dic.ContainsKey(address)) - return false; - - dic[address] -= balance; - } - } - return dic.Values.All(x => x == BigInteger.Zero); - } - - bool ValidateTransfers(Token token, (List<(string, string, BigInteger)> Transfers, List<(string, BigInteger)> Balances) ctx) - { - var dic = new Dictionary(); - foreach (var (from, to, amount) in ctx.Transfers) - { - if (!dic.ContainsKey(from)) - dic.Add(from, BigInteger.Zero); - - if (!dic.ContainsKey(to)) - dic.Add(to, BigInteger.Zero); - - dic[from] -= amount; - dic[to] += amount; - } - foreach (var (address, balance) in ctx.Balances) - { - var prevBalance = BigInteger.Zero; - if (Cache.Accounts.TryGetCached(address, out var account) && - Cache.TokenBalances.TryGet(account.Id, token.Id, out var tokenBalance)) - prevBalance = tokenBalance.Balance; - - var diff = balance - prevBalance; - if (diff != BigInteger.Zero) - { - if (!dic.ContainsKey(address)) - return false; - - dic[address] -= diff; - } - } - return dic.Values.All(x => x == BigInteger.Zero); - } - - List<(Account, TokenBalance, BigInteger)> GetDiffs(ContractOperation op, Block block, Contract contract, BigInteger tokenId, List<(string, BigInteger)> balances) - { - var diffs = new List<(Account, TokenBalance, BigInteger Diff)>(balances.Count); - foreach (var (address, balance) in balances) - { - if (balance != BigInteger.Zero) - { - var token = GetOrCreateToken(op, block, contract, tokenId); - var account = GetOrCreateAccount(op, block, address); - var tokenBalance = GetOrCreateTokenBalance(op, block, token, account); - diffs.Add((account, tokenBalance, balance)); - } - } - return diffs; - } - - List<(Account, TokenBalance, BigInteger)> GetDiffs(ContractOperation op, Block block, Token token, List<(string, BigInteger)> balances) - { - var diffs = new List<(Account, TokenBalance, BigInteger Diff)>(balances.Count); - foreach (var (address, balance) in balances) - { - var prevBalance = BigInteger.Zero; - if (Cache.Accounts.TryGetCached(address, out var account) && - Cache.TokenBalances.TryGet(account.Id, token.Id, out var tokenBalance)) - prevBalance = tokenBalance.Balance; - - var diff = balance - prevBalance; - if (diff != BigInteger.Zero) - { - account = GetOrCreateAccount(op, block, address); - tokenBalance = GetOrCreateTokenBalance(op, block, token, account); - diffs.Add((account, tokenBalance, diff)); - } - } - return diffs; - } - - void ProcessTransfers(ContractOperation op, Block block, Contract contract, Token token, List<(string, string, BigInteger)> transfers) - { - Db.TryAttach(token); - token.LastLevel = op.Level; - - block.Events |= BlockEvents.Tokens; - - foreach (var (from, to, amount) in transfers) - { - var fromAcc = GetOrCreateAccount(op, block, from); - var fromBalance = GetOrCreateTokenBalance(op, block, token, fromAcc); - var toAcc = GetOrCreateAccount(op, block, to); - var toBalance = GetOrCreateTokenBalance(op, block, token, toAcc); - TransferTokens(op, contract, token, fromAcc, fromBalance, toAcc, toBalance, amount); - } - } - - void ProcessDiffs(ContractOperation op, Block block, Contract contract, Token token, List<(Account, TokenBalance, BigInteger Diff)> diffs) - { - Db.TryAttach(token); - token.LastLevel = op.Level; - - block.Events |= BlockEvents.Tokens; - - if (diffs.Count == 1 || diffs.BigSum(x => x.Diff) != BigInteger.Zero) - { - foreach (var (account, tokenBalance, diff) in diffs) - MintOrBurnTokens(op, contract, token, account, tokenBalance, diff); - } - else if (diffs.Count(x => x.Diff < BigInteger.Zero) == 1) - { - var (fromAcc, fromBalance, fromDiff) = diffs.First(x => x.Diff < BigInteger.Zero); - foreach (var (toAcc, toBalance, toDiff) in diffs) - { - if (toAcc == fromAcc) continue; - TransferTokens(op, contract, token, fromAcc, fromBalance, toAcc, toBalance, toDiff); - } - } - else if (diffs.Count(x => x.Diff > BigInteger.Zero) == 1) - { - var (toAcc, toBalance, toDiff) = diffs.First(x => x.Diff > BigInteger.Zero); - foreach (var (fromAcc, fromBalance, fromDiff) in diffs) - { - if (fromAcc == toAcc) continue; - TransferTokens(op, contract, token, fromAcc, fromBalance, toAcc, toBalance, -fromDiff); - } - } - else - { - foreach (var (account, tokenBalance, diff) in diffs) - MintOrBurnTokens(op, contract, token, account, tokenBalance, diff); - } - } - - Account GetOrCreateAccount(ContractOperation op, Block block, string address) - { - if (!Cache.Accounts.TryGetCached(address, out var account)) - { - account = address[0] == 't' && address[1] == 'z' - ? new User - { - Id = Cache.AppState.NextAccountId(), - Address = address, - FirstLevel = op.Level, - LastLevel = op.Level, - Type = AccountType.User - } - : new Account - { - Id = Cache.AppState.NextAccountId(), - Address = address, - FirstLevel = op.Level, - LastLevel = op.Level, - Type = AccountType.Ghost - }; - Db.Accounts.Add(account); - Cache.Accounts.Add(account); - - Db.TryAttach(block); - block.Events |= BlockEvents.NewAccounts; - } - return account; - } - - Token GetOrCreateToken(ContractOperation op, Block block, Contract contract, BigInteger tokenId) - { - if (!Cache.Tokens.TryGet(contract.Id, tokenId, out var token)) - { - var state = Cache.AppState.Get(); - state.TokensCount++; - - token = new Token - { - Id = Cache.AppState.NextSubId(op), - ContractId = contract.Id, - TokenId = tokenId, - FirstMinterId = op.InitiatorId ?? op.SenderId, - FirstLevel = op.Level, - LastLevel = op.Level, - TotalBurned = BigInteger.Zero, - TotalMinted = BigInteger.Zero, - TotalSupply = BigInteger.Zero, - Tags = contract.Tags.HasFlag(ContractTags.Nft) - ? TokenTags.Nft - : contract.Tags.HasFlag(ContractTags.FA2) - ? TokenTags.Fa2 - : TokenTags.Fa12, - IndexedAt = op.Level <= state.Level ? state.Level + 1 : null - }; - Db.Tokens.Add(token); - Cache.Tokens.Add(token); - - Db.TryAttach(contract); - contract.TokensCount++; - - Db.TryAttach(block); - block.Events |= BlockEvents.Tokens; - } - return token; - } - - TokenBalance GetOrCreateTokenBalance(ContractOperation op, Block block, Token token, Account account) - { - if (!Cache.TokenBalances.TryGet(account.Id, token.Id, out var tokenBalance)) - { - var state = Cache.AppState.Get(); - state.TokenBalancesCount++; - - tokenBalance = new TokenBalance - { - Id = Cache.AppState.NextSubId(op), - AccountId = account.Id, - TokenId = token.Id, - ContractId = token.ContractId, - FirstLevel = op.Level, - LastLevel = op.Level, - Balance = BigInteger.Zero, - IndexedAt = op.Level <= state.Level ? state.Level + 1 : null - }; - Db.TokenBalances.Add(tokenBalance); - Cache.TokenBalances.Add(tokenBalance); - - Db.TryAttach(token); - token.BalancesCount++; - - Db.TryAttach(account); - account.TokenBalancesCount++; - if (account.FirstLevel > op.Level) - { - account.FirstLevel = op.Level; - block.Events |= BlockEvents.NewAccounts; - } - } - return tokenBalance; - } - - void TransferTokens(ContractOperation op, Contract contract, Token token, - Account from, TokenBalance fromBalance, - Account to, TokenBalance toBalance, - BigInteger amount) - { - op.TokenTransfers = (op.TokenTransfers ?? 0) + 1; - - Db.TryAttach(from); - from.TokenTransfersCount++; - - Db.TryAttach(to); - if (to != from) to.TokenTransfersCount++; - - Db.TryAttach(fromBalance); - fromBalance.Balance -= amount; - fromBalance.TransfersCount++; - fromBalance.LastLevel = op.Level; - - Db.TryAttach(toBalance); - toBalance.Balance += amount; - if (toBalance != fromBalance) toBalance.TransfersCount++; - toBalance.LastLevel = op.Level; - - token.TransfersCount++; - if (amount != BigInteger.Zero && fromBalance.Id != toBalance.Id) - { - if (fromBalance.Balance == BigInteger.Zero) - { - from.ActiveTokensCount--; - token.HoldersCount--; - } - if (toBalance.Balance == amount) - { - to.ActiveTokensCount++; - token.HoldersCount++; - } - if (contract.Tags.HasFlag(ContractTags.Nft)) - token.OwnerId = to.Id; - } - - var state = Cache.AppState.Get(); - state.TokenTransfersCount++; - - Db.TokenTransfers.Add(new TokenTransfer - { - Id = Cache.AppState.NextSubId(op), - Amount = amount, - FromId = from.Id, - ToId = to.Id, - Level = op.Level, - TokenId = token.Id, - ContractId = token.ContractId, - TransactionId = (op as TransactionOperation)?.Id, - OriginationId = (op as OriginationOperation)?.Id, - IndexedAt = op.Level <= state.Level ? state.Level + 1 : null - }); - } - - void MintOrBurnTokens(ContractOperation op, Contract contract, Token token, - Account account, TokenBalance balance, - BigInteger diff) - { - op.TokenTransfers = (op.TokenTransfers ?? 0) + 1; - - Db.TryAttach(account); - account.TokenTransfersCount++; - - Db.TryAttach(balance); - balance.Balance += diff; - balance.TransfersCount++; - balance.LastLevel = op.Level; - - token.TransfersCount++; - if (balance.Balance == BigInteger.Zero) - { - account.ActiveTokensCount--; - token.HoldersCount--; - - if (contract.Tags.HasFlag(ContractTags.Nft)) - token.OwnerId = null; - } - if (balance.Balance == diff) - { - account.ActiveTokensCount++; - token.HoldersCount++; - - if (contract.Tags.HasFlag(ContractTags.Nft)) - token.OwnerId = account.Id; - } - if (diff > 0) token.TotalMinted += diff; - else token.TotalBurned += -diff; - token.TotalSupply += diff; - - var state = Cache.AppState.Get(); - state.TokenTransfersCount++; - - Db.TokenTransfers.Add(new TokenTransfer - { - Id = Cache.AppState.NextSubId(op), - Amount = diff > BigInteger.Zero ? diff : -diff, - FromId = diff < BigInteger.Zero ? account.Id : null, - ToId = diff > BigInteger.Zero ? account.Id : null, - Level = op.Level, - TokenId = token.Id, - ContractId = token.ContractId, - TransactionId = (op as TransactionOperation)?.Id, - OriginationId = (op as OriginationOperation)?.Id, - IndexedAt = op.Level <= state.Level ? state.Level + 1 : null - }); - } - - public virtual async Task Revert(Block block) - { - if (!block.Events.HasFlag(BlockEvents.Tokens)) - return; - - var state = Cache.AppState.Get(); - - var transfers = await Db.TokenTransfers - .AsNoTracking() - .Where(x => x.Level == block.Level) - .OrderByDescending(x => x.Id) - .ToListAsync(); - - #region precache - var accountsSet = new HashSet(); - var tokensSet = new HashSet(); - var tokenBalancesSet = new HashSet<(int, long)>(); - - foreach (var tr in transfers) - tokensSet.Add(tr.TokenId); - - await Cache.Tokens.Preload(tokensSet); - - foreach (var tr in transfers) - { - if (tr.FromId is int fromId) - { - accountsSet.Add(fromId); - tokenBalancesSet.Add((fromId, tr.TokenId)); - } - - if (tr.ToId is int toId) - { - accountsSet.Add(toId); - tokenBalancesSet.Add((toId, tr.TokenId)); - } - } - - foreach (var id in tokensSet) - { - var token = Cache.Tokens.Get(id); - accountsSet.Add(token.ContractId); - } - - await Cache.Accounts.Preload(accountsSet); - await Cache.TokenBalances.Preload(tokenBalancesSet); - #endregion - - var tokensToRemove = new HashSet(); - var tokenBalancesToRemove = new HashSet(); - - foreach (var transfer in transfers) - { - var token = Cache.Tokens.Get(transfer.TokenId); - var contract = (Contract)Cache.Accounts.GetCached(token.ContractId); - Db.TryAttach(token); - token.LastLevel = block.Level; - if (token.FirstLevel == block.Level) - tokensToRemove.Add(token); - - if (transfer.FromId is int fromId && transfer.ToId is int toId) - { - #region revert transfer - var from = Cache.Accounts.GetCached(fromId); - var to = Cache.Accounts.GetCached(toId); - var fromBalance = Cache.TokenBalances.Get(from.Id, token.Id); - var toBalance = Cache.TokenBalances.Get(to.Id, token.Id); - - Db.TryAttach(from); - Db.TryAttach(to); - Db.TryAttach(fromBalance); - Db.TryAttach(toBalance); - - from.TokenTransfersCount--; - if (to != from) to.TokenTransfersCount--; - - fromBalance.Balance += transfer.Amount; - fromBalance.TransfersCount--; - fromBalance.LastLevel = block.Level; - if (fromBalance.FirstLevel == block.Level) - tokenBalancesToRemove.Add(fromBalance); - - toBalance.Balance -= transfer.Amount; - if (toBalance != fromBalance) toBalance.TransfersCount--; - toBalance.LastLevel = block.Level; - if (toBalance.FirstLevel == block.Level) - tokenBalancesToRemove.Add(toBalance); - - token.TransfersCount--; - if (transfer.Amount != BigInteger.Zero && fromBalance.Id != toBalance.Id) - { - if (fromBalance.Balance == transfer.Amount) - { - from.ActiveTokensCount++; - token.HoldersCount++; - } - if (toBalance.Balance == BigInteger.Zero) - { - to.ActiveTokensCount--; - token.HoldersCount--; - } - - if (contract.Tags.HasFlag(ContractTags.Nft)) - token.OwnerId = from.Id; - } - - state.TokenTransfersCount--; - #endregion - } - else if (transfer.ToId != null) - { - #region revert mint - var to = Cache.Accounts.GetCached((int)transfer.ToId); - var toBalance = Cache.TokenBalances.Get(to.Id, token.Id); - - Db.TryAttach(to); - Db.TryAttach(toBalance); - - to.TokenTransfersCount--; - - toBalance.Balance -= transfer.Amount; - toBalance.TransfersCount--; - toBalance.LastLevel = block.Level; - if (toBalance.FirstLevel == block.Level) - tokenBalancesToRemove.Add(toBalance); - - token.TransfersCount--; - if (transfer.Amount != BigInteger.Zero) - { - if (toBalance.Balance == BigInteger.Zero) - { - to.ActiveTokensCount--; - token.HoldersCount--; - } - - if (contract.Tags.HasFlag(ContractTags.Nft)) - token.OwnerId = null; - - token.TotalMinted -= transfer.Amount; - token.TotalSupply -= transfer.Amount; - } - - state.TokenTransfersCount--; - #endregion - } - else - { - #region revert burn - var from = Cache.Accounts.GetCached(transfer.FromId!.Value); - var fromBalance = Cache.TokenBalances.Get(from.Id, token.Id); - - Db.TryAttach(from); - Db.TryAttach(fromBalance); - - from.TokenTransfersCount--; - - fromBalance.Balance += transfer.Amount; - fromBalance.TransfersCount--; - fromBalance.LastLevel = block.Level; - if (fromBalance.FirstLevel == block.Level) - tokenBalancesToRemove.Add(fromBalance); - - token.TransfersCount--; - if (transfer.Amount != BigInteger.Zero) - { - if (fromBalance.Balance == transfer.Amount) - { - from.ActiveTokensCount++; - token.HoldersCount++; - } - - if (contract.Tags.HasFlag(ContractTags.Nft)) - token.OwnerId = from.Id; - - token.TotalBurned -= transfer.Amount; - token.TotalSupply += transfer.Amount; - } - - state.TokenTransfersCount--; - #endregion - } - } - - foreach (var tokenBalance in tokenBalancesToRemove) - { - if (tokenBalance.FirstLevel == block.Level) - { - Db.TokenBalances.Remove(tokenBalance); - Cache.TokenBalances.Remove(tokenBalance); - - var t = Cache.Tokens.Get(tokenBalance.TokenId); - Db.TryAttach(t); - t.BalancesCount--; - - var a = Cache.Accounts.GetCached(tokenBalance.AccountId); - Db.TryAttach(a); - a.TokenBalancesCount--; - - state.TokenBalancesCount--; - } - } - - foreach (var token in tokensToRemove) - { - if (token.FirstLevel == block.Level) - { - Db.Tokens.Remove(token); - Cache.Tokens.Remove(token); - - var c = (Contract)Cache.Accounts.GetCached(token.ContractId); - Db.TryAttach(c); - c.TokensCount--; - - state.TokensCount--; - } - } - - await Db.Database.ExecuteSqlRawAsync(""" - DELETE FROM "TokenTransfers" - WHERE "Level" = {0} - """, block.Level); - } - - static List<(string, string, BigInteger, BigInteger)> ParseTransferParam(IMicheline micheline) - { - var transfers = new List<(string, string, BigInteger, BigInteger)>(); - if (micheline is MichelineArray arr) - { - foreach (var transfer in arr) - { - var transferPair = (transfer as MichelinePrim)!; - var from = transferPair.Args![0].ParseAddress(); - foreach (var tx in (transferPair.Args[1] as MichelineArray)!) - { - var txPair = (tx as MichelinePrim)!; - var to = txPair.Args![0].ParseAddress(); - var txPair2 = (txPair.Args[1] as MichelinePrim)!; - var tokenId = (txPair2.Args![0] as MichelineInt)!.Value; - var amount = (txPair2.Args[1] as MichelineInt)!.Value; - - transfers.Add((from, to, tokenId, amount)); - } - } - } - else if (micheline is MichelinePrim pair) - { - var from = pair.Args![0].ParseAddress(); - var pair2 = (pair.Args[1] as MichelinePrim)!; - var to = pair2.Args![0].ParseAddress(); - var value = (pair2.Args[1] as MichelineInt)!.Value; - - transfers.Add((from, to, BigInteger.Zero, value)); - } - return transfers; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/VotingCommit.cs deleted file mode 100644 index 0a12a51fe..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Commits/VotingCommit.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class VotingCommit(ProtocolHandler protocol) : Proto1.VotingCommit(protocol) - { - protected override int GetParticipationEma(VotingPeriod period, Protocol proto) - { - var prev = Db.VotingPeriods - .AsNoTracking() - .OrderByDescending(x => x.Index) - .FirstOrDefault(x => x.Kind == PeriodKind.Exploration || x.Kind == PeriodKind.Promotion); - - if (prev != null) - { - var participation = 10000.MulRatio(prev.YayVotingPower!.Value + prev.NayVotingPower!.Value + prev.PassVotingPower!.Value, prev.TotalVotingPower); - return (int)((prev.ParticipationEma!.Value * 8000 + participation * 2000) / 10000); - } - - return proto.BallotQuorumMax; - } - - protected override int GetBallotQuorum(VotingPeriod period, Protocol proto) - { - return proto.BallotQuorumMin + period.ParticipationEma!.Value * (proto.BallotQuorumMax - proto.BallotQuorumMin) / 10000; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Diagnostics/Diagnostics.cs deleted file mode 100644 index 1802e9b8b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class Diagnostics(ProtocolHandler handler) : Proto1.Diagnostics(handler) - { - protected override void TestDelegatorsCount(JsonElement remote, Data.Models.Delegate local) - { - var delegators = remote.RequiredArray("delegated_contracts").Count(); - - if (delegators != local.DelegatorsCount && delegators != local.DelegatorsCount + 1) - throw new Exception($"Diagnostics failed: wrong delegators count {local.Address}"); - } - - protected override void TestAccountDelegate(JsonElement remote, Account local) - { - if (local.Type == AccountType.Delegate) - return; - - var delegat = Cache.Accounts.GetDelegateOrDefault(local.DelegateId); - if (delegat?.Address != remote.OptionalString("delegate")) - throw new Exception($"Diagnostics failed: wrong delegate {local.Address}"); - } - - protected override void TestAccountCounter(JsonElement remote, Account local) - { - if (local.Type == AccountType.Contract) return; - - if (remote.RequiredInt64("balance") > 0 && remote.RequiredInt32("counter") != local.Counter) - throw new Exception($"Diagnostics failed: wrong counter {local.Address}"); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Helpers.cs deleted file mode 100644 index 018861de2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Proto5Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Proto5Handler.cs deleted file mode 100644 index 0def10697..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Proto5Handler.cs +++ /dev/null @@ -1,281 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto5; - -namespace Tzkt.Sync.Protocols -{ - class Proto5Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "babylon_005"; - public override int VersionNumber => 5; - - public Proto5Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - await new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - await new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Rpc/Rpc.cs deleted file mode 100644 index 8a451d56c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto5 -{ - class Rpc : Proto1.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto5/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto5/Validation/Validator.cs deleted file mode 100644 index 1b8b2ef33..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto5/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto5 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Activation/ProtoActivator.cs deleted file mode 100644 index 8c7a02873..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Activation/ProtoActivator.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto6 -{ - class ProtoActivator : Proto5.ProtoActivator - { - public ProtoActivator(ProtocolHandler proto) : base(proto) { } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - var br = parameters["baking_reward_per_endorsement"] as JArray; - var ar = parameters["endorsement_reward"] as JArray; - - protocol.RampUpCycles = parameters["security_deposit_ramp_up_cycles"]?.Value() ?? 0; - protocol.NoRewardCycles = parameters["no_reward_cycles"]?.Value() ?? 0; - protocol.BlockDeposit = parameters["block_security_deposit"]?.Value() ?? 512_000_000; - protocol.BlockReward0 = br == null ? 1_250_000 : br.Count > 0 ? br[0].Value() : 0; - protocol.BlockReward1 = br == null ? 187_500 : br.Count > 1 ? br[1].Value() : protocol.BlockReward0; - protocol.BlocksPerCommitment = parameters["blocks_per_commitment"]?.Value() ?? 32; - protocol.BlocksPerCycle = parameters["blocks_per_cycle"]?.Value() ?? 4096; - protocol.BlocksPerSnapshot = parameters["blocks_per_roll_snapshot"]?.Value() ?? 256; - protocol.BlocksPerVoting = parameters["blocks_per_voting_period"]?.Value() ?? 32_768; - protocol.ByteCost = parameters["cost_per_byte"]?.Value() ?? 1000; - protocol.AttestationDeposit = parameters["endorsement_security_deposit"]?.Value() ?? 64_000_000; - protocol.AttestationReward0 = ar == null ? 1_250_000 : ar.Count > 0 ? ar[0].Value() : 0; - protocol.AttestationReward1 = ar == null ? 833_333 : ar.Count > 1 ? ar[1].Value() : protocol.AttestationReward0; - protocol.AttestersPerBlock = parameters["endorsers_per_block"]?.Value() ?? 32; - protocol.HardBlockGasLimit = parameters["hard_gas_limit_per_block"]?.Value() ?? 10_400_000; - protocol.HardOperationGasLimit = parameters["hard_gas_limit_per_operation"]?.Value() ?? 1_040_000; - protocol.HardOperationStorageLimit = parameters["hard_storage_limit_per_operation"]?.Value() ?? 60_000; - protocol.OriginationSize = parameters["origination_size"]?.Value() ?? 257; - protocol.ConsensusRightsDelay = parameters["preserved_cycles"]?.Value() ?? 5; - protocol.ToleratedInactivityPeriod = protocol.ConsensusRightsDelay + 1; - protocol.TimeBetweenBlocks = parameters["time_between_blocks"]?[0]!.Value() ?? 60; - protocol.MinimalStake = parameters["tokens_per_roll"]?.Value() ?? 8_000_000_000; - protocol.BallotQuorumMin = parameters["quorum_min"]?.Value() ?? 2000; - protocol.BallotQuorumMax = parameters["quorum_max"]?.Value() ?? 7000; - protocol.ProposalQuorum = parameters["min_proposal_quorum"]?.Value() ?? 500; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.BlockReward0 = 1_250_000; - protocol.BlockReward1 = 187_500; - protocol.AttestationReward0 = 1_250_000; - protocol.AttestationReward1 = 833_333; - protocol.HardBlockGasLimit = 10_400_000; - protocol.HardOperationGasLimit = 1_040_000; - } - - protected override long GetFutureBlockReward(Protocol protocol, int cycle) - => cycle < protocol.NoRewardCycles ? 0 : (protocol.BlockReward0 * protocol.AttestersPerBlock); - - protected override long GetFutureAttestationReward(Protocol protocol, int cycle, int slots) - => cycle < protocol.NoRewardCycles ? 0 : (slots * protocol.AttestationReward0); - - // migrate baker cycles - - protected override async Task MigrateContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "BakerCycles" - SET "FutureBlockRewards" = "FutureBlocks" * 40000000 :: bigint, - "FutureAttestationRewards" = "FutureAttestations" * 1250000 :: bigint - WHERE "Cycle" > {0}; - """, block.Cycle); - } - - protected override async Task RevertContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - - await Db.Database.ExecuteSqlRawAsync(""" - UPDATE "BakerCycles" - SET "FutureBlockRewards" = "FutureBlocks" * 16000000 :: bigint, - "FutureAttestationRewards" = "FutureAttestations" * 2000000 :: bigint - WHERE "Cycle" > {0}; - """, block.Cycle); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BakerCycleCommit.cs deleted file mode 100644 index e202ebc23..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto6 -{ - class BakerCycleCommit(ProtocolHandler protocol) : Proto5.BakerCycleCommit(protocol) - { - protected override long GetFutureBlockReward(Protocol protocol, int cycle) - => cycle < protocol.NoRewardCycles ? 0 : (protocol.BlockReward0 * protocol.AttestersPerBlock); - - protected override long GetBlockReward(Protocol protocol, int cycle, int priority, long slots) - => cycle < protocol.NoRewardCycles ? 0 : ((priority == 0 ? protocol.BlockReward0 : protocol.BlockReward1) * slots); - - protected override long GetFutureAttestationReward(Protocol protocol, int cycle, long slots) - => cycle < protocol.NoRewardCycles ? 0 : (slots * protocol.AttestationReward0); - - protected override long GetAttestationReward(Protocol protocol, int cycle, int slots, int priority) - => cycle < protocol.NoRewardCycles ? 0 : ((priority == 0 ? protocol.AttestationReward0 : protocol.AttestationReward1) * slots); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BakingRightsCommit.cs deleted file mode 100644 index 3e765cf21..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class BakingRightsCommit : Proto3.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BigMapCommit.cs deleted file mode 100644 index 332965ad8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BigMapCommit.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Netezos.Contracts; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto6 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override BigMapTag GetTags(Contract contract, TreeView node) - { - var tags = base.GetTags(contract, node); - - // custom handler for tzBTC - if (contract.Address == "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn") - tags |= BigMapTag.Ledger7; - - return tags; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BlockCommit.cs deleted file mode 100644 index 851421e10..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class BlockCommit : Proto1.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/CycleCommit.cs deleted file mode 100644 index 9b0f4509c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/DeactivationCommit.cs deleted file mode 100644 index 2dc1a2f24..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 22e89a9e8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/FreezerCommit.cs deleted file mode 100644 index 34de6dae5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/FreezerCommit.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto6 -{ - class FreezerCommit : Proto4.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override IEnumerable GetFreezerUpdates(Block block, Protocol protocol, JsonElement rawBlock) - { - return rawBlock - .Required("metadata") - .Required("balance_updates") - .EnumerateArray() - .Where(x => x.RequiredString("kind")[0] == 'f' && - x.RequiredInt64("change") < 0 && - GetFreezerCycle(x) == block.Cycle - protocol.ConsensusRightsDelay); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 05736f4ca..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 4ec2cd985..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 6f10baadb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 0cc1f5c95..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 9f8edaa79..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 1b8e6058e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class DoubleConsensusCommit : Proto4.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index c32fafc02..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index aa45b3c70..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class OriginationsCommit : Proto5.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 615269aa6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index d3186e9db..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 8a273bded..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class TransactionsCommit : Proto5.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index 57c710252..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Linq; -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto6 -{ - class RevelationPenaltyCommit : Proto4.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override bool HasPenaltiesUpdates(Block block, Protocol protocol, JsonElement rawBlock) - { - return rawBlock - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .Any(x => x.RequiredString("kind")[0] == 'f' && - x.RequiredInt64("change") < 0 && - GetFreezerCycle(x) != block.Cycle - protocol.ConsensusRightsDelay); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 2b13ffb39..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class SnapshotBalanceCommit : Proto4.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/SoftwareCommit.cs deleted file mode 100644 index 4753d2d8d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/StateCommit.cs deleted file mode 100644 index 67ec429be..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/StatisticsCommit.cs deleted file mode 100644 index ff4615521..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/TokensCommit.cs deleted file mode 100644 index 400ed9ce1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/VotingCommit.cs deleted file mode 100644 index 1a5f55a94..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class VotingCommit : Proto5.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Diagnostics/Diagnostics.cs deleted file mode 100644 index 470c22e60..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class Diagnostics : Proto5.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Helpers.cs deleted file mode 100644 index 211925d7b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Proto6Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Proto6Handler.cs deleted file mode 100644 index e2664d751..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Proto6Handler.cs +++ /dev/null @@ -1,281 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto6; - -namespace Tzkt.Sync.Protocols -{ - class Proto6Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "carthage_006"; - public override int VersionNumber => 6; - - public Proto6Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - await new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - await new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Rpc/Rpc.cs deleted file mode 100644 index 604a0bb3a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Rpc/Rpc.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json; -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto6 -{ - class Rpc : Proto1.Rpc - { - public Rpc(TezosNode node) : base(node) { } - - public override Task GetBakingRightsAsync(int block, int cycle) - => Node.GetAsync($"chains/main/blocks/{block}/helpers/baking_rights?cycle={cycle}&max_priority=7&all=true"); - - public override Task GetLevelBakingRightsAsync(int block, int level, int maxRound) - => Node.GetAsync($"chains/main/blocks/{block}/helpers/baking_rights?level={level}&max_priority={maxRound}&all=true"); - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto6/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto6/Validation/Validator.cs deleted file mode 100644 index 869d45d5e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto6/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto6 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Activation/ProtoActivator.cs deleted file mode 100644 index 950099962..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Activation/ProtoActivator.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto7 -{ - class ProtoActivator : Proto6.ProtoActivator - { - public ProtoActivator(ProtocolHandler proto) : base(proto) { } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.ByteCost = parameters["cost_per_byte"]?.Value() ?? 250; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.ByteCost = 250; - } - - protected override Task MigrateContext(AppState state) => Task.CompletedTask; - protected override Task RevertContext(AppState state) => Task.CompletedTask; - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BakerCycleCommit.cs deleted file mode 100644 index b16a0c545..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class BakerCycleCommit : Proto6.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BakingRightsCommit.cs deleted file mode 100644 index 96c7f3af2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class BakingRightsCommit : Proto3.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BigMapCommit.cs deleted file mode 100644 index 53349bc35..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BlockCommit.cs deleted file mode 100644 index f23432ebe..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class BlockCommit : Proto1.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/CycleCommit.cs deleted file mode 100644 index 15993b2b4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/DeactivationCommit.cs deleted file mode 100644 index 77ac8f57b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 052847e71..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/FreezerCommit.cs deleted file mode 100644 index 0316592d8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class FreezerCommit : Proto6.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 40004e6bb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 4394337b2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 94c63dbd8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index f0fe6dff5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index ddc357fad..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 42933afc5..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class DoubleConsensusCommit : Proto4.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index daa85ca27..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index f1b39cbc8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class OriginationsCommit : Proto5.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index bc724561c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index be5d23b43..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 955c7be05..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class TransactionsCommit : Proto5.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index 88fb49bbb..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class RevelationPenaltyCommit : Proto6.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index d9d09ea26..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class SnapshotBalanceCommit : Proto4.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/SoftwareCommit.cs deleted file mode 100644 index 90732896a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/StateCommit.cs deleted file mode 100644 index 804441183..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/StatisticsCommit.cs deleted file mode 100644 index de7775e75..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/TokensCommit.cs deleted file mode 100644 index d005df035..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/VotingCommit.cs deleted file mode 100644 index cb463ac31..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class VotingCommit : Proto5.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Diagnostics/Diagnostics.cs deleted file mode 100644 index adadcb537..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class Diagnostics : Proto5.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Helpers.cs deleted file mode 100644 index d4aa17368..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Proto7Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Proto7Handler.cs deleted file mode 100644 index a426e954e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Proto7Handler.cs +++ /dev/null @@ -1,281 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto7; - -namespace Tzkt.Sync.Protocols -{ - class Proto7Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "delphi_007"; - public override int VersionNumber => 7; - - public Proto7Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - await new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - await new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Rpc/Rpc.cs deleted file mode 100644 index dfb0f9158..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto7 -{ - class Rpc : Proto6.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto7/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto7/Validation/Validator.cs deleted file mode 100644 index 892c06fe2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto7/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto7 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Activation/ProtoActivator.cs deleted file mode 100644 index 591a9172f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Activation/ProtoActivator.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Newtonsoft.Json.Linq; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto8 -{ - class ProtoActivator : Proto7.ProtoActivator - { - public ProtoActivator(ProtocolHandler proto) : base(proto) { } - - protected override void SetParameters(Protocol protocol, JToken parameters) - { - base.SetParameters(protocol, parameters); - protocol.BlocksPerVoting = parameters["blocks_per_voting_period"]?.Value() ?? 20_480; - } - - protected override void UpgradeParameters(Protocol protocol, Protocol prev) - { - protocol.BlocksPerVoting = 20_480; - } - - protected override async Task MigrateContext(AppState state) - { - - var prevPeriod = await Cache.Periods.GetAsync(state.VotingPeriod - 1); - Db.TryAttach(prevPeriod); - prevPeriod.LastLevel -= 1; - - var newPeriod = await Cache.Periods.GetAsync(state.VotingPeriod); - Db.TryAttach(newPeriod); - newPeriod.FirstLevel -= 1; - newPeriod.LastLevel = newPeriod.FirstLevel + 20_479; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BakerCycleCommit.cs deleted file mode 100644 index 0c5f9d544..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class BakerCycleCommit : Proto6.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BakingRightsCommit.cs deleted file mode 100644 index 771f97b2a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class BakingRightsCommit : Proto3.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BigMapCommit.cs deleted file mode 100644 index cc653ba4a..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BigMapCommit.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Netezos.Contracts; -using Netezos.Encoding; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto8 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override BigMapTag GetTags(Contract contract, TreeView node) - { - var tags = base.GetTags(contract, node); - - // custom handler for Tezos Domains - if (contract.Address == "KT1GBZmSxmnKJXGMdMLbugPfLyUPmuLSMwKS" && - (node.Value as MichelineInt)!.Value == 1264) // %records - tags |= BigMapTag.Ledger12; - - return tags; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BlockCommit.cs deleted file mode 100644 index 24e9b26a0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/BlockCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class BlockCommit : Proto1.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/CycleCommit.cs deleted file mode 100644 index c8d9fdd2e..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/DeactivationCommit.cs deleted file mode 100644 index e59db6d64..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 30021ea6c..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/FreezerCommit.cs deleted file mode 100644 index 2ffdcef63..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/FreezerCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class FreezerCommit : Proto6.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index d2efef90b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index 39012c73b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 2f9713473..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index 3847e99c4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 306aa146b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index 0490ec483..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class DoubleConsensusCommit : Proto4.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 003a2fd65..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index b5ac54873..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class OriginationsCommit : Proto5.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 98d0766c1..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index bc429b110..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 31ce02dce..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class TransactionsCommit : Proto5.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index 91b85d6da..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class RevelationPenaltyCommit : Proto6.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 3b6631189..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class SnapshotBalanceCommit : Proto4.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/SoftwareCommit.cs deleted file mode 100644 index db7156f68..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/StateCommit.cs deleted file mode 100644 index 6f670dc78..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/StatisticsCommit.cs deleted file mode 100644 index 2b82889de..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/TokensCommit.cs deleted file mode 100644 index 59959b2fa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/VotingCommit.cs deleted file mode 100644 index 22e16e8e9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Commits/VotingCommit.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto8 -{ - class VotingCommit(ProtocolHandler protocol) : Proto5.VotingCommit(protocol) - { - // new voting period - protected override ProposalStatus GetProposalStatus(Proposal proposal, VotingPeriod period) - { - if (period.Status == PeriodStatus.Success) - return period.Kind == PeriodKind.Adoption - ? ProposalStatus.Accepted - : ProposalStatus.Active; - - if (period.Status == PeriodStatus.NoSupermajority) - return ProposalStatus.Rejected; - - return ProposalStatus.Skipped; - } - - // new voting period - protected override VotingPeriod StartNextPeriod(Block block, Protocol protocol, VotingPeriod current) - { - return current.Kind switch - { - PeriodKind.Proposal => StartBallotPeriod(block, protocol, current, PeriodKind.Exploration), - PeriodKind.Exploration => StartWaitingPeriod(block, protocol, current, PeriodKind.Testing), - PeriodKind.Testing => StartBallotPeriod(block, protocol, current, PeriodKind.Promotion), - PeriodKind.Promotion => StartWaitingPeriod(block, protocol, current, PeriodKind.Adoption), - PeriodKind.Adoption => StartProposalPeriod(block, protocol, current), - _ => throw new Exception("Invalid voting period kind") - }; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Diagnostics/Diagnostics.cs deleted file mode 100644 index 10b1dabc9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class Diagnostics : Proto5.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Helpers.cs deleted file mode 100644 index 8d8761b12..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Proto8Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Proto8Handler.cs deleted file mode 100644 index 457f8c183..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Proto8Handler.cs +++ /dev/null @@ -1,281 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto8; - -namespace Tzkt.Sync.Protocols -{ - class Proto8Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "edo_008"; - public override int VersionNumber => 8; - - public Proto8Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - await new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - await new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Rpc/Rpc.cs deleted file mode 100644 index 377abfdb8..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto8 -{ - class Rpc : Proto6.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto8/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto8/Validation/Validator.cs deleted file mode 100644 index abff3b5ef..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto8/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto8 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Activation/ProtoActivator.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Activation/ProtoActivator.cs deleted file mode 100644 index 256562a6b..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Activation/ProtoActivator.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto9 -{ - class ProtoActivator(ProtocolHandler proto) : Proto8.ProtoActivator(proto) - { - // Proposal invoice - - protected override async Task MigrateContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(block); - - var account = (await Cache.Accounts.GetAsync("tz1abmz7jiCV2GH2u81LRrGgAFFgvQgiDiaf"))!; - Db.TryAttach(account); - Receive(account, 100_000_000); - account.MigrationsCount++; - account.LastLevel = block.Level; - - block.Operations |= Operations.Migrations; - - var migration = new MigrationOperation - { - Id = Cache.AppState.NextOperationId(), - Level = block.Level, - Timestamp = block.Timestamp, - AccountId = account.Id, - Kind = MigrationKind.ProposalInvoice, - BalanceChange = 100_000_000 - }; - Db.MigrationOps.Add(migration); - Context.MigrationOps.Add(migration); - - Db.TryAttach(state); - state.MigrationOpsCount++; - - var stats = Cache.Statistics.Current; - Db.TryAttach(stats); - stats.TotalCreated += 100_000_000; - } - - protected override async Task RevertContext(AppState state) - { - var block = await Cache.Blocks.CurrentAsync(); - - var invoice = await Db.MigrationOps - .AsNoTracking() - .FirstAsync(x => x.Level == block.Level && x.Kind == MigrationKind.ProposalInvoice); - - var account = await Cache.Accounts.GetAsync(invoice.AccountId); - Db.TryAttach(account); - RevertReceive(account, 100_000_000); - account.MigrationsCount--; - - Db.MigrationOps.Remove(invoice); - Cache.AppState.ReleaseOperationId(); - - state.MigrationOpsCount--; - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BakerCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BakerCycleCommit.cs deleted file mode 100644 index 002756b85..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BakerCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class BakerCycleCommit : Proto6.BakerCycleCommit - { - public BakerCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BakingRightsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BakingRightsCommit.cs deleted file mode 100644 index 9df6d1944..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BakingRightsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class BakingRightsCommit : Proto3.BakingRightsCommit - { - public BakingRightsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BigMapCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BigMapCommit.cs deleted file mode 100644 index 825cee6ca..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BigMapCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class BigMapCommit : Proto1.BigMapCommit - { - public BigMapCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BlockCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BlockCommit.cs deleted file mode 100644 index 193fb0d13..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/BlockCommit.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Linq; -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto9 -{ - class BlockCommit : Proto1.BlockCommit - { - public BlockCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override (long, long) ParseBalanceUpdates(JsonElement balanceUpdates) - { - var deposit = 0L; - var reward = 0L; - foreach (var bu in balanceUpdates.EnumerateArray().Where(x => x.RequiredString("origin")[0] == 'b').Take(3)) - { - if (bu.RequiredString("kind")[0] == 'f') - { - var change = bu.RequiredInt64("change"); - if (change > 0) - { - if (bu.RequiredString("category")[0] == 'd') - deposit = change; - else - reward = change; - } - - } - } - return (deposit, reward); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/CycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/CycleCommit.cs deleted file mode 100644 index 56f35a7cc..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/CycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class CycleCommit : Proto1.CycleCommit - { - public CycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/DeactivationCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/DeactivationCommit.cs deleted file mode 100644 index 0e140ed91..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/DeactivationCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class DeactivationCommit : Proto2.DeactivationCommit - { - public DeactivationCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/DelegatorCycleCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/DelegatorCycleCommit.cs deleted file mode 100644 index 9fb31a910..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/DelegatorCycleCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class DelegatorCycleCommit : Proto3.DelegatorCycleCommit - { - public DelegatorCycleCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/FreezerCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/FreezerCommit.cs deleted file mode 100644 index 7132d16e9..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/FreezerCommit.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto9 -{ - class FreezerCommit : Proto6.FreezerCommit - { - public FreezerCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override IEnumerable GetFreezerUpdates(Block block, Protocol protocol, JsonElement rawBlock) - { - return rawBlock - .Required("metadata") - .Required("balance_updates") - .EnumerateArray() - .Where(x => x.RequiredString("origin")[0] == 'b' && - x.RequiredString("kind")[0] == 'f' && - x.RequiredInt64("change") < 0 && - GetFreezerCycle(x) == block.Cycle - protocol.ConsensusRightsDelay); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/ActivationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/ActivationsCommit.cs deleted file mode 100644 index 46e7287fa..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/ActivationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class ActivationsCommit : Proto1.ActivationsCommit - { - public ActivationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/AttestationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/AttestationsCommit.cs deleted file mode 100644 index a6e2763da..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/AttestationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class AttestationsCommit : Proto1.AttestationsCommit - { - public AttestationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/BallotsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/BallotsCommit.cs deleted file mode 100644 index 421805085..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/BallotsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class BallotsCommit : Proto3.BallotsCommit - { - public BallotsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DelegationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DelegationsCommit.cs deleted file mode 100644 index ddb7a644f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DelegationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class DelegationsCommit : Proto1.DelegationsCommit - { - public DelegationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DoubleBakingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DoubleBakingCommit.cs deleted file mode 100644 index 0efc94ae7..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DoubleBakingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class DoubleBakingCommit : Proto2.DoubleBakingCommit - { - public DoubleBakingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DoubleConsensusCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DoubleConsensusCommit.cs deleted file mode 100644 index d3c37b991..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/DoubleConsensusCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class DoubleConsensusCommit : Proto4.DoubleConsensusCommit - { - public DoubleConsensusCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/NonceRevelationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/NonceRevelationsCommit.cs deleted file mode 100644 index 59628e229..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/NonceRevelationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class NonceRevelationsCommit : Proto1.NonceRevelationsCommit - { - public NonceRevelationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/OriginationsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/OriginationsCommit.cs deleted file mode 100644 index 1b284a2a2..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/OriginationsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class OriginationsCommit : Proto5.OriginationsCommit - { - public OriginationsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/ProposalsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/ProposalsCommit.cs deleted file mode 100644 index 1fb58eb92..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/ProposalsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class ProposalsCommit : Proto3.ProposalsCommit - { - public ProposalsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/RevealsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/RevealsCommit.cs deleted file mode 100644 index 599b3e807..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/RevealsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class RevealsCommit : Proto1.RevealsCommit - { - public RevealsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/TransactionsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/TransactionsCommit.cs deleted file mode 100644 index 3969232a6..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/Operations/TransactionsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class TransactionsCommit : Proto5.TransactionsCommit - { - public TransactionsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/RevelationPenaltyCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/RevelationPenaltyCommit.cs deleted file mode 100644 index fe0e66b20..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/RevelationPenaltyCommit.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Linq; -using System.Text.Json; -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols.Proto9 -{ - class RevelationPenaltyCommit : Proto6.RevelationPenaltyCommit - { - public RevelationPenaltyCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override bool HasPenaltiesUpdates(Block block, Protocol protocol, JsonElement rawBlock) - { - return rawBlock - .Required("metadata") - .RequiredArray("balance_updates") - .EnumerateArray() - .Any(x => x.RequiredString("origin")[0] == 'b' && - x.RequiredString("kind")[0] == 'f' && - x.RequiredInt64("change") < 0 && - GetFreezerCycle(x) != block.Cycle - protocol.ConsensusRightsDelay); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/SnapshotBalanceCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/SnapshotBalanceCommit.cs deleted file mode 100644 index 867d3ab5d..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/SnapshotBalanceCommit.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.Json; - -namespace Tzkt.Sync.Protocols.Proto9 -{ - class SnapshotBalanceCommit : Proto4.SnapshotBalanceCommit - { - public SnapshotBalanceCommit(ProtocolHandler protocol) : base(protocol) { } - - protected override IEnumerable GetBalanceUpdates(JsonElement rawBlock) - { - return rawBlock - .GetProperty("metadata") - .GetProperty("balance_updates") - .EnumerateArray() - .Where(x => x.RequiredString("origin")[0] == 'b'); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/SoftwareCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/SoftwareCommit.cs deleted file mode 100644 index f0fa8a865..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/SoftwareCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class SoftwareCommit : Proto5.SoftwareCommit - { - public SoftwareCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/StateCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/StateCommit.cs deleted file mode 100644 index 554a28925..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/StateCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class StateCommit : Proto1.StateCommit - { - public StateCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/StatisticsCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/StatisticsCommit.cs deleted file mode 100644 index 4592b4349..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/StatisticsCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class StatisticsCommit : Proto1.StatisticsCommit - { - public StatisticsCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/TokensCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/TokensCommit.cs deleted file mode 100644 index 60aaa5c01..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/TokensCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class TokensCommit : Proto5.TokensCommit - { - public TokensCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/VotingCommit.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/VotingCommit.cs deleted file mode 100644 index 44f1d63e0..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Commits/VotingCommit.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class VotingCommit : Proto8.VotingCommit - { - public VotingCommit(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Diagnostics/Diagnostics.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Diagnostics/Diagnostics.cs deleted file mode 100644 index 9edb529db..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Diagnostics/Diagnostics.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class Diagnostics : Proto5.Diagnostics - { - public Diagnostics(ProtocolHandler handler) : base(handler) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Helpers.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Helpers.cs deleted file mode 100644 index 0c81f9169..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Helpers.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - public class Helpers(ProtocolHandler proto) : Proto1.Helpers(proto) { } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Proto9Handler.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Proto9Handler.cs deleted file mode 100644 index 9cbaf659f..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Proto9Handler.cs +++ /dev/null @@ -1,281 +0,0 @@ -using System.Text.Json; -using App.Metrics; -using Tzkt.Data; -using Tzkt.Data.Models; -using Tzkt.Sync.Services; -using Tzkt.Sync.Protocols.Proto9; - -namespace Tzkt.Sync.Protocols -{ - class Proto9Handler : ProtocolHandler - { - public override IDiagnostics Diagnostics { get; } - public override IHelpers Helpers { get; } - public override IValidator Validator { get; } - public override IRpc Rpc { get; } - public override string VersionName => "florence_009"; - public override int VersionNumber => 9; - - public Proto9Handler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) - : base(node, db, cache, quotes, services, config, logger, metrics) - { - Rpc = new Rpc(node); - Diagnostics = new Diagnostics(this); - Helpers = new Helpers(this); - Validator = new Validator(this); - } - - public override Task Activate(AppState state, JsonElement block) => new ProtoActivator(this).Activate(state, block); - public override Task Deactivate(AppState state) => new ProtoActivator(this).Deactivate(state); - - public override async Task Commit(JsonElement block) - { - await new StatisticsCommit(this).Apply(block); - - var blockCommit = new BlockCommit(this); - await blockCommit.Apply(block); - - await new SoftwareCommit(this).Apply(blockCommit.Block, block); - new FreezerCommit(this).Apply(blockCommit.Block, block); - await new RevelationPenaltyCommit(this).Apply(blockCommit.Block, block); - await new DeactivationCommit(this).Apply(blockCommit.Block, block); - - var operations = block.RequiredArray("operations", 4); - - #region operations 0 - foreach (var operation in operations[0].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "endorsement_with_slot": - await new AttestationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[0]"); - } - } - } - #endregion - - #region operations 1 - foreach (var operation in operations[1].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "proposals": - await new ProposalsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "ballot": - await new BallotsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[1]"); - } - } - } - #endregion - - #region operations 2 - foreach (var operation in operations[2].EnumerateArray()) - { - foreach (var content in operation.RequiredArray("contents", 1).EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "activate_account": - await new ActivationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_baking_evidence": - await new DoubleBakingCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "double_endorsement_evidence": - await new DoubleConsensusCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "seed_nonce_revelation": - await new NonceRevelationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not allowed in operations[2]"); - } - } - } - #endregion - - var bigMapCommit = new BigMapCommit(this); - - #region operations 3 - foreach (var operation in operations[3].EnumerateArray()) - { - Manager.Init(operation); - foreach (var content in operation.RequiredArray("contents").EnumerateArray()) - { - switch (content.RequiredString("kind")) - { - case "reveal": - await new RevealsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "delegation": - await new DelegationsCommit(this).Apply(blockCommit.Block, operation, content); - break; - case "origination": - var orig = new OriginationsCommit(this); - await orig.Apply(blockCommit.Block, operation, content); - if (orig.BigMapDiffs != null) - bigMapCommit.Append(orig.Origination, orig.Contract!, orig.BigMapDiffs); - break; - case "transaction": - var parent = new TransactionsCommit(this); - await parent.Apply(blockCommit.Block, operation, content); - if (parent.BigMapDiffs != null) - bigMapCommit.Append(parent.Transaction, (parent.Target as Contract)!, parent.BigMapDiffs); - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResult)) - { - foreach (var internalContent in internalResult.EnumerateArray()) - { - switch (internalContent.RequiredString("kind")) - { - case "delegation": - await new DelegationsCommit(this).ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - break; - case "origination": - var internalOrig = new OriginationsCommit(this); - await internalOrig.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalOrig.BigMapDiffs != null) - bigMapCommit.Append(internalOrig.Origination, internalOrig.Contract!, internalOrig.BigMapDiffs); - break; - case "transaction": - var internalTx = new TransactionsCommit(this); - await internalTx.ApplyInternal(blockCommit.Block, parent.Transaction, internalContent); - if (internalTx.BigMapDiffs != null) - bigMapCommit.Append(internalTx.Transaction, (internalTx.Target as Contract)!, internalTx.BigMapDiffs); - break; - default: - throw new NotImplementedException($"internal '{internalContent.RequiredString("kind")}' is not implemented"); - } - } - } - break; - default: - throw new NotImplementedException($"'{content.RequiredString("kind")}' is not expected in operations[3]"); - } - } - Manager.Reset(); - } - #endregion - - await bigMapCommit.Apply(); - await new TokensCommit(this).Apply(blockCommit.Block, bigMapCommit.Updates); - - var brCommit = new BakingRightsCommit(this); - await brCommit.Apply(blockCommit.Block); - - var cycleCommit = new CycleCommit(this); - await cycleCommit.Apply(blockCommit.Block); - - await new DelegatorCycleCommit(this).Apply(blockCommit.Block, cycleCommit.FutureCycle); - - await new BakerCycleCommit(this).Apply( - blockCommit.Block, - cycleCommit.FutureCycle, - brCommit.FutureBakingRights, - brCommit.FutureAttestationRights, - cycleCommit.BakerSnapshots, - brCommit.CurrentRights); - - await new VotingCommit(this).Apply(blockCommit.Block, block); - await new StateCommit(this).Apply(blockCommit.Block, block); - } - - public override async Task AfterCommit(JsonElement rawBlock) - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Apply(rawBlock, block); - } - - public override async Task BeforeRevert() - { - var block = await Cache.Blocks.CurrentAsync(); - await new SnapshotBalanceCommit(this).Revert(block); - } - - public override async Task Revert() - { - var currBlock = await Cache.Blocks.CurrentAsync(); - Db.TryAttach(currBlock); - - await new VotingCommit(this).Revert(currBlock); - await new StatisticsCommit(this).Revert(currBlock); - - await new BakerCycleCommit(this).Revert(currBlock); - await new DelegatorCycleCommit(this).Revert(currBlock); - await new CycleCommit(this).Revert(currBlock); - await new BakingRightsCommit(this).Revert(currBlock); - await new TokensCommit(this).Revert(currBlock); - await new BigMapCommit(this).Revert(currBlock); - - foreach (var operation in Context.EnumerateOps().OrderByDescending(x => x.Id).ToList()) - { - switch (operation) - { - case AttestationOperation op: - await new AttestationsCommit(this).Revert(currBlock, op); - break; - case ProposalOperation op: - await new ProposalsCommit(this).Revert(currBlock, op); - break; - case BallotOperation op: - await new BallotsCommit(this).Revert(currBlock, op); - break; - case ActivationOperation op: - await new ActivationsCommit(this).Revert(currBlock, op); - break; - case DoubleBakingOperation op: - await new DoubleBakingCommit(this).Revert(currBlock, op); - break; - case DoubleConsensusOperation op: - await new DoubleConsensusCommit(this).Revert(currBlock, op); - break; - case NonceRevelationOperation op: - await new NonceRevelationsCommit(this).Revert(currBlock, op); - break; - case RevealOperation op: - await new RevealsCommit(this).Revert(currBlock, op); - break; - case DelegationOperation op: - if (op.InitiatorId == null) - await new DelegationsCommit(this).Revert(currBlock, op); - else - await new DelegationsCommit(this).RevertInternal(currBlock, op); - break; - case OriginationOperation op: - if (op.InitiatorId == null) - await new OriginationsCommit(this).Revert(currBlock, op); - else - await new OriginationsCommit(this).RevertInternal(currBlock, op); - break; - case TransactionOperation op: - if (op.InitiatorId == null) - await new TransactionsCommit(this).Revert(currBlock, op); - else - await new TransactionsCommit(this).RevertInternal(currBlock, op); - break; - default: - throw new NotImplementedException($"'{operation.GetType()}' is not implemented"); - } - } - - await new DeactivationCommit(this).Revert(currBlock); - await new RevelationPenaltyCommit(this).Revert(currBlock); - await new FreezerCommit(this).Revert(currBlock); - await new SoftwareCommit(this).Revert(currBlock); - await new BlockCommit(this).Revert(currBlock); - - await new StateCommit(this).Revert(currBlock); - } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Rpc/Rpc.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Rpc/Rpc.cs deleted file mode 100644 index 26dda02f4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Rpc/Rpc.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Tzkt.Sync.Services; - -namespace Tzkt.Sync.Protocols.Proto9 -{ - class Rpc : Proto6.Rpc - { - public Rpc(TezosNode node) : base(node) { } - } -} diff --git a/Tzkt.Sync/Protocols/Handlers/Proto9/Validation/Validator.cs b/Tzkt.Sync/Protocols/Handlers/Proto9/Validation/Validator.cs deleted file mode 100644 index c5c1b48d4..000000000 --- a/Tzkt.Sync/Protocols/Handlers/Proto9/Validation/Validator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Tzkt.Sync.Protocols.Proto9 -{ - class Validator : Proto1.Validator - { - public Validator(ProtocolHandler protocol) : base(protocol) { } - } -} diff --git a/Tzkt.Sync/Protocols/Helpers/Blind.cs b/Tzkt.Sync/Protocols/Helpers/Blind.cs deleted file mode 100644 index dd735c51f..000000000 --- a/Tzkt.Sync/Protocols/Helpers/Blind.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Blake2Fast; -using Netezos.Encoding; - -namespace Tzkt.Sync.Protocols -{ - static class Blind - { - static readonly byte[] Prefix = [1, 2, 49, 223]; - - public static string GetBlindedAddress(string address, string secret) - { - var pkh = Base58.Parse(address).GetBytes(3, 20); - var key = Hex.Parse(secret); - var blind = Blake2b.ComputeHash(20, key, pkh); - - return Base58.Convert(blind, Prefix); - } - } -} diff --git a/Tzkt.Sync/Protocols/Helpers/BlockContext.cs b/Tzkt.Sync/Protocols/Helpers/BlockContext.cs index 7c109ee66..4f30c97c4 100644 --- a/Tzkt.Sync/Protocols/Helpers/BlockContext.cs +++ b/Tzkt.Sync/Protocols/Helpers/BlockContext.cs @@ -9,110 +9,31 @@ namespace Tzkt.Sync.Protocols public class BlockContext { public Block Block { get; set; } = null!; - public Data.Models.Delegate Proposer { get; set; } = null!; public Protocol Protocol { get; set; } = null!; #region operations - public List AttestationOps { get; set; } = []; - public List PreattestationOps { get; set; } = []; - - public List ProposalOps { get; set; } = []; - public List BallotOps { get; set; } = []; - - public List ActivationOps { get; set; } = []; - public List DalEntrapmentEvidenceOps { get; set; } = []; - public List DoubleBakingOps { get; set; } = []; - public List DoubleConsensusOps { get; set; } = []; - public List NonceRevelationOps { get; set; } = []; - public List VdfRevelationOps { get; set; } = []; - public List DrainDelegateOps { get; set; } = []; - - public List DelegationOps { get; set; } = []; public List OriginationOps { get; set; } = []; public List TransactionOps { get; set; } = []; public List RevealOps { get; set; } = []; public List RegisterConstantOps { get; set; } = []; - public List SetDepositsLimitOps { get; set; } = []; public List IncreasePaidStorageOps { get; set; } = []; - public List UpdateSecondaryKeyOps { get; set; } = []; public List TransferTicketOps { get; set; } = []; - public List SetDelegateParametersOps { get; set; } = []; - public List DalPublishCommitmentOps { get; set; } = []; - public List StakingOps { get; set; } = []; - - public List TxRollupOriginationOps { get; set; } = []; - public List TxRollupSubmitBatchOps { get; set; } = []; - public List TxRollupCommitOps { get; set; } = []; - public List TxRollupFinalizeCommitmentOps { get; set; } = []; - public List TxRollupRemoveCommitmentOps { get; set; } = []; - public List TxRollupReturnBondOps { get; set; } = []; - public List TxRollupRejectionOps { get; set; } = []; - public List TxRollupDispatchTicketsOps { get; set; } = []; - - public List SmartRollupAddMessagesOps { get; set; } = []; - public List SmartRollupCementOps { get; set; } = []; - public List SmartRollupExecuteOps { get; set; } = []; - public List SmartRollupOriginateOps { get; set; } = []; - public List SmartRollupPublishOps { get; set; } = []; - public List SmartRollupRecoverBondOps { get; set; } = []; - public List SmartRollupRefuteOps { get; set; } = []; #endregion #region fictive operations public List MigrationOps { get; set; } = []; - public List RevelationPenaltyOps { get; set; } = []; - public List AttestationRewardOps { get; set; } = []; - public List DalAttestationRewardOps { get; set; } = []; - public List AutostakingOps { get; set; } = []; #endregion public IEnumerable EnumerateOps() { var ops = Enumerable.Empty(); - if (AttestationOps.Count != 0) ops = ops.Concat(AttestationOps); - if (PreattestationOps.Count != 0) ops = ops.Concat(PreattestationOps); - - if (BallotOps.Count != 0) ops = ops.Concat(BallotOps); - if (ProposalOps.Count != 0) ops = ops.Concat(ProposalOps); - - if (ActivationOps.Count != 0) ops = ops.Concat(ActivationOps); - if (DalEntrapmentEvidenceOps.Count != 0) ops = ops.Concat(DalEntrapmentEvidenceOps); - if (DoubleBakingOps.Count != 0) ops = ops.Concat(DoubleBakingOps); - if (DoubleConsensusOps.Count != 0) ops = ops.Concat(DoubleConsensusOps); - if (NonceRevelationOps.Count != 0) ops = ops.Concat(NonceRevelationOps); - if (VdfRevelationOps.Count != 0) ops = ops.Concat(VdfRevelationOps); - if (DrainDelegateOps.Count != 0) ops = ops.Concat(DrainDelegateOps); - - if (DelegationOps.Count != 0) ops = ops.Concat(DelegationOps); if (OriginationOps.Count != 0) ops = ops.Concat(OriginationOps); if (TransactionOps.Count != 0) ops = ops.Concat(TransactionOps); if (RevealOps.Count != 0) ops = ops.Concat(RevealOps); if (RegisterConstantOps.Count != 0) ops = ops.Concat(RegisterConstantOps); - if (SetDepositsLimitOps.Count != 0) ops = ops.Concat(SetDepositsLimitOps); if (IncreasePaidStorageOps.Count != 0) ops = ops.Concat(IncreasePaidStorageOps); - if (UpdateSecondaryKeyOps.Count != 0) ops = ops.Concat(UpdateSecondaryKeyOps); if (TransferTicketOps.Count != 0) ops = ops.Concat(TransferTicketOps); - if (SetDelegateParametersOps.Count != 0) ops = ops.Concat(SetDelegateParametersOps); - if (DalPublishCommitmentOps.Count != 0) ops = ops.Concat(DalPublishCommitmentOps); - if (StakingOps.Count != 0) ops = ops.Concat(StakingOps); - - if (TxRollupOriginationOps.Count != 0) ops = ops.Concat(TxRollupOriginationOps); - if (TxRollupSubmitBatchOps.Count != 0) ops = ops.Concat(TxRollupSubmitBatchOps); - if (TxRollupCommitOps.Count != 0) ops = ops.Concat(TxRollupCommitOps); - if (TxRollupFinalizeCommitmentOps.Count != 0) ops = ops.Concat(TxRollupFinalizeCommitmentOps); - if (TxRollupRemoveCommitmentOps.Count != 0) ops = ops.Concat(TxRollupRemoveCommitmentOps); - if (TxRollupReturnBondOps.Count != 0) ops = ops.Concat(TxRollupReturnBondOps); - if (TxRollupRejectionOps.Count != 0) ops = ops.Concat(TxRollupRejectionOps); - if (TxRollupDispatchTicketsOps.Count != 0) ops = ops.Concat(TxRollupDispatchTicketsOps); - - if (SmartRollupAddMessagesOps.Count != 0) ops = ops.Concat(SmartRollupAddMessagesOps); - if (SmartRollupCementOps.Count != 0) ops = ops.Concat(SmartRollupCementOps); - if (SmartRollupExecuteOps.Count != 0) ops = ops.Concat(SmartRollupExecuteOps); - if (SmartRollupOriginateOps.Count != 0) ops = ops.Concat(SmartRollupOriginateOps); - if (SmartRollupPublishOps.Count != 0) ops = ops.Concat(SmartRollupPublishOps); - if (SmartRollupRecoverBondOps.Count != 0) ops = ops.Concat(SmartRollupRecoverBondOps); - if (SmartRollupRefuteOps.Count != 0) ops = ops.Concat(SmartRollupRefuteOps); return ops; } @@ -123,9 +44,6 @@ public void Apply(TzktContext db) if (TransactionOps.Count != 0) TransactionOperation.Write(conn, TransactionOps); - - if (AttestationOps.Count != 0) - AttestationOperation.Write(conn, AttestationOps); } public async Task Revert(TzktContext db) @@ -135,12 +53,6 @@ await db.Database.ExecuteSqlRawAsync($$""" DELETE FROM "{{nameof(TzktContext.TransactionOps)}}" WHERE "{{nameof(TransactionOperation.Level)}}" = {0} """, Block.Level); - - if (AttestationOps.Count != 0) - await db.Database.ExecuteSqlRawAsync($$""" - DELETE FROM "{{nameof(TzktContext.AttestationOps)}}" - WHERE "{{nameof(AttestationOperation.Level)}}" = {0} - """, Block.Level); } } } diff --git a/Tzkt.Sync/Protocols/Helpers/Chains.cs b/Tzkt.Sync/Protocols/Helpers/Chains.cs deleted file mode 100644 index e3434962b..000000000 --- a/Tzkt.Sync/Protocols/Helpers/Chains.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Tzkt.Sync.Protocols -{ - static class Chains - { - public static string GetName(string chainId) => chainId switch - { - "NetXdQprcVkpaWU" => "mainnet", - "NetXSgo1ZT2DRUG" => "edo2net", - "NetXxkAx4woPLyu" => "florencenet", - "NetXz969SFaFn8k" => "granadanet", - "NetXuXoGoLxNK6o" => "hangzhounet", - "NetXZSsxBpMQeAT" => "hangzhou2net", - "NetXLH1uAxK7CCh" => "jakartanet", - "NetXnHfVqm9iesp" => "ghostnet", - "NetXi2ZagzEsXbZ" => "kathmandunet", - "NetXizpkH94bocH" => "limanet", - "NetXgbcrNtXD2yA" => "mumbainet", - "NetXyuzvDo2Ugzb" => "nairobinet", - "NetXxWsskGahzQB" => "oxfordnet", - "NetXXWAHLEvre9b" => "parisnet", - "NetXuTeGinLEqxp" => "quebecnet", - "NetXPdgaoabtBth" => "rionet", - "NetXd56aBs1aeW3" => "seoulnet", - "NetXsqzbfFenSTS" => "shadownet", - "NetXe8DbhW9A1eS" => "tallinnnet", - "NetXYRoAfQDxZux" => "nextnet", - _ => "private" - }; - } -} diff --git a/Tzkt.Sync/Protocols/Helpers/GracePeriod.cs b/Tzkt.Sync/Protocols/Helpers/GracePeriod.cs deleted file mode 100644 index 50b27614b..000000000 --- a/Tzkt.Sync/Protocols/Helpers/GracePeriod.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols -{ - static class GracePeriod - { - public static int Init(int level, Protocol proto) - => proto.GetCycleStart(proto.GetCycle(level) + proto.ConsensusRightsDelay + proto.ToleratedInactivityPeriod + 1); - - public static int Reset(int level, Protocol proto) - => proto.GetCycleStart(proto.GetCycle(level) + proto.ToleratedInactivityPeriod + 1); - } -} diff --git a/Tzkt.Sync/Protocols/Helpers/InboxContext.cs b/Tzkt.Sync/Protocols/Helpers/InboxContext.cs deleted file mode 100644 index 151bbbe0a..000000000 --- a/Tzkt.Sync/Protocols/Helpers/InboxContext.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Tzkt.Sync.Protocols -{ - public class InboxContext - { - public List<(long, byte[]?)> Messages { get; } = []; - - public void Push(long operationId, byte[]? payload = null) - { - Messages.Add((operationId, payload)); - } - } -} diff --git a/Tzkt.Sync/Protocols/Helpers/OriginationNonce.cs b/Tzkt.Sync/Protocols/Helpers/OriginationNonce.cs deleted file mode 100644 index 1c8fb092c..000000000 --- a/Tzkt.Sync/Protocols/Helpers/OriginationNonce.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Netezos.Encoding; -using Netezos.Utils; - -namespace Tzkt.Sync.Protocols -{ - static class OriginationNonce - { - public static string GetContractAddress(int index) - { - byte[] hash = - [ - 72, 1, 189, 111, 8, 152, 13, 214, 38, 163, 228, 90, 249, 51, 127, 242, - 206, 198, 138, 55, 219, 134, 18, 158, 128, 96, 185, 73, 180, 9, 86, 229 - ]; - var address = Blake2b.GetDigest([.. hash, .. GetBytes(index)], 160); - return Base58.Convert(address, [2, 90, 121]); - } - - static byte[] GetBytes(int value) => - [ - (byte)((value >> 24) & 0xff), - (byte)((value >> 16) & 0xff), - (byte)((value >> 8) & 0xff), - (byte)(value & 0xff), - ]; - } -} diff --git a/Tzkt.Sync/Protocols/Helpers/RightsGenerator.cs b/Tzkt.Sync/Protocols/Helpers/RightsGenerator.cs deleted file mode 100644 index 701c1527a..000000000 --- a/Tzkt.Sync/Protocols/Helpers/RightsGenerator.cs +++ /dev/null @@ -1,185 +0,0 @@ -using Tzkt.Data.Models; - -namespace Tzkt.Sync.Protocols -{ - class RightsGenerator - { - readonly Sampler Sampler; - readonly byte[] Seed; - - RightsGenerator(Sampler sampler, byte[] seed) - { - Sampler = sampler; - Seed = new byte[seed.Length + 8]; - Buffer.BlockCopy(seed, 0, Seed, 0, seed.Length); - } - - IEnumerable EnumerateBakingRights(int position, int rounds) - { - WriteInt32(Seed, 32, position); - for (var round = 0; round < rounds; round++) - { - WriteInt32(Seed, 36, round); - yield return Sampler.GetBaker(Seed); - } - } - - List GetBakingRights(int position, int rounds) - { - WriteInt32(Seed, 32, position); - var result = new List(rounds); - for (var round = 0; round < rounds; round++) - { - WriteInt32(Seed, 36, round); - result.Add(Sampler.GetBaker(Seed)); - } - return result; - } - - Dictionary GetAttestationRights(int position, int slots) - { - WriteInt32(Seed, 32, position); - var result = new Dictionary(); - for (var slot = 0; slot < slots; slot++) - { - WriteInt32(Seed, 36, slot); - var baker = Sampler.GetBaker(Seed); - result.TryGetValue(baker, out var count); - result[baker] = count + 1; - } - return result; - } - - int GetAttester(int position, int slot) - { - WriteInt32(Seed, 32, position); - for (var i = 0; i < slot; i++) - WriteInt32(Seed, 36, i); - WriteInt32(Seed, 36, slot); - return Sampler.GetBaker(Seed); - } - - static void WriteInt32(byte[] bytes, int pos, int value) - { - bytes[pos + 3] = (byte)(value & 0xFF); - value >>= 8; - bytes[pos + 2] = (byte)(value & 0xFF); - value >>= 8; - bytes[pos + 1] = (byte)(value & 0xFF); - value >>= 8; - bytes[pos] = (byte)value; - } - - public static async Task> GetBakingRightsAsync(Sampler sampler, Protocol protocol, Cycle cycle) - { - var rounds = BakingRight.MaxRound + 1; - var res = new List
(protocol.BlocksPerCycle * rounds); - var step = (int)Math.Ceiling((double)protocol.BlocksPerCycle / Environment.ProcessorCount); - var tasks = new List(); - for (int i = 0; i < protocol.BlocksPerCycle; i += step) - { - var from = i; - var to = Math.Min(protocol.BlocksPerCycle, i + step); - tasks.Add(Task.Run(() => - { - var generator = new RightsGenerator(sampler, cycle.Seed); - for (int position = from; position < to; position++) - { - var rights = generator.GetBakingRights(position, rounds); - lock (res) - { - for (int i = 0; i < rights.Count; i++) - res.Add(new() { Level = cycle.FirstLevel + position, Round = i, Baker = rights[i]}); - } - } - })); - } - await Task.WhenAll(tasks); - return res.OrderBy(x => x.Level).ThenBy(x => x.Round); - } - - public static async Task> GetAttestationRightsAsync(Sampler sampler, Protocol protocol, Cycle cycle) - { - var res = new List(protocol.BlocksPerCycle * sampler.Length); - var step = (int)Math.Ceiling((double)protocol.BlocksPerCycle / Environment.ProcessorCount); - var tasks = new List(); - for (int i = 0; i < protocol.BlocksPerCycle; i += step) - { - var from = i; - var to = Math.Min(protocol.BlocksPerCycle, i + step); - tasks.Add(Task.Run(() => - { - var generator = new RightsGenerator(sampler, cycle.Seed); - for (int position = from; position < to; position++) - { - var rights = generator.GetAttestationRights(position, protocol.AttestersPerBlock); - lock (res) - { - foreach (var (baker, slots) in rights) - res.Add(new() { Level = cycle.FirstLevel + position, Baker = baker, Slots = slots }); - } - } - })); - } - await Task.WhenAll(tasks); - return res.OrderBy(x => x.Level).ThenByDescending(x => x.Slots); - } - - public static IEnumerable
EnumerateBakingRights(Sampler sampler, Cycle cycle, int level, int rounds) - { - var round = 0; - var generator = new RightsGenerator(sampler, cycle.Seed); - foreach (var bakerId in generator.EnumerateBakingRights(level - cycle.FirstLevel, rounds)) - { - yield return new BR - { - Baker = bakerId, - Level = level, - Round = round++ - }; - } - } - - public static IEnumerable
GetBakingRights(Sampler sampler, Cycle cycle, int level, int rounds = BakingRight.MaxRound + 1) - { - var generator = new RightsGenerator(sampler, cycle.Seed); - var rights = generator.GetBakingRights(level - cycle.FirstLevel, rounds); - var res = new List
(rights.Count); - for (int i = 0; i < rights.Count; i++) - res.Add(new() { Level = level, Round = i, Baker = rights[i] }); - return res; - } - - public static IEnumerable GetAttestationRights(Sampler sampler, Protocol protocol, Cycle cycle, int level) - { - var generator = new RightsGenerator(sampler, cycle.Seed); - var rights = generator.GetAttestationRights(level - cycle.FirstLevel, protocol.AttestersPerBlock); - return rights.Select(kv => new AR - { - Level = level, - Baker = kv.Key, - Slots = kv.Value - }); - } - - public static int GetAttester(Sampler sampler, Cycle cycle, int level, int slot) - { - var generator = new RightsGenerator(sampler, cycle.Seed); - return generator.GetAttester(level - cycle.FirstLevel, slot); - } - - public class AR - { - public int Level { get; init; } - public int Baker { get; init; } - public int Slots { get; init; } - } - - public class BR - { - public int Level { get; init; } - public int Round { get; init; } - public int Baker { get; init; } - } - } -} diff --git a/Tzkt.Sync/Protocols/Helpers/Sampler.cs b/Tzkt.Sync/Protocols/Helpers/Sampler.cs deleted file mode 100644 index 1f513d862..000000000 --- a/Tzkt.Sync/Protocols/Helpers/Sampler.cs +++ /dev/null @@ -1,159 +0,0 @@ -using Dynamic.Json; -using Netezos.Keys; - -namespace Tzkt.Sync.Protocols -{ - class Sampler - { - public int Length => Bakers.Length; - - readonly int[] Alias; - readonly int[] Bakers; - readonly long[] P; - readonly long Total; - - public Sampler(int[] bakers, long[] stakes) - { - var cnt = stakes.Length; - var p = new long[cnt]; - var alias = new int[cnt]; - var small = new List(cnt); - var large = new List(cnt); - var total = stakes.Sum(); - - var ind = 0; - foreach (var stake in stakes) - { - var item = new Item - { - Index = ind++, - P = stake, - Q = stake * cnt - }; - if (item.Q < total) small.Add(item); - else large.Add(item); - } - - while (true) - { - if (small.Count > 0 && large.Count > 0) - { - var l = small[^1]; - var g = large[^1]; - - small.RemoveAt(small.Count - 1); - - p[l.Index] = l.Q; - alias[l.Index] = g.Index; - - g.Q += l.Q - total; - if (g.Q < total) - { - large.RemoveAt(large.Count - 1); - small.Add(g); - } - } - else if (small.Count > 0) - { - foreach (var l in small) - { - p[l.Index] = total; - alias[l.Index] = -1; - } - break; - } - else if (large.Count > 0) - { - foreach (var g in large) - { - p[g.Index] = total; - alias[g.Index] = -1; - } - break; - } - else - { - throw new Exception("Sampler initialization failed"); - } - } - - (P, Alias, Total) = (p, alias, total); - Bakers = bakers; - } - - public int GetBaker(byte[] seed) - { - var state = Blake2Fast.Blake2b.ComputeHash(32, seed); - var i = TakeInt64(state, 0, P.Length, out var nextState, out var nextPos); - var el = TakeInt64(nextState, nextPos, Total, out var _, out var _); - return el < P[i] ? Bakers[i] : Bakers[Alias[i]]; - } - - public async Task Validate(ProtocolHandler proto, int block, int cycle) - { - dynamic raw = DJson.Create(await proto.Node.GetAsync($"chains/main/blocks/{block}/context/raw/json/cycle/{cycle}")); - var state = raw.delegate_sampler_state; - - if (state.total != Total) - throw new Exception("Invalid sampler 'total'"); - - if (state.support.elements.length != Bakers.Length) - throw new Exception("Invalid sampler 'support'"); - - for (int i = 0; i < Bakers.Length; i++) - { - if (state.support.elements[i] is DJsonValue) - { - if (PubKey.FromBase58(state.support.elements[i]).Address != proto.Cache.Accounts.GetDelegate(Bakers[i]).Address) - throw new Exception("Invalid sampler 'support' element"); - } - else if (state.support.elements[i].@delegate == null) - { - if (PubKey.FromBase58(state.support.elements[i].consensus_pk).Address != proto.Cache.Accounts.GetDelegate(Bakers[i]).Address) - throw new Exception("Invalid sampler 'support' element"); - } - else - { - if (state.support.elements[i].@delegate != proto.Cache.Accounts.GetDelegate(Bakers[i]).Address) - throw new Exception("Invalid sampler 'support' element"); - } - } - - if (state.p.elements.length != P.Length) - throw new Exception("Invalid sampler 'p'"); - - for (int i = 0; i < P.Length; i++) - if (state.p.elements[i] != P[i]) - throw new Exception("Invalid sampler 'p' element"); - - if (state.alias.elements.length != Alias.Length) - throw new Exception("Invalid sampler 'alias'"); - - for (int i = 0; i < Alias.Length; i++) - if (state.alias.elements[i] != Alias[i]) - throw new Exception("Invalid sampler 'alias' element"); - } - - static long TakeInt64(byte[] state, int pos, long bound, out byte[] nextState, out int nextPos) - { - if (pos > state.Length - 8) - return TakeInt64(Blake2Fast.Blake2b.ComputeHash(32, state), 0, bound, out nextState, out nextPos); - - var r = state.ReadInt64(pos); - r = r == long.MinValue ? 0L : Math.Abs(r); - if (r >= long.MaxValue - long.MaxValue % bound) - return TakeInt64(state, pos + 8, bound, out nextState, out nextPos); - - nextState = state; - nextPos = pos + 8; - return r % bound; - } - - class Item - { - public int Index { get; set; } - public long Q { get; set; } - public long P { get; set; } - } - } -} diff --git a/Tzkt.Sync/Protocols/Helpers/Seed.cs b/Tzkt.Sync/Protocols/Helpers/Seed.cs deleted file mode 100644 index 470ed3548..000000000 --- a/Tzkt.Sync/Protocols/Helpers/Seed.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Blake2Fast; - -namespace Tzkt.Sync.Protocols -{ - static class Seed - { - public static List GetInitialSeeds(int count, byte[] initialSeed) - { - var list = new List(count) - { - Blake2b.ComputeHash(32, initialSeed) - }; - for (int i = 1; i < count; i++) - { - list.Add(Blake2b.ComputeHash(32, list[^1].Concat(new byte[32]))); - } - return list; - } - - public static byte[] GetNextSeed(byte[] seed, IEnumerable nonces, byte[]? vdfSolution) - { - var res = Blake2b.ComputeHash(32, seed.Concat(new byte[32])); - foreach (var nonce in nonces) - res = Blake2b.ComputeHash(32, res.Concat(nonce)); - if (vdfSolution != null) - res = Blake2b.ComputeHash(32, res.Concat(vdfSolution)); - return res; - } - - public static int GetSnapshotIndex(byte[] seed, int snapshots, bool ithaca = false) - { - var state = Blake2b.ComputeHash(32, Blake2b.ComputeHash(32, seed.Concat(ithaca - ? [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 115, 116, 97, 107, 101, 95, 115, 110, 97, 112, 115, 104, 111, 116 - ] - : [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 114, 111, 108, 108, 95, 115, 110, 97, 112, 115, 104, 111, 116 - ]))); - var max = int.MaxValue - int.MaxValue % snapshots; - var tries = 1_000_000; - while (--tries > 0) - { - state = Blake2b.ComputeHash(32, state); - var r = state.ReadInt32(0); - r = r == int.MinValue ? 0 : Math.Abs(r); - if (r < max) return r % snapshots; - } - throw new Exception("You are lucky :D"); - } - } -} diff --git a/Tzkt.Sync/Protocols/ProtocolCommit.cs b/Tzkt.Sync/Protocols/ProtocolCommit.cs index e72776698..0e45b52b1 100644 --- a/Tzkt.Sync/Protocols/ProtocolCommit.cs +++ b/Tzkt.Sync/Protocols/ProtocolCommit.cs @@ -1,5 +1,4 @@ -using Microsoft.EntityFrameworkCore; -using Tzkt.Data; +using Tzkt.Data; using Tzkt.Data.Models; using Tzkt.Sync.Services; @@ -13,480 +12,36 @@ public abstract class ProtocolCommit(ProtocolHandler protocol) protected readonly BlockContext Context = protocol.Context; protected readonly ILogger Logger = protocol.Logger; - protected Data.Models.Delegate RegisterBaker(User user, Protocol? protocol = null) - { - var baker = new Data.Models.Delegate - { - ActivationLevel = Context.Block.Level, - DeactivationLevel = GracePeriod.Init(Context.Block.Level, protocol ?? Context.Protocol), - Address = user.Address, - FirstLevel = user.FirstLevel, - LastLevel = user.LastLevel, - Balance = user.Balance, - Counter = user.Counter, - DelegateId = null, - DelegationLevel = null, - Id = user.Id, - Index = user.Index, - ActivationsCount = user.ActivationsCount, - DelegationsCount = user.DelegationsCount, - OriginationsCount = user.OriginationsCount, - TransactionsCount = user.TransactionsCount, - RevealsCount = user.RevealsCount, - RegisterConstantsCount = user.RegisterConstantsCount, - SetDepositsLimitsCount = user.SetDepositsLimitsCount, - ContractsCount = user.ContractsCount, - MigrationsCount = user.MigrationsCount, - PublicKey = user.PublicKey, - Revealed = user.Revealed, - Staked = true, - OwnDelegatedBalance = user.Balance - user.UnstakedBalance, - StakedPseudotokens = user.StakedPseudotokens, - UnstakedBalance = user.UnstakedBalance, - UnstakedBakerId = user.UnstakedBakerId, - StakingOpsCount = user.StakingOpsCount, - ExternalDelegatedBalance = 0, - MinTotalDelegated = long.MaxValue, - MinTotalDelegatedLevel = 0, - Type = AccountType.Delegate, - ActiveTokensCount = user.ActiveTokensCount, - TokenBalancesCount = user.TokenBalancesCount, - TokenTransfersCount = user.TokenTransfersCount, - ActiveTicketsCount = user.ActiveTicketsCount, - TicketBalancesCount = user.TicketBalancesCount, - TicketTransfersCount = user.TicketTransfersCount, - TransferTicketCount = user.TransferTicketCount, - TxRollupCommitCount = user.TxRollupCommitCount, - TxRollupDispatchTicketsCount = user.TxRollupDispatchTicketsCount, - TxRollupFinalizeCommitmentCount = user.TxRollupFinalizeCommitmentCount, - TxRollupOriginationCount = user.TxRollupOriginationCount, - TxRollupRejectionCount = user.TxRollupRejectionCount, - TxRollupRemoveCommitmentCount = user.TxRollupRemoveCommitmentCount, - TxRollupReturnBondCount = user.TxRollupReturnBondCount, - TxRollupSubmitBatchCount = user.TxRollupSubmitBatchCount, - IncreasePaidStorageCount = user.IncreasePaidStorageCount, - UpdateSecondaryKeyCount = user.UpdateSecondaryKeyCount, - DrainDelegateCount = user.DrainDelegateCount, - RollupBonds = user.RollupBonds, - RollupsCount = user.RollupsCount, - SmartRollupBonds = user.SmartRollupBonds, - SmartRollupsCount = user.SmartRollupsCount, - SmartRollupAddMessagesCount = user.SmartRollupAddMessagesCount, - SmartRollupCementCount = user.SmartRollupCementCount, - SmartRollupExecuteCount = user.SmartRollupExecuteCount, - SmartRollupOriginateCount = user.SmartRollupOriginateCount, - SmartRollupPublishCount = user.SmartRollupPublishCount, - SmartRollupRecoverBondCount = user.SmartRollupRecoverBondCount, - SmartRollupRefuteCount = user.SmartRollupRefuteCount, - DalPublishCommitmentOpsCount = user.DalPublishCommitmentOpsCount, - SetDelegateParametersOpsCount = user.SetDelegateParametersOpsCount, - RefutationGamesCount = user.RefutationGamesCount, - ActiveRefutationGamesCount = user.ActiveRefutationGamesCount, - StakingUpdatesCount = user.StakingUpdatesCount - }; - - UpdateBakerPower(baker); - - Cache.Statistics.Current.TotalOwnDelegated += baker.OwnDelegatedBalance; - Cache.Statistics.Current.TotalBakers++; - - var isAdded = Db.Entry(user).State == EntityState.Added; - Db.Entry(user).State = EntityState.Detached; - Db.Entry(baker).State = isAdded ? EntityState.Added : EntityState.Modified; - Cache.Accounts.Add(baker); - - return baker; - } - - protected User UnregisterBaker(Data.Models.Delegate baker) - { - var user = new User - { - Address = baker.Address, - FirstLevel = baker.FirstLevel, - LastLevel = baker.LastLevel, - Balance = baker.Balance, - Counter = baker.Counter, - DelegateId = null, - DelegationLevel = null, - StakedPseudotokens = baker.StakedPseudotokens, - UnstakedBalance = baker.UnstakedBalance, - UnstakedBakerId = baker.UnstakedBakerId, - StakingOpsCount = baker.StakingOpsCount, - Id = baker.Id, - Index = baker.Index, - ActivationsCount = baker.ActivationsCount, - DelegationsCount = baker.DelegationsCount, - OriginationsCount = baker.OriginationsCount, - TransactionsCount = baker.TransactionsCount, - RevealsCount = baker.RevealsCount, - RegisterConstantsCount = baker.RegisterConstantsCount, - SetDepositsLimitsCount = baker.SetDepositsLimitsCount, - ContractsCount = baker.ContractsCount, - MigrationsCount = baker.MigrationsCount, - PublicKey = baker.PublicKey, - Revealed = baker.Revealed, - Staked = false, - Type = AccountType.User, - ActiveTokensCount = baker.ActiveTokensCount, - TokenBalancesCount = baker.TokenBalancesCount, - TokenTransfersCount = baker.TokenTransfersCount, - ActiveTicketsCount = baker.ActiveTicketsCount, - TicketBalancesCount = baker.TicketBalancesCount, - TicketTransfersCount = baker.TicketTransfersCount, - TransferTicketCount = baker.TransferTicketCount, - TxRollupCommitCount = baker.TxRollupCommitCount, - TxRollupDispatchTicketsCount = baker.TxRollupDispatchTicketsCount, - TxRollupFinalizeCommitmentCount = baker.TxRollupFinalizeCommitmentCount, - TxRollupOriginationCount = baker.TxRollupOriginationCount, - TxRollupRejectionCount = baker.TxRollupRejectionCount, - TxRollupRemoveCommitmentCount = baker.TxRollupRemoveCommitmentCount, - TxRollupReturnBondCount = baker.TxRollupReturnBondCount, - TxRollupSubmitBatchCount = baker.TxRollupSubmitBatchCount, - IncreasePaidStorageCount = baker.IncreasePaidStorageCount, - UpdateSecondaryKeyCount = baker.UpdateSecondaryKeyCount, - DrainDelegateCount = baker.DrainDelegateCount, - RollupBonds = baker.RollupBonds, - RollupsCount = baker.RollupsCount, - SmartRollupBonds = baker.SmartRollupBonds, - SmartRollupsCount = baker.SmartRollupsCount, - SmartRollupAddMessagesCount = baker.SmartRollupAddMessagesCount, - SmartRollupCementCount = baker.SmartRollupCementCount, - SmartRollupExecuteCount = baker.SmartRollupExecuteCount, - SmartRollupOriginateCount = baker.SmartRollupOriginateCount, - SmartRollupPublishCount = baker.SmartRollupPublishCount, - SmartRollupRecoverBondCount = baker.SmartRollupRecoverBondCount, - SmartRollupRefuteCount = baker.SmartRollupRefuteCount, - SetDelegateParametersOpsCount = baker.SetDelegateParametersOpsCount, - DalPublishCommitmentOpsCount = baker.DalPublishCommitmentOpsCount, - RefutationGamesCount = baker.RefutationGamesCount, - ActiveRefutationGamesCount = baker.ActiveRefutationGamesCount, - StakingUpdatesCount = baker.StakingUpdatesCount - }; - - var isAdded = Db.Entry(baker).State == EntityState.Added; - Db.Entry(baker).State = EntityState.Detached; - Db.Entry(user).State = isAdded ? EntityState.Added : EntityState.Modified; - Cache.Accounts.Add(user); - - return user; - } - - protected async Task ActivateBaker(Data.Models.Delegate baker) - { - baker.Staked = true; - - foreach (var delegator in await Db.Accounts.Where(x => x.DelegateId == baker.Id).ToListAsync()) - { - Cache.Accounts.Add(delegator); - delegator.LastLevel = Context.Block.Level; - delegator.Staked = true; - } - - UpdateBakerPower(baker); - - Cache.Statistics.Current.TotalOwnStaked += baker.OwnStakedBalance; - Cache.Statistics.Current.TotalExternalStaked += baker.ExternalStakedBalance; - Cache.Statistics.Current.TotalOwnDelegated += baker.OwnDelegatedBalance; - Cache.Statistics.Current.TotalExternalDelegated += baker.ExternalDelegatedBalance; - - Cache.Statistics.Current.TotalBakers++; - Cache.Statistics.Current.TotalStakers += baker.StakersCount; - Cache.Statistics.Current.TotalDelegators += baker.DelegatorsCount; - } - - protected async Task DeactivateBaker(Data.Models.Delegate baker) - { - baker.Staked = false; - - foreach (var delegator in await Db.Accounts.Where(x => x.DelegateId == baker.Id).ToListAsync()) - { - Cache.Accounts.Add(delegator); - delegator.LastLevel = Context.Block.Level; - delegator.Staked = false; - } - - UpdateBakerPower(baker); - - Cache.Statistics.Current.TotalOwnStaked -= baker.OwnStakedBalance; - Cache.Statistics.Current.TotalExternalStaked -= baker.ExternalStakedBalance; - Cache.Statistics.Current.TotalOwnDelegated -= baker.OwnDelegatedBalance; - Cache.Statistics.Current.TotalExternalDelegated -= baker.ExternalDelegatedBalance; - - Cache.Statistics.Current.TotalBakers--; - Cache.Statistics.Current.TotalStakers -= baker.StakersCount; - Cache.Statistics.Current.TotalDelegators -= baker.DelegatorsCount; - } - - protected void UpdateBakersPower() - { - foreach (var baker in Cache.Accounts.GetDelegates()) - { - Db.TryAttach(baker); - UpdateBakerPower(baker); - } - } - - protected void UpdateBakerPower(Data.Models.Delegate baker) - { - Cache.Statistics.Current.TotalBakingPower -= baker.BakingPower; - Cache.Statistics.Current.TotalVotingPower -= baker.VotingPower; - - baker.BakingPower = Proto.Helpers.BakingPower(baker); - baker.VotingPower = Proto.Helpers.VotingPower(baker); - - Cache.Statistics.Current.TotalBakingPower += baker.BakingPower; - Cache.Statistics.Current.TotalVotingPower += baker.VotingPower; - } - - protected void RevertBakersPower() - { - foreach (var baker in Cache.Accounts.GetDelegates()) - { - Db.TryAttach(baker); - RevertBakerPower(baker); - } - } - - protected void RevertBakerPower(Data.Models.Delegate baker) - { - baker.BakingPower = Proto.Helpers.BakingPower(baker); - baker.VotingPower = Proto.Helpers.VotingPower(baker); - } - - protected void ReceiveLockedRewards(Data.Models.Delegate baker, long amount) - { - baker.Balance += amount; - UpdateBakerPower(baker); - } - - protected void RevertReceiveLockedRewards(Data.Models.Delegate baker, long amount) - { - baker.Balance -= amount; - RevertBakerPower(baker); - } - - protected void BurnLockedRewards(Data.Models.Delegate baker, long amount) - { - baker.Balance -= amount; - UpdateBakerPower(baker); - } - - protected void RevertBurnLockedRewards(Data.Models.Delegate baker, long amount) - { - baker.Balance += amount; - RevertBakerPower(baker); - } - - protected void UnlockRewards(Data.Models.Delegate baker, long amount) - { - baker.OwnDelegatedBalance += amount; - UpdateBakerPower(baker); - - if (baker.Staked) - Cache.Statistics.Current.TotalOwnDelegated += amount; - } - - protected void RevertUnlockRewards(Data.Models.Delegate baker, long amount) - { - baker.OwnDelegatedBalance -= amount; - RevertBakerPower(baker); - } - protected void PayFee(Account account, long bakerFee) { Spend(account, bakerFee); - Context.Block.Fees += bakerFee; - - Context.Proposer.Balance += bakerFee; - Context.Proposer.OwnDelegatedBalance += bakerFee; - UpdateBakerPower(Context.Proposer); - - if (Context.Proposer.Staked) - Cache.Statistics.Current.TotalOwnDelegated += bakerFee; + Cache.Statistics.Current.TotalBurned += bakerFee; } protected void RevertPayFee(Account account, long bakerFee) { RevertSpend(account, bakerFee); - - Context.Proposer.Balance -= bakerFee; - Context.Proposer.OwnDelegatedBalance -= bakerFee; - RevertBakerPower(Context.Proposer); } protected void Spend(Account account, long amount) - { - var baker = Cache.Accounts.GetDelegate(account.DelegateId) ?? account as Data.Models.Delegate; - Db.TryAttach(baker); - - Spend(account, baker, amount); - } - - protected void Spend(Account account, Data.Models.Delegate? baker, long amount) { account.Balance -= amount; - - if (baker != null) - { - if (baker == account) - { - baker.OwnDelegatedBalance -= amount; - if (baker.Staked) - Cache.Statistics.Current.TotalOwnDelegated -= amount; - } - else - { - baker.ExternalDelegatedBalance -= amount; - if (baker.Staked) - Cache.Statistics.Current.TotalExternalDelegated -= amount; - } - - UpdateBakerPower(baker); - } } protected void RevertSpend(Account account, long amount) - { - var baker = Cache.Accounts.GetDelegate(account.DelegateId) ?? account as Data.Models.Delegate; - Db.TryAttach(baker); - - RevertSpend(account, baker, amount); - } - - protected void RevertSpend(Account account, Data.Models.Delegate? baker, long amount) { account.Balance += amount; - - if (baker != null) - { - if (baker == account) - baker.OwnDelegatedBalance += amount; - else - baker.ExternalDelegatedBalance += amount; - - RevertBakerPower(baker); - } } protected void Receive(Account account, long amount) - { - var baker = Cache.Accounts.GetDelegate(account.DelegateId) ?? account as Data.Models.Delegate; - Db.TryAttach(baker); - - Receive(account, baker, amount); - } - - protected void Receive(Account account, Data.Models.Delegate? baker, long amount) { account.Balance += amount; - - if (baker != null) - { - if (baker == account) - { - baker.OwnDelegatedBalance += amount; - if (baker.Staked) - Cache.Statistics.Current.TotalOwnDelegated += amount; - } - else - { - baker.ExternalDelegatedBalance += amount; - if (baker.Staked) - Cache.Statistics.Current.TotalExternalDelegated += amount; - } - - UpdateBakerPower(baker); - } } protected void RevertReceive(Account account, long amount) - { - var baker = Cache.Accounts.GetDelegate(account.DelegateId) ?? account as Data.Models.Delegate; - Db.TryAttach(baker); - - RevertReceive(account, baker, amount); - } - - protected void RevertReceive(Account account, Data.Models.Delegate? baker, long amount) { account.Balance -= amount; - - if (baker != null) - { - if (baker == account) - baker.OwnDelegatedBalance -= amount; - else - baker.ExternalDelegatedBalance -= amount; - - RevertBakerPower(baker); - } - } - - protected void ReceiveRewards(Data.Models.Delegate baker, long delegated, long stakedOwn, long stakedEdge, long stakedShared) - { - baker.Balance += delegated + stakedOwn + stakedEdge; - baker.OwnDelegatedBalance += delegated; - baker.OwnStakedBalance += stakedOwn + stakedEdge; - baker.ExternalStakedBalance += stakedShared; - UpdateBakerPower(baker); - - if (baker.Staked) - { - Cache.Statistics.Current.TotalOwnDelegated += delegated; - Cache.Statistics.Current.TotalOwnStaked += stakedOwn + stakedEdge; - Cache.Statistics.Current.TotalExternalStaked += stakedShared; - } - } - - protected void RevertReceiveRewards(Data.Models.Delegate baker, long delegated, long stakedOwn, long stakedEdge, long stakedShared) - { - baker.Balance -= delegated + stakedOwn + stakedEdge; - baker.OwnDelegatedBalance -= delegated; - baker.OwnStakedBalance -= stakedOwn + stakedEdge; - baker.ExternalStakedBalance -= stakedShared; - RevertBakerPower(baker); - } - - protected void Delegate(Account delegator, Data.Models.Delegate baker, int delegationLevel) - { - var amount = delegator.Balance - ((delegator as User)?.UnstakedBalance ?? 0); - - delegator.DelegateId = baker.Id; - delegator.DelegationLevel = delegationLevel; - delegator.Staked = baker.Staked; - - baker.DelegatorsCount++; - baker.ExternalDelegatedBalance += amount; - - UpdateBakerPower(baker); - - if (baker.Staked) - { - Cache.Statistics.Current.TotalExternalDelegated += amount; - Cache.Statistics.Current.TotalDelegators++; - } - } - - protected void Undelegate(Account delegator, Data.Models.Delegate baker) - { - var amount = delegator.Balance - ((delegator as User)?.UnstakedBalance ?? 0); - - delegator.DelegateId = null; - delegator.DelegationLevel = null; - delegator.Staked = false; - - baker.DelegatorsCount--; - baker.ExternalDelegatedBalance -= amount; - - UpdateBakerPower(baker); - - if (baker.Staked) - { - Cache.Statistics.Current.TotalExternalDelegated -= amount; - Cache.Statistics.Current.TotalDelegators--; - } } } } diff --git a/Tzkt.Sync/Protocols/ProtocolHandler.cs b/Tzkt.Sync/Protocols/ProtocolHandler.cs index 6803f5ea0..0cab8cda7 100644 --- a/Tzkt.Sync/Protocols/ProtocolHandler.cs +++ b/Tzkt.Sync/Protocols/ProtocolHandler.cs @@ -10,8 +10,8 @@ namespace Tzkt.Sync { public abstract class ProtocolHandler { - public abstract IDiagnostics Diagnostics { get; } - public abstract IHelpers Helpers { get; } + public abstract IActivator Activator { get; } + public abstract IMigrator Migrator { get; } public abstract IValidator Validator { get; } public abstract IRpc Rpc { get; } public abstract string VersionName { get; } @@ -26,11 +26,8 @@ public abstract class ProtocolHandler public readonly ILogger Logger; public readonly IMetrics Metrics; public readonly ManagerContext Manager; - public readonly InboxContext Inbox; public BlockContext Context { get; private set; } - bool _ForceDiagnostics = false; - public ProtocolHandler(TezosNode node, TzktContext db, CacheService cache, QuotesService quotes, IServiceProvider services, IConfiguration config, ILogger logger, IMetrics metrics) { Node = node; @@ -42,7 +39,6 @@ public ProtocolHandler(TezosNode node, TzktContext db, CacheService cache, Quote Logger = logger; Metrics = metrics; Manager = new(this); - Inbox = new(); Context = new(); } @@ -68,10 +64,10 @@ public virtual async Task CommitNextBlock() using var tx = await Db.Database.BeginTransactionAsync(); try { - Logger.LogDebug("Warm up cache"); - using (Metrics.Measure.Timer.Time(MetricsRegistry.CacheWarmUpTime)) + if (state.BlocksCount == 0) { - await WarmUpCache(block); + Logger.LogDebug("Activate context"); + await Activator.ActivateContext(state, block); } if (Config.Validation) @@ -92,28 +88,13 @@ public virtual async Task CommitNextBlock() Logger.LogDebug("Touch accounts"); TouchAccounts(); - var nextProtocol = this; - if (state.Protocol != state.NextProtocol) - nextProtocol = Services.GetProtocolHandler(state.Level + 1, state.NextProtocol).WithContext(Context); - Logger.LogDebug("Save changes"); using (Metrics.Measure.Timer.Time(MetricsRegistry.SaveChangesTime)) { - if (Config.Diagnostics || _ForceDiagnostics) - nextProtocol.Diagnostics.TrackChanges(); Context.Apply(Db); await Db.SaveChangesAsync(); } - Logger.LogDebug("Save post-changes"); - using (Metrics.Measure.Timer.Time(MetricsRegistry.PostProcessingTime)) - { - await AfterCommit(block); - if (Config.Diagnostics || _ForceDiagnostics) - nextProtocol.Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - } - Logger.LogDebug("Process quotes"); using (Metrics.Measure.Timer.Time(MetricsRegistry.QuotesProcessingTime)) { @@ -122,23 +103,12 @@ public virtual async Task CommitNextBlock() if (state.Protocol != state.NextProtocol) { - Logger.LogDebug("Activate protocol {hash}", state.NextProtocol); - await nextProtocol.Activate(state, block); - if (Config.Diagnostics || _ForceDiagnostics) - nextProtocol.Diagnostics.TrackChanges(); + Logger.LogDebug("Migrate to {hash}", state.NextProtocol); + var nextProtocol = Services.GetNextBlockHandler(state).WithContext(Context); + await nextProtocol.Migrator.MigrateContext(state); await Db.SaveChangesAsync(); } - if (Config.Diagnostics || _ForceDiagnostics) - { - Logger.LogDebug("Diagnostics"); - using (Metrics.Measure.Timer.Time(MetricsRegistry.DiagnosticsTime)) - { - await nextProtocol.Diagnostics.Run(block); - } - _ForceDiagnostics = false; - } - Logger.LogDebug("Commit DB transaction"); await tx.CommitAsync(); } @@ -152,7 +122,7 @@ public virtual async Task CommitNextBlock() return Cache.AppState.Get(); } - public virtual async Task RevertLastBlock(string predecessor) + public virtual async Task RevertLastBlock() { Logger.LogDebug("Begin DB transaction"); using var tx = await Db.Database.BeginTransactionAsync(); @@ -163,17 +133,12 @@ public virtual async Task RevertLastBlock(string predecessor) Logger.LogDebug("Init block context"); await InitContext(state); - Db.TryAttach(Context.Proposer); - var nextProtocol = this; if (state.Protocol != state.NextProtocol) { - nextProtocol = Services.GetProtocolHandler(state.Level + 1, state.NextProtocol); - - Logger.LogDebug("Deactivate protocol {hash}", state.NextProtocol); - await nextProtocol.Deactivate(state); - - nextProtocol.Diagnostics.TrackChanges(); + Logger.LogDebug("Revert migration to {hash}", state.NextProtocol); + var nextProtocol = Services.GetNextBlockHandler(state).WithContext(Context); + await nextProtocol.Migrator.RevertContext(state); await Db.SaveChangesAsync(); } @@ -183,42 +148,30 @@ public virtual async Task RevertLastBlock(string predecessor) await Quotes.Revert(); } - Logger.LogDebug("Revert post-changes"); - using (Metrics.Measure.Timer.Time(MetricsRegistry.RevertPostProcessingTime)) - { - await BeforeRevert(); - - nextProtocol.Diagnostics.TrackChanges(); - await Db.SaveChangesAsync(); - } - Logger.LogDebug("Revert block"); using (Metrics.Measure.Timer.Time(MetricsRegistry.RevertProcessingTime)) { await Revert(); } - Logger.LogDebug("Touch accounts"); - ClearAccounts(state.Level + 1); + if (state.BlocksCount != 0) + { + Logger.LogDebug("Touch accounts"); + ClearAccounts(state.Level + 1); + } + else + { + Logger.LogDebug("Deactivate context"); + await Activator.DeactivateContext(state); + } Logger.LogDebug("Save changes"); using (Metrics.Measure.Timer.Time(MetricsRegistry.RevertSaveChangesTime)) { - nextProtocol.Diagnostics.TrackChanges(); await Context.Revert(Db); await Db.SaveChangesAsync(); } - if ((Config.Diagnostics || _ForceDiagnostics) && state.Hash == predecessor) - { - Logger.LogDebug("Diagnostics"); - using (Metrics.Measure.Timer.Time(MetricsRegistry.RevertDiagnosticsTime)) - { - await Diagnostics.Run(state.Level); - } - _ForceDiagnostics = false; - } - Logger.LogDebug("Commit DB transaction"); await tx.CommitAsync(); } @@ -232,127 +185,16 @@ public virtual async Task RevertLastBlock(string predecessor) return Cache.AppState.Get(); } - public virtual async Task WarmUpCache(JsonElement block) - { - var accounts = new HashSet(64); - var contracts = new HashSet(64); - var operations = block.RequiredArray("operations", 4); - - foreach (var op in operations[2].RequiredArray().EnumerateArray()) - { - var content = op.RequiredArray("contents", 1)[0]; - if (content.RequiredString("kind") == "activate_account") - accounts.Add(content.RequiredString("pkh")); - } - - foreach (var op in operations[3].RequiredArray().EnumerateArray()) - { - foreach (var content in op.RequiredArray("contents").EnumerateArray()) - { - accounts.Add(content.RequiredString("source")); - if (content.RequiredString("kind") == "transaction") - { - if (content.OptionalString("destination") is string dest) - { - accounts.Add(dest); - if (dest[0] == 'K') - contracts.Add(dest); - } - - if (content.Required("metadata").TryGetProperty("internal_operation_results", out var internalResults)) - foreach (var internalContent in internalResults.RequiredArray().EnumerateArray()) - { - accounts.Add(internalContent.RequiredString("source")); - if (internalContent.RequiredString("kind") == "transaction") - { - if (internalContent.OptionalString("destination") is string internalDest) - { - accounts.Add(internalDest); - if (internalDest[0] == 'K') - contracts.Add(internalDest); - } - } - } - } - } - } - - if (accounts.Count != 0) - { - await Cache.Accounts.LoadAsync(accounts); - } - if (contracts.Count != 0) - { - var contractIds = new List(); - foreach (var contract in contracts) - if (Cache.Accounts.TryGetCached(contract, out var _contract)) - contractIds.Add(_contract.Id); - - if (contractIds.Count != 0) - { - await Cache.Storages.PreloadAsync(contractIds); - await Cache.Schemas.PreloadAsync(contractIds); - } - } - } - - public virtual Task Activate(AppState state, JsonElement block) => Task.CompletedTask; - - public virtual Task Deactivate(AppState state) => Task.CompletedTask; - - public virtual Task AfterCommit(JsonElement block) => Task.CompletedTask; - - public virtual Task BeforeRevert() => Task.CompletedTask; - public abstract Task Commit(JsonElement block); public abstract Task Revert(); - public void ForceDiagnostics() => _ForceDiagnostics = true; - async Task InitContext(AppState state) { var currBlock = Cache.Blocks.Get(state.Level); Context.Block = currBlock; - Context.Proposer = Cache.Accounts.GetDelegate(currBlock.ProposerId!.Value); Context.Protocol = await Cache.Protocols.GetAsync(currBlock.ProtoCode); - if (currBlock.Operations.HasFlag(Operations.Attestations)) - Context.AttestationOps = await Db.AttestationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.Preattestations)) - Context.PreattestationOps = await Db.PreattestationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.Proposals)) - Context.ProposalOps = await Db.ProposalOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.Ballots)) - Context.BallotOps = await Db.BallotOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.Activations)) - Context.ActivationOps = await Db.ActivationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.DalEntrapmentEvidence)) - Context.DalEntrapmentEvidenceOps = await Db.DalEntrapmentEvidenceOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.DoubleBakings)) - Context.DoubleBakingOps = await Db.DoubleBakingOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.DoubleConsensus)) - Context.DoubleConsensusOps = await Db.DoubleConsensusOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.Revelations)) - Context.NonceRevelationOps = await Db.NonceRevelationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.VdfRevelation)) - Context.VdfRevelationOps = await Db.VdfRevelationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.DrainDelegate)) - Context.DrainDelegateOps = await Db.DrainDelegateOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.Delegations)) - Context.DelegationOps = await Db.DelegationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Operations.HasFlag(Operations.Originations)) Context.OriginationOps = await Db.OriginationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); @@ -365,87 +207,15 @@ async Task InitContext(AppState state) if (currBlock.Operations.HasFlag(Operations.RegisterConstant)) Context.RegisterConstantOps = await Db.RegisterConstantOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Operations.HasFlag(Operations.SetDepositsLimits)) - Context.SetDepositsLimitOps = await Db.SetDepositsLimitOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Operations.HasFlag(Operations.IncreasePaidStorage)) Context.IncreasePaidStorageOps = await Db.IncreasePaidStorageOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Operations.HasFlag(Operations.UpdateSecondaryKey)) - Context.UpdateSecondaryKeyOps = await Db.UpdateSecondaryKeyOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Operations.HasFlag(Operations.TransferTicket)) Context.TransferTicketOps = await Db.TransferTicketOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Operations.HasFlag(Operations.SetDelegateParameters)) - Context.SetDelegateParametersOps = await Db.SetDelegateParametersOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.DalPublishCommitment)) - Context.DalPublishCommitmentOps = await Db.DalPublishCommitmentOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.Staking)) - Context.StakingOps = await Db.StakingOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.TxRollupOrigination)) - Context.TxRollupOriginationOps = await Db.TxRollupOriginationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.TxRollupSubmitBatch)) - Context.TxRollupSubmitBatchOps = await Db.TxRollupSubmitBatchOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.TxRollupCommit)) - Context.TxRollupCommitOps = await Db.TxRollupCommitOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.TxRollupFinalizeCommitment)) - Context.TxRollupFinalizeCommitmentOps = await Db.TxRollupFinalizeCommitmentOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.TxRollupRemoveCommitment)) - Context.TxRollupRemoveCommitmentOps = await Db.TxRollupRemoveCommitmentOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.TxRollupReturnBond)) - Context.TxRollupReturnBondOps = await Db.TxRollupReturnBondOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.TxRollupRejection)) - Context.TxRollupRejectionOps = await Db.TxRollupRejectionOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.TxRollupDispatchTickets)) - Context.TxRollupDispatchTicketsOps = await Db.TxRollupDispatchTicketsOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.SmartRollupAddMessages)) - Context.SmartRollupAddMessagesOps = await Db.SmartRollupAddMessagesOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.SmartRollupCement)) - Context.SmartRollupCementOps = await Db.SmartRollupCementOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.SmartRollupExecute)) - Context.SmartRollupExecuteOps = await Db.SmartRollupExecuteOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.SmartRollupOriginate)) - Context.SmartRollupOriginateOps = await Db.SmartRollupOriginateOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.SmartRollupPublish)) - Context.SmartRollupPublishOps = await Db.SmartRollupPublishOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.SmartRollupRecoverBond)) - Context.SmartRollupRecoverBondOps = await Db.SmartRollupRecoverBondOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.SmartRollupRefute)) - Context.SmartRollupRefuteOps = await Db.SmartRollupRefuteOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Operations.HasFlag(Operations.Migrations)) Context.MigrationOps = await Db.MigrationOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Operations.HasFlag(Operations.RevelationPenalty)) - Context.RevelationPenaltyOps = await Db.RevelationPenaltyOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.AttestationRewards)) - Context.AttestationRewardOps = await Db.AttestationRewardOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.DalAttestationReward)) - Context.DalAttestationRewardOps = await Db.DalAttestationRewardOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - - if (currBlock.Operations.HasFlag(Operations.Autostaking)) - Context.AutostakingOps = await Db.AutostakingOps.AsNoTracking().Where(x => x.Level == currBlock.Level).ToListAsync(); - if (currBlock.Events.HasFlag(BlockEvents.NewAccounts)) { var createdAccounts = await Db.Accounts diff --git a/Tzkt.Sync/Protocols/TezosProtocols.cs b/Tzkt.Sync/Protocols/TezosProtocols.cs index 709bd0b7e..fd539baec 100644 --- a/Tzkt.Sync/Protocols/TezosProtocols.cs +++ b/Tzkt.Sync/Protocols/TezosProtocols.cs @@ -1,4 +1,5 @@ -using Tzkt.Sync.Protocols; +using Tzkt.Data.Models; +using Tzkt.Sync.Protocols; namespace Tzkt.Sync { @@ -13,93 +14,46 @@ public static class TezosProtocols public static void AddTezosProtocols(this IServiceCollection services) { - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); services.AddScoped(); } - public static ProtocolHandler GetProtocolHandler(this IServiceProvider services, int level, string protocol) + public static ProtocolHandler GetNextBlockHandler(this IServiceProvider services, AppState state) { - if (level > 1) + return GetProtocolOrFallbackHandler(services, state.NextProtocol); + } + + public static ProtocolHandler GetCurrentBlockHandler(this IServiceProvider services, AppState state) + { + return GetProtocolOrFallbackHandler(services, state.Protocol); + } + + private static ProtocolHandler GetProtocolOrFallbackHandler(IServiceProvider services, string protocol) + { + var protocolHandler = GetProtocolHandler(services, protocol); + if (protocolHandler != null) + { + return protocolHandler; + } + + var fallback = GetFallback(services); + if (fallback != null) { - var protocolHandler = GetProtocolHandler(services, protocol); + protocolHandler = GetProtocolHandler(services, fallback); if (protocolHandler != null) { return protocolHandler; } - var fallback = GetFallback(services); - if (fallback != null) - { - protocolHandler = GetProtocolHandler(services, fallback); - if (protocolHandler != null) - { - return protocolHandler; - } - } - throw new NotImplementedException($"Protocol '{protocol}' is not supported"); - } - else if (level == 1) - { - return services.GetRequiredService(); - } - else - { - return services.GetRequiredService(); } + + throw new NotImplementedException($"Protocol '{protocol}' is not supported"); } private static ProtocolHandler? GetProtocolHandler(IServiceProvider services, string protocol) { return protocol switch { - "PtCJ7pwoxe8JasnHY8YonnLYjcVHmhiARPJvqcC6VfHT5s8k8sY" => services.GetRequiredService(), - "PsYLVpVvgbLhAhoqAkMFUo6gudkJ9weNXhUYCiLDzcUpFpkk8Wt" => services.GetRequiredService(), - "PsddFKi32cMJ2qPjf43Qv5GDWLDPZb3T3bF6fLKiF5HtvHNU7aP" => services.GetRequiredService(), - "Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd" => services.GetRequiredService(), - "PsBabyM1eUXZseaJdmXFApDSBqj8YBfwELoxZHHW77EMcAbbwAS" => services.GetRequiredService(), - "PsCARTHAGazKbHtnKfLzQg3kms52kSRpgnDY982a9oYsSXRLQEb" => services.GetRequiredService(), - "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo" => services.GetRequiredService(), - "PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA" => services.GetRequiredService(), - "PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i" => services.GetRequiredService(), - "PtGRANADsDU8R9daYKAgWnQYAJ64omN1o3KMGVCykShA97vQbvV" => services.GetRequiredService(), - "PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx" => services.GetRequiredService(), - "Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A" => services.GetRequiredService(), - "PtJakart2xVj7pYXJBXrqHgd82rdkLey5ZeeGwDgPp9rhQUbSqY" => services.GetRequiredService(), - "PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg" => services.GetRequiredService(), - "PtLimaPtLMwfNinJi9rCfDPWea8dFgTZ1MeJ9f1m2SRic6ayiwW" => services.GetRequiredService(), - "PtMumbaiiFFEGbew1rRjzSPyzRbA51Tm3RVZL5suHPxSZYDhCEc" => services.GetRequiredService(), - "PtMumbai2TmsJHNGRkD8v8YDbtao7BLUC3wjASn1inAKLFCjaH1" => services.GetRequiredService(), - "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf" => services.GetRequiredService(), - "ProxfordYmVfjWnRcgjWH36fW6PArwqykTFzotUxRs6gmTcZDuH" => services.GetRequiredService(), - "PtParisBQscdCm6Cfow6ndeU6wKJyA3aV1j4D3gQBQMsTQyJCrz" => services.GetRequiredService(), - "PtParisBxoLz5gzMmn3d9WBQNoPSZakgnkMC2VNuQ3KXfUtUQeZ" => services.GetRequiredService(), - "PsParisCZo7KAh1Z1smVd9ZMZ1HHn5gkzbM94V3PLCpknFWhUAi" => services.GetRequiredService(), - "PsQuebecnLByd3JwTiGadoG4nGWi3HYiLXUjkibeFV8dCFeVMUg" => services.GetRequiredService(), - "PsRiotumaAMotcRoDWW1bysEhQy2n1M5fy8JgRp8jjRfHGmfeA7" => services.GetRequiredService(), - "PtSeouLouXkxhg39oWzjxDWaCydNfR3RxCUrNe4Q9Ro8BTehcbh" => services.GetRequiredService(), + "PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i" => services.GetRequiredService(), + "Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P" => services.GetRequiredService(), "PtTALLiNtPec7mE7yY4m3k26J8Qukef3E3ehzhfXgFZKGtDdAXu" => services.GetRequiredService(), _ => null, }; diff --git a/Tzkt.Sync/Protocols/TezosProtocolsConfig.cs b/Tzkt.Sync/Protocols/TezosProtocolsConfig.cs index 2473f04ff..2eb1c782d 100644 --- a/Tzkt.Sync/Protocols/TezosProtocolsConfig.cs +++ b/Tzkt.Sync/Protocols/TezosProtocolsConfig.cs @@ -2,7 +2,6 @@ { public class TezosProtocolsConfig { - public bool Diagnostics { get; set; } = false; public bool Validation { get; set; } = true; public List? Precompiles { get; set; } = null; } diff --git a/Tzkt.Sync/Services/Cache/AppStateCache.cs b/Tzkt.Sync/Services/Cache/AppStateCache.cs index 82aa92811..83059a5cf 100644 --- a/Tzkt.Sync/Services/Cache/AppStateCache.cs +++ b/Tzkt.Sync/Services/Cache/AppStateCache.cs @@ -211,12 +211,12 @@ public int GetManagerCounter() public void IncreaseManagerCounter(int value) { - AppState.ManagerCounter += value; + //AppState.ManagerCounter += value; } public void ReleaseManagerCounter() { - --AppState.ManagerCounter; + //--AppState.ManagerCounter; } } } diff --git a/Tzkt.Sync/Services/EvmNode/EvmNode.cs b/Tzkt.Sync/Services/EvmNode/EvmNode.cs new file mode 100644 index 000000000..1738eddca --- /dev/null +++ b/Tzkt.Sync/Services/EvmNode/EvmNode.cs @@ -0,0 +1,89 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Tzkt.Sync.Services +{ + public sealed class EvmNode : IDisposable + { + readonly TzktClient _client; + readonly ILogger _logger; + + public EvmNode(IConfiguration config, ILogger logger) + { + var nodeConfig = config.GetEvmNodeConfig(); + _client = new TzktClient(nodeConfig.Endpoint, nodeConfig.Timeout); + _logger = logger; + } + + public async Task PostAsync(string method, params object[] args) + { + try + { + var request = new JsonRpcRequest(method, args); + var response = await _client.PostAsync>(string.Empty, JsonSerializer.Serialize(request)); + + if (response.RequestId != request.Id) + throw new Exception("Invalid RPC response id"); + + if (response.Error != null) + throw new Exception(response.Error.Message); + + return response.Result!; + } + catch (Exception ex) + { + _logger.LogError(ex, "RPC request ({method}) failed", method); + throw; + } + } + + public void Dispose() => _client.Dispose(); + + class JsonRpcRequest(string method, params object[] args) + { + [JsonPropertyName("jsonrpc")] + public string Version { get; private set; } = "2.0"; + + [JsonPropertyName("id")] + public int Id { get; private set; } = 0; + + [JsonPropertyName("method")] + public string Method { get; private set; } = method; + + [JsonPropertyName("params")] + public object[] Params { get; private set; } = args; + } + + class JsonRpcResponse + { + [JsonPropertyName("jsonrpc")] + public required string Version { get; set; } + + [JsonPropertyName("id")] + public required int RequestId { get; set; } + + [JsonPropertyName("result")] + public T? Result { get; set; } + + [JsonPropertyName("error")] + public JsonRpcError? Error { get; set; } + } + + class JsonRpcError + { + [JsonPropertyName("code")] + public required int Code { get; set; } + + [JsonPropertyName("message")] + public required string Message { get; set; } + } + } + + public static class EvmNodeExt + { + public static void AddEvmNode(this IServiceCollection services) + { + services.AddSingleton(); + } + } +} diff --git a/Tzkt.Sync/Services/EvmNode/EvmNodeConfig.cs b/Tzkt.Sync/Services/EvmNode/EvmNodeConfig.cs new file mode 100644 index 000000000..4a9361732 --- /dev/null +++ b/Tzkt.Sync/Services/EvmNode/EvmNodeConfig.cs @@ -0,0 +1,17 @@ +namespace Tzkt.Sync.Services +{ + public class EvmNodeConfig + { + public required string Endpoint { get; set; } + public int Timeout { get; set; } = 10; + } + + public static class EvmNodeConfigExt + { + public static EvmNodeConfig GetEvmNodeConfig(this IConfiguration config) + { + return config.GetSection("EvmNode")?.Get() + ?? throw new Exception("EvmNode is not configured"); + } + } +} diff --git a/Tzkt.Sync/Services/Observer/ObserverService.cs b/Tzkt.Sync/Services/Observer/ObserverService.cs index 856a2a8dc..8be0a740d 100644 --- a/Tzkt.Sync/Services/Observer/ObserverService.cs +++ b/Tzkt.Sync/Services/Observer/ObserverService.cs @@ -179,7 +179,7 @@ private async Task AdvanceLocalBranch(CancellationToken cancellationToken) using (_metrics.Measure.Timer.Time(MetricsRegistry.ApplyBlockTime)) { using var scope = _services.CreateScope(); - var protocol = scope.ServiceProvider.GetProtocolHandler(_appState.Level + 1, _appState.NextProtocol); + var protocol = scope.ServiceProvider.GetNextBlockHandler(_appState); _appState = await protocol.CommitNextBlock(); } _metrics.Measure.Gauge.SetHealthValue(_appState); @@ -202,7 +202,7 @@ private async Task AdvanceLocalBranch(CancellationToken cancellationToken) private async Task RebaseLocalBranch(CancellationToken cancellationToken) { - while (_appState.Level >= 0 && !cancellationToken.IsCancellationRequested) + while (_appState.BlocksCount > 0 && !cancellationToken.IsCancellationRequested) { try { @@ -213,8 +213,8 @@ private async Task RebaseLocalBranch(CancellationToken cancellationToken) using (_metrics.Measure.Timer.Time(MetricsRegistry.RevertBlockTime)) { using var scope = _services.CreateScope(); - var protocol = scope.ServiceProvider.GetProtocolHandler(_appState.Level, _appState.Protocol); - _appState = await protocol.RevertLastBlock(remote.Predecessor); + var protocol = scope.ServiceProvider.GetCurrentBlockHandler(_appState); + _appState = await protocol.RevertLastBlock(); } _metrics.Measure.Gauge.SetHealthValue(_appState); _logger.LogInformation("Reverted to {level} of {total}", _appState.Level, _appState.KnownHead); diff --git a/Tzkt.Sync/Tzkt.Sync.csproj b/Tzkt.Sync/Tzkt.Sync.csproj index 5132a60fd..773b755b4 100644 --- a/Tzkt.Sync/Tzkt.Sync.csproj +++ b/Tzkt.Sync/Tzkt.Sync.csproj @@ -33,19 +33,4 @@ - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - diff --git a/Tzkt.Sync/appsettings.json b/Tzkt.Sync/appsettings.json index 056e18004..14cba86a1 100644 --- a/Tzkt.Sync/appsettings.json +++ b/Tzkt.Sync/appsettings.json @@ -7,13 +7,18 @@ "LessReorgs": true }, "Protocols": { - "Diagnostics": false, "Validation": true, "Fallback": null, - "Precompiles": [] + "Precompiles": [ + "KT18oDJJKXMKhfE1bSuAPGp92pYcwVDiqsPw" + ] + }, + "EvmNode": { + "Endpoint": "https://demo.txpark.nomadic-labs.com/rpc", + "Timeout": 10 }, "TezosNode": { - "Endpoint": "https://rpc.tzkt.io/mainnet/", + "Endpoint": "https://demo.txpark.nomadic-labs.com/rpc/tezlink", "Timeout": 60 }, "Quotes": {