sbuilder-ethereum 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/VERSION +1 -0
  3. data/lib/mixer/decl_ref.rb +19 -0
  4. data/lib/mixer/domain_ref.rb +18 -0
  5. data/lib/mixer/scope.rb +92 -0
  6. data/lib/mixer/scoped.rb +17 -0
  7. data/lib/mixer/symbol_ref.rb +16 -0
  8. data/lib/mixer/type_symbol.rb +75 -0
  9. data/lib/plugin/plugin.rb +332 -0
  10. data/lib/resources/correctness/accouns_type.tla +1 -0
  11. data/lib/resources/correctness/accounts_unique.tla +2 -0
  12. data/lib/resources/correctness/accounts_valid.tla +2 -0
  13. data/lib/resources/correctness/storage_root_unique.tla +2 -0
  14. data/lib/resources/correctness/total_value.tla +1 -0
  15. data/lib/resources/eth/accounts_state.tla +2 -0
  16. data/lib/resources/eth/accounts_temp.tla +2 -0
  17. data/lib/resources/eth/address_free.tla +2 -0
  18. data/lib/resources/eth/mined_state.tla +1 -0
  19. data/lib/resources/eth/storageRoot.tla +1 -0
  20. data/lib/resources/eth/storageRoot_temp.tla +1 -0
  21. data/lib/resources/mine/mine_entry.tla +4 -0
  22. data/lib/resources/mine/mine_service.tla +22 -0
  23. data/lib/resources/operators/elementExists.tla +4 -0
  24. data/lib/resources/operators/gasPrice.tla +2 -0
  25. data/lib/resources/operators/gasValue.tla +2 -0
  26. data/lib/resources/operators/getElement.tla +5 -0
  27. data/lib/resources/operators/intrinsicGas.tla +4 -0
  28. data/lib/resources/operators/transactionGas.tla +4 -0
  29. data/lib/resources/operators/upFrontCost.tla +6 -0
  30. data/lib/resources/personal_newAccount/personal_newAccount_done.tla +14 -0
  31. data/lib/resources/personal_newAccount/personal_newAccount_entry.tla +10 -0
  32. data/lib/resources/personal_newAccount/personal_newAccount_service.tla +29 -0
  33. data/lib/resources/removed/sendTransaction_entry.tla +5 -0
  34. data/lib/resources/removed/sendTransaction_service.tla +36 -0
  35. data/lib/resources/removed/tst.tla +1 -0
  36. data/lib/resources/transaction/ethereum_service_done.tla +24 -0
  37. data/lib/resources/transaction/ethereum_service_pop.tla +24 -0
  38. data/lib/resources/transaction/ethereum_service_push.tla +14 -0
  39. data/lib/resources/transaction/ethereum_service_start.tla +13 -0
  40. data/lib/resources/transaction/status_fail.tla +1 -0
  41. data/lib/resources/transaction/status_ok.tla +1 -0
  42. data/lib/sbuilder-ethereum.rb +52 -0
  43. data/lib/sbuilder/compile.rb +163 -0
  44. data/lib/sbuilder/constants.rb +93 -0
  45. data/lib/sbuilder/exception.rb +22 -0
  46. data/lib/sbuilder/generate/sexp_processor_tla.rb +2674 -0
  47. data/lib/sbuilder/generate/tla_element_generator.rb +1206 -0
  48. data/lib/sbuilder/generate/tla_element_text.rb +703 -0
  49. data/lib/sbuilder/load.rb +119 -0
  50. data/lib/sbuilder/mustache/renderer.rb +152 -0
  51. data/lib/sbuilder/render.rb +141 -0
  52. data/lib/sbuilder/s.rb +21 -0
  53. data/lib/sbuilder/sexp_ast.rb +1378 -0
  54. data/lib/sbuilder/sexp_processor_api.rb +184 -0
  55. data/lib/sbuilder/sexp_processor_canonize.rb +326 -0
  56. data/lib/sbuilder/sexp_processor_dataflow.rb +461 -0
  57. data/lib/sbuilder/sexp_processor_ethereum.rb +127 -0
  58. data/lib/sbuilder/sexp_processor_need_to_canonize.rb +572 -0
  59. data/lib/sbuilder/sexp_processor_snippet.rb +154 -0
  60. data/lib/sbuilder/sexp_processor_symboltable1.rb +296 -0
  61. data/lib/sbuilder/sexp_processor_symboltable2.rb +175 -0
  62. data/lib/sbuilder/sexp_utils.rb +417 -0
  63. data/lib/utils/logger.rb +82 -0
  64. data/lib/utils/string_inject.rb +11 -0
  65. data/sbuilder-ethereum.gemspec +39 -0
  66. metadata +190 -0
@@ -0,0 +1,703 @@
1
+ module Sbuilder
2
+ module Ethereum
3
+
4
+
5
+ class TlaElementText
6
+
7
+ # operator body
8
+ OP_INFRASTRUCTURE_SVC_RETURN="TRUE"
9
+
10
+ # OP_INFRA_SET_RESPONSE="InfrastructureServiceResponse"
11
+ OP_INFRA_RETURN="InfrastructureServiceReturn"
12
+ OP_INFRA_GET_RESPONSE="InfrastructureServiceGetResponse"
13
+ OP_INFRA_GET_STATUS="InfrastructureServiceGetStatus"
14
+ OP_INFRA_STATUS_INIT="InfrastructureServiceInit"
15
+ OP_INFRA_THROW="schedule_throw"
16
+ OP_INFRA_UPDATE_TOP='UpdateTop'
17
+ OP_INFRA_RESPONSES='responses'
18
+
19
+ # ------------------------------------------------------------------
20
+ # Wrap snippets - allow extracting snippets from specification code
21
+
22
+ SNIPPET_HEADER="(* ETH-SNIPPET: {{metatype}}:{{appName}} --> {{specName}} *)\n"
23
+ SNIPPET_FOOTER="(* ETH-SNIPPET-END *)\n"
24
+
25
+ # ------------------------------------------------------------------
26
+ # TLA constants
27
+
28
+ TLA_LABEL_ABORT = "_abort"
29
+ TLA_LABEL_END = "_end"
30
+ TLA_LABEL_FAIL = "_fail"
31
+ # TLA_STATUS_OK = "status-200"
32
+ TLA_RECORD_FIELD_FOR_SINGLE_VALUE = "dummy"
33
+ TLA_VARIABLE_STEP="step"
34
+ TLA_VARIABLE_NOW="now"
35
+ TLA_LOCALS_VARIABLE="locals"
36
+ TLA_SERVICE_COMPLETION="ethereum_service_done"
37
+ TLA_SERVICE_START="ethereum_service_start"
38
+ TLA_SERVICE_PUSH="ethereum_service_push"
39
+ TLA_SERVICE_POP="ethereum_service_pop"
40
+ TLA_SERVICE_STATUS_OK="status_OK"
41
+ TLA_SERVICE_STATUS_FAIL="status_FAIL"
42
+ TLA_SERVICE_STATUS_ABORT="Abort"
43
+
44
+ # ------------------------------------------------------------------
45
+ # appNames
46
+ ACCOUNT_TYPE = "Accounts"
47
+ # https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_newaccount
48
+ INTERFACE_ACCOUNT_NEW="personal_newAccount"
49
+ SERVICE_ACCOUNT_NEW="#{INTERFACE_ACCOUNT_NEW}()"
50
+ SERVICE_ACCOUNT_DONE="#{INTERFACE_ACCOUNT_NEW}_done"
51
+ # https://github.com/ethereum/go-ethereum/wiki/Mining#cpu-mining-with-geth
52
+ INTERFACE_MINE="geth_mine"
53
+ # INTERFACE_ACCOUNT_SEND_TRANSACTION="sendTransaction"
54
+ ACCOUNT_STATE = ACCOUNT_TYPE
55
+
56
+ # ------------------------------------------------------------------
57
+ # FRAMEWORK -services
58
+ FW_SVC_UNIQUE_ELEMENTS='uniqueElements'
59
+ FW_OP_ELEMENT_EXISTS = 'elementExists'
60
+ FW_OP_GET_ELEMENT = "getElement"
61
+
62
+ FW_STATE_ACCOUNTS = "accounts"
63
+ FW_STATE_ACCOUNTS_TEMP = "accounts_temp"
64
+ # FW_STATE_GAS_USED = "gasUsed"
65
+ # FW_STATE_GAS_USED_TEMP = "gasUsed_temp"
66
+ FW_STATE_STORAGE_ROOT = 'storageRoot'
67
+ FW_STATE_STORAGE_ROOT_TEMP = 'storageRoot_temp'
68
+ FW_STATE_MINED = 'mined'
69
+
70
+ ETH_OPEATOR_INTRINSIC_GAS = 'intrinsicGas'
71
+ ETH_OPEATOR_TRANSACTION_GAS = 'transactionGas'
72
+ ETH_OPEATOR_UP_FRONT_COST = 'upFrontCost'
73
+ ETH_OPEATOR_GAS_VALUE = 'gasValue'
74
+
75
+ # ------------------------------------------------------------------
76
+ # Domains
77
+
78
+ # ------------------------------------------------------------------
79
+ #
80
+
81
+ # metatype used to create snippets within this module
82
+ METATYPES = {
83
+ :state => { :name => "Solidity contract state" },
84
+ :state_temp => { :name => "Solidity contract state during transaction" },
85
+ :solidity_contract_function => { :name => "Procedures implementing interface services" },
86
+ :service_entry => { :name => "Macros called from process" },
87
+ :type => { :name => "Type sets" },
88
+ :op_new => { :name => "Operator to create new types" },
89
+ :eth => { :name => "Ethereum infrastructure", :prefix => 'eth' },
90
+ :dispatcher => { :name => "Dispatch contract methods", :prefix => 'dispatch' },
91
+ :dispatcher_ret => { :name => "Dispatch contract methods return", :prefix => 'dispatch_ret' },
92
+ }
93
+
94
+ # ------------------------------------------------------------------
95
+ # Ethreum base snippet specs, where +:loaderType+ refers to
96
+ # lambdas defined in +SNIPPETLOADERS+.
97
+
98
+ ETHEREUM_ENVIRONMENT_SNIPPETS = [
99
+
100
+ # ethreum domains
101
+ {
102
+ :loaderType => 'addDomains',
103
+ :definition => [ Constants::DOMAIN_ADDRESS, Constants::DOMAIN_VALUE, Constants::DOMAIN_GAS, Constants::DOMAIN_CODE_HASH, ]
104
+ },
105
+
106
+ # Interface personal_newAccount:
107
+ #
108
+ # Generates a new private key and stores it in the key store
109
+ # directory. The key file is encrypted with the given
110
+ # passphrase. Returns the address of the new account.
111
+ #
112
+ # @see https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_newaccount
113
+ #
114
+ {
115
+ :loaderType => 'addInterface',
116
+ :definition => s( :function, INTERFACE_ACCOUNT_NEW, "",
117
+ s( :input,
118
+ ),
119
+ s( :output,
120
+ s( :parameter, Constants::FIELD_NAME_ADDRESS, Constants::DOMAIN_ADDRESS),
121
+ ),
122
+ )
123
+ },
124
+
125
+ # Geth command line geth --mine
126
+ #
127
+ #
128
+ # must have etherbase address set.
129
+ #
130
+
131
+ {
132
+ :loaderType => 'addInterface',
133
+ :definition => s( :function, INTERFACE_MINE, "",
134
+ s( :input,
135
+ s( :parameter, Constants::FIELD_NAME_VALUE, Constants::DOMAIN_VALUE),
136
+ s( :parameter, Constants::FIELD_NAME_BENEFICIARY, Constants::DOMAIN_ADDRESS),
137
+ ),
138
+ s( :output,
139
+ ),
140
+ )
141
+ },
142
+
143
+
144
+ {
145
+ :loaderType => 'addDefinition',
146
+ :definition => s( :function, ACCOUNT_TYPE,
147
+ s( :properties,
148
+ s( :parameter, Constants::FIELD_NAME_ADDRESS, Constants::DOMAIN_ADDRESS),
149
+ s( :parameter, Constants::FIELD_NAME_CODE_HASH, Constants::DOMAIN_CODE_HASH),
150
+ s( :parameter, Constants::FIELD_NAME_BALANCE, Constants::DOMAIN_VALUE),
151
+ ),
152
+ )
153
+ },
154
+
155
+ ]
156
+
157
+ # Lambda functions to load loaderSpecs defined in
158
+ # +ETHEREUM_SNIPPETS+ into sbuilder context.
159
+ #
160
+ # Lamda functions are executed in SexpProcessorTla context
161
+ # (i.e. they may refer to methods in this class,
162
+ # e.g. 'addSnippet')
163
+
164
+ SNIPPETLOADERS = {
165
+
166
+ 'addDomains' => ->( spec ) do
167
+ # iterate string of domain names to add
168
+ domainNames = spec[:definition]
169
+ domainNames.each{ |domainName| addDomainName( domainName ) }
170
+ end,
171
+
172
+ 'addInterface' => ->( spec ) do
173
+ interface = spec[:definition]
174
+ # define expects input and output to be s( s(:type, name, domain), ... )
175
+ addInterface( Interface.define( interface[1], interface[2], interface.t(:input), interface.t(:output) ) )
176
+ end,
177
+
178
+ 'addDefinition' => ->( spec ) do
179
+ definition = spec[:definition]
180
+ # define expects input and output to be s( s(:type, name, domain), ... )
181
+ addDefinition( Definition.define( definition[1], definition.t(:properties) ))
182
+ end,
183
+
184
+ }
185
+
186
+ # ------------------------------------------------------------------
187
+ # Constant base snippets
188
+
189
+ FIXED_SNIPPETS=
190
+ [
191
+
192
+ # ------------------------------------------------------------------
193
+ # Base snippets - i.e. no connection to ethreums
194
+ {
195
+ :comment => "macro to update existing contract",
196
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
197
+ :appName => 'update_existing_contract',
198
+ :body =>
199
+ <<-EOS.unindent,
200
+ macro update_existing_contract() {
201
+ print <<"update_existing_contract">>;
202
+ }
203
+ EOS
204
+ },
205
+
206
+ {
207
+ :comment => "Add element to sequence head",
208
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
209
+ :appName => 'Push',
210
+ :body =>
211
+ <<-EOS.unindent,
212
+ Push( s, e ) == <<e>> \\o s
213
+ EOS
214
+ },
215
+
216
+ {
217
+ :comment => "Update element to sequence head",
218
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
219
+ :appName => OP_INFRA_UPDATE_TOP,
220
+ :body =>
221
+ <<-EOS.unindent,
222
+ UpdateTop( s, e ) == <<e>> \\o Tail(s)
223
+ EOS
224
+ },
225
+
226
+ {
227
+ :comment => "Propgate top element to stack & pop",
228
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
229
+ :appName => 'PropageTopAndPop',
230
+ :body =>
231
+ <<-EOS.unindent,
232
+ PropageTopAndPop( s ) == [i \\in 1..(Len(s) -1 )|-> s[1] ]
233
+ EOS
234
+ },
235
+
236
+ {
237
+ :comment => "Propgate top element to stack & pop",
238
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
239
+ :appName => 'PropageOnStack',
240
+ :body =>
241
+ <<-EOS.unindent,
242
+ (* PropageOnStack( s, v ) == [i \\in 1..Len(s) |-> v ] *)
243
+ PropageOnStack( s, v ) == [i \\in 1..Len(s) |-> IF i = 1 THEN v ELSE s[i] ]
244
+ EOS
245
+ },
246
+
247
+
248
+ {
249
+ :comment => "macro to create new contract",
250
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
251
+ :appName => 'create_new_contract',
252
+ :body =>
253
+ <<-EOS.unindent,
254
+ macro create_new_contract( var, entry, idPool, id ) {
255
+ print <<"create_new_contract", entry >>;
256
+ var := var \\union { entry };
257
+ idPool := idPool \\ {id};
258
+ }
259
+ EOS
260
+ },
261
+
262
+ {
263
+ :comment => "stable when process finished running",
264
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
265
+ :appName => 'Stable',
266
+ :body =>
267
+ <<-EOS.unindent,
268
+ Stable == tx_running = FALSE
269
+ EOS
270
+ },
271
+
272
+ {
273
+ :comment => "Sum record fields",
274
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
275
+ :appName => 'SumRecordField',
276
+ :body =>
277
+ <<-EOS.unindent,
278
+ RECURSIVE SumRecordField(_,_)
279
+ (*
280
+ * Sum of field 'f' of record elements in set 'S'
281
+ *
282
+ * @param [Set] S set of records
283
+ * @param [String] f name of field
284
+ *)
285
+ SumRecordField(S,f) ==
286
+ IF S = {} THEN 0
287
+ ELSE LET x == CHOOSE x \\in S : TRUE
288
+ IN x[f] + SumRecordField(S \\ {x}, f)
289
+ EOS
290
+ },
291
+
292
+ {
293
+ :comment => "Sum function",
294
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
295
+ :appName => 'SumOfFunction',
296
+ :body =>
297
+ <<-EOS.unindent,
298
+ RECURSIVE SumOfFunction(_)
299
+ (*
300
+ * Sum of function values
301
+ *
302
+ * @param [Sequnce|Function] F to sum over
303
+ *
304
+ *)
305
+ SumOfFunction( F ) ==
306
+ IF F = <<>> THEN 0
307
+ ELSE LET x == CHOOSE x \\in DOMAIN F : TRUE
308
+ IN F[x] + SumOfFunction( [ v \\in DOMAIN F \\ {x} |-> F[v] ] )
309
+ EOS
310
+ },
311
+
312
+ {
313
+ :comment => "operator to check element uniques in a set",
314
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
315
+ :appName => FW_SVC_UNIQUE_ELEMENTS,
316
+ :body =>
317
+ <<-EOS.unindent,
318
+ #{FW_SVC_UNIQUE_ELEMENTS}( set, key ) == \\A e1 \\in set: \\A e2 \\in set: e1[key] = e2[key] => e1 = e2
319
+ EOS
320
+ },
321
+
322
+ {
323
+ :comment => "Take given 'address', or choose any address from pool of 'ids'. Notice (CHOOSE operation is deterministic)",
324
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
325
+ :appName => 'NextId',
326
+ :body =>
327
+ <<-EOS.unindent,
328
+ NextId( ids, address ) == CHOOSE x \\in ids: (address = x /\\ address # Nil) \\/ address = Nil
329
+ EOS
330
+ },
331
+
332
+
333
+ # ------------------------------------------------------------------
334
+ # Ethereum related snippets
335
+
336
+ # Service: personal_newAccount
337
+ {
338
+ :comment => 'Interface service "createAccount"',
339
+ :metatype => 'eth',
340
+ :appName => INTERFACE_ACCOUNT_NEW,
341
+ :file => 'personal_newAccount/personal_newAccount_service.tla'
342
+ },
343
+
344
+ {
345
+ :comment => 'Interface entry for "createAccount"',
346
+ :metatype => 'service_implementation',
347
+ :appName => SERVICE_ACCOUNT_NEW,
348
+ :file => 'personal_newAccount/personal_newAccount_entry.tla',
349
+ },
350
+
351
+ {
352
+ :comment => 'Finalize "personal_newAccount"',
353
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
354
+ :appName => SERVICE_ACCOUNT_DONE,
355
+ :file => 'personal_newAccount/personal_newAccount_done.tla',
356
+ },
357
+
358
+ {
359
+ :comment => "Use completion #{SERVICE_ACCOUNT_DONE} for service #{SERVICE_ACCOUNT_NEW}",
360
+ :metatype => Sbuilder::Facade::META_MODEL_SERVICE_COMPLETION,
361
+ :appName => SERVICE_ACCOUNT_NEW,
362
+ :specName => SERVICE_ACCOUNT_DONE,
363
+ },
364
+
365
+ # Service: mine
366
+ {
367
+ :comment => 'Interface service "mine"',
368
+ :metatype => 'eth',
369
+ :appName => 'mine',
370
+ :file => 'mine/mine_service.tla'
371
+ },
372
+
373
+ {
374
+ :comment => 'Interface entry for "mine"',
375
+ :metatype => 'service_implementation',
376
+ :appName => 'geth_mine()',
377
+ :file => 'mine/mine_entry.tla',
378
+ },
379
+
380
+
381
+ # State:
382
+
383
+ {
384
+ :comment => 'Accounts created in the system',
385
+ :metatype => 'eth',
386
+ :appName => FW_STATE_ACCOUNTS,
387
+ :file => 'eth/accounts_state.tla',
388
+ },
389
+
390
+ {
391
+ :comment => 'Account storageRoot (contract state)',
392
+ :metatype => 'eth',
393
+ :appName => FW_STATE_STORAGE_ROOT,
394
+ :file => 'eth/storageRoot.tla',
395
+ },
396
+
397
+ {
398
+ :comment => 'storageRoot temporary state during service execution',
399
+ :metatype => 'eth',
400
+ :appName => FW_STATE_STORAGE_ROOT_TEMP,
401
+ :file => 'eth/storageRoot_temp.tla',
402
+ },
403
+
404
+
405
+ {
406
+ :comment => 'accounts temporary state during service execution',
407
+ :metatype => 'eth',
408
+ :appName => FW_STATE_ACCOUNTS_TEMP,
409
+ :file => 'eth/accounts_temp.tla',
410
+ },
411
+
412
+
413
+ {
414
+ :comment => 'Set of unassigned addresses',
415
+ :metatype => 'eth',
416
+ :appName => 'address_free',
417
+ :file => 'eth/address_free.tla',
418
+ },
419
+
420
+ # {
421
+ # :comment => 'Cumulative amount of gas used',
422
+ # :metatype => 'eth',
423
+ # :appName => FW_STATE_GAS_USED,
424
+ # :file => "eth/#{FW_STATE_GAS_USED}.tla",
425
+ # },
426
+
427
+ # {
428
+ # :comment => 'Cumulative amount of gas used during service execution',
429
+ # :metatype => 'eth',
430
+ # :appName => FW_STATE_GAS_USED_TEMP,
431
+ # :file => "eth/gasUsed_temp.tla",
432
+ # },
433
+
434
+ {
435
+ :comment => 'Return element form a set by id',
436
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
437
+ :appName => FW_OP_GET_ELEMENT,
438
+ :file => 'operators/getElement.tla',
439
+ },
440
+
441
+ {
442
+ :comment => 'Ensure that element exists',
443
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
444
+ :appName => FW_OP_ELEMENT_EXISTS,
445
+ :file => 'operators/elementExists.tla',
446
+ },
447
+
448
+ {
449
+ :comment => 'Value mined',
450
+ :metatype => 'eth',
451
+ :appName => FW_STATE_MINED,
452
+ :file => 'eth/mined_state.tla',
453
+ },
454
+
455
+ # transction & status stuff
456
+ {
457
+ :comment => 'Pop ethreum block context from stack',
458
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
459
+ :appName => TLA_SERVICE_COMPLETION,
460
+ :file => 'transaction/ethereum_service_done.tla',
461
+ },
462
+
463
+ {
464
+ :comment => 'Start ethereum transaction, create stack',
465
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
466
+ :appName => TLA_SERVICE_START,
467
+ :file => 'transaction/ethereum_service_start.tla',
468
+ },
469
+
470
+ {
471
+ :comment => 'Push ethereum block context to stack',
472
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
473
+ :appName => TLA_SERVICE_PUSH,
474
+ :file => 'transaction/ethereum_service_push.tla',
475
+ },
476
+
477
+
478
+ {
479
+ :comment => 'Finish service procedure: propage stack top on succcess && pop',
480
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
481
+ :appName => TLA_SERVICE_POP,
482
+ :file => 'transaction/ethereum_service_pop.tla',
483
+ },
484
+
485
+ {
486
+ :comment => 'Service ran successfully',
487
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
488
+ :appName => TLA_SERVICE_STATUS_OK,
489
+ :file => 'transaction/status_ok.tla',
490
+ },
491
+
492
+
493
+ {
494
+ :comment => 'Service execution failed',
495
+ :metatype => Sbuilder::Facade::META_MODEL_FRAMEWORK_SVC,
496
+ :appName => TLA_SERVICE_STATUS_FAIL,
497
+ :file => 'transaction/status_fail.tla',
498
+ },
499
+
500
+ # {
501
+ # :comment => 'Interface entry for "sendTransaction"',
502
+ # :metatype => 'service_implementation',
503
+ # :appName => 'sendTransaction()',
504
+ # :file => 'sendTransaction_entry.tla',
505
+ # },
506
+
507
+ # {
508
+ # :comment => 'Interface service for "sendTransaction"',
509
+ # :metatype => 'framework-svc',
510
+ # :appName => 'sendTransaction',
511
+ # :file => 'sendTransaction_service.tla',
512
+ # },
513
+
514
+ {
515
+ :comment => 'Operator calculating value of gas (using gasPrice)',
516
+ :metatype => 'framework-svc',
517
+ :appName => ETH_OPEATOR_GAS_VALUE,
518
+ :file => 'operators/gasValue.tla',
519
+ },
520
+
521
+ {
522
+ :comment => 'Price of gas used to calculate value of gas',
523
+ :metatype => 'framework-svc',
524
+ :appName => 'gasPrice',
525
+ :file => 'operators/gasPrice.tla',
526
+ },
527
+
528
+ {
529
+ :comment => 'Gas paid prior to execution',
530
+ :metatype => 'framework-svc',
531
+ :appName => ETH_OPEATOR_INTRINSIC_GAS,
532
+ :file => "operators/#{ETH_OPEATOR_INTRINSIC_GAS}.tla",
533
+ },
534
+
535
+ {
536
+ :comment => 'Amount of gas consumed when running the transaction',
537
+ :metatype => 'framework-svc',
538
+ :appName => ETH_OPEATOR_TRANSACTION_GAS,
539
+ :file => 'operators/transactionGas.tla',
540
+ },
541
+
542
+ {
543
+ :comment => 'Acount balance must exceed upFronCost before starting',
544
+ :metatype => 'framework-svc',
545
+ :appName => ETH_OPEATOR_UP_FRONT_COST,
546
+ :file => "operators/#{ETH_OPEATOR_UP_FRONT_COST}.tla",
547
+ },
548
+
549
+
550
+ # ------------------------------------------------------------------
551
+ # correctness
552
+
553
+ {
554
+
555
+ :metatype => 'framework-svc',
556
+ :appName => 'accounts_unique',
557
+ :file => 'correctness/accounts_unique.tla'
558
+ },
559
+
560
+ {
561
+
562
+ :metatype => 'framework-svc',
563
+ :appName => 'storageRoot_unique',
564
+ :file => 'correctness/storage_root_unique.tla'
565
+ },
566
+
567
+ {
568
+ :comment => 'Invariant operator to check that accounts are valid',
569
+ :metatype => 'framework-svc',
570
+ appName: 'accounts_valid',
571
+ :file => 'correctness/accounts_valid.tla',
572
+ },
573
+
574
+ {
575
+ :comment => 'SUM( accounts.balance ) + mined == 0',
576
+ :metatype => 'framework-svc',
577
+ appName: 'total_value',
578
+ :file => 'correctness/total_value.tla',
579
+ },
580
+
581
+ {
582
+ :comment => 'Invariant operator to account type',
583
+ :metatype => 'framework-svc',
584
+ appName: 'accounts_type',
585
+ :file => 'correctness/accouns_type.tla',
586
+ },
587
+
588
+ ]
589
+
590
+ def self.fixedSnippetSpecs
591
+ FIXED_SNIPPETS
592
+ end
593
+
594
+ # @return [Boolean] true if numeric type name 'uint', ..
595
+ def self.solIsNumericType( solType )
596
+ ['uint'].include?( solType )
597
+ end
598
+
599
+ ##
600
+ # @return [Hash] loaderSpec to feed lamdba returned by
601
+ # +getLoaderLamdba+
602
+ def self.ethereumSnippetSpecs
603
+ ETHEREUM_ENVIRONMENT_SNIPPETS
604
+ end
605
+
606
+ ##
607
+ # @return [Lambda] lamda to process +loaderSpec+ hashes returned
608
+ # by +ethereumSnippetSpecs+. Lamdba is executed in
609
+ # SexpProcessorTla context.
610
+ def self.getLoaderLamdba( spec )
611
+ loaderType = spec[:loaderType]
612
+ raise SbuilderEtherumException, "Unknwon loaderType '#{loaderType}' in #{spec}" unless SNIPPETLOADERS[loaderType]
613
+ SNIPPETLOADERS[loaderType]
614
+ end
615
+
616
+ # Map table to map solc (javascript) operator to TLA operator
617
+ SOLC_OPEATOR_2_TLA = {
618
+ '<' => '<',
619
+ '>' => '>',
620
+ '==' => '=',
621
+ '<=' => '<=',
622
+ '>=' => '>=',
623
+ '!=' => '#',
624
+ '!' => '~',
625
+ '+' => '+',
626
+ '-' => '-',
627
+ }
628
+
629
+ ##
630
+ # @return [String] tlaOperator corresponding to solcOparator
631
+ def self.solcOperator2Tla( solcOperator )
632
+ tlaOperator = SOLC_OPEATOR_2_TLA[solcOperator]
633
+ raise SbuilderEtherumException, "Unknwon solcOparator '#{solcOperator}', known operators #{SOLC_OPEATOR_2_TLA.keys.join(',')}" if tlaOperator.nil?
634
+ tlaOperator
635
+ end
636
+
637
+ # @return [String] name of composite variable 'expVariableDecl'
638
+ # definition in contract 'expContract'
639
+ def self.compositeDefinitionName( expContract, expVariableDecl )
640
+ name = "#{expContract.name}_#{expVariableDecl.name}"
641
+ end
642
+
643
+ ##
644
+ # These are added to all contract messages.
645
+ #
646
+ #
647
+ # @param [String] reqOrResponse 'request' or 'response'
648
+ #
649
+ # @param [String] messageType true for 'constructor',
650
+ # false 'method-call' return different fields
651
+ #
652
+ # @return [Sexp:Array] msgProperties
653
+ # @option msgProperties [0] :parameter
654
+ # @option msgProperties [1] name
655
+ # @option msgProperties [2] domain_name
656
+ def self.commonMsgProperties( reqOrResponse, messageType )
657
+ props =
658
+ {
659
+ 'request' => {
660
+ true =>
661
+ # constructor
662
+ s(
663
+ s( :parameter, Constants::FIELD_NAME_SENDER, Constants::DOMAIN_ADDRESS),
664
+ s( :parameter, Constants::FIELD_NAME_ORIGINATOR, Constants::DOMAIN_ADDRESS),
665
+ s( :parameter, Constants::FIELD_NAME_VALUE, Constants::DOMAIN_VALUE ),
666
+ # s( :parameter, Constants::FIELD_NAME_GAS, Constants::DOMAIN_GAS ),
667
+ ),
668
+ false =>
669
+ # contract function
670
+ s(
671
+ s( :parameter, Constants::FIELD_NAME_SENDER, Constants::DOMAIN_ADDRESS),
672
+ s( :parameter, Constants::FIELD_NAME_ORIGINATOR, Constants::DOMAIN_ADDRESS),
673
+ s( :parameter, Constants::FIELD_NAME_RECIPIENT, Constants::DOMAIN_ADDRESS),
674
+ s( :parameter, Constants::FIELD_NAME_VALUE, Constants::DOMAIN_VALUE ),
675
+ # s( :parameter, Constants::FIELD_NAME_GAS, Constants::DOMAIN_GAS ),
676
+ ),
677
+
678
+ },
679
+ 'response' => {
680
+ # constructor
681
+ true => s(
682
+ s( :parameter, Constants::FIELD_NAME_ADDRESS, Constants::DOMAIN_ADDRESS),
683
+ ),
684
+ false => s()
685
+ },
686
+ 'response-bool' => {
687
+ # constructor
688
+ true => s(
689
+ s( :parameter, Constants::FIELD_NAME_STATUS, Constants::DOMAIN_BOOLEAN),
690
+ ),
691
+ false => s(
692
+ s( :parameter, Constants::FIELD_NAME_STATUS, Constants::DOMAIN_BOOLEAN),
693
+ )
694
+ }
695
+ }
696
+ raise SbuilderEtherumException, "Unknwon messageType '#{messageType}', expecting #{props[reqOrResponse].keys.join(',')}" unless props[reqOrResponse][messageType]
697
+ props[reqOrResponse][messageType]
698
+ end
699
+
700
+ end
701
+
702
+ end
703
+ end