Repository navigation
fix: bare except catches SystemExit; silent address fallback #1764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v0.123-dev
Are you sure you want to change the base?
Changes from all commits
9702d45
c4d0666
ebefab0
7813b03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,18 +6,26 @@ | |
| def get_validators_for_transaction( | ||
| nodes: list[dict], | ||
| num_validators: int | None = None, | ||
| rng=np.random.default_rng(seed=int(datetime.now().timestamp())), | ||
| rng: np.random.Generator | None = None, | ||
| ) -> list[dict]: | ||
| """ | ||
| Returns subset of validators for a transaction. | ||
| The selelction and order is given by a random sampling based on the stake of the validators. | ||
| """ | ||
| if rng is None: | ||
| rng = np.random.default_rng(seed=int(datetime.now().timestamp())) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🛡️ Analyzed with Security Review | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🤖 get_repo_knowledge executed:
Length of output: 4999 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- backend/consensus/vrf.py ---'
sed -n '1,120p' backend/consensus/vrf.py
printf '%s\n' '--- backend/consensus/base.py:20-35 ---'
sed -n '20,35p' backend/consensus/base.py
printf '%s\n' '--- backend/consensus/base.py:1310-1345 ---'
sed -n '1310,1345p' backend/consensus/base.py
printf '%s\n' '--- backend/consensus/base.py:1405-1422 ---'
sed -n '1405,1422p' backend/consensus/base.py
printf '%s\n' '--- backend/consensus/base.py:1945-2042 ---'
sed -n '1945,2042p' backend/consensus/base.py
printf '%s\n' '--- VRF-related symbols and imports ---'
rg -n --glob '*.py' 'VRF|vrf|rng=|get_validators_for_transaction' backend tests | head -120Repository: genlayerlabs/genlayer-studio Length of output: 11280 🏁 Script executed: #!/bin/bash
set -eu
sed -n '1,120p' backend/consensus/vrf.py
printf '\n--- callers ---\n'
sed -n '20,35p' backend/consensus/base.py
sed -n '1310,1345p' backend/consensus/base.py
sed -n '1405,1422p' backend/consensus/base.py
sed -n '1945,2042p' backend/consensus/base.py
printf '\n--- related symbols ---\n'
rg -n --glob '*.py' 'VRF|vrf|rng=|get_validators_for_transaction' backend tests | head -120Repository: genlayerlabs/genlayer-studio Length of output: 11077 Weak Cryptography Reachability: Internal Pass consensus VRF output to validator selection.
🤖 Prompt for AI Agents |
||
|
|
||
| if num_validators is None: | ||
| num_validators = DEFAULT_VALIDATORS_COUNT | ||
|
|
||
| num_validators = min(num_validators, len(nodes)) | ||
|
|
||
| total_stake = sum(validator["stake"] for validator in nodes) | ||
| if total_stake == 0: | ||
| raise ValueError( | ||
| "Cannot select validators: all stakes are zero. " | ||
| "At least one validator must have a positive stake." | ||
| ) | ||
| probabilities = [validator["stake"] / total_stake for validator in nodes] | ||
|
|
||
| selected_validators = rng.choice( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| from backend.consensus.vrf import get_validators_for_transaction | ||
| from unittest.mock import Mock | ||
| import pytest | ||
|
|
||
|
|
||
| def list_of_dicts_to_set(list_of_dicts: list[dict]) -> set: | ||
|
|
@@ -66,3 +67,21 @@ def choice_mock(a, p, size, replace): | |
|
|
||
| rng.choice.assert_called_once() | ||
| assert validators == [{"stake": 3}, {"stake": 2}, {"stake": 1}] | ||
|
|
||
|
|
||
| def test_get_validators_zero_stake_raises(): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Add return type annotations to the test functions. Add Also applies to: 79-79 🤖 Prompt for AI AgentsSource: Coding guidelines |
||
| """When all stakes are zero, selection should raise ValueError.""" | ||
| nodes = [{"stake": 0}, {"stake": 0}] | ||
| with pytest.raises(ValueError, match="all stakes are zero"): | ||
| get_validators_for_transaction(nodes, 1) | ||
|
|
||
|
|
||
| def test_get_validators_rng_not_shared_between_calls(): | ||
| """Each call without an explicit rng should get a fresh generator.""" | ||
| nodes = [{"stake": 1}, {"stake": 2}, {"stake": 3}] | ||
| # Call twice without passing rng — the default must be created fresh each time. | ||
| v1 = get_validators_for_transaction(nodes, 1) | ||
| v2 = get_validators_for_transaction(nodes, 1) | ||
| # Both should succeed (no shared mutable state corruption). | ||
| assert len(v1) == 1 | ||
| assert len(v2) == 1 | ||
|
Comment on lines
+83
to
+87
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Make the RNG isolation test distinguish generator reuse. Both calls return one validator when the RNG is shared. This assertion therefore passes with the previous mutable default RNG. Spy on 🤖 Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Handle the nullable factory result.
For a non-
SENDtransaction with a legacy snapshot and an invalidto_address,contract_snapshot_factoryreturnsNone. The hydration path then readsfresh.balanceand can raiseAttributeError. Make the factory and itsCallableannotations returnContractSnapshot | None, then handleNoneinTransactionContextbefore reading.balance.🤖 Prompt for AI Agents