Skip to content

Commit

Permalink
coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
richardkiss committed Jan 5, 2024
1 parent 6c67aba commit a0e6ef2
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 32 deletions.
2 changes: 1 addition & 1 deletion hsms/cmds/hsm_dump_us.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ def main(argv=sys.argv[1:]):
return hsms_dump_us(args, parser)


if __name__ == "__main__":
if __name__ == "__main__": # pragma: no cover
main()
2 changes: 1 addition & 1 deletion hsms/cmds/hsm_test_spend.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,5 @@ def main(argv=sys.argv[1:]):
return hsm_test_spend(args, parser)


if __name__ == "__main__":
if __name__ == "__main__": # pragma: no cover
main()
2 changes: 1 addition & 1 deletion hsms/cmds/hsmpk.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ def main(argv=sys.argv[1:]):
print(secret_exponent.public_key().as_bech32m())


if __name__ == "__main__":
if __name__ == "__main__": # pragma: no cover
main()
4 changes: 4 additions & 0 deletions hsms/core/unsigned_spend.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
from .signing_hints import PathHint, SumHint


# `CoinSpend` objects have the puzzle reveal and the puzzle hash (in the coin)
# which is a little redundant. Casting to `CSTuple` removes the redundant
# puzzle hash, saving 32 bytes when serialized.

CSTuple = Tuple[bytes, Program, int, Program]
SerdeCoinSpends = List[CSTuple]

Expand Down
7 changes: 4 additions & 3 deletions hsms/process/sign.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ def generate_synthetic_offset_signatures(us: UnsignedSpend) -> List[SignatureInf
secret_key = sum_hint.synthetic_offset
partial_public_key = secret_key.public_key()
signature = secret_key.sign(message, final_public_key)
if final_public_key == partial_public_key:
assert signature.verify([(partial_public_key, message)])
sig_info = SignatureInfo(
signature, partial_public_key, final_public_key, message
)
Expand Down Expand Up @@ -135,7 +133,10 @@ def verify_pairs_for_conditions(

agg_sig_unsafe_conditions = d.get(AGG_SIG_UNSAFE, [])
for condition in agg_sig_unsafe_conditions:
yield BLSPublicKey.from_bytes(condition.at("rf")), hexbytes(condition.at("rrf"))
yield (
BLSPublicKey.from_bytes(condition.at("rf").atom),
hexbytes(condition.at("rrf").atom),
)


def secret_key_for_public_key(
Expand Down
6 changes: 5 additions & 1 deletion hsms/util/byte_chunks.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class ChunkAssembler:
chunks: List[bytes]

def __init__(self, chunks=[]):
self.chunks = chunks
self.chunks = []
for chunk in chunks:
self.add_chunk(chunk)

def add_chunk(self, chunk: bytes):
if chunk in self.chunks:
Expand All @@ -66,6 +68,8 @@ def status(self) -> Tuple[int, int]:
return len(self.chunks), self.chunks[0][-1] + 1

def __bytes__(self) -> bytes:
if not self.is_assembled():
raise ValueError("insufficient chunks")
sorted_chunks = sorted(self.chunks, key=lambda c: c[-2])
bare_chunks = [c[:-2] for c in sorted_chunks]
return b"".join(bare_chunks)
Expand Down
6 changes: 1 addition & 5 deletions tests/legacy/clvm_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ def transform_dict(program, dict_transformer_f):
where the keys match the keys in d and the values of d are transformed
by invoking the corresponding values in xformer.
"""
try:
r = clvm_to_list(program, lambda x: dict_transformer_f(x.pair[0], x.pair[1]))
except Exception as ex:
print(ex)
breakpoint()
r = clvm_to_list(program, lambda x: dict_transformer_f(x.pair[0], x.pair[1]))
d = dict(r)
return d

Expand Down
2 changes: 0 additions & 2 deletions tests/test_clvm_serde.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,6 @@ class Baz(str):


def randbytes(r: random.Random, count: int) -> bytes:
if hasattr(r, "randbytes"):
return r.randbytes(count)
return bytes([r.randint(0, 255) for _ in range(count)])


Expand Down
10 changes: 5 additions & 5 deletions tests/test_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ def get_test_cases(path):
while 1:
line = f.readline().rstrip()
if len(line) < 1 or line[0] != "#":
if line[-1:] == "\\":
if line[-1:] == "\\": # pragma: no cover
cmd_lines.append(line[:-1])
continue
cmd_lines.append(line)
break
comments.append(line + "\n")
comments.append(line + "\n") # pragma: no cover
expected_output = f.read()
test_name = os.path.relpath(p, PREFIX).replace(".", "_").replace("/", "_")
test_cases.append((test_name, cmd_lines, expected_output, comments, p))
Expand Down Expand Up @@ -70,7 +70,7 @@ def f(self):
cmd = "".join(cmd_lines)
for c in cmd.split(";"):
r, actual_output, actual_stderr = self.invoke_tool(c)
if actual_output != expected_output:
if actual_output != expected_output: # pragma: no cover
print(path)
print(cmd)
print(actual_output)
Expand Down Expand Up @@ -100,11 +100,11 @@ def inject(*paths):
inject("cmds")


def main():
def main(): # pragma: no cover
unittest.main()


if __name__ == "__main__":
if __name__ == "__main__": # pragma: no cover
main()


Expand Down
105 changes: 105 additions & 0 deletions tests/test_coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# gratuitous coverage tests

import pathlib
import tempfile
import zlib

from clvm_rs import Program

from hsms.process.sign import verify_pairs_for_conditions
from hsms.puzzles.conlang import AGG_SIG_ME, AGG_SIG_UNSAFE
from hsms.puzzles.p2_delegated_puzzle_or_hidden_puzzle import (
calculate_synthetic_secret_key,
solution_for_hidden_puzzle,
)
from hsms.puzzles.p2_conditions import solution_for_conditions
from hsms.util.byte_chunks import (
blob_for_chunks,
blob_for_zlib_chunks,
create_chunks_for_blob,
ChunkAssembler,
)

import pytest

from .generate import bytes32_generate, se_generate, pk_generate


def test_cssk():
se = se_generate(1)
b32 = bytes32_generate(1)
xse = 2483436177918370406060013642567697118387289473841058299688804535472357425177
assert int(calculate_synthetic_secret_key(se, b32)) == xse


def test_sfhp():
pk = pk_generate(1)
hp = Program.to("foobar")
sthp = Program.to("fake solve")
s = solution_for_hidden_puzzle(pk, hp, sthp)
ethh = "eca8c5557fe1c4929f8d3dd7a5551d023c9a6c4215e69ebe3eb55f84b5a25c95"
assert s.tree_hash().hex() == ethh


def test_sfc():
s = solution_for_conditions(Program.to("a bunch of conditions"))
ethh = "adabdc6a70925a06b1bd3e148d910793abf879de327adc1ff9ea405d72f29a48"
assert s.tree_hash().hex() == ethh


def test_byte_chunks():
blob = b"foo" * 10240
with pytest.raises(ValueError):
create_chunks_for_blob(blob, 5)

chunks_1 = create_chunks_for_blob(blob, 2000)
chunks_2 = create_chunks_for_blob(blob, 4000)
with pytest.raises(ValueError):
bogus_list = [chunks_1[0], chunks_2[0]]
blob_for_chunks(bogus_list)

with pytest.raises(ValueError):
bogus_c1 = bytearray(chunks_1[0])
bogus_c1[0] += 1
bogus_c1 = bytes(bogus_c1)
bogus_list = [chunks_1[0], bogus_c1]
blob_for_chunks(bogus_list)

ca = ChunkAssembler()
assert ca.status() == (0, 0)

c_blob = zlib.compress(blob)
out = blob_for_zlib_chunks(create_chunks_for_blob(c_blob, 1000))
assert out == blob

with pytest.raises(ValueError):
blob_for_chunks([chunks_1[0]])


def test_aggsig_me_conditions():
pk_1 = pk_generate(1)
pk_2 = pk_generate(2)
b32_1 = bytes32_generate(1)
b32_2 = bytes32_generate(2)
b32_3 = bytes32_generate(3)
conditions = Program.to(
[[AGG_SIG_ME, bytes(pk_1), b32_1], [AGG_SIG_UNSAFE, bytes(pk_2), b32_2]]
)
pairs = list(verify_pairs_for_conditions(conditions, b32_3))
msg1 = b32_1 + b32_3
msg2 = b32_2
assert pairs == [(pk_1, msg1), (pk_2, msg2)]


def test_hsms_dump_us():
# for some reason, if this import is move to the global scope,
# the `test_cmd` test fails. Maybe the stdout capture fails?
from hsms.cmds import hsm_dump_us

where = pathlib.Path(__file__)
d = (where.parent / "cmds" / "hsm_dump_us_1.txt").read_text()
hex_blob = d.split()[1]
with tempfile.NamedTemporaryFile("w") as f:
f.write(hex_blob)
f.flush()
hsm_dump_us.main([f.name])
13 changes: 0 additions & 13 deletions tests/test_qrint.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,3 @@ def test_b2a_qrint():
start = (MAX_SIZE - size) // 2
blob = BIG_BLOB[start : start + size]
check_b2a(blob)


def print_sizes():
long_blob = bytes([_ % 256 for _ in range(4000)])
d = []
for size in range(2, 96):
b = b2a_qrint_payload(long_blob, size)
bits_used = ((len(b) + 2) // 3) * 10
bytes_used = (bits_used + 7) // 8
print(len(b), size)
d.append((len(b), size, bytes_used))
d.sort()
print(d)

0 comments on commit a0e6ef2

Please sign in to comment.