Skip to content
This repository has been archived by the owner on Nov 15, 2021. It is now read-only.

Commit

Permalink
Implementing a few methods
Browse files Browse the repository at this point in the history
  • Loading branch information
localhuman committed Jan 23, 2018
1 parent f64416e commit acfdbb4
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 5 deletions.
1 change: 1 addition & 0 deletions neo/Core/State/AccountState.py
Expand Up @@ -8,6 +8,7 @@


class AccountState(StateBase):

ScriptHash = None
IsFrozen = False
Votes = []
Expand Down
10 changes: 9 additions & 1 deletion neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.py
Expand Up @@ -512,7 +512,7 @@ def GetBlock(self, height_or_hash):
except Exception as e:
pass

if len(height_or_hash) == 64:
if intval is None and len(height_or_hash) == 64:
bhash = height_or_hash.encode('utf-8')
if bhash in self._header_index:
hash = bhash
Expand All @@ -535,6 +535,14 @@ def GetBlockByHash(self, hash):
logger.info("Could not get block %s " % e)
return None

def GetNextBlockHash(self, hash):
header = self.GetHeader(hash.ToBytes())
if header:
if header.Index + 1 >= len(self._header_index):
return None
return self._header_index[header.Index + 1]
return None

def AddHeader(self, header):
self.AddHeaders([header])

Expand Down
97 changes: 95 additions & 2 deletions neo/api/JSONRPC/JsonRpcApi.py
Expand Up @@ -14,6 +14,13 @@
from logzero import logger
from neo.Core.Blockchain import Blockchain
from neo.api.utils import json_response
from neo.Core.State.AccountState import AccountState
from neo.Core.State.ContractState import ContractState
from neocore.UInt160 import UInt160
from neocore.UInt256 import UInt256
from neo.Wallets import Wallet
from neo.Core.Helper import Helper
from neo.Network.NodeLeader import NodeLeader


class JsonRpcError(Exception):
Expand Down Expand Up @@ -110,13 +117,99 @@ def get_custom_error_payload(self, request_id, code, message):

def json_rpc_method_handler(self, method, params):
# print("method", method, params)
if method == "getblockcount":
return Blockchain.Default().HeaderHeight

if method == "getaccountstate":
acct = Blockchain.Default().GetAccountState(params[0])
if acct is None:
acct = AccountState(script_hash=Helper.AddrStrToScriptHash(params[0]))
return acct.ToJson()

elif method == "getassetstate":
asset_id = params[0].encode('utf-8')
asset = Blockchain.Default().GetAssetState(asset_id)
if asset:
return asset.ToJson()
raise JsonRpcError(-100, "Unknown asset")

elif method == "getbestblockhash":
return Blockchain.Default().CurrentHeaderHash.decode('utf-8')

elif method == "getblock":
# this should work for either str or int
block = Blockchain.Default().GetBlock(params[0])
if not block:
raise JsonRpcError(-100, "Unknown block")

verbose = False
if len(params) >= 2 and params[1]:
verbose = True

if verbose:
jsn = block.ToJson()
jsn['confirmations'] = Blockchain.Default().Height - block.Index + 1
hash = Blockchain.Default().GetNextBlockHash(block.Hash)
if hash:
jsn['nextblockhash'] = hash.decode('utf-8')
return jsn

# full tx data is not included by default
# this will load them to be serialized
block.Transactions = block.FullTransactions
return Helper.ToArray(block).decode('utf-8')

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 JsonRpcError(-100, "Invalid Height")

elif method == "getblocksysfee":
raise NotImplementedError()

elif method == "getconnectioncount":
return len(NodeLeader.Instance().Peers)

elif method == "getcontractstate":
raise NotImplementedError()

elif method == "getrawmempool":
raise NotImplementedError()

elif method == "getrawtransaction":
raise NotImplementedError()

elif method == "getstorage":
raise NotImplementedError()

elif method == "gettxout":
raise NotImplementedError()

elif method == "invoke":
raise NotImplementedError()

elif method == "invokefunction":
raise NotImplementedError()

elif method == "invokescript":
raise NotImplementedError()

elif method == "sendrawtransaction":
raise NotImplementedError()

elif method == "submitblock":
raise NotImplementedError()

elif method == "validateaddress":
raise NotImplementedError()

elif method == "getpeers":
raise NotImplementedError()

elif method == "getversion":
raise NotImplementedError()

raise JsonRpcError.methodNotFound()
78 changes: 76 additions & 2 deletions neo/api/JSONRPC/test_json_rpc_api.py
Expand Up @@ -5,6 +5,8 @@
from klein.test.test_resource import requestMock
from neo.api.JSONRPC.JsonRpcApi import JsonRpcApi
from neo.Utils.BlockchainFixtureTestCase import BlockchainFixtureTestCase
from neo.IO.Helper import Helper
import binascii


def mock_request(body):
Expand Down Expand Up @@ -87,6 +89,78 @@ def test_getblockhash_failure(self):
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertEqual(-100, res["error"]["code"])
self.assertEqual("Invalid Height", res["error"]["message"])

# TODO: fix this later
# self.assertEqual("Invalid Height", res["error"]["message"])
def test_account_state(self):
addr_str = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'
req = self._gen_rpc_req("getaccountstate", params=[addr_str])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertEqual(res['result']['balances']['c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b'], '4061.0')
self.assertEqual(res['result']['script_hash'], addr_str)

def test_account_state_not_existing_yet(self):
addr_str = 'AHozf8x8GmyLnNv8ikQcPKgRHQTbFi46u2'
req = self._gen_rpc_req("getaccountstate", params=[addr_str])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertEqual(res['result']['balances'], {})
self.assertEqual(res['result']['script_hash'], addr_str)

def test_get_asset_state(self):
asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
req = self._gen_rpc_req("getassetstate", params=[asset_str])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertEqual(res['result']['assetId'], asset_str)
self.assertEqual(res['result']['admin'], 'AWKECj9RD8rS8RPcpCgYVjk1DeYyHwxZm3')
self.assertEqual(res['result']['available'], 3825482025899)

def test_bad_asset_state(self):
asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282dee'
req = self._gen_rpc_req("getassetstate", params=[asset_str])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertTrue('error' in res)
self.assertEqual(res['error']['message'], 'Unknown asset')

def test_get_bestblockhash(self):
req = self._gen_rpc_req("getbestblockhash", params=[])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertEqual(res['result'], '370007195c10a05e355b606f8f8867239f026a925f2ddc46940f62c9136d3ff5')

def test_get_connectioncount(self):
# @TODO
# Not sure if there's a great way to test this as it will always return 0 in tests
req = self._gen_rpc_req("getconnectioncount", params=[])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertEqual(res['result'], 0)

def test_get_block_int(self):
req = self._gen_rpc_req("getblock", params=[10, 1])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertEqual(res['result']['index'], 10)
self.assertEqual(res['result']['hash'], '9410bd44beb7d6febc9278b028158af2781fcfb40cf2c6067b3525d24eff19f6')
self.assertEqual(res['result']['confirmations'], 756610)
self.assertEqual(res['result']['nextblockhash'], 'a0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf')

def test_get_block_hash(self):
req = self._gen_rpc_req("getblock", params=['a0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertEqual(res['result']['index'], 11)
self.assertEqual(res['result']['confirmations'], 756609)
self.assertEqual(res['result']['previousblockhash'], '9410bd44beb7d6febc9278b028158af2781fcfb40cf2c6067b3525d24eff19f6')

def test_block_non_verbose(self):
req = self._gen_rpc_req("getblock", params=[2003, 0])
mock_req = mock_request(json.dumps(req).encode("utf-8"))
res = json.loads(self.app.home(mock_req))
self.assertIsNotNone(res['result'])

# output = binascii.unhexlify( res['result'])
# @TODO
# The getblock non verbose method is not serializing the blocks correctly

0 comments on commit acfdbb4

Please sign in to comment.