-
-
Save ixje/eb8e6fef5011d0232e6b44b7097da584 to your computer and use it in GitHub Desktop.
dry coded rpc server bodies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import binascii | |
from neo.Core.Blockchain import Blockchain | |
from neo.Wallets import Wallet | |
from neocore.UInt256 import UInt256 | |
from neo.Network.NodeLeader import NodeLeader | |
from neo.Core.State.StorageKey import StorageKey | |
from neo.VM.ScriptBuilder import ScriptBuilder | |
from neo.Core.TX.Transaction import Transaction | |
from neocore.IO.BinaryReader import BinaryReader | |
from neo.IO.MemoryStream import MemoryStream | |
from neo.IO.Helper import Helper as IOHelper | |
from neo.Settings import settings | |
class RpcException(Exception): | |
pass | |
def Process(method, params): | |
if method == "getaccountstate": | |
address = params[0] | |
# requires making ToScriptHash static in Wallet. That'' currently not the case, it is static in C# | |
script_hash = Wallet.ToScriptHash(address) | |
account = Blockchain.Default().GetAccountState(script_hash) | |
return account.ToJson() | |
elif method == "getassetstate": | |
asset_id = UInt256(data=params[0]) | |
asset = Blockchain.Default().GetAssetState(asset_id) | |
# return asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset"); | |
if not asset: | |
raise RpcException("-100 Unknown asset") | |
else: | |
return asset.ToJson() | |
elif method == "getbestblockhash": | |
return Blockchain.Default().CurrentBlockHash | |
elif method == "getblock": | |
block = Blockchain.Default().GetBlock(params[0]) | |
if block is None: | |
raise RpcException("-100 Unknown block") | |
verbose = False | |
if len(params) >= 2: | |
if isinstance(params[1], bool): | |
verbose = params[1] | |
if not verbose: | |
return block.ToArray().decode('utf-8') | |
else: | |
json_data = block.ToJson() | |
json_data["confirmations"] = Blockchain.Default().Height - block.Index + 1 | |
# TODO: GetNextBlockHash doesn'' exist | |
hash = Blockchain.Default().GetNextBlockHash(block.Hash) | |
if hash is not None: | |
json_data['nextblockhash'] = hash | |
return json_data | |
elif method == "getblockcount": | |
return Blockchain.Default().Height + 1 | |
elif method == "getblockhash": | |
height = params[0] | |
if height >= 0 and height <= Blockchain.Default().Height: | |
return Blockchain.Default().GetBlockHash(height).decode('utf-8') | |
else: | |
raise RpcException("-100 Invalid height") | |
elif method == "getconnectioncount": | |
nl = NodeLeader.Instance() | |
return len(nl.Peers) | |
elif method == "getcontractstate": | |
script_hash = params[0] | |
contract = Blockchain.Default().GetContract(script_hash) | |
if contract is None: | |
raise RpcException("-100 Unknown contract") | |
else: | |
return contract.ToJson() | |
elif method == "getrawmempool": | |
# return new JArray(LocalNode.GetMemoryPool().Select(p => (JObject)p.Hash.ToString())); | |
nl = NodeLeader.Instance() | |
return map(lambda hash: hash.decode('utf-8'), nl.MemPool.keys()) | |
elif method == "getrawtransaction": | |
hash = params[0] | |
verbose = False | |
if len(params) >= 2: | |
if isinstance(params[1], bool): | |
verbose = params[1] | |
height = -1 | |
tx = NodeLeader.Instance() # TODO: implement later. There's no NodeLeader.GetTransaction() equivalent. | |
# Check neo-project implementation if it only fetches from the MemPool or from the db | |
if tx is None: | |
tx, height = Blockchain.Default().GetTransaction(hash) | |
if tx is None: | |
raise RpcException("-100 Unknown transaction") | |
if not verbose: | |
return tx.ToArray().decode('utf-8') | |
else: | |
json_data = tx.ToJson() | |
if height >= 0: | |
header = Blockchain.Default().GetHeaderBy(height) | |
json_data["blockhash"] = header.Hash.ToString() | |
json_data["confirmations"] = Blockchain.Default().Height - header.Index + 1 | |
json_data["blocktime"] = header.Timestamp | |
elif method == "getstorage": | |
script_hash = params[0] | |
if len(params) < 2: # note this is not in the original RPC server,I assume they forgot this | |
raise RpcException("-100 Invalid key") | |
key = bytearray(params[1]) | |
storage_key = StorageKey(script_hash, key) | |
item = Blockchain.Default().GetStorageItem(storage_key) | |
# return item.Value?.ToHexString(); | |
# TODO: likely fix | |
return binascii.hexlify(item.Value) | |
elif method == "gettxout": | |
hash = params[0] | |
index = params[1] | |
# return Blockchain.Default.GetUnspent(hash, index)?.ToJson(index); | |
# TODO: check what does on here, as our GetUnspent is likely to return a single tx_output | |
# our TransactionOutput does not have an Index parameter. | |
tx_output = Blockchain.Default().GetUnspent(hash, index) | |
elif method == "invoke": | |
script_hash = params[0] | |
sb = ScriptBuilder() | |
# TODO: fix/implement | |
# script = sb.EmitAppCall(script_hash, parameters).ToArray(); | |
# return GetInvokeResult(script); | |
elif method == "invokescript": | |
# TODO: fix/implement | |
script = binascii.unhexlify(params[0]) | |
# return GetInvokeResult(script); | |
elif method == "sendrawtransaction": | |
ms = MemoryStream(binascii.unhexlify(params[0])) | |
reader = BinaryReader(ms) | |
tx = Transaction.DeserializeFrom(reader) | |
return NodeLeader.Instance().Relay(tx) | |
elif method == "submitblock": | |
raw_data = binascii.unhexlify(params[0]) | |
block = IOHelper.AsSerializableWithType(raw_data, 'neo.Core.Block.Block') | |
return NodeLeader.Instance().Relay(block) | |
elif method == "validateaddress": | |
# TODO check neo-project Wallet.ToScriptHash body what they validate on | |
''' | |
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; | |
''' | |
pass | |
elif method == "getpeers": | |
# TODO: | |
pass | |
elif method == "getversion": | |
return {'port': settings.NODE_PORT, | |
"useragent": settings.VERSION_NAME, | |
"nonce": 123 # TODO: check how LocalNode.Nonce is defined. our NodeLeader doesn't have a Nonce property. | |
} | |
else: | |
raise RpcException("-32601 Method not found") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment