Exemple #1
0
 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);
 }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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(