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.
- checksums.yaml +7 -0
- data/VERSION +1 -0
- data/lib/mixer/decl_ref.rb +19 -0
- data/lib/mixer/domain_ref.rb +18 -0
- data/lib/mixer/scope.rb +92 -0
- data/lib/mixer/scoped.rb +17 -0
- data/lib/mixer/symbol_ref.rb +16 -0
- data/lib/mixer/type_symbol.rb +75 -0
- data/lib/plugin/plugin.rb +332 -0
- data/lib/resources/correctness/accouns_type.tla +1 -0
- data/lib/resources/correctness/accounts_unique.tla +2 -0
- data/lib/resources/correctness/accounts_valid.tla +2 -0
- data/lib/resources/correctness/storage_root_unique.tla +2 -0
- data/lib/resources/correctness/total_value.tla +1 -0
- data/lib/resources/eth/accounts_state.tla +2 -0
- data/lib/resources/eth/accounts_temp.tla +2 -0
- data/lib/resources/eth/address_free.tla +2 -0
- data/lib/resources/eth/mined_state.tla +1 -0
- data/lib/resources/eth/storageRoot.tla +1 -0
- data/lib/resources/eth/storageRoot_temp.tla +1 -0
- data/lib/resources/mine/mine_entry.tla +4 -0
- data/lib/resources/mine/mine_service.tla +22 -0
- data/lib/resources/operators/elementExists.tla +4 -0
- data/lib/resources/operators/gasPrice.tla +2 -0
- data/lib/resources/operators/gasValue.tla +2 -0
- data/lib/resources/operators/getElement.tla +5 -0
- data/lib/resources/operators/intrinsicGas.tla +4 -0
- data/lib/resources/operators/transactionGas.tla +4 -0
- data/lib/resources/operators/upFrontCost.tla +6 -0
- data/lib/resources/personal_newAccount/personal_newAccount_done.tla +14 -0
- data/lib/resources/personal_newAccount/personal_newAccount_entry.tla +10 -0
- data/lib/resources/personal_newAccount/personal_newAccount_service.tla +29 -0
- data/lib/resources/removed/sendTransaction_entry.tla +5 -0
- data/lib/resources/removed/sendTransaction_service.tla +36 -0
- data/lib/resources/removed/tst.tla +1 -0
- data/lib/resources/transaction/ethereum_service_done.tla +24 -0
- data/lib/resources/transaction/ethereum_service_pop.tla +24 -0
- data/lib/resources/transaction/ethereum_service_push.tla +14 -0
- data/lib/resources/transaction/ethereum_service_start.tla +13 -0
- data/lib/resources/transaction/status_fail.tla +1 -0
- data/lib/resources/transaction/status_ok.tla +1 -0
- data/lib/sbuilder-ethereum.rb +52 -0
- data/lib/sbuilder/compile.rb +163 -0
- data/lib/sbuilder/constants.rb +93 -0
- data/lib/sbuilder/exception.rb +22 -0
- data/lib/sbuilder/generate/sexp_processor_tla.rb +2674 -0
- data/lib/sbuilder/generate/tla_element_generator.rb +1206 -0
- data/lib/sbuilder/generate/tla_element_text.rb +703 -0
- data/lib/sbuilder/load.rb +119 -0
- data/lib/sbuilder/mustache/renderer.rb +152 -0
- data/lib/sbuilder/render.rb +141 -0
- data/lib/sbuilder/s.rb +21 -0
- data/lib/sbuilder/sexp_ast.rb +1378 -0
- data/lib/sbuilder/sexp_processor_api.rb +184 -0
- data/lib/sbuilder/sexp_processor_canonize.rb +326 -0
- data/lib/sbuilder/sexp_processor_dataflow.rb +461 -0
- data/lib/sbuilder/sexp_processor_ethereum.rb +127 -0
- data/lib/sbuilder/sexp_processor_need_to_canonize.rb +572 -0
- data/lib/sbuilder/sexp_processor_snippet.rb +154 -0
- data/lib/sbuilder/sexp_processor_symboltable1.rb +296 -0
- data/lib/sbuilder/sexp_processor_symboltable2.rb +175 -0
- data/lib/sbuilder/sexp_utils.rb +417 -0
- data/lib/utils/logger.rb +82 -0
- data/lib/utils/string_inject.rb +11 -0
- data/sbuilder-ethereum.gemspec +39 -0
- 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
|