From 5bfbb753e02ba46fcf0f75d56f41ba4a246cd9b5 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Mon, 13 May 2024 11:26:50 +0900 Subject: [PATCH 1/6] return nullable long in MongoDbStore.GetLatestBlockIndex --- Mimir.Worker/BlockPoller.cs | 4 ++-- Mimir.Worker/Services/MongoDbStore.cs | 14 +++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Mimir.Worker/BlockPoller.cs b/Mimir.Worker/BlockPoller.cs index 54d669af..62ac9dfc 100644 --- a/Mimir.Worker/BlockPoller.cs +++ b/Mimir.Worker/BlockPoller.cs @@ -17,10 +17,10 @@ public async Task RunAsync(CancellationToken cancellationToken) var stateGetter = new StateGetter(stateService); while (!cancellationToken.IsCancellationRequested) { - var syncedBlockIndex = await mongoDbStore.GetLatestBlockIndex(); var currentBlockIndex = await stateService.GetLatestIndex(); + var syncedBlockIndex = await mongoDbStore.GetLatestBlockIndex() ?? currentBlockIndex - 1; var processBlockIndex = syncedBlockIndex + 1; - if (processBlockIndex >= currentBlockIndex) + if (processBlockIndex > currentBlockIndex) { await Task.Delay(TimeSpan.FromMilliseconds(3000), cancellationToken); continue; diff --git a/Mimir.Worker/Services/MongoDbStore.cs b/Mimir.Worker/Services/MongoDbStore.cs index d9fd2ec4..aefc30e4 100644 --- a/Mimir.Worker/Services/MongoDbStore.cs +++ b/Mimir.Worker/Services/MongoDbStore.cs @@ -66,11 +66,19 @@ public async Task UpdateLatestBlockIndex(long blockIndex) await MetadataCollection.BulkWriteAsync(new[] { updateModel }); } - public async Task GetLatestBlockIndex() + public async Task GetLatestBlockIndex() { var filter = Builders.Filter.Eq("_id", "SyncContext"); - var doc = await MetadataCollection.FindSync(filter).FirstAsync(); - return doc.GetValue("LatestBlockIndex").AsInt64; + try + { + var doc = await MetadataCollection.FindSync(filter).FirstAsync(); + return doc.GetValue("LatestBlockIndex").AsInt64; + } + catch (InvalidOperationException e) + { + Console.WriteLine(e); + return null; + } } public async Task BulkUpsertArenaDataAsync(List arenaDatas) From 0d9d0c39e5b83ca476536b8838c67ab2c5b173fe Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Mon, 13 May 2024 12:17:44 +0900 Subject: [PATCH 2/6] add temporary snippets to AvatarController --- Mimir/Controllers/AvatarController.cs | 81 +++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/Mimir/Controllers/AvatarController.cs b/Mimir/Controllers/AvatarController.cs index 07addee0..36faa13d 100644 --- a/Mimir/Controllers/AvatarController.cs +++ b/Mimir/Controllers/AvatarController.cs @@ -8,6 +8,87 @@ namespace Mimir.Controllers; [Route("{network}/avatars")] public class AvatarController(AvatarRepository avatarRepository) : ControllerBase { + #region temporary snippets + + // This is a snippet from Mimir/Util/BigIntegerToStringConverter.cs + private class BigIntegerToStringConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType == typeof(BigInteger); + } + + public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, + JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + writer.WriteValue(value?.ToString()); + } + } + + // This is a snippet from Mimir/Util/StateJsonConverter.cs + private class StateJsonConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return typeof(IState).IsAssignableFrom(objectType); + } + + public override object ReadJson( + JsonReader reader, + Type objectType, + object? existingValue, + JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + if (value is null) + { + return; + } + + var jo = JObject.FromObject(value, JsonSerializer.CreateDefault(new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + Converters = new List { new BigIntegerToStringConverter() }, + Formatting = Formatting.Indented, + NullValueHandling = NullValueHandling.Ignore + })); + + var iValue = value switch + { + AvatarState avatarState => avatarState.SerializeList(), + IState state => state.Serialize(), + _ => null + }; + + if (iValue != null) + { + var rawValue = ByteUtil.Hex(new Codec().Encode(iValue)); + jo.Add("Raw", rawValue); + } + + jo.WriteTo(writer); + } + } + + // This is a snippet from Mimir.Worker/Models/State/BaseData.cs + private static JsonSerializerSettings JsonSerializerSettings => new() + { + Converters = { new StateJsonConverter() }, + Formatting = Formatting.Indented, + NullValueHandling = NullValueHandling.Ignore + }; + + #endregion snippets + [HttpGet("{avatarAddress}/inventory")] public Inventory? GetInventory(string network, string avatarAddress) { From 1a12f703218b0588b284225cb3f8cc1e978b57f7 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Mon, 13 May 2024 12:18:26 +0900 Subject: [PATCH 3/6] improve inventory api --- Mimir/Controllers/AvatarController.cs | 36 +++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/Mimir/Controllers/AvatarController.cs b/Mimir/Controllers/AvatarController.cs index 36faa13d..9b35a78b 100644 --- a/Mimir/Controllers/AvatarController.cs +++ b/Mimir/Controllers/AvatarController.cs @@ -1,6 +1,16 @@ +using System.Numerics; +using Bencodex; +using Libplanet.Common; +using Libplanet.Crypto; using Microsoft.AspNetCore.Mvc; using Mimir.Models.Avatar; using Mimir.Repositories; +using Mimir.Services; +using Mimir.Util; +using MongoDB.Bson; +using Nekoyume.Model.State; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Mimir.Controllers; @@ -90,15 +100,37 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer #endregion snippets [HttpGet("{avatarAddress}/inventory")] - public Inventory? GetInventory(string network, string avatarAddress) + public async Task GetInventory( + string network, + string avatarAddress, + IStateService stateService) { var inventory = avatarRepository.GetInventory(network, avatarAddress); - if (inventory is null) + if (inventory is not null) + { + return inventory; + } + + var stateGetter = new StateGetter(stateService); + var inventoryState = await stateGetter.GetInventoryStateAsync(new Address(avatarAddress)); + if (inventoryState is null) { Response.StatusCode = StatusCodes.Status404NotFound; return null; } + try + { + var jsonString = JsonConvert.SerializeObject(inventoryState, JsonSerializerSettings); + var bsonDocument = BsonDocument.Parse(jsonString); + inventory = new Inventory(bsonDocument); + } + catch + { + Response.StatusCode = StatusCodes.Status500InternalServerError; + return null; + } + return inventory; } } From 2c68397e192ce66bdd8bf5b1cad96d0ea4ac3649 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Mon, 13 May 2024 16:08:35 +0900 Subject: [PATCH 4/6] Revert "return nullable long in MongoDbStore.GetLatestBlockIndex" This reverts commit 5bfbb753e02ba46fcf0f75d56f41ba4a246cd9b5. --- Mimir.Worker/BlockPoller.cs | 4 ++-- Mimir.Worker/Services/MongoDbStore.cs | 14 +++----------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/Mimir.Worker/BlockPoller.cs b/Mimir.Worker/BlockPoller.cs index 62ac9dfc..54d669af 100644 --- a/Mimir.Worker/BlockPoller.cs +++ b/Mimir.Worker/BlockPoller.cs @@ -17,10 +17,10 @@ public async Task RunAsync(CancellationToken cancellationToken) var stateGetter = new StateGetter(stateService); while (!cancellationToken.IsCancellationRequested) { + var syncedBlockIndex = await mongoDbStore.GetLatestBlockIndex(); var currentBlockIndex = await stateService.GetLatestIndex(); - var syncedBlockIndex = await mongoDbStore.GetLatestBlockIndex() ?? currentBlockIndex - 1; var processBlockIndex = syncedBlockIndex + 1; - if (processBlockIndex > currentBlockIndex) + if (processBlockIndex >= currentBlockIndex) { await Task.Delay(TimeSpan.FromMilliseconds(3000), cancellationToken); continue; diff --git a/Mimir.Worker/Services/MongoDbStore.cs b/Mimir.Worker/Services/MongoDbStore.cs index aefc30e4..d9fd2ec4 100644 --- a/Mimir.Worker/Services/MongoDbStore.cs +++ b/Mimir.Worker/Services/MongoDbStore.cs @@ -66,19 +66,11 @@ public async Task UpdateLatestBlockIndex(long blockIndex) await MetadataCollection.BulkWriteAsync(new[] { updateModel }); } - public async Task GetLatestBlockIndex() + public async Task GetLatestBlockIndex() { var filter = Builders.Filter.Eq("_id", "SyncContext"); - try - { - var doc = await MetadataCollection.FindSync(filter).FirstAsync(); - return doc.GetValue("LatestBlockIndex").AsInt64; - } - catch (InvalidOperationException e) - { - Console.WriteLine(e); - return null; - } + var doc = await MetadataCollection.FindSync(filter).FirstAsync(); + return doc.GetValue("LatestBlockIndex").AsInt64; } public async Task BulkUpsertArenaDataAsync(List arenaDatas) From e326212b8151fa4704364b27d80db8e2b7b5251d Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Mon, 13 May 2024 18:44:03 +0900 Subject: [PATCH 5/6] implement overloaded constructor for a sevaral models --- Mimir/Models/Avatar/Inventory.cs | 20 ++++++++++++++++---- Mimir/Models/Items/Equipment.cs | 14 ++++++++++++-- Mimir/Models/Items/Item.cs | 14 ++++++++++++-- Mimir/Models/Items/NonFungibleItem.cs | 16 +++++++++++++--- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/Mimir/Models/Avatar/Inventory.cs b/Mimir/Models/Avatar/Inventory.cs index 64d29820..e7e48538 100644 --- a/Mimir/Models/Avatar/Inventory.cs +++ b/Mimir/Models/Avatar/Inventory.cs @@ -3,9 +3,21 @@ namespace Mimir.Models.Avatar; -public class Inventory(BsonValue inventory) +public class Inventory { - public List Equipments { get; set; } = inventory["Equipments"].AsBsonArray - .Select(e => new Equipment(e.AsBsonDocument)) - .ToList(); + public List Equipments { get; set; } + + public Inventory(Nekoyume.Model.Item.Inventory inventory) + { + Equipments = inventory.Equipments + .Select(e => new Equipment(e)) + .ToList(); + } + + public Inventory(BsonValue inventory) + { + Equipments = inventory["Equipments"].AsBsonArray + .Select(e => new Equipment(e.AsBsonDocument)) + .ToList(); + } } diff --git a/Mimir/Models/Items/Equipment.cs b/Mimir/Models/Items/Equipment.cs index 599ab3aa..7ec1d86a 100644 --- a/Mimir/Models/Items/Equipment.cs +++ b/Mimir/Models/Items/Equipment.cs @@ -2,7 +2,17 @@ namespace Mimir.Models.Items; -public class Equipment(BsonValue equipment) : NonFungibleItem(equipment) +public class Equipment : NonFungibleItem { - public int Level { get; set; } = equipment["level"].AsInt32; + public int Level { get; set; } + + public Equipment(Nekoyume.Model.Item.Equipment equipment) : base(equipment) + { + Level = equipment.level; + } + + public Equipment(BsonValue equipment) : base(equipment) + { + Level = equipment["level"].AsInt32; + } } diff --git a/Mimir/Models/Items/Item.cs b/Mimir/Models/Items/Item.cs index 98145e5e..764706dc 100644 --- a/Mimir/Models/Items/Item.cs +++ b/Mimir/Models/Items/Item.cs @@ -3,7 +3,17 @@ namespace Mimir.Models.Items; -public class Item(BsonValue item) +public class Item { - public ItemSubType ItemSubType { get; set; } = (ItemSubType)item["ItemSubType"].AsInt32; + public ItemSubType ItemSubType { get; set; } + + public Item(IItem item) + { + ItemSubType = item.ItemSubType; + } + + public Item(BsonValue item) + { + ItemSubType = (ItemSubType)item["ItemSubType"].AsInt32; + } } diff --git a/Mimir/Models/Items/NonFungibleItem.cs b/Mimir/Models/Items/NonFungibleItem.cs index 335653fa..49a1cb54 100644 --- a/Mimir/Models/Items/NonFungibleItem.cs +++ b/Mimir/Models/Items/NonFungibleItem.cs @@ -1,11 +1,21 @@ using MongoDB.Bson; +using Nekoyume.Model.Item; namespace Mimir.Models.Items; -public class NonFungibleItem(BsonValue nonFungibleItem) : Item(nonFungibleItem) +public class NonFungibleItem : Item { - public Guid NonFungibleId { get; set; } = - Guid.TryParse(nonFungibleItem["NonFungibleId"].AsString, out var nonFungibleId) + public Guid NonFungibleId { get; set; } + + public NonFungibleItem(INonFungibleItem nonFungibleItem) : base(nonFungibleItem) + { + NonFungibleId = nonFungibleItem.NonFungibleId; + } + + public NonFungibleItem(BsonValue nonFungibleItem) : base(nonFungibleItem) + { + NonFungibleId = Guid.TryParse(nonFungibleItem["NonFungibleId"].AsString, out var nonFungibleId) ? nonFungibleId : Guid.Empty; + } } From d9cf28757259d25f4b8d6e1206ead91ef2c24b53 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Mon, 13 May 2024 18:44:15 +0900 Subject: [PATCH 6/6] optimize minor --- Mimir/Controllers/AvatarController.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Mimir/Controllers/AvatarController.cs b/Mimir/Controllers/AvatarController.cs index 9b35a78b..54579eb8 100644 --- a/Mimir/Controllers/AvatarController.cs +++ b/Mimir/Controllers/AvatarController.cs @@ -7,7 +7,6 @@ using Mimir.Repositories; using Mimir.Services; using Mimir.Util; -using MongoDB.Bson; using Nekoyume.Model.State; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -119,18 +118,6 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer return null; } - try - { - var jsonString = JsonConvert.SerializeObject(inventoryState, JsonSerializerSettings); - var bsonDocument = BsonDocument.Parse(jsonString); - inventory = new Inventory(bsonDocument); - } - catch - { - Response.StatusCode = StatusCodes.Status500InternalServerError; - return null; - } - - return inventory; + return new Inventory(inventoryState); } }