Browse Source

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
master
cindiv 6 years ago
parent
commit
52108b62d8
  1. 5
      jmbase/jmbase/support.py
  2. 7
      jmclient/jmclient/blockchaininterface.py
  3. 3
      jmclient/jmclient/client_protocol.py
  4. 6
      jmclient/jmclient/commitment_utils.py
  5. 6
      jmclient/jmclient/maker.py
  6. 3
      jmclient/jmclient/podle.py
  7. 3
      jmclient/jmclient/taker_utils.py
  8. 13
      jmclient/jmclient/wallet_utils.py
  9. 5
      jmclient/jmclient/yieldgenerator.py
  10. 13
      scripts/add-utxo.py
  11. 3
      scripts/obwatch/ob-watcher.py
  12. 7
      scripts/receive-payjoin.py
  13. 16
      scripts/sendpayment.py
  14. 13
      scripts/tumbler.py
  15. 2
      setupall.py

5
jmbase/jmbase/support.py

@ -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,

7
jmclient/jmclient/blockchaininterface.py

@ -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

3
jmclient/jmclient/client_protocol.py

@ -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
jmclient/jmclient/commitment_utils.py

@ -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

6
jmclient/jmclient/maker.py

@ -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.

3
jmclient/jmclient/podle.py

@ -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']

3
jmclient/jmclient/taker_utils.py

@ -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.")

13
jmclient/jmclient/wallet_utils.py

@ -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)

5
jmclient/jmclient/yieldgenerator.py

@ -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()

13
scripts/add-utxo.py

@ -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)

3
scripts/obwatch/ob-watcher.py

@ -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

7
scripts/receive-payjoin.py

@ -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()

16
scripts/sendpayment.py

@ -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

13
scripts/tumbler.py

@ -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")

2
setupall.py

@ -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…
Cancel
Save