|
| 1 | +from typing import Collection |
| 2 | + |
1 | 3 | from djongo.models.fields import DjongoManager
|
2 | 4 |
|
3 | 5 | from node.blockchain.inner_models import Node as PydanticNode
|
| 6 | +from node.blockchain.types import NodeRole |
4 | 7 | from node.core.managers import CustomQuerySet
|
5 | 8 |
|
6 | 9 | from .account_state import AccountState
|
7 | 10 |
|
| 11 | +NODE_ROLES = set(NodeRole) |
| 12 | + |
| 13 | + |
| 14 | +class NodeQuerySet(CustomQuerySet): |
| 15 | + |
| 16 | + def filter_by_roles(self, roles: Collection[NodeRole]): |
| 17 | + # self.annotate() does not work with Djongo |
| 18 | + roles = set(roles or ()) |
| 19 | + if not roles or set(roles) == NODE_ROLES: |
| 20 | + return self |
| 21 | + |
| 22 | + from node.blockchain.models import Schedule |
| 23 | + |
| 24 | + assert {NodeRole.REGULAR_NODE, NodeRole.CONFIRMATION_VALIDATOR, NodeRole.PRIMARY_VALIDATOR} == NODE_ROLES |
| 25 | + |
| 26 | + next_block_schedule = Schedule.objects.get_schedule_for_next_block() |
| 27 | + primary_validator_identifier = next_block_schedule.node_identifier if next_block_schedule else None |
| 28 | + validator_identifiers = {item.node_identifier for item in Schedule.objects.all().order_by('_id')} |
| 29 | + if NodeRole.REGULAR_NODE in roles: |
| 30 | + if NodeRole.PRIMARY_VALIDATOR in roles: |
| 31 | + if NodeRole.CONFIRMATION_VALIDATOR in roles: |
| 32 | + raise AssertionError('Should have exited on previous shortcut guard condition') |
| 33 | + else: # regular and primary validator |
| 34 | + return self.exclude(_id__in=validator_identifiers - {primary_validator_identifier}) |
| 35 | + elif NodeRole.CONFIRMATION_VALIDATOR in roles: # regular and confirmation |
| 36 | + return self.exclude(_id=primary_validator_identifier) |
| 37 | + else: # only regular |
| 38 | + return self.exclude(_id__in=validator_identifiers) |
| 39 | + |
| 40 | + if NodeRole.PRIMARY_VALIDATOR in roles: |
| 41 | + if NodeRole.CONFIRMATION_VALIDATOR in roles: # only all validators |
| 42 | + return self.filter(_id__in=validator_identifiers) |
| 43 | + else: # only primary validator |
| 44 | + return self.filter(_id=primary_validator_identifier) |
| 45 | + elif NodeRole.CONFIRMATION_VALIDATOR in roles: # only confirmation validators |
| 46 | + return self.filter(_id__in=validator_identifiers - {primary_validator_identifier}) |
| 47 | + |
| 48 | + raise AssertionError('Should have exited on previous shortcut guard condition') |
| 49 | + |
8 | 50 |
|
9 |
| -class NodeManager(DjongoManager.from_queryset(CustomQuerySet)): # type: ignore |
| 51 | +class NodeManager(DjongoManager.from_queryset(NodeQuerySet)): # type: ignore |
10 | 52 |
|
11 | 53 | def get_queryset(self):
|
12 | 54 | return super().get_queryset().filter(node__isnull=False)
|
|
0 commit comments