Skip to content
This repository was archived by the owner on Apr 16, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/test_suite/fixture_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,15 @@ def write_fixture_to_disk(
fixture.ParseFromString(serialized_fixture)

# Encode fields for instruction context and effects
context = harness_ctx.context_type()
context.CopyFrom(fixture.input)
# encode_input(context)
harness_ctx.context_human_encode_fn(context)
if harness_ctx.context_type is not None:
context = harness_ctx.context_type()
context.CopyFrom(fixture.input)
harness_ctx.context_human_encode_fn(context)
fixture.input.CopyFrom(context)

instr_effects = harness_ctx.effects_type()
instr_effects.CopyFrom(fixture.output)
harness_ctx.effects_human_encode_fn(instr_effects)

fixture.input.CopyFrom(context)
fixture.output.CopyFrom(instr_effects)

with open(output_dir / (file_stem + ".fix.txt"), "w") as f:
Expand Down Expand Up @@ -367,6 +366,9 @@ def regenerate_fixture(test_file: Path) -> int:
fixture = read_fixture(test_file)
harness_ctx = get_harness_for_entrypoint(fixture.metadata.fn_entrypoint)

if harness_ctx.context_type is None:
return # Scalar-input harnesses do not support feature regeneration

features_path = pb_utils.find_field_with_type(
harness_ctx.context_type.DESCRIPTOR, context_pb.FeatureSet.DESCRIPTOR
)
Expand Down
15 changes: 8 additions & 7 deletions src/test_suite/fuzz_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import test_suite.protos.invoke_pb2 as invoke_pb
import test_suite.protos.vm_pb2 as vm_pb
import test_suite.protos.block_pb2 as block_pb
import test_suite.protos.pack_pb2 as pack_pb

import test_suite.protos.gossip_pb2 as gossip_pb

import test_suite.block.codec_utils as block_codec
Expand Down Expand Up @@ -75,12 +75,6 @@
consensus_diff_effect_fn=txn_diff.consensus_txn_diff_effects,
)

PackComputeBudgetHarness = HarnessCtx(
fuzz_fn_name="sol_compat_pack_compute_budget_v1",
fixture_desc=pack_pb.PackComputeBudgetFixture.DESCRIPTOR,
context_extension=".packctx",
)

BlockHarness = HarnessCtx(
fuzz_fn_name="sol_compat_block_execute_v1",
fixture_desc=block_pb.BlockFixture.DESCRIPTOR,
Expand All @@ -100,6 +94,13 @@
effects_human_encode_fn=gossip_codec.encode_output,
)

GossipDecodeHarness = HarnessCtx(
fuzz_fn_name="sol_compat_gossip_decode_v1",
fixture_desc=gossip_pb.GossipFixture.DESCRIPTOR,
context_extension=".gossipdecodectx",
Comment thread
cmoyes-jump marked this conversation as resolved.
effects_human_encode_fn=gossip_codec.encode_effects,
)


ENTRYPOINT_HARNESS_MAP = {
obj.fuzz_fn_name: obj for obj in globals().values() if isinstance(obj, HarnessCtx)
Expand Down
11 changes: 8 additions & 3 deletions src/test_suite/fuzz_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,14 @@ class HarnessCtx:

def __post_init__(self, fixture_desc):
self.fixture_type = message_factory.GetMessageClass(fixture_desc)
self.context_type = message_factory.GetMessageClass(
fixture_desc.fields_by_name["input"].message_type
)
input_field = fixture_desc.fields_by_name["input"]
if input_field.message_type is not None:
self.context_type = message_factory.GetMessageClass(
input_field.message_type
)
else:
# Scalar input (e.g. bytes) - no message class to derive
self.context_type = None
Comment thread
cmoyes-jump marked this conversation as resolved.
self.effects_type = message_factory.GetMessageClass(
fixture_desc.fields_by_name["output"].message_type
)
Expand Down
5 changes: 5 additions & 0 deletions src/test_suite/gossip/codec_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ def decode_input(msg: gossip_pb.GossipMessageBinary):
def encode_output(effects: gossip_pb.AcceptsGossipMessage):
"""No-op: output is just a bool, already human-readable."""
pass


def encode_effects(effects: gossip_pb.GossipEffects):
"""No-op: GossipEffects fields are already human-readable."""
pass
7 changes: 6 additions & 1 deletion src/test_suite/multiprocessing_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ def read_context(harness_ctx: HarnessCtx, test_file: Path) -> message.Message |
Returns:
- message.Message | None: Instruction context, or None if reading failed.
"""
if harness_ctx.context_type is None:
return None

# Try to read in first as binary-encoded Protobuf messages
try:
# Read in binary Protobuf messages
Expand Down Expand Up @@ -440,8 +443,10 @@ def decode_single_test_case(test_file: Path) -> int:
# Encode the input fields to be human readable
if test_file.suffix == FIXTURE_EXTENSION:
output = harness_ctx.fixture_type()
else:
elif harness_ctx.context_type is not None:
output = harness_ctx.context_type()
else:
return 0

output.ParseFromString(serialized_protobuf)

Expand Down
44 changes: 43 additions & 1 deletion src/test_suite/protos/gossip_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 0 additions & 40 deletions src/test_suite/protos/pack_pb2.py

This file was deleted.

40 changes: 0 additions & 40 deletions src/test_suite/protos/shred_pb2.py

This file was deleted.

Loading