Skip to content

Commit b7319ef

Browse files
author
Sergey Shilov
committed
Merge remote-tracking branch 'base/master' into feature/INDY-1205
2 parents 4945aba + b60f16f commit b7319ef

26 files changed

+863
-753
lines changed

plenum/common/constants.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
# ROLES
118118
STEWARD = Roles.STEWARD.value
119119
TRUSTEE = Roles.TRUSTEE.value
120+
STEWARD_STRING = 'STEWARD'
120121

121122
# TXNs
122123
NODE = PlenumTransactions.NODE.value
@@ -171,6 +172,7 @@ class LedgerState(IntEnum):
171172
POOL_LEDGER_ID = 0
172173
DOMAIN_LEDGER_ID = 1
173174
CONFIG_LEDGER_ID = 2
175+
INVALID_LEDGER_ID = 5908
174176

175177
VALID_LEDGER_IDS = (POOL_LEDGER_ID, DOMAIN_LEDGER_ID, CONFIG_LEDGER_ID)
176178

@@ -198,3 +200,6 @@ class ReplicaHooks(UniqueSet):
198200
RECV_PPR = 5
199201
RECV_PR = 6
200202
RECV_CM = 7
203+
204+
205+
INVALID_SEQ_NO = -23

plenum/common/exceptions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,19 @@ def __init__(self, expLen, actLen, *args, **kwargs):
280280
ex_txt = 'Message len {} exceeded allowed limit of {}'.format(
281281
actLen, expLen)
282282
super().__init__(ex_txt, *args, **kwargs)
283+
284+
285+
class RequestNackedException(Exception):
286+
pass
287+
288+
289+
class RequestRejectedException(Exception):
290+
pass
291+
292+
293+
class CommonSdkIOException(Exception):
294+
pass
295+
296+
297+
class PoolLedgerTimeoutException(Exception):
298+
pass

plenum/common/messages/fields.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ class NetworkPortField(FieldBase):
240240
_base_types = (int,)
241241

242242
def _specific_validation(self, val):
243-
if val < 0 or val > 65535:
243+
if val <= 0 or val > 65535:
244244
return 'network port out of the range 0-65535'
245245

246246

plenum/server/pool_req_handler.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def authErrorWhileAddingNode(self, request):
8080
origin)
8181
if self.stewardHasNode(origin):
8282
return "{} already has a node".format(origin)
83-
if self.isNodeDataConflicting(operation.get(DATA, {})):
83+
if self.isNodeDataConflicting(data):
8484
return "existing data has conflicts with " \
8585
"request data {}".format(operation.get(DATA))
8686

@@ -156,14 +156,14 @@ def isNodeDataSame(self, nodeNym, newData, isCommitted=True):
156156
nodeInfo.pop(f.IDENTIFIER.nm, None)
157157
return nodeInfo == newData
158158

159-
def isNodeDataConflicting(self, data, nodeNym=None):
159+
def isNodeDataConflicting(self, data, updatingNym=None):
160160
# Check if node's ALIAS or IPs or ports conflicts with other nodes,
161161
# also, the node is not allowed to change its alias.
162162

163163
# Check ALIAS change
164164
nodeData = {}
165-
if nodeNym:
166-
nodeData = self.getNodeData(nodeNym, isCommitted=False)
165+
if updatingNym:
166+
nodeData = self.getNodeData(updatingNym, isCommitted=False)
167167
if nodeData.get(ALIAS) != data.get(ALIAS):
168168
return True
169169
else:
@@ -177,7 +177,7 @@ def isNodeDataConflicting(self, data, nodeNym=None):
177177
otherNodeData = self.stateSerializer.deserialize(otherNodeData)
178178
otherNodeData.pop(f.IDENTIFIER.nm, None)
179179
otherNodeData.pop(SERVICES, None)
180-
if not nodeNym or otherNode != nodeNym:
180+
if not updatingNym or otherNode != updatingNym:
181181
# The node's ip, port and alias shuuld be unique
182182
bag = set()
183183
for d in (nodeData, otherNodeData):
@@ -191,6 +191,9 @@ def isNodeDataConflicting(self, data, nodeNym=None):
191191
if (not nodeData and len(bag) != 3) or (
192192
nodeData and len(bag) != 6):
193193
return True
194+
if data.get(ALIAS) == otherNodeData.get(
195+
ALIAS) and not updatingNym:
196+
return True
194197

195198
def dataErrorWhileValidatingUpdate(self, data, nodeNym):
196199
error = self.dataErrorWhileValidating(data, skipKeys=True)

plenum/test/batching_3pc/test_basic_batching.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import types
22
import pytest
3-
from plenum.common.exceptions import UnauthorizedClientRequest
3+
from plenum.common.exceptions import UnauthorizedClientRequest, RequestRejectedException
44
from plenum.test.batching_3pc.helper import checkNodesHaveSameRoots
5-
from plenum.test.helper import sendRandomRequests, checkRejectWithReason, waitForSufficientRepliesForRequests
5+
from plenum.test.helper import sdk_send_random_requests, sdk_get_and_check_replies
66
from stp_core.loop.eventually import eventually
77
from plenum.common.exceptions import InvalidClientRequest
88
from plenum.test.helper import sdk_sign_request_from_dict, sdk_send_random_and_check
99
from plenum.common.request import Request
1010

1111

12-
def testRequestStaticValidation(tconf, looper,txnPoolNodeSet,
12+
def testRequestStaticValidation(tconf, looper, txnPoolNodeSet,
1313
sdk_wallet_client):
1414
"""
1515
Check that for requests which fail static validation, REQNACK is sent
@@ -59,7 +59,7 @@ def testTreeRootsCorrectAfterEachBatch(tconf, looper, txnPoolNodeSet,
5959

6060

6161
def testRequestDynamicValidation(tconf, looper, txnPoolNodeSet,
62-
client, wallet1):
62+
sdk_pool_handle, sdk_wallet_client):
6363
"""
6464
Check that for requests which fail dynamic (state based) validation,
6565
REJECT is sent to the client
@@ -82,16 +82,14 @@ def rejectingMethod(self, req):
8282
origMethods.append(node.doDynamicValidation)
8383
node.doDynamicValidation = types.MethodType(rejectingMethod, node)
8484

85-
reqs = sendRandomRequests(wallet1, client, tconf.Max3PCBatchSize)
86-
waitForSufficientRepliesForRequests(looper, client, requests=reqs[:-1])
85+
reqs = sdk_send_random_requests(looper, sdk_pool_handle,
86+
sdk_wallet_client,
87+
tconf.Max3PCBatchSize)
88+
sdk_get_and_check_replies(looper, reqs[:-1])
89+
with pytest.raises(RequestRejectedException) as e:
90+
sdk_get_and_check_replies(looper, reqs[-1:])
8791

88-
with pytest.raises(AssertionError):
89-
waitForSufficientRepliesForRequests(looper, client, requests=reqs[-1:])
90-
91-
for node in txnPoolNodeSet:
92-
looper.run(eventually(checkRejectWithReason, client,
93-
'Simulated rejection', node.clientstack.name,
94-
retryWait=1))
92+
assert 'Simulated rejection' in e._excinfo[1].args[0]
9593

9694
for i, node in enumerate(txnPoolNodeSet):
9795
node.doDynamicValidation = origMethods[i]

plenum/test/batching_3pc/test_batch_rejection.py

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,20 @@
55
from stp_core.loop.eventually import eventually
66
from plenum.common.constants import DOMAIN_LEDGER_ID
77
from plenum.common.util import updateNamedTuple
8-
from plenum.test.helper import sendRandomRequests, \
9-
waitForSufficientRepliesForRequests
10-
from plenum.test.test_node import getNonPrimaryReplicas, getPrimaryReplica
8+
from plenum.test.helper import sdk_send_random_requests, \
9+
sdk_send_random_and_check
10+
from plenum.test.test_node import getNonPrimaryReplicas, \
11+
getPrimaryReplica
1112

1213

1314
@pytest.fixture(scope="module")
14-
def setup(tconf, looper, txnPoolNodeSet, client, wallet1):
15+
def setup(tconf, looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client):
1516
# Patch the 3phase request sending method to send incorrect digest and
1617
pr, otherR = getPrimaryReplica(txnPoolNodeSet, instId=0), \
17-
getNonPrimaryReplicas(txnPoolNodeSet, instId=0)
18-
19-
reqs = sendRandomRequests(wallet1, client, tconf.Max3PCBatchSize)
20-
waitForSufficientRepliesForRequests(
21-
looper,
22-
client,
23-
requests=reqs,
24-
customTimeoutPerReq=tconf.Max3PCBatchWait)
18+
getNonPrimaryReplicas(txnPoolNodeSet, instId=0)
19+
20+
sdk_send_random_and_check(looper, txnPoolNodeSet, sdk_pool_handle,
21+
sdk_wallet_client, tconf.Max3PCBatchSize)
2522
stateRoot = pr.stateRootHash(DOMAIN_LEDGER_ID, to_str=False)
2623

2724
origMethod = pr.create3PCBatch
@@ -36,7 +33,8 @@ def badMethod(self, ledgerId):
3633
return pp
3734

3835
pr.create3PCBatch = types.MethodType(badMethod, pr)
39-
sendRandomRequests(wallet1, client, tconf.Max3PCBatchSize)
36+
sdk_send_random_requests(looper, sdk_pool_handle, sdk_wallet_client,
37+
tconf.Max3PCBatchSize)
4038
return pr, otherR, stateRoot
4139

4240

@@ -75,15 +73,13 @@ def testViewChangeAfterBatchRejected(viewChanged):
7573
"""
7674

7775

78-
def testMoreBatchesWillBeSentAfterViewChange(reverted, viewChanged, wallet1,
79-
client, tconf, looper):
76+
def testMoreBatchesWillBeSentAfterViewChange(reverted, viewChanged,
77+
txnPoolNodeSet,
78+
sdk_pool_handle, sdk_wallet_client,
79+
tconf, looper):
8080
"""
8181
After retrying discarded batches, new batches are sent
8282
:return:
8383
"""
84-
reqs = sendRandomRequests(wallet1, client, tconf.Max3PCBatchSize)
85-
waitForSufficientRepliesForRequests(
86-
looper,
87-
client,
88-
requests=reqs,
89-
customTimeoutPerReq=tconf.Max3PCBatchWait)
84+
sdk_send_random_and_check(looper, txnPoolNodeSet, sdk_pool_handle,
85+
sdk_wallet_client, tconf.Max3PCBatchSize)

plenum/test/helper.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
from plenum.client.wallet import Wallet
2424
from plenum.common.constants import DOMAIN_LEDGER_ID, OP_FIELD_NAME, REPLY, REQACK, REQNACK, REJECT, \
2525
CURRENT_PROTOCOL_VERSION
26+
from plenum.common.exceptions import RequestNackedException, RequestRejectedException, CommonSdkIOException, \
27+
PoolLedgerTimeoutException
2628
from plenum.common.messages.node_messages import Reply, PrePrepare, Prepare, Commit
2729
from plenum.common.types import f
2830
from plenum.common.util import getNoInstances, get_utc_epoch
@@ -1057,14 +1059,18 @@ def get_res(task, done_list):
10571059
def sdk_check_reply(req_res):
10581060
req, res = req_res
10591061
if isinstance(res, ErrorCode):
1060-
raise AssertionError("Got an error with code {} for request {}"
1061-
.format(res, req))
1062+
if res == 307:
1063+
raise PoolLedgerTimeoutException('Got PoolLedgerTimeout for request {}'
1064+
.format(req))
1065+
else:
1066+
raise CommonSdkIOException('Got an error with code {} for request {}'
1067+
.format(res, req))
10621068
if res['op'] == REQNACK:
1063-
raise AssertionError("ReqNack of id {}. Reason: {}"
1064-
.format(req['reqId'], res['reason']))
1069+
raise RequestNackedException('ReqNack of id {}. Reason: {}'
1070+
.format(req['reqId'], res['reason']))
10651071
if res['op'] == REJECT:
1066-
raise AssertionError("Reject of id {}. Reason: {}"
1067-
.format(req['reqId'], res['reason']))
1072+
raise RequestRejectedException('Reject of id {}. Reason: {}'
1073+
.format(req['reqId'], res['reason']))
10681074

10691075

10701076
def sdk_get_and_check_replies(looper, sdk_req_resp: Sequence, timeout=None):

plenum/test/input_validation/helper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,11 @@ class NetworkPortField(TestFieldBase):
183183

184184
@property
185185
def negative_test_cases(self):
186-
return -1, 65535 + 1
186+
return 0, -1, 65535 + 1
187187

188188
@property
189189
def positive_test_cases(self):
190-
return 0, 9700, 65535
190+
return 0 + 1, 9700, 65535
191191

192192

193193
class NetworkIpAddressField(TestFieldBase):

plenum/test/logging/test_logging_txn_state.py

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
import functools
2+
import json
23

4+
import pytest
5+
6+
from plenum.common.exceptions import RequestRejectedException
7+
from plenum.common.util import randomString
38
from stp_core.loop.eventually import eventually
49

5-
from plenum.common.constants import STEWARD, DOMAIN_LEDGER_ID
10+
from plenum.common.constants import DOMAIN_LEDGER_ID, STEWARD_STRING
611

7-
from plenum.test.pool_transactions.conftest import looper, stewardAndWallet1, \
8-
steward1, stewardWallet, client1, clientAndWallet1, client1Connected
9-
from plenum.test.pool_transactions.helper import sendAddNewClient
12+
from plenum.test.pool_transactions.conftest import looper
13+
from plenum.test.pool_transactions.helper import prepare_nym_request, \
14+
sdk_sign_and_send_prepared_request
1015
from plenum.test import waits
11-
from plenum.test.helper import ensureRejectsRecvd, sdk_send_random_and_check
16+
from plenum.test.helper import sdk_send_random_and_check, sdk_get_and_check_replies
1217

1318

1419
ERORR_MSG = "something went wrong"
15-
whitelist = [ERORR_MSG]
1620

1721

1822
def testLoggingTxnStateForValidRequest(
@@ -33,7 +37,8 @@ def testLoggingTxnStateForValidRequest(
3337
funcs=['executeBatch'], msgs=['committed batch request']
3438
)
3539

36-
reqs = sdk_send_random_and_check(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client, 1)
40+
reqs = sdk_send_random_and_check(looper, txnPoolNodeSet, sdk_pool_handle,
41+
sdk_wallet_client, 1)
3742
req, _ = reqs[0]
3843

3944
reqId = str(req['reqId'])
@@ -43,10 +48,7 @@ def testLoggingTxnStateForValidRequest(
4348

4449

4550
def testLoggingTxnStateForInvalidRequest(
46-
looper, txnPoolNodeSet, clientAndWallet1, client1Connected, logsearch):
47-
48-
client, clientWallet = clientAndWallet1
49-
51+
looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client, logsearch):
5052
logsPropagate, _ = logsearch(
5153
levels=['INFO'], files=['propagator.py'],
5254
funcs=['propagate'], msgs=['propagating.*request.*from client']
@@ -58,21 +60,28 @@ def testLoggingTxnStateForInvalidRequest(
5860
msgs=['encountered exception.*while processing.*will reject']
5961
)
6062

61-
req, wallet = sendAddNewClient(STEWARD, "name", client, clientWallet)
63+
seed = randomString(32)
64+
wh, _ = sdk_wallet_client
6265

63-
ensureRejectsRecvd(
64-
looper, txnPoolNodeSet, client,
65-
reason="Only Steward is allowed to do these transactions",
66-
timeout=waits.expectedReqRejectQuorumTime()
67-
)
66+
nym_request, _ = looper.loop.run_until_complete(
67+
prepare_nym_request(sdk_wallet_client, seed,
68+
"name", STEWARD_STRING))
69+
70+
request_couple = sdk_sign_and_send_prepared_request(looper, sdk_wallet_client,
71+
sdk_pool_handle, nym_request)
6872

69-
reqId = str(req.reqId)
73+
with pytest.raises(RequestRejectedException) as e:
74+
sdk_get_and_check_replies(looper, [request_couple])
75+
76+
assert 'Only Steward is allowed to do these transactions' in e._excinfo[1].args[0]
77+
78+
reqId = str(json.loads(nym_request)['reqId'])
7079
assert any(reqId in record.getMessage() for record in logsPropagate)
7180
assert any(reqId in record.getMessage() for record in logsReject)
7281

7382

7483
def testLoggingTxnStateWhenCommitFails(
75-
looper, txnPoolNodeSet, steward1, stewardWallet, logsearch):
84+
looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_steward, logsearch):
7685
logsPropagate, _ = logsearch(
7786
levels=['INFO'], files=['propagator.py'],
7887
funcs=['propagate'], msgs=['propagating.*request.*from client']
@@ -88,7 +97,15 @@ def testLoggingTxnStateWhenCommitFails(
8897
funcs=['executeBatch'], msgs=['commit failed for batch request']
8998
)
9099

91-
req, wallet = sendAddNewClient(None, "name", steward1, stewardWallet)
100+
seed = randomString(32)
101+
wh, _ = sdk_wallet_steward
102+
103+
nym_request, _ = looper.loop.run_until_complete(
104+
prepare_nym_request(sdk_wallet_steward, seed,
105+
"name", None))
106+
107+
sdk_sign_and_send_prepared_request(looper, sdk_wallet_steward,
108+
sdk_pool_handle, nym_request)
92109

93110
class SomeError(Exception):
94111
pass
@@ -127,7 +144,7 @@ def checkSufficientExceptionsHappend():
127144
eventually(checkSufficientExceptionsHappend,
128145
retryWait=1, timeout=timeout))
129146

130-
reqId = str(req.reqId)
147+
reqId = str(json.loads(nym_request)['reqId'])
131148
assert any(reqId in record.getMessage() for record in logsPropagate)
132149
assert any(reqId in record.getMessage() for record in logsOrdered)
133150
assert any(reqId in record.getMessage() for record in logsCommitFail)

plenum/test/node_request/test_different_ledger_request_interleave.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def test_different_ledger_request_interleave(tconf, looper, txnPoolNodeSet,
7070
sigseed, verkey, bls_key, nodeIp, nodePort, clientIp, clientPort = \
7171
prepare_new_node_data(tconf, tdir, next_node_name)
7272
node_req = looper.loop.run_until_complete(
73-
prepare_node_request(next_node_name, steward_did, clientIp,
73+
prepare_node_request(steward_did, next_node_name, clientIp,
7474
clientPort, nodeIp, nodePort, bls_key,
7575
sigseed))
7676

plenum/test/pool_transactions/conftest.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ def sdk_node_theta_added(looper,
9292
new_node_name,
9393
tdir,
9494
tconf,
95-
allPluginsPath,
96-
nodeClass=testNodeClass)
95+
allPluginsPath)
9796
txnPoolNodeSet.append(new_node)
9897
looper.run(checkNodesConnected(txnPoolNodeSet))
9998
sdk_pool_refresh(looper, sdk_pool_handle)

0 commit comments

Comments
 (0)