public override IAccountStateDelta Execute(IActionContext context) { var states = context.PreviousStates; var shardedShopAddress = ShardedShopStateV2.DeriveAddress(itemSubType, orderId); var inventoryAddress = sellerAvatarAddress.Derive(LegacyInventoryKey); var worldInformationAddress = sellerAvatarAddress.Derive(LegacyWorldInformationKey); var questListAddress = sellerAvatarAddress.Derive(LegacyQuestListKey); var orderDigestListAddress = OrderDigestListState.DeriveAddress(sellerAvatarAddress); var itemAddress = Addresses.GetItemAddress(tradableId); if (context.Rehearsal) { states = states.SetState(shardedShopAddress, MarkChanged); return(states .SetState(inventoryAddress, MarkChanged) .SetState(worldInformationAddress, MarkChanged) .SetState(questListAddress, MarkChanged) .SetState(orderDigestListAddress, MarkChanged) .SetState(itemAddress, MarkChanged) .SetState(sellerAvatarAddress, MarkChanged)); } CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context); var addressesHex = GetSignerAndOtherAddressesHex(context, sellerAvatarAddress); var sw = new Stopwatch(); sw.Start(); var started = DateTimeOffset.UtcNow; Log.Verbose("{AddressesHex}Sell Cancel exec started", addressesHex); if (!states.TryGetAvatarStateV2(context.Signer, sellerAvatarAddress, out var avatarState, out _)) { throw new FailedLoadStateException( $"{addressesHex}Aborted as the avatar state of the seller failed to load."); } sw.Stop(); Log.Verbose("{AddressesHex}Sell Cancel 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); } if (!states.TryGetState(shardedShopAddress, out BxDictionary shopStateDict)) { throw new FailedLoadStateException($"{addressesHex}failed to load {nameof(ShardedShopStateV2)}({shardedShopAddress})."); } sw.Stop(); Log.Verbose("{AddressesHex}Sell Cancel Get ShopState: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); if (!states.TryGetState(Order.DeriveAddress(orderId), out Dictionary orderDict)) { throw new FailedLoadStateException($"{addressesHex}failed to load {nameof(Order)}({Order.DeriveAddress(orderId)})."); } Order order = OrderFactory.Deserialize(orderDict); order.ValidateCancelOrder2(avatarState, tradableId); ITradableItem sellItem = order.Cancel2(avatarState, context.BlockIndex); var shardedShopState = new ShardedShopStateV2(shopStateDict); shardedShopState.Remove(order, context.BlockIndex); states = states.SetState(shardedShopAddress, shardedShopState.Serialize()); if (!states.TryGetState(orderDigestListAddress, out Dictionary rawList)) { throw new FailedLoadStateException($"{addressesHex}failed to load {nameof(OrderDigest)}({orderDigestListAddress})."); } var digestList = new OrderDigestListState(rawList); digestList.Remove(order.OrderId); var expirationMail = avatarState.mailBox.OfType <OrderExpirationMail>() .FirstOrDefault(m => m.OrderId.Equals(orderId)); if (!(expirationMail is null)) { avatarState.mailBox.Remove(expirationMail); } var mail = new CancelOrderMail( context.BlockIndex, orderId, context.BlockIndex, orderId ); avatarState.Update(mail); avatarState.updatedAt = context.BlockIndex; avatarState.blockIndex = context.BlockIndex; sw.Stop(); Log.Verbose("{AddressesHex}Sell Cancel Update AvatarState: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); states = states .SetState(itemAddress, sellItem.Serialize()) .SetState(orderDigestListAddress, digestList.Serialize()) .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 Cancel Set AvatarState: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); sw.Stop(); var ended = DateTimeOffset.UtcNow; Log.Verbose("{AddressesHex}Sell Cancel Set ShopState: {Elapsed}", addressesHex, sw.Elapsed); Log.Verbose("{AddressesHex}Sell Cancel Total Executed Time: {Elapsed}", addressesHex, ended - started); return(states); }
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); }