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); } }
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); }
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)); }
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); } } }
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(); }
internal static DataCache GetTestSnapshot() { return(TheNeoSystem.GetSnapshot().CreateSnapshot()); }
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); } }