From f1dedc6c65e72a5c85d15c07b91f8e7ddac86ff0 Mon Sep 17 00:00:00 2001 From: Erik van den Brink Date: Wed, 16 Jan 2019 11:17:16 +0100 Subject: [PATCH 1/4] Updated changelog for release --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5f0c61bcf..9e96d0a3c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,7 +3,7 @@ Changelog All notable changes to this project are documented in this file. -[0.8.3-dev] in progress +[0.8.3] 2019-01-16 ----------------------- - Update ``getassetstate`` RPC method to support `neo` and `gas` aliases; Cleanup ``show_contract_state`` `#667 `_ - Add fix to ensure tx is saved to wallet when sent using RPC `#680 `_ From 82aa12e942a972855a1d216332c602582cccfe38 Mon Sep 17 00:00:00 2001 From: Erik van den Brink Date: Thu, 28 Feb 2019 16:54:55 +0100 Subject: [PATCH 2/4] fix sys_fee calculation in leveldb Persist --- neo/Core/State/StateDescriptor.py | 6 +++--- neo/Core/TX/StateTransaction.py | 9 --------- .../Blockchains/LevelDB/LevelDBBlockchain.py | 8 ++++---- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/neo/Core/State/StateDescriptor.py b/neo/Core/State/StateDescriptor.py index 704026eb5..7dc68d8c2 100644 --- a/neo/Core/State/StateDescriptor.py +++ b/neo/Core/State/StateDescriptor.py @@ -22,10 +22,10 @@ class StateDescriptor(SerializableMixin): @property def SystemFee(self): - if self.Type == StateType.Account: - return Fixed8.Zero() - elif self.Type == StateType.Validator: + if self.Type == StateType.Validator: return self.GetSystemFee_Validator() + else: + return Fixed8.Zero() def Size(self): """ diff --git a/neo/Core/TX/StateTransaction.py b/neo/Core/TX/StateTransaction.py index 392c49184..7d1036b5d 100644 --- a/neo/Core/TX/StateTransaction.py +++ b/neo/Core/TX/StateTransaction.py @@ -28,15 +28,6 @@ def __init__(self, *args, **kwargs): self.Type = TransactionType.StateTransaction - def NetworkFee(self): - """ - Get the network fee for a claim transaction. - - Returns: - Fixed8: currently fixed to 0. - """ - return Fixed8(0) - def SystemFee(self): amount = Fixed8.Zero() for d in self.Descriptors: diff --git a/neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.py b/neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.py index e87ce2779..402ff3b3d 100644 --- a/neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.py +++ b/neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.py @@ -1,5 +1,6 @@ import plyvel import binascii +import struct from neo.Core.Blockchain import Blockchain from neo.Core.Header import Header from neo.Core.Block import Block @@ -511,7 +512,7 @@ def GetSysFeeAmount(self, hash): hash = hash.ToBytes() try: value = self._db.get(DBPrefix.DATA_Block + hash)[0:8] - amount = int.from_bytes(value, 'little', signed=False) + amount = struct.unpack(" Date: Thu, 28 Feb 2019 16:57:50 +0100 Subject: [PATCH 3/4] Update testcases, fixtures and changelog --- CHANGELOG.rst | 1 + .../LevelDB/TestLevelDBBlockchain.py | 5 +++-- .../LevelDB/test_LevelDBBlockchain.py | 2 +- .../Blockchains/LevelDB/tests/test_leveldb.py | 2 +- .../Wallets/peewee/test_user_wallet.py | 2 +- .../Commands/tests/test_claim_command.py | 6 +++--- .../Commands/tests/test_send_commands.py | 7 +++++-- .../tests/test_smart_contract.py | 2 +- neo/Utils/BlockchainFixtureTestCase.py | 8 ++++---- neo/Utils/fixtures/neo-test1-w.wallet | Bin 110592 -> 110592 bytes neo/Utils/fixtures/neo-test2-w.wallet | Bin 86016 -> 86016 bytes neo/Utils/fixtures/neo-test3-w.wallet | Bin 86016 -> 86016 bytes neo/api/JSONRPC/test_json_rpc_api.py | 4 ++-- 13 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c6428b2ff..b2d6f0a2e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,7 @@ All notable changes to this project are documented in this file. [0.8.5-dev] in progress ----------------------- - Change class attributes of ``Transaction`` into instance attributes and fix constructor +- Fix sys_fee calculation in block persist. [0.8.4] 2019-02-14 diff --git a/neo/Implementations/Blockchains/LevelDB/TestLevelDBBlockchain.py b/neo/Implementations/Blockchains/LevelDB/TestLevelDBBlockchain.py index b147c0a00..467e422d6 100644 --- a/neo/Implementations/Blockchains/LevelDB/TestLevelDBBlockchain.py +++ b/neo/Implementations/Blockchains/LevelDB/TestLevelDBBlockchain.py @@ -19,6 +19,7 @@ from neo.SmartContract.StateMachine import StateMachine from neo.SmartContract.ApplicationEngine import ApplicationEngine from neo.SmartContract import TriggerType +import struct class TestLevelDBBlockchain(LevelDBBlockchain): @@ -33,8 +34,8 @@ def Persist(self, block): contracts = DBCollection(self._db, DBPrefix.ST_Contract, ContractState) storages = DBCollection(self._db, DBPrefix.ST_Storage, StorageItem) - amount_sysfee = self.GetSysFeeAmount(block.PrevHash) + block.TotalFees().value - amount_sysfee_bytes = amount_sysfee.to_bytes(8, 'little') + amount_sysfee = self.GetSysFeeAmount(block.PrevHash) + (block.TotalFees().value / Fixed8.D) + amount_sysfee_bytes = struct.pack("MV$FDYW5N=DA!fb;2L4%m1^njx=De$T?(*E-EGTf2 zXY&1+^XfhvJ}f4joQ2QJ*cSO6m=|PfXLWafoz@!(`x%W~e8&o>-#?!$eQo+=i#SE5 zBEQK8;zYIit}-M;wP~&V#lgC6hPIGb#aa_@?sQu&`HQO;Wi#>0v&%kkp0Wd^jk!qe z!{mc;B9jZ^GSz)J!Pc$(?%J`V_0r7=G0fVF0=9K%YlX(8Xza`0A{TJmtx7xxs82ys zbEi6k%*g{W@BcqLdwpY5W7fo=H;Tz@iJX)9;}R#&icc5i|HQz||CWLO5C3=mw?O!U z{~rIn&4LD}`NfogK>z_<>@3WjjGRCYE63*V`BnCeuA7V2&kSIe;QzgyuYmC_KMPP! zZ2NzHMn;E84_LOd6fph)i%D%~2>>#;H829@#Fr&73V<*V)Lcd&ExDa1fbk1I03yqM Aq5uE@ delta 210 zcmZp8z}E19ZGtrCVg?2VX&{!GsAA2ycw@p6e<2n=UIzYId8SZWa_c z$us$W%=w86kBccj6{4Ox!#-{)#`N!{(y(eG35Ra}JFF diff --git a/neo/Utils/fixtures/neo-test3-w.wallet b/neo/Utils/fixtures/neo-test3-w.wallet index 6c24176ebaee2f9d9bc7c6ee1e895eeed532f6cd..e590de972b2e67775568b91ca83444dfe16a525d 100644 GIT binary patch delta 26 icmZozz}m2Yb%HeGs);hrjH@;#2(D*z-CVT3Zvg;-{0db7 delta 26 icmZozz}m2Yb%HeG{E0HojPo}p2(D+e-(0l5Zvg;+nF=`o diff --git a/neo/api/JSONRPC/test_json_rpc_api.py b/neo/api/JSONRPC/test_json_rpc_api.py index 8f06387fd..c15c19463 100644 --- a/neo/api/JSONRPC/test_json_rpc_api.py +++ b/neo/api/JSONRPC/test_json_rpc_api.py @@ -273,7 +273,7 @@ def test_get_bestblockhash(self): req = self._gen_post_rpc_req("getbestblockhash", params=[]) mock_req = mock_post_request(json.dumps(req).encode("utf-8")) res = json.loads(self.app.home(mock_req)) - self.assertEqual(res['result'], '0x62539bdf30ff2567355efb38b1911cc07258710cfab5b50d3e32751618969bcb') + self.assertEqual(res['result'], '0x0c9f39eddd425aba7c27543a90768093a90c76a35090ef9b413027927e887811') def test_get_connectioncount(self): # make sure we have a predictable state @@ -752,7 +752,7 @@ def test_valid_multirequest(self): self.assertEqual(type(res), list) self.assertEqual(len(res), 2) - expected_raw_block = '00000000999086db552ba8f84734bddca55b25a8d3d8c5f866f941209169c38d35376e9902c78a8ae8efe7e9d46f76399a9d9449155e861d6849c110ea5f6b7d146a9a8aa4d1305b01000000bd7d9349807816a1be48d3a3f5d10013ab9ffee489706078714f1ea201c340dcbeadb300ff983f40f537ba6d63721cafda183b2cd161801ffb0f8316f100b63dbfbae665bba75fa1a954f14351f91cbf07bf90e60ff79f3e9076bcb1b512184075c25a44184ce92f7d7af1d2f22bee69374dd1bf0327f8956ede0dc23dda90106cf555fb8202fe6db9acda1d0b4fff8fdcd0404daa4b359c73017c7cdb80094640fb383c7016aae89a0a01b3c431a5625340378b95b57f4b71c4427ff1177a786b11b1c8060c075e3234afdd03790764ccd99680ea102890e359ab9050b5b32b2b8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae010000bd7d934900000000' + expected_raw_block = '00000000999086db552ba8f84734bddca55b25a8d3d8c5f866f941209169c38d35376e9902c78a8ae8efe7e9d46f76399a9d9449155e861d6849c110ea5f6b7d146a9a8aa4d1305b01000000bd7d9349807816a1be48d3a3f5d10013ab9ffee489706078714f1ea201c340dcbeadb300ff983f40f537ba6d63721cafda183b2cd161801ffb0f8316f100b63dbfbae665bba75fa1a954f14351f91cbf07bf90e60ff79f3e9076bcb1b5121840665a065b967ac0bddddd1ed1b9a7c02c7c434e804e6e77d019778b74d6642423401e35dd9d8195d6896322e7ed6922c1eb8b086391b884a6acda2c34b70927f84075c25a44184ce92f7d7af1d2f22bee69374dd1bf0327f8956ede0dc23dda90106cf555fb8202fe6db9acda1d0b4fff8fdcd0404daa4b359c73017c7cdb8009468b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae010000bd7d934900000000' self.assertEqual(res[0]['result'], expected_raw_block) expected_verbose_hash = '0x55f745c9098d5d5bdaff9f8f32aad29c904c83d9832b48c16e677d30c7da4273' self.assertEqual(res[1]['result']['hash'], expected_verbose_hash) From 6f0d0a422080a3cd8fa36accbc9cdac173f2f4ba Mon Sep 17 00:00:00 2001 From: Erik van den Brink Date: Thu, 16 May 2019 12:53:38 +0200 Subject: [PATCH 4/4] fix test + linting --- neo/Core/TX/Transaction.py | 10 ++++----- neo/Core/TX/test_transactions.py | 13 +++++++++-- neo/Prompt/Commands/WalletAddress.py | 4 ++-- neo/Prompt/test_utils.py | 32 ++++------------------------ 4 files changed, 22 insertions(+), 37 deletions(-) diff --git a/neo/Core/TX/Transaction.py b/neo/Core/TX/Transaction.py index f93c26de5..c837d7605 100644 --- a/neo/Core/TX/Transaction.py +++ b/neo/Core/TX/Transaction.py @@ -245,7 +245,7 @@ def __init__(self, inputs=None, outputs=None, attributes=None, scripts=None): self.Attributes = [] if attributes is None else attributes self.scripts = [] if scripts is None else scripts self.InventoryType = 0x01 # InventoryType TX 0x01 - self.__references = None + self._references = None self.Type = None self.raw_tx = False self.withdraw_hold = None @@ -297,7 +297,7 @@ def getAllInputs(self): def ResetReferences(self): """Reset local stored references.""" - self.__references = None + self._references = None def ResetHashData(self): """Reset local stored hash data.""" @@ -323,7 +323,7 @@ def References(self): Key (UInt256): input PrevHash Value (TransactionOutput): object. """ - if self.__references is None: + if self._references is None: refs = {} @@ -335,9 +335,9 @@ def References(self): for input in group: refs[input] = tx.outputs[input.PrevIndex] - self.__references = refs + self._references = refs - return self.__references + return self._references def Size(self): """ diff --git a/neo/Core/TX/test_transactions.py b/neo/Core/TX/test_transactions.py index c8ce5b208..af9072ec9 100644 --- a/neo/Core/TX/test_transactions.py +++ b/neo/Core/TX/test_transactions.py @@ -183,7 +183,7 @@ def test_issue_tx(self): self.assertEqual(json['sys_fee'], "0") self.assertEqual(json['net_fee'], "0") self.assertEqual(json['scripts'][0]['invocation'], "") - self.assertEqual(json['scripts'][0]['verification'], "51") + self.assertEqual(json['scripts'][0]['verification'], "51") cr = b'800001f012e99481e4bb93e59088e7baa6e6b58be8af9502f8e0bc69b6af579e69a56d3d3d559759cdb848cb55b54531afc6e3322c85badf08002c82c09c5b49d10cd776c8679789ba98d0b0236f0db4dc67695a1eb920a646b9000001cd5e195b9235a31b7423af5e6937a660f7e7e62524710110b847bab41721090c0061c2540cd1220067f97110a66136d38badc7b9f88eab013027ce490241400bd2e921cee90c8de1a192e61e33eb8980a3dc00c388ee9aac0712178cc8fceed8bb59788f7caf3c4dc082abcdaaa49772fda86db4ceea243bda31bcde9b8a0b3c21034b44ed9c8a88fb2497b6b57206cc08edd42c5614bd1fee790e5b795dee0f4e1104182f145967cc4ee2f1c9f4e0782756dabf246d0a4fe60a035441402fe3e20c303e26c3817fed6fc7db8edde4ac62b16eee796c01c2b59e382b7ddfc82f0b36c7f7520821c7b72b9aff50ae27a016961f1ef1dade9cafa85655380f2321034b44ed9c8a88fb2497b6b57206cc08edd42c5614bd1fee790e5b795dee0f4e11ac' cr2 = b'800001f012e99481e4bb93e59088e7baa6e6b58be8af9502f8e0bc69b6af579e69a56d3d3d559759cdb848cb55b54531afc6e3322c85badf08002c82c09c5b49d10cd776c8679789ba98d0b0236f0db4dc67695a1eb920a646b9000001cd5e195b9235a31b7423af5e6937a660f7e7e62524710110b847bab41721090c0061c2540cd1220067f97110a66136d38badc7b9f88eab013027ce49' @@ -275,10 +275,19 @@ def test_state_tx(self): reader = BinaryReader(ms) tx = Transaction.DeserializeFrom(reader) + + # the net_fee calculation in short is : net_fee = inputs - outputs -system fee. + # For this test to be able to grab the input values we need to make the TX that it references available for this test + ms2 = MemoryStream(binascii.unhexlify( + b'80000001def3ab1c73a13e80fea34ca751c79fe8dcf68d93d91d4956818baf0b99d95818010002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6000e8764817000000faaa0f339e0fb33f91697cbf5aac41d17921222ae72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60008997b2270000002d9a070d388aa24d9f639bc8ddf985dc473c75d70141401a07d186fdfe3f9862c873d7cd9bdcb9cc8b3f5edcf853af31addcc4476d7d4fe89385cc955a4f604c667110332c14cb2fd8f62a29569b01a572774c7f7136572321026aeca2aed2094e9622a44cf584c694554f10cdb84d4f8eeab3e28ead4e87c168ac')) + reader2 = BinaryReader(ms2) + vout_tx = Transaction.DeserializeFrom(reader2) + self.assertEqual(tx.ToArray(), self.sttx) self.assertEqual(tx.Hash.ToBytes(), self.sttx_id) - json = tx.ToJson() + with patch('neo.Core.Blockchain.Blockchain.GetTransaction', return_value=(vout_tx, 0)): + json = tx.ToJson() self.assertEqual(json['size'], 191) self.assertEqual(json['type'], "StateTransaction") self.assertEqual(json['version'], 0) diff --git a/neo/Prompt/Commands/WalletAddress.py b/neo/Prompt/Commands/WalletAddress.py index 099a042fc..459e7a0f5 100644 --- a/neo/Prompt/Commands/WalletAddress.py +++ b/neo/Prompt/Commands/WalletAddress.py @@ -268,8 +268,8 @@ def SplitUnspentCoin(wallet, asset_id, from_addr, index, divisions, fee=Fixed8.Z try: passwd = prompt("[Password]> ", is_password=True) except KeyboardInterrupt: - print("Splitting cancelled") - return + print("Splitting cancelled") + return if not wallet.ValidatePassword(passwd): print("incorrect password") return diff --git a/neo/Prompt/test_utils.py b/neo/Prompt/test_utils.py index 9c5d607d8..9241c8817 100644 --- a/neo/Prompt/test_utils.py +++ b/neo/Prompt/test_utils.py @@ -16,7 +16,6 @@ class TestInputParser(TestCase): def test_utils_1(self): - args = [1, 2, 3] args, neo, gas = Utils.get_asset_attachments(args) @@ -26,7 +25,6 @@ def test_utils_1(self): self.assertIsNone(gas) def test_utils_2(self): - args = [] args, neo, gas = Utils.get_asset_attachments(args) @@ -36,14 +34,12 @@ def test_utils_2(self): self.assertIsNone(gas) def test_utils_3(self): - args = None with self.assertRaises(Exception): Utils.get_asset_attachments(args) def test_utils_4(self): - args = [1, 2, '--attach-neo=100'] args, neo, gas = Utils.get_asset_attachments(args) @@ -115,7 +111,6 @@ def test_owner_3(self): self.assertIsInstance(list(owners)[0], UInt160) def test_owner_and_assets(self): - args = [1, 2, "--owners=['APRgMZHZubii29UXF9uFa6sohrsYupNAvx','AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK',]", '--attach-neo=10'] args, owners = Utils.get_owners_from_params(args) @@ -130,7 +125,6 @@ def test_owner_and_assets(self): self.assertEqual(neo, Fixed8.FromDecimal(10)) def test_string_from_fixed8(self): - amount_str = Utils.string_from_fixed8(100234, 8) self.assertEqual(amount_str, '0.00100234') @@ -144,7 +138,6 @@ def test_string_from_fixed8(self): self.assertEqual(amount_str, '5343534002.34') def test_parse_no_address(self): - params = ['a', 'b', 'c'] params, result = Utils.get_parse_addresses(params) @@ -160,77 +153,64 @@ def test_parse_no_address(self): self.assertFalse(result) def test_gather_param(self): - with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value='hello') as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.String) self.assertEqual(result, 'hello') with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value=1) as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Integer) self.assertEqual(result, 1) with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value='1') as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Integer) self.assertEqual(result, 1) with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value=1.03) as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Integer) self.assertEqual(result, 1) with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value="bytearray(b'abc')") as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.ByteArray) self.assertEqual(result, bytearray(b'abc')) with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value="b'abc'") as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.ByteArray) self.assertEqual(result, bytearray(b'abc')) with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value="abc") as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Boolean) self.assertEqual(result, True) with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value=0) as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Boolean) self.assertEqual(result, False) # test ContractParameterType.ByteArray for address input with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value='AeV59NyZtgj5AMQ7vY6yhr2MRvcfFeLWSb') as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.ByteArray) self.assertEqual(result, bytearray(b'\xf9\x1dkp\x85\xdb|Z\xaf\t\xf1\x9e\xee\xc1\xca<\r\xb2\xc6\xec')) with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value='["a","b","c"]') as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Array) self.assertEqual(result, ['a', 'b', 'c']) with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value='["a","b","c", [1, 3, 4], "e"]') as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Array) self.assertEqual(result, ['a', 'b', 'c', [1, 3, 4], 'e']) # test ContractParameterType.Array without a closed list with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value='["a","b","c", [1, 3, 4], "e"') as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Array, do_continue=False) self.assertEqual(result, None) @@ -238,16 +218,14 @@ def test_gather_param(self): # test ContractParameterType.Array with no list with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value="b'abc'") as fake_prompt: + result, abort = Utils.gather_param(0, ContractParameterType.Array, do_continue=False) - result, abort = Utils.gather_param(0, ContractParameterType.Array, do_continue=False) - - self.assertRaises(Exception, "Please provide a list") - self.assertEqual(result, None) - self.assertEqual(abort, True) + self.assertRaises(Exception, "Please provide a list") + self.assertEqual(result, None) + self.assertEqual(abort, True) # test ContractParameterType.PublicKey with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value="03cbb45da6072c14761c9da545749d9cfd863f860c351066d16df480602a2024c6") as fake_prompt: - test_wallet_path = shutil.copyfile( WalletFixtureTestCase.wallet_1_path(), WalletFixtureTestCase.wallet_1_dest() @@ -272,14 +250,12 @@ def test_gather_param(self): # test ContractParameterType.PublicKey with bad public key with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value="blah") as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.PublicKey) self.assertIsNone(result) self.assertTrue(abort) # test unknown ContractParameterType with mock.patch('neo.Prompt.Utils.get_input_prompt', return_value="9698b1cac6ce9cbe8517e490778525b929e01903") as fake_prompt: - result, abort = Utils.gather_param(0, ContractParameterType.Hash160, do_continue=False) self.assertRaises(Exception, "Unknown param type Hash160")