-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtest_epapers.py
More file actions
145 lines (121 loc) · 6.44 KB
/
Copy pathtest_epapers.py
File metadata and controls
145 lines (121 loc) · 6.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import argparse
from DART import *
from pprint import pprint
# -----------------------------------------------------
parser = argparse.ArgumentParser(description='Esegui il test EPapers (test scenario A paper ICDCS).')
parser.add_argument('--build', type=str,
default='build/contracts/DART.json',
help="path all'artifact DART.json prodotto da Truffle a seguito della compilazione (default: build/contracts/DART.json)")
parser.add_argument('--host', type=str,
default='http://localhost:8545',
help="hostname e porta della blockchain su cui è stato deployato DART (default: http://localhost:8545)")
parser.add_argument('--netid', type=int,
default=1,
help="network id della blockchain (default: 1)")
parser.add_argument(dest='n_eligibles', type=int, help='numero di principal da registrare come studenti e membri EOrg')
parser.add_argument(dest='n_universities', type=int, help='numero di università da istanziare e su cui smistare gli studenti')
args = parser.parse_args()
nEligibles = args.n_eligibles
nUniversities = args.n_universities
# Inizializza web3 connettendolo al provider locale ganache
w3 = Web3(Web3.HTTPProvider(args.host))
accounts = w3.eth.accounts;
w3.eth.defaultAccount = accounts[0]
if len(accounts) < (3+nEligibles+nUniversities):
print("Not enough available Ethereum accounts! At least (N_eligibles + N_universities + 3) accounts are needed in order to run this test")
sys.exit(-1)
addressesOfEligibles = accounts[3:3+nEligibles]
addressesOfUniversities = accounts[3+nEligibles:3+nEligibles+nUniversities]
# Inizializza l'interfaccia per interagire con lo smart contract DART
DARTArtifact = json.load(open(args.build))
d = DART(DARTArtifact['abi'], DARTArtifact['networks'][str(args.netid)]['address'], w3)
# -----------------------------------------------------
# Per facilitare la stesura dei test e la lettura dei risultati
# realizza due coppie di dizionari per legare:
# ... principals ad address e viceversa
PR = {
'EPapers': accounts[0],
'EOrg': accounts[1],
'StateA': accounts[2]
}
for idx, addr in enumerate(addressesOfEligibles):
PR['Principal[' + str(idx+1) + ']'] = addr
for idx, addr in enumerate(addressesOfUniversities):
PR['Uni[' + str(idx+1) + ']'] = addr
INV_PR = {v: k for k, v in PR.items()}
print("\nPRINCIPALS:")
pprint(PR)
# ... rolenames esadecimali a rolenames stringhe e viceversa
RN = {
'canAccess': '0x000a',
'student': '0x000b',
'member': '0x000c',
'university': '0x000d',
'student': '0x000e'
}
INV_RN = {v: k for k, v in RN.items()}
print("\nROLENAMES:")
pprint(RN)
# Funzione di utilità per convertire una Expression in una stringa human-readable
def expr2str(expr):
if isinstance(expr, SMExpression):
return INV_PR[expr.member]
elif isinstance(expr, SIExpression):
return INV_PR[expr.principal] + "." + INV_RN[expr.roleName]
elif isinstance(expr, LIExpression):
return INV_PR[expr.principal] + "." + INV_RN[expr.roleNameA] + "." + INV_RN[expr.roleNameB]
elif isinstance(expr, IIExpression):
return INV_PR[expr.principalA] + "." + INV_RN[expr.roleNameA] + " ∩ " + INV_PR[expr.principalB] + "." + INV_RN[expr.roleNameB]
# -----------------------------------------------------
# Registra ruoli e credenziali per istanziare la policy di test EPapers
print("Loading policy... ", end='')
d.newRole(RN['canAccess'], {'from': PR['EPapers']})
d.newRole(RN['student'], {'from': PR['EOrg']})
d.newRole(RN['member'], {'from': PR['EOrg']})
d.newRole(RN['university'], {'from': PR['EOrg']})
d.newRole(RN['university'], {'from': PR['StateA']})
for uniAddr in addressesOfUniversities:
d.newRole(RN['student'], {'from': uniAddr})
for idx, principalAddr in enumerate(addressesOfEligibles):
# Registra il principal a EOrg.member
d.addSimpleMember(RN['member'], SMExpression(principalAddr), 100, {'from': PR['EOrg']})
# Registra il principal come studente di una delle università
d.addSimpleMember(RN['student'], SMExpression(principalAddr), 100, {'from': addressesOfUniversities[idx % len(addressesOfUniversities)]})
for uniAddr in addressesOfUniversities:
# StateA.university ←− Uni_X
d.addSimpleMember(RN['university'], SMExpression(uniAddr), 100, {'from': PR['StateA']})
# EOrg.university ←− StateA.university
d.addSimpleInclusion(RN['university'], SIExpression(PR['StateA'], RN['university']), 100, {'from': PR['EOrg']})
# EOrg.student ←− EOrg.university.student
d.addLinkedInclusion(RN['student'], LIExpression(PR['EOrg'], RN['university'], RN['student']), 100, {'from': PR['EOrg']})
# EPapers.canAccess ←− EOrg.member ∩ EOrg.student
d.addIntersectionInclusion(RN['canAccess'], IIExpression(PR['EOrg'], RN['student'], PR['EOrg'], RN['member']), 50, {'from': PR['EPapers']})
print("Done")
# -----------------------------------------------------
# Effettua una ricerca locale di tutti i membri a cui risulta assegnato il ruolo EPapers.canAccess
print("\nSearching... ", end='')
solutions = d.search(SIExpression(PR['EPapers'], RN['canAccess']))
print(f"Found solutions: {len(solutions)}")
# Per ciascun membro trovato, costruiscine la dimostrazione per il metodo di verifica on-chain sulla base dei paths nelle soluzioni
for idx, currSol in enumerate(solutions.values()):
print(f'\nSolution #{idx+1}: member={INV_PR[currSol.member]}, weight={currSol.weight}')
proofStrs = []
proof = []
for currEdge in currSol.path:
if not isinstance(currEdge.toNode.expr, LIExpression):
proofStrs.append(expr2str(currEdge.toNode.expr) + ' ←- ' + expr2str(currEdge.fromNode.expr))
proof.append(currEdge.toNode.expr.id)
proof.append(currEdge.fromNode.expr.id)
# Verifica la dimostrazione on-chain
print('On-chain verification proof:')
pprint(proofStrs)
verifGas = d.contract.functions.verifyProof(proof, currSol.reqStackSize).estimateGas()
verifRes = d.verifyProof(proof, currSol.reqStackSize)
if verifRes['principal'] != PR['EPapers'] or verifRes['rolename'] != RN['canAccess'] or verifRes['member'] != currSol.member:
print("ERROR: invalid proof for current solution!")
else:
verifRes['principal'] = INV_PR[verifRes['principal']]
verifRes['rolename'] = INV_RN[verifRes['rolename']]
verifRes['member'] = INV_PR[verifRes['member']]
print(f'On-chain verification gas: {verifGas}')
print(f'On-chain verification result: {verifRes}')