private void InitializeConsensus(byte view_number) { lock (context) { if (view_number == 0) { context.Reset(wallet); } else { context.ChangeView(view_number); } if (context.MyIndex < 0) { return; } Log($"initialize: height={context.BlockIndex} view={view_number} index={context.MyIndex} role={(context.MyIndex == context.PrimaryIndex ? ConsensusState.Primary : ConsensusState.Backup)}"); if (context.MyIndex == context.PrimaryIndex) { context.State |= ConsensusState.Primary; if (!context.State.HasFlag(ConsensusState.SignatureSent)) { FillContext(); } if (context.TransactionHashes.Length > 1) { InvPayload invPayload = InvPayload.Create(InventoryType.TX, context.TransactionHashes.Skip(1).ToArray()); foreach (RemoteNode node in localNode.GetRemoteNodes()) { node.EnqueueMessage("inv", invPayload); } } timer_height = context.BlockIndex; timer_view = view_number; // 议长发起共识时间控制 TimeSpan span = DateTime.Now - block_received_time; if (span >= Blockchain.TimePerBlock) { timer.Change(0, Timeout.Infinite);// 间隔时间大于预订时间则立即发起共识 } else { timer.Change(Blockchain.TimePerBlock - span, Timeout.InfiniteTimeSpan);// 定时执行 } } else { context.State = ConsensusState.Backup; timer_height = context.BlockIndex; timer_view = view_number; // 议员超时控制 t * 2 ^ (view_number + 1) timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (view_number + 1)), Timeout.InfiniteTimeSpan); } } }
private void ClearRts(LocalNode localNode) { foreach (RemoteNode node in localNode.GetRemoteNodes()) { node.ClearCounters(); } }
private JObject GetPeers(JObject param) { LocalNode localNode = GetTargetNode(param); JObject json = new JObject(); if (localNode != null) { json["unconnected"] = new JArray(localNode.GetUnconnectedPeers().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Address.ToString(); peerJson["port"] = p.Port; return(peerJson); })); json["bad"] = new JArray(); //badpeers has been removed json["connected"] = new JArray(localNode.GetRemoteNodes().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Remote.Address.ToString(); peerJson["port"] = p.ListenerPort; return(peerJson); })); } return(json); }
private void OnShowStateCommand() { var cancel = new CancellationTokenSource(); Console.CursorVisible = false; Console.Clear(); Task broadcast = Task.Run(async() => { while (!cancel.Token.IsCancellationRequested) { NeoSystem.LocalNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(NativeContract.Ledger.CurrentIndex(NeoSystem.StoreView)))); await Task.Delay(NeoSystem.Settings.TimePerBlock, cancel.Token); } }); Task task = Task.Run(async() => { int maxLines = 0; while (!cancel.Token.IsCancellationRequested) { uint height = NativeContract.Ledger.CurrentIndex(NeoSystem.StoreView); uint headerHeight = NeoSystem.HeaderCache.Last?.Index ?? height; Console.SetCursorPosition(0, 0); WriteLineWithoutFlicker($"block: {height}/{headerHeight} connected: {LocalNode.ConnectedCount} unconnected: {LocalNode.UnconnectedCount}", Console.WindowWidth - 1); int linesWritten = 1; foreach (RemoteNode node in LocalNode.GetRemoteNodes().OrderByDescending(u => u.LastBlockIndex).Take(Console.WindowHeight - 2).ToArray()) { ConsoleHelper.Info(" ip: ", $"{ node.Remote.Address,-15}\t", "port: ", $"{node.Remote.Port,-5}\t", "listen: ", $"{node.ListenerTcpPort,-5}\t", "height: ", $"{node.LastBlockIndex,-7}"); linesWritten++; } maxLines = Math.Max(maxLines, linesWritten); while (linesWritten < maxLines) { WriteLineWithoutFlicker("", Console.WindowWidth - 1); maxLines--; } await Task.Delay(500, cancel.Token); } }); ReadLine(); cancel.Cancel(); try { Task.WaitAll(task, broadcast); } catch { } Console.WriteLine(); Console.CursorVisible = true; }
private bool OnShowNodeCommand(string[] args) { RemoteNode[] nodes = localnode.GetRemoteNodes(); for (int i = 0; i < nodes.Length; i++) { Console.WriteLine($"{nodes[i].RemoteEndpoint.Address} port:{nodes[i].RemoteEndpoint.Port} listen:{nodes[i].ListenerEndpoint?.Port ?? 0} [{i + 1}/{nodes.Length}]"); } return(true); }
private void ShowState(LocalNode localNode, bool printRemoteNode) { Blockchain blockchain = localNode.Blockchain; Console.WriteLine($"block:{blockchain.Name} {blockchain.ChainHash.ToString()} {blockchain.Height}/{blockchain.HeaderHeight} connected: {localNode.ConnectedCount} unconnected: {localNode.UnconnectedCount} mempool:{blockchain.GetMemoryPoolCount()}"); if (printRemoteNode) { foreach (RemoteNode node in localNode.GetRemoteNodes()) { Console.WriteLine($" ip: {node.Remote.Address}\tport: {node.Remote.Port}\tlisten: {node.ListenerPort}\theight: {node.Height}\tlatency: {node.Latency}"); } } }
private void ShowRts(LocalNode localNode, InventoryType type) { Blockchain blockchain = localNode.Blockchain; Console.WriteLine($"block:{blockchain.Name} {blockchain.ChainHash.ToString()} {blockchain.Height}/{blockchain.HeaderHeight} connected: {localNode.ConnectedCount} mempool:{blockchain.GetMemoryPoolCount()} TX:{GetTXRate(localNode.TxRate)}"); foreach (RemoteNode node in localNode.GetRemoteNodes()) { Console.WriteLine($" ip: {node.Remote.Address}\t" + $"send: {node.GetCounter(RemoteNode.CounterType.Send, type)} " + $"request: {node.GetCounter(RemoteNode.CounterType.Request, type)} " + $"recv: {node.GetCounter(RemoteNode.CounterType.Received, type)} " + $"timeout: {node.GetCounter(RemoteNode.CounterType.Timeout, type)} " + $"TX:{GetTXRate(node.TXRate)}"); } }
private void OnTimeout(object state) { lock (context) { if (timer_height != context.BlockIndex || timer_view != context.ViewNumber) { return; } Log($"timeout: height={timer_height} view={timer_view} state={context.State}"); if (context.State.HasFlag(ConsensusState.Primary) && !context.State.HasFlag(ConsensusState.RequestSent)) { Log($"send perpare request: height={timer_height} view={timer_view}"); context.State |= ConsensusState.RequestSent; if (!context.State.HasFlag(ConsensusState.SignatureSent)) { context.Timestamp = Math.Max(DateTime.Now.ToTimestamp(), Blockchain.Default.GetHeader(context.PrevHash).Timestamp + 1); context.Nonce = GetNonce(); List <Transaction> transactions = LocalNode.GetMemoryPool().Where(p => CheckPolicy(p)).ToList(); if (transactions.Count >= Settings.Default.MaxTransactionsPerBlock) { transactions = transactions.OrderByDescending(p => p.NetworkFee / p.Size).Take(Settings.Default.MaxTransactionsPerBlock - 1).ToList(); } transactions.Insert(0, CreateMinerTransaction(transactions, context.BlockIndex, context.Nonce)); context.TransactionHashes = transactions.Select(p => p.Hash).ToArray(); context.Transactions = transactions.ToDictionary(p => p.Hash); context.NextConsensus = Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(transactions).ToArray()); context.Signatures[context.MyIndex] = context.MakeHeader().Sign(context.KeyPair); } InvPayload invPayload = InvPayload.Create(InventoryType.TX, context.TransactionHashes); foreach (RemoteNode node in localNode.GetRemoteNodes()) { node.EnqueueMessage("inv", invPayload); } SignAndRelay(context.MakePrepareRequest()); timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (timer_view + 1)), Timeout.InfiniteTimeSpan); } else if ((context.State.HasFlag(ConsensusState.Primary) && context.State.HasFlag(ConsensusState.RequestSent)) || context.State.HasFlag(ConsensusState.Backup)) { RequestChangeView(); } } }
protected virtual JObject Process(string method, JArray _params) { switch (method) { case "getaccountstate": { UInt160 script_hash = Wallet.ToScriptHash(_params[0].AsString()); AccountState account = Blockchain.Default.GetAccountState(script_hash) ?? new AccountState(script_hash); return(account.ToJson()); } case "getassetstate": { UInt256 asset_id = UInt256.Parse(_params[0].AsString()); AssetState asset = Blockchain.Default.GetAssetState(asset_id); return(asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset")); } case "getbestblockhash": return(Blockchain.Default.CurrentBlockHash.ToString()); case "getblock": { Block block; if (_params[0] is JNumber) { uint index = (uint)_params[0].AsNumber(); block = Blockchain.Default.GetBlock(index); } else { UInt256 hash = UInt256.Parse(_params[0].AsString()); block = Blockchain.Default.GetBlock(hash); } if (block == null) { throw new RpcException(-100, "Unknown block"); } bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false); if (verbose) { JObject json = block.ToJson(); json["confirmations"] = Blockchain.Default.Height - block.Index + 1; UInt256 hash = Blockchain.Default.GetNextBlockHash(block.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } else { return(block.ToArray().ToHexString()); } } case "getblockcount": return(Blockchain.Default.Height + 1); case "getblockhash": { uint height = (uint)_params[0].AsNumber(); if (height >= 0 && height <= Blockchain.Default.Height) { return(Blockchain.Default.GetBlockHash(height).ToString()); } else { throw new RpcException(-100, "Invalid Height"); } } case "getblocksysfee": { uint height = (uint)_params[0].AsNumber(); if (height >= 0 && height <= Blockchain.Default.Height) { return(Blockchain.Default.GetSysFeeAmount(height).ToString()); } else { throw new RpcException(-100, "Invalid Height"); } } case "getconnectioncount": return(LocalNode.RemoteNodeCount); case "getcontractstate": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractState contract = Blockchain.Default.GetContract(script_hash); return(contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract")); } case "getrawmempool": return(new JArray(LocalNode.GetMemoryPool().Select(p => (JObject)p.Hash.ToString()))); case "getrawtransaction": { UInt256 hash = UInt256.Parse(_params[0].AsString()); bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false); int height = -1; Transaction tx = LocalNode.GetTransaction(hash); if (tx == null) { tx = Blockchain.Default.GetTransaction(hash, out height); } if (tx == null) { throw new RpcException(-100, "Unknown transaction"); } if (verbose) { JObject json = tx.ToJson(); if (height >= 0) { Header header = Blockchain.Default.GetHeader((uint)height); json["blockhash"] = header.Hash.ToString(); json["confirmations"] = Blockchain.Default.Height - header.Index + 1; json["blocktime"] = header.Timestamp; } return(json); } else { return(tx.ToArray().ToHexString()); } } case "getstorage": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); byte[] key = _params[1].AsString().HexToBytes(); StorageItem item = Blockchain.Default.GetStorageItem(new StorageKey { ScriptHash = script_hash, Key = key }) ?? new StorageItem(); return(item.Value?.ToHexString()); } case "gettxout": { UInt256 hash = UInt256.Parse(_params[0].AsString()); ushort index = (ushort)_params[1].AsNumber(); return(Blockchain.Default.GetUnspent(hash, index)?.ToJson(index)); } case "invoke": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractParameter[] parameters = ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray(); byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, parameters).ToArray(); } return(GetInvokeResult(script)); } case "invokefunction": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); string operation = _params[1].AsString(); ContractParameter[] args = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, operation, args).ToArray(); } return(GetInvokeResult(script)); } case "invokescript": { byte[] script = _params[0].AsString().HexToBytes(); return(GetInvokeResult(script)); } case "sendrawtransaction": { Transaction tx = Transaction.DeserializeFrom(_params[0].AsString().HexToBytes()); return(LocalNode.Relay(tx)); } case "submitblock": { Block block = _params[0].AsString().HexToBytes().AsSerializable <Block>(); return(LocalNode.Relay(block)); } case "validateaddress": { JObject json = new JObject(); UInt160 scriptHash; try { scriptHash = Wallet.ToScriptHash(_params[0].AsString()); } catch { scriptHash = null; } json["address"] = _params[0]; json["isvalid"] = scriptHash != null; return(json); } case "getpeers": { JObject json = new JObject(); { JArray unconnectedPeers = new JArray(); foreach (IPEndPoint peer in LocalNode.GetUnconnectedPeers()) { JObject peerJson = new JObject(); peerJson["address"] = peer.Address.ToString(); peerJson["port"] = peer.Port; unconnectedPeers.Add(peerJson); } json["unconnected"] = unconnectedPeers; } { JArray badPeers = new JArray(); foreach (IPEndPoint peer in LocalNode.GetBadPeers()) { JObject peerJson = new JObject(); peerJson["address"] = peer.Address.ToString(); peerJson["port"] = peer.Port; badPeers.Add(peerJson); } json["bad"] = badPeers; } { JArray connectedPeers = new JArray(); foreach (RemoteNode node in LocalNode.GetRemoteNodes()) { JObject peerJson = new JObject(); peerJson["address"] = node.RemoteEndpoint.Address.ToString(); peerJson["port"] = node.ListenerEndpoint?.Port ?? 0; connectedPeers.Add(peerJson); } json["connected"] = connectedPeers; } return(json); } case "getversion": { JObject json = new JObject(); json["port"] = LocalNode.Port; json["nonce"] = LocalNode.Nonce; json["useragent"] = LocalNode.UserAgent; return(json); } default: throw new RpcException(-32601, "Method not found"); } }
private JObject Process(string method, JArray _params) { switch (method) { case "getaccountstate": { UInt160 script_hash = _params[0].AsString().ToScriptHash(); AccountState account = Blockchain.Root.Store.GetAccounts().TryGet(script_hash) ?? new AccountState(script_hash); return(account.ToJson()); } case "getassetstate": { UInt256 asset_id = UInt256.Parse(_params[0].AsString()); AssetState asset = Blockchain.Root.Store.GetAssets().TryGet(asset_id); return(asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset")); } case "getbalance": if (wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //NEP-5 balance json["balance"] = wallet.GetAvailable(asset_id_160).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); json["balance"] = coins.Sum(p => p.Output.Value).ToString(); json["confirmed"] = coins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString(); break; } return(json); } case "getbestblockhash": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } return(blockchain.CurrentBlockHash.ToString()); } case "getblock": { Block block; UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } if (_params[1] is JNumber) { uint index = (uint)_params[1].AsNumber(); block = blockchain.Store.GetBlock(index); } else { UInt256 hash = UInt256.Parse(_params[1].AsString()); block = blockchain.Store.GetBlock(hash); } if (block == null) { throw new RpcException(-100, "Unknown block"); } bool verbose = _params.Count >= 3 && _params[2].AsBooleanOrDefault(false); if (verbose) { JObject json = block.ToJson(); json["confirmations"] = blockchain.Height - block.Index + 1; UInt256 hash = blockchain.Store.GetNextBlockHash(block.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } return(block.ToArray().ToHexString()); } case "getblockcount": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } return(blockchain.Height + 1); } case "getblockhash": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } uint height = (uint)_params[1].AsNumber(); if (height <= blockchain.Height) { return(blockchain.GetBlockHash(height).ToString()); } throw new RpcException(-100, "Invalid Height"); } case "getblockheader": { Header header; UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } if (_params[1] is JNumber) { uint height = (uint)_params[1].AsNumber(); header = blockchain.Store.GetHeader(height); } else { UInt256 hash = UInt256.Parse(_params[1].AsString()); header = blockchain.Store.GetHeader(hash); } if (header == null) { throw new RpcException(-100, "Unknown block"); } bool verbose = _params.Count >= 3 && _params[2].AsBooleanOrDefault(false); if (verbose) { JObject json = header.ToJson(); json["confirmations"] = blockchain.Height - header.Index + 1; UInt256 hash = blockchain.Store.GetNextBlockHash(header.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } return(header.ToArray().ToHexString()); } case "getblocksysfee": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } uint height = (uint)_params[1].AsNumber(); if (height <= blockchain.Height) { return(blockchain.Store.GetSysFeeAmount(height).ToString()); } throw new RpcException(-100, "Invalid Height"); } case "getconnectioncount": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); LocalNode localNode = LocalNode.GetLocalNode(chain_hash); return(localNode != null ? localNode.ConnectedCount : 0); } case "getcontractstate": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } UInt160 script_hash = UInt160.Parse(_params[1].AsString()); ContractState contract = blockchain.Store.GetContracts().TryGet(script_hash); return(contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract")); } case "getnewaddress": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletAccount account = wallet.CreateAccount(); if (wallet is NEP6Wallet nep6) { nep6.Save(); } return(account.Address); } case "getpeers": { JObject json = new JObject(); UInt160 chain_hash = UInt160.Parse(_params[0].AsString()); LocalNode localNode = LocalNode.GetLocalNode(chain_hash); if (localNode != null) { json["unconnected"] = new JArray(localNode.GetUnconnectedPeers().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Address.ToString(); peerJson["port"] = p.Port; return(peerJson); })); json["bad"] = new JArray(); //badpeers has been removed json["connected"] = new JArray(localNode.GetRemoteNodes().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Remote.Address.ToString(); peerJson["port"] = p.ListenerPort; return(peerJson); })); } return(json); } case "getrawmempool": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } return(new JArray(blockchain.GetMemoryPool().Select(p => (JObject)p.Hash.ToString()))); } case "getrawtransaction": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } UInt256 hash = UInt256.Parse(_params[1].AsString()); bool verbose = _params.Count >= 3 && _params[2].AsBooleanOrDefault(false); Transaction tx = blockchain.GetTransaction(hash); if (tx == null) { throw new RpcException(-100, "Unknown transaction"); } if (verbose) { JObject json = tx.ToJson(); uint? height = blockchain.Store.GetTransactions().TryGet(hash)?.BlockIndex; if (height != null) { Header header = blockchain.Store.GetHeader((uint)height); json["blockhash"] = header.Hash.ToString(); json["confirmations"] = blockchain.Height - header.Index + 1; json["blocktime"] = header.Timestamp; } return(json); } return(tx.ToArray().ToHexString()); } case "getstorage": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } UInt160 script_hash = UInt160.Parse(_params[1].AsString()); byte[] key = _params[1].AsString().HexToBytes(); StorageItem item = blockchain.Store.GetStorages().TryGet(new StorageKey { ScriptHash = script_hash, Key = key }) ?? new StorageItem(); return(item.Value?.ToHexString()); } case "gettxout": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } UInt256 hash = UInt256.Parse(_params[1].AsString()); ushort index = (ushort)_params[2].AsNumber(); return(blockchain.Store.GetUnspent(hash, index)?.ToJson(index)); } case "getvalidators": { UInt160 chain_hash = _params[0].AsString().ToScriptHash(); Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } using (Snapshot snapshot = blockchain.GetSnapshot()) { var validators = snapshot.GetValidators(); return(snapshot.GetEnrollments().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()); } } case "getversion": { JObject json = new JObject(); json["port"] = LocalNode.Root.ListenerPort; json["nonce"] = LocalNode.Nonce; json["useragent"] = LocalNode.UserAgent; return(json); } case "getwalletheight": if (wallet == null) { throw new RpcException(-400, "Access denied."); } else { return((wallet.WalletHeight > 0) ? wallet.WalletHeight - 1 : 0); } case "invoke": { UInt160 chain_hash = UInt160.Parse(_params[0].AsString()); UInt160 script_hash = UInt160.Parse(_params[1].AsString()); ContractParameter[] parameters = ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray(); byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, parameters).ToArray(); } return(GetInvokeResult(chain_hash, script)); } case "invokefunction": { UInt160 chain_hash = UInt160.Parse(_params[0].AsString()); UInt160 script_hash = UInt160.Parse(_params[1].AsString()); string operation = _params[2].AsString(); ContractParameter[] args = _params.Count >= 4 ? ((JArray)_params[3]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, operation, args).ToArray(); } return(GetInvokeResult(chain_hash, script)); } case "invokescript": { UInt160 chain_hash = UInt160.Parse(_params[0].AsString()); byte[] script = _params[1].AsString().HexToBytes(); return(GetInvokeResult(chain_hash, script)); } case "listaddress": if (wallet == null) { throw new RpcException(-400, "Access denied."); } else { return(wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "sendrawtransaction": { UInt160 chain_hash = UInt160.Parse(_params[0].AsString()); if (system.GetAppChainSystem(chain_hash, out ZoroSystem targetSystem)) { Transaction tx = Transaction.DeserializeFrom(_params[1].AsString().HexToBytes()); RelayResultReason reason = targetSystem.Blockchain.Ask <RelayResultReason>(tx).Result; return(GetRelayResult(reason)); } return(RelayResultReason.Invalid); } case "submitblock": { UInt160 chain_hash = UInt160.Parse(_params[0].AsString()); if (system.GetAppChainSystem(chain_hash, out ZoroSystem targetSystem)) { Block block = _params[0].AsString().HexToBytes().AsSerializable <Block>(); RelayResultReason reason = targetSystem.Blockchain.Ask <RelayResultReason>(block).Result; return(GetRelayResult(reason)); } return(RelayResultReason.Invalid); } case "validateaddress": { JObject json = new JObject(); UInt160 scriptHash; try { scriptHash = _params[0].AsString().ToScriptHash(); } catch { scriptHash = null; } json["address"] = _params[0]; json["isvalid"] = scriptHash != null; return(json); } default: throw new RpcException(-32601, "Method not found"); } }
private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest message) { Log($"{nameof(OnPrepareRequestReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex} tx={message.TransactionHashes.Length}"); if (!context.State.HasFlag(ConsensusState.Backup) || context.State.HasFlag(ConsensusState.RequestReceived)) { return; } if (payload.ValidatorIndex != context.PrimaryIndex) { return; } if (payload.Timestamp <= Blockchain.Default.GetHeader(context.PrevHash).Timestamp || payload.Timestamp > DateTime.Now.AddMinutes(10).ToTimestamp()) { Log($"Timestamp incorrect: {payload.Timestamp}"); return; } context.State |= ConsensusState.RequestReceived; context.Timestamp = payload.Timestamp; context.Nonce = message.Nonce; context.CurrentConsensus = message.CurrentConsensus; context.NextConsensus = message.NextConsensus; context.TransactionHashes = message.TransactionHashes; if (context.TransactionHashes.Length > MaxTransactionsPerBlock) { return; } context.Transactions = new Dictionary <UInt256, Transaction>(); if (!Crypto.Default.VerifySignature(context.MakeHeader().GetHashData(), message.Signature, context.Validators[payload.ValidatorIndex].EncodePoint(false))) { return; } context.Signatures = new byte[context.Validators.Length][]; context.Signatures[payload.ValidatorIndex] = message.Signature; Dictionary <UInt256, Transaction> mempool = LocalNode.GetMemoryPool().ToDictionary(p => p.Hash); foreach (UInt256 hash in context.TransactionHashes.Skip(1)) { if (mempool.TryGetValue(hash, out Transaction tx)) { Console.WriteLine("No Verify Add Transaction" + tx.is_consensus_mempool); if (!AddTransaction(tx, true)) { return; } } } if (!AddTransaction(message.MinerTransaction, true)) { return; } if (context.Transactions.Count < context.TransactionHashes.Length) { LocalNode.AllowHashes(context.TransactionHashes.Except(context.Transactions.Keys)); UInt256[] hashes = context.TransactionHashes.ToArray(); // get hashes InvPayload msg = InvPayload.Create(InventoryType.TX, hashes); // create message foreach (RemoteNode node in localNode.GetRemoteNodes()) // enqueue message { node.EnqueueMessage("getdata", msg); } } }