Skip to content

Commit d6213dd

Browse files
committed
Fix for later confirmations
1 parent 19a3723 commit d6213dd

File tree

7 files changed

+59
-17
lines changed

7 files changed

+59
-17
lines changed

node/blockchain/tests/base.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
from node.core.utils.cryptography import get_node_identifier
77

88

9-
@contextmanager
10-
def as_role(node_role: NodeRole):
9+
def make_node_as_role(node_identifier, node_role):
1110
next_block_number = BlockchainFacade.get_instance().get_next_block_number()
12-
node_identifier = get_node_identifier()
1311
if node_role == NodeRole.PRIMARY_VALIDATOR:
1412
Schedule.objects.update_or_create(_id=next_block_number, defaults={'node_identifier': node_identifier})
1513
elif node_role == NodeRole.CONFIRMATION_VALIDATOR:
@@ -20,4 +18,8 @@ def as_role(node_role: NodeRole):
2018
assert node_role == NodeRole.REGULAR_NODE
2119
Schedule.objects.filter(node_identifier=node_identifier).delete()
2220

21+
22+
@contextmanager
23+
def as_role(node_role: NodeRole):
24+
make_node_as_role(get_node_identifier(), node_role)
2325
yield

node/blockchain/tests/fixtures/account.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ def confirmation_validator_key_pair_2() -> KeyPair:
3636
)
3737

3838

39+
@pytest.fixture
40+
def confirmation_validator_key_pair_3() -> KeyPair:
41+
return KeyPair(
42+
public=AccountNumber('5db9a262236cc148fd2adf841dbe0967e9bfe77e5e482dc7e0ef0c59d7fb56cf'),
43+
private=SigningKey('67eb1838664e12d0773988618a1c69d90757dae5b9ea4e7c7e543b118f31aa55'),
44+
)
45+
46+
3947
@pytest.fixture
4048
def regular_node_key_pair() -> KeyPair:
4149
return KeyPair(

node/blockchain/tests/fixtures/node.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ def confirmation_validator_node_2(confirmation_validator_key_pair_2):
3737
)
3838

3939

40+
@pytest.fixture
41+
def confirmation_validator_node_3(confirmation_validator_key_pair_3):
42+
return make_node(
43+
confirmation_validator_key_pair_3,
44+
['http://not-existing-confirmation-validator-3-address-674898923.com:8555/']
45+
)
46+
47+
4048
@pytest.fixture
4149
def self_node(self_node_key_pair, test_server_address):
4250
return make_node(self_node_key_pair, ['http://not-existing-self-address-674898923.com:8555/', test_server_address])

node/blockchain/tests/test_rest_api/test_block_confirmation.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@
99

1010

1111
@pytest.mark.usefixtures('rich_blockchain', 'as_confirmation_validator')
12-
def test_send_confirmation_to_cv(confirmation_validator_key_pair_2, api_client):
12+
def test_send_confirmation_to_cv(next_block, confirmation_validator_key_pair_2, api_client):
1313
assert not ORMBlockConfirmation.objects.exists()
1414

15-
facade = BlockchainFacade.get_instance()
16-
assert facade.get_next_block_number() >= 4
17-
block = facade.get_block_by_number(4)
15+
block = next_block
16+
assert BlockchainFacade.get_instance().get_next_block_number() >= block.get_block_number()
1817

1918
hash_ = block.make_hash()
2019
block_confirmation = BlockConfirmation.create(

node/blockchain/tests/test_tasks/test_process_block_confirmations.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
get_consensus_block_hash_with_confirmations, get_next_block_confirmations, is_valid_consensus,
1111
process_block_confirmations_task, process_next_block
1212
)
13+
from node.blockchain.tests.base import make_node_as_role
1314
from node.blockchain.types import NodeRole
1415

1516

@@ -117,8 +118,11 @@ def test_process_block_confirmations_task():
117118

118119
@pytest.mark.usefixtures('rich_blockchain', 'as_confirmation_validator')
119120
def test_process_block_confirmations_integration(
120-
next_block, self_node_key_pair, confirmation_validator_key_pair, confirmation_validator_key_pair_2, api_client
121+
next_block, self_node_key_pair, confirmation_validator_key_pair, confirmation_validator_key_pair_2,
122+
confirmation_validator_key_pair_3, api_client
121123
):
124+
make_node_as_role(confirmation_validator_key_pair_3.public, NodeRole.CONFIRMATION_VALIDATOR)
125+
122126
facade = BlockchainFacade.get_instance()
123127
block_number = facade.get_next_block_number()
124128

@@ -137,17 +141,34 @@ def test_process_block_confirmations_integration(
137141
assert pending_block
138142
assert pending_block.body == payload
139143

144+
assert not BlockConfirmation.objects.all().exists()
140145
# TODO(dmu) CRITICAL: Remove artificial own confirmation
141146
# https://thenewboston.atlassian.net/browse/BC-263
142147
confirmation = PydanticBlockConfirmation.create_from_block(block, self_node_key_pair.private)
143148
BlockConfirmation.objects.create_from_block_confirmation(confirmation)
149+
assert BlockConfirmation.objects.all().exists()
144150

145151
# Create confirmations from other CVs
146-
for private_key in (confirmation_validator_key_pair.private, confirmation_validator_key_pair_2.private):
152+
counter = 1
153+
cv_keys = (
154+
confirmation_validator_key_pair.private, confirmation_validator_key_pair_2.private,
155+
confirmation_validator_key_pair_3.private
156+
)
157+
for private_key in cv_keys:
147158
confirmation = PydanticBlockConfirmation.create_from_block(block, private_key)
148159
payload = confirmation.json()
149160
response = api_client.post('/api/block-confirmations/', payload, content_type='application/json')
150-
assert response.status_code == 201
161+
162+
counter += 1
163+
if counter < 3:
164+
assert response.status_code == 201
165+
assert BlockConfirmation.objects.all().exists()
166+
elif counter == 3:
167+
assert response.status_code == 201
168+
assert not BlockConfirmation.objects.all().exists() # because of always eager
169+
else:
170+
assert response.status_code == 204
171+
assert not BlockConfirmation.objects.all().exists()
151172

152173
# Assert that block was added to the blockchain
153174
assert facade.get_next_block_number() == block_number + 1

node/blockchain/views/block_confirmation.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,18 @@ def create(self, request, *args, **kwargs):
1919

2020
facade = BlockchainFacade.get_instance()
2121
next_block_number = facade.get_next_block_number()
22-
is_next_block_number = block_confirmation.get_number() == next_block_number
23-
if is_next_block_number:
22+
block_confirmation_number = block_confirmation.get_number()
23+
if block_confirmation_number < next_block_number:
24+
return Response(status=status.HTTP_204_NO_CONTENT) # Block is already confirmed
25+
26+
if block_confirmation_number == next_block_number:
2427
block_confirmation.validate_all(facade)
2528
else:
2629
block_confirmation.validate_business_logic()
2730

2831
ORMBlockConfirmation.objects.update_or_create_from_block_confirmation(block_confirmation)
2932

30-
if is_next_block_number and (
33+
if block_confirmation_number == next_block_number and (
3134
ORMBlockConfirmation.objects.filter(number=next_block_number).count() >= facade.get_minimum_consensus()
3235
):
3336
apply_on_commit(start_process_block_confirmations_task)

node/core/tests/test_node_client.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,13 @@ def test_send_block_to_address_integration(
116116

117117

118118
@pytest.mark.usefixtures('rich_blockchain', 'as_confirmation_validator')
119-
def test_send_confirmation_to_cv(test_server_address, confirmation_validator_key_pair_2, smart_mocked_node_client):
119+
def test_send_confirmation_to_cv(
120+
next_block, test_server_address, confirmation_validator_key_pair_2, smart_mocked_node_client
121+
):
120122
assert not ORMBlockConfirmation.objects.exists()
121123

122-
facade = BlockchainFacade.get_instance()
123-
assert facade.get_next_block_number() >= 4
124-
block = facade.get_block_by_number(4)
124+
block = next_block
125+
assert BlockchainFacade.get_instance().get_next_block_number() >= block.get_block_number()
125126

126127
hash_ = block.make_hash()
127128
block_confirmation = BlockConfirmation.create(

0 commit comments

Comments
 (0)