1
1
import base58
2
2
import os
3
3
4
- from common .serializers .serialization import state_roots_serializer
5
- from plenum .common .constants import DOMAIN_LEDGER_ID , ALIAS , BLS_KEY
4
+ from crypto .bls .bls_crypto import BlsCryptoVerifier
5
+ from plenum .bls .bls_crypto_factory import create_default_bls_crypto_factory
6
+ from plenum .server .quorums import Quorums
7
+ from crypto .bls .bls_multi_signature import MultiSignatureValue
8
+ from state .pruning_state import PruningState
9
+ from common .serializers .serialization import state_roots_serializer , proof_nodes_serializer
10
+ from plenum .common .constants import DOMAIN_LEDGER_ID , ALIAS , BLS_KEY , STATE_PROOF , TXN_TYPE , MULTI_SIGNATURE , \
11
+ MULTI_SIGNATURE_PARTICIPANTS , MULTI_SIGNATURE_SIGNATURE , MULTI_SIGNATURE_VALUE
6
12
from plenum .common .keygen_utils import init_bls_keys
7
13
from plenum .common .messages .node_messages import Commit , Prepare , PrePrepare
8
- from plenum .common .util import get_utc_epoch , randomString , random_from_alphabet
9
- from plenum .test .helper import sendRandomRequests , waitForSufficientRepliesForRequests
14
+ from plenum .common .util import get_utc_epoch , randomString , random_from_alphabet , hexToFriendly
15
+ from plenum .test .helper import sendRandomRequests , waitForSufficientRepliesForRequests , sdk_send_random_and_check
10
16
from plenum .test .node_catchup .helper import waitNodeDataEquality , ensureClientConnectedToNodesAndPoolLedgerSame
11
- from plenum .test .pool_transactions .helper import updateNodeData , new_client
17
+ from plenum .test .node_request .helper import sdk_ensure_pool_functional
18
+ from plenum .test .pool_transactions .helper import updateNodeData , sdk_send_update_node , \
19
+ sdk_pool_refresh
20
+ from stp_core .common .log import getlogger
21
+
22
+ logger = getlogger ()
12
23
13
24
14
25
def generate_state_root ():
15
26
return base58 .b58encode (os .urandom (32 ))
16
27
17
28
18
- def check_bls_multi_sig_after_send (looper , txnPoolNodeSet ,
19
- client , wallet ,
20
- saved_multi_sigs_count ):
29
+ def sdk_check_bls_multi_sig_after_send (looper , txnPoolNodeSet ,
30
+ sdk_pool_handle , sdk_wallet_handle ,
31
+ saved_multi_sigs_count ):
21
32
# at least two because first request could have no
22
33
# signature since state can be clear
23
34
number_of_requests = 3
@@ -26,8 +37,8 @@ def check_bls_multi_sig_after_send(looper, txnPoolNodeSet,
26
37
# Using loop to avoid 3pc batching
27
38
state_roots = []
28
39
for i in range (number_of_requests ):
29
- reqs = sendRandomRequests ( wallet , client , 1 )
30
- waitForSufficientRepliesForRequests ( looper , client , requests = reqs )
40
+ sdk_send_random_and_check ( looper , txnPoolNodeSet , sdk_pool_handle ,
41
+ sdk_wallet_handle , 1 )
31
42
waitNodeDataEquality (looper , txnPoolNodeSet [0 ], * txnPoolNodeSet [:- 1 ])
32
43
state_roots .append (
33
44
state_roots_serializer .serialize (
@@ -45,7 +56,7 @@ def check_bls_multi_sig_after_send(looper, txnPoolNodeSet,
45
56
46
57
# 3. check how many multi-sigs are saved
47
58
for multi_sigs in multi_sigs_for_batch :
48
- assert len (multi_sigs ) == saved_multi_sigs_count ,\
59
+ assert len (multi_sigs ) == saved_multi_sigs_count , \
49
60
"{} != {}" .format (len (multi_sigs ), saved_multi_sigs_count )
50
61
51
62
# 3. check that bls multi-sig is the same for all nodes we get PrePrepare for (that is for all expect the last one)
@@ -89,20 +100,20 @@ def calculate_multi_sig(creator, bls_bft_with_commits, quorums, pre_prepare):
89
100
90
101
91
102
def create_pre_prepare_params (state_root ,
92
- ledger_id = DOMAIN_LEDGER_ID ,
103
+ ledger_id = DOMAIN_LEDGER_ID ,
93
104
txn_root = None ,
94
105
timestamp = None ,
95
106
bls_multi_sig = None ):
96
- params = [0 ,
97
- 0 ,
98
- 0 ,
99
- timestamp or get_utc_epoch (),
100
- [('1' * 16 , 1 )],
101
- 0 ,
102
- "random digest" ,
103
- ledger_id ,
104
- state_root ,
105
- txn_root or '1' * 32 ]
107
+ params = [0 ,
108
+ 0 ,
109
+ 0 ,
110
+ timestamp or get_utc_epoch (),
111
+ [('1' * 16 , 1 )],
112
+ 0 ,
113
+ "random digest" ,
114
+ ledger_id ,
115
+ state_root ,
116
+ txn_root or '1' * 32 ]
106
117
if bls_multi_sig :
107
118
params .append (bls_multi_sig .as_list ())
108
119
return params
@@ -122,12 +133,14 @@ def create_commit_no_bls_sig(req_key):
122
133
params = create_commit_params (view_no , pp_seq_no )
123
134
return Commit (* params )
124
135
136
+
125
137
def create_commit_with_bls_sig (req_key , bls_sig ):
126
138
view_no , pp_seq_no = req_key
127
139
params = create_commit_params (view_no , pp_seq_no )
128
140
params .append (bls_sig )
129
141
return Commit (* params )
130
142
143
+
131
144
def create_commit_bls_sig (bls_bft , req_key , pre_prepare ):
132
145
view_no , pp_seq_no = req_key
133
146
params = create_commit_params (view_no , pp_seq_no )
@@ -159,8 +172,8 @@ def change_bls_key(looper, txnPoolNodeSet,
159
172
160
173
key_in_txn = \
161
174
new_blspk \
162
- if not add_wrong \
163
- else '' .join (random_from_alphabet (32 , base58 .alphabet ))
175
+ if not add_wrong \
176
+ else '' .join (random_from_alphabet (32 , base58 .alphabet ))
164
177
165
178
node_data = {
166
179
ALIAS : node .name ,
@@ -174,6 +187,32 @@ def change_bls_key(looper, txnPoolNodeSet,
174
187
return new_blspk
175
188
176
189
190
+ def sdk_change_bls_key (looper , txnPoolNodeSet ,
191
+ node ,
192
+ sdk_pool_handle ,
193
+ sdk_wallet_steward ,
194
+ add_wrong = False ,
195
+ new_bls = None ):
196
+ new_blspk = init_bls_keys (node .keys_dir , node .name )
197
+ key_in_txn = new_bls or new_blspk \
198
+ if not add_wrong \
199
+ else base58 .b58encode (randomString (128 ).encode ())
200
+ node_dest = hexToFriendly (node .nodestack .verhex )
201
+ sdk_send_update_node (looper , sdk_wallet_steward ,
202
+ sdk_pool_handle ,
203
+ node_dest , node .name ,
204
+ None , None ,
205
+ None , None ,
206
+ bls_key = key_in_txn ,
207
+ services = None )
208
+ poolSetExceptOne = list (txnPoolNodeSet )
209
+ poolSetExceptOne .remove (node )
210
+ waitNodeDataEquality (looper , node , * poolSetExceptOne )
211
+ sdk_pool_refresh (looper , sdk_pool_handle )
212
+ sdk_ensure_pool_functional (looper , txnPoolNodeSet , sdk_wallet_steward , sdk_pool_handle )
213
+ return new_blspk
214
+
215
+
177
216
def check_bls_key (blskey , node , nodes , add_wrong = False ):
178
217
'''
179
218
Check that each node has the same and correct blskey for this node
@@ -195,24 +234,89 @@ def check_bls_key(blskey, node, nodes, add_wrong=False):
195
234
196
235
def check_update_bls_key (node_num , saved_multi_sigs_count ,
197
236
looper , txnPoolNodeSet ,
198
- client_tdir ,
199
- poolTxnClientData ,
200
- stewards_and_wallets ,
237
+ sdk_wallet_stewards ,
238
+ sdk_wallet_client ,
239
+ sdk_pool_handle ,
201
240
add_wrong = False ):
202
241
# 1. Change BLS key for a specified NODE
203
242
node = txnPoolNodeSet [node_num ]
204
- steward_client , steward_wallet = stewards_and_wallets [node_num ]
205
- new_blspk = change_bls_key (looper , txnPoolNodeSet , node ,
206
- steward_client , steward_wallet ,
207
- add_wrong )
243
+ sdk_wallet_steward = sdk_wallet_stewards [node_num ]
244
+ new_blspk = sdk_change_bls_key (looper , txnPoolNodeSet ,
245
+ node ,
246
+ sdk_pool_handle ,
247
+ sdk_wallet_steward ,
248
+ add_wrong )
208
249
209
250
# 2. Check that all Nodes see the new BLS key value
210
251
check_bls_key (new_blspk , node , txnPoolNodeSet , add_wrong )
211
252
212
253
# 3. Check that we can send new requests and have correct multisigs
213
- client , wallet = new_client (looper ,
214
- poolTxnClientData ,
215
- txnPoolNodeSet , client_tdir )
216
- check_bls_multi_sig_after_send (looper , txnPoolNodeSet ,
217
- client , wallet ,
218
- saved_multi_sigs_count = saved_multi_sigs_count )
254
+ sdk_check_bls_multi_sig_after_send (looper , txnPoolNodeSet ,
255
+ sdk_pool_handle , sdk_wallet_client ,
256
+ saved_multi_sigs_count )
257
+
258
+
259
+ def validate_proof (result ):
260
+ """
261
+ Validates state proof
262
+ """
263
+ state_root_hash = result [STATE_PROOF ]['root_hash' ]
264
+ state_root_hash = state_roots_serializer .deserialize (state_root_hash )
265
+ proof_nodes = result [STATE_PROOF ]['proof_nodes' ]
266
+ if isinstance (proof_nodes , str ):
267
+ proof_nodes = proof_nodes .encode ()
268
+ proof_nodes = proof_nodes_serializer .deserialize (proof_nodes )
269
+ key , value = prepare_for_state (result )
270
+ valid = PruningState .verify_state_proof (state_root_hash ,
271
+ key ,
272
+ value ,
273
+ proof_nodes ,
274
+ serialized = True )
275
+ return valid
276
+
277
+
278
+ def prepare_for_state (result ):
279
+ if result [TXN_TYPE ] == "buy" :
280
+ from plenum .test .test_node import TestDomainRequestHandler
281
+ key , value = TestDomainRequestHandler .prepare_buy_for_state (result )
282
+ return key , value
283
+
284
+
285
+ def validate_multi_signature (state_proof , txnPoolNodeSet ):
286
+ """
287
+ Validates multi signature
288
+ """
289
+ multi_signature = state_proof [MULTI_SIGNATURE ]
290
+ if not multi_signature :
291
+ logger .debug ("There is a state proof, but no multi signature" )
292
+ return False
293
+
294
+ participants = multi_signature [MULTI_SIGNATURE_PARTICIPANTS ]
295
+ signature = multi_signature [MULTI_SIGNATURE_SIGNATURE ]
296
+ value = MultiSignatureValue (
297
+ ** (multi_signature [MULTI_SIGNATURE_VALUE ])
298
+ ).as_single_value ()
299
+ quorums = Quorums (len (txnPoolNodeSet ))
300
+ if not quorums .bls_signatures .is_reached (len (participants )):
301
+ logger .debug ("There is not enough participants of "
302
+ "multi-signature" )
303
+ return False
304
+ public_keys = []
305
+ for node_name in participants :
306
+ key = next (node .bls_bft .bls_crypto_signer .pk for node
307
+ in txnPoolNodeSet if node .name == node_name )
308
+ if key is None :
309
+ logger .debug ("There is no bls key for node {}"
310
+ .format (node_name ))
311
+ return False
312
+ public_keys .append (key )
313
+ _multi_sig_verifier = _create_multi_sig_verifier ()
314
+ return _multi_sig_verifier .verify_multi_sig (signature ,
315
+ value ,
316
+ public_keys )
317
+
318
+
319
+ def _create_multi_sig_verifier () -> BlsCryptoVerifier :
320
+ verifier = create_default_bls_crypto_factory () \
321
+ .create_bls_crypto_verifier ()
322
+ return verifier
0 commit comments