Example #1
0
def btcRpc(cmd):
    return callrpc_cli(cfg.BITCOIN_BINDIR, os.path.join(cfg.TEST_DATADIRS, str(BTC_NODE)), 'regtest', cmd, cfg.BITCOIN_CLI)
Example #2
0
def nmcRpc(cmd):
    return callrpc_cli(cfg.NAMECOIN_BINDIR, os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)), 'regtest', cmd, cfg.NAMECOIN_CLI)
Example #3
0
def btcRpc(cmd, node_id=0):
    return callrpc_cli(cfg.BITCOIN_BINDIR,
                       os.path.join(TEST_DIR, 'btc_' + str(node_id)),
                       'regtest', cmd, cfg.BITCOIN_CLI)
Example #4
0
def partRpc(cmd, node_id=0):
    return callrpc_cli(cfg.PARTICL_BINDIR, os.path.join(cfg.TEST_DATADIRS, str(node_id)), 'regtest', cmd, cfg.PARTICL_CLI)
Example #5
0
    def setUpClass(cls):
        super(Test, cls).setUpClass()

        cls.update_thread = None
        cls.coins_update_thread = None
        cls.http_threads = []
        cls.swap_clients = []
        cls.part_daemons = []
        cls.btc_daemons = []

        cls.part_stakelimit = 0
        cls.btc_addr = None

        logger.propagate = False
        logger.handlers = []
        logger.setLevel(
            logging.INFO)  # DEBUG shows many messages from requests.post
        formatter = logging.Formatter(
            '%(asctime)s %(levelname)s : %(message)s')
        stream_stdout = logging.StreamHandler()
        stream_stdout.setFormatter(formatter)
        logger.addHandler(stream_stdout)

        if os.path.isdir(TEST_DIR):
            logging.info('Removing ' + TEST_DIR)
            shutil.rmtree(TEST_DIR)
        if not os.path.exists(TEST_DIR):
            os.makedirs(TEST_DIR)

        cls.stream_fp = logging.FileHandler(os.path.join(TEST_DIR, 'test.log'))
        cls.stream_fp.setFormatter(formatter)
        logger.addHandler(cls.stream_fp)

        try:
            logging.info('Preparing coin nodes.')
            for i in range(NUM_NODES):
                data_dir = prepareDataDir(TEST_DIR, i, 'particl.conf', 'part_')
                if os.path.exists(
                        os.path.join(cfg.PARTICL_BINDIR, 'particl-wallet')):
                    callrpc_cli(cfg.PARTICL_BINDIR, data_dir, 'regtest',
                                '-wallet=wallet.dat create', 'particl-wallet')

                cls.part_daemons.append(
                    startDaemon(os.path.join(TEST_DIR, 'part_' + str(i)),
                                cfg.PARTICL_BINDIR, cfg.PARTICLD))
                logging.info('Started %s %d', cfg.PARTICLD,
                             cls.part_daemons[-1].pid)

            for i in range(NUM_NODES):
                # Load mnemonics after all nodes have started to avoid staking getting stuck in TryToSync
                rpc = make_rpc_func(i)
                waitForRPC(rpc)
                if i == 0:
                    rpc('extkeyimportmaster', [
                        'abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb'
                    ])
                elif i == 1:
                    rpc('extkeyimportmaster', [
                        'pact mammal barrel matrix local final lecture chunk wasp survey bid various book strong spread fall ozone daring like topple door fatigue limb olympic',
                        '', 'true'
                    ])
                    rpc('getnewextaddress', ['lblExtTest'])
                    rpc('rescanblockchain')
                else:
                    rpc('extkeyimportmaster',
                        [rpc('mnemonic', ['new'])['master']])
                # Lower output split threshold for more stakeable outputs
                rpc('walletsettings', [
                    'stakingoptions', {
                        'stakecombinethreshold': 100,
                        'stakesplitthreshold': 200
                    }
                ])

            for i in range(NUM_BTC_NODES):
                data_dir = prepareDataDir(TEST_DIR,
                                          i,
                                          'bitcoin.conf',
                                          'btc_',
                                          base_p2p_port=BTC_BASE_PORT,
                                          base_rpc_port=BTC_BASE_RPC_PORT)
                if os.path.exists(
                        os.path.join(cfg.BITCOIN_BINDIR, 'bitcoin-wallet')):
                    callrpc_cli(cfg.BITCOIN_BINDIR, data_dir, 'regtest',
                                '-wallet=wallet.dat create', 'bitcoin-wallet')

                cls.btc_daemons.append(
                    startDaemon(os.path.join(TEST_DIR, 'btc_' + str(i)),
                                cfg.BITCOIN_BINDIR, cfg.BITCOIND))
                logging.info('Started %s %d', cfg.BITCOIND,
                             cls.part_daemons[-1].pid)

                waitForRPC(make_rpc_func(i, base_rpc_port=BTC_BASE_RPC_PORT))

            logging.info('Preparing swap clients.')
            eckey = ECKey()
            eckey.generate()
            cls.network_key = toWIF(PREFIX_SECRET_KEY_REGTEST,
                                    eckey.get_bytes())
            cls.network_pubkey = eckey.get_pubkey().get_bytes().hex()

            for i in range(NUM_NODES):
                prepare_swapclient_dir(TEST_DIR, i, cls.network_key,
                                       cls.network_pubkey)
                basicswap_dir = os.path.join(
                    os.path.join(TEST_DIR, 'basicswap_' + str(i)))
                settings_path = os.path.join(basicswap_dir,
                                             cfg.CONFIG_FILENAME)
                with open(settings_path) as fs:
                    settings = json.load(fs)
                fp = open(os.path.join(basicswap_dir, 'basicswap.log'), 'w')
                sc = BasicSwap(fp,
                               basicswap_dir,
                               settings,
                               'regtest',
                               log_name='BasicSwap{}'.format(i))
                sc.setDaemonPID(Coins.BTC, cls.btc_daemons[i].pid)
                sc.setDaemonPID(Coins.PART, cls.part_daemons[i].pid)
                sc.start()
                cls.swap_clients.append(sc)

                t = HttpThread(cls.swap_clients[i].fp, TEST_HTTP_HOST,
                               TEST_HTTP_PORT + i, False, cls.swap_clients[i])
                cls.http_threads.append(t)
                t.start()

            cls.btc_addr = callnoderpc(0,
                                       'getnewaddress',
                                       ['mining_addr', 'bech32'],
                                       base_rpc_port=BTC_BASE_RPC_PORT)

            num_blocks = 500
            logging.info('Mining %d Bitcoin blocks to %s', num_blocks,
                         cls.btc_addr)
            callnoderpc(0,
                        'generatetoaddress', [num_blocks, cls.btc_addr],
                        base_rpc_port=BTC_BASE_RPC_PORT)

            checkForks(
                callnoderpc(0,
                            'getblockchaininfo',
                            base_rpc_port=BTC_BASE_RPC_PORT))

            logging.info('Starting update thread.')
            signal.signal(signal.SIGINT, signal_handler)
            cls.update_thread = threading.Thread(target=run_loop, args=(cls, ))
            cls.update_thread.start()

            cls.coins_update_thread = threading.Thread(target=run_coins_loop,
                                                       args=(cls, ))
            cls.coins_update_thread.start()
        except Exception:
            traceback.print_exc()
            Test.tearDownClass()
            raise ValueError('setUpClass() failed.')
Example #6
0
    def setUpClass(cls):
        super(Test, cls).setUpClass()

        eckey = ECKey()
        eckey.generate()
        cls.network_key = toWIF(PREFIX_SECRET_KEY_REGTEST, eckey.get_bytes())
        cls.network_pubkey = eckey.get_pubkey().get_bytes().hex()

        if os.path.isdir(cfg.TEST_DATADIRS):
            logging.info('Removing ' + cfg.TEST_DATADIRS)
            shutil.rmtree(cfg.TEST_DATADIRS)

        for i in range(NUM_NODES):
            data_dir = prepareDir(cfg.TEST_DATADIRS, i, cls.network_key, cls.network_pubkey)
            callrpc_cli(cfg.PARTICL_BINDIR, data_dir, 'regtest', '-wallet=wallet.dat create', 'particl-wallet')  # Necessary for 0.21

        prepareOtherDir(cfg.TEST_DATADIRS, LTC_NODE)
        data_dir = prepareOtherDir(cfg.TEST_DATADIRS, BTC_NODE, 'bitcoin.conf')
        callrpc_cli(cfg.BITCOIN_BINDIR, data_dir, 'regtest', '-wallet=wallet.dat create', 'bitcoin-wallet')  # Necessary for 0.21

        cls.daemons = []
        cls.swap_clients = []
        cls.http_threads = []

        cls.daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, str(BTC_NODE)), cfg.BITCOIN_BINDIR, cfg.BITCOIND))
        logging.info('Started %s %d', cfg.BITCOIND, cls.daemons[-1].pid)
        cls.daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, str(LTC_NODE)), cfg.LITECOIN_BINDIR, cfg.LITECOIND))
        logging.info('Started %s %d', cfg.LITECOIND, cls.daemons[-1].pid)

        for i in range(NUM_NODES):
            cls.daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, str(i)), cfg.PARTICL_BINDIR, cfg.PARTICLD))
            logging.info('Started %s %d', cfg.PARTICLD, cls.daemons[-1].pid)

        for i in range(NUM_NODES):
            # Load mnemonics after all nodes have started to avoid staking getting stuck in TryToSync
            rpc = make_part_cli_rpc_func(i)
            waitForRPC(rpc)
            if i == 0:
                rpc('extkeyimportmaster', ['abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb'])
            elif i == 1:
                rpc('extkeyimportmaster', ['pact mammal barrel matrix local final lecture chunk wasp survey bid various book strong spread fall ozone daring like topple door fatigue limb olympic', '', 'true'])
                rpc('getnewextaddress', ['lblExtTest'])
                rpc('rescanblockchain')
            else:
                rpc('extkeyimportmaster', [rpc('mnemonic', ['new'])['master']])
            # Lower output split threshold for more stakeable outputs
            rpc('walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])

            basicswap_dir = os.path.join(os.path.join(cfg.TEST_DATADIRS, str(i)), 'basicswap')
            settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
            with open(settings_path) as fs:
                settings = json.load(fs)
            fp = open(os.path.join(basicswap_dir, 'basicswap.log'), 'w')
            sc = BasicSwap(fp, basicswap_dir, settings, 'regtest', log_name='BasicSwap{}'.format(i))
            sc.setDaemonPID(Coins.BTC, cls.daemons[0].pid)
            sc.setDaemonPID(Coins.LTC, cls.daemons[1].pid)
            sc.setDaemonPID(Coins.PART, cls.daemons[2 + i].pid)
            sc.start()
            cls.swap_clients.append(sc)

            t = HttpThread(cls.swap_clients[i].fp, TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, cls.swap_clients[i])
            cls.http_threads.append(t)
            t.start()

        waitForRPC(ltcRpc)
        num_blocks = 500
        logging.info('Mining %d litecoin blocks', num_blocks)
        cls.ltc_addr = ltcRpc('getnewaddress mining_addr legacy')
        ltcRpc('generatetoaddress {} {}'.format(num_blocks, cls.ltc_addr))

        ro = ltcRpc('getblockchaininfo')
        checkForks(ro)

        waitForRPC(btcRpc)
        cls.btc_addr = btcRpc('getnewaddress mining_addr bech32')
        logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr)
        btcRpc('generatetoaddress {} {}'.format(num_blocks, cls.btc_addr))

        ro = btcRpc('getblockchaininfo')
        checkForks(ro)

        ro = ltcRpc('getwalletinfo')
        print('ltcRpc', ro)

        signal.signal(signal.SIGINT, signal_handler)
        cls.update_thread = threading.Thread(target=run_loop, args=(cls,))
        cls.update_thread.start()

        cls.coins_update_thread = threading.Thread(target=run_coins_loop, args=(cls,))
        cls.coins_update_thread.start()

        # Wait for height, or sequencelock is thrown off by genesis blocktime
        num_blocks = 3
        logging.info('Waiting for Particl chain height %d', num_blocks)
        for i in range(60):
            particl_blocks = cls.swap_clients[0].callrpc('getblockchaininfo')['blocks']
            print('particl_blocks', particl_blocks)
            if particl_blocks >= num_blocks:
                break
            test_delay_event.wait(1)
        assert(particl_blocks >= num_blocks)
Example #7
0
def btcRpc(client_no, cmd):
    bin_path = os.path.join(test_path, 'bin', 'bitcoin')
    data_path = os.path.join(test_path, 'client{}'.format(client_no),
                             'bitcoin')
    return callrpc_cli(bin_path, data_path, 'regtest', cmd, 'bitcoin-cli')
Example #8
0
    def rpc_func(cmd):
        nonlocal bin_dir
        nonlocal data_dir
        nonlocal chain

        return callrpc_cli(bin_dir, data_dir, chain, cmd, cfg.PARTICL_CLI)
Example #9
0
def prepareDataDir(coin, settings, chain, particl_mnemonic):
    core_settings = settings['chainclients'][coin]
    bin_dir = core_settings['bindir']
    data_dir = core_settings['datadir']

    if not os.path.exists(data_dir):
        os.makedirs(data_dir)

    if coin == 'monero':
        core_conf_path = os.path.join(data_dir, coin + 'd.conf')
        if os.path.exists(core_conf_path):
            exitWithError('{} exists'.format(core_conf_path))
        with open(core_conf_path, 'w') as fp:
            if chain == 'regtest':
                fp.write('regtest=1\n')
                fp.write('keep-fakechain=1\n')
                fp.write('fixed-difficulty=1\n')
            else:
                fp.write('bootstrap-daemon-address=auto\n')
                fp.write('restricted-rpc=1\n')
            if chain == 'testnet':
                fp.write('testnet=1\n')
            fp.write('data-dir={}\n'.format(data_dir))
            fp.write('rpc-bind-port={}\n'.format(core_settings['rpcport']))
            fp.write('rpc-bind-ip=127.0.0.1\n')
            fp.write('zmq-rpc-bind-port={}\n'.format(core_settings['zmqport']))
            fp.write('zmq-rpc-bind-ip=127.0.0.1\n')
            fp.write('prune-blockchain=1\n')

        wallet_conf_path = os.path.join(data_dir, coin + '_wallet.conf')
        if os.path.exists(wallet_conf_path):
            exitWithError('{} exists'.format(wallet_conf_path))
        with open(wallet_conf_path, 'w') as fp:
            fp.write('daemon-address={}:{}\n'.format(core_settings['rpchost'],
                                                     core_settings['rpcport']))
            fp.write('no-dns=1\n')
            fp.write('rpc-bind-port={}\n'.format(
                core_settings['walletrpcport']))
            fp.write('wallet-dir={}\n'.format(os.path.join(
                data_dir, 'wallets')))
            fp.write('log-file={}\n'.format(
                os.path.join(data_dir, 'wallet.log')))
            fp.write('shared-ringdb-dir={}\n'.format(
                os.path.join(data_dir, 'shared-ringdb')))
            fp.write('rpc-login={}:{}\n'.format(
                core_settings['walletrpcuser'],
                core_settings['walletrpcpassword']))
        return
    core_conf_path = os.path.join(data_dir, coin + '.conf')
    if os.path.exists(core_conf_path):
        exitWithError('{} exists'.format(core_conf_path))
    with open(core_conf_path, 'w') as fp:
        if chain != 'mainnet':
            fp.write(chain + '=1\n')
            if chain == 'testnet':
                fp.write('[test]\n\n')
            if chain == 'regtest':
                fp.write('[regtest]\n\n')
            else:
                logger.warning('Unknown chain %s', chain)

        fp.write('rpcport={}\n'.format(core_settings['rpcport']))
        fp.write('printtoconsole=0\n')
        fp.write('daemon=0\n')
        fp.write('wallet=wallet.dat\n')

        if coin == 'particl':
            fp.write('debugexclude=libevent\n')
            fp.write('zmqpubsmsg=tcp://127.0.0.1:{}\n'.format(
                settings['zmqport']))
            fp.write('spentindex=1\n')
            fp.write('txindex=1\n')
            fp.write('staking=0\n')

            if particl_mnemonic == 'none':
                fp.write('createdefaultmasterkey=1')
        elif coin == 'litecoin':
            fp.write('prune=2000\n')
        elif coin == 'bitcoin':
            fp.write('prune=2000\n')
            fp.write('fallbackfee=0.0002\n')
        elif coin == 'namecoin':
            fp.write('prune=2000\n')
        else:
            logger.warning('Unknown coin %s', coin)

    wallet_util = coin + '-wallet'
    if os.path.exists(os.path.join(bin_dir, wallet_util)):
        logger.info('Creating wallet.dat for {}.'.format(
            wallet_util.capitalize()))
        callrpc_cli(bin_dir, data_dir, chain, '-wallet=wallet.dat create',
                    wallet_util)