Skip to content

INDY-790: Let client send get requests to one node #409

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

Merged
merged 3 commits into from
Oct 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions plenum/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def __init__(self,
logger.debug("total plugins loaded in client: {}".format(tp))

self._multi_sig_verifier = self._create_multi_sig_verifier()
self._read_only_requests = set()

@lazy_field
def _bls_register(self):
Expand Down Expand Up @@ -276,11 +277,14 @@ async def prod(self, limit) -> int:
def submitReqs(self, *reqs: Request) -> List[Request]:
requests = []
errs = []

for request in reqs:
if (self.mode == Mode.discovered and self.hasSufficientConnections) or (
request.isForced() and self.hasAnyConnections):
logger.debug(
'Client {} sending request {}'.format(self, request))
if (self.mode == Mode.discovered and self.hasSufficientConnections) or \
(self.hasAnyConnections and
(request.txn_type in self._read_only_requests or request.isForced())):

logger.debug('Client {} sending request {}'
.format(self, request))
stat, err_msg = self.send(request)
if stat:
self.expectingFor(request)
Expand All @@ -292,7 +296,7 @@ def submitReqs(self, *reqs: Request) -> List[Request]:
else:
logger.debug(
"{} pending request since in mode {} and "
"connected to {} nodes". format(
"connected to {} nodes".format(
self, self.mode, self.nodestack.connecteds))
self.pendReqsTillConnection(request)
requests.append(request)
Expand Down
6 changes: 5 additions & 1 deletion plenum/common/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Mapping, NamedTuple

from common.serializers.serialization import serialize_msg_for_signing
from plenum.common.constants import REQDIGEST, REQKEY, FORCE, CURRENT_PROTOCOL_VERSION
from plenum.common.constants import REQDIGEST, REQKEY, FORCE, TXN_TYPE, CURRENT_PROTOCOL_VERSION
from plenum.common.messages.client_request import ClientMessageValidator
from plenum.common.types import f, OPERATION
from stp_core.types import Identifier
Expand Down Expand Up @@ -87,6 +87,10 @@ def isForced(self):
force = self.operation.get(FORCE)
return str(force) == 'True'

@property
def txn_type(self):
return self.operation.get(TXN_TYPE)

def __hash__(self):
return hash(self.serialized())

Expand Down
47 changes: 47 additions & 0 deletions plenum/test/client/test_client_sends_get_request_to_one_node.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import random

from plenum.test.client.conftest import passThroughReqAcked1

from plenum.test.helper import sendReqsToNodesAndVerifySuffReplies, stopNodes, waitForSufficientRepliesForRequests, \
send_signed_requests
from plenum.test.malicious_behaviors_client import \
genDoesntSendRequestToSomeNodes
from plenum.test.node_catchup.helper import waitNodeDataEquality


nodeCount = 4
clientFault = genDoesntSendRequestToSomeNodes("AlphaC")
reqAcked1 = passThroughReqAcked1


def test_client_sends_get_request_to_one_node(looper,
client1,
wallet1,
nodeSet):
"""
Check that read only equest can be sent
without having connection to all nodes
"""
client = client1
wallet = wallet1

nodes_to_stop = list(nodeSet)[1:]
stopNodes(nodes_to_stop, looper)

initial_submit_count = client.spylog.count(client.submitReqs)
initial_send_count = client.spylog.count(client.send)

def sign_and_send(op):
signed = wallet.signOp(op)
send_signed_requests(client, [signed])

buy = {'type': 'buy', 'amount': random.randint(10, 100)}
sign_and_send(buy)
assert initial_submit_count + 1 == client.spylog.count(client.submitReqs)
assert initial_send_count == client.spylog.count(client.send)

get_buy = {'type': 'get_buy'}
client._read_only_requests.add('get_buy')
sign_and_send(get_buy)
assert initial_submit_count + 2 == client.spylog.count(client.submitReqs)
assert initial_send_count + 1 == client.spylog.count(client.send)
5 changes: 4 additions & 1 deletion plenum/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@

logger = getlogger()

client_spyables = [Client.handleOneNodeMsg, Client.resendRequests]
client_spyables = [Client.handleOneNodeMsg,
Client.resendRequests,
Client.send,
Client.submitReqs]


@spyable(methods=client_spyables)
Expand Down