Ejemplo n.º 1
0
class Testcases(unittest.TestCase):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.bts = BitShares(
            "wss://node.testnet.bitshares.eu",
            nobroadcast=True,
            keys={"active": wif, "owner": wif, "memo": wif},
        )
        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_bitshares_instance(self.bts)
        self.bts.set_default_account("init0")

    def test_connect(self):
        self.bts.connect()

    def test_set_default_account(self):
        self.bts.set_default_account("init0")

    def test_info(self):
        info = self.bts.info()
        for key in ['current_witness',
                    'head_block_id',
                    'head_block_number',
                    'id',
                    'last_irreversible_block_num',
                    'next_maintenance_time',
                    'recently_missed_count',
                    'time']:
            self.assertTrue(key in info)

    def test_finalizeOps(self):
        bts = self.bts
        tx1 = bts.new_tx()
        tx2 = bts.new_tx()
        self.bts.transfer("init1", 1, core_unit, append_to=tx1)
        self.bts.transfer("init1", 2, core_unit, append_to=tx2)
        self.bts.transfer("init1", 3, core_unit, append_to=tx1)
        tx1 = tx1.json()
        tx2 = tx2.json()
        ops1 = tx1["operations"]
        ops2 = tx2["operations"]
        self.assertEqual(len(ops1), 2)
        self.assertEqual(len(ops2), 1)

    def test_transfer(self):
        bts = self.bts
        tx = bts.transfer(
            "1.2.8", 1.33, core_unit, memo="Foobar", account="1.2.7")
        self.assertEqual(
            getOperationNameForId(tx["operations"][0][0]),
            "transfer"
        )
        op = tx["operations"][0][1]
        self.assertIn("memo", op)
        self.assertEqual(op["from"], "1.2.7")
        self.assertEqual(op["to"], "1.2.8")
        amount = Amount(op["amount"])
        self.assertEqual(float(amount), 1.33)

    def test_create_account(self):
        bts = self.bts
        name = ''.join(random.choice(string.ascii_lowercase) for _ in range(12))
        key1 = PrivateKey()
        key2 = PrivateKey()
        key3 = PrivateKey()
        key4 = PrivateKey()
        tx = bts.create_account(
            name,
            registrar="init0",   # 1.2.7
            referrer="init1",    # 1.2.8
            referrer_percent=33,
            owner_key=format(key1.pubkey, core_unit),
            active_key=format(key2.pubkey, core_unit),
            memo_key=format(key3.pubkey, core_unit),
            additional_owner_keys=[format(key4.pubkey, core_unit)],
            additional_active_keys=[format(key4.pubkey, core_unit)],
            additional_owner_accounts=["committee-account"],  # 1.2.0
            additional_active_accounts=["committee-account"],
            proxy_account="init0",
            storekeys=False
        )
        self.assertEqual(
            getOperationNameForId(tx["operations"][0][0]),
            "account_create"
        )
        op = tx["operations"][0][1]
        role = "active"
        self.assertIn(
            format(key4.pubkey, core_unit),
            [x[0] for x in op[role]["key_auths"]])
        self.assertIn(
            format(key4.pubkey, core_unit),
            [x[0] for x in op[role]["key_auths"]])
        self.assertIn(
            "1.2.0",
            [x[0] for x in op[role]["account_auths"]])
        role = "owner"
        self.assertIn(
            format(key4.pubkey, core_unit),
            [x[0] for x in op[role]["key_auths"]])
        self.assertIn(
            format(key4.pubkey, core_unit),
            [x[0] for x in op[role]["key_auths"]])
        self.assertIn(
            "1.2.0",
            [x[0] for x in op[role]["account_auths"]])
        self.assertEqual(
            op["options"]["voting_account"],
            "1.2.6")
        self.assertEqual(
            op["registrar"],
            "1.2.6")
        self.assertEqual(
            op["referrer"],
            "1.2.7")
        self.assertEqual(
            op["referrer_percent"],
            33 * 100)

    def test_weight_threshold(self):
        bts = self.bts

        auth = {'account_auths': [['1.2.0', '1']],
                'extensions': [],
                'key_auths': [
                    ['TEST55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n', 1],
                    ['TEST7GM9YXcsoAJAgKbqW2oVj7bnNXFNL4pk9NugqKWPmuhoEDbkDv', 1]],
                'weight_threshold': 3}  # threshold fine
        bts._test_weights_treshold(auth)
        auth = {'account_auths': [['1.2.0', '1']],
                'extensions': [],
                'key_auths': [
                    ['TEST55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n', 1],
                    ['TEST7GM9YXcsoAJAgKbqW2oVj7bnNXFNL4pk9NugqKWPmuhoEDbkDv', 1]],
                'weight_threshold': 4}  # too high

        with self.assertRaises(ValueError):
            bts._test_weights_treshold(auth)

    def test_allow(self):
        bts = self.bts
        tx = bts.allow(
            "TEST55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n",
            weight=1,
            threshold=1,
            permission="owner"
        )
        self.assertEqual(
            getOperationNameForId(tx["operations"][0][0]),
            "account_update"
        )
        op = tx["operations"][0][1]
        self.assertIn("owner", op)
        self.assertIn(
            ["TEST55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", '1'],
            op["owner"]["key_auths"])
        self.assertEqual(op["owner"]["weight_threshold"], 1)

    def test_disallow(self):
        bts = self.bts
        with self.assertRaisesRegex(ValueError, ".*Changes nothing.*"):
            bts.disallow(
                "TEST55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n",
                weight=1,
                threshold=1,
                permission="owner"
            )
        with self.assertRaisesRegex(ValueError, ".*Changes nothing!.*"):
            bts.disallow(
                "TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
                weight=1,
                threshold=1,
                permission="owner"
            )

    def test_update_memo_key(self):
        bts = self.bts
        tx = bts.update_memo_key("TEST55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n")
        self.assertEqual(
            getOperationNameForId(tx["operations"][0][0]),
            "account_update"
        )
        op = tx["operations"][0][1]
        self.assertEqual(
            op["new_options"]["memo_key"],
            "TEST55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n")

    def test_approvewitness(self):
        bts = self.bts
        tx = bts.approvewitness("init0")
        self.assertEqual(
            getOperationNameForId(tx["operations"][0][0]),
            "account_update"
        )
        op = tx["operations"][0][1]
        self.assertIn(
            "1:0",
            op["new_options"]["votes"])

    def test_approvecommittee(self):
        bts = self.bts
        tx = bts.approvecommittee("init0")
        self.assertEqual(
            getOperationNameForId(tx["operations"][0][0]),
            "account_update"
        )
        op = tx["operations"][0][1]
        self.assertIn(
            "0:11",
            op["new_options"]["votes"])

    def test_sign_message(self):
        def new_refresh(self):
            dict.__init__(
                self, {"name": "init0",
                 "options": {
                     "memo_key": "TEST6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
                 }})

        with mock.patch(
            "bitshares.account.Account.refresh",
            new=new_refresh
        ):
            p = Message("message foobar").sign()
            Message(p).verify()
class NodeCall():
    """ Concurent call a method for node."""
    def __init__(self, node: str):
        """ Connect to a specified node."""
        self.bts = BitShares(node)

    def call_wrapper(self, call, method: str, kwargs: dict):
        # Copy method from call to responce.
        result: dict = {"method": method}
        if not method or not call:
            result['error']: str = ""
            "`{0}` is not implemented!".format(method)
        else:
            try:
                # call can return dict, list, str
                result['result'] = call(self, **kwargs)
            except (RPCError, UnhandledRPCError) as err:
                result['error']: str = str(err)
        return result

    def get_global_properties(self):
        """ Retrieve the current global_property_object."""
        return self.bts.info()

    def get_block(self, block_num: int):
        """ Retrieve a full, signed block."""
        result = Block(block_num, blockchain_instance=self.bts)
        return dict(result)

    def get_chain_properties(self):
        """ Retrieve the chain_property_object associated with the chain."""
        self.chain = Blockchain(blockchain_instance=self.bts)
        return self.chain.get_chain_properties()

    def get_dynamic_global_properties(self):
        """ This call returns the *dynamic global properties*."""
        self.chain = Blockchain(blockchain_instance=self.bts)
        return self.chain.info()

    def get_config(self):
        """ Retrieve compile-time constants."""
        self.chain = Blockchain(blockchain_instance=self.bts)
        return self.chain.config()

    def get_accounts(self, account_ids: list) -> list:
        """ Get a list of accounts by ID.

            :param str account_ids: Identify of the account
            :param bitshares.bitshares.BitShares blockchain_instance: BitShares
                   instance
            :returns: Account data list
            :rtype: list
            :raises bitshares.exceptions.AccountDoesNotExistsException:
            if account does not exist

        """
        result = []
        for account_id in account_ids:
            account = Account(account_id, blockchain_instance=self.bts)
            result.append(dict(account))
        return result

    def get_chain_id(self):
        """ Get the chain ID."""
        self.chain = Blockchain(blockchain_instance=self.bts)
        return self.chain.get_chain_properties()

    def get_transaction(self, block_num: int, trx_in_block: int):
        """ Fetch an individual processed transaction from a block."""
        result = self.bts.rpc.get_transaction(block_num, trx_in_block)
        return dict(result)
Ejemplo n.º 3
0
class NodeCalls(object):

    """ Connect to a specified node and perform calls."""

    def __init__(self, scenario: dict, roundup: dict):
        self.scenario: dict = scenario
        self.roundup = roundup

    def connect(self, node: str, **kwargs):
        """ Connect to a specified node."""
        self.bts = BitShares(node, kwargs)
        log.info('Connected to node "{0}".'.format(self.bts.rpc.url))
        if not getattr(self, 'chain', None):
            self.chain = Blockchain(blockchain_instance=self.bts)

    def run(self):
        try:
            self.connect(self.scenario.get("node"))
        except BaseException as err:
            log.critical('Fail to connect to node "{0} due to {1}".'.format(
                self.scenario.get("node"), err)
            )
            log.error('Scenario run has stopped.')
            return

        if not self.scenario or not self.scenario.get("stages", []):
            log.warning("Empty stages!")

        for stage in self.scenario.get("stages", []):
            start_time = time.time()
            method: str = stage.get("method", '')
            call = getattr(self, method, lambda: None)
            # Copy method from call to responce.
            result: dict = {"method": method}
            if not method or not call:
                result['result']['message']: str = ""
                "`{0}` is not implemented!".format(method)
                log.error(json.dumps(result,  indent=(2 * ' ')))
                continue
            else:
                kwargs: dict = stage.get("params", {})
                try:
                    result['result']: str = call(**kwargs)
                    log.info(json.dumps(result,  indent=(2 * ' ')))
                except (RPCError,  UnhandledRPCError) as err:
                    result['result']['message']: str = str(err)
                    log.error(json.dumps(result,  indent=(2 * ' ')))
            # Track time spent on calls, sum up to table
            self.roundup[method] = self.roundup.get(method, 0) + time.time() - start_time

    def get_global_properties(self):
        """ Retrieve the current global_property_object."""
        return self.bts.info()

    def get_block(self, block_num: int):
        """ Retrieve a full, signed block."""
        return Block(block_num, blockchain_instance=self.bts, lazy=False)

    def get_chain_properties(self):
        """ Retrieve the chain_property_object associated with the chain."""
        return self.chain.get_chain_properties()

    def get_dynamic_global_properties(self):
        """ This call returns the *dynamic global properties*."""
        return self.chain.info()

    def get_config(self):
        """ Retrieve compile-time constants."""
        return self.chain.config()

#    def get_all_accounts(self, start='', stop='', steps=1e3, **kwargs):
#        """ Yields account names between start and stop.
#
#            :param str start: Start at this account name
#            :param str stop: Stop at this account name
#            :param int steps: Obtain ``steps`` ret with a single call from RPC
#        """
#        return json.dumps((account for account in self.chain.get_all_accounts(
#            start, stop,  steps)), iterable_as_array=True)

    def get_accounts(self, account_ids: list) -> list:
        """ Get a list of accounts by ID.

            :param str account_ids: Identify of the account
            :param bitshares.bitshares.BitShares blockchain_instance: BitShares
                   instance
            :returns: Account data list
            :rtype: list
            :raises bitshares.exceptions.AccountDoesNotExistsException: if account
                    does not exist

        """
        result = []
        for account_id in account_ids:
            account = Account(account_id,  blockchain_instance=self.bts)
            result.append(account)
        return result

    def get_chain_id(self):
        """ Get the chain ID."""
        return {"chain_id": self.chain.get_chain_properties()["chain_id"]}

    @log_exceptions
    def get_transaction(self, block_num: int, trx_in_block: int):
        """ Fetch an individual processed transaction from a block."""
        return self.bts.rpc.get_transaction(block_num, trx_in_block)

    def get_proposed_transactions(self, account: str):
        """ Obtain a list of pending proposals for an account.

            :param str account: Account name
            :param bitshares blockchain_instance: BitShares() instance to use
                when accesing a RPC

        """
        proposals: list = Proposals(account,  blockchain_instance=self.bts)
        return {"proposed_transactions": proposals}