예제 #1
0
        public static Address GetPrevWeekAddress(long thisWeekBlockIndex)
        {
            var gameConfigState = States.Instance.GameConfigState;
            var index           = Math.Max((int)thisWeekBlockIndex / gameConfigState.WeeklyArenaInterval, 0);

            return(WeeklyArenaState.DeriveAddress(index));
        }
예제 #2
0
        public static Address GetNextWeekAddress(long blockIndex)
        {
            var gameConfigState = States.Instance.GameConfigState;
            var index           = (int)blockIndex / gameConfigState.WeeklyArenaInterval;

            index++;
            return(WeeklyArenaState.DeriveAddress(index));
        }
예제 #3
0
        public static bool TryGetThisWeekAddress(long blockIndex, out Address weeklyArenaAddress)
        {
            var gameConfigState = States.Instance.GameConfigState;
            var index           = (int)blockIndex / gameConfigState.WeeklyArenaInterval;

            if (index < 0)
            {
                return(false);
            }

            weeklyArenaAddress = WeeklyArenaState.DeriveAddress(index);
            return(true);
        }
예제 #4
0
        private Transaction <PolymorphicAction <ActionBase> > RankingReward()
        {
            // private 테스트용 임시 로직 변경
            var index = (int)_chain.Tip.Index / GameConfig.WeeklyArenaInterval;
            var weeklyArenaAddress = WeeklyArenaState.DeriveAddress(index);
            var weeklyArenaState   = new WeeklyArenaState(_chain.GetState(weeklyArenaAddress));
            var actions            = new List <PolymorphicAction <ActionBase> >
            {
                new RankingReward
                {
                    gold1          = 50,
                    gold2          = 30,
                    gold3          = 10,
                    agentAddresses = weeklyArenaState.GetAgentAddresses(3),
                }
            };

            return(_chain.MakeTransaction(_privateKey, actions.ToImmutableHashSet()));
        }
예제 #5
0
        public async Task Query(bool ended)
        {
            const string query = @"
            {
                address
                ended
                orderedArenaInfos {
                    agentAddress
                    avatarAddress
                    arenaRecord {
                        win
                        lose
                        draw
                    }
                    level
                    combatPoint
                    armorId
                    active
                    dailyChallengeCount
                    score
                }
            }";

            var weeklyArenaState = new WeeklyArenaState(WeeklyArenaState.DeriveAddress(0));

            if (ended)
            {
                weeklyArenaState.End();
            }
            var queryResult = await ExecuteQueryAsync <WeeklyArenaStateType>(query, source : weeklyArenaState);

            Assert.Equal(
                new Dictionary <string, object>
            {
                ["address"]           = WeeklyArenaState.DeriveAddress(0).ToString(),
                ["ended"]             = ended,
                ["orderedArenaInfos"] = new List <object>(),
            },
                queryResult.Data
                );
        }
예제 #6
0
        public IAccountStateDelta ResetChallengeCount(IActionContext ctx, IAccountStateDelta states)
        {
            var gameConfigState = states.GetGameConfigState();
            var index           = Math.Max((int)ctx.BlockIndex / gameConfigState.WeeklyArenaInterval, 0);
            var weeklyAddress   = WeeklyArenaState.DeriveAddress(index);
            var rawWeekly       = (Dictionary)states.GetState(weeklyAddress);
            var resetIndex      = rawWeekly["resetIndex"].ToLong();

            if (ctx.BlockIndex - resetIndex >= gameConfigState.DailyArenaInterval)
            {
                var weekly = new WeeklyArenaState(rawWeekly);
                if (resetIndex >= RankingBattle.UpdateTargetBlockIndex)
                {
                    // Reset count each ArenaInfo.
                    weekly.ResetIndex = ctx.BlockIndex;
                    var listAddress = weeklyAddress.Derive("address_list");
                    if (states.TryGetState(listAddress, out List rawList))
                    {
                        var addressList = rawList.ToList(StateExtensions.ToAddress);
                        foreach (var address in addressList)
                        {
                            var infoAddress = weeklyAddress.Derive(address.ToByteArray());
                            if (states.TryGetState(infoAddress, out Dictionary rawInfo))
                            {
                                var info = new ArenaInfo(rawInfo);
                                info.ResetCount();
                                states = states.SetState(infoAddress, info.Serialize());
                            }
                        }
                    }
                }
                else
                {
                    // Run legacy ResetCount.
                    weekly.ResetCount(ctx.BlockIndex);
                }
                states = states.SetState(weeklyAddress, weekly.Serialize());
            }
            return(states);
        }
예제 #7
0
        public IAccountStateDelta WeeklyArenaRankingBoard2(IActionContext ctx, IAccountStateDelta states)
        {
            var gameConfigState = states.GetGameConfigState();
            var index           = Math.Max((int)ctx.BlockIndex / gameConfigState.WeeklyArenaInterval, 0);
            var weeklyAddress   = WeeklyArenaState.DeriveAddress(index);
            var rawWeekly       = (Dictionary)states.GetState(weeklyAddress);
            var nextIndex       = index + 1;
            var nextWeekly      = states.GetWeeklyArenaState(nextIndex);

            if (nextWeekly is null)
            {
                nextWeekly = new WeeklyArenaState(nextIndex);
                states     = states.SetState(nextWeekly.address, nextWeekly.Serialize());
            }
            var resetIndex = rawWeekly["resetIndex"].ToLong();

            // Beginning block of a new weekly arena.
            if (ctx.BlockIndex % gameConfigState.WeeklyArenaInterval == 0 && index > 0)
            {
                var prevWeeklyAddress = WeeklyArenaState.DeriveAddress(index - 1);
                var rawPrevWeekly     = (Dictionary)states.GetState(prevWeeklyAddress);
                if (!rawPrevWeekly["ended"].ToBoolean())
                {
                    rawPrevWeekly = rawPrevWeekly.SetItem("ended", true.Serialize());
                    var weekly     = new WeeklyArenaState(rawWeekly);
                    var prevWeekly = new WeeklyArenaState(rawPrevWeekly);
                    weekly.Update(prevWeekly, ctx.BlockIndex);
                    states = states.SetState(prevWeeklyAddress, rawPrevWeekly);
                    states = states.SetState(weeklyAddress, weekly.Serialize());
                }
            }
            else if (ctx.BlockIndex - resetIndex >= gameConfigState.DailyArenaInterval)
            {
                var weekly = new WeeklyArenaState(rawWeekly);
                weekly.ResetCount(ctx.BlockIndex);
                states = states.SetState(weeklyAddress, weekly.Serialize());
            }
            return(states);
        }
예제 #8
0
        private void UpdateWeeklyArenaState()
        {
            _blockRenderer.EveryBlock()
            .ObserveOnMainThread()
            .Subscribe(_ =>
            {
                var doNothing       = true;
                var agent           = Game.Game.instance.Agent;
                var gameConfigState = States.Instance.GameConfigState;
                var challengeCountResetBlockIndex = States.Instance.WeeklyArenaState.ResetIndex;
                var currentBlockIndex             = agent.BlockIndex;
                if (currentBlockIndex % gameConfigState.WeeklyArenaInterval == 0 &&
                    currentBlockIndex >= gameConfigState.WeeklyArenaInterval)
                {
                    doNothing = false;
                }

                if (currentBlockIndex - challengeCountResetBlockIndex >=
                    gameConfigState.DailyArenaInterval)
                {
                    doNothing = false;
                }

                if (doNothing)
                {
                    return;
                }

                var weeklyArenaIndex =
                    (int)currentBlockIndex / gameConfigState.WeeklyArenaInterval;
                var weeklyArenaAddress = WeeklyArenaState.DeriveAddress(weeklyArenaIndex);
                var weeklyArenaState   =
                    new WeeklyArenaState(
                        (Bencodex.Types.Dictionary)agent.GetState(weeklyArenaAddress));
                States.Instance.SetWeeklyArenaState(weeklyArenaState);
            })
            .AddTo(_disposables);
        }
예제 #9
0
        public void Execute()
        {
            var previousWeeklyState  = _initialState.GetWeeklyArenaState(ArenaIndex);
            var previousAvatar1State = _initialState.GetAvatarState(_avatar1Address);

            previousAvatar1State.level = 10;
            var prevScore = previousWeeklyState[_avatar1Address].Score;

            var previousState = _initialState.SetState(
                _avatar1Address,
                previousAvatar1State.Serialize());

            var itemIds = _tableSheets.WeeklyArenaRewardSheet.Values
                          .Select(r => r.Reward.ItemId)
                          .ToList();

            Assert.All(itemIds, id => Assert.False(previousAvatar1State.inventory.HasItem(id)));

            var row     = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.ATK);
            var costume = (Costume)ItemFactory.CreateItem(
                _tableSheets.ItemSheet[row.CostumeId], new TestRandom());

            costume.equipped = true;
            previousAvatar1State.inventory.AddItem(costume);

            var row2         = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.DEF);
            var enemyCostume = (Costume)ItemFactory.CreateItem(
                _tableSheets.ItemSheet[row2.CostumeId], new TestRandom());

            enemyCostume.equipped = true;
            var enemyAvatarState = _initialState.GetAvatarState(_avatar2Address);

            enemyAvatarState.inventory.AddItem(enemyCostume);

            Address worldInformationAddress = _avatar1Address.Derive(LegacyWorldInformationKey);
            var     weeklyArenaAddress      =
                WeeklyArenaState.DeriveAddress(RankingBattle.UpdateTargetWeeklyArenaIndex);

            previousState = previousState
                            .SetState(
                _avatar1Address.Derive(LegacyInventoryKey),
                previousAvatar1State.inventory.Serialize())
                            .SetState(
                worldInformationAddress,
                previousAvatar1State.worldInformation.Serialize())
                            .SetState(
                _avatar1Address.Derive(LegacyQuestListKey),
                previousAvatar1State.questList.Serialize())
                            .SetState(_avatar1Address, previousAvatar1State.SerializeV2())
                            .SetState(
                _avatar2Address.Derive(LegacyInventoryKey),
                enemyAvatarState.inventory.Serialize())
                            .SetState(
                _avatar2Address.Derive(LegacyWorldInformationKey),
                enemyAvatarState.worldInformation.Serialize())
                            .SetState(
                _avatar2Address.Derive(LegacyQuestListKey),
                enemyAvatarState.questList.Serialize())
                            .SetState(_avatar2Address, enemyAvatarState.SerializeV2())
                            .SetState(
                weeklyArenaAddress,
                new WeeklyArenaState(RankingBattle.UpdateTargetWeeklyArenaIndex).Serialize());

            var action = new RankingBattle
            {
                avatarAddress      = _avatar1Address,
                enemyAddress       = _avatar2Address,
                weeklyArenaAddress = weeklyArenaAddress,
                costumeIds         = new List <Guid> {
                    costume.ItemId
                },
                equipmentIds = new List <Guid>(),
            };

            var nextState = action.Execute(new ActionContext
            {
                PreviousStates = previousState,
                Signer         = _agent1Address,
                Random         = new TestRandom(),
                Rehearsal      = false,
                BlockIndex     = RankingBattle.UpdateTargetBlockIndex,
            });

            Assert.True(nextState.TryGetState(weeklyArenaAddress.Derive(_avatar1Address.ToByteArray()), out Dictionary rawArenaInfo));
            Assert.True(nextState.TryGetState(weeklyArenaAddress.Derive(_avatar2Address.ToByteArray()), out Dictionary rawEnemyInfo));
            Assert.True(nextState.TryGetState(weeklyArenaAddress.Derive("address_list"), out List rawAddressList));
            var nextWeekly = nextState.GetWeeklyArenaState(weeklyArenaAddress);

            Assert.Empty(nextWeekly.Map);

            var nextAvatar1State = nextState.GetAvatarStateV2(_avatar1Address);
            var nextArenaInfo    = new ArenaInfo(rawArenaInfo);
            var addressList      = rawAddressList.ToList(StateExtensions.ToAddress);

            Assert.Contains(_avatar1Address, addressList);
            Assert.Contains(_avatar2Address, addressList);
            Assert.Contains(nextAvatar1State.inventory.Materials, i => itemIds.Contains(i.Id));
            Assert.NotNull(action.ArenaInfo);
            Assert.NotNull(action.EnemyArenaInfo);
            Assert.True(nextArenaInfo.Score > prevScore);

            // Check simulation result equal.
            var player = new Player(
                previousAvatar1State,
                _tableSheets.CharacterSheet,
                _tableSheets.CharacterLevelSheet,
                _tableSheets.EquipmentItemSetEffectSheet);
            var simulator = new RankingSimulator(
                new TestRandom(),
                player,
                action.EnemyPlayerDigest,
                new List <Guid>(),
                _tableSheets.GetRankingSimulatorSheets(),
                RankingBattle.StageId,
                action.ArenaInfo,
                action.EnemyArenaInfo,
                _tableSheets.CostumeStatSheet);

            simulator.Simulate();

            Assert.Equal(nextArenaInfo.Score, simulator.Log.score);
            Assert.Equal(previousAvatar1State.SerializeV2(), nextAvatar1State.SerializeV2());
            Assert.Equal(previousAvatar1State.worldInformation.Serialize(), nextAvatar1State.worldInformation.Serialize());
        }
        public WeeklyArenaStateUpdateScenarioTest()
        {
            _initialState = new Tests.Action.State();

            var sheets = TableSheetsImporter.ImportSheets();

            foreach (var(key, value) in sheets)
            {
                _initialState = _initialState.SetState(
                    Addresses.TableSheet.Derive(key),
                    value.Serialize());
            }

            var tableSheets = new TableSheets(sheets);

            var rankingMapAddress = new PrivateKey().ToAddress();

            _agent1Address  = new PrivateKey().ToAddress();
            _avatar1Address = new PrivateKey().ToAddress();

            var agentState  = new AgentState(_agent1Address);
            var avatarState = new AvatarState(
                _avatar1Address,
                _agent1Address,
                0,
                tableSheets.GetAvatarSheets(),
                new GameConfigState(sheets[nameof(GameConfigSheet)]),
                rankingMapAddress
                )
            {
                worldInformation = new WorldInformation(
                    0,
                    tableSheets.WorldSheet,
                    Math.Max(
                        tableSheets.StageSheet.First?.Id ?? 1,
                        GameConfig.RequireClearedStageLevel.ActionsInRankingBoard)),
                level = 100,
            };

            agentState.avatarAddresses.Add(0, _avatar1Address);

            var agent2Address = new PrivateKey().ToAddress();

            _avatar2Address = new PrivateKey().ToAddress();

            var agent2State  = new AgentState(agent2Address);
            var avatar2State = new AvatarState(
                _avatar2Address,
                agent2Address,
                0,
                tableSheets.GetAvatarSheets(),
                new GameConfigState(sheets[nameof(GameConfigSheet)]),
                rankingMapAddress
                )
            {
                worldInformation = new WorldInformation(
                    0,
                    tableSheets.WorldSheet,
                    Math.Max(
                        tableSheets.StageSheet.First?.Id ?? 1,
                        GameConfig.RequireClearedStageLevel.ActionsInRankingBoard)),
                level = 100,
            };

            agent2State.avatarAddresses.Add(0, _avatar2Address);

            var agent3Address = new PrivateKey().ToAddress();

            _avatar3Address = new PrivateKey().ToAddress();

            var agent3State  = new AgentState(agent3Address);
            var avatar3State = new AvatarState(
                _avatar3Address,
                agent2Address,
                0,
                tableSheets.GetAvatarSheets(),
                new GameConfigState(sheets[nameof(GameConfigSheet)]),
                rankingMapAddress
                )
            {
                worldInformation = new WorldInformation(
                    0,
                    tableSheets.WorldSheet,
                    Math.Max(
                        tableSheets.StageSheet.First?.Id ?? 1,
                        GameConfig.RequireClearedStageLevel.ActionsInRankingBoard)),
                level = 100,
            };

            agent3State.avatarAddresses.Add(0, _avatar3Address);

            var prevWeeklyArenaState = new WeeklyArenaState(RankingBattle.UpdateTargetWeeklyArenaIndex - 2);
            var weeklyArenaState     = new WeeklyArenaState(RankingBattle.UpdateTargetWeeklyArenaIndex - 1);

            weeklyArenaState.SetV2(avatarState, tableSheets.CharacterSheet, tableSheets.CostumeStatSheet);
            weeklyArenaState[_avatar1Address].Activate();
            weeklyArenaState.SetV2(avatar2State, tableSheets.CharacterSheet, tableSheets.CostumeStatSheet);
            weeklyArenaState[_avatar2Address].Activate();
            _weeklyArenaAddress = WeeklyArenaState.DeriveAddress(RankingBattle.UpdateTargetWeeklyArenaIndex);

            var gold = new GoldCurrencyState(new Currency("NCG", 2, minter: null));

            _initialState = _initialState
                            .SetState(_agent1Address, agentState.Serialize())
                            .SetState(_avatar1Address, avatarState.Serialize())
                            .SetState(agent2Address, agent2State.Serialize())
                            .SetState(_avatar2Address, avatar2State.Serialize())
                            .SetState(agent3Address, agent2State.Serialize())
                            .SetState(_avatar3Address, avatar2State.Serialize())
                            .SetState(Addresses.GameConfig, new GameConfigState(sheets[nameof(GameConfigSheet)]).Serialize())
                            .SetState(prevWeeklyArenaState.address, prevWeeklyArenaState.Serialize())
                            .SetState(weeklyArenaState.address, weeklyArenaState.Serialize())
                            .SetState(_weeklyArenaAddress, new WeeklyArenaState(RankingBattle.UpdateTargetWeeklyArenaIndex).Serialize())
                            .SetState(GoldCurrencyState.Address, gold.Serialize())
                            .SetState(Addresses.GoldDistribution, GoldDistributionTest.Fixture.Select(v => v.Serialize()).Serialize())
                            .MintAsset(GoldCurrencyState.Address, gold.Currency * 100000000000);
        }
예제 #11
0
        public static WeeklyArenaState GetWeeklyArenaState(this IAccountStateDelta states, int index)
        {
            var address = WeeklyArenaState.DeriveAddress(index);

            return(GetWeeklyArenaState(states, address));
        }
예제 #12
0
        public static MakeInitialStateResult MakeInitialState()
        {
            var goldCurrencyState = new GoldCurrencyState(new Currency("NCG", 2, minter: null));
            var ranking           = new RankingState1();

            for (var i = 0; i < RankingState1.RankingMapCapacity; i++)
            {
                ranking.RankingMap[RankingState1.Derive(i)] = new HashSet <Address>().ToImmutableHashSet();
            }

            var sheets             = TableSheetsImporter.ImportSheets();
            var weeklyArenaAddress = WeeklyArenaState.DeriveAddress(0);
            var initialState       = new Tests.Action.State()
                                     .SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize())
                                     .SetState(
                Addresses.GoldDistribution,
                GoldDistributionTest.Fixture.Select(v => v.Serialize()).Serialize()
                )
                                     .SetState(
                Addresses.GameConfig,
                new GameConfigState(sheets[nameof(GameConfigSheet)]).Serialize()
                )
                                     .SetState(Addresses.Ranking, ranking.Serialize())
                                     .SetState(weeklyArenaAddress, new WeeklyArenaState(0).Serialize());

            foreach (var(key, value) in sheets)
            {
                initialState = initialState.SetState(Addresses.TableSheet.Derive(key), value.Serialize());
            }

            var tableSheets       = new TableSheets(sheets);
            var rankingMapAddress = new PrivateKey().ToAddress();

            var agentAddress = new PrivateKey().ToAddress();
            var agentState   = new AgentState(agentAddress);

            var avatarAddress = new PrivateKey().ToAddress();
            var avatarState   = new AvatarState(
                avatarAddress,
                agentAddress,
                0,
                tableSheets.GetAvatarSheets(),
                new GameConfigState(),
                rankingMapAddress)
            {
                worldInformation = new WorldInformation(
                    0,
                    tableSheets.WorldSheet,
                    GameConfig.RequireClearedStageLevel.ActionsInShop),
            };

            agentState.avatarAddresses[0] = avatarAddress;

            var initCurrencyGold   = goldCurrencyState.Currency * 100000000000;
            var agentCurrencyGold  = goldCurrencyState.Currency * 1000;
            var remainCurrencyGold = initCurrencyGold - agentCurrencyGold;

            initialState = initialState
                           .SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize())
                           .SetState(agentAddress, agentState.Serialize())
                           .SetState(avatarAddress, avatarState.Serialize())
                           .SetState(Addresses.Shop, new ShopState().Serialize())
                           .MintAsset(GoldCurrencyState.Address, initCurrencyGold)
                           .TransferAsset(Addresses.GoldCurrency, agentAddress, agentCurrencyGold);

            var action = new CreateTestbed
            {
                weeklyArenaAddress = weeklyArenaAddress,
            };
            var nextState = action.Execute(new ActionContext()
            {
                BlockIndex     = 0,
                PreviousStates = initialState,
                Random         = new TestRandom(),
                Rehearsal      = false,
            });

            return(new MakeInitialStateResult(
                       nextState,
                       action,
                       agentState,
                       avatarState,
                       goldCurrencyState,
                       rankingMapAddress,
                       tableSheets,
                       remainCurrencyGold,
                       agentCurrencyGold));
        }
예제 #13
0
        public IAccountStateDelta PrepareNextArena(IActionContext ctx, IAccountStateDelta states)
        {
            var gameConfigState = states.GetGameConfigState();
            var index           = Math.Max((int)ctx.BlockIndex / gameConfigState.WeeklyArenaInterval, 0);
            var weeklyAddress   = WeeklyArenaState.DeriveAddress(index);
            var rawWeekly       = (Dictionary)states.GetState(weeklyAddress);
            var nextIndex       = index + 1;
            var nextWeekly      = states.GetWeeklyArenaState(nextIndex);

            if (nextWeekly is null)
            {
                nextWeekly = new WeeklyArenaState(nextIndex);
                states     = states.SetState(nextWeekly.address, nextWeekly.Serialize());
            }

            // Beginning block of a new weekly arena.
            if (ctx.BlockIndex % gameConfigState.WeeklyArenaInterval == 0 && index > 0)
            {
                var prevWeeklyAddress = WeeklyArenaState.DeriveAddress(index - 1);
                var rawPrevWeekly     = (Dictionary)states.GetState(prevWeeklyAddress);
                if (!rawPrevWeekly["ended"].ToBoolean())
                {
                    rawPrevWeekly = rawPrevWeekly.SetItem("ended", true.Serialize());
                    var weekly      = new WeeklyArenaState(rawWeekly);
                    var prevWeekly  = new WeeklyArenaState(rawPrevWeekly);
                    var listAddress = weekly.address.Derive("address_list");
                    // Set ArenaInfo, address list for new RankingBattle.
                    var addressList = states.TryGetState(listAddress, out List rawList)
                        ? rawList.ToList(StateExtensions.ToAddress)
                        : new List <Address>();
                    if (ctx.BlockIndex >= RankingBattle.UpdateTargetBlockIndex)
                    {
                        weekly.ResetIndex = ctx.BlockIndex;

                        // Copy Map to address list.
                        if (ctx.BlockIndex == RankingBattle.UpdateTargetBlockIndex)
                        {
                            foreach (var kv in prevWeekly.Map)
                            {
                                var address  = kv.Key;
                                var lazyInfo = kv.Value;
                                var info     = new ArenaInfo(lazyInfo.State);
                                states = states.SetState(
                                    weeklyAddress.Derive(address.ToByteArray()), info.Serialize());
                                if (!addressList.Contains(address))
                                {
                                    addressList.Add(address);
                                }
                            }
                        }
                        else
                        {
                            // Copy addresses from prev weekly address list.
                            var prevListAddress = prevWeekly.address.Derive("address_list");

                            if (states.TryGetState(prevListAddress, out List prevRawList))
                            {
                                var prevList = prevRawList.ToList(StateExtensions.ToAddress);
                                foreach (var address in prevList.Where(address => !addressList.Contains(address)))
                                {
                                    addressList.Add(address);
                                }
                            }

                            // Copy ArenaInfo from prev ArenaInfo.
                            foreach (var address in addressList)
                            {
                                if (states.TryGetState(
                                        prevWeekly.address.Derive(address.ToByteArray()),
                                        out Dictionary rawInfo))
                                {
                                    var prevInfo = new ArenaInfo(rawInfo);
                                    var info     = new ArenaInfo(prevInfo);
                                    states = states.SetState(
                                        weeklyAddress.Derive(address.ToByteArray()),
                                        info.Serialize());
                                }
                            }
                        }

                        // Set address list.
                        states = states.SetState(listAddress,
                                                 addressList.Aggregate(List.Empty,
                                                                       (current, address) => current.Add(address.Serialize())));
                    }
                    // Run legacy Update.
                    else
                    {
                        weekly.Update(prevWeekly, ctx.BlockIndex);
                    }

                    states = states.SetState(prevWeeklyAddress, rawPrevWeekly);
                    states = states.SetState(weeklyAddress, weekly.Serialize());
                }
            }
            return(states);
        }