Example #1
0
 def test_chain_params_context_manager(self):
     with ChainParams(BitcoinRegtestParams) as p1:
         assert isinstance(p1, BitcoinRegtestParams)
         with ChainParams(BitcoinSignetParams) as p2:
             assert isinstance(p2, BitcoinSignetParams)
             assert isinstance(get_current_chain_params(),
                               BitcoinSignetParams)
         assert isinstance(get_current_chain_params(), BitcoinRegtestParams)
Example #2
0
 def base58_get_match_candidates(
     cls: Type[T_CBase58DataDispatched]
 ) -> List[Type[T_CBase58DataDispatched]]:
     assert isinstance(cls, ClassMappingDispatcher)
     candidates = dispatcher_mapped_list(cls)
     if P2SHLitecoinAddress in candidates\
             and get_current_chain_params().allow_legacy_p2sh:
         return [P2SHLitecoinLegacyAddress] + candidates
     return super(CBase58LitecoinAddress, cls).base58_get_match_candidates()
Example #3
0
 async def async_mainnet() -> None:
     select_chain_params('bitcoin/mainnet')
     await wait_async('testnet')
     a = P2PKHCoinAddress.from_pubkey(pub)
     assert CBase58Data(str(a))[0] == 0
     check_core_modules()
     ready('mainnet')
     finish('mainnet')
     self.assertEqual(get_current_chain_params().NAME, 'bitcoin')
Example #4
0
 async def async_testnet() -> None:
     select_chain_params('bitcoin/testnet')
     await wait_async('regtest')
     a = P2SHCoinAddress.from_redeemScript(
         CScript(b'\xa9' + Hash160(pub) + b'\x87'))
     assert CBase58Data(str(a))[0] == 196
     check_core_modules()
     ready('testnet')
     await wait_async('mainnet')
     self.assertEqual(get_current_chain_params().NAME,
                      'bitcoin/testnet')
     finish('testnet')
Example #5
0
 async def async_regtest() -> None:
     select_chain_params('bitcoin/regtest')
     a = P2WPKHCoinAddress.from_pubkey(pub)
     witver, data = bitcointx.segwit_addr.decode(
         P2WPKHBitcoinRegtestAddress.bech32_hrp, str(a))
     assert witver == 0
     assert data == Hash160(pub)
     check_core_modules()
     ready('regtest')
     await wait_async('testnet')
     await wait_async('mainnet')
     self.assertEqual(get_current_chain_params().NAME,
                      'bitcoin/regtest')
     finish('regtest')
 def setUpClass(cls) -> None:
     cls._prev_chain_params = bitcointx.get_current_chain_params(
     )  # type: ignore
     bitcointx.select_chain_params('elements')
Example #7
0
    def __init__(self,
                 service_url=None,
                 service_port=None,
                 conf_file=None,
                 allow_default_conf=False,
                 timeout=DEFAULT_HTTP_TIMEOUT,
                 connection=None):

        # Create a dummy connection early on so if __init__() fails prior to
        # __conn being created __del__() can detect the condition and handle it
        # correctly.
        self.__conn = None
        authpair = None

        self.__timeout = timeout

        if service_url is None:
            params = bitcointx.get_current_chain_params()

            # Figure out the path to the config file
            if conf_file is None:
                if not allow_default_conf:
                    raise ValueError("if conf_file is not specified, "
                                     "allow_default_conf must be True")
                conf_file = params.get_config_path()

            conf = _try_read_conf_file(conf_file, allow_default_conf)

            if service_port is None:
                service_port = params.RPC_PORT

            extraname = params.get_datadir_extra_name()

            (host, port) = split_hostport(
                conf.get('{}.rpcconnect'.format(extraname),
                         conf.get('rpcconnect', 'localhost')))

            port = int(conf.get('{}.rpcport'.format(extraname),
                                conf.get('rpcport', port or service_port)))
            service_url = ('%s://%s:%d' % ('http', host, port))

            cookie_dir = conf.get('datadir', os.path.dirname(conf_file))
            cookie_dir = os.path.join(cookie_dir,
                                      params.get_datadir_extra_name())
            cookie_file = os.path.join(cookie_dir, ".cookie")
            try:
                with open(cookie_file, 'r') as fd:
                    authpair = fd.read()
            except IOError as err:
                if 'rpcpassword' in conf:
                    authpair = "%s:%s" % (conf['rpcuser'], conf['rpcpassword'])

                else:
                    raise ValueError(
                        'Cookie file unusable (%s) and rpcpassword '
                        'not specified in the configuration file: %r'
                        % (err, conf_file))

        else:
            url = urllib.parse.urlparse(service_url)
            authpair = "%s:%s" % (url.username, url.password)

        self.__service_url = service_url
        self.__url = urllib.parse.urlparse(service_url)

        if self.__url.scheme not in ('http',):
            raise ValueError('Unsupported URL scheme %r' % self.__url.scheme)

        if self.__url.port is None:
            self.__port = service_port or http.client.HTTP_PORT
        else:
            self.__port = self.__url.port

        self.__id_count = 0

        if authpair is None:
            self.__auth_header = None
        else:
            authpair = authpair.encode('utf8')
            self.__auth_header = b"Basic " + base64.b64encode(authpair)

        self.connect(connection=connection)
Example #8
0
 def setUp(self) -> None:
     self.current_params = get_current_chain_params()
Example #9
0
 def setUpClass(cls):
     logging.basicConfig()
     cls._prev_chain_params = bitcointx.get_current_chain_params()
     bitcointx.select_chain_params('elements')
Example #10
0
    def test_addresses(self) -> None:
        pub = CPubKey(
            x('0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71'
              ))

        events: Dict[str, Union[threading.Event, asyncio.Event]]
        events = {
            'mainnet': threading.Event(),
            'testnet': threading.Event(),
            'regtest': threading.Event(),
        }

        # list append is thread-safe, can use just the list.
        finished_successfully = []

        def wait(name: str) -> None:
            evt = events[name]
            assert isinstance(evt, threading.Event)
            not_timed_out = evt.wait(timeout=5.0)
            assert not_timed_out

        async def wait_async(name: str) -> None:
            evt = events[name]
            assert isinstance(evt, asyncio.Event)
            await asyncio.wait_for(evt.wait(), 5.0)

        def ready(name: str) -> None:
            events[name].set()

        def finish(name: str) -> None:
            finished_successfully.append(name)

        def check_core_modules() -> None:
            # check that mutable/immutable thread-local context works
            CTransaction().to_mutable().to_immutable()

            # check secp256k1 error handling (which uses thread-local storage)
            _secp256k1.secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify,
                                                     ctypes.c_char_p(0),
                                                     ctypes.c_char_p(0))
            err = secp256k1_get_last_error()
            assert err['code'] == -2
            assert err['type'] == 'illegal_argument'
            assert 'message' in err

        def mainnet() -> None:
            select_chain_params('bitcoin/mainnet')
            wait('testnet')
            a = P2PKHCoinAddress.from_pubkey(pub)
            assert CBase58Data(str(a))[0] == 0
            check_core_modules()
            ready('mainnet')
            finish('mainnet')
            self.assertEqual(get_current_chain_params().NAME, 'bitcoin')

        async def async_mainnet() -> None:
            select_chain_params('bitcoin/mainnet')
            await wait_async('testnet')
            a = P2PKHCoinAddress.from_pubkey(pub)
            assert CBase58Data(str(a))[0] == 0
            check_core_modules()
            ready('mainnet')
            finish('mainnet')
            self.assertEqual(get_current_chain_params().NAME, 'bitcoin')

        def testnet() -> None:
            select_chain_params('bitcoin/testnet')
            wait('regtest')
            a = P2SHCoinAddress.from_redeemScript(
                CScript(b'\xa9' + Hash160(pub) + b'\x87'))
            assert CBase58Data(str(a))[0] == 196
            check_core_modules()
            ready('testnet')
            wait('mainnet')
            self.assertEqual(get_current_chain_params().NAME,
                             'bitcoin/testnet')
            finish('testnet')

        async def async_testnet() -> None:
            select_chain_params('bitcoin/testnet')
            await wait_async('regtest')
            a = P2SHCoinAddress.from_redeemScript(
                CScript(b'\xa9' + Hash160(pub) + b'\x87'))
            assert CBase58Data(str(a))[0] == 196
            check_core_modules()
            ready('testnet')
            await wait_async('mainnet')
            self.assertEqual(get_current_chain_params().NAME,
                             'bitcoin/testnet')
            finish('testnet')

        def regtest() -> None:
            select_chain_params('bitcoin/regtest')
            a = P2WPKHCoinAddress.from_pubkey(pub)
            witver, data = bitcointx.segwit_addr.decode(
                P2WPKHBitcoinRegtestAddress.bech32_hrp, str(a))
            assert witver == 0
            assert data == Hash160(pub)
            check_core_modules()
            ready('regtest')
            wait('testnet')
            wait('mainnet')
            self.assertEqual(get_current_chain_params().NAME,
                             'bitcoin/regtest')
            finish('regtest')

        async def async_regtest() -> None:
            select_chain_params('bitcoin/regtest')
            a = P2WPKHCoinAddress.from_pubkey(pub)
            witver, data = bitcointx.segwit_addr.decode(
                P2WPKHBitcoinRegtestAddress.bech32_hrp, str(a))
            assert witver == 0
            assert data == Hash160(pub)
            check_core_modules()
            ready('regtest')
            await wait_async('testnet')
            await wait_async('mainnet')
            self.assertEqual(get_current_chain_params().NAME,
                             'bitcoin/regtest')
            finish('regtest')

        assert isinstance(get_current_chain_params(), BitcoinMainnetParams), \
            "tests assume bitcoin params in effect by default"

        mainnet_thread = threading.Thread(target=mainnet)
        testnet_thread = threading.Thread(target=testnet)
        regtest_thread = threading.Thread(target=regtest)
        mainnet_thread.start()
        testnet_thread.start()
        regtest_thread.start()
        mainnet_thread.join()
        testnet_thread.join()
        regtest_thread.join()

        self.assertEqual(set(finished_successfully),
                         set(['mainnet', 'testnet', 'regtest']))
        self.assertIsInstance(get_current_chain_params(), BitcoinMainnetParams)

        if issubclass(ContextVarsCompat, threading.local):
            logging.basicConfig()
            log = logging.getLogger("Test_Threading")
            log.warning(
                'contextvars.ContextVar is unavailable, asyncio contexts '
                'when switching chain params will be broken. '
                'Use python >= 3.7 if you want asyncio compatibility, or '
                'just don\'set chainparams in concurrent code.')
            return

        finished_successfully = []

        events = {
            'mainnet': asyncio.Event(),
            'testnet': asyncio.Event(),
            'regtest': asyncio.Event(),
        }

        async def go() -> None:
            f1 = asyncio.ensure_future(async_mainnet())
            f2 = asyncio.ensure_future(async_testnet())
            f3 = asyncio.ensure_future(async_regtest())
            await asyncio.gather(f1, f2, f3)

        asyncio.get_event_loop().run_until_complete(go())

        self.assertEqual(set(finished_successfully),
                         set(['mainnet', 'testnet', 'regtest']))
        self.assertIsInstance(get_current_chain_params(), BitcoinMainnetParams)
 def setUpClass(cls) -> None:
     logging.basicConfig()
     cls._prev_chain_params = bitcointx.get_current_chain_params(
     )  # type: ignore
     bitcointx.select_chain_params('elements')
 def setUpClass(cls):
     cls._prev_chain_params = bitcointx.get_current_chain_params()
     bitcointx.select_chain_params('elements')
Example #13
0
    def __init__(
            self,  # noqa
            service_url: Optional[str] = None,
            service_port: Optional[int] = None,
            conf_file: Optional[str] = None,
            conf_file_contents: Optional[str] = None,
            allow_default_conf: bool = False,
            timeout: int = DEFAULT_HTTP_TIMEOUT,
            connection: Optional[HTTPClient_Type] = None) -> None:

        if (conf_file is not None) and (conf_file_contents is not None):
            raise ValueError(
                'Either conf_file or conf_file_contents must be specified, '
                'but not both')
        # Create a dummy connection early on so if __init__() fails prior to
        # __conn being created __del__() can detect the condition and handle it
        # correctly.
        self.__conn: Optional[HTTPClient_Type] = None
        authpair = None

        self.__timeout = timeout

        if service_url is None:
            params = bitcointx.get_current_chain_params()

            # Figure out the path to the config file
            if conf_file is None and conf_file_contents is None:
                if not allow_default_conf:
                    raise ValueError("if conf_file is not specified, "
                                     "allow_default_conf must be True")
                conf_file = params.get_config_path()

            conf = _try_read_conf_file(conf_file, conf_file_contents,
                                       allow_default_conf)

            if service_port is None:
                service_port = params.RPC_PORT

            extraname = params.get_datadir_extra_name()
            network_id = params.get_network_id()

            (host, port) = split_hostport(
                conf.get(f'{network_id}.rpcconnect',
                         conf.get('rpcconnect', 'localhost')))

            port = int(
                conf.get(f'{network_id}.rpcport',
                         conf.get('rpcport', port or service_port)))
            service_url = ('%s://%s:%d' % ('http', host, port))

            cookie_dir = conf.get(
                f'{network_id}.datadir',
                conf.get(
                    'datadir',
                    None if conf_file is None else os.path.dirname(conf_file)))
            io_err = None
            if cookie_dir is not None:
                cookie_dir = os.path.join(cookie_dir, extraname)
                cookie_file = os.path.join(cookie_dir, ".cookie")
                try:
                    with open(cookie_file, 'r') as fd:
                        authpair = fd.read()
                except IOError as err:
                    io_err = err

            if authpair is None:
                if f'{network_id}.rpcpassword' in conf:
                    authpair = "%s:%s" % (conf.get(
                        f'{network_id}.rpcuser',
                        ''), conf[f'{network_id}.rpcpassword'])
                elif 'rpcpassword' in conf:
                    authpair = "%s:%s" % (conf.get('rpcuser',
                                                   ''), conf['rpcpassword'])
                elif io_err is None:
                    raise ValueError(
                        'Cookie dir is not known and rpcpassword is not '
                        'specified in conf_file_contents')
                else:
                    raise ValueError(
                        'Cookie file unusable (%s) and rpcpassword '
                        'not specified in the configuration file: %r' %
                        (io_err, conf_file))
        else:
            url = urllib.parse.urlparse(service_url)
            authpair = "%s:%s" % (url.username, url.password)

        self.__service_url = service_url
        self.__url = urllib.parse.urlparse(service_url)

        if self.__url.scheme not in ('http', ):
            raise ValueError('Unsupported URL scheme %r' % self.__url.scheme)

        if self.__url.port is None:
            self.__port = service_port or http.client.HTTP_PORT
        else:
            self.__port = self.__url.port

        self.__id_count = 0

        if authpair is None:
            self.__auth_header = None
        else:
            self.__auth_header = (
                "Basic " +
                base64.b64encode(authpair.encode('utf8')).decode('utf8'))

        self.connect(connection=connection)
Example #14
0
 def base58_get_match_candidates(cls):
     candidates = dispatcher_mapped_list(cls)
     if P2SHLitecoinAddress in candidates\
             and get_current_chain_params().allow_legacy_p2sh:
         return [P2SHLitecoinLegacyAddress] + candidates
     return super(CBase58LitecoinAddress, cls).base58_get_match_candidates()
Example #15
0
                             BlindingInputDescriptor, CElementsTransaction,
                             CElementsTxOut, CElementsMutableTxOut,
                             CElementsTxInWitness, BlindingSuccess)
from elementstx.core import CElementsScript
from elementstx.wallet import CCoinConfidentialAddress, CElementsAddress

if __name__ == '__main__':
    if len(sys.argv) not in (5, 6):
        sys.stderr.write(
            "usage: {} <raw-hex-tx-file> <spending-key-wif-file> <unblinding-key-hex-file> <destination-address> [chainparams]\n"
            .format(sys.argv[0]))
        sys.exit(-1)

    if len(sys.argv) == 6:
        select_chain_params(sys.argv[5])
        if not isinstance(get_current_chain_params(), ElementsParams):
            print('specified chainparams is not Elements-compatible')
            sys.exit(-1)
    else:
        # Switch the chain parameters to Elements
        select_chain_params('elements')

    # Read in and decode the blinded transaction.
    # expected to be hex-encoded as one line.
    with open(sys.argv[1]) as f:
        # We could use CTransaction here, but if we want to
        # use mypy to do static checking, we need to use the elements-specific
        # classes. mypy does cannot know about dynamic class dispatch.
        input_tx = CElementsTransaction.deserialize(x(f.readline().rstrip()))

    # Read in the key, expected to be in WIF format.