示例#1
0
        public static IEnumerable <(Nep17Contract contract, BigInteger balance, uint lastUpdatedBlock)> GetNep17Balances(NeoSystem neoSystem, IStorageProvider storageProvider, UInt160 address)
        {
            // assets key is the script hash of the asset contract
            // assets value is the last updated block of the assoicated asset for address
            var assets = new Dictionary <UInt160, uint>();

            foreach (var(blockIndex, _, notification) in GetNep17Transfers(storageProvider))
            {
                var from = ToUInt160(notification.State[0]);
                var to   = ToUInt160(notification.State[1]);

                var fromAddress = notification.State[0].IsNull ? "<null>" : from.ToAddress(neoSystem.Settings.AddressVersion);
                var toAddress   = notification.State[1].IsNull ? "<null>" : to.ToAddress(neoSystem.Settings.AddressVersion);

                if (from == address || to == address)
                {
                    assets[notification.ScriptHash] = blockIndex;
                }
            }

            if (!assets.ContainsKey(NativeContract.NEO.Hash))
            {
                assets[NativeContract.NEO.Hash] = 0;
            }

            if (!assets.ContainsKey(NativeContract.GAS.Hash))
            {
                assets[NativeContract.GAS.Hash] = 0;
            }

            using var snapshot = neoSystem.GetSnapshot();
            foreach (var kvp in assets)
            {
                if (TryGetBalance(kvp.Key, out var balance) &&
                    balance > BigInteger.Zero)
                {
                    var contract = Nep17Contract.TryLoad(neoSystem.Settings, snapshot, kvp.Key, out var _contract)
                        ? _contract : Nep17Contract.Unknown(kvp.Key);
                    yield return(contract, balance, kvp.Value);
                }
            }

            bool TryGetBalance(UInt160 asset, out BigInteger balance)
            {
                using var sb = new ScriptBuilder();
                sb.EmitDynamicCall(asset, "balanceOf", address.ToArray());

                using var engine = sb.Invoke(neoSystem.Settings, snapshot);
                if (!engine.State.HasFlag(VMState.FAULT) && engine.ResultStack.Count >= 1)
                {
                    balance = engine.ResultStack.Pop <Neo.VM.Types.Integer>().GetInteger();
                    return(true);
                }

                balance = default;
                return(false);
            }
        }
示例#2
0
        public JObject ExpressGetPopulatedBlocks(JArray @params)
        {
            using var snapshot = neoSystem.GetSnapshot();
            var height = NativeContract.Ledger.CurrentIndex(snapshot);

            var count = @params.Count >= 1 ? uint.Parse(@params[0].AsString()) : 20;

            count = count > 100 ? 100 : count;

            var start = @params.Count >= 2 ? uint.Parse(@params[1].AsString()) : height;

            start = start > height ? height : start;

            var populatedBlocks = new JArray();
            var index           = start;

            while (true)
            {
                var hash = NativeContract.Ledger.GetBlockHash(snapshot, index)
                           ?? throw new Exception($"GetBlockHash for {index} returned null");
                var block = NativeContract.Ledger.GetTrimmedBlock(snapshot, hash)
                            ?? throw new Exception($"GetTrimmedBlock for {index} returned null");

                System.Diagnostics.Debug.Assert(block.Index == index);

                if (index == 0 || block.Hashes.Length > 0)
                {
                    populatedBlocks.Add(index);
                }

                if (index == 0 || populatedBlocks.Count >= count)
                {
                    break;
                }
                index--;
            }

            var response = new JObject();

            response["cacheId"] = cacheId;
            response["blocks"]  = populatedBlocks;
            return(response);
        }
示例#3
0
        public async Task <UInt256> SubmitOracleResponseAsync(OracleResponse response, IReadOnlyList <ECPoint> oracleNodes)
        {
            if (disposedValue)
            {
                throw new ObjectDisposedException(nameof(OfflineNode));
            }

            using var snapshot = neoSystem.GetSnapshot();
            var height  = NativeContract.Ledger.CurrentIndex(snapshot) + 1;
            var request = NativeContract.Oracle.GetRequest(snapshot, response.Id);
            var tx      = ExpressOracle.CreateResponseTx(snapshot, request, response, oracleNodes, ProtocolSettings);

            if (tx == null)
            {
                throw new Exception("Failed to create Oracle Response Tx");
            }
            ExpressOracle.SignOracleResponseTransaction(ProtocolSettings, chain, tx, oracleNodes);

            return(await SubmitTransactionAsync(tx));
        }
示例#4
0
        public static IEnumerable <Nep17Contract> GetNep17Contracts(NeoSystem neoSystem, IStorageProvider storageProvider)
        {
            var scriptHashes = new HashSet <UInt160>();

            foreach (var(_, _, notification) in GetNep17Transfers(storageProvider))
            {
                scriptHashes.Add(notification.ScriptHash);
            }

            scriptHashes.Add(NativeContract.NEO.Hash);
            scriptHashes.Add(NativeContract.GAS.Hash);

            using var snapshot = neoSystem.GetSnapshot();
            foreach (var scriptHash in scriptHashes)
            {
                if (Nep17Contract.TryLoad(neoSystem.Settings, snapshot, scriptHash, out var contract))
                {
                    yield return(contract);
                }
            }
        }
示例#5
0
        public void attribute_test()
        {
            var verificable = new DummyVerificable(new UInt160(new byte[20]));
            var snapshot    = _system.GetSnapshot().CreateSnapshot();

            using var testengine = new TestEngine(TriggerType.Application, verificable, snapshot: snapshot);
            Assert.IsTrue(testengine.AddEntryScript("./TestClasses/Contract_Attribute.cs").Success);

            var result = testengine.ExecuteTestCaseStandard("test");

            Assert.AreEqual(1, result.Count);
            var item = result.Pop();

            Assert.IsTrue(item.GetBoolean());

            testengine.Reset();
            verificable.Hashes = Array.Empty <UInt160>();

            result = testengine.ExecuteTestCaseStandard("test");
            Assert.AreEqual(VM.VMState.FAULT, testengine.State);
            Assert.AreEqual(0, result.Count);
            testengine.Dispose();
        }
示例#6
0
 internal static DataCache GetTestSnapshot()
 {
     return(TheNeoSystem.GetSnapshot().CreateSnapshot());
 }
示例#7
0
        private void Persist(Block block)
        {
            using (SnapshotCache snapshot = system.GetSnapshot())
            {
                List <ApplicationExecuted> all_application_executed = new List <ApplicationExecuted>();
                using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.OnPersist, null, snapshot, block))
                {
                    engine.LoadScript(onPersistScript);
                    if (engine.Execute() != VMState.HALT)
                    {
                        throw new InvalidOperationException();
                    }
                    ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                    Context.System.EventStream.Publish(application_executed);
                    all_application_executed.Add(application_executed);
                }
                DataCache clonedSnapshot = snapshot.CreateSnapshot();
                // Warning: Do not write into variable snapshot directly. Write into variable clonedSnapshot and commit instead.
                foreach (Transaction tx in block.Transactions)
                {
                    using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, block, tx.SystemFee))
                    {
                        engine.LoadScript(tx.Script);
                        if (engine.Execute() == VMState.HALT)
                        {
                            clonedSnapshot.Commit();
                        }
                        else
                        {
                            clonedSnapshot = snapshot.CreateSnapshot();
                        }
                        ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                        Context.System.EventStream.Publish(application_executed);
                        all_application_executed.Add(application_executed);
                    }
                }
                using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.PostPersist, null, snapshot, block))
                {
                    engine.LoadScript(postPersistScript);
                    if (engine.Execute() != VMState.HALT)
                    {
                        throw new InvalidOperationException();
                    }
                    ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                    Context.System.EventStream.Publish(application_executed);
                    all_application_executed.Add(application_executed);
                }
                foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
                {
                    plugin.OnPersist(block, snapshot, all_application_executed);
                }
                snapshot.Commit();
                List <Exception> commitExceptions = null;
                foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
                {
                    try
                    {
                        plugin.OnCommit(block, snapshot);
                    }
                    catch (Exception ex)
                    {
                        if (plugin.ShouldThrowExceptionFromCommit(ex))
                        {
                            if (commitExceptions == null)
                            {
                                commitExceptions = new List <Exception>();
                            }

                            commitExceptions.Add(ex);
                        }
                    }
                }
                if (commitExceptions != null)
                {
                    throw new AggregateException(commitExceptions);
                }
                system.MemPool.UpdatePoolForBlockPersisted(block, snapshot);
            }
            extensibleWitnessWhiteList = null;
            block_cache.Remove(block.PrevHash);
            Context.System.EventStream.Publish(new PersistCompleted {
                Block = block
            });
            if (system.HeaderCache.TryRemoveFirst(out Header header))
            {
                Debug.Assert(header.Index == block.Index);
            }
        }