Esempio n. 1
0
 private void OnNewHeaders(Header[] headers)
 {
     using (SnapshotView snapshot = GetSnapshot())
     {
         foreach (Header header in headers)
         {
             if (header.Index - 1 >= header_index.Count)
             {
                 break;
             }
             if (header.Index < header_index.Count)
             {
                 continue;
             }
             if (!header.Verify(snapshot))
             {
                 break;
             }
             header_index.Add(header.Hash);
             snapshot.Blocks.Add(header.Hash, header.Trim());
             snapshot.HeaderHashIndex.GetAndChange().Hash  = header.Hash;
             snapshot.HeaderHashIndex.GetAndChange().Index = header.Index;
         }
         SaveHeaderHashList(snapshot);
         snapshot.Commit();
     }
     UpdateCurrentSnapshot();
     system.TaskManager.Tell(new TaskManager.HeaderTaskCompleted(), Sender);
 }
Esempio n. 2
0
        private void SendPingMessage()
        {
            if (sessions.Count == 0)
            {
                return;
            }

            TrimmedBlock block;

            using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
            {
                block = snapshot.Blocks[snapshot.CurrentBlockHash];
            }

            foreach (KeyValuePair <IActorRef, TaskSession> item in sessions)
            {
                var node    = item.Key;
                var session = item.Value;

                if (session.ExpireTime < TimeProvider.Current.UtcNow ||
                    (block.Index >= session.LastBlockIndex &&
                     TimeProvider.Current.UtcNow.ToTimestampMS() - PingCoolingOffPeriod >= block.Timestamp))
                {
                    if (session.InvTasks.Remove(MemPoolTaskHash))
                    {
                        node.Tell(Message.Create(MessageCommand.Mempool));
                    }
                    node.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Blockchain.Singleton.Height)));
                    session.ExpireTime = TimeProvider.Current.UtcNow.AddMilliseconds(PingCoolingOffPeriod);
                }
            }
        }
Esempio n. 3
0
        public AssetDescriptor(UInt160 asset_id)
        {
            using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
            var contract = NativeContract.ContractManagement.GetContract(snapshot, asset_id);

            if (contract is null)
            {
                throw new ArgumentException();
            }

            byte[] script;
            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitDynamicCall(asset_id, "decimals", true);
                sb.EmitDynamicCall(asset_id, "symbol", true);
                script = sb.ToArray();
            }
            using ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, gas: 0_10000000);
            if (engine.State.HasFlag(VMState.FAULT))
            {
                throw new ArgumentException();
            }
            this.AssetId   = asset_id;
            this.AssetName = contract.Manifest.Name;
            this.Symbol    = engine.ResultStack.Pop().GetString();
            this.Decimals  = (byte)engine.ResultStack.Pop().GetInteger();
        }
        public JObject GetNep17Balances(JArray _params)
        {
            using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
            UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString());

            JObject json     = new JObject();
            JArray  balances = new JArray();

            json["balance"] = balances;
            json["address"] = userScriptHash.ToAddress();
            var dbCache = new DbCache <Nep17BalanceKey, Nep17Balance>(_db, null, null, Nep17BalancePrefix);

            byte[] prefix = userScriptHash.ToArray();
            foreach (var(key, value) in dbCache.Find(prefix))
            {
                JObject balance = new JObject();
                if (NativeContract.ContractManagement.GetContract(snapshot, key.AssetScriptHash) is null)
                {
                    continue;
                }
                balance["assethash"]        = key.AssetScriptHash.ToString();
                balance["amount"]           = value.Balance.ToString();
                balance["lastupdatedblock"] = value.LastUpdatedBlock;
                balances.Add(balance);
            }
            return(json);
        }
Esempio n. 5
0
        protected virtual JObject GetNextBlockValidators(JArray _params)
        {
            using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
            var validators = NativeContract.NEO.GetNextBlockValidators(snapshot);
            var candidates = NativeContract.NEO.GetCandidates(snapshot);

            if (candidates.Length > 0)
            {
                return(candidates.Select(p =>
                {
                    JObject validator = new JObject();
                    validator["publickey"] = p.PublicKey.ToString();
                    validator["votes"] = p.Votes.ToString();
                    validator["active"] = validators.Contains(p.PublicKey);
                    return validator;
                }).ToArray());
            }
            else
            {
                return(validators.Select(p =>
                {
                    JObject validator = new JObject();
                    validator["publickey"] = p.ToString();
                    validator["votes"] = 0;
                    validator["active"] = true;
                    return validator;
                }).ToArray());
            }
        }
Esempio n. 6
0
        public void BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered()
        {
            long txFee = 1;

            AddTransactionsWithBalanceVerify(70, txFee);

            _unit.SortedTxCount.Should().Be(70);

            var block = new Block
            {
                Transactions = _unit.GetSortedVerifiedTransactions().Take(10).ToArray()
            };

            // Simulate the transfer process in tx by burning the balance
            UInt160      sender   = block.Transactions[0].Sender;
            SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
            BigInteger   balance  = NativeContract.GAS.BalanceOf(snapshot, sender);

            ApplicationEngine applicationEngine = ApplicationEngine.Create(TriggerType.All, block, snapshot, (long)balance);

            NativeContract.GAS.Burn(applicationEngine, sender, balance);
            NativeContract.GAS.Mint(applicationEngine, sender, txFee * 30); // Set the balance to meet 30 txs only

            // Persist block and reverify all the txs in mempool, but half of the txs will be discarded
            _unit.UpdatePoolForBlockPersisted(block, snapshot);
            _unit.SortedTxCount.Should().Be(30);
            _unit.UnverifiedSortedTxCount.Should().Be(0);

            // Revert the balance
            NativeContract.GAS.Burn(applicationEngine, sender, txFee * 30);
            NativeContract.GAS.Mint(applicationEngine, sender, balance);
        }
Esempio n. 7
0
 public static ApplicationEngine Run(byte[] script, IVerifiable container = null, Block persistingBlock = null, bool testMode = false, long extraGAS = default)
 {
     using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
     {
         return(Run(script, snapshot, container, persistingBlock, testMode, extraGAS));
     }
 }
Esempio n. 8
0
        private void SaveHeaderHashList(SnapshotView snapshot = null)
        {
            if ((header_index.Count - stored_header_count < 2000))
            {
                return;
            }
            bool snapshot_created = snapshot == null;

            if (snapshot_created)
            {
                snapshot = GetSnapshot();
            }
            try
            {
                while (header_index.Count - stored_header_count >= 2000)
                {
                    snapshot.HeaderHashList.Add(stored_header_count, new HeaderHashList
                    {
                        Hashes = header_index.Skip((int)stored_header_count).Take(2000).ToArray()
                    });
                    stored_header_count += 2000;
                }
                if (snapshot_created)
                {
                    snapshot.Commit();
                }
            }
            finally
            {
                if (snapshot_created)
                {
                    snapshot.Dispose();
                }
            }
        }
Esempio n. 9
0
        protected virtual JObject GetContractState(JArray _params)
        {
            using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
            UInt160       script_hash = ToScriptHash(_params[0].AsString());
            ContractState contract    = NativeContract.ContractManagement.GetContract(snapshot, script_hash);

            return(contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract"));
        }
Esempio n. 10
0
        private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray contractParameters = null, UInt160[] witnessAddress = null)
        {
            List <Cosigner> signCollection = new List <Cosigner>();

            if (witnessAddress != null && !NoWallet())
            {
                using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                {
                    UInt160[] accounts = CurrentWallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).Where(p => NativeContract.GAS.BalanceOf(snapshot, p).Sign > 0).ToArray();
                    foreach (var signAccount in accounts)
                    {
                        if (witnessAddress is null)
                        {
                            break;
                        }
                        foreach (var witness in witnessAddress)
                        {
                            if (witness.Equals(signAccount))
                            {
                                signCollection.Add(new Cosigner()
                                {
                                    Account = signAccount
                                });
                                break;
                            }
                        }
                    }
                }
            }

            Transaction tx = new Transaction
            {
                Sender     = UInt160.Zero,
                Attributes = signCollection.ToArray(),
                Witnesses  = Array.Empty <Witness>(),
            };

            _ = OnInvokeWithResult(scriptHash, operation, tx, contractParameters);

            if (NoWallet())
            {
                return;
            }
            try
            {
                tx = CurrentWallet.MakeTransaction(tx.Script, null, tx.Attributes);
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine("Error: insufficient balance.");
                return;
            }
            if (!ReadUserInput("Relay tx(no|yes)").IsYes())
            {
                return;
            }
            SignAndSendTx(tx);
        }
Esempio n. 11
0
        /// <summary>
        /// Event fired when the Select None button is clicked
        /// </summary>
        private void SelectNoneBtn_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem I in SnapshotView.Items)
            {
                I.Checked = false;
            }

            SnapshotView.Update();
        }
        public void Execute(Arguments arguments)
        {
            GetSnapshotRequest request  = CreateRequest(arguments);
            Snapshot           snapshot = mediator.Send(request).Result;

            SnapshotView snapshotView = new SnapshotView(snapshot);

            snapshotView.Display();
        }
Esempio n. 13
0
        /// <summary>
        /// Make and send transaction with script, sender
        /// </summary>
        /// <param name="script">script</param>
        /// <param name="account">sender</param>
        private void SendTransaction(byte[] script, UInt160 account = null)
        {
            List <Cosigner> signCollection = new List <Cosigner>();

            if (account != null)
            {
                using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                {
                    UInt160[] accounts = CurrentWallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).Where(p => NativeContract.GAS.BalanceOf(snapshot, p).Sign > 0).ToArray();
                    foreach (var signAccount in accounts)
                    {
                        if (account.Equals(signAccount))
                        {
                            signCollection.Add(new Cosigner()
                            {
                                Account = signAccount
                            });
                            break;
                        }
                    }
                }
            }

            try
            {
                Transaction tx = CurrentWallet.MakeTransaction(script, account, signCollection?.ToArray());
                Console.WriteLine($"Invoking script with: '{tx.Script.ToHexString()}'");

                using (ApplicationEngine engine = ApplicationEngine.Run(tx.Script, tx, null, testMode: true))
                {
                    Console.WriteLine($"VM State: {engine.State}");
                    Console.WriteLine($"Gas Consumed: {new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals)}");
                    Console.WriteLine($"Evaluation Stack: {new JArray(engine.ResultStack.Select(p => p.ToParameter().ToJson()))}");
                    Console.WriteLine();
                    if (engine.State.HasFlag(VMState.FAULT))
                    {
                        Console.WriteLine("Engine faulted.");
                        return;
                    }
                }

                if (!ReadUserInput("relay tx(no|yes)").IsYes())
                {
                    return;
                }

                SignAndSendTx(tx);
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine("Error: insufficient balance.");
                return;
            }

            return;
        }
Esempio n. 14
0
        private void AddTransactionsWithBalanceVerify(int count, long fee, SnapshotView snapshot)
        {
            for (int i = 0; i < count; i++)
            {
                var txToAdd = CreateTransactionWithFeeAndBalanceVerify(fee);
                _unit.TryAdd(txToAdd, snapshot);
            }

            Console.WriteLine($"created {count} tx");
        }
        public IActionResult GetUnclaimedGas()
        {
            CheckWallet();
            BigInteger gas = BigInteger.Zero;

            using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                foreach (UInt160 account in wallet.GetAccounts().Select(p => p.ScriptHash))
                {
                    gas += NativeContract.NEO.UnclaimedGas(snapshot, account, snapshot.Height + 1);
                }
            return(FormatJson(gas.ToString()));
        }
Esempio n. 16
0
        private JObject GetWalletUnclaimedGas(JArray _params)
        {
            CheckWallet();
            BigInteger gas = BigInteger.Zero;

            using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                foreach (UInt160 account in wallet.GetAccounts().Select(p => p.ScriptHash))
                {
                    gas += NativeContract.NEO.UnclaimedGas(snapshot, account, snapshot.Height + 1);
                }
            return(gas.ToString());
        }
Esempio n. 17
0
        /// <summary>
        ///  Sets the data context for snapshot view.
        /// </summary>
        /// <returns> Snapshot view </returns>
        public SnapshotView GetSnapshotView()
        {
            if (snapshotViewModel == null)
            {
                snapshotViewModel = new SnapshotViewModel(GetSnapshotModel());
                snapshotView      = new SnapshotView()
                {
                    DataContext = snapshotViewModel
                };
            }

            return(snapshotView);
        }
Esempio n. 18
0
        /// <summary>
        /// Make and send transaction with script, sender
        /// </summary>
        /// <param name="script">script</param>
        /// <param name="account">sender</param>
        private void SendTransaction(byte[] script, UInt160 account = null)
        {
            Signer[] signers = System.Array.Empty <Signer>();

            if (account != null)
            {
                using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                {
                    signers = CurrentWallet.GetAccounts()
                              .Where(p => !p.Lock && !p.WatchOnly && p.ScriptHash == account && NativeContract.GAS.BalanceOf(snapshot, p.ScriptHash).Sign > 0)
                              .Select(p => new Signer()
                    {
                        Account = p.ScriptHash, Scopes = WitnessScope.CalledByEntry
                    })
                              .ToArray();
                }
            }

            try
            {
                Transaction tx = CurrentWallet.MakeTransaction(script, account, signers);
                Console.WriteLine($"Invoking script with: '{tx.Script.ToHexString()}'");

                using (ApplicationEngine engine = ApplicationEngine.Run(tx.Script, tx, null, testMode: true))
                {
                    Console.WriteLine($"VM State: {engine.State}");
                    Console.WriteLine($"Gas Consumed: {new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals)}");
                    Console.WriteLine($"Evaluation Stack: {new JArray(engine.ResultStack.Select(p => p.ToJson()))}");
                    Console.WriteLine();
                    if (engine.State.HasFlag(VMState.FAULT))
                    {
                        Console.WriteLine("Error: " + GetExceptionMessage(engine.FaultException));
                        return;
                    }
                }

                if (!ReadUserInput("relay tx(no|yes)").IsYes())
                {
                    return;
                }

                SignAndSendTx(tx);
            }
            catch (InvalidOperationException e)
            {
                Console.WriteLine("Error: " + GetExceptionMessage(e));
                return;
            }

            return;
        }
        private JObject GetValidators(JArray _params)
        {
            using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
            var validators = NativeContract.NEO.GetValidators(snapshot);

            return(NativeContract.NEO.GetRegisteredValidators(snapshot).Select(p =>
            {
                JObject validator = new JObject();
                validator["publickey"] = p.PublicKey.ToString();
                validator["votes"] = p.Votes.ToString();
                validator["active"] = validators.Contains(p.PublicKey);
                return validator;
            }).ToArray());
        }
Esempio n. 20
0
        private void OnShowGasCommand()
        {
            if (NoWallet())
            {
                return;
            }
            BigInteger gas = BigInteger.Zero;

            using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                foreach (UInt160 account in CurrentWallet.GetAccounts().Select(p => p.ScriptHash))
                {
                    gas += NativeContract.NEO.UnclaimedGas(snapshot, account, snapshot.Height + 1);
                }
            Console.WriteLine($"Unclaimed gas: {new BigDecimal(gas, NativeContract.GAS.Decimals)}");
        }
Esempio n. 21
0
        /// <summary>
        /// Make and send transaction with script, sender
        /// </summary>
        /// <param name="script">script</param>
        /// <param name="account">sender</param>
        private void SendTransaction(byte[] script, UInt160 account = null)
        {
            Signer[] signers = System.Array.Empty <Signer>();

            if (account != null)
            {
                using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                {
                    signers = CurrentWallet.GetAccounts()
                              .Where(p => !p.Lock && !p.WatchOnly && p.ScriptHash == account && NativeContract.GAS.BalanceOf(snapshot, p.ScriptHash).Sign > 0)
                              .Select(p => new Signer()
                    {
                        Account = p.ScriptHash, Scopes = WitnessScope.CalledByEntry
                    })
                              .ToArray();
                }
            }

            try
            {
                Transaction tx = CurrentWallet.MakeTransaction(script, account, signers);
                Console.WriteLine($"Invoking script with: '{tx.Script.ToBase64String()}'");

                using (ApplicationEngine engine = ApplicationEngine.Run(tx.Script, container: tx))
                {
                    PrintExecutionOutput(engine, true);
                    if (engine.State == VMState.FAULT)
                    {
                        return;
                    }
                }

                if (!ReadUserInput("Relay tx(no|yes)").IsYes())
                {
                    return;
                }

                SignAndSendTx(tx);
            }
            catch (InvalidOperationException e)
            {
                Console.WriteLine("Error: " + GetExceptionMessage(e));
                return;
            }

            return;
        }
        public IActionResult GetValidators()
        {
            JArray json = new JArray();

            using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
            var validators = NativeContract.NEO.GetValidators(snapshot);

            json = NativeContract.NEO.GetRegisteredValidators(snapshot).Select(p =>
            {
                JObject validator      = new JObject();
                validator["publickey"] = p.PublicKey.ToString();
                validator["votes"]     = p.Votes.ToString();
                validator["active"]    = validators.Contains(p.PublicKey);
                return(validator);
            }).ToArray();
            return(FormatJson(json));
        }
Esempio n. 23
0
        /// <summary>
        /// show unclaimed gas amount
        /// </summary>
        /// <returns></returns>
        public async Task <object> ShowGas()
        {
            if (CurrentWallet == null)
            {
                return(Error(ErrorCode.WalletNotOpen));
            }
            BigInteger gas = BigInteger.Zero;

            using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                foreach (UInt160 account in CurrentWallet.GetAccounts().Select(p => p.ScriptHash))
                {
                    gas += NativeContract.NEO.UnclaimedGas(snapshot, account, snapshot.Height + 1);
                }
            return(new UnclaimedGasModel()
            {
                UnclaimedGas = new BigDecimal(gas, NativeContract.GAS.Decimals)
            });
        }
Esempio n. 24
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="account"></param>
 /// <param name="snapshot"></param>
 /// <returns></returns>
 public static AccountType GetAccountType(this WalletAccount account, SnapshotView snapshot)
 {
     if (account.Contract != null)
     {
         if (account.Contract.Script.IsMultiSigContract(out _, out int _))
         {
             return(AccountType.MultiSignature);
         }
         if (account.Contract.Script.IsSignatureContract())
         {
             return(AccountType.Standard);
         }
         if (snapshot.Contracts.TryGet(account.Contract.ScriptHash) != null)
         {
             return(AccountType.DeployedContract);
         }
     }
     return(AccountType.NonStandard);
 }
Esempio n. 25
0
        protected virtual JObject GetStorage(JArray _params)
        {
            if (!int.TryParse(_params[0].AsString(), out int id))
            {
                using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
                UInt160       script_hash = UInt160.Parse(_params[0].AsString());
                ContractState contract    = NativeContract.ContractManagement.GetContract(snapshot, script_hash);
                if (contract == null)
                {
                    return(null);
                }
                id = contract.Id;
            }
            byte[]      key  = _params[1].AsString().HexToBytes();
            StorageItem item = Blockchain.Singleton.View.Storages.TryGet(new StorageKey
            {
                Id  = id,
                Key = key
            }) ?? new StorageItem();

            return(item.Value?.ToHexString());
        }
Esempio n. 26
0
        private JObject GetUnclaimedGas(JArray _params)
        {
            string  address = _params[0].AsString();
            JObject json    = new JObject();
            UInt160 script_hash;

            try
            {
                script_hash = address.ToScriptHash();
            }
            catch
            {
                script_hash = null;
            }
            if (script_hash == null)
            {
                throw new RpcException(-100, "Invalid address");
            }
            SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();

            json["unclaimed"] = NativeContract.NEO.UnclaimedGas(snapshot, script_hash, snapshot.Height + 1).ToString();
            json["address"]   = script_hash.ToAddress();
            return(json);
        }
Esempio n. 27
0
        private void Persist(Block block)
        {
            using (SnapshotView snapshot = GetSnapshot())
            {
                if (block.Index == header_index.Count)
                {
                    header_index.Add(block.Hash);
                    snapshot.HeaderHashIndex.GetAndChange().Set(block);
                }
                List <ApplicationExecuted> all_application_executed = new List <ApplicationExecuted>();
                snapshot.PersistingBlock = block;
                if (block.Index > 0)
                {
                    using (ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true))
                    {
                        engine.LoadScript(onPersistNativeContractScript);
                        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);
                    }
                }
                snapshot.Blocks.Add(block.Hash, block.Trim());
                StoreView clonedSnapshot = snapshot.Clone();
                // Warning: Do not write into variable snapshot directly. Write into variable clonedSnapshot and commit instead.
                foreach (Transaction tx in block.Transactions)
                {
                    var state = new TransactionState
                    {
                        BlockIndex  = block.Index,
                        Transaction = tx
                    };

                    clonedSnapshot.Transactions.Add(tx.Hash, state);
                    clonedSnapshot.Transactions.Commit();

                    using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee))
                    {
                        engine.LoadScript(tx.Script);
                        state.VMState = engine.Execute();
                        if (state.VMState == VMState.HALT)
                        {
                            clonedSnapshot.Commit();
                        }
                        else
                        {
                            clonedSnapshot = snapshot.Clone();
                        }
                        ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                        Context.System.EventStream.Publish(application_executed);
                        all_application_executed.Add(application_executed);
                    }
                }
                snapshot.BlockHashIndex.GetAndChange().Set(block);
                foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
                {
                    plugin.OnPersist(snapshot, all_application_executed);
                }
                snapshot.Commit();
                List <Exception> commitExceptions = null;
                foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
                {
                    try
                    {
                        plugin.OnCommit(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);
                }
            }
            UpdateCurrentSnapshot();
            block_cache.Remove(block.PrevHash);
            MemPool.UpdatePoolForBlockPersisted(block, currentSnapshot);
            Context.System.EventStream.Publish(new PersistCompleted {
                Block = block
            });
        }
Esempio n. 28
0
 protected virtual JObject GetCommittee(JArray _params)
 {
     using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
     return(new JArray(NativeContract.NEO.GetCommittee(snapshot).Select(p => (JObject)p.ToString())));
 }
Esempio n. 29
0
        private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray contractParameters = null, UInt160[] witnessAddress = null)
        {
            List <ContractParameter> parameters     = new List <ContractParameter>();
            List <Cosigner>          signCollection = new List <Cosigner>();

            if (!NoWallet() && witnessAddress != null)
            {
                using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
                {
                    UInt160[] accounts = CurrentWallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).Where(p => NativeContract.GAS.BalanceOf(snapshot, p).Sign > 0).ToArray();
                    foreach (var signAccount in accounts)
                    {
                        if (witnessAddress is null)
                        {
                            break;
                        }
                        foreach (var witness in witnessAddress)
                        {
                            if (witness.Equals(signAccount))
                            {
                                signCollection.Add(new Cosigner()
                                {
                                    Account = signAccount
                                });
                                break;
                            }
                        }
                    }
                }
            }

            if (contractParameters != null)
            {
                foreach (var contractParameter in contractParameters)
                {
                    parameters.Add(ContractParameter.FromJson(contractParameter));
                }
            }

            Transaction tx = new Transaction
            {
                Sender     = UInt160.Zero,
                Attributes = Array.Empty <TransactionAttribute>(),
                Witnesses  = Array.Empty <Witness>(),
                Cosigners  = signCollection.ToArray()
            };

            using (ScriptBuilder scriptBuilder = new ScriptBuilder())
            {
                scriptBuilder.EmitAppCall(scriptHash, operation, parameters.ToArray());
                tx.Script = scriptBuilder.ToArray();
                Console.WriteLine($"Invoking script with: '{tx.Script.ToHexString()}'");
            }

            using (ApplicationEngine engine = ApplicationEngine.Run(tx.Script, tx, testMode: true))
            {
                Console.WriteLine($"VM State: {engine.State}");
                Console.WriteLine($"Gas Consumed: {new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals)}");
                Console.WriteLine($"Evaluation Stack: {new JArray(engine.ResultStack.Select(p => p.ToParameter().ToJson()))}");
                Console.WriteLine();
                if (engine.State.HasFlag(VMState.FAULT))
                {
                    Console.WriteLine("Engine faulted.");
                    return;
                }
            }

            if (NoWallet())
            {
                return;
            }
            try
            {
                tx = CurrentWallet.MakeTransaction(tx.Script, null, tx.Attributes, tx.Cosigners);
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine("Error: insufficient balance.");
                return;
            }
            if (!ReadUserInput("relay tx(no|yes)").IsYes())
            {
                return;
            }
            SignAndSendTx(tx);
        }
Esempio n. 30
0
        private VerifyResult OnNewBlock(Block block)
        {
            if (block.Index <= Height)
            {
                return(VerifyResult.AlreadyExists);
            }
            if (block_cache.ContainsKey(block.Hash))
            {
                return(VerifyResult.AlreadyExists);
            }
            if (block.Index - 1 >= header_index.Count)
            {
                AddUnverifiedBlockToCache(block);
                return(VerifyResult.UnableToVerify);
            }
            if (block.Index == header_index.Count)
            {
                if (!block.Verify(currentSnapshot))
                {
                    return(VerifyResult.Invalid);
                }
            }
            else
            {
                if (!block.Hash.Equals(header_index[(int)block.Index]))
                {
                    return(VerifyResult.Invalid);
                }
            }
            if (block.Index == Height + 1)
            {
                Block        block_persist       = block;
                List <Block> blocksToPersistList = new List <Block>();
                while (true)
                {
                    blocksToPersistList.Add(block_persist);
                    if (block_persist.Index + 1 >= header_index.Count)
                    {
                        break;
                    }
                    UInt256 hash = header_index[(int)block_persist.Index + 1];
                    if (!block_cache.TryGetValue(hash, out block_persist))
                    {
                        break;
                    }
                }

                int blocksPersisted = 0;
                foreach (Block blockToPersist in blocksToPersistList)
                {
                    block_cache_unverified.Remove(blockToPersist.Index);
                    Persist(blockToPersist);

                    // 15000 is the default among of seconds per block, while MilliSecondsPerBlock is the current
                    uint extraBlocks = (15000 - MillisecondsPerBlock) / 1000;

                    if (blocksPersisted++ < blocksToPersistList.Count - (2 + Math.Max(0, extraBlocks)))
                    {
                        continue;
                    }
                    // Empirically calibrated for relaying the most recent 2 blocks persisted with 15s network
                    // Increase in the rate of 1 block per second in configurations with faster blocks

                    if (blockToPersist.Index + 100 >= header_index.Count)
                    {
                        system.LocalNode.Tell(new LocalNode.RelayDirectly {
                            Inventory = blockToPersist
                        });
                    }
                }
                SaveHeaderHashList();

                if (block_cache_unverified.TryGetValue(Height + 1, out LinkedList <Block> unverifiedBlocks))
                {
                    foreach (var unverifiedBlock in unverifiedBlocks)
                    {
                        Self.Tell(unverifiedBlock, ActorRefs.NoSender);
                    }
                    block_cache_unverified.Remove(Height + 1);
                }
            }
            else
            {
                block_cache.Add(block.Hash, block);
                if (block.Index + 100 >= header_index.Count)
                {
                    system.LocalNode.Tell(new LocalNode.RelayDirectly {
                        Inventory = block
                    });
                }
                if (block.Index == header_index.Count)
                {
                    header_index.Add(block.Hash);
                    using (SnapshotView snapshot = GetSnapshot())
                    {
                        snapshot.Blocks.Add(block.Hash, block.Header.Trim());
                        snapshot.HeaderHashIndex.GetAndChange().Set(block);
                        SaveHeaderHashList(snapshot);
                        snapshot.Commit();
                    }
                    UpdateCurrentSnapshot();
                }
            }
            return(VerifyResult.Succeed);
        }