Skip to content

Commit

Permalink
Add /bigmaps/updates/count API endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Groxan committed Jan 3, 2024
1 parent bb88f5c commit 66e6ba9
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 11 deletions.
60 changes: 56 additions & 4 deletions Tzkt.Api/Controllers/BigMapsController.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Netezos.Encoding;
using Tzkt.Api.Models;
using Tzkt.Api.Repositories;
using Tzkt.Api.Services;
using Tzkt.Api.Services.Cache;

namespace Tzkt.Api.Controllers
{
[ApiController]
[Route("v1/bigmaps")]
public class BigMapsController : ControllerBase
{
readonly StateCache State;
readonly BigMapsRepository BigMaps;
readonly ResponseCacheService ResponseCache;

public BigMapsController(BigMapsRepository bigMaps, ResponseCacheService responseCache)
public BigMapsController(StateCache state, BigMapsRepository bigMaps, ResponseCacheService responseCache)
{
State = state;
BigMaps = bigMaps;
ResponseCache = responseCache;
}
Expand Down Expand Up @@ -159,6 +160,57 @@ public async Task<ActionResult<IEnumerable<BigMapKeyFull>>> GetBigMapKeys(
return this.Bytes(cached);
}

/// <summary>
/// Get bigmap updates count
/// </summary>
/// <remarks>
/// Returns a total number of bigmap updates.
/// </remarks>
/// <param name="bigmap">Filters by bigmap ptr</param>
/// <param name="path">Filters by bigmap path</param>
/// <param name="contract">Filters by bigmap contract</param>
/// <param name="tags">Filters by bigmap tags: `metadata`, `token_metadata`, `ledger`</param>
/// <param name="action">Filters by action</param>
/// <param name="value">Filters by JSON value. Note, this query parameter supports the following format: `?value{.path?}{.mode?}=...`,
/// so you can specify a path to a particular field to filter by, for example: `?value.balance.gt=...`.</param>
/// <param name="level">Filters by level</param>
/// <param name="timestamp">Filters by timestamp</param>
/// <returns></returns>
[HttpGet("updates/count")]
public async Task<ActionResult<IEnumerable<BigMapUpdate>>> GetBigMapUpdates(
Int32Parameter bigmap,
StringParameter path,
AccountParameter contract,
BigMapTagsParameter tags,
BigMapActionParameter action,
JsonParameter value,
Int32Parameter level,
TimestampParameter timestamp)
{
if (bigmap != null ||
path != null ||
contract != null ||
tags != null ||
action != null ||
value != null ||
level != null ||
timestamp != null)
{
var query = ResponseCacheService.BuildKey(Request.Path.Value,
("bigmap", bigmap), ("path", path), ("contract", contract), ("tags", tags),
("action", action), ("value", value), ("level", level), ("timestamp", timestamp));

if (ResponseCache.TryGet(query, out var cached))
return this.Bytes(cached);

var res = await BigMaps.GetUpdatesCount(bigmap, path, contract, action, value, tags, level, timestamp);
cached = ResponseCache.Set(query, res);
return this.Bytes(cached);
}

return Ok(State.Current.BigMapUpdateCounter);
}

/// <summary>
/// Get bigmap updates
/// </summary>
Expand Down
30 changes: 29 additions & 1 deletion Tzkt.Api/Repositories/BigMapsRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,34 @@ public async Task<IEnumerable<BigMapKeyUpdate>> GetKeyByHashUpdates(
#endregion

#region bigmap updates
public async Task<int> GetUpdatesCount(
Int32Parameter ptr,
StringParameter path,
AccountParameter contract,
BigMapActionParameter action,
JsonParameter value,
BigMapTagsParameter tags,
Int32Parameter level,
TimestampParameter timestamp)
{
var query = @"SELECT COUNT(*) FROM ""BigMapUpdates"" as u";
if (path != null || contract != null || tags != null)
query += @"\nLEFT JOIN ""BigMaps"" as b on b.""Ptr"" = u.""BigMapPtr""";

var sql = new SqlBuilder(query)
.Filter("BigMapPtr", ptr)
.Filter("StoragePath", path)
.Filter("ContractId", contract)
.Filter("Action", action)
.Filter("JsonValue", value)
.Filter("Tags", tags)
.Filter("Level", level)
.Filter("Level", timestamp);

using var db = GetConnection();
return await db.QueryFirstAsync<int>(sql.Query, sql.Params);
}

public async Task<IEnumerable<BigMapUpdate>> GetUpdates(
Int32Parameter ptr,
BigMapActionParameter action,
Expand Down Expand Up @@ -1211,7 +1239,7 @@ public async Task<IEnumerable<BigMapUpdate>> GetUpdates(
};
});
}

public async Task<IEnumerable<BigMapUpdate>> GetUpdates(
Int32Parameter ptr,
StringParameter path,
Expand Down
12 changes: 6 additions & 6 deletions Tzkt.Api/Repositories/OperationRepository.Transactions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ INNER JOIN ""Blocks"" as b
.FilterA(@"o.""SenderCodeHash""", senderCodeHash)
.FilterA(@"o.""TargetCodeHash""", targetCodeHash)
.FilterOrA(new[] { @"o.""SenderCodeHash""", @"o.""TargetCodeHash""" }, codeHash)
.Take(sort, offset, limit, x => x switch
.Take(sort, offset, Math.Max(limit, 100), x => x switch
{
"level" => ("Level", "Level"),
"gasUsed" => ("GasUsed", "GasUsed"),
Expand All @@ -389,7 +389,7 @@ INNER JOIN ""Blocks"" as b
}, "o");

using var db = GetConnection();
var rows = await db.QueryAsync(sql.Query, sql.Params);
var rows = (await db.QueryAsync(sql.Query, sql.Params)).Take(limit);

#region include storage
var storages = includeStorage
Expand Down Expand Up @@ -564,7 +564,7 @@ public async Task<object[][]> GetTransactions(
.FilterA(@"o.""SenderCodeHash""", senderCodeHash)
.FilterA(@"o.""TargetCodeHash""", targetCodeHash)
.FilterOrA(new[] { @"o.""SenderCodeHash""", @"o.""TargetCodeHash""" }, codeHash)
.Take(sort, offset, limit, x => x switch
.Take(sort, offset, Math.Max(limit, 100), x => x switch
{
"level" => ("Level", "Level"),
"gasUsed" => ("GasUsed", "GasUsed"),
Expand All @@ -577,7 +577,7 @@ public async Task<object[][]> GetTransactions(
}, "o");

using var db = GetConnection();
var rows = await db.QueryAsync(sql.Query, sql.Params);
var rows = (await db.QueryAsync(sql.Query, sql.Params)).Take(limit);

var result = new object[rows.Count()][];
for (int i = 0; i < result.Length; i++)
Expand Down Expand Up @@ -845,7 +845,7 @@ public async Task<object[]> GetTransactions(
.FilterA(@"o.""SenderCodeHash""", senderCodeHash)
.FilterA(@"o.""TargetCodeHash""", targetCodeHash)
.FilterOrA(new[] { @"o.""SenderCodeHash""", @"o.""TargetCodeHash""" }, codeHash)
.Take(sort, offset, limit, x => x switch
.Take(sort, offset, Math.Max(limit, 100), x => x switch
{
"level" => ("Level", "Level"),
"gasUsed" => ("GasUsed", "GasUsed"),
Expand All @@ -858,7 +858,7 @@ public async Task<object[]> GetTransactions(
}, "o");

using var db = GetConnection();
var rows = await db.QueryAsync(sql.Query, sql.Params);
var rows = (await db.QueryAsync(sql.Query, sql.Params)).Take(limit);

//TODO: optimize memory allocation
var result = new object[rows.Count()];
Expand Down
1 change: 1 addition & 0 deletions Tzkt.Api/Services/Cache/State/RawModels/RawState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class RawState
public int SmartRollupCommitmentCounter { get; set; }
public int RefutationGameCounter { get; set; }
public int InboxMessageCounter { get; set; }
public int BigMapUpdateCounter { get; set; }

#region entities count
public int CommitmentsCount { get; set; }
Expand Down

0 comments on commit 66e6ba9

Please sign in to comment.