private void OnGetDataMessageReceived(InvPayload payload) { foreach (UInt256 hash in payload.Hashes.Distinct()) { IInventory inventory; if (!localNode.RelayCache.TryGet(hash, out inventory) && !localNode.ServiceEnabled) { continue; } switch (payload.Type) { case InventoryType.TX: if (inventory == null) { inventory = LocalNode.GetTransaction(hash); } if (inventory == null && Blockchain.Default != null) { inventory = Blockchain.Default.GetTransaction(hash); } if (inventory != null) { EnqueueMessage("tx", inventory); } break; case InventoryType.Block: if (inventory == null && Blockchain.Default != null) { inventory = Blockchain.Default.GetBlock(hash); } if (inventory != null) { BloomFilter filter = bloom_filter; if (filter == null) { EnqueueMessage("block", inventory); } else { Block block = (Block)inventory; BitArray flags = new BitArray(block.Transactions.Select(p => TestFilter(filter, p)).ToArray()); EnqueueMessage("merkleblock", MerkleBlockPayload.Create(block, flags)); } } break; case InventoryType.Consensus: if (inventory != null) { EnqueueMessage("consensus", inventory); } break; } } }
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"); } }
protected virtual JObject Process(string method, JArray _params) { switch (method) { 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(); return(Blockchain.Default.GetBlockHash(height).ToString()); } case "getconnectioncount": return(LocalNode.RemoteNodeCount); 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(-101, "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 "gettxout": { UInt256 hash = UInt256.Parse(_params[0].AsString()); ushort index = (ushort)_params[1].AsNumber(); return(Blockchain.Default.GetUnspent(hash, index)?.ToJson(index)); } 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); } default: throw new RpcException(-32601, "Method not found"); } }
private JObject InternalCall(string method, JArray _params) { switch (method) { case "getbalance": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { UInt256 assetId = UInt256.Parse(_params[0].AsString()); IEnumerable <Coin> coins = Program.Wallet.FindCoins().Where(p => p.AssetId.Equals(assetId)); JObject json = new JObject(); json["balance"] = coins.Where(p => p.State == CoinState.Unspent || p.State == CoinState.Unconfirmed).Sum(p => p.Value).ToString(); json["confirmed"] = coins.Where(p => p.State == CoinState.Unspent).Sum(p => p.Value).ToString(); return(json); } 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.Height + 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(); return(Blockchain.Default.GetBlockHash(height).ToString()); } case "getconnectioncount": return(localNode.RemoteNodeCount); 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(-101, "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.Height + 1; json["blocktime"] = header.Timestamp; } return(json); } else { return(tx.ToArray().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 "sendrawtransaction": { Transaction tx = Transaction.DeserializeFrom(_params[0].AsString().HexToBytes()); return(localNode.Relay(tx)); } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt256 assetId = UInt256.Parse(_params[0].AsString()); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); Fixed8 value = Fixed8.Parse(_params[2].AsString()); Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (value <= Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } ContractTransaction tx = Program.Wallet.MakeTransaction(new ContractTransaction { Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } } }, fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } SignatureContext context = new SignatureContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.SaveTransaction(tx); localNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "submitblock": { Block block = _params[0].AsString().HexToBytes().AsSerializable <Block>(); return(localNode.Relay(block)); } default: throw new RpcException(-32601, "Method not found"); } }
private JObject InternalCall(string method, JArray _params) { switch (method) { 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) { return(block.ToJson()); } else { return(block.ToArray().ToHexString()); } } case "getblockcount": return(Blockchain.Default.Height + 1); case "getblockhash": { uint height = (uint)_params[0].AsNumber(); return(Blockchain.Default.GetBlockHash(height).ToString()); } case "getconnectioncount": return(localNode.RemoteNodeCount); 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); Transaction tx = LocalNode.GetTransaction(hash); if (tx == null) { tx = Blockchain.Default.GetTransaction(hash); } if (tx == null) { throw new RpcException(-101, "Unknown transaction"); } if (verbose) { return(tx.ToJson()); } else { return(tx.ToArray().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 "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)); } default: throw new RpcException(-32601, "Method not found"); } }