Skip to content

feat: update consensus ABI to v0.5 IConsensusMain interface#64

Open
MuncleUscles wants to merge 4 commits intomainfrom
feat/v0.5-abi-updates
Open

feat: update consensus ABI to v0.5 IConsensusMain interface#64
MuncleUscles wants to merge 4 commits intomainfrom
feat/v0.5-abi-updates

Conversation

@MuncleUscles
Copy link
Member

@MuncleUscles MuncleUscles commented Feb 9, 2026

Summary

  • Replace consensus_main_abi.json with v0.5 IConsensusMain interface ABI (27 events, updated functions)
  • Add valid_until parameter to addTransaction encoder (default 0 = no expiry)
  • Add valid_until to decoder output for round-trip compatibility
  • Update actions.py to pass valid_until through the encoding pipeline

Test plan

  • All 36 unit tests pass
  • Verify addTransaction signature matches v0.5: addTransaction(address,address,uint256,uint256,bytes,uint256)
  • Verify backward compatibility with default valid_until=0

Summary by CodeRabbit

  • New Features

    • Added transaction validity expiration support with a new valid_until parameter for encoding and decoding transaction data.
    • Updated consensus contract interface with restructured events and refined function signatures.
  • Chores

    • Updated testnet WebSocket endpoint configuration to point to the genlayer testnet.
  • Tests

    • Added comprehensive test coverage for consensus contract read-only operations and transaction data encoding/decoding validation.

- Replace consensus_main_abi.json with v0.5 IConsensusMain ABI
- Add valid_until parameter to addTransaction encoder/decoder
- Update actions.py to pass valid_until (default 0 = no expiry)
@coderabbitai
Copy link

coderabbitai bot commented Feb 10, 2026

Warning

Rate limit exceeded

@MuncleUscles has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 18 minutes and 56 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

The PR updates the consensus contract ABI with major event and function signature refactoring, adds valid_until parameter support throughout the transaction encoding/decoding pipeline, updates the testnet WebSocket endpoint configuration, and introduces new smoke tests for consensus contract interactions and encoder/decoder round-trip validation.

Changes

Cohort / File(s) Summary
ABI and Encoding/Decoding
genlayer_py/consensus/abi/consensus_main_abi.json, genlayer_py/consensus/consensus_main/decoder.py, genlayer_py/consensus/consensus_main/encoder.py
Major ABI restructuring: event signatures renamed (e.g., OwnableInvalidOwnerActivatorReplaced, AppealStartedAllVotesCommitted), function parameters updated (e.g., addTransaction now includes _operator, _calldata, _validUntil), and getter functions refactored (e.g., getAddressManager returns single address vs. struct). Encoder/decoder updated to handle new valid_until field in transaction data encoding/decoding pipeline.
Contract Actions
genlayer_py/contracts/actions.py
Updated _encode_add_transaction_data method signature to include optional valid_until parameter with default value for backward compatibility.
Configuration
genlayer_py/chains/testnet_asimov.py
Updated TESTNET_WS_URL from alpha testnet endpoint to genlayer testnet endpoint.
Tests
tests/unit/smoke/test_testnet_smoke.py
Added two new test classes: TestConsensusContractReadOnly for consensus contract read-only operations and TestEncoderDecoderRoundTrip for transaction encoding/decoding round-trip validation including call and deploy transaction paths.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • cristiam86
  • kstroobants

Poem

🐰 The consensus grows with structured grace,
Events renamed to find their place,
Valid\_until bounds the time,
Encoding flows in perfect rhyme,
Tests confirm the round-trip dance!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating the consensus ABI to v0.5 IConsensusMain interface, which is reflected in the major ABI restructuring and related encoder/decoder updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/v0.5-abi-updates

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@tests/unit/smoke/test_testnet_smoke.py`:
- Around line 90-91: The TestEncoderDecoderRoundTrip class is incorrectly marked
with `@pytest.mark.testnet` even though it only runs local encode/decode logic;
remove the decorator so these tests run by default. Locate the
TestEncoderDecoderRoundTrip class definition and delete the `@pytest.mark.testnet`
line (or move any necessary markers to individual network-dependent tests),
ensuring the class and its methods remain unchanged so encoder/decoder coverage
runs in the standard pytest suite.
- Around line 94-131: Add assertions to verify the new valid_until field
round-trips through encode_add_transaction_data and decode_add_transaction_data:
in test_round_trip_call (and similarly test_round_trip_deploy) assert
decoded["valid_until"] == 0 for the default case, and add a new test (or extend)
that calls encode_add_transaction_data with valid_until=1234567890 then
decode_add_transaction_data and assert decoded["valid_until"] == 1234567890;
reference encode_add_transaction_data, decode_add_transaction_data,
test_round_trip_call, and test_round_trip_deploy to locate the places to add
these assertions.
🧹 Nitpick comments (2)
genlayer_py/contracts/actions.py (1)

242-263: valid_until is plumbed internally but not exposed in the public API.

The _encode_add_transaction_data function now accepts valid_until, but neither write_contract (Line 115) nor deploy_contract (Line 151) forward this parameter to callers. Users cannot set a non-zero expiry through the public API. If this is intentional for an incremental rollout, consider adding a TODO or tracking issue. Otherwise, propagate valid_until through write_contract and deploy_contract.

♻️ Example: expose valid_until in write_contract
 def write_contract(
     self: GenLayerClient,
     address: Union[Address, ChecksumAddress],
     function_name: str,
     account: Optional[LocalAccount] = None,
     consensus_max_rotations: Optional[int] = None,
     value: int = 0,
     leader_only: bool = False,
     args: Optional[List[CalldataEncodable]] = None,
     kwargs: Optional[Dict[str, CalldataEncodable]] = None,
     sim_config: Optional[SimConfig] = None,
+    valid_until: int = 0,
 ):
     ...
     encoded_data = _encode_add_transaction_data(
         self=self,
         sender_account=sender_account,
         recipient=address,
         consensus_max_rotations=consensus_max_rotations,
         data=serialized_data,
+        valid_until=valid_until,
     )

Apply the same pattern to deploy_contract.

tests/unit/smoke/test_testnet_smoke.py (1)

42-52: Consider using a fixture to avoid repeated Web3 instantiation.

Each test in TestTestnetConnectivity creates a fresh Web3(Web3.HTTPProvider(...)) instance. A class-scoped fixture would reduce duplication and connection overhead.

♻️ Proposed refactor
 `@pytest.mark.testnet`
 class TestTestnetConnectivity:
     """Verify RPC connectivity to testnet. Run with: pytest -m testnet"""

+    `@pytest.fixture`(autouse=True)
+    def setup(self):
+        self.w3 = Web3(Web3.HTTPProvider(TESTNET_JSON_RPC_URL))
+
     def test_rpc_connects(self):
-        w3 = Web3(Web3.HTTPProvider(TESTNET_JSON_RPC_URL))
-        assert w3.is_connected()
+        assert self.w3.is_connected()

     def test_chain_id_matches(self):
-        w3 = Web3(Web3.HTTPProvider(TESTNET_JSON_RPC_URL))
-        assert w3.eth.chain_id == 4221
+        assert self.w3.eth.chain_id == 4221

     def test_block_number_positive(self):
-        w3 = Web3(Web3.HTTPProvider(TESTNET_JSON_RPC_URL))
-        assert w3.eth.block_number > 0
+        assert self.w3.eth.block_number > 0

Comment on lines +90 to +91
@pytest.mark.testnet
class TestEncoderDecoderRoundTrip:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

TestEncoderDecoderRoundTrip is marked @pytest.mark.testnet but doesn't use the network.

These tests perform purely local encode/decode operations and don't require testnet connectivity. Marking them testnet means they won't run in the default test suite (pytest without -m testnet), reducing coverage of the encoder/decoder logic in CI.

Remove the @pytest.mark.testnet marker so these tests run by default.

Proposed fix
-@pytest.mark.testnet
 class TestEncoderDecoderRoundTrip:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@pytest.mark.testnet
class TestEncoderDecoderRoundTrip:
class TestEncoderDecoderRoundTrip:
🤖 Prompt for AI Agents
In `@tests/unit/smoke/test_testnet_smoke.py` around lines 90 - 91, The
TestEncoderDecoderRoundTrip class is incorrectly marked with
`@pytest.mark.testnet` even though it only runs local encode/decode logic; remove
the decorator so these tests run by default. Locate the
TestEncoderDecoderRoundTrip class definition and delete the `@pytest.mark.testnet`
line (or move any necessary markers to individual network-dependent tests),
ensuring the class and its methods remain unchanged so encoder/decoder coverage
runs in the standard pytest suite.

Comment on lines +94 to +131
def test_round_trip_call(self):
from genlayer_py.consensus.consensus_main.encoder import (
encode_add_transaction_data,
encode_tx_data_call,
)
from genlayer_py.consensus.consensus_main.decoder import (
decode_add_transaction_data,
)

sender = "0xABcdEFABcdEFabcdEfAbCdefAbCdEFaBcDEFabCD"
recipient = "0x1111111111111111111111111111111111111111"
num_validators = 7
max_rotations = 2

tx_data = encode_tx_data_call(
function_name="my_method",
leader_only=True,
args=["hello"],
kwargs={"key": "value"},
)

encoded = encode_add_transaction_data(
sender_address=sender,
recipient_address=recipient,
num_of_initial_validators=num_validators,
max_rotations=max_rotations,
tx_data=tx_data.hex() if isinstance(tx_data, bytes) else tx_data,
)

decoded = decode_add_transaction_data(encoded)
assert decoded["sender_address"].lower() == sender.lower()
assert decoded["recipient_address"].lower() == recipient.lower()
assert decoded["num_of_initial_validators"] == num_validators
assert decoded["max_rotations"] == max_rotations
assert decoded["tx_data"]["decoded"]["call_data"]["method"] == "my_method"
assert decoded["tx_data"]["decoded"]["leader_only"] is True
assert decoded["tx_data"]["decoded"]["type"] == "call"

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Round-trip tests don't assert valid_until.

The valid_until field is the primary addition in this PR, but neither test_round_trip_call nor test_round_trip_deploy asserts its value after decoding. Add an assertion to verify the round-trip of valid_until (both default 0 and a non-zero value).

Proposed addition for test_round_trip_call
         assert decoded["tx_data"]["decoded"]["leader_only"] is True
         assert decoded["tx_data"]["decoded"]["type"] == "call"
+        assert decoded["valid_until"] == 0

Consider also adding a test case with a non-zero valid_until to exercise the new parameter end-to-end:

    def test_round_trip_call_with_valid_until(self):
        # ... same setup ...
        encoded = encode_add_transaction_data(
            sender_address=sender,
            recipient_address=recipient,
            num_of_initial_validators=num_validators,
            max_rotations=max_rotations,
            tx_data=tx_data.hex() if isinstance(tx_data, bytes) else tx_data,
            valid_until=1234567890,
        )
        decoded = decode_add_transaction_data(encoded)
        assert decoded["valid_until"] == 1234567890
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_round_trip_call(self):
from genlayer_py.consensus.consensus_main.encoder import (
encode_add_transaction_data,
encode_tx_data_call,
)
from genlayer_py.consensus.consensus_main.decoder import (
decode_add_transaction_data,
)
sender = "0xABcdEFABcdEFabcdEfAbCdefAbCdEFaBcDEFabCD"
recipient = "0x1111111111111111111111111111111111111111"
num_validators = 7
max_rotations = 2
tx_data = encode_tx_data_call(
function_name="my_method",
leader_only=True,
args=["hello"],
kwargs={"key": "value"},
)
encoded = encode_add_transaction_data(
sender_address=sender,
recipient_address=recipient,
num_of_initial_validators=num_validators,
max_rotations=max_rotations,
tx_data=tx_data.hex() if isinstance(tx_data, bytes) else tx_data,
)
decoded = decode_add_transaction_data(encoded)
assert decoded["sender_address"].lower() == sender.lower()
assert decoded["recipient_address"].lower() == recipient.lower()
assert decoded["num_of_initial_validators"] == num_validators
assert decoded["max_rotations"] == max_rotations
assert decoded["tx_data"]["decoded"]["call_data"]["method"] == "my_method"
assert decoded["tx_data"]["decoded"]["leader_only"] is True
assert decoded["tx_data"]["decoded"]["type"] == "call"
def test_round_trip_call(self):
from genlayer_py.consensus.consensus_main.encoder import (
encode_add_transaction_data,
encode_tx_data_call,
)
from genlayer_py.consensus.consensus_main.decoder import (
decode_add_transaction_data,
)
sender = "0xABcdEFABcdEFabcdEfAbCdefAbCdEFaBcDEFabCD"
recipient = "0x1111111111111111111111111111111111111111"
num_validators = 7
max_rotations = 2
tx_data = encode_tx_data_call(
function_name="my_method",
leader_only=True,
args=["hello"],
kwargs={"key": "value"},
)
encoded = encode_add_transaction_data(
sender_address=sender,
recipient_address=recipient,
num_of_initial_validators=num_validators,
max_rotations=max_rotations,
tx_data=tx_data.hex() if isinstance(tx_data, bytes) else tx_data,
)
decoded = decode_add_transaction_data(encoded)
assert decoded["sender_address"].lower() == sender.lower()
assert decoded["recipient_address"].lower() == recipient.lower()
assert decoded["num_of_initial_validators"] == num_validators
assert decoded["max_rotations"] == max_rotations
assert decoded["tx_data"]["decoded"]["call_data"]["method"] == "my_method"
assert decoded["tx_data"]["decoded"]["leader_only"] is True
assert decoded["tx_data"]["decoded"]["type"] == "call"
assert decoded["valid_until"] == 0
🤖 Prompt for AI Agents
In `@tests/unit/smoke/test_testnet_smoke.py` around lines 94 - 131, Add assertions
to verify the new valid_until field round-trips through
encode_add_transaction_data and decode_add_transaction_data: in
test_round_trip_call (and similarly test_round_trip_deploy) assert
decoded["valid_until"] == 0 for the default case, and add a new test (or extend)
that calls encode_add_transaction_data with valid_until=1234567890 then
decode_add_transaction_data and assert decoded["valid_until"] == 1234567890;
reference encode_add_transaction_data, decode_add_transaction_data,
test_round_trip_call, and test_round_trip_deploy to locate the places to add
these assertions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant