Skip to content

Commit

Permalink
pyln-testing: add new schema types.
Browse files Browse the repository at this point in the history
These are useful for requests:
1. "outpoint": <txid>:<outnum>
2. "feerate": strings or a number
3. "outputdesc": bitcoin-style addresses-as-keys
4. "msat_or_all": amount or "all"
4. "msat_or_any": amount or "any"
5. "short_channel_id_dir": scid with /0 or /1.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Apr 1, 2022
1 parent 1b6f4e7 commit 3b11292
Showing 1 changed file with 72 additions and 0 deletions.
72 changes: 72 additions & 0 deletions contrib/pyln-testing/pyln/testing/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,48 @@ def is_short_channel_id(checker, instance):
and txnum >= 0 and txnum < 2**24
and outnum >= 0 and outnum < 2**16)

def is_short_channel_id_dir(checker, instance):
"""Short channel id with direction"""
if not checker.is_type(instance, "string"):
return False
if not instance.endswith("/0") and not instance.endswith("/1"):
return False
return is_short_channel_id(checker, instance[:-2])

def is_outpoint(checker, instance):
"""Outpoint: txid and outnum"""
if not checker.is_type(instance, "string"):
return False
parts = instance.split(":")
if len(parts) != 2:
return False
if len(parts[0]) != 64 or any(c not in string.hexdigits for c in parts[0]):
return False
try:
outnum = int(parts[1])
except ValueError:
return False
return outnum < 2**32

def is_feerate(checker, instance):
"""feerate string or number (optionally ending in perkw/perkb)"""
if checker.is_type(instance, "integer"):
return True
if not checker.is_type(instance, "string"):
return False
if instance in ("urgent", "normal", "slow"):
return True
if instance in ("opening", "mutual_close", "unilateral_close", "delayed_to_us", "htlc_resolution", "penalty", "min_acceptable", "max_acceptable"):
return True
if not instance.endswith("perkw") and not instance.endswith("perkb"):
return False

try:
int(instance.rpartition("per")[0])
except ValueError:
return False
return True

def is_pubkey(checker, instance):
"""SEC1 encoded compressed pubkey"""
if not checker.is_type(instance, "hex"):
Expand Down Expand Up @@ -308,6 +350,30 @@ def is_txid(checker, instance):
return False
return len(instance) == 64

def is_outputdesc(checker, instance):
"""Bitcoin-style output object, keys = destination, values = amount"""
if not checker.is_type(instance, "object"):
return False
for k, v in instance.items():
if not checker.is_type(k, "string"):
return False
if v != "all":
if not is_msat_request(checker, v):
return False
return True

def is_msat_or_all(checker, instance):
"""msat field, or 'all'"""
if instance == "all":
return True
return is_msat_request(checker, instance)

def is_msat_or_any(checker, instance):
"""msat field, or 'any'"""
if instance == "any":
return True
return is_msat_request(checker, instance)

type_checker = jsonschema.Draft7Validator.TYPE_CHECKER.redefine_many({
"hex": is_hex,
"u64": is_u64,
Expand All @@ -316,11 +382,17 @@ def is_txid(checker, instance):
"u8": is_u8,
"pubkey": is_pubkey,
"msat": is_msat,
"msat_or_all": is_msat_or_all,
"msat_or_any": is_msat_or_any,
"txid": is_txid,
"signature": is_signature,
"bip340sig": is_bip340sig,
"point32": is_point32,
"short_channel_id": is_short_channel_id,
"short_channel_id_dir": is_short_channel_id_dir,
"outpoint": is_outpoint,
"feerate": is_feerate,
"outputdesc": is_outputdesc,
})

return jsonschema.validators.extend(jsonschema.Draft7Validator,
Expand Down

0 comments on commit 3b11292

Please sign in to comment.