mirror of
https://github.com/JoinMarket-Org/joinmarket-clientserver.git
synced 2026-08-13 12:33:40 +02:00
Update exit codes
Many exit codes were 0 (success) when they should have been 1 (general failure) or 2 (argument error). This corrects that. Related: #409
This commit is contained in:
parent
e4ba373ea6
commit
52108b62d8
15 changed files with 62 additions and 43 deletions
|
|
@ -8,6 +8,11 @@ from getpass import getpass
|
|||
# global Joinmarket constants
|
||||
JM_WALLET_NAME_PREFIX = "joinmarket-wallet-"
|
||||
|
||||
# Exit status codes
|
||||
EXIT_SUCCESS = 0
|
||||
EXIT_FAILURE = 1
|
||||
EXIT_ARGERROR = 2
|
||||
|
||||
from chromalog.log import (
|
||||
ColorizingStreamHandler,
|
||||
ColorizingFormatter,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ import jmbitcoin as btc
|
|||
|
||||
from jmclient.jsonrpc import JsonRpcConnectionError, JsonRpcError
|
||||
from jmclient.configure import jm_single
|
||||
from jmbase.support import get_log, jmprint
|
||||
from jmbase.support import get_log, jmprint, EXIT_SUCCESS, EXIT_FAILURE
|
||||
|
||||
|
||||
# an inaccessible blockheight; consider rewriting in 1900 years
|
||||
INF_HEIGHT = 10**8
|
||||
|
|
@ -227,7 +228,7 @@ class BitcoinCoreInterface(BlockchainInterface):
|
|||
restart_cb(fatal_msg)
|
||||
else:
|
||||
jmprint(fatal_msg, "important")
|
||||
sys.exit(1)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
|
||||
def add_watchonly_addresses(self, addr_list, wallet_name, restart_cb=None):
|
||||
"""For backwards compatibility, this fn name is preserved
|
||||
|
|
@ -247,7 +248,7 @@ class BitcoinCoreInterface(BlockchainInterface):
|
|||
restart_cb(restart_msg)
|
||||
else:
|
||||
jmprint(restart_msg, "important")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_SUCCESS)
|
||||
|
||||
def _yield_transactions(self, wallet_name):
|
||||
batch_size = 1000
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from jmbase import get_log
|
|||
from jmclient import (jm_single, get_irc_mchannels,
|
||||
RegtestBitcoinCoreInterface)
|
||||
import jmbitcoin as btc
|
||||
from jmbase.support import EXIT_FAILURE
|
||||
|
||||
jlog = get_log()
|
||||
|
||||
|
|
@ -556,7 +557,7 @@ def start_reactor(host, port, factory, ish=True, daemon=False, rs=True,
|
|||
jlog.warn("Cannot listen on port " + str(port) + ", trying next port")
|
||||
if port >= (orgport + 100):
|
||||
jlog.error("Tried 100 ports but cannot listen on any of them. Quitting.")
|
||||
sys.exit(1)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
port += 1
|
||||
else:
|
||||
# if daemon run separately, and we do p2ep, we are using
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ import sys
|
|||
import jmbitcoin as btc
|
||||
from jmbase import jmprint
|
||||
from jmclient import jm_single, get_p2pk_vbyte, get_p2sh_vbyte
|
||||
from jmbase.support import EXIT_FAILURE
|
||||
|
||||
|
||||
def quit(parser, errmsg): #pragma: no cover
|
||||
parser.error(errmsg)
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
|
||||
def get_utxo_info(upriv):
|
||||
"""Verify that the input string parses correctly as (utxo, priv)
|
||||
|
|
@ -66,4 +68,4 @@ def validate_utxo_data(utxo_datas, retrieve=False, segwit=False):
|
|||
jmprint('all utxos validated OK', "success")
|
||||
if retrieve:
|
||||
return results
|
||||
return True
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import jmbitcoin as btc
|
|||
from jmclient.wallet import estimate_tx_fee
|
||||
from jmclient.wallet_service import WalletService
|
||||
from jmclient.configure import jm_single
|
||||
from jmbase.support import get_log
|
||||
from jmbase.support import get_log, EXIT_SUCCESS, EXIT_FAILURE
|
||||
from jmclient.support import calc_cj_fee, select_one_utxo
|
||||
from jmclient.podle import verify_podle, PoDLE, PoDLEError
|
||||
from twisted.internet import task, reactor
|
||||
|
|
@ -48,7 +48,7 @@ class Maker(object):
|
|||
self.sync_wait_loop.stop()
|
||||
if not self.offerlist:
|
||||
jlog.info("Failed to create offers, giving up.")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
jlog.info('offerlist={}'.format(self.offerlist))
|
||||
|
||||
def on_auth_received(self, nick, offer, commitment, cr, amount, kphex):
|
||||
|
|
@ -339,7 +339,7 @@ class P2EPMaker(Maker):
|
|||
f.write("Amount (in sats): " + str(self.receiving_amount) + "\n")
|
||||
f.write("Receiver nick: " + jm_single().nickname + "\n")
|
||||
if not self.user_check("Enter 'y' to wait for the payment:"):
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_SUCCESS)
|
||||
|
||||
def create_my_orders(self):
|
||||
""" Fake offer for public consumption.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import struct
|
|||
from jmbase import jmprint
|
||||
from jmbitcoin import multiply, add_pubkeys, getG, podle_PublicKey,\
|
||||
podle_PrivateKey, encode, decode, N, podle_PublicKey_class
|
||||
from jmbase.support import EXIT_FAILURE
|
||||
|
||||
|
||||
PODLE_COMMIT_FILE = None
|
||||
|
|
@ -315,7 +316,7 @@ def update_commitments(commitment=None,
|
|||
#Exit conditions cannot be included in tests.
|
||||
jmprint("the file: " + PODLE_COMMIT_FILE + " is not valid json.",
|
||||
"error")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
|
||||
if 'used' in c:
|
||||
commitments = c['used']
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from .schedule import human_readable_schedule_entry, tweak_tumble_schedule,\
|
|||
schedule_to_text
|
||||
from .wallet import BaseWallet, estimate_tx_fee
|
||||
from jmbitcoin import deserialize, mktx, serialize, txhash, amount_to_str
|
||||
from jmbase.support import EXIT_SUCCESS
|
||||
log = get_log()
|
||||
|
||||
"""
|
||||
|
|
@ -141,7 +142,7 @@ def restart_wait(txid):
|
|||
return False
|
||||
if res["confirmations"] < 0:
|
||||
log.warn("Tx: " + txid + " has a conflict, abandoning.")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_SUCCESS)
|
||||
else:
|
||||
log.debug("Tx: " + str(txid) + " has " + str(
|
||||
res["confirmations"]) + " confirmations.")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ from jmclient import (get_network, WALLET_IMPLEMENTATIONS, Storage, podle,
|
|||
VolatileStorage, StoragePasswordError, is_segwit_mode, SegwitLegacyWallet,
|
||||
LegacyWallet, SegwitWallet, is_native_segwit_mode)
|
||||
from jmclient.wallet_service import WalletService
|
||||
from jmbase.support import get_password, jmprint
|
||||
from jmbase.support import get_password, jmprint, EXIT_FAILURE, EXIT_ARGERROR
|
||||
|
||||
from .cryptoengine import TYPE_P2PKH, TYPE_P2SH_P2WPKH, TYPE_P2WPKH
|
||||
from .output import fmt_utxo
|
||||
import jmbitcoin as btc
|
||||
|
|
@ -1218,11 +1219,11 @@ def wallet_tool_main(wallet_root_path):
|
|||
|
||||
if len(args) < 1:
|
||||
parser.error('Needs a wallet file or method')
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
|
||||
if options.mixdepth is not None and options.mixdepth < 0:
|
||||
parser.error("Must have at least one mixdepth.")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
|
||||
if args[0] in noseed_methods:
|
||||
method = args[0]
|
||||
|
|
@ -1263,7 +1264,7 @@ def wallet_tool_main(wallet_root_path):
|
|||
if not isinstance(jm_single().bc_interface, BitcoinCoreInterface):
|
||||
jmprint('showing history only available when using the Bitcoin Core ' +
|
||||
'blockchain interface', "error")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
else:
|
||||
return wallet_fetch_history(wallet_service, options)
|
||||
elif method == "generate":
|
||||
|
|
@ -1293,13 +1294,13 @@ def wallet_tool_main(wallet_root_path):
|
|||
return wallet_freezeutxo(wallet_service, options.mixdepth)
|
||||
else:
|
||||
parser.error("Unknown wallet-tool method: " + method)
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
|
||||
|
||||
#Testing (can port to test modules, TODO)
|
||||
if __name__ == "__main__":
|
||||
if not test_bip32_pathparse():
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
rootpath="m/0"
|
||||
walletbranch = 0
|
||||
accounts = range(3)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from jmclient import Maker, jm_single, load_program_config, \
|
|||
JMClientProtocolFactory, start_reactor, \
|
||||
calc_cj_fee, WalletService
|
||||
from .wallet_utils import open_test_wallet_maybe, get_wallet_path
|
||||
from jmbase.support import EXIT_ARGERROR
|
||||
|
||||
jlog = get_log()
|
||||
|
||||
|
|
@ -228,7 +229,7 @@ def ygmain(ygclass, txfee=1000, cjfee_a=200, cjfee_r=0.002, ordertype='swreloffe
|
|||
(options, args) = parser.parse_args()
|
||||
if len(args) < 1:
|
||||
parser.error('Needs a wallet')
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
wallet_name = args[0]
|
||||
ordertype = options.ordertype
|
||||
txfee = options.txfee
|
||||
|
|
@ -245,7 +246,7 @@ def ygmain(ygclass, txfee=1000, cjfee_a=200, cjfee_r=0.002, ordertype='swreloffe
|
|||
else:
|
||||
parser.error('You specified an incorrect offer type which ' +\
|
||||
'can be either swreloffer or swabsoffer')
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
nickserv_password = options.password
|
||||
|
||||
load_program_config()
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ from jmclient import load_program_config, jm_single, get_p2pk_vbyte,\
|
|||
open_wallet, WalletService, add_external_commitments, update_commitments,\
|
||||
PoDLE, get_podle_commitments, get_utxo_info, validate_utxo_data, quit,\
|
||||
get_wallet_path
|
||||
from jmbase.support import EXIT_SUCCESS, EXIT_FAILURE, EXIT_ARGERROR
|
||||
|
||||
|
||||
def add_ext_commitments(utxo_datas):
|
||||
|
|
@ -163,16 +164,16 @@ def main():
|
|||
if input("You have chosen to delete commitments, other arguments "
|
||||
"will be ignored; continue? (y/n)") != 'y':
|
||||
jmprint("Quitting", "warning")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_SUCCESS)
|
||||
c, e = get_podle_commitments()
|
||||
jmprint(pformat(e), "info")
|
||||
if input(
|
||||
"You will remove the above commitments; are you sure? (y/n): ") != 'y':
|
||||
jmprint("Quitting", "warning")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_SUCCESS)
|
||||
update_commitments(external_to_remove=e)
|
||||
jmprint("Commitments deleted.", "important")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_SUCCESS)
|
||||
|
||||
#Three options (-w, -r, -R) for loading utxo and privkey pairs from a wallet,
|
||||
#csv file or json file.
|
||||
|
|
@ -206,13 +207,13 @@ def main():
|
|||
elif options.in_json:
|
||||
if not os.path.isfile(options.in_json):
|
||||
jmprint("File: " + options.in_json + " not found.", "error")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
with open(options.in_json, "rb") as f:
|
||||
try:
|
||||
utxo_json = json.loads(f.read())
|
||||
except:
|
||||
jmprint("Failed to read json from " + options.in_json, "error")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
for u, pva in iteritems(utxo_json):
|
||||
utxo_data.append((u, pva['privkey']))
|
||||
elif len(args) == 1:
|
||||
|
|
@ -230,7 +231,7 @@ def main():
|
|||
if not validate_utxo_data(utxo_data, segwit=sw):
|
||||
quit(parser, "Utxos did not validate, quitting")
|
||||
if options.vonly:
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
|
||||
#We are adding utxos to the external list
|
||||
assert len(utxo_data)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from decimal import Decimal
|
|||
from optparse import OptionParser
|
||||
from twisted.internet import reactor
|
||||
|
||||
from jmbase.support import EXIT_FAILURE
|
||||
|
||||
|
||||
# https://stackoverflow.com/questions/2801882/generating-a-png-with-matplotlib-when-display-is-undefined
|
||||
|
|
@ -29,7 +30,7 @@ try:
|
|||
except:
|
||||
print("matplotlib not found; do `pip install matplotlib`"
|
||||
"in the joinmarket virtualenv.")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
|
||||
from jmbase import get_log
|
||||
from jmclient import jm_single, load_program_config, calc_cj_fee, get_irc_mchannels
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from jmclient import P2EPMaker, jm_single, load_program_config, \
|
|||
sync_wallet, JMClientProtocolFactory, start_reactor, \
|
||||
open_test_wallet_maybe, get_wallet_path
|
||||
from cli_options import check_regtest
|
||||
from jmbase.support import EXIT_FAILURE, EXIT_ARGERROR
|
||||
|
||||
jlog = get_log()
|
||||
|
||||
|
|
@ -45,16 +46,16 @@ def receive_payjoin_main(makerclass):
|
|||
(options, args) = parser.parse_args()
|
||||
if len(args) < 2:
|
||||
parser.error('Needs a wallet, and a receiving amount in satoshis')
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
wallet_name = args[0]
|
||||
try:
|
||||
receiving_amount = int(args[1])
|
||||
except:
|
||||
parser.error("Invalid receiving amount passed: " + receiving_amount)
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
if receiving_amount < 0:
|
||||
parser.error("Receiving amount must be a positive integer in satoshis")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
load_program_config()
|
||||
|
||||
check_regtest()
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ from jmclient import Taker, P2EPTaker, load_program_config, get_schedule,\
|
|||
estimate_tx_fee, direct_send, WalletService,\
|
||||
open_test_wallet_maybe, get_wallet_path
|
||||
from twisted.python.log import startLogging
|
||||
from jmbase.support import get_log, set_logging_level, jmprint
|
||||
from jmbase.support import get_log, set_logging_level, jmprint, \
|
||||
EXIT_FAILURE, EXIT_ARGERROR
|
||||
|
||||
from cli_options import get_sendpayment_parser, get_max_cj_fee_values, \
|
||||
check_regtest
|
||||
import jmbitcoin as btc
|
||||
|
|
@ -55,11 +57,11 @@ def main():
|
|||
if options.p2ep and len(args) != 3:
|
||||
parser.error("PayJoin requires exactly three arguments: "
|
||||
"wallet, amount and destination address.")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
elif options.schedule == '' and len(args) != 3:
|
||||
parser.error("Joinmarket sendpayment (coinjoin) needs arguments:"
|
||||
" wallet, amount and destination address")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
|
||||
#without schedule file option, use the arguments to create a schedule
|
||||
#of a single transaction
|
||||
|
|
@ -73,18 +75,18 @@ def main():
|
|||
addr_valid, errormsg = validate_address(destaddr)
|
||||
if not addr_valid:
|
||||
jmprint('ERROR: Address invalid. ' + errormsg, "error")
|
||||
return
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
schedule = [[options.mixdepth, amount, options.makercount,
|
||||
destaddr, 0.0, 0]]
|
||||
else:
|
||||
if options.p2ep:
|
||||
parser.error("Schedule files are not compatible with PayJoin")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
result, schedule = get_schedule(options.schedule)
|
||||
if not result:
|
||||
log.error("Failed to load schedule file, quitting. Check the syntax.")
|
||||
log.error("Error was: " + str(schedule))
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
mixdepth = 0
|
||||
for s in schedule:
|
||||
if s[1] == 0:
|
||||
|
|
@ -167,7 +169,7 @@ def main():
|
|||
if wallet.get_txtype() == 'p2pkh':
|
||||
jmprint("Only direct sends (use -N 0) are supported for "
|
||||
"legacy (non-segwit) wallets.", "error")
|
||||
return
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
|
||||
def filter_orders_callback(orders_fees, cjamount):
|
||||
orders, total_cj_fee = orders_fees
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ from jmclient import Taker, load_program_config, get_schedule,\
|
|||
schedule_to_text, estimate_tx_fee, restart_waiter, WalletService,\
|
||||
get_tumble_log, tumbler_taker_finished_update,\
|
||||
tumbler_filter_orders_callback, validate_address
|
||||
from jmbase.support import get_log, jmprint
|
||||
from jmbase.support import get_log, jmprint, EXIT_SUCCESS, \
|
||||
EXIT_FAILURE, EXIT_ARGERROR
|
||||
from cli_options import get_tumbler_parser, get_max_cj_fee_values, \
|
||||
check_regtest
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ def main():
|
|||
options = vars(options)
|
||||
if len(args) < 1:
|
||||
jmprint('Error: Needs a wallet file', "error")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
load_program_config()
|
||||
|
||||
check_regtest()
|
||||
|
|
@ -62,7 +63,7 @@ def main():
|
|||
success, errmsg = validate_address(daddr)
|
||||
if not success:
|
||||
jmprint("Invalid destination address: " + daddr, "error")
|
||||
sys.exit(1)
|
||||
sys.exit(EXIT_ARGERROR)
|
||||
jmprint("Destination addresses: " + str(destaddrs), "important")
|
||||
#If the --restart flag is set we read the schedule
|
||||
#from the file, and filter out entries that are
|
||||
|
|
@ -74,7 +75,7 @@ def main():
|
|||
jmprint("Failed to load schedule, name: " + str(
|
||||
options['schedulefile']), "error")
|
||||
jmprint("Error was: " + str(schedule), "error")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
#This removes all entries that are marked as done
|
||||
schedule = [s for s in schedule if s[5] != 1]
|
||||
# remaining destination addresses must be stored in Taker.tdestaddrs
|
||||
|
|
@ -85,7 +86,7 @@ def main():
|
|||
" so passed destinations on the command line were ignored.",
|
||||
"important")
|
||||
if input("OK? (y/n)") != "y":
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_SUCCESS)
|
||||
destaddrs = [s[3] for s in schedule if s[3] not in ["INTERNAL", "addrask"]]
|
||||
jmprint("Remaining destination addresses in restart: " + ",".join(destaddrs),
|
||||
"important")
|
||||
|
|
@ -100,7 +101,7 @@ def main():
|
|||
schedule = schedule[1:]
|
||||
elif schedule[0][5] != 0:
|
||||
print("Error: first schedule entry is invalid.")
|
||||
sys.exit(0)
|
||||
sys.exit(EXIT_FAILURE)
|
||||
with open(os.path.join(logsdir, options['schedulefile']), "wb") as f:
|
||||
f.write(schedule_to_text(schedule))
|
||||
tumble_log.info("TUMBLE RESTARTING")
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ def help():
|
|||
"`--client-bitcoin` - using joinmarket bitcoin code, installs secp256k1\n"
|
||||
"`--develop` - uses the local code for all packages (does not install to site-packages)."
|
||||
)
|
||||
sys.exit(0)
|
||||
sys.exit(2)
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
help()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue