コード例 #1
0
        public MimisbrunnrBattle3Test()
        {
            var sheets = TableSheetsImporter.ImportSheets();

            _tableSheets = new TableSheets(sheets);

            var privateKey = new PrivateKey();

            _agentAddress = privateKey.PublicKey.ToAddress();
            var agentState = new AgentState(_agentAddress);

            _avatarAddress     = _agentAddress.Derive("avatar");
            _rankingMapAddress = _avatarAddress.Derive("ranking_map");
            var avatarState = new AvatarState(
                _avatarAddress,
                _agentAddress,
                0,
                _tableSheets.GetAvatarSheets(),
                new GameConfigState(sheets[nameof(GameConfigSheet)]),
                _rankingMapAddress
                )
            {
                level = 400,
            };

            agentState.avatarAddresses.Add(0, _avatarAddress);

            _weeklyArenaState = new WeeklyArenaState(0);

            _initialState = new State()
                            .SetState(_weeklyArenaState.address, _weeklyArenaState.Serialize())
                            .SetState(_agentAddress, agentState.Serialize())
                            .SetState(_avatarAddress, avatarState.Serialize())
                            .SetState(_rankingMapAddress, new RankingMapState(_rankingMapAddress).Serialize());

            foreach (var(key, value) in sheets)
            {
                _initialState = _initialState
                                .SetState(Addresses.TableSheet.Derive(key), value.Serialize());
            }
        }
コード例 #2
0
ファイル: DailyRewardTest2.cs プロジェクト: GunnerJnr/lib9c
        public DailyRewardTest2(ITestOutputHelper outputHelper)
        {
            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Verbose()
                         .WriteTo.TestOutput(outputHelper)
                         .CreateLogger();

            _initialState = new 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);

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

            _avatarAddress = new PrivateKey().ToAddress();
            var rankingMapAddress = new PrivateKey().ToAddress();
            var avatarState       = new AvatarState(
                _avatarAddress,
                _agentAddress,
                0,
                tableSheets.GetAvatarSheets(),
                new GameConfigState(),
                rankingMapAddress)
            {
                actionPoint = 0,
            };

            agentState.avatarAddresses[0] = _avatarAddress;

            _initialState = _initialState
                            .SetState(Addresses.GameConfig, new GameConfigState().Serialize())
                            .SetState(_agentAddress, agentState.Serialize())
                            .SetState(_avatarAddress, avatarState.Serialize());
        }
コード例 #3
0
        public static string GetSheetCsv <T>(this IAccountStateDelta states) where T : ISheet, new()
        {
            var address = Addresses.GetSheetAddress <T>();
            var value   = states.GetState(address);

            if (value is null)
            {
                Log.Warning($"{nameof(T)} is null ({0})", address.ToHex());
                throw new FailedLoadStateException(nameof(T));
            }

            try
            {
                return(value.ToDotnetString());
            }
            catch (Exception e)
            {
                Log.Error(e, $"Unexpected error occurred during {nameof(T)}()");
                throw;
            }
        }
コード例 #4
0
 public ActionContext(
     Address signer,
     Address miner,
     long blockIndex,
     IAccountStateDelta previousStates,
     int randomSeed,
     bool rehearsal = false,
     ITrie?previousBlockStatesTrie = null,
     bool blockAction = false
     )
 {
     Signer                   = signer;
     Miner                    = miner;
     BlockIndex               = blockIndex;
     Rehearsal                = rehearsal;
     PreviousStates           = previousStates;
     Random                   = new Random(randomSeed);
     _randomSeed              = randomSeed;
     _previousBlockStatesTrie = previousBlockStatesTrie;
     BlockAction              = blockAction;
 }
コード例 #5
0
        public IAccountStateDelta MinerReward(IActionContext ctx, IAccountStateDelta states)
        {
            // 마이닝 보상
            // https://www.notion.so/planetarium/Mining-Reward-b7024ef463c24ebca40a2623027d497d
            Currency           currency            = states.GetGoldCurrency();
            FungibleAssetValue defaultMiningReward = currency * 10;
            var countOfHalfLife             = (int)Math.Pow(2, Convert.ToInt64((ctx.BlockIndex - 1) / 12614400));
            FungibleAssetValue miningReward =
                defaultMiningReward.DivRem(countOfHalfLife, out FungibleAssetValue _);

            if (miningReward >= FungibleAssetValue.Parse(currency, "1.25"))
            {
                states = states.TransferAsset(
                    GoldCurrencyState.Address,
                    ctx.Miner,
                    miningReward
                    );
            }

            return(states);
        }
コード例 #6
0
 public MakeInitialStateResult(
     IAccountStateDelta state,
     CreateTestbed testbed,
     AgentState agentState,
     AvatarState avatarState,
     GoldCurrencyState goldCurrencyState,
     Address rankingMapAddress,
     TableSheets tableSheets,
     FungibleAssetValue currencyGold,
     FungibleAssetValue agentCurrencyGold)
 {
     _state             = state;
     _testbed           = testbed;
     _agentState        = agentState;
     _avatarState       = avatarState;
     _goldCurrencyState = goldCurrencyState;
     _rankingMapAddress = rankingMapAddress;
     _tableSheets       = tableSheets;
     _currencyGold      = currencyGold;
     _agentCurrencyGold = agentCurrencyGold;
 }
コード例 #7
0
        public static bool TryGetState <T>(this IAccountStateDelta states, Address address, out T result)
            where T : IValue
        {
            IValue raw = states.GetState(address);

            if (raw is T v)
            {
                result = v;
                return(true);
            }

            Log.Error(
                "Expected a {0}, but got invalid state ({1}): ({2}) {3}",
                typeof(T).Name,
                address.ToHex(),
                raw?.GetType().Name,
                raw
                );
            result = default;
            return(false);
        }
コード例 #8
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IImmutableSet <string> usedWeapons    = ImmutableHashSet <string> .Empty;
            IImmutableSet <string> targets        = ImmutableHashSet <string> .Empty;
            IAccountStateDelta     previousStates = context.PreviousStates;

            object value = previousStates.GetState(TargetAddress);

            if (!ReferenceEquals(value, null))
            {
                var previousResult = BattleResult.FromBencodex((Bencodex.Types.Dictionary)value);
                usedWeapons = previousResult.UsedWeapons;
                targets     = previousResult.Targets;
            }

            usedWeapons = usedWeapons.Add(Weapon);
            targets     = targets.Add(Target);
            var result = new BattleResult(usedWeapons, targets);

            return(previousStates.SetState(TargetAddress, result.ToBencodex()));
        }
コード例 #9
0
        public CancelMonsterCollectTest()
        {
            _signer = default;
            _state  = new State();
            Dictionary <string, string> sheets = TableSheetsImporter.ImportSheets();

            _tableSheets = new TableSheets(sheets);
            var agentState        = new AgentState(_signer);
            var currency          = new Currency("NCG", 2, minters: null);
            var goldCurrencyState = new GoldCurrencyState(currency);

            _state = _state
                     .SetState(_signer, agentState.Serialize())
                     .SetState(Addresses.GoldCurrency, goldCurrencyState.Serialize());

            foreach ((string key, string value) in sheets)
            {
                _state = _state
                         .SetState(Addresses.TableSheet.Derive(key), value.Serialize());
            }
        }
コード例 #10
0
        public void ExecuteThrowNotEnoughClearedStageLevelException()
        {
            _initialState = _initialState
                            .SetState(_slotAddress, new CombinationSlotState(_slotAddress, 0).Serialize());

            var action = new CombinationConsumable0()
            {
                AvatarAddress = _avatarAddress,
                recipeId      = 1,
                slotIndex     = 0,
            };

            Assert.Throws <NotEnoughClearedStageLevelException>(() => action.Execute(new ActionContext()
            {
                PreviousStates = _initialState,
                Signer         = _agentAddress,
                BlockIndex     = 1,
                Random         = _random,
            })
                                                                );
        }
コード例 #11
0
        public void Execute_Throw_InvalidLevelException(int prevLevel, int level)
        {
            Address collectionAddress = MonsterCollectionState0.DeriveAddress(_signer, 0);
            MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(collectionAddress, prevLevel, 0, _tableSheets.MonsterCollectionRewardSheet);

            _state = _state.SetState(collectionAddress, monsterCollectionState.Serialize());

            CancelMonsterCollect action = new CancelMonsterCollect
            {
                level        = level,
                collectRound = 0,
            };

            Assert.Throws <InvalidLevelException>(() => action.Execute(new ActionContext
            {
                PreviousStates = _state,
                Signer         = _signer,
                BlockIndex     = 0,
            })
                                                  );
        }
コード例 #12
0
ファイル: RewardGold.cs プロジェクト: planetarium/lib9c
        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);
        }
コード例 #13
0
        public void Execute()
        {
            var agentAddress  = new PrivateKey().ToAddress();
            var avatarAddress = new PrivateKey().ToAddress();
            var avatarState   = new AvatarState(
                avatarAddress,
                agentAddress,
                0,
                _tableSheets.GetAvatarSheets(),
                new GameConfigState(),
                default
                );
            var nonce = new byte[] { 0x00, 0x01, 0x02, 0x03 };
            var admin = new Address("8d9f76aF8Dc5A812aCeA15d8bf56E2F790F47fd7");
            var state = new State(ImmutableDictionary <Address, IValue> .Empty
                                  .Add(AdminState.Address, new AdminState(admin, 100).Serialize())
                                  .Add(avatarAddress, avatarState.SerializeV2())
                                  );

            var action = new MigrationAvatarState
            {
                avatarStates = new List <Dictionary>
                {
                    (Dictionary)avatarState.Serialize(),
                },
            };

            IAccountStateDelta nextState = action.Execute(new ActionContext()
            {
                PreviousStates = state,
                Signer         = admin,
                BlockIndex     = 1,
            });

            var nextAvatarState = nextState.GetAvatarStateV2(avatarAddress);

            Assert.NotNull(nextAvatarState.inventory);
            Assert.NotNull(nextAvatarState.worldInformation);
            Assert.NotNull(nextAvatarState.questList);
        }
コード例 #14
0
        internal ActionEvaluation EvaluateBlockAction(
            Block <T> block,
            IReadOnlyList <ActionEvaluation> txActionEvaluations)
        {
            if (Policy.BlockAction is null)
            {
                var message = "To evaluate block action, Policy.BlockAction must not be null.";
                throw new InvalidOperationException(message);
            }

            IAccountStateDelta lastStates = null;

            if (!(txActionEvaluations is null) && txActionEvaluations.Count > 0)
            {
                lastStates = txActionEvaluations[txActionEvaluations.Count - 1].OutputStates;
            }

            Address miner = block.Miner.GetValueOrDefault();

            var minerState = GetStates(new[] { miner }, block.PreviousHash)
                             .GetValueOrDefault(miner);

            if (lastStates is null)
            {
                lastStates = new AccountStateDeltaImpl(a => minerState);
            }
            else if (lastStates.GetState(miner) is null)
            {
                lastStates = lastStates.SetState(miner, minerState);
            }

            return(ActionEvaluation.EvaluateActionsGradually(
                       block.Hash,
                       block.Index,
                       lastStates,
                       miner,
                       miner,
                       Array.Empty <byte>(),
                       new[] { Policy.BlockAction }.ToImmutableList()).First());
        }
コード例 #15
0
ファイル: MonsterCollect0Test.cs プロジェクト: dahlia/lib9c
        public void Execute_Throw_MonsterCollectionExpiredException()
        {
            Address collectionAddress = MonsterCollectionState0.DeriveAddress(_signer, 0);
            MonsterCollectionState0 prevMonsterCollectionState = new MonsterCollectionState0(collectionAddress, 1, 0, _tableSheets.MonsterCollectionRewardSheet);

            Assert.Equal(MonsterCollectionState0.ExpirationIndex, prevMonsterCollectionState.ExpiredBlockIndex);

            _initialState = _initialState.SetState(collectionAddress, prevMonsterCollectionState.Serialize());

            MonsterCollect0 action = new MonsterCollect0
            {
                level           = 2,
                collectionRound = 0,
            };

            Assert.Throws <MonsterCollectionExpiredException>(() => action.Execute(new ActionContext
            {
                PreviousStates = _initialState,
                Signer         = _signer,
                BlockIndex     = prevMonsterCollectionState.ExpiredBlockIndex + 1,
            }));
        }
コード例 #16
0
        public IAccountStateDelta GenesisGoldDistribution(IActionContext ctx, IAccountStateDelta states)
        {
            IEnumerable <GoldDistribution> goldDistributions = states.GetGoldDistribution();
            var      index        = ctx.BlockIndex;
            Currency goldCurrency = states.GetGoldCurrency();
            Address  fund         = GoldCurrencyState.Address;

            foreach (GoldDistribution distribution in goldDistributions)
            {
                BigInteger amount = distribution.GetAmount(index);
                if (amount <= 0)
                {
                    continue;
                }
                states = states.TransferAsset(
                    fund,
                    distribution.Address,
                    goldCurrency * amount
                    );
            }
            return(states);
        }
コード例 #17
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);
        }
コード例 #18
0
        public CombinationConsumable4Test()
        {
            _agentAddress  = default;
            _avatarAddress = _agentAddress.Derive("avatar");
            _slotAddress   = _avatarAddress.Derive(
                string.Format(
                    CultureInfo.InvariantCulture,
                    CombinationSlotState.DeriveFormat,
                    0
                    )
                );
            _sheets      = TableSheetsImporter.ImportSheets();
            _random      = new TestRandom();
            _tableSheets = new TableSheets(_sheets);

            var agentState = new AgentState(_agentAddress);

            agentState.avatarAddresses[0] = _avatarAddress;
            var gameConfigState = new GameConfigState();

            _avatarState = new AvatarState(
                _avatarAddress,
                _agentAddress,
                1,
                _tableSheets.GetAvatarSheets(),
                gameConfigState,
                default
                );

            _initialState = new State()
                            .SetState(_agentAddress, agentState.Serialize())
                            .SetState(_avatarAddress, _avatarState.Serialize());

            foreach (var(key, value) in _sheets)
            {
                _initialState =
                    _initialState.SetState(Addresses.TableSheet.Derive(key), value.Serialize());
            }
        }
コード例 #19
0
        public void GetSetState()
        {
            IAccountStateDelta init = new AccountStateDeltaImpl(GetState);
            IAccountStateDelta a    = init.SetState(_addr[0], "A");

            Assert.Equal("A", a.GetState(_addr[0]));
            Assert.Equal("a", init.GetState(_addr[0]));
            Assert.Equal("b", a.GetState(_addr[1]));
            Assert.Equal("b", init.GetState(_addr[1]));
            Assert.Null(a.GetState(_addr[2]));
            Assert.Null(init.GetState(_addr[2]));
            Assert.Equal(
                new[] { _addr[0] }.ToImmutableHashSet(),
                a.UpdatedAddresses
                );
            Assert.Empty(init.UpdatedAddresses);

            IAccountStateDelta b = a.SetState(_addr[0], "z");

            Assert.Equal("z", b.GetState(_addr[0]));
            Assert.Equal("A", a.GetState(_addr[0]));
            Assert.Equal("a", init.GetState(_addr[0]));
            Assert.Equal("b", b.GetState(_addr[1]));
            Assert.Equal("b", a.GetState(_addr[1]));
            Assert.Null(b.GetState(_addr[2]));
            Assert.Null(a.GetState(_addr[2]));
            Assert.Equal(
                new[] { _addr[0] }.ToImmutableHashSet(),
                a.UpdatedAddresses
                );
            Assert.Empty(init.UpdatedAddresses);

            IAccountStateDelta c = b.SetState(_addr[0], "a");

            Assert.Equal("a", c.GetState(_addr[0]));
            Assert.Equal("z", b.GetState(_addr[0]));
            Assert.Empty(c.UpdatedAddresses);
            Assert.Empty(init.UpdatedAddresses);
        }
コード例 #20
0
        public void Execute_Throw_InsufficientBalanceException()
        {
            Address collectionAddress = MonsterCollectionState0.DeriveAddress(_signer, 0);
            MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(collectionAddress, 1, 0, _tableSheets.MonsterCollectionRewardSheet);

            _state = _state.SetState(collectionAddress, monsterCollectionState.Serialize());

            ClaimMonsterCollectionReward0 action = new ClaimMonsterCollectionReward0
            {
                avatarAddress   = _avatarAddress,
                collectionRound = 0,
            };

            Assert.Throws <InsufficientBalanceException>(() => action.Execute(new ActionContext
            {
                PreviousStates = _state,
                Signer         = _signer,
                BlockIndex     = MonsterCollectionState0.ExpirationIndex,
                Random         = new TestRandom(),
            })
                                                         );
        }
コード例 #21
0
        public static IEnumerable <GoldDistribution> GetGoldDistribution(
            this IAccountStateDelta states)
        {
            var value = states.GetState(Addresses.GoldDistribution);

            if (value is null)
            {
                Log.Warning($"{nameof(GoldDistribution)} is null ({0})", Addresses.GoldDistribution.ToHex());
                return(null);
            }

            try
            {
                var goldDistributions = (Bencodex.Types.List)value;
                return(goldDistributions.Select(v => new GoldDistribution(v)));
            }
            catch (Exception e)
            {
                Log.Error(e, $"Unexpected error occurred during {nameof(GetGoldDistribution)}()");
                throw;
            }
        }
コード例 #22
0
        public static IAccountStateDelta MarkBalanceChanged(
            this IAccountStateDelta states,
            Currency currency,
            params Address[] accounts
            )
        {
            if (accounts.Length == 1)
            {
                return(states.MintAsset(accounts[0], currency * 1));
            }
            else if (accounts.Length < 1)
            {
                return(states);
            }

            for (int i = 1; i < accounts.Length; i++)
            {
                states = states.TransferAsset(accounts[i - 1], accounts[i], currency * 1, true);
            }

            return(states);
        }
コード例 #23
0
        public void ExecuteThrowSheetRowNotFoundException()
        {
            var row         = _tableSheets.EquipmentItemRecipeSheet.Values.First();
            var materialRow = _tableSheets.MaterialItemSheet[row.MaterialId];
            var material    = ItemFactory.CreateItem(materialRow, _random);

            _avatarState.inventory.AddItem(material, row.MaterialCount);

            const int requiredStage = GameConfig.RequireClearedStageLevel.CombinationEquipmentAction;

            for (var i = 1; i < requiredStage + 1; i++)
            {
                _avatarState.worldInformation.ClearStage(
                    1,
                    i,
                    0,
                    _tableSheets.WorldSheet,
                    _tableSheets.WorldUnlockSheet
                    );
            }

            _initialState = _initialState.SetState(_avatarAddress, _avatarState.Serialize());

            var action = new CombinationEquipment()
            {
                AvatarAddress = _avatarAddress,
                RecipeId      = 999,
                SlotIndex     = 0,
            };

            Assert.Throws <SheetRowNotFoundException>(() => action.Execute(new ActionContext()
            {
                PreviousStates = _initialState,
                Signer         = _agentAddress,
                BlockIndex     = 1,
                Random         = _random,
            })
                                                      );
        }
コード例 #24
0
ファイル: RedeemCodeTest.cs プロジェクト: x86chi/lib9c
        public void Execute()
        {
            var       privateKey           = new PrivateKey();
            PublicKey publicKey            = privateKey.PublicKey;
            var       prevRedeemCodesState = new RedeemCodeState(new Dictionary <PublicKey, Reward>()
            {
                [publicKey] = new Reward(1),
            });
            var gameConfigState = new GameConfigState();
            var agentState      = new AgentState(_agentAddress);

            agentState.avatarAddresses[0] = _avatarAddress;
            var avatarState = new AvatarState(
                _avatarAddress,
                _agentAddress,
                1,
                _tableSheets,
                gameConfigState
                );

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

            var initialState = new State()
                               .SetState(_agentAddress, agentState.Serialize())
                               .SetState(_avatarAddress, avatarState.Serialize())
                               .SetState(TableSheetsState.Address, _tableSheetsState.Serialize())
                               .SetState(RedeemCodeState.Address, prevRedeemCodesState.Serialize())
                               .SetState(GoldCurrencyState.Address, goldState.Serialize())
                               .MintAsset(GoldCurrencyState.Address, goldState.Currency * 100000000);
            var redeemCode = new RedeemCode(
                ByteUtil.Hex(privateKey.ByteArray),
                _avatarAddress
                );

            IAccountStateDelta nextState = redeemCode.Execute(new ActionContext()
            {
                BlockIndex     = 1,
                Miner          = default,
コード例 #25
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IAccountStateDelta state = context.PreviousStates;

            if (context.Rehearsal)
            {
                return(state
                       .SetState(ActivatedAccountsState.Address, MarkChanged)
                       .SetState(PendingAddress, MarkChanged));
            }

            if (!state.TryGetState(ActivatedAccountsState.Address, out Dictionary accountsAsDict))
            {
                throw new ActivatedAccountsDoesNotExistsException();
            }
            if (!state.TryGetState(PendingAddress, out Dictionary pendingAsDict))
            {
                throw new PendingActivationDoesNotExistsException(PendingAddress);
            }

            var accounts = new ActivatedAccountsState(accountsAsDict);
            var pending  = new PendingActivationState(pendingAsDict);

            if (pending.Verify(this))
            {
                return(state.SetState(
                           ActivatedAccountsState.Address,
                           accounts.AddAccount(context.Signer).Serialize()
                           ).SetState(
                           pending.address,
                           new Bencodex.Types.Null()
                           ));
            }
            else
            {
                throw new InvalidSignatureException(pending, Signature);
            }
        }
コード例 #26
0
        internal ActionEvaluation EvaluateBlockAction(
            Block <T> block,
            IReadOnlyList <ActionEvaluation> txActionEvaluations)
        {
            if (Policy.BlockAction is null)
            {
                var message = "To evaluate block action, Policy.BlockAction must not be null.";
                throw new InvalidOperationException(message);
            }

            _logger.Debug(
                "Evaluating block action in block {blockIndex}: {block}", block?.Index, block);

            IAccountStateDelta lastStates = null;

            if (!(txActionEvaluations is null) && txActionEvaluations.Count > 0)
            {
                lastStates = txActionEvaluations[txActionEvaluations.Count - 1].OutputStates;
            }

            Address miner = block.Miner.GetValueOrDefault();

            if (lastStates is null)
            {
                lastStates = new AccountStateDeltaImpl(
                    a => GetState(a, block.PreviousHash).GetValueOrDefault(a));
            }

            return(ActionEvaluation.EvaluateActionsGradually(
                       block.Hash,
                       block.Index,
                       null,
                       lastStates,
                       miner,
                       miner,
                       Array.Empty <byte>(),
                       new[] { Policy.BlockAction }.ToImmutableList()).First());
        }
コード例 #27
0
ファイル: MonsterCollect0Test.cs プロジェクト: dahlia/lib9c
        public void Rehearsal()
        {
            Address         collectionAddress = MonsterCollectionState0.DeriveAddress(_signer, 1);
            MonsterCollect0 action            = new MonsterCollect0
            {
                level           = 1,
                collectionRound = 1,
            };
            IAccountStateDelta nextState = action.Execute(new ActionContext
            {
                PreviousStates = new State(),
                Signer         = _signer,
                Rehearsal      = true,
            });

            List <Address> updatedAddresses = new List <Address>()
            {
                _signer,
                collectionAddress,
            };

            Assert.Equal(updatedAddresses.ToImmutableHashSet(), nextState.UpdatedAddresses);
        }
コード例 #28
0
        public static bool TryGetAgentAvatarStates(
            this IAccountStateDelta states,
            Address agentAddress,
            Address avatarAddress,
            out AgentState agentState,
            out AvatarState avatarState
            )
        {
            avatarState = null;
            agentState  = states.GetAgentState(agentAddress);
            if (agentState is null)
            {
                return(false);
            }
            if (!agentState.avatarAddresses.ContainsValue(avatarAddress))
            {
                throw new AgentStateNotContainsAvatarAddressException(
                          $"The avatar {avatarAddress.ToHex()} does not belong to the agent {agentAddress.ToHex()}.");
            }

            avatarState = states.GetAvatarState(avatarAddress);
            return(!(avatarState is null));
        }
コード例 #29
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IAccountStateDelta state            = context.PreviousStates;
            Address            activatedAddress = context.Signer.Derive(ActivationKey.DeriveKey);

            if (context.Rehearsal)
            {
                return(state
                       .SetState(activatedAddress, MarkChanged)
                       .SetState(PendingAddress, MarkChanged));
            }

            if (!(state.GetState(activatedAddress) is null))
            {
                throw new AlreadyActivatedException($"{context.Signer} already activated.");
            }
            if (!state.TryGetState(PendingAddress, out Dictionary pendingAsDict))
            {
                throw new PendingActivationDoesNotExistsException(PendingAddress);
            }

            var pending = new PendingActivationState(pendingAsDict);

            if (pending.Verify(this))
            {
                // We left this log message to track activation history.
                // Please delete it if we have an API for evaluation results on the Libplanet side.
                Log.Information("{pendingAddress} is activated by {signer} now.", pending.address, context.Signer);
                return(state
                       .SetState(activatedAddress, true.Serialize())
                       .SetState(pending.address, new Bencodex.Types.Null()));
            }
            else
            {
                throw new InvalidSignatureException(pending, Signature);
            }
        }
コード例 #30
0
        public static bool TryGetAvatarStateV2(
            this IAccountStateDelta states,
            Address agentAddress,
            Address avatarAddress,
            out AvatarState avatarState,
            out bool migrationRequired
            )
        {
            avatarState       = null;
            migrationRequired = false;
            if (states.GetState(avatarAddress) is Dictionary serializedAvatar)
            {
                try
                {
                    if (serializedAvatar[AgentAddressKey].ToAddress() != agentAddress)
                    {
                        return(false);
                    }

                    avatarState = GetAvatarStateV2(states, avatarAddress);
                    return(true);
                }
                catch (Exception e)
                {
                    // BackWardCompatible.
                    if (e is KeyNotFoundException || e is FailedLoadStateException)
                    {
                        migrationRequired = true;
                        return(states.TryGetAvatarState(agentAddress, avatarAddress, out avatarState));
                    }

                    return(false);
                }
            }

            return(false);
        }