public void Add(OrderDigest orderDigest, long blockIndex) { if (_orderDigestList.Exists(o => o.OrderId.Equals(orderDigest.OrderId))) { throw new DuplicateOrderIdException($"{orderDigest.OrderId} Already Exist."); } _orderDigestList.Add(orderDigest); CleanUp(blockIndex); }
public void Remove(Order order, long blockIndex) { OrderDigest orderDigest = _orderDigestList .FirstOrDefault(o => o.OrderId.Equals(order.OrderId) && o.SellerAgentAddress.Equals(order.SellerAgentAddress) && o.TradableId.Equals(order.TradableId) ); if (orderDigest is null) { throw new OrderIdDoesNotExistException($"Can't find {nameof(OrderDigest)}: {order.OrderId}"); } _orderDigestList.Remove(orderDigest); CleanUp(blockIndex); }
public void Execute( ItemType itemType, bool orderExist, int itemCount, bool backward ) { var avatarState = _initialState.GetAvatarState(_avatarAddress); ITradableItem tradableItem; switch (itemType) { case ItemType.Consumable: tradableItem = ItemFactory.CreateItemUsable( _tableSheets.ConsumableItemSheet.First, Guid.NewGuid(), 0); break; case ItemType.Costume: tradableItem = ItemFactory.CreateCostume( _tableSheets.CostumeItemSheet.First, Guid.NewGuid()); break; case ItemType.Equipment: tradableItem = ItemFactory.CreateItemUsable( _tableSheets.EquipmentItemSheet.First, Guid.NewGuid(), 0); break; case ItemType.Material: var tradableMaterialRow = _tableSheets.MaterialItemSheet.OrderedList .First(row => row.ItemSubType == ItemSubType.Hourglass); tradableItem = ItemFactory.CreateTradableMaterial(tradableMaterialRow); break; default: throw new ArgumentOutOfRangeException(nameof(itemType), itemType, null); } Assert.Equal(0, tradableItem.RequiredBlockIndex); avatarState.inventory.AddItem2((ItemBase)tradableItem, itemCount); var previousStates = _initialState; if (backward) { previousStates = previousStates.SetState(_avatarAddress, avatarState.Serialize()); } else { previousStates = previousStates .SetState(_avatarAddress.Derive(LegacyInventoryKey), avatarState.inventory.Serialize()) .SetState(_avatarAddress.Derive(LegacyWorldInformationKey), avatarState.worldInformation.Serialize()) .SetState(_avatarAddress.Derive(LegacyQuestListKey), avatarState.questList.Serialize()) .SetState(_avatarAddress, avatarState.SerializeV2()); } var currencyState = previousStates.GetGoldCurrency(); var price = new FungibleAssetValue(currencyState, ProductPrice, 0); var orderId = new Guid("6f460c1a755d48e4ad6765d5f519dbc8"); var existOrderId = new Guid("229e5f8c-fabe-4c04-bab9-45325cfa69a4"); var orderAddress = Order.DeriveAddress(orderId); var shardedShopAddress = ShardedShopStateV2.DeriveAddress( tradableItem.ItemSubType, orderId); long blockIndex = 1; if (orderExist) { var shardedShopState = new ShardedShopStateV2(shardedShopAddress); var existOrder = OrderFactory.Create( _agentAddress, _avatarAddress, existOrderId, price, tradableItem.TradableId, 0, tradableItem.ItemSubType, 1 ); existOrder.Sell2(avatarState); blockIndex = existOrder.ExpiredBlockIndex; shardedShopState.Add(existOrder.Digest2(avatarState, _tableSheets.CostumeStatSheet), blockIndex); Assert.Single(shardedShopState.OrderDigestList); previousStates = previousStates.SetState( shardedShopAddress, shardedShopState.Serialize()); } else { Assert.Null(previousStates.GetState(shardedShopAddress)); } var sellAction = new Sell7 { sellerAvatarAddress = _avatarAddress, tradableId = tradableItem.TradableId, count = itemCount, price = price, itemSubType = tradableItem.ItemSubType, orderId = orderId, }; var nextState = sellAction.Execute(new ActionContext { BlockIndex = blockIndex, PreviousStates = previousStates, Rehearsal = false, Signer = _agentAddress, Random = new TestRandom(), }); long expiredBlockIndex = Order.ExpirationInterval + blockIndex; // Check AvatarState and Inventory var nextAvatarState = nextState.GetAvatarStateV2(_avatarAddress); Assert.Single(nextAvatarState.inventory.Items); Assert.True(nextAvatarState.inventory.TryGetTradableItems( tradableItem.TradableId, expiredBlockIndex, 1, out var inventoryItems)); Assert.Single(inventoryItems); ITradableItem nextTradableItem = (ITradableItem)inventoryItems.First().item; Assert.Equal(expiredBlockIndex, nextTradableItem.RequiredBlockIndex); // Check ShardedShopState var nextSerializedShardedShopState = nextState.GetState(shardedShopAddress); Assert.NotNull(nextSerializedShardedShopState); var nextShardedShopState = new ShardedShopStateV2((Dictionary)nextSerializedShardedShopState); var expectedCount = orderExist ? 2 : 1; Assert.Equal(expectedCount, nextShardedShopState.OrderDigestList.Count); var orderDigest = nextShardedShopState.OrderDigestList.First(o => o.OrderId.Equals(orderId)); Assert.Equal(price, orderDigest.Price); Assert.Equal(blockIndex, orderDigest.StartedBlockIndex); Assert.Equal(expiredBlockIndex, orderDigest.ExpiredBlockIndex); Assert.Equal(((ItemBase)tradableItem).Id, orderDigest.ItemId); Assert.Equal(tradableItem.TradableId, orderDigest.TradableId); var serializedOrder = nextState.GetState(orderAddress); Assert.NotNull(serializedOrder); var serializedItem = nextState.GetState(Addresses.GetItemAddress(tradableItem.TradableId)); Assert.NotNull(serializedItem); var order = OrderFactory.Deserialize((Dictionary)serializedOrder); ITradableItem orderItem = (ITradableItem)ItemFactory.Deserialize((Dictionary)serializedItem); Assert.Equal(price, order.Price); Assert.Equal(orderId, order.OrderId); Assert.Equal(tradableItem.TradableId, order.TradableId); Assert.Equal(blockIndex, order.StartedBlockIndex); Assert.Equal(expiredBlockIndex, order.ExpiredBlockIndex); Assert.Equal(_agentAddress, order.SellerAgentAddress); Assert.Equal(_avatarAddress, order.SellerAvatarAddress); Assert.Equal(expiredBlockIndex, orderItem.RequiredBlockIndex); var mailList = nextAvatarState.mailBox.OfType <OrderExpirationMail>().ToList(); Assert.Single(mailList); var mail = mailList.First(); Assert.NotNull(mail); Assert.Equal(expiredBlockIndex, mail.requiredBlockIndex); Assert.Equal(orderId, mail.OrderId); var receiptDict = nextState.GetState(OrderDigestListState.DeriveAddress(_avatarAddress)); Assert.NotNull(receiptDict); var orderDigestList = new OrderDigestListState((Dictionary)receiptDict); Assert.Single(orderDigestList.OrderDigestList); OrderDigest orderDigest2 = orderDigestList.OrderDigestList.First(); Assert.Equal(orderDigest, orderDigest2); }
public override IAccountStateDelta Execute(IActionContext context) { var states = context.PreviousStates; var inventoryAddress = sellerAvatarAddress.Derive(LegacyInventoryKey); var worldInformationAddress = sellerAvatarAddress.Derive(LegacyWorldInformationKey); var questListAddress = sellerAvatarAddress.Derive(LegacyQuestListKey); Address shopAddress = ShardedShopStateV2.DeriveAddress(itemSubType, orderId); Address itemAddress = Addresses.GetItemAddress(tradableId); Address orderAddress = Order.DeriveAddress(orderId); Address orderReceiptAddress = OrderDigestListState.DeriveAddress(sellerAvatarAddress); if (context.Rehearsal) { return(states .SetState(context.Signer, MarkChanged) .SetState(shopAddress, MarkChanged) .SetState(itemAddress, MarkChanged) .SetState(orderAddress, MarkChanged) .SetState(orderReceiptAddress, MarkChanged) .SetState(inventoryAddress, MarkChanged) .SetState(worldInformationAddress, MarkChanged) .SetState(questListAddress, MarkChanged) .SetState(sellerAvatarAddress, MarkChanged)); } var addressesHex = GetSignerAndOtherAddressesHex(context, sellerAvatarAddress); var sw = new Stopwatch(); sw.Start(); var started = DateTimeOffset.UtcNow; Log.Verbose("{AddressesHex}Sell exec started", addressesHex); if (price.Sign < 0) { throw new InvalidPriceException( $"{addressesHex}Aborted as the price is less than zero: {price}."); } if (!states.TryGetAgentAvatarStatesV2( context.Signer, sellerAvatarAddress, out _, out var avatarState)) { throw new FailedLoadStateException( $"{addressesHex}Aborted as the avatar state of the signer was failed to load."); } sw.Stop(); Log.Verbose( "{AddressesHex}Sell Get AgentAvatarStates: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); if (!avatarState.worldInformation.IsStageCleared( GameConfig.RequireClearedStageLevel.ActionsInShop)) { avatarState.worldInformation.TryGetLastClearedStageId(out var current); throw new NotEnoughClearedStageLevelException( addressesHex, GameConfig.RequireClearedStageLevel.ActionsInShop, current); } sw.Stop(); Log.Verbose("{AddressesHex}Sell IsStageCleared: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); Order order = OrderFactory.Create(context.Signer, sellerAvatarAddress, orderId, price, tradableId, context.BlockIndex, itemSubType, count); order.Validate(avatarState, count); ITradableItem tradableItem = order.Sell(avatarState); var shardedShopState = states.TryGetState(shopAddress, out Dictionary serializedState) ? new ShardedShopStateV2(serializedState) : new ShardedShopStateV2(shopAddress); sw.Stop(); Log.Verbose( "{AddressesHex}Sell Get ShardedShopState: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); var costumeStatSheet = states.GetSheet <CostumeStatSheet>(); OrderDigest orderDigest = order.Digest(avatarState, costumeStatSheet); shardedShopState.Add(orderDigest, context.BlockIndex); avatarState.updatedAt = context.BlockIndex; avatarState.blockIndex = context.BlockIndex; var orderReceiptList = states.TryGetState(orderReceiptAddress, out Dictionary receiptDict) ? new OrderDigestListState(receiptDict) : new OrderDigestListState(orderReceiptAddress); orderReceiptList.Add(orderDigest); states = states.SetState(orderReceiptAddress, orderReceiptList.Serialize()); states = states .SetState(inventoryAddress, avatarState.inventory.Serialize()) .SetState(worldInformationAddress, avatarState.worldInformation.Serialize()) .SetState(questListAddress, avatarState.questList.Serialize()) .SetState(sellerAvatarAddress, avatarState.SerializeV2()); sw.Stop(); Log.Verbose("{AddressesHex}Sell Set AvatarState: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); states = states .SetState(itemAddress, tradableItem.Serialize()) .SetState(orderAddress, order.Serialize()) .SetState(shopAddress, shardedShopState.Serialize()); sw.Stop(); var ended = DateTimeOffset.UtcNow; Log.Verbose("{AddressesHex}Sell Set ShopState: {Elapsed}", addressesHex, sw.Elapsed); Log.Verbose( "{AddressesHex}Sell Total Executed Time: {Elapsed}", addressesHex, ended - started); return(states); }
public OrderDigestListStateTest() { var orderId = new Guid("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4"); var tradableId = new Guid("936DA01F-9ABD-4d9d-80C7-02AF85C822A8"); _orderDigest = new OrderDigest(