def test_tx(self): self.set_tx(Address.from_string(f"hx{'1234' * 10}")) self.score2.t_tx() # On the upper line, set the tx property to pass the assert statement so that no exception is raised. self.set_tx(Address.from_string(f"hx{'12' * 20}")) self.assertRaises(AssertionError, self.score2.t_tx) # On the upper line, set the tx property not to pass the assert statement, and raise an exception.
def setUp(self): super().setUp() self.mock_score = Address.from_string(f"cx{'abcd' * 10}") self.dividends = self.get_score_instance(Dividends, self.test_account1) self.wallet_array = [KeyWallet.load(v) for v in TEST_ACCOUNTS] account_info = { Address.from_string(wallet.get_address()): 10**21 for wallet in self.wallet_array } self.initialize_accounts(account_info)
def setUp(self): super().setUp() self.mock_score_address = Address.from_string(f"cx{'1234' * 10}") self.score2 = self.get_score_instance( SimpleScore2, self.test_account1, on_install_params={'score_address': self.mock_score_address}) self.test_account3 = Address.from_string(f"hx{'12345' * 8}") self.test_account4 = Address.from_string(f"hx{'1234' * 10}") account_info = {self.test_account3: 10**21, self.test_account4: 10**21} self.initialize_accounts(account_info)
def test_default_parameters(self): tx1 = self._make_deploy_tx("test_scores", "test_db_returns_default_value", self._addr_array[0], ZERO_SCORE_ADDRESS, deploy_params={}) prev_block, tx_results = self._make_and_req_block([tx1]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(True)) score_addr1 = tx_results[0].score_address val1 = 3 val2 = "string" val3 = b'bytestring' val4 = Address.from_string(f"hx{'0'*40}") val5 = False val6 = Address.from_string(f"hx{'abcd1234'*5}") query_request = { "from": self._admin, "to": score_addr1, "dataType": "call", "data": { "method": "get_value1", "params": {} } } response = self._query(query_request) self.assertEqual(response, val1) query_request['data']['method'] = 'get_value2' response = self._query(query_request) self.assertEqual(response, val2) query_request['data']['method'] = 'get_value3' response = self._query(query_request) self.assertEqual(response, val3) query_request['data']['method'] = 'get_value4' response = self._query(query_request) self.assertEqual(response, val4) query_request['data']['method'] = 'get_value5' response = self._query(query_request) self.assertEqual(response, val5) query_request['data']['method'] = 'get_value6' response = self._query(query_request) self.assertEqual(response, val6)
def test_canTransferByPartition(self): self.set_msg(self.test_account1) self.score.issueByPartition( "default", self.test_account2, 1000, b'minting 1000 tokens to test_account2 in default partition') self.score.issueByPartition( "locked", self.test_account2, 1000, b'minting 1000 tokens to test_account2 in locked partition') self.score.issueByPartition( "reserved", self.test_account2, 1000, b'minting 1000 tokens to test_account2 in reserved partition') self.set_msg(self.test_account2) reason = self.score.canTransferByPartition("random", self.test_account2, self.test_account3, 1000, None) self.assertEqual(reason, "0x50 Invalid Partition") reason = self.score.canTransferByPartition("default", self.test_account2, self.test_account3, 1001, None) self.assertEqual(reason, "0x52 Insufficient Balance") reason = self.score.canTransferByPartition( "default", self.test_account2, Address.from_prefix_and_int(AddressPrefix.EOA, 0), 1000, None) self.assertEqual(reason, "0x57 Invalid Receiver") reason = self.score.canTransferByPartition("default", self.test_account2, self.test_account3, 1000, None) self.assertEqual(reason, "0x51 Transfer Successful")
def test_default_parameters(self): tx_results: List['TransactionResult'] = self.deploy_score( score_root="sample_scores", score_name="sample_db_returns_default_value", from_=self._accounts[0], deploy_params={}) score_address: 'Address' = tx_results[0].score_address val1 = 3 val2 = "string" val3 = b'bytestring' val4 = Address.from_string(f"hx{'0' * 40}") val5 = False val6 = Address.from_string(f"hx{'abcd1234' * 5}") query_request = { "from": self._admin, "to": score_address, "dataType": "call", "data": { "method": "get_value1", "params": {} } } response = self._query(query_request) self.assertEqual(response, val1) query_request['data']['method'] = 'get_value2' response = self._query(query_request) self.assertEqual(response, val2) query_request['data']['method'] = 'get_value3' response = self._query(query_request) self.assertEqual(response, val3) query_request['data']['method'] = 'get_value4' response = self._query(query_request) self.assertEqual(response, val4) query_request['data']['method'] = 'get_value5' response = self._query(query_request) self.assertEqual(response, val5) query_request['data']['method'] = 'get_value6' response = self._query(query_request) self.assertEqual(response, val6)
def __init__(self, serialized: bytes) -> None: self.__bytes = serialized self.__addresses = [] if serialized is not None: self.__hash = get_hash(serialized) unpacked = rlp.rlp_decode(self.__bytes, {list: bytes}) for b in unpacked: address = Address.from_bytes(b) self.__addresses.append(address)
def from_string(s: str) -> 'Validators': if not isinstance(s, str) or len(s) < 1: return None splitted = s.split(",") addresses = [] for a in splitted: try: addresses.append(Address.from_string(a).to_bytes()) except BaseException as e: if len(splitted) == 1: return Validators(base64.urlsafe_b64decode(s)) else: raise e b = rlp.rlp_encode(addresses) return Validators(b)
def convert_from_bytes(param_type: str, v: bytes): if param_type == "int": return rlp.from_bytes(v, int) elif param_type == "str": return rlp.from_bytes(v, str) elif param_type == "bool": return rlp.from_bytes(v, bool) elif param_type == "bytes": return v elif param_type == "Address": return Address.from_bytes(v) else: raise BMVException( f"{param_type} is not supported type (only int, str, bool, Address, bytes are supported)" )
def setUp(self): super().setUp() self.name = "IconHouseToken" self.symbol = "IHT" self.decimals = 18 self.initial_supply = 0 #self.controllable = 1 params = { 'name': self.name, 'symbol': self.symbol, 'decimals': self.decimals, 'initial_supply': self.initial_supply, # 'controllable': self.controllable, } self.score = self.get_score_instance(SampleIRC16, self.test_account1, params) self.set_msg(self.test_account1) # self.test_account1 = hxe48913df85da204d99ac22e0180e017c82a5dc9b # self.test_account2 = hx541441378726178b4bce6d411765ee0b51bd7a03 self.test_account3 = Address.from_string(f"hx{'12345'*8}") self.test_account4 = Address.from_string(f"hx{'1234'*10}") self.test_account5 = Address.from_string(f"hx{'4321'*10}")
def test_handleRelayMessage(self): # ================================================ # test_block_update # ================================================ block_updates = [] _block_header = Dummy.block_header(1, self._validators.hash) _votes = Dummy.votes(_block_header, self._validators_with_key) _next_validators = None block_update = rlp.rlp_encode([_block_header._bytes, _votes._bytes, _next_validators]) block_updates.append(block_update) block_proof = None receipt_proofs = [] _msgs = rlp.rlp_encode([block_updates, block_proof, receipt_proofs]) self.set_msg(Address.from_string(self._btp_bmc.contract)) btp_msgs = self.score.handleRelayMessage(str(self._btp_bmc), str(self._btp_bmc), 1, base64.urlsafe_b64encode(_msgs)) print(btp_msgs)
def _create_address_with_key(public_key: bytes): """Create an address with a given public key :param public_key: Public key based on secp256k1 :return: Address created from a given public key or None if failed """ # if isinstance(public_key, bytes): # size = len(public_key) # prefix: bytes = public_key[0] # # if size == 33 and prefix in (0x02, 0x03): # uncompressed_public_key: bytes = _convert_key(public_key) # elif size == 65 and prefix == 0x04: # uncompressed_public_key: bytes = public_key # else: # return None body: bytes = hashlib.sha3_256(public_key[1:]).digest()[-20:] return Address("0x", body)
def get(self, k): if k in self.__remove: return None elif k in self.__cache: return self.__cache[k] else: b = self.__db[k] if b is None: if k in self.__default: v = self.__default[k] if isinstance(v, type) and issubclass(v, Serializable): v = None else: v = None elif b[0] == PropertiesDB.Type.INT: v = int.from_bytes(b[1:], "big", signed=True) elif b[0] == PropertiesDB.Type.STR: v = b[1:].decode('utf-8') elif b[0] == PropertiesDB.Type.BOOL: v = True if b[1:] == b'\x01' else False elif b[0] == PropertiesDB.Type.BYTES: v = b[1:] elif b[0] == PropertiesDB.Type.ADDRESS: v = Address.from_bytes(b[1:]) elif b[0] == PropertiesDB.Type.BTPADDRESS: v = BTPAddress.from_bytes(b[1:]) elif b[0] == PropertiesDB.Type.SERIALIZABLE: v = self.__default[k] if isinstance(v, type): v = v.__new__(v) if isinstance(v, Serializable): v = v.from_bytes(b[1:]) else: raise PropertiesDB.TypeException( f"{type(v)} is not supported") else: raise PropertiesDB.TypeException( f"{b[0]} is not supported type") self.__cache[k] = v return v
def address_by_public_key(public_key: bytes) -> Address: try: return create_address_with_key(public_key) except Exception as e: _check_recoverable_error(e) log_warning("fail to create_address_with_key, try coincurve") assert isinstance(public_key, bytes) assert len(public_key) in (33, 65) size = len(public_key) prefix: int = public_key[0] if size == 33 and prefix in (0x02, 0x03): uncompressed_public_key: bytes = _convert_key(public_key, compressed=True) elif size == 65 and prefix == 0x04: uncompressed_public_key: bytes = public_key else: raise Exception("not supported public key length") body: bytes = hashlib.sha3_256( uncompressed_public_key[1:]).digest()[-20:] return Address(AddressPrefix.EOA, body)
def test_transfer_from_approved(self): # Mint an NFT token first via 'mint' params = {'_to': self._test1.get_address(), '_tokenId': 1} transaction = CallTransactionBuilder() \ .from_(self._test1.get_address()) \ .to(self._score_address) \ .step_limit(100_000_000) \ .method("mint") \ .params(params) \ .build() signed_transaction = SignedTransaction(transaction, self._test1) tx_result = self.process_transaction(signed_transaction, self.icon_service) self.assertTrue('status' in tx_result) self.assertEqual(1, tx_result['status']) # Approve token operation to new wallet via 'approve' params = {'_to': self._wallet_array[0].get_address(), '_tokenId': 1} transaction = CallTransactionBuilder() \ .from_(self._test1.get_address()) \ .to(self._score_address) \ .step_limit(100_000_000) \ .method("approve") \ .params(params) \ .build() signed_transaction = SignedTransaction(transaction, self._test1) tx_result = self.process_transaction(signed_transaction, self.icon_service) self.assertTrue('status' in tx_result) self.assertEqual(1, tx_result['status']) # Check approval of token 1 via 'getApproval' # owner of token 1 should be self._test1 # approvee of token 1 should be self._wallet_array[0] params = {"_tokenId": 1} call = CallBuilder().from_(self._test1.get_address()) \ .to(self._score_address) \ .method("getApproved") \ .params(params) \ .build() response = self.process_call(call, self.icon_service) self.assertEqual(response, self._wallet_array[0].get_address()) # Transfer ownership of token 1 from self._test1 to self._wallet_array[1] by its operator approvee self._wall_array[0] using 'transferFrom' params = { '_from': self._test1.get_address(), '_to': self._wallet_array[1].get_address(), '_tokenId': 1 } transaction = CallTransactionBuilder() \ .from_(self._test1.get_address()) \ .to(self._score_address) \ .step_limit(100_000_000) \ .method("transferFrom") \ .params(params) \ .build() signed_transaction = SignedTransaction(transaction, self._test1) tx_result = self.process_transaction(signed_transaction, self.icon_service) self.assertTrue('status' in tx_result) self.assertEqual(1, tx_result['status']) # Check new ownership of token 1, expected to be self._wallet_array[1] params = {"_tokenId": 1} call = CallBuilder().from_(self._test1.get_address()) \ .to(self._score_address) \ .method("ownerOf") \ .params(params) \ .build() response = self.process_call(call, self.icon_service) self.assertEqual(response, self._wallet_array[1].get_address()) # Check token 1's new approved operator, expected zero address params = {"_tokenId": 1} call = CallBuilder().from_(self._test1.get_address()) \ .to(self._score_address) \ .method("getApproved") \ .params(params) \ .build() response = self.process_call(call, self.icon_service) self.assertEqual( response, str(Address.from_prefix_and_int(AddressPrefix.EOA, 0))) # Check token count of self._test1, expected 0 params = {"_owner": self._test1.get_address()} call = CallBuilder().from_(self._test1.get_address()) \ .to(self._score_address) \ .method("balanceOf") \ .params(params) \ .build() response = self.process_call(call, self.icon_service) self.assertEqual(response, hex(0)) # Last we burn the token from the new owner self._wallet_array[1] params = { "_tokenId": 1, } transaction = CallTransactionBuilder() \ .from_(self._wallet_array[1].get_address()) \ .to(self._score_address) \ .step_limit(100_000_000) \ .method("burn") \ .params(params) \ .build() signed_transaction = SignedTransaction(transaction, self._wallet_array[1]) tx_result = self.process_transaction(signed_transaction, self.icon_service) self.assertTrue('status' in tx_result) self.assertEqual(1, tx_result['status']) # Check owner of token 1, expect invalid owner (zero address) params = {"_tokenId": 1} call = CallBuilder().from_(self._test1.get_address()) \ .to(self._score_address) \ .method("ownerOf") \ .params(params) \ .build() with self.assertRaises(IconScoreException) as e: self.process_call(call, self.icon_service) self.assertEqual(e.exception.code, 32) self.assertEqual(e.exception.message, "Invalid _tokenId. NFT is burned")
def setUp(self): super().setUp() self.test_admin_account = Address.from_string(f"hx{'1574' * 10}") self.test_account3 = Address.from_string(f"hx{'1238' * 10}") self.test_account4 = Address.from_string(f"hx{'1237' * 10}") self.test_account5 = Address.from_string(f"hx{'1236' * 10}") self.test_account6 = Address.from_string(f"hx{'2365' * 10}") self.test_account7 = Address.from_string(f"hx{'6964' * 10}") self.initialize_accounts({self.test_account1: 100000 * 10**18}) self.cps_score_address = Address.from_string(f"cx{'1234' * 10}") self.cps_treasury_score = Address.from_string(f"cx{'3456' * 10}") self.cpf_treasury_score = Address.from_string(f"cx{'5678' * 10}") self.bnUSD_score = Address.from_string(f"cx{'7890' * 10}") self.sICX_score = Address.from_string(f"cx{'1985' * 10}") self.dex_score = Address.from_string(f"cx{'2000' * 10}") self.staking_score = Address.from_string(f"cx{'2001' * 10}") self.initialize_accounts({self.cpf_treasury_score: 100000 * 10**18}) self.test_contract_1 = Address.from_string(f"cx{'6789' * 10}") self.set_msg(self.test_account1) self.set_tx(self.test_account1) self.cpf_score = self.get_score_instance( CPF_TREASURY, self.test_account1, on_install_params={}, score_address=self.cpf_treasury_score)
def __init__(self): self.test_account3 = Address.from_string(f"hx{'1238' * 10}")
# See the License for the specific language governing permissions and # limitations under the License. from iconservice import ZERO_SCORE_ADDRESS, Address from tests.integrate_test.test_integrate_base import TestIntegrateBase ONE = '1' ZERO = '0' EMPTY_STR = "" EMPTY_BYTE = bytes.hex(b"") NUM1 = 1 NUM0 = 0 INT_VAL = '0x14' STRING_VAL = 'string value' BYTE_VAL = bytes.hex(b'byte string') ADDRESS_VAL = str(Address.from_string(f"hx{'abcd1234' * 5}")) BOOL_VAL = hex(False) class TestIntegrateMethodParamters(TestIntegrateBase): def test_int_type_parameters_methods(self): tx1 = self._make_deploy_tx("test_scores", "test_db_returns", self._addr_array[0], ZERO_SCORE_ADDRESS, deploy_params={ "value": str(self._addr_array[1]), "value1": str(self._addr_array[1]) }) prev_block, tx_results = self._make_and_req_block([tx1])
def test_address_type_parameters_methods(self): tx1 = self._make_deploy_tx("test_scores", "test_db_returns", self._addr_array[0], ZERO_SCORE_ADDRESS, deploy_params={ "value": str(self._addr_array[1]), "value1": str(self._addr_array[1]) }) prev_block, tx_results = self._make_and_req_block([tx1]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(True)) score_addr1 = tx_results[0].score_address query_request = { "from": self._admin, "to": score_addr1, "dataType": "call", "data": { "method": "get_value4", "params": {} } } response = self._query(query_request) self.assertEqual(response, self._addr_array[1]) # original value: 0(int) # set value to '1' -> fail tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": ONE}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to '0' -> fail tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": ZERO}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to '' fail tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": EMPTY_STR}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to b'' fail tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": EMPTY_BYTE}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to None -> fail tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": None}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to 1 -> fail tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": NUM1}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to 0 -> fail tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": NUM0}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to '0x14' tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": INT_VAL}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to 'string value'' tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": STRING_VAL}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to b'byte value' tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": BYTE_VAL}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False)) # set value to address value tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": ADDRESS_VAL}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(True)) response = self._query(query_request) self.assertEqual(response, Address.from_string(ADDRESS_VAL)) # set value to False tx = self._make_score_call_tx(self._addr_array[0], score_addr1, 'set_value4', {"value": BOOL_VAL}, pre_validation_enabled=False) prev_block, tx_results = self._make_and_req_block([tx]) self._write_precommit_state(prev_block) self.assertEqual(tx_results[0].status, int(False))
def score_address() -> Address: return Address.from_data(AddressPrefix.CONTRACT, secrets.token_bytes(Dummy.ICON_ADDRESS_BODY_SIZE))
def address() -> Address: return Address.from_data(AddressPrefix.EOA, secrets.token_bytes(Dummy.ICON_ADDRESS_BODY_SIZE))
def raw_to_object(self, raw): return self.new_relayer(Address.from_string(raw))
class TestSmartWallet(TestCase): sender = Address(AddressPrefix(0), b"1" * 20) def setUp(self): self.key_value_mock = MockKeyValueDatabase({}) self.db = IconScoreDatabase(self.sender, ContextDatabase(self.key_value_mock)) IconScoreBase.get_owner = lambda score_object, score_address: self.sender self.smart_wallet = SmartWallet(self.db) type(self.smart_wallet).msg = PropertyMock( return_value=Message(sender=self.sender, value=10000)) # print test name print(f"===== {self._testMethodName} ==========================") def tearDown(self): print("=================================================") def test_add_account(self): """ GIVEN account to put WHEN on_install and call from the method `add_account` THEN _accounts have all of accounts (3) """ # GIVEN SmartWallet.Account = lambda _self, acccount: None # WHEN sample_account = { "id": 0, "tokenType": "test_token_type", "contractAddr": "test_contract_addr", "balance": "test_balance", "sendLimit": "test_send_limit", "totalUsed": "test_total_used", "lastUsedDate": "test_last_used_date", "dids": "test_dids" } str_sample_account = json.dumps(sample_account) self.smart_wallet.on_install(str_sample_account) self.smart_wallet.add_account(str_sample_account) self.smart_wallet.add_account(str_sample_account) # THEN assert len(self.smart_wallet._accounts) == 3 def test_change_setting_value(self): """ GIVEN the previous account WHEN the previous account is updated THEN the account change to the new one """ # GIVEN SmartWallet.Account = lambda _self, account: None sample_account = { "id": 0, "tokenType": "test_token_type", "contractAddr": "test_contract_addr", "balance": "test_balance", "sendLimit": "test_send_limit", "totalUsed": "test_total_used", "lastUsedDate": "test_last_used_date", "dids": "test_dids" } str_sample_account = json.dumps(sample_account) self.smart_wallet.on_install(str_sample_account) self.smart_wallet.add_account(str_sample_account) # WHEN sample_account["id"] = 1 sample_account["tokenType"] = "new" str_sample_account = json.dumps(sample_account) self.smart_wallet._change_setting_value(account=str_sample_account) json_sample_account = json.loads(self.smart_wallet._accounts[1]) # THEN self.assertEqual(json_sample_account["tokenType"], "new") @only_owner def _test_only_owner(self): pass def test_only_owner(self): self.msg = MagicMock(return_value=self.smart_wallet.owner) self.msg.sender = self.msg() self.owner = self.msg() self._test_only_owner() self.msg.sender = 123 self.assertRaises(AttributeError, self._test_only_owner)
class TestWalletManager(TestCase): sender = Address(AddressPrefix(0), b"1" * 20) def setUp(self): self.key_value_mock = MockKeyValueDatabase({}) self.db = IconScoreDatabase(self.sender, ContextDatabase(self.key_value_mock)) IconScoreBase.get_owner = lambda score_object, score_address: self.sender self.smart_wallet = SmartWallet(self.db) type(self.smart_wallet).msg = PropertyMock( return_value=Message(sender=self.sender, value=10000)) SmartWallet.Account = lambda _self, account: None self.smart_wallet.on_install( json.dumps({ "id": 0, "tokenType": "icx", "balance": 3000, "sendLimit": 1000, "totalUsed": 500, "lastUsedDate": "2018-11-21", "dids": [] })) # print test name print("=====================================================") print(f"{self._testMethodName}") def tearDown(self): print(f"end test") print("=====================================================") def test_transfer_direct_send(self): """GIVEN an account that has token icx and required did is nothing WHEN send icx lower than today used_limits THEN account update balance and limit and register event send_transaction """ # GIVEN self.__setup_no_did_transfer_env() def TransferSuccessMock(contract, account_id: int, token_type: str, token_address: str, to: str, amount: int): self.assertEqual(0, account_id) self.assertEqual("icx", token_type) self.assertEqual("", token_address) self.assertEqual("hx111111111111111111111111111111111111111111", to) self.assertEqual(500, amount) SmartWallet.TransferSuccess = TransferSuccessMock # WHEN self.smart_wallet.transfer( account_id=0, token_type="icx", contract_addr="", to="hx111111111111111111111111111111111111111111", amount=500) # THEN updated_account = json.loads(self.smart_wallet._accounts[0]) self.assertEqual(updated_account["totalUsed"], 1000) self.assertEqual(updated_account["balance"], 2500) def __setup_no_did_transfer_env(self): Icx.transfer = lambda contract, addr_to, amount: None self.smart_wallet._accounts = [ json.dumps({ "id": 0, "tokenType": "icx", "balance": 3000, "sendLimit": 1000, "totalUsed": 500, "lastUsedDate": "2018-11-21", "dids": [] }) ] type(self.smart_wallet).block = PropertyMock( return_value=Block(0, 1542773377)) def test_transfer_amount_is_higher_than_balance_must_raise_revert(self): # GIVEN self.__setup_no_did_transfer_env() # WHEN THEN self.assertRaises(RevertException, self.smart_wallet.transfer, account_id=0, token_type="icx", contract_addr="", to="hx111111111111111111111111111111111111111111", amount=3500) def test_transfer_amount_is_higher_than_left_today_limit_must_raise_revert( self): # GIVEN self.__setup_no_did_transfer_env() # WHEN THEN self.assertRaises(RevertException, self.smart_wallet.transfer, account_id=0, token_type="icx", contract_addr="", to="hx111111111111111111111111111111111111111111", amount=600) def test_transfer_amount_is_higher_than_left_today_limit_but_can_if_day_change( self): # GIVEN self.__setup_no_did_transfer_env() # setup last date is 11_21 ts_11_23 = 1542993377 type(self.smart_wallet).block = PropertyMock( return_value=Block(0, ts_11_23)) # THEN def TransferSuccessMock(contract, account_id: int, token_type: str, token_address: str, to: str, amount: int): self.assertEqual(0, account_id) self.assertEqual("icx", token_type) self.assertEqual("", token_address) self.assertEqual("hx111111111111111111111111111111111111111111", to) self.assertEqual(600, amount) SmartWallet.TransferSuccess = TransferSuccessMock # WHEN self.smart_wallet.transfer( account_id=0, token_type="icx", contract_addr="", to="hx111111111111111111111111111111111111111111", amount=600) # THEN account = json.loads(self.smart_wallet._accounts[0]) self.assertEqual(2400, account["balance"]) self.assertEqual(600, account["totalUsed"]) self.assertEqual("2018-11-23", account["lastUsedDate"]) def test_pending_transaction(self): """ GIVEN account with did_list not empty WHEN call transfer with transferable info THEN a transaction will be pending """ # GIVEN self.__setup_processing_pending_tx() # THEN def PendingMock(_self, pending_tx: str): print(pending_tx) pending_tx_as_dict = json.loads(pending_tx) self.assertEqual(1, pending_tx_as_dict["id"]) self.assertEqual(0, pending_tx_as_dict["from"]) self.assertEqual("hx" + "1" * 40, pending_tx_as_dict["to"]) self.assertEqual("icx", pending_tx_as_dict["tokenType"]) self.assertEqual("", pending_tx_as_dict["contractAddr"]) self.assertEqual(500, pending_tx_as_dict["amount"]) self.assertEqual(["kakao", "chainId"], pending_tx_as_dict["dids"]) SmartWallet.Pending = PendingMock # WHEN self.smart_wallet.transfer(account_id=0, token_type="icx", contract_addr="", to="hx" + "1" * 40, amount=500) # THEN pending_tx_db = DictDB(PENDING_TX, self.smart_wallet.db, str, 1) pending_tx_as_dict = json.loads(pending_tx_db[1]) self.assertEqual(1, pending_tx_as_dict["id"]) self.assertEqual(0, pending_tx_as_dict["from"]) self.assertEqual("hx" + "1" * 40, pending_tx_as_dict["to"]) self.assertEqual("icx", pending_tx_as_dict["tokenType"]) self.assertEqual("", pending_tx_as_dict["contractAddr"]) self.assertEqual(500, pending_tx_as_dict["amount"]) self.assertEqual(["kakao", "chainId"], pending_tx_as_dict["dids"]) pending_tx_list = json.loads( VarDB(PENDING_TX_ID_LIST, self.smart_wallet.db, str).get()) self.assertEqual(1, len(pending_tx_list)) self.assertEqual(1, pending_tx_list[0]) last_tx_id = VarDB(LAST_TX_ID, self.smart_wallet.db, int).get() self.assertEqual(1, last_tx_id) def __setup_processing_pending_tx(self): Icx.transfer = lambda contract, addr_to, amount: None self.smart_wallet._accounts = [ json.dumps({ "id": 0, "tokenType": "icx", "balance": 3000, "sendLimit": 1000, "totalUsed": 500, "lastUsedDate": "2018-11-21", "dids": ["kakao", "chainId"] }) ] type(self.smart_wallet).block = PropertyMock( return_value=Block(0, 1542773377)) def test_approval(self): """ GIVEN account with two dids, and pending one tx from that account, WHEN call approval twice THEN first approval remove dids in pending tx, second remove pending tx with TransferSuccess event """ # GIVEN self.__setup_processing_pending_tx() SmartWallet.Pending = lambda _self, pending_tx: None self.smart_wallet.transfer(account_id=0, token_type="icx", contract_addr="", to="hx" + "1" * 40, amount=500) # first WHEN def FirstApprovalMock(_self, tx_id, did): self.assertEqual(1, tx_id) self.assertEqual("kakao", did) SmartWallet.Approval = FirstApprovalMock self.smart_wallet.approval(1, "kakao", "true") # first THEN pending_tx_db = DictDB(PENDING_TX, self.smart_wallet.db, str, 1) pending_tx_as_dict = json.loads(pending_tx_db[1]) self.assertEqual(["chainId"], pending_tx_as_dict["dids"]) # second WHEN def SecondApprovalMock(_self, tx_id, did): self.assertEqual(1, tx_id) self.assertEqual("chainId", did) SmartWallet.Approval = SecondApprovalMock SmartWallet.TransferSuccess = lambda _self, account_id, token_type, contract_addr, to, amount: None self.smart_wallet.approval(1, "chainId", "true") # second THEN self.assertEqual("", pending_tx_db[1]) self.assertEqual( json.dumps([]), VarDB(PENDING_TX_ID_LIST, self.smart_wallet.db, str).get()) def test_transfer_account_to_account(self): """ GIVEN two accounts WHEN to address is 1 THEN transfer success to account """ # GIVEN self.__setup_no_did_transfer_env() self.smart_wallet._accounts\ .append(json.dumps({ "id": 1, "tokenType": "icx", "balance": 3000, "sendLimit": 1000, "totalUsed": 500, "lastUsedDate": "2018-11-21", "dids": ["kakao", "chainId"] }) ) def TransferSuccessMock(contract, account_id: int, token_type: str, token_address: str, to: str, amount: int): self.assertEqual(0, account_id) self.assertEqual("icx", token_type) self.assertEqual("", token_address) self.assertEqual("1", to) self.assertEqual(500, amount) SmartWallet.TransferSuccess = TransferSuccessMock self.smart_wallet.transfer(0, "icx", "", "1", 500) # THEN account0 = json.loads(self.smart_wallet._accounts[0]) assert account0['balance'] == 2500 assert account0['totalUsed'] == 1000 account1 = json.loads(self.smart_wallet._accounts[1]) assert account1['balance'] == 3500
# limitations under the License. import copy from unittest.mock import PropertyMock import pytest from iconservice import Address from iconservice.base.block import Block from iconservice.icon_constant import Revision, IconScoreContextType from iconservice.iconscore.context.context import ContextContainer from iconservice.iconscore.icon_score_context import IconScoreContext from iconservice.icx.coin_part import CoinPart, CoinPartFlag, CoinPartType from iconservice.icx.icx_account import Account from iconservice.icx.stake_part import StakePart ADDRESS = Address.from_string(f"hx{'1234'*10}") UNSTAKE_LOCK_PERIOD = 20 WITHDRAWAL_AMOUNT = 10 @pytest.fixture(scope="function") def context(): ctx = IconScoreContext(IconScoreContextType.DIRECT) block = Block(0, None, 0, None, 0) ctx.block = block ContextContainer._push_context(ctx) yield ctx ContextContainer._pop_context() class TestAccount: