diff --git a/scripts/joinmarket-qt.py b/scripts/joinmarket-qt.py index 39a0e3aeb..d869e69f0 100755 --- a/scripts/joinmarket-qt.py +++ b/scripts/joinmarket-qt.py @@ -2449,6 +2449,8 @@ def onTabChange(i): mainWindow.resize(600, 500) if get_network() == 'testnet': suffix = ' - Testnet' +elif get_network() == 'testnet4': + suffix = ' - Testnet4' elif get_network() == 'signet': suffix = ' - Signet' else: diff --git a/scripts/qtsupport.py b/scripts/qtsupport.py index c900178cf..134bdd222 100644 --- a/scripts/qtsupport.py +++ b/scripts/qtsupport.py @@ -61,7 +61,7 @@ 'absurd_fee_per_kb': 'amount'} config_tips = { 'blockchain_source': 'options: bitcoin-rpc, regtest (for testing)', - 'network': 'one of "signet", "testnet" or "mainnet"', + 'network': 'one of "signet", "testnet", "testnet4" or "mainnet"', 'checktx': 'whether to check fees before completing transaction', 'rpc_host': 'the host for bitcoind; only used if blockchain_source is bitcoin-rpc', diff --git a/src/jmbitcoin/secp256k1_deterministic.py b/src/jmbitcoin/secp256k1_deterministic.py index eb4fa3dbd..5c3050c6f 100644 --- a/src/jmbitcoin/secp256k1_deterministic.py +++ b/src/jmbitcoin/secp256k1_deterministic.py @@ -12,8 +12,10 @@ TESTNET_PUBLIC = b'\x04\x35\x87\xCF' SIGNET_PRIVATE = b'\x04\x35\x83\x94' SIGNET_PUBLIC = b'\x04\x35\x87\xCF' -PRIVATE = [MAINNET_PRIVATE, TESTNET_PRIVATE, SIGNET_PRIVATE] -PUBLIC = [MAINNET_PUBLIC, TESTNET_PUBLIC, SIGNET_PUBLIC] +TESTNET4_PRIVATE = b'\x04\x35\x83\x94' +TESTNET4_PUBLIC = b'\x04\x35\x87\xCF' +PRIVATE = [MAINNET_PRIVATE, TESTNET_PRIVATE, SIGNET_PRIVATE, TESTNET4_PRIVATE] +PUBLIC = [MAINNET_PUBLIC, TESTNET_PUBLIC, SIGNET_PUBLIC, TESTNET4_PUBLIC] privtopub = privkey_to_pubkey diff --git a/src/jmbitcoin/secp256k1_main.py b/src/jmbitcoin/secp256k1_main.py index 44204f920..68c9f8d7f 100644 --- a/src/jmbitcoin/secp256k1_main.py +++ b/src/jmbitcoin/secp256k1_main.py @@ -22,8 +22,9 @@ N = 115792089237316195423570985008687907852837564279074904382605163141518161494337 BTC_P2PK_VBYTE = {"mainnet": b'\x00', "testnet": b'\x6f', "signet": b'\x6f', - "regtest": 100} -BTC_P2SH_VBYTE = {"mainnet": b'\x05', "testnet": b'\xc4', "signet": b'\xc4'} + "regtest": 100, "testnet4": b'\x6f'} +BTC_P2SH_VBYTE = {"mainnet": b'\x05', "testnet": b'\xc4', "signet": b'\xc4', + "testnet4": b'\xc4'} """PoDLE related primitives """ diff --git a/src/jmclient/blockchaininterface.py b/src/jmclient/blockchaininterface.py index 3251eea26..af06b744b 100644 --- a/src/jmclient/blockchaininterface.py +++ b/src/jmclient/blockchaininterface.py @@ -342,7 +342,7 @@ def __init__(self, jsonRpc: JsonRpc, network: str, wallet_name: str) -> None: actualNet = blockchainInfo['chain'] netmap = {'main': 'mainnet', 'test': 'testnet', 'regtest': 'regtest', - 'signet': 'signet'} + 'signet': 'signet', 'testnet4': 'testnet4'} if netmap[actualNet] != network and \ (not (actualNet == "regtest" and network == "testnet")): #special case of regtest and testnet having the same addr format diff --git a/src/jmclient/configure.py b/src/jmclient/configure.py index 9a31a5e90..fcdfd562e 100644 --- a/src/jmclient/configure.py +++ b/src/jmclient/configure.py @@ -121,12 +121,13 @@ def jm_single() -> AttributeDict: # to Bitcoin Core; note that use of this option for any other purpose is currently unsupported. blockchain_source = bitcoin-rpc -# options: signet, testnet, mainnet +# options: signet, testnet, testnet4, mainnet # Note: for regtest, use network = testnet network = mainnet rpc_host = localhost -# default ports are 8332 for mainnet, 18443 for regtest, 18332 for testnet, 38332 for signet +# default ports are 8332 for mainnet, 18443 for regtest, 18332 for testnet, +# 38332 for signet, 48332 for testnet4 rpc_port = # Use either rpc_user / rpc_password pair or rpc_cookie_file. @@ -183,6 +184,9 @@ def jm_single() -> AttributeDict: # for SIGNET (testing network): # directory_nodes = rr6f6qtleiiwic45bby4zwmiwjrj3jsbmcvutwpqxjziaydjydkk5iad.onion:5222,k74oyetjqgcamsyhlym2vgbjtvhcrbxr4iowd4nv4zk5sehw4v665jad.onion:5222,y2ruswmdbsfl4hhwwiqz4m3sx6si5fr6l3pf62d4pms2b53wmagq3eqd.onion:5222 +# for TESTNET4 (testing network): +# directory_nodes = qibbq5s7come4ihuroa232pf2pf6kse4wsu3n753fjkyfn6bhyllhdyd.onion:5222 + # This setting is ONLY for developer regtest setups, # running multiple bots at once. Don't alter it otherwise regtest_count = 0,0 @@ -771,7 +775,7 @@ def load_program_config(config_path: str = "", bs: Optional[str] = None, "location cmtdata/commitments.json") if get_network() != "mainnet": # no need to be flexible for tests; note this is used - # for regtest, signet and testnet3 + # for regtest, signet, testnet3 and testnet4 global_singleton.commit_file_location = "cmtdata/" + get_network() + \ "_commitments.json" set_commitment_file(os.path.join(config_path, @@ -872,7 +876,7 @@ def get_blockchain_interface_instance(_config: ConfigParser): BitcoinCoreNoHistoryInterface source = _config.get("BLOCKCHAIN", "blockchain_source") network = get_network() - testnet = (network == 'testnet' or network == 'signet') + testnet = (network in ['testnet', 'testnet4', 'signet']) if source in ('bitcoin-rpc', 'regtest', 'bitcoin-rpc-no-history'): rpc_host = _config.get("BLOCKCHAIN", "rpc_host") @@ -884,6 +888,8 @@ def get_blockchain_interface_instance(_config: ConfigParser): rpc_port = 18443 elif network == 'testnet': rpc_port = 18332 + elif network == 'testnet4': + rpc_port = 48332 elif network == 'signet': rpc_port = 38332 else: diff --git a/src/jmclient/cryptoengine.py b/src/jmclient/cryptoengine.py index 065e3eeac..1ea73cbd7 100644 --- a/src/jmclient/cryptoengine.py +++ b/src/jmclient/cryptoengine.py @@ -17,11 +17,13 @@ TYPE_P2PKH, TYPE_P2SH_P2WPKH, TYPE_P2WPKH, TYPE_P2SH_M_N, TYPE_TIMELOCK_P2WSH, \ TYPE_SEGWIT_WALLET_FIDELITY_BONDS, TYPE_WATCHONLY_FIDELITY_BONDS, \ TYPE_WATCHONLY_TIMELOCK_P2WSH, TYPE_WATCHONLY_P2WPKH, TYPE_P2WSH, TYPE_P2TR = range(11) -NET_MAINNET, NET_TESTNET, NET_SIGNET = range(3) +NET_MAINNET, NET_TESTNET, NET_SIGNET, NET_TESTNET4 = range(4) NET_MAP = {'mainnet': NET_MAINNET, 'testnet': NET_TESTNET, - 'signet': NET_SIGNET} -WIF_PREFIX_MAP = {'mainnet': b'\x80', 'testnet': b'\xef', 'signet': b'\xef'} -BIP44_COIN_MAP = {'mainnet': 2**31, 'testnet': 2**31 + 1, 'signet': 2**31 + 1} + 'signet': NET_SIGNET, 'testnet4': NET_TESTNET4} +WIF_PREFIX_MAP = {'mainnet': b'\x80', 'testnet': b'\xef', 'signet': b'\xef', + 'testnet4': b'\xef'} +BIP44_COIN_MAP = {'mainnet': 2**31, 'testnet': 2**31 + 1, 'signet': 2**31 + 1, + 'testnet4': 2**31 + 1} BIP32_PUB_PREFIX = "xpub" BIP49_PUB_PREFIX = "ypub" diff --git a/src/jmclient/wallet.py b/src/jmclient/wallet.py index 5ac786fee..19bcc1932 100644 --- a/src/jmclient/wallet.py +++ b/src/jmclient/wallet.py @@ -416,7 +416,7 @@ def __init__(self, storage, gap_limit=6, merge_algorithm_name=None, assert self._cache is not None assert self.max_mixdepth is not None assert self.max_mixdepth >= 0 - assert self.network in ('mainnet', 'testnet', 'signet') + assert self.network in ('mainnet', 'testnet', 'signet', 'testnet4') if mixdepth is not None: assert mixdepth >= 0 @@ -479,12 +479,13 @@ def initialize(cls, storage, network, max_mixdepth=2, timestamp=None, args: storage: a Storage object - network: str, network we are on, 'mainnet', 'testnet' or 'signet' + network: str, network we are on, 'mainnet', 'testnet', 'signet' + or 'testnet4' max_mixdepth: int, number of the highest mixdepth timestamp: bytes or None, defaults to the current time write: execute storage.save() """ - assert network in ('mainnet', 'testnet', 'signet') + assert network in ('mainnet', 'testnet', 'signet', 'testnet4') assert max_mixdepth >= 0 if storage.data != {}: diff --git a/src/jmclient/yieldgenerator.py b/src/jmclient/yieldgenerator.py index 8be330771..d6a7873da 100644 --- a/src/jmclient/yieldgenerator.py +++ b/src/jmclient/yieldgenerator.py @@ -477,8 +477,8 @@ def ygmain(ygclass, nickserv_password='', gaplimit=6): if jm_single().config.get("BLOCKCHAIN", "network") == "mainnet": jlog.error("You have enabled SNICKER on mainnet, this is not " "yet supported for yieldgenerators; either use " - "signet/regtest/testnet, or run SNICKER manually " - "with snicker/receive-snicker.py.") + "signet/regtest/testnet/testnet4, or run SNICKER " + "manually with snicker/receive-snicker.py.") sys.exit(EXIT_ARGERROR) snicker_r = SNICKERReceiver(wallet_service) servers = jm_single().config.get("SNICKER", "servers").split(",") @@ -487,7 +487,8 @@ def ygmain(ygclass, nickserv_password='', gaplimit=6): snicker_factory = None nodaemon = jm_single().config.getint("DAEMON", "no_daemon") daemon = True if nodaemon == 1 else False - if jm_single().config.get("BLOCKCHAIN", "network") in ["regtest", "testnet", "signet"]: + if jm_single().config.get("BLOCKCHAIN", "network") in [ + "regtest", "testnet", "signet", "testnet4"]: startLogging(sys.stdout) start_reactor(jm_single().config.get("DAEMON", "daemon_host"), jm_single().config.getint("DAEMON", "daemon_port"), diff --git a/src/jmdaemon/irc.py b/src/jmdaemon/irc.py index 7b090f380..6039158e3 100644 --- a/src/jmdaemon/irc.py +++ b/src/jmdaemon/irc.py @@ -47,6 +47,8 @@ def get_config_irc_channel(chan_name, btcnet): channel = "#" + chan_name if btcnet == "testnet": channel += "-test" + elif btcnet == "testnet4": + channel += "-test4" elif btcnet == "signet": channel += "-sig" return channel