def test_dunders(self): wc = contracts.WildcardContainer(data=['method1', 'method2']) wc2 = contracts.WildcardContainer(data=['method1', 'method2']) self.assertIn('method1', wc) self.assertIn('method2', wc) self.assertNotIn('method3', wc) self.assertEqual('method2', wc[1]) self.assertEqual(2, len(wc)) self.assertNotEqual(wc, object()) self.assertEqual(wc, wc2)
def test_to_json_with_trusts_safemethods_extra(self): # create a default manifest m = contracts.ContractManifest(types.UInt160.zero()) t1 = types.UInt160.from_string("01" * 20) t2 = types.UInt160.from_string("02" * 20) m.trusts = contracts.WildcardContainer(data=[t1, t2]) m.safe_methods = contracts.WildcardContainer(data=["safe1"]) m.extra = False json_out = m.to_json() self.assertIn("0x" + str(t1), json_out['trusts']) self.assertIn("0x" + str(t2), json_out['trusts']) self.assertIn("safe1", json_out['safemethods']) self.assertFalse(json_out['extra'])
def test_to_json(self): wc = contracts.WildcardContainer.create_wildcard() self.assertDictEqual({'wildcard': '*'}, wc.to_json()) wc = contracts.WildcardContainer(data=['method1', 'method2']) self.assertDictEqual({'wildcard': ['method1', 'method2']}, wc.to_json())
def test_is_allowed_invalid_method(self): # in the above tests we validated the 'group' and 'contract_hash' matching logic # now we validate 'method' matching mock_manifest = mock.MagicMock() mock_manifest.contract_hash = types.UInt160.zero() # setup an allowed permission for a contract with UInt160.zero hash for 2 methods cpd = contracts.ContractPermissionDescriptor( contract_hash=types.UInt160.zero()) cp = contracts.ContractPermission( contract=cpd, methods=contracts.WildcardContainer(data=['method1', 'method2'])) self.assertTrue(cp.is_allowed(mock_manifest, "method1")) self.assertTrue(cp.is_allowed(mock_manifest, "method2")) self.assertFalse(cp.is_allowed(mock_manifest, "method3"))
def test_is_allowed_invalid_method(self): # in the above tests we validated the 'group' and 'contract_hash' matching logic # now we validate 'method' matching dummy_contract_hash = types.UInt160.from_string("01" * 20) contract_state = contracts.ContractState(1, contracts.NEF(), contracts.ContractManifest(), 0, dummy_contract_hash) # setup an allowed permission for a contract with UInt160.zero hash for 2 methods cpd = contracts.ContractPermissionDescriptor( contract_hash=dummy_contract_hash) cp = contracts.ContractPermission( contract=cpd, methods=contracts.WildcardContainer(data=['method1', 'method2'])) self.assertTrue(cp.is_allowed(contract_state, "method1")) self.assertTrue(cp.is_allowed(contract_state, "method2")) self.assertFalse(cp.is_allowed(contract_state, "method3"))
def test_to_json_with_trusts_extra(self): # create a default manifest m = contracts.ContractManifest("test_contract") method1 = contracts.ContractMethodDescriptor( name="main_entry", offset=0, parameters=[], return_type=contracts.ContractParameterType.INTEGER, safe=True) m.abi.methods = [method1] t1 = types.UInt160.from_string("01" * 20) t2 = types.UInt160.from_string("02" * 20) m.trusts = contracts.WildcardContainer(data=[t1, t2]) m.extra = False json_out = m.to_json() self.assertIn("0x" + str(t1), json_out['trusts']) self.assertIn("0x" + str(t2), json_out['trusts']) self.assertFalse(json_out['extra'])
def test_wildcard(self): wc = contracts.WildcardContainer.create_wildcard() self.assertTrue(wc.is_wildcard) wc = contracts.WildcardContainer(['method1']) self.assertFalse(wc.is_wildcard)
def test_contract_call_exceptions(self): engine = test_engine(has_snapshot=True, default_script=False) engine.load_script(vm.Script(hello_world_nef.script)) # can't find contract with self.assertRaises(ValueError) as context: engine._contract_call_internal( types.UInt160.zero(), "valid_method", contracts.CallFlags.ALL, False, vm.ArrayStackItem(engine.reference_counter)) self.assertEqual("[System.Contract.Call] Can't find target contract", str(context.exception)) fake_contract_hash = types.UInt160(b'\x01' * 20) target_contract = contracts.ContractState(0, contract3_nef, contract3_manifest, 0, fake_contract_hash) engine.snapshot.contracts.put(target_contract) # modify the manifest of the current executing contract to only allow to call 1 specific method on other contracts new_current_manifest = deepcopy(hello_world_manifest) new_current_manifest.permissions = [ contracts.ContractPermission( contracts.ContractPermissionDescriptor( ), # allow to call any contract contracts.WildcardContainer( ['method_aaaa']) # allowing to call the listed method only ) ] fake_contract_hash2 = types.UInt160(b'\x02' * 20) new_current_contract = contracts.ContractState(1, hello_world_nef, new_current_manifest, 0, fake_contract_hash2) engine.snapshot.contracts.put(new_current_contract) with self.assertRaises(ValueError) as context: engine._contract_call_internal( target_contract.hash, "invalid_method", contracts.CallFlags.ALL, False, vm.ArrayStackItem(engine.reference_counter)) self.assertEqual( "[System.Contract.Call] Method 'invalid_method' with 0 arguments does not exist on target contract", str(context.exception)) # restore current contract to its original form and try to call a non-existing contract current_contract = contracts.ContractState(1, hello_world_nef, hello_world_manifest, 1, fake_contract_hash2) engine.snapshot.contracts.delete(new_current_contract.hash) engine.snapshot.contracts.put(current_contract) with self.assertRaises(ValueError) as context: engine._contract_call_internal( target_contract.hash, "invalid_method", contracts.CallFlags.ALL, False, vm.ArrayStackItem(engine.reference_counter)) self.assertEqual( "[System.Contract.Call] Method 'invalid_method' with 0 arguments does not exist on target contract", str(context.exception)) # call the target method with invalid number of arguments array = vm.ArrayStackItem(engine.reference_counter) array.append([vm.NullStackItem(), vm.NullStackItem()]) with self.assertRaises(ValueError) as context: engine._contract_call_internal(target_contract.hash, "test_func", contracts.CallFlags.ALL, False, array) self.assertEqual( "[System.Contract.Call] Method 'test_func' with 2 arguments does not exist on target contract", str(context.exception))
def test_contract_call_exceptions(self): engine = test_engine(has_snapshot=True, default_script=False) engine.load_script(vm.Script(hello_world_nef.script)) with self.assertRaises(ValueError) as context: contract_call_internal(engine, types.UInt160.zero(), "_invalid_method", vm.ArrayStackItem(engine.reference_counter), contracts.native.CallFlags) self.assertEqual( "[System.Contract.Call] Method not allowed to start with _", str(context.exception)) # can't find contract with self.assertRaises(ValueError) as context: contract_call_internal(engine, types.UInt160.zero(), "valid_method", vm.ArrayStackItem(engine.reference_counter), contracts.native.CallFlags) self.assertEqual("[System.Contract.Call] Can't find target contract", str(context.exception)) target_contract = storage.ContractState(contract3_nef.script, contract3_manifest) engine.snapshot.contracts.put(target_contract) # modify the manifest of the current executing contract to only allow to call 1 specific method on other contracts new_current_manifest = deepcopy(hello_world_manifest) new_current_manifest.permissions = [ contracts.ContractPermission( contracts.ContractPermissionDescriptor( ), # allow to call any contract contracts.WildcardContainer( ['method_aaaa']) # allowing to call the listed method only ) ] new_current_contract = storage.ContractState(hello_world_nef.script, new_current_manifest) engine.snapshot.contracts.put(new_current_contract) with self.assertRaises(ValueError) as context: contract_call_internal(engine, target_contract.script_hash(), "invalid_method", vm.ArrayStackItem(engine.reference_counter), contracts.native.CallFlags) self.assertEqual( "[System.Contract.Call] Not allowed to call target method 'invalid_method' according to manifest", str(context.exception)) # restore current contract to its original form and try to call a non-existing contract current_contract = storage.ContractState(hello_world_nef.script, hello_world_manifest) engine.snapshot.contracts.delete(new_current_contract.script_hash()) engine.snapshot.contracts.put(current_contract) with self.assertRaises(ValueError) as context: contract_call_internal(engine, target_contract.script_hash(), "invalid_method", vm.ArrayStackItem(engine.reference_counter), contracts.native.CallFlags) self.assertEqual( "[System.Contract.Call] requested target method 'invalid_method' does not exist on target contract", str(context.exception)) # call the target method with invalid number of arguments array = vm.ArrayStackItem(engine.reference_counter) array.append([vm.NullStackItem(), vm.NullStackItem()]) with self.assertRaises(ValueError) as context: contract_call_internal(engine, target_contract.script_hash(), "test_func", array, contracts.native.CallFlags) self.assertEqual( "[System.Contract.Call] Invalid number of contract arguments. Expected 0 actual 2", str(context.exception))