Skip to content

Commit 4cd48a1

Browse files
authored
Merge pull request #1282 from ashcherbakov/transaction-endorser
INDY-2173: support Endorser field in Request
2 parents 557b3c1 + f34b48b commit 4cd48a1

File tree

7 files changed

+158
-22
lines changed

7 files changed

+158
-22
lines changed

plenum/common/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@
164164
TXN_PAYLOAD_DATA = "data"
165165
TXN_PAYLOAD_METADATA = "metadata"
166166
TXN_PAYLOAD_METADATA_FROM = "from"
167+
TXN_PAYLOAD_METADATA_ENDORSER = "endorser"
167168
TXN_PAYLOAD_METADATA_REQ_ID = "reqId"
168169
TXN_PAYLOAD_METADATA_DIGEST = "digest"
169170
TXN_PAYLOAD_METADATA_PAYLOAD_DIGEST = "payloadDigest"

plenum/common/request.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def __init__(self,
2121
signatures: Dict[str, str] = None,
2222
protocolVersion: int = None,
2323
taaAcceptance: Dict = None,
24+
endorser: Identifier = None,
2425
# Intentionally omitting *args
2526
**kwargs):
2627
self._identifier = identifier
@@ -30,6 +31,7 @@ def __init__(self,
3031
self.operation = operation
3132
self.protocolVersion = protocolVersion
3233
self.taaAcceptance = taaAcceptance
34+
self.endorser = endorser
3335
self._digest = None
3436
self._payload_digest = None
3537
for nm in PLUGIN_CLIENT_REQUEST_FIELDS:
@@ -67,6 +69,8 @@ def as_dict(self):
6769
rv[f.PROTOCOL_VERSION.nm] = self.protocolVersion
6870
if self.taaAcceptance is not None:
6971
rv[f.TAA_ACCEPTANCE.nm] = self.taaAcceptance
72+
if self.endorser is not None:
73+
rv[f.ENDORSER.nm] = self.endorser
7074
return rv
7175

7276
def __eq__(self, other):
@@ -112,6 +116,8 @@ def signingPayloadState(self, identifier=None):
112116
dct[f.PROTOCOL_VERSION.nm] = self.protocolVersion
113117
if self.taaAcceptance is not None:
114118
dct[f.TAA_ACCEPTANCE.nm] = self.taaAcceptance
119+
if self.endorser is not None:
120+
dct[f.ENDORSER.nm] = self.endorser
115121
return dct
116122

117123
def __setstate__(self, state):

plenum/common/txn_util.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
TXN_SIGNATURE_FROM, TXN_SIGNATURE_VALUE, TXN_SIGNATURE_VALUES, TXN_PAYLOAD_DATA, TXN_PAYLOAD_METADATA_REQ_ID, \
99
TXN_PAYLOAD_METADATA_FROM, TXN_PAYLOAD_PROTOCOL_VERSION, TXN_PAYLOAD_TYPE, TXN_METADATA_SEQ_NO, TXN_METADATA_TIME, \
1010
TXN_METADATA_ID, TXN_VERSION, TXN_PAYLOAD_METADATA_DIGEST, TXN_ID, CURRENT_PROTOCOL_VERSION, \
11-
TXN_PAYLOAD_METADATA_PAYLOAD_DIGEST, TXN_PAYLOAD_METADATA_TAA_ACCEPTANCE
11+
TXN_PAYLOAD_METADATA_PAYLOAD_DIGEST, TXN_PAYLOAD_METADATA_TAA_ACCEPTANCE, TXN_PAYLOAD_METADATA_ENDORSER
1212
from plenum.common.request import Request
1313
from plenum.common.types import f, OPERATION
1414
from stp_core.common.log import getlogger
@@ -200,7 +200,7 @@ def set_payload_data(txn, data):
200200

201201

202202
def append_payload_metadata(
203-
txn, frm=None, req_id=None, digest=None, payload_digest=None, taa_acceptance=None):
203+
txn, frm=None, req_id=None, digest=None, payload_digest=None, taa_acceptance=None, endorser=None):
204204
if frm is not None:
205205
txn[TXN_PAYLOAD][TXN_PAYLOAD_METADATA][TXN_PAYLOAD_METADATA_FROM] = frm
206206
if req_id is not None:
@@ -211,6 +211,8 @@ def append_payload_metadata(
211211
txn[TXN_PAYLOAD][TXN_PAYLOAD_METADATA][TXN_PAYLOAD_METADATA_DIGEST] = digest
212212
if payload_digest is not None:
213213
txn[TXN_PAYLOAD][TXN_PAYLOAD_METADATA][TXN_PAYLOAD_METADATA_PAYLOAD_DIGEST] = payload_digest
214+
if endorser is not None:
215+
txn[TXN_PAYLOAD][TXN_PAYLOAD_METADATA][TXN_PAYLOAD_METADATA_ENDORSER] = endorser
214216
return txn
215217

216218

@@ -241,7 +243,8 @@ def reqToTxn(req):
241243
signature=req.get(f.SIG.nm, None),
242244
signatures=req.get(f.SIGS.nm, None),
243245
protocolVersion=req.get(f.PROTOCOL_VERSION.nm, None),
244-
taaAcceptance=req.get(f.TAA_ACCEPTANCE.nm, None)
246+
taaAcceptance=req.get(f.TAA_ACCEPTANCE.nm, None),
247+
endorser=req.get(f.ENDORSER.nm, None)
245248
)
246249
req = TxnUtilConfig.client_request_class(**kwargs)
247250
if isinstance(req, Request):
@@ -291,7 +294,8 @@ def do_req_to_txn(req_data, req_op):
291294
req_id=req_data.pop(f.REQ_ID.nm, None),
292295
digest=req_data.pop(f.DIGEST.nm, None),
293296
payload_digest=req_data.pop(f.PAYLOAD_DIGEST.nm, None),
294-
taa_acceptance=req_data.pop(f.TAA_ACCEPTANCE.nm, None))
297+
taa_acceptance=req_data.pop(f.TAA_ACCEPTANCE.nm, None),
298+
endorser=req_data.pop(f.ENDORSER.nm, None))
295299

296300
# 4. Fill Payload data
297301
set_payload_data(result, req_op)

plenum/test/helper.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,16 @@ def sdk_multisign_request_object(looper, sdk_wallet, req):
829829
wh, did = sdk_wallet
830830
return looper.loop.run_until_complete(multi_sign_request(wh, did, req))
831831

832+
def sdk_multisign_request_from_dict(looper, sdk_wallet, op, reqId=None, taa_acceptance=None, endorser=None):
833+
wh, did = sdk_wallet
834+
reqId = reqId or random.randint(10, 100000)
835+
request = Request(operation=op, reqId=reqId,
836+
protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=did,
837+
taaAcceptance=taa_acceptance,
838+
endorser=endorser)
839+
req_str = json.dumps(request.as_dict)
840+
resp = looper.loop.run_until_complete(multi_sign_request(wh, did, req_str))
841+
return json.loads(resp)
832842

833843
def sdk_signed_random_requests(looper, sdk_wallet, count):
834844
_, did = sdk_wallet
@@ -1062,12 +1072,13 @@ def sdk_send_batches_of_random(looper, txnPoolNodeSet, sdk_pool, sdk_wallet,
10621072
return sdk_reqs
10631073

10641074

1065-
def sdk_sign_request_from_dict(looper, sdk_wallet, op, reqId=None, taa_acceptance=None):
1075+
def sdk_sign_request_from_dict(looper, sdk_wallet, op, reqId=None, taa_acceptance=None, endorser=None):
10661076
wallet_h, did = sdk_wallet
10671077
reqId = reqId or random.randint(10, 100000)
10681078
request = Request(operation=op, reqId=reqId,
10691079
protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=did,
1070-
taaAcceptance=taa_acceptance)
1080+
taaAcceptance=taa_acceptance,
1081+
endorser=endorser)
10711082
req_str = json.dumps(request.as_dict)
10721083
resp = looper.loop.run_until_complete(sign_request(wallet_h, did, req_str))
10731084
return json.loads(resp)

plenum/test/node_catchup/test_catchup_with_old_txn_metadata_digest_format.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ def check_nodes_domain_ledger(nodes: Iterable, txn_count: int):
3333
# Patch payload metadata, note that it will prevent pool from sending adequate replies to clients
3434
def append_old_payload_metadata(
3535
txn, frm=None, req_id=None,
36-
digest=None, payload_digest=None, taa_acceptance=None):
37-
txn = append_payload_metadata(txn, frm, req_id, digest, payload_digest, taa_acceptance)
36+
digest=None, payload_digest=None, taa_acceptance=None,
37+
endorser=None):
38+
txn = append_payload_metadata(txn, frm, req_id, digest, payload_digest, taa_acceptance, endorser)
3839
metadata = txn[TXN_PAYLOAD][TXN_PAYLOAD_METADATA]
3940
del metadata[TXN_PAYLOAD_METADATA_PAYLOAD_DIGEST]
4041
metadata[TXN_PAYLOAD_METADATA_DIGEST] = payload_digest
4142
return txn
43+
4244
monkeypatch.setattr(txn_util, 'append_payload_metadata', append_old_payload_metadata)
4345

4446
# Check pool initial state

plenum/test/test_request.py

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,107 @@
1+
import pytest
2+
3+
from plenum.common.constants import CURRENT_PROTOCOL_VERSION
14
from plenum.common.request import Request
5+
from plenum.common.types import OPERATION, f
6+
from plenum.test.helper import sdk_sign_request_from_dict, sdk_multisign_request_from_dict
7+
8+
9+
@pytest.fixture(params=['with_endorser', 'no_endorser'])
10+
def endorser(request):
11+
if request.param == 'with_endorser':
12+
return '5gC6mJq5MoGPwubtU8F5Qc'
13+
return None
14+
15+
16+
@pytest.fixture(params=['all', 'sig_only', 'sigs_only', 'no_protocol_vers',
17+
'all_sdk', 'sig_only_sdk', 'sigs_only_sdk', 'no_protocol_vers_sdk',
18+
'endorser'])
19+
def req(request, looper, sdk_wallet_client, endorser):
20+
op = {'type': '1',
21+
'something': 'nothing'}
22+
taaa = {
23+
'a': 'b',
24+
'c': 3
25+
}
26+
if request.param.endswith('_sdk'):
27+
request.param = request.param[:-4]
28+
if request.param == 'sigs_only':
29+
req = sdk_multisign_request_from_dict(looper, sdk_wallet_client,
30+
op, reqId=1513945121191691,
31+
taa_acceptance=taaa,
32+
endorser=endorser)
33+
else:
34+
req = sdk_sign_request_from_dict(looper, sdk_wallet_client,
35+
op, reqId=1513945121191691,
36+
taa_acceptance=taaa,
37+
endorser=endorser)
38+
39+
if request.param == 'no_protocol_vers': # TODO INDY-2072 always false here
40+
req.pop('protocolVersion')
41+
req = Request(
42+
req.get(f.IDENTIFIER.nm, None),
43+
req.get(f.REQ_ID.nm, None),
44+
req.get(OPERATION, None),
45+
req.get(f.SIG.nm, None),
46+
req.get(f.SIGS.nm, None),
47+
req.get(f.PROTOCOL_VERSION.nm, None),
48+
req.get(f.TAA_ACCEPTANCE.nm, None),
49+
req.get(f.ENDORSER.nm, None)
50+
)
51+
else:
52+
req = Request(operation=op, reqId=1513945121191691,
53+
protocolVersion=CURRENT_PROTOCOL_VERSION, identifier="6ouriXMZkLeHsuXrN1X1fd",
54+
taaAcceptance=taaa, endorser=endorser)
55+
sign = "2DaRm3nt6H5fJu2TP5vxqbaDCtABPYmUTSX4ocnY8fVGgyJMVNaeh2z6JZhcW1gbmGKJcZopZMKZJwADuXFFJobM"
56+
req.signature = sign
57+
req.add_signature("6ouriXMZkLeHsuXrN1X1fd",
58+
sign)
59+
if request.param == 'sig_only':
60+
req.signatures = None
61+
if request.param == 'sigs_only':
62+
req.signature = None
63+
if request.param == 'no_protocol_vers':
64+
req.protocolVersion = None
65+
66+
return req
267

368

469
def test_request_all_identifiers_returns_empty_list_for_request_without_signatures():
570
req = Request()
6-
771
assert req.all_identifiers == []
72+
73+
74+
def test_as_dict(req, endorser):
75+
req_dct = req.as_dict
76+
assert req_dct.get(f.REQ_ID.nm) == req.reqId
77+
assert req_dct.get(OPERATION) == req.operation
78+
assert req_dct.get(f.IDENTIFIER.nm) == req.identifier
79+
assert req_dct.get(f.SIGS.nm) == req.signatures
80+
assert req_dct.get(f.SIG.nm) == req.signature
81+
assert req_dct.get(f.PROTOCOL_VERSION.nm) == req.protocolVersion
82+
assert req_dct.get(f.TAA_ACCEPTANCE.nm) == req.taaAcceptance
83+
assert req_dct.get(f.ENDORSER.nm) == req.endorser
84+
85+
86+
def test_signing_payload_state(req, endorser):
87+
signing_state = req.signingPayloadState()
88+
assert signing_state.get(f.REQ_ID.nm) == req.reqId
89+
assert signing_state.get(OPERATION) == req.operation
90+
assert signing_state.get(f.IDENTIFIER.nm) == req.identifier
91+
assert signing_state.get(f.PROTOCOL_VERSION.nm) == req.protocolVersion
92+
assert signing_state.get(f.TAA_ACCEPTANCE.nm) == req.taaAcceptance
93+
assert signing_state.get(f.ENDORSER.nm) == req.endorser
94+
assert f.SIGS.nm not in signing_state
95+
assert f.SIG.nm not in signing_state
96+
97+
98+
def test_signing_state(req, endorser):
99+
signing_state = req.signingState()
100+
assert signing_state.get(f.REQ_ID.nm) == req.reqId
101+
assert signing_state.get(OPERATION) == req.operation
102+
assert signing_state.get(f.IDENTIFIER.nm) == req.identifier
103+
assert signing_state.get(f.PROTOCOL_VERSION.nm) == req.protocolVersion
104+
assert signing_state.get(f.TAA_ACCEPTANCE.nm) == req.taaAcceptance
105+
assert signing_state.get(f.ENDORSER.nm) == req.endorser
106+
assert signing_state.get(f.SIGS.nm) == req.signatures
107+
assert signing_state.get(f.SIG.nm) == req.signature

plenum/test/transactions/test_req_to_txn.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,37 @@
55
from plenum.common.txn_util import reqToTxn, append_txn_metadata
66
from plenum.common.types import OPERATION, f
77
from plenum.common.util import SortedDict
8-
from plenum.test.helper import sdk_sign_request_from_dict
8+
from plenum.test.helper import sdk_sign_request_from_dict, sdk_multisign_request_from_dict
9+
10+
11+
@pytest.fixture(params=['with_endorser', 'no_endorser'])
12+
def endorser(request):
13+
if request.param == 'with_endorser':
14+
return '5gC6mJq5MoGPwubtU8F5Qc'
15+
return None
916

1017

1118
@pytest.fixture(params=['all', 'sig_only', 'sigs_only', 'no_protocol_vers',
1219
'all_sdk', 'sig_only_sdk', 'sigs_only_sdk', 'no_protocol_vers_sdk'])
13-
def req_and_expected(request, looper, sdk_wallet_client):
20+
def req_and_expected(request, looper, sdk_wallet_client, endorser):
1421
op = {'type': '1',
1522
'something': 'nothing'}
1623
taaa = {
1724
'a': 'b',
1825
'c': 3
1926
}
2027
if request.param.endswith('_sdk'):
21-
req = sdk_sign_request_from_dict(looper, sdk_wallet_client,
22-
op, reqId=1513945121191691,
23-
taa_acceptance=taaa)
2428
request.param = request.param[:-4]
25-
# TODO: support multi-sig in SDK
26-
# if request.param == 'sig_only':
27-
# req.pop('signatures')
28-
# if request.param == 'sigs_only':
29-
# req.pop('signature')
29+
if request.param == 'sigs_only':
30+
req = sdk_multisign_request_from_dict(looper, sdk_wallet_client,
31+
op, reqId=1513945121191691,
32+
taa_acceptance=taaa,
33+
endorser=endorser)
34+
else:
35+
req = sdk_sign_request_from_dict(looper, sdk_wallet_client,
36+
op, reqId=1513945121191691,
37+
taa_acceptance=taaa,
38+
endorser=endorser)
3039
if request.param == 'no_protocol_vers': # TODO INDY-2072 always false here
3140
req.pop('protocolVersion')
3241
r = Request(
@@ -36,15 +45,16 @@ def req_and_expected(request, looper, sdk_wallet_client):
3645
req.get(f.SIG.nm, None),
3746
req.get(f.SIGS.nm, None),
3847
req.get(f.PROTOCOL_VERSION.nm, None),
39-
req.get(f.TAA_ACCEPTANCE.nm, None)
48+
req.get(f.TAA_ACCEPTANCE.nm, None),
49+
req.get(f.ENDORSER.nm, None)
4050
)
4151
digest = r.digest
4252
payload_digest = r.payload_digest
43-
sign = req.get(f.SIG.nm)
53+
sign = req.get(f.SIG.nm) if request.param != 'sigs_only' else next(iter(req.get(f.SIGS.nm).values()))
4454
else:
4555
req = Request(operation=op, reqId=1513945121191691,
4656
protocolVersion=CURRENT_PROTOCOL_VERSION, identifier="6ouriXMZkLeHsuXrN1X1fd",
47-
taaAcceptance=taaa)
57+
taaAcceptance=taaa, endorser=endorser)
4858
sign = "2DaRm3nt6H5fJu2TP5vxqbaDCtABPYmUTSX4ocnY8fVGgyJMVNaeh2z6JZhcW1gbmGKJcZopZMKZJwADuXFFJobM"
4959
req.signature = sign
5060
req.add_signature("6ouriXMZkLeHsuXrN1X1fd",
@@ -96,6 +106,8 @@ def req_and_expected(request, looper, sdk_wallet_client):
96106
new_expected["txn"]["metadata"]["digest"] = digest
97107
if payload_digest is not None:
98108
new_expected["txn"]["metadata"]["payloadDigest"] = payload_digest
109+
if endorser is not None:
110+
new_expected["txn"]["metadata"]["endorser"] = endorser
99111

100112
return req, new_expected
101113

0 commit comments

Comments
 (0)