Beispiel #1
0
        public async Task ResetAsync()
        {
            BakerCycles.Reset();
            BakingRights.Reset();
            Blocks.Reset();
            Protocols.Reset();
            Proposals.Reset();
            Periods.Reset();
            Statistics.Reset();
            Software.Reset();
            Schemas.Reset();
            Storages.Reset();
            BigMaps.Reset();
            BigMapKeys.Reset();

            await AppState.ResetAsync();

            await Accounts.ResetAsync();
        }
Beispiel #2
0
        async Task OriginateContract(Block block, string address)
        {
            var rawContract = await Proto.Rpc.GetContractAsync(block.Level, address);

            #region contract
            var contract = new Contract
            {
                Id              = Cache.AppState.NextAccountId(),
                FirstBlock      = block,
                Address         = address,
                Balance         = rawContract.RequiredInt64("balance"),
                Creator         = await Cache.Accounts.GetAsync(NullAddress.Address),
                Type            = AccountType.Contract,
                Kind            = ContractKind.SmartContract,
                MigrationsCount = 1,
            };

            Db.TryAttach(contract.Creator);
            contract.Creator.ContractsCount++;

            Db.Accounts.Add(contract);
            #endregion

            #region script
            var code           = Micheline.FromJson(rawContract.Required("script").Required("code")) as MichelineArray;
            var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter);
            var micheStorage   = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage);
            var micheCode      = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code);
            var micheViews     = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view);
            var script         = new Script
            {
                Id              = Cache.AppState.NextScriptId(),
                Level           = block.Level,
                ContractId      = contract.Id,
                ParameterSchema = micheParameter.ToBytes(),
                StorageSchema   = micheStorage.ToBytes(),
                CodeSchema      = micheCode.ToBytes(),
                Views           = micheViews.Any()
                    ? micheViews.Select(x => x.ToBytes()).ToArray()
                    : null,
                Current = true
            };

            var viewsBytes = script.Views?
                             .OrderBy(x => x, new BytesComparer())
                             .SelectMany(x => x)
                             .ToArray()
                             ?? Array.Empty <byte>();
            var typeSchema = script.ParameterSchema.Concat(script.StorageSchema).Concat(viewsBytes);
            var fullSchema = typeSchema.Concat(script.CodeSchema);
            contract.TypeHash = script.TypeHash = Script.GetHash(typeSchema);
            contract.CodeHash = script.CodeHash = Script.GetHash(fullSchema);

            if (script.Schema.IsFA1())
            {
                if (script.Schema.IsFA12())
                {
                    contract.Tags |= ContractTags.FA12;
                }

                contract.Tags |= ContractTags.FA1;
                contract.Kind  = ContractKind.Asset;
            }
            if (script.Schema.IsFA2())
            {
                contract.Tags |= ContractTags.FA2;
                contract.Kind  = ContractKind.Asset;
            }

            Db.Scripts.Add(script);
            #endregion

            #region storage
            var storageValue = Micheline.FromJson(rawContract.Required("script").Required("storage"));
            var storage      = new Storage
            {
                Id         = Cache.AppState.NextStorageId(),
                Level      = block.Level,
                ContractId = contract.Id,
                RawValue   = script.Schema.OptimizeStorage(storageValue, false).ToBytes(),
                JsonValue  = script.Schema.HumanizeStorage(storageValue),
                Current    = true
            };

            Db.Storages.Add(storage);
            #endregion

            #region migration
            var migration = new MigrationOperation
            {
                Id            = Cache.AppState.NextOperationId(),
                Block         = block,
                Level         = block.Level,
                Timestamp     = block.Timestamp,
                Kind          = MigrationKind.Origination,
                Account       = contract,
                BalanceChange = contract.Balance,
                Script        = script,
                Storage       = storage,
            };

            script.MigrationId  = migration.Id;
            storage.MigrationId = migration.Id;

            block.Events     |= BlockEvents.SmartContracts;
            block.Operations |= Operations.Migrations;

            var state = Cache.AppState.Get();
            state.MigrationOpsCount++;

            var statistics = await Cache.Statistics.GetAsync(state.Level);

            statistics.TotalCreated += contract.Balance;

            Db.MigrationOps.Add(migration);
            #endregion

            #region bigmaps
            var storageScript = new ContractStorage(micheStorage);
            var storageTree   = storageScript.Schema.ToTreeView(storageValue);
            var bigmaps       = storageTree.Nodes()
                                .Where(x => x.Schema is BigMapSchema)
                                .Select(x => (x, x.Schema as BigMapSchema, (int)(x.Value as MichelineInt).Value));

            foreach (var(bigmap, schema, ptr) in bigmaps)
            {
                block.Events |= BlockEvents.Bigmaps;

                migration.BigMapUpdates = (migration.BigMapUpdates ?? 0) + 1;
                Db.BigMapUpdates.Add(new BigMapUpdate
                {
                    Id          = Cache.AppState.NextBigMapUpdateId(),
                    Action      = BigMapAction.Allocate,
                    BigMapPtr   = ptr,
                    Level       = block.Level,
                    MigrationId = migration.Id
                });

                var allocated = new BigMap
                {
                    Id          = Cache.AppState.NextBigMapId(),
                    Ptr         = ptr,
                    ContractId  = contract.Id,
                    StoragePath = bigmap.Path,
                    KeyType     = schema.Key.ToMicheline().ToBytes(),
                    ValueType   = schema.Value.ToMicheline().ToBytes(),
                    Active      = true,
                    FirstLevel  = block.Level,
                    LastLevel   = block.Level,
                    ActiveKeys  = 0,
                    TotalKeys   = 0,
                    Updates     = 1,
                    Tags        = BigMaps.GetTags(bigmap)
                };
                Db.BigMaps.Add(allocated);

                if (address == LiquidityToken && allocated.StoragePath == "tokens")
                {
                    var rawKey   = new MichelineString(NullAddress.Address);
                    var rawValue = new MichelineInt(100);

                    allocated.ActiveKeys++;
                    allocated.TotalKeys++;
                    allocated.Updates++;
                    var key = new BigMapKey
                    {
                        Id         = Cache.AppState.NextBigMapKeyId(),
                        Active     = true,
                        BigMapPtr  = ptr,
                        FirstLevel = block.Level,
                        LastLevel  = block.Level,
                        JsonKey    = schema.Key.Humanize(rawKey),
                        JsonValue  = schema.Value.Humanize(rawValue),
                        RawKey     = schema.Key.Optimize(rawKey).ToBytes(),
                        RawValue   = schema.Value.Optimize(rawValue).ToBytes(),
                        KeyHash    = schema.GetKeyHash(rawKey),
                        Updates    = 1
                    };
                    Db.BigMapKeys.Add(key);

                    migration.BigMapUpdates++;
                    Db.BigMapUpdates.Add(new BigMapUpdate
                    {
                        Id          = Cache.AppState.NextBigMapUpdateId(),
                        Action      = BigMapAction.AddKey,
                        BigMapKeyId = key.Id,
                        BigMapPtr   = key.BigMapPtr,
                        JsonValue   = key.JsonValue,
                        RawValue    = key.RawValue,
                        Level       = key.LastLevel,
                        MigrationId = migration.Id
                    });
                }
            }
            #endregion
        }