-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
165 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
namespace Tzkt.Data.Models | ||
{ | ||
public class ContractEvent | ||
{ | ||
public int Id { get; set; } | ||
public int Level { get; set; } | ||
public int ContractId { get; set; } | ||
public int TransactionId { get; set; } | ||
|
||
public string Tag { get; set; } | ||
public byte[] Type { get; set; } | ||
public byte[] RawPayload { get; set; } | ||
public string JsonPayload { get; set; } | ||
} | ||
|
||
public static class ContractEventModel | ||
{ | ||
public static void BuildContractEventModel(this ModelBuilder modelBuilder) | ||
{ | ||
#region keys | ||
modelBuilder.Entity<ContractEvent>() | ||
.HasKey(x => x.Id); | ||
#endregion | ||
|
||
#region props | ||
modelBuilder.Entity<ContractEvent>() | ||
.Property(x => x.JsonPayload) | ||
.HasColumnType("jsonb"); | ||
#endregion | ||
|
||
#region indexes | ||
modelBuilder.Entity<ContractEvent>() | ||
.HasIndex(x => x.Id) | ||
.IsUnique(); | ||
|
||
modelBuilder.Entity<ContractEvent>() | ||
.HasIndex(x => x.Level); | ||
|
||
modelBuilder.Entity<ContractEvent>() | ||
.HasIndex(x => x.ContractId); | ||
|
||
modelBuilder.Entity<ContractEvent>() | ||
.HasIndex(x => x.TransactionId); | ||
|
||
modelBuilder.Entity<ContractEvent>() | ||
.HasIndex(x => x.Tag); | ||
|
||
modelBuilder.Entity<ContractEvent>() | ||
.HasIndex(x => new { x.ContractId, x.Tag }); | ||
|
||
modelBuilder.Entity<ContractEvent>() | ||
.HasIndex(x => x.JsonPayload) | ||
.HasMethod("gin") | ||
.HasOperators("jsonb_path_ops"); | ||
#endregion | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
Tzkt.Sync/Protocols/Handlers/Proto14/Commits/ContractEventCommit.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.Extensions.Logging; | ||
using Netezos.Contracts; | ||
using Netezos.Encoding; | ||
using Tzkt.Data.Models; | ||
using Tzkt.Data.Models.Base; | ||
|
||
namespace Tzkt.Sync.Protocols.Proto14 | ||
{ | ||
class ContractEventCommit : ProtocolCommit | ||
{ | ||
public ContractEventCommit(ProtocolHandler protocol) : base(protocol) { } | ||
|
||
public virtual async Task Apply(Block block, JsonElement content) | ||
{ | ||
#region init | ||
var contract = await Cache.Accounts.GetAsync(content.RequiredString("source")) as Contract; | ||
var parentTx = block.Transactions.OrderByDescending(x => x.Id).FirstOrDefault(x => x.Target?.Id == 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.RequiredInt64("consumed_milligas") + 999) / 1000); | ||
|
||
var contractEvent = new ContractEvent | ||
{ | ||
Id = Cache.AppState.NextOperationId(), | ||
Level = block.Level, | ||
ContractId = contract.Id, | ||
TransactionId = parentTx.Id, | ||
Tag = content.RequiredString("tag") | ||
}; | ||
|
||
try | ||
{ | ||
var type = Micheline.FromJson(content.Required("type")); | ||
var rawPayload = Micheline.FromJson(content.Required("payload")); | ||
var schema = Schema.Create(type as MichelinePrim); | ||
contractEvent.JsonPayload = schema.Humanize(rawPayload); | ||
contractEvent.RawPayload = schema.Optimize(rawPayload).ToBytes(); | ||
contractEvent.Type = type.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--; | ||
|
||
var state = Cache.AppState.Get(); | ||
Db.TryAttach(state); | ||
state.EventsCount--; | ||
} | ||
|
||
await Db.Database.ExecuteSqlRawAsync($@"DELETE FROM ""Events"" WHERE ""Level"" = {block.Level};"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters