mirror of
https://github.com/basicswap/basicswap.git
synced 2025-11-05 10:28:10 +01:00
Merge pull request #371 from tecnovert/createoffers
scripts: remove default values occluding error
This commit is contained in:
@@ -11968,9 +11968,10 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
strategy = self.queryOne(
|
strategy = self.queryOne(
|
||||||
AutomationStrategy, cursor, {"record_id": strategy_id}
|
AutomationStrategy, cursor, {"record_id": strategy_id}
|
||||||
)
|
)
|
||||||
|
if strategy is None:
|
||||||
|
raise ValueError("AutomationStrategy not found.")
|
||||||
if "data" in data:
|
if "data" in data:
|
||||||
strategy.data = json.dumps(data["data"]).encode("UTF-8")
|
strategy.data = json.dumps(data["data"]).encode("UTF-8")
|
||||||
self.log.debug("data {}".format(data["data"]))
|
|
||||||
if "note" in data:
|
if "note" in data:
|
||||||
strategy.note = data["note"]
|
strategy.note = data["note"]
|
||||||
if "label" in data:
|
if "label" in data:
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ Create offers
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "0.3"
|
__version__ = "0.4"
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
@@ -90,6 +90,7 @@ delay_event = threading.Event()
|
|||||||
shutdown_in_progress = False
|
shutdown_in_progress = False
|
||||||
coins_map = {}
|
coins_map = {}
|
||||||
read_json_api = None
|
read_json_api = None
|
||||||
|
read_json_api_wallet = None
|
||||||
|
|
||||||
DEFAULT_CONFIG_FILE: str = "createoffers.json"
|
DEFAULT_CONFIG_FILE: str = "createoffers.json"
|
||||||
DEFAULT_STATE_FILE: str = "createoffers_state.json"
|
DEFAULT_STATE_FILE: str = "createoffers_state.json"
|
||||||
@@ -206,42 +207,6 @@ def make_json_api_func(host: str, port: int, auth_string: str = None):
|
|||||||
return api_func
|
return api_func
|
||||||
|
|
||||||
|
|
||||||
def read_json_api_wallet(path):
|
|
||||||
"""Read wallet data from API with error handling"""
|
|
||||||
try:
|
|
||||||
wallet_data = read_json_api(path)
|
|
||||||
|
|
||||||
# Check if wallet_data is a valid dictionary response
|
|
||||||
if not isinstance(wallet_data, dict):
|
|
||||||
# Return safe defaults if response is not a dictionary (e.g., error string)
|
|
||||||
return {
|
|
||||||
"balance": "0",
|
|
||||||
"unconfirmed": "0",
|
|
||||||
"anon_balance": "0",
|
|
||||||
"blind_balance": "0",
|
|
||||||
}
|
|
||||||
|
|
||||||
default_wallet = {
|
|
||||||
"balance": "0",
|
|
||||||
"unconfirmed": "0",
|
|
||||||
"anon_balance": "0",
|
|
||||||
"blind_balance": "0",
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, default_value in default_wallet.items():
|
|
||||||
if key not in wallet_data:
|
|
||||||
wallet_data[key] = default_value
|
|
||||||
|
|
||||||
return wallet_data
|
|
||||||
except Exception:
|
|
||||||
return {
|
|
||||||
"balance": "0",
|
|
||||||
"unconfirmed": "0",
|
|
||||||
"anon_balance": "0",
|
|
||||||
"blind_balance": "0",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def signal_handler(sig, _) -> None:
|
def signal_handler(sig, _) -> None:
|
||||||
global shutdown_in_progress
|
global shutdown_in_progress
|
||||||
os.write(
|
os.write(
|
||||||
@@ -706,30 +671,25 @@ def process_offers(args, config, script_state) -> None:
|
|||||||
coin_from_data = coins_map[offer_template["coin_from"]]
|
coin_from_data = coins_map[offer_template["coin_from"]]
|
||||||
coin_to_data = coins_map[offer_template["coin_to"]]
|
coin_to_data = coins_map[offer_template["coin_to"]]
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
if args.debug:
|
|
||||||
print(f"Coin not found in coins_map: {e}")
|
|
||||||
else:
|
|
||||||
print(f"Skipping {offer_template['name']} - coin not available")
|
print(f"Skipping {offer_template['name']} - coin not available")
|
||||||
|
if args.debug:
|
||||||
|
print(f"Error: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
wallet_from = read_json_api_wallet(
|
|
||||||
"wallets/{}".format(coin_from_data["ticker"])
|
|
||||||
)
|
|
||||||
|
|
||||||
coin_ticker = coin_from_data["ticker"]
|
coin_ticker = coin_from_data["ticker"]
|
||||||
|
|
||||||
coin_from_data_name = offer_template["coin_from"]
|
coin_from_data_name = offer_template["coin_from"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
wallet_from = read_json_api_wallet(f"wallets/{coin_ticker}")
|
||||||
if coin_ticker == "PART":
|
if coin_ticker == "PART":
|
||||||
if "variant" in coin_from_data:
|
if "variant" in coin_from_data:
|
||||||
coin_variant = coin_from_data["variant"]
|
coin_variant = coin_from_data["variant"]
|
||||||
if coin_variant == "Anon":
|
if coin_variant == "Anon":
|
||||||
wallet_balance = float(wallet_from.get("anon_balance", 0))
|
wallet_balance = float(wallet_from["anon_balance"])
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(f"Using anon balance: {wallet_balance}")
|
print(f"Using anon balance: {wallet_balance}")
|
||||||
elif coin_variant == "Blind":
|
elif coin_variant == "Blind":
|
||||||
wallet_balance = float(wallet_from.get("blind_balance", 0))
|
wallet_balance = float(wallet_from["blind_balance"])
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(f"Using blind balance: {wallet_balance}")
|
print(f"Using blind balance: {wallet_balance}")
|
||||||
else:
|
else:
|
||||||
@@ -737,19 +697,18 @@ def process_offers(args, config, script_state) -> None:
|
|||||||
f"{coin_ticker} variant {coin_variant} not handled"
|
f"{coin_ticker} variant {coin_variant} not handled"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
wallet_balance = float(wallet_from.get("balance", 0))
|
wallet_balance = float(wallet_from["balance"])
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(f"Using regular balance: {wallet_balance}")
|
print(f"Using regular balance: {wallet_balance}")
|
||||||
else:
|
else:
|
||||||
wallet_balance = float(wallet_from.get("balance", 0))
|
wallet_balance = float(wallet_from["balance"])
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(f"Using balance for {coin_ticker}: {wallet_balance}")
|
print(f"Using balance for {coin_ticker}: {wallet_balance}")
|
||||||
except (KeyError, TypeError, ValueError) as e:
|
except (KeyError, TypeError, ValueError) as e:
|
||||||
if args.debug:
|
|
||||||
print(f"Error getting wallet balance for {coin_ticker}: {e}")
|
|
||||||
print(f"Wallet data: {wallet_from}")
|
|
||||||
else:
|
|
||||||
print(f"Skipping {offer_template['name']} - wallet balance unavailable")
|
print(f"Skipping {offer_template['name']} - wallet balance unavailable")
|
||||||
|
if args.debug:
|
||||||
|
print(f"coin_ticker {coin_ticker}, error: {e}")
|
||||||
|
print(f"Wallet data: {wallet_from}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for offer in sent_offers:
|
for offer in sent_offers:
|
||||||
@@ -1446,8 +1405,8 @@ def process_bids(args, config, script_state) -> None:
|
|||||||
"wallets/{}".format(coin_from_data["ticker"])
|
"wallets/{}".format(coin_from_data["ticker"])
|
||||||
)
|
)
|
||||||
|
|
||||||
wallet_balance = float(wallet_from.get("balance", 0)) + float(
|
wallet_balance = float(wallet_from["balance"]) + float(
|
||||||
wallet_from.get("unconfirmed", 0)
|
wallet_from["unconfirmed"]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get minimum amount from the offer
|
# Get minimum amount from the offer
|
||||||
@@ -1675,6 +1634,7 @@ def process_bids(args, config, script_state) -> None:
|
|||||||
print(f"Reduced bid amount to {bid_amount}")
|
print(f"Reduced bid amount to {bid_amount}")
|
||||||
swap_amount_to = adjusted_bid_amount * offer_rate
|
swap_amount_to = adjusted_bid_amount * offer_rate
|
||||||
|
|
||||||
|
if total_balance_to - swap_amount_to < min_coin_to_balance:
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(
|
print(
|
||||||
f"Bid amount would exceed minimum coin to wallet total for offer {offer_id}"
|
f"Bid amount would exceed minimum coin to wallet total for offer {offer_id}"
|
||||||
|
|||||||
@@ -249,15 +249,26 @@ class Test(unittest.TestCase):
|
|||||||
"--debug",
|
"--debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Set defaults
|
||||||
|
post_json = {
|
||||||
|
"set_data": json.dumps({"exact_rate_only": True, "max_concurrent_bids": 5}),
|
||||||
|
}
|
||||||
|
for i in range(3):
|
||||||
|
waitForServer(cls.delay_event, UI_PORT + i)
|
||||||
|
for j in range(1, 3):
|
||||||
|
json_rv = read_json_api(
|
||||||
|
UI_PORT + i, f"automationstrategies/{j}", post_json
|
||||||
|
)
|
||||||
|
assert json_rv["data"]["max_concurrent_bids"] == 5
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
logging.info("Stopping test")
|
logging.info("Stopping test")
|
||||||
cls.thread_http.stop()
|
cls.thread_http.stop()
|
||||||
|
|
||||||
def test_enabled(self):
|
def test_enabled(self):
|
||||||
|
for i in range(2):
|
||||||
waitForServer(self.delay_event, UI_PORT + 0)
|
waitForServer(self.delay_event, UI_PORT + i)
|
||||||
waitForServer(self.delay_event, UI_PORT + 1)
|
|
||||||
|
|
||||||
# Test no 'Processing...' messages are shown without config
|
# Test no 'Processing...' messages are shown without config
|
||||||
node0_test_config = {}
|
node0_test_config = {}
|
||||||
@@ -318,9 +329,8 @@ class Test(unittest.TestCase):
|
|||||||
assert count_lines_with(rv_stdout, "Processing 0 bid templates") == 1
|
assert count_lines_with(rv_stdout, "Processing 0 bid templates") == 1
|
||||||
|
|
||||||
def test_offers(self):
|
def test_offers(self):
|
||||||
|
for i in range(2):
|
||||||
waitForServer(self.delay_event, UI_PORT + 0)
|
waitForServer(self.delay_event, UI_PORT + i)
|
||||||
waitForServer(self.delay_event, UI_PORT + 1)
|
|
||||||
|
|
||||||
# Reset test
|
# Reset test
|
||||||
clear_offers(self.delay_event, 0)
|
clear_offers(self.delay_event, 0)
|
||||||
@@ -410,6 +420,7 @@ class Test(unittest.TestCase):
|
|||||||
"max_coin_from_balance": -1,
|
"max_coin_from_balance": -1,
|
||||||
"min_coin_to_balance": -1,
|
"min_coin_to_balance": -1,
|
||||||
"max_concurrent": 4,
|
"max_concurrent": 4,
|
||||||
|
"offers_to_bid_on": "all", # !?
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"coin_from": "PART",
|
"coin_from": "PART",
|
||||||
@@ -421,6 +432,7 @@ class Test(unittest.TestCase):
|
|||||||
"min_swap_amount": 0.1,
|
"min_swap_amount": 0.1,
|
||||||
"max_coin_from_balance": -1,
|
"max_coin_from_balance": -1,
|
||||||
"min_coin_to_balance": -1,
|
"min_coin_to_balance": -1,
|
||||||
|
"offers_to_bid_on": "all", # !?
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@@ -553,7 +565,6 @@ class Test(unittest.TestCase):
|
|||||||
result = subprocess.run(self.node1_args, stdout=subprocess.PIPE)
|
result = subprocess.run(self.node1_args, stdout=subprocess.PIPE)
|
||||||
rv_stdout = result.stdout.decode().split("\n")
|
rv_stdout = result.stdout.decode().split("\n")
|
||||||
possible_bids = get_possible_bids(rv_stdout)
|
possible_bids = get_possible_bids(rv_stdout)
|
||||||
possible_bids = get_possible_bids(rv_stdout)
|
|
||||||
assert len(possible_bids) == 1
|
assert len(possible_bids) == 1
|
||||||
assert float(possible_bids[0]["amount_from"]) < 20.0
|
assert float(possible_bids[0]["amount_from"]) < 20.0
|
||||||
|
|
||||||
@@ -581,8 +592,8 @@ class Test(unittest.TestCase):
|
|||||||
assert count_lines_with(rv_stdout, "too many failed bids") == 1
|
assert count_lines_with(rv_stdout, "too many failed bids") == 1
|
||||||
|
|
||||||
def test_offer_amount_step(self):
|
def test_offer_amount_step(self):
|
||||||
waitForServer(self.delay_event, UI_PORT + 0)
|
for i in range(2):
|
||||||
waitForServer(self.delay_event, UI_PORT + 1)
|
waitForServer(self.delay_event, UI_PORT + i)
|
||||||
|
|
||||||
# Reset test
|
# Reset test
|
||||||
clear_offers(self.delay_event, 0)
|
clear_offers(self.delay_event, 0)
|
||||||
@@ -645,8 +656,8 @@ class Test(unittest.TestCase):
|
|||||||
assert len(get_created_offers(rv_stdout)) == 1
|
assert len(get_created_offers(rv_stdout)) == 1
|
||||||
|
|
||||||
def test_error_messages(self):
|
def test_error_messages(self):
|
||||||
waitForServer(self.delay_event, UI_PORT + 0)
|
for i in range(2):
|
||||||
waitForServer(self.delay_event, UI_PORT + 1)
|
waitForServer(self.delay_event, UI_PORT + i)
|
||||||
|
|
||||||
# Reset test
|
# Reset test
|
||||||
clear_offers(self.delay_event, 0)
|
clear_offers(self.delay_event, 0)
|
||||||
@@ -678,15 +689,14 @@ class Test(unittest.TestCase):
|
|||||||
rv_stdout = result.stdout.decode().split("\n")
|
rv_stdout = result.stdout.decode().split("\n")
|
||||||
assert (
|
assert (
|
||||||
count_lines_with(
|
count_lines_with(
|
||||||
rv_stdout, "Error: Server failed to create offer: To amount above max"
|
rv_stdout, "Server failed to create offer: To amount above max"
|
||||||
)
|
)
|
||||||
== 1
|
== 1
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_bid_tracking(self):
|
def test_bid_tracking(self):
|
||||||
|
for i in range(2):
|
||||||
waitForServer(self.delay_event, UI_PORT + 0)
|
waitForServer(self.delay_event, UI_PORT + i)
|
||||||
waitForServer(self.delay_event, UI_PORT + 1)
|
|
||||||
|
|
||||||
# Reset test
|
# Reset test
|
||||||
clear_offers(self.delay_event, 0)
|
clear_offers(self.delay_event, 0)
|
||||||
@@ -870,10 +880,8 @@ class Test(unittest.TestCase):
|
|||||||
assert bid["addr_from"] == addr_bid_from
|
assert bid["addr_from"] == addr_bid_from
|
||||||
|
|
||||||
def test_auto_accept(self):
|
def test_auto_accept(self):
|
||||||
|
for i in range(3):
|
||||||
waitForServer(self.delay_event, UI_PORT + 0)
|
waitForServer(self.delay_event, UI_PORT + i)
|
||||||
waitForServer(self.delay_event, UI_PORT + 1)
|
|
||||||
waitForServer(self.delay_event, UI_PORT + 2)
|
|
||||||
|
|
||||||
logging.info("Reset test")
|
logging.info("Reset test")
|
||||||
clear_offers(self.delay_event, 0)
|
clear_offers(self.delay_event, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user