Esempio n. 1
0
    def fill(
        self,
        counter: Optional[int] = None,
        ttl: Optional[int] = None,
        **kwargs
    ) -> 'OperationGroup':
        """Try to fill all fields left unfilled, use approximate fees
        (not optimal, use `autofill` to simulate operation and get precise values).

        :param counter: Override counter value (for manual handling)
        :param ttl: Number of blocks to wait in the mempool before removal (default is 5 for public network, 60 for sandbox)
        :rtype: OperationGroup
        """
        if kwargs.get('branch_offset') is not None:
            logger.warning('`branch_offset` argument is deprecated, use `ttl` instead')
            ttl = MAX_OPERATIONS_TTL - kwargs['branch_offset']

        if ttl is None:
            ttl = self.context.get_operations_ttl()
        if not 0 < ttl <= MAX_OPERATIONS_TTL:
            raise Exception('`ttl` has to be in range (0, 60]')

        chain_id = self.chain_id or self.context.get_chain_id()
        branch = self.branch or self.shell.blocks[f'head-{MAX_OPERATIONS_TTL - ttl}'].hash()
        protocol = self.protocol or self.shell.head.header()['protocol']
        source = self.key.public_key_hash()

        if counter is not None:
            self.context.set_counter(counter)

        replace_map = {
            'pkh': source,
            'source': source,
            'delegate': source,  # self registration
            'counter': lambda x: str(self.context.get_counter()),
            'secret': lambda x: self.key.activation_code,
            'period': lambda x: str(self.shell.head.voting_period()),
            'public_key': lambda x: self.key.public_key(),
            'fee': lambda x: str(default_fee(x)),
            'gas_limit': lambda x: str(default_gas_limit(x, self.context.constants)),
            'storage_limit': lambda x: str(default_storage_limit(x, self.context.constants)),
        }

        def fill_content(content):
            content = content.copy()
            for k, v in replace_map.items():
                if content.get(k) in ['', '0']:
                    content[k] = v(content) if callable(v) else v
            return content

        return self._spawn(
            contents=list(map(fill_content, self.contents)),
            protocol=protocol,
            chain_id=chain_id,
            branch=branch,
        )
Esempio n. 2
0
    def test_default_gas_and_storage_limit(self) -> None:
        # Arrange
        node_gas_limit = 88888
        node_storage_limit = 66666
        node_constants = dict(
            hard_gas_limit_per_operation=node_gas_limit,
            hard_storage_limit_per_operation=node_storage_limit,
        )
        testmap = {
            'tz_no_constants': [
                'tz',
                None,
                DEFAULT_TRANSACTION_GAS_LIMIT,
                DEFAULT_TRANSACTION_STORAGE_LIMIT,
            ],
            'tz_constants': [
                'tz',
                node_constants,
                DEFAULT_TRANSACTION_GAS_LIMIT,
                DEFAULT_TRANSACTION_STORAGE_LIMIT,
            ],
            'KT_no_constants': [
                'KT',
                None,
                DEFAULT_CONSTANTS['hard_gas_limit_per_operation'],
                DEFAULT_CONSTANTS['hard_storage_limit_per_operation'],
            ],
            'KT_constants': [
                'KT',
                node_constants,
                node_gas_limit,
                node_storage_limit,
            ],
        }

        for name, data in testmap.items():
            dest_prefix, constants, expected_gas_limit, expected_storage_limit = data
            with self.subTest(name):
                # Act
                self.content['destination'] = dest_prefix + self.content[
                    'destination'][2:]
                gas_limit = default_gas_limit(self.content, constants)
                storage_limit = default_storage_limit(self.content, constants)

                # Assert
                self.assertEqual(expected_gas_limit, gas_limit)
                self.assertEqual(expected_storage_limit, storage_limit)
Esempio n. 3
0
    def fill(self, counter=None, branch_offset=50):
        """ Try to fill all fields left unfilled, use approximate fees
        (not optimal, use `autofill` to simulate operation and get precise values).

        :param counter: Override counter value (for manual handling)
        :param branch_offset: select head~offset block as branch, where offset is in range (0, 60)
        :rtype: OperationGroup
        """
        assert 0 < branch_offset < 60, f'branch offset has to be in range (0, 60)'
        chain_id = self.chain_id or self.context.get_chain_id()
        branch = self.branch or self.shell.blocks[-branch_offset].hash()
        protocol = self.protocol or self.shell.head.header()['protocol']
        source = self.key.public_key_hash()

        if counter is not None:
            self.context.set_counter(counter)

        replace_map = {
            'pkh': source,
            'source': source,
            'delegate': source,  # self registration
            'counter': lambda x: str(self.context.get_counter()),
            'secret': lambda x: self.key.activation_code,
            'period': lambda x: str(self.shell.head.voting_period()),
            'public_key': lambda x: self.key.public_key(),
            'fee': lambda x: str(default_fee(x)),
            'gas_limit': lambda x: str(default_gas_limit(x)),
            'storage_limit': lambda x: str(default_storage_limit(x)),
        }

        def fill_content(content):
            content = content.copy()
            for k, v in replace_map.items():
                if content.get(k) in ['', '0']:
                    content[k] = v(content) if callable(v) else v
            return content

        return self._spawn(contents=list(map(fill_content, self.contents)),
                           protocol=protocol,
                           chain_id=chain_id,
                           branch=branch)
Esempio n. 4
0
    def fill(self):
        """
        Try to fill all fields left unfilled, use approximate fees
        (not optimal, use `autofill` to simulate operation and get precise values).
        :return: OperationGroup
        """
        chain_id = self.chain_id or self.shell.chains.main.chain_id()
        branch = self.branch or self.shell.head.predecessor.hash()
        protocol = self.protocol or self.shell.head.header()['protocol']
        source = self.key.public_key_hash()
        counter = self.shell.contracts[source].count()

        replace_map = {
            'pkh': source,
            'source': source,
            'delegate': source,  # self registration
            'counter': lambda x: str(next(counter)),
            'secret': lambda x: self.key.activation_code,
            'period': lambda x: str(self.shell.head.voting_period()),
            'public_key': lambda x: self.key.public_key(),
            'manager_pubkey': source,  # I know, it hurts
            'fee': lambda x: str(default_fee(x)),
            'gas_limit': lambda x: str(default_gas_limit(x)),
            'storage_limit': lambda x: str(default_storage_limit(x)),
        }

        def fill_content(content):
            content = content.copy()
            for k, v in replace_map.items():
                if content.get(k) in ['', '0']:
                    content[k] = v(content) if callable(v) else v
            return content

        return self._spawn(contents=list(map(fill_content, self.contents)),
                           protocol=protocol,
                           chain_id=chain_id,
                           branch=branch)