public void TryUnregister() { var shopState = new ShopState(); var agentAddress = new PrivateKey().ToAddress(); var avatarAddress = new PrivateKey().ToAddress(); var productId = Guid.NewGuid(); var weaponRow = new EquipmentItemSheet.Row(); weaponRow.Set(new[] { "10100000", "Weapon", "0", "Normal", "0", "ATK", "1", "2", "10100000", }); var itemUsable = new Weapon( weaponRow, Guid.NewGuid(), 0); var price = new FungibleAssetValue(new Currency("NCG", 2, minter: null)); var shopItem = new ShopItem( agentAddress, avatarAddress, productId, itemUsable, price ); shopState.Register(shopItem); Assert.True(shopState.TryUnregister( agentAddress, shopItem.ProductId, out var unregisteredItem)); Assert.Equal(shopItem, unregisteredItem); Assert.Equal(0, shopState.Products.Count); Assert.Equal(0, shopState.AgentProducts.Count); Assert.Equal(0, shopState.ItemSubTypeProducts.Count); Assert.Throws <FailedToUnregisterInShopStateException>(() => shopState.Unregister(agentAddress, shopItem)); }
public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; if (ctx.Rehearsal) { states = states.SetState(ShopState.Address, MarkChanged); return(states.SetState(sellerAvatarAddress, MarkChanged)); } var sw = new Stopwatch(); sw.Start(); var started = DateTimeOffset.UtcNow; Log.Debug($"Sell Cancel exec started."); if (!states.TryGetAgentAvatarStates(ctx.Signer, sellerAvatarAddress, out _, out var avatarState)) { return(states); } sw.Stop(); Log.Debug($"Sell Cancel Get AgentAvatarStates: {sw.Elapsed}"); sw.Restart(); if (!avatarState.worldInformation.TryGetUnlockedWorldByStageClearedBlockIndex( out var world)) { return(states); } if (world.StageClearedId < GameConfig.RequireClearedStageLevel.ActionsInShop) { // 스테이지 클리어 부족 에러. return(states); } if (!states.TryGetState(ShopState.Address, out Bencodex.Types.Dictionary d)) { return(states); } var shopState = new ShopState(d); sw.Stop(); Log.Debug($"Sell Cancel Get ShopState: {sw.Elapsed}"); sw.Restart(); // 상점에서 아이템을 빼온다. if (!shopState.TryUnregister(ctx.Signer, productId, out var outUnregisteredItem)) { return(states); } sw.Stop(); Log.Debug($"Sell Cancel Get Unregister Item: {sw.Elapsed}"); sw.Restart(); //9c-beta 브랜치에서는 블록 인덱스도 확인 해야함 (이전 블록 유효성 보장) if (outUnregisteredItem.SellerAvatarAddress != sellerAvatarAddress) { Log.Error("Invalid Avatar Address"); return(states); } // 메일에 아이템을 넣는다. result = new Result { shopItem = outUnregisteredItem, itemUsable = outUnregisteredItem.ItemUsable }; var mail = new SellCancelMail(result, ctx.BlockIndex, ctx.Random.GenerateRandomGuid(), ctx.BlockIndex); result.id = mail.id; avatarState.Update(mail); avatarState.UpdateFromAddItem(result.itemUsable, true); avatarState.updatedAt = DateTimeOffset.UtcNow; avatarState.blockIndex = ctx.BlockIndex; sw.Stop(); Log.Debug($"Sell Cancel Update AvatarState: {sw.Elapsed}"); sw.Restart(); states = states.SetState(sellerAvatarAddress, avatarState.Serialize()); sw.Stop(); Log.Debug($"Sell Cancel Set AvatarState: {sw.Elapsed}"); sw.Restart(); states = states.SetState(ShopState.Address, shopState.Serialize()); sw.Stop(); var ended = DateTimeOffset.UtcNow; Log.Debug($"Sell Cancel Set ShopState: {sw.Elapsed}"); Log.Debug($"Sell Cancel Total Executed Time: {ended - started}"); return(states); }