Skip to content

Commit d225dfc

Browse files
cmickeybprakashngit
authored andcommitted
restructure create plugin command to enable broader client access
Signed-off-by: Mic Bowman <[email protected]>
1 parent b4a4c5d commit d225dfc

File tree

2 files changed

+64
-42
lines changed

2 files changed

+64
-42
lines changed

client/pdo/client/controller/commands/create.py

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import os
1516
import argparse
1617
import logging
1718
import random
@@ -33,7 +34,7 @@
3334
__all__ = ['command_create']
3435

3536
## -----------------------------------------------------------------
36-
def __add_enclave_secrets(ledger_config, contract_id, client_keys, enclaveclients, provclients) :
37+
def __add_enclave_secrets__(ledger_config, contract_id, client_keys, enclaveclients, provclients) :
3738
"""Create and provision the encrypted secrets for each of the
3839
enclaves that will be provisioned for this contract.
3940
"""
@@ -76,7 +77,7 @@ def __add_enclave_secrets(ledger_config, contract_id, client_keys, enclaveclient
7677
return encrypted_state_encryption_keys
7778

7879
## -----------------------------------------------------------------
79-
def __create_contract(ledger_config, client_keys, preferred_eservice_client, eservice_clients, contract) :
80+
def __create_contract__(ledger_config, client_keys, preferred_eservice_client, eservice_clients, contract) :
8081
"""Create the initial contract state
8182
"""
8283

@@ -106,30 +107,27 @@ def __create_contract(ledger_config, client_keys, preferred_eservice_client, ese
106107

107108
## -----------------------------------------------------------------
108109
## -----------------------------------------------------------------
109-
def command_create(state, bindings, pargs) :
110-
"""controller command to create a contract
110+
def create_contract(state, save_file, contract_source, **kwargs) :
111+
"""Expose the contract creation logic to other client applications
112+
113+
@param save_file: file name for the local contract information
114+
@param contract_source : path to the contract source file
115+
@param contract_class : optional parameter to specific class in the contract source
116+
@param eservice_group : name of the eservice group to provision the contract
117+
@param pservice_group : name of the pservice group to provision the contract
118+
@param interpreter : name of the interpreter that is expected from the eservices
119+
@param state_replicas : number of mandatory copies of state
120+
@param state_duration : minimum duration replicas must be available
121+
@param extra_data : opaque data that can be store in the contract file
111122
"""
112-
default_interpreter = state.get(['Contract', 'Interpreter'])
113-
default_replicas = state.get(['Replication', 'NumProvableReplicas'], 2)
114-
default_duration = state.get(['Replication', 'Duration'], 120)
115-
116-
parser = argparse.ArgumentParser(prog='create')
117-
parser.add_argument('-c', '--contract-class', help='Name of the contract class', required=False, type=str)
118-
parser.add_argument('-e', '--eservice-group', help='Name of the enclave service group to use', default="default")
119-
parser.add_argument('-f', '--save-file', help='File where contract data is stored', type=str)
120-
parser.add_argument('-i', '--interpreter', help='Interpreter used to evaluate the contract', default=default_interpreter)
121-
parser.add_argument('-p', '--pservice-group', help='Name of the provisioning service group to use', default="default")
122-
parser.add_argument('-s', '--contract-source', help='File that contains contract source code', required=True, type=str)
123-
124-
parser.add_argument('--symbol', help='binding symbol for result', type=str)
125-
parser.add_argument('--state-replicas', help='Number of authoritative replicas of the state', default=default_replicas)
126-
parser.add_argument('--state-duration', help='Duration required for state replicas', default=default_duration)
127-
parser.add_argument('--extra-data', help='Simple string that can save extra data with the contract file', type=str)
128-
129-
options = parser.parse_args(pargs)
130123

131-
contract_class = options.contract_class
132-
contract_source = options.contract_source
124+
contract_class = kwargs.get('contract_class') or os.path.basename(contract_source)
125+
eservice_group = kwargs.get('eservice_group') or 'default'
126+
pservice_group = kwargs.get('pservice_group') or 'default'
127+
interpreter = kwargs.get('interpreter') or state.get(['Contract', 'Interpreter'])
128+
state_replicas = kwargs.get('state_replicas') or state.get(['Replication', 'NumProvableReplicas'], 2)
129+
state_duration = kwargs.get('state_duration') or state.get(['Replication', 'Duration'], 120)
130+
extra_data = kwargs.get('extra_data')
133131

134132
# ---------- load the invoker's keys ----------
135133
try :
@@ -143,38 +141,38 @@ def command_create(state, bindings, pargs) :
143141
try :
144142
source_path = state.get(['Contract', 'SourceSearchPath'])
145143
contract_code = ContractCode.create_from_file(
146-
contract_class, contract_source, source_path, interpreter=options.interpreter)
144+
contract_class, contract_source, source_path, interpreter=interpreter)
147145
except Exception as e :
148146
raise Exception('unable to load contract source; {0}'.format(str(e)))
149147

150148
logger.debug('Loaded contract code for %s', contract_class)
151149

152150
# ---------- set up the enclave clients ----------
153-
eservice_clients = get_eservice_list(state, options.eservice_group)
151+
eservice_clients = get_eservice_list(state, eservice_group)
154152
if len(eservice_clients) == 0 :
155-
raise Exception('unable to locate enclave services in the group %s', options.eservice_group)
153+
raise Exception('unable to locate enclave services in the group %s', eservice_group)
156154

157-
preferred_eservice_client = get_eservice(state, eservice_group=options.eservice_group)
158-
if preferred_eservice_client.interpreter != options.interpreter :
159-
raise Exception('enclave interpreter does not match requested contract interpreter %s', options.interpreter)
155+
preferred_eservice_client = get_eservice(state, eservice_group=eservice_group)
156+
if preferred_eservice_client.interpreter != interpreter :
157+
raise Exception('enclave interpreter does not match requested contract interpreter %s', interpreter)
160158

161159
# ---------- set up the provisioning service clients ----------
162-
pservice_clients = get_pservice_list(state, options.pservice_group)
160+
pservice_clients = get_pservice_list(state, pservice_group)
163161
if len(pservice_clients) == 0 :
164-
raise Exception('unable to locate provisioning services in the group %s', options.pservice_group)
162+
raise Exception('unable to locate provisioning services in the group %s', pservice_group)
165163

166164
# ---------- register contract ----------
167165
data_directory = state.get(['Contract', 'DataDirectory'])
168166
ledger_config = state.get(['Ledger'])
169167

170168
try :
171169
extra_params = {
172-
'num_provable_replicas' : options.state_replicas,
173-
'availability_duration' : options.state_duration,
170+
'num_provable_replicas' : state_replicas,
171+
'availability_duration' : state_duration,
174172
}
175173

176-
if options.extra_data :
177-
extra_params['extra_data'] = options.extra_data
174+
if extra_data :
175+
extra_params['extra_data'] = extra_data
178176

179177
provisioning_service_keys = [pc.identity for pc in pservice_clients]
180178
contract_id = register_contract(
@@ -188,8 +186,8 @@ def command_create(state, bindings, pargs) :
188186
contract.extra_data['preferred-enclave'] = preferred_eservice_client.enclave_id
189187

190188
contract_file = "{0}_{1}.pdo".format(contract_class, contract.short_id)
191-
if options.save_file :
192-
contract_file = options.save_file
189+
if save_file :
190+
contract_file = save_file
193191

194192
contract.save_to_file(contract_file, data_dir=data_directory)
195193

@@ -198,7 +196,7 @@ def command_create(state, bindings, pargs) :
198196

199197
# provision the encryption keys to all of the enclaves
200198
try :
201-
encrypted_state_encryption_keys = __add_enclave_secrets(
199+
encrypted_state_encryption_keys = __add_enclave_secrets__(
202200
ledger_config, contract.contract_id, client_keys, eservice_clients, pservice_clients)
203201

204202
for enclave_id in encrypted_state_encryption_keys :
@@ -211,11 +209,35 @@ def command_create(state, bindings, pargs) :
211209

212210
# create the initial contract state
213211
try :
214-
__create_contract(ledger_config, client_keys, preferred_eservice_client, eservice_clients, contract)
212+
__create_contract__(ledger_config, client_keys, preferred_eservice_client, eservice_clients, contract)
215213

216214
contract.save_to_file(contract_file, data_dir=data_directory)
217215
except Exception as e :
218216
raise Exception('failed to create the initial contract state; {0}'.format(str(e)))
219217

218+
return contract_file
219+
220+
## -----------------------------------------------------------------
221+
## -----------------------------------------------------------------
222+
def command_create(state, bindings, pargs) :
223+
"""controller command to create a contract
224+
"""
225+
226+
parser = argparse.ArgumentParser(prog='create')
227+
parser.add_argument('-c', '--contract-class', help='Name of the contract class', type=str)
228+
parser.add_argument('-e', '--eservice-group', help='Name of the enclave service group to use', type=str)
229+
parser.add_argument('-f', '--save-file', help='File where contract data is stored', type=str)
230+
parser.add_argument('-i', '--interpreter', help='Interpreter used to evaluate the contract', type=str)
231+
parser.add_argument('-p', '--pservice-group', help='Name of the provisioning service group to use', type=str)
232+
parser.add_argument('-s', '--contract-source', help='File that contains contract source code', required=True, type=str)
233+
234+
parser.add_argument('--symbol', help='binding symbol for result', type=str)
235+
parser.add_argument('--state-replicas', help='Number of authoritative replicas of the state', type=int)
236+
parser.add_argument('--state-duration', help='Duration required for state replicas', type=int)
237+
parser.add_argument('--extra-data', help='Simple string that can save extra data with the contract file', type=str)
238+
239+
options = parser.parse_args(pargs)
240+
241+
contract_id = create_contract(state, **vars(options))
220242
if contract_id and options.symbol :
221243
bindings.bind(options.symbol, contract_id)

client/pdo/client/controller/contract_controller.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ def bind(self, variable, value) :
130130
return saved
131131

132132
# --------------------------------------------------
133-
def isbound(self, variable) :
134-
return variable in self.__bindings__
133+
def isbound(self, variable, default_value=None) :
134+
return self.__bindings__.get(variable, default_value)
135135

136136
# --------------------------------------------------
137137
def expand(self, argstring) :

0 commit comments

Comments
 (0)