sbuilder-ethereum 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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,184 @@
1
+ module Sbuilder;
2
+ module Ethereum
3
+ ##
4
+ # Load Api information to sbuilder using facade
5
+
6
+ class SexpProcessorApi < SexpProcessorEthereum
7
+
8
+ # ------------------------------------------------------------------
9
+ # Attributes
10
+
11
+ # @attr [ApiLoaderFacade] apiFacade
12
+ attr_accessor :apiFacade
13
+
14
+ # ------------------------------------------------------------------
15
+ # Maintain state in tree tarversal
16
+
17
+
18
+ # @attr [ParamSet_If] currentInterface
19
+ attr_accessor :currentInterface
20
+
21
+ # @attr [ParamSetDef_If] currentDefinition
22
+ attr_accessor :currentDefinition
23
+
24
+ # @attr [ParamSetRoot:Stack] paramSetStack
25
+ attr_reader :paramSetStack
26
+
27
+ # ------------------------------------------------------------------
28
+ # @!group Construct & configure
29
+
30
+ def initialize( options={} )
31
+ super( options )
32
+ @paramSetStack = []
33
+ end
34
+
35
+ # @!endgroup
36
+
37
+ # ------------------------------------------------------------------
38
+ # @!group wrap interfaces
39
+
40
+
41
+ # @param [Interface] expInterface
42
+ def encloseInterface( expInterface )
43
+ logger.info "#{__method__}: #{expInterface}"
44
+
45
+ raise "Invalid call sequence, should have callde #apiFacade= before #process" unless apiFacade
46
+
47
+ # create new interface
48
+ self.currentInterface = apiFacade.newInterface( expInterface.path, expInterface.op )
49
+
50
+ begin
51
+ # build new interface
52
+ yield
53
+ ensure
54
+ # pass interface object built to sbuilder
55
+ apiFacade.modelInterface( currentInterface )
56
+ self.currentInterface = nil
57
+ end
58
+ end
59
+
60
+ def encloseDefinition( expDefinition )
61
+ logger.info "#{__method__}: #{expDefinition}"
62
+
63
+ raise "Invalid call sequence, should have callde #apiFacade= before #process" unless apiFacade
64
+
65
+ # create new definition based on 'expDefinition.definitionType'
66
+ case expDefinition.definitionType
67
+ when :normal
68
+ self.currentDefinition = apiFacade.newDefinition( expDefinition.name )
69
+ when :function
70
+ self.currentDefinition = apiFacade.newFunctionDefinition( expDefinition.name )
71
+ else
72
+ raise "Unknown definitionType #{expDefinition.definitionType}"
73
+ end
74
+
75
+ begin
76
+ # build new interface
77
+ yield currentDefinition
78
+ ensure
79
+ # pass definition object built to sbuilder
80
+ apiFacade.modelDefinition( currentDefinition )
81
+ self.currentDefinition = nil
82
+ end
83
+ end
84
+
85
+
86
+ def encloseParameterList( expParameterList )
87
+ logger.info "#{__method__}: currentInterface=#{currentInterface}"
88
+ paramSetStack.push( currentInterface )
89
+ begin
90
+ # traverse the tree under the newly created scope
91
+ yield
92
+ ensure
93
+ paramSetStack.pop
94
+ end
95
+ end
96
+
97
+ # ------------------------------------------------------------------
98
+ # @!group Sexp node actions
99
+
100
+ def process_Definition( exp )
101
+ logger.info "#{__method__}: #{exp}"
102
+
103
+ encloseDefinition( exp ) do |paramSet|
104
+
105
+ exp.properties.each do |prop|
106
+ if prop[:type] == :parameter
107
+ sbuilderParameter = apiFacade.newParameter( prop[:name] )
108
+ domainName = prop[:domain_name]
109
+ logger.debug "#{__method__}: add definition parameter=#{sbuilderParameter} with domain '#{domainName}' for prop=#{prop}" if logger.debug?
110
+ apiFacade.addParameter( paramSet, sbuilderParameter, domainName )
111
+ elsif prop[:type] == :reference
112
+ isArray = false
113
+ sbuilderParameter = apiFacade.newParameterReference( prop[:name], prop[:reference], isArray )
114
+ logger.debug "#{__method__}: add definition parameter=#{sbuilderParameter} for prop=#{prop}" if logger.debug?
115
+ apiFacade.addParameter( paramSet, sbuilderParameter )
116
+ else
117
+ raise "Unknown :type #{prop[:type]} in #{prop}, knwon types ':parameter', ':reference'"
118
+ end
119
+ # add it to the parameter list on top of the stack
120
+ end
121
+
122
+ end
123
+
124
+ s()
125
+ end
126
+
127
+ def process_Interface( exp )
128
+ logger.info "#{__method__}: #{exp}"
129
+
130
+ encloseInterface( exp ) do
131
+
132
+ encloseParameterList( exp ) do
133
+
134
+ # processing arameter set on top of the stack
135
+ paramSet = paramSetStack.last
136
+
137
+ exp.interfaceDefinition[:input].each do |param|
138
+ sbuilderParameter = apiFacade.newParameter( param[:name] )
139
+ logger.info "#{__method__}: add input parameter=#{sbuilderParameter}"
140
+ # add it to the parameter list on top of the stack
141
+ apiFacade.addParameter( paramSet, sbuilderParameter, param[:domain_name] )
142
+ end
143
+
144
+ exp.interfaceDefinition[:output].each do |param|
145
+ sbuilderParameter = apiFacade.newParameter( param[:name] )
146
+ logger.info "#{__method__}: add outpu parameter=#{sbuilderParameter}"
147
+ apiFacade.addResponseParameter( paramSet, sbuilderParameter, param[:domain_name] )
148
+ end
149
+
150
+ # process_rest( exp.inputParameters )
151
+ end
152
+ end
153
+ s()
154
+ end
155
+
156
+ # def process_ParameterList( exp )
157
+ # raise "no support for recursive ParameterList"
158
+ # # logger.info "#{__method__}"
159
+ # # encloseParameterList( exp ) do
160
+ # # process_rest( exp )
161
+ # # end
162
+ # end
163
+
164
+ # def process_VariableDeclaration( exp )
165
+ # logger.info "#{__method__}: #{exp}}"
166
+ # raise "Support only elementary types" unless exp.isElementary
167
+
168
+ # # create elementary parameter
169
+ # sbuilderParameter = apiFacade.newParameter( exp.name )
170
+
171
+ # # add it to the parameter list on top of the stack
172
+ # paramSetStack.last.addParameter( sbuilderParameter )
173
+ # s()
174
+ # end
175
+
176
+
177
+ # @!endgroup
178
+
179
+
180
+ end # class
181
+
182
+
183
+ end
184
+ end
@@ -0,0 +1,326 @@
1
+ module Sbuilder
2
+ module Ethereum
3
+
4
+ require 'yaml'
5
+ require 'json'
6
+
7
+ ##
8
+ # SexpProcessorCanonize know how to canonize SexpAst. It expect
9
+ # +SexpProcessorNeedToCanonize+ object in +needs+ attribute to
10
+ # know, what needs to be canonized. After canonization, this
11
+ # method returns +somethingCanonized+
12
+ #
13
+ # - constructor - if missing
14
+ # - balance - if missing
15
+ # - getter methods - if missing
16
+ #
17
+ # Generates unique identifiers using static variable +idGenerator+
18
+ #
19
+ #
20
+ #
21
+
22
+ class SexpProcessorCanonize < SexpProcessorEthereum
23
+
24
+
25
+
26
+ # @attr [SexpProcessorNeedToCanonize] needs SexpProcessor, which
27
+ # knows what needs to be added to SexpAst -tree.
28
+ attr_reader :needs
29
+
30
+
31
+ # @attr [Hash] optionss
32
+ attr_reader :options
33
+
34
+ # @attr [Boolean] somethingCanonized true if any chg in SexpTree
35
+ attr_reader :somethingCanonized
36
+
37
+ # @attr [String] compileUnit for better log message
38
+ attr_reader :compileUnit
39
+
40
+ # ------------------------------------------------------------------
41
+ # @!group Scoped
42
+
43
+ # @attr [Contract] currentContract which currently processing
44
+ attr_accessor :currentContract
45
+
46
+ # @attr [FunctionDefinition] currentFunction
47
+ attr_accessor :currentFunction
48
+
49
+
50
+ def contracted( expContract )
51
+
52
+ self.currentContract = expContract
53
+ begin
54
+ yield
55
+ ensure
56
+ self.currentContract = nil
57
+ end
58
+ end
59
+
60
+ def functed( expFunctionDef )
61
+ self.currentFunction = expFunctionDef
62
+
63
+ begin
64
+ yield
65
+ ensure
66
+ self.currentFunction = nil
67
+ end
68
+
69
+ end
70
+
71
+ # @!endgroup
72
+
73
+
74
+ # ------------------------------------------------------------------
75
+ # @!group Construct & init & configure
76
+
77
+ def initialize( options={} )
78
+ super( options )
79
+ logger.debug "#{__method__}: created" if logger.debug?
80
+
81
+ @options = options
82
+
83
+ initIt
84
+ end
85
+
86
+
87
+ ##
88
+ # Init +needs+ which knows what to canonize
89
+ # MUST BE CALLED FOR EACH FIX POINT ITERATION
90
+ def setNeeds( sexpProcessorNeedToCanonize )
91
+ @needs = sexpProcessorNeedToCanonize
92
+ initIt
93
+ end
94
+
95
+ ##
96
+ # better log messages
97
+ def setCompileUnit( compileUnit )
98
+ @compileUnit = compileUnit
99
+ end
100
+
101
+ def initIt
102
+ # default no changes - toggle if changed
103
+ @somethingCanonized = false
104
+ end
105
+
106
+ # @!endgroup
107
+
108
+ # ------------------------------------------------------------------
109
+ # @!group scope support
110
+
111
+ # @attr [Contract] currentContract which currently processing
112
+ attr_accessor :currentContract
113
+
114
+ def contracted( expContract )
115
+
116
+ @currentContract = expContract
117
+ begin
118
+ yield
119
+ ensure
120
+ @currentContract = nil
121
+ end
122
+ end
123
+
124
+ ##
125
+ # Set flag +somethingCanonized+ to indicate that SexpAst has been modified
126
+ def addNewNode( exp, chldExp )
127
+
128
+ logger.debug "#{__method__}: add #{chldExp}, to #{exp}" if logger.debug?
129
+
130
+ # # Added as child --> add pointer to parent
131
+ # chldExp.setParent( exp )
132
+ # exp << chldExp
133
+ SexpUtils.addNewChild( exp, chldExp )
134
+
135
+ # Iterate as long as something has changed
136
+ @somethingCanonized = true
137
+ end
138
+
139
+
140
+
141
+ # @!endgroup
142
+
143
+ ##
144
+ # @return [s(s(name,functionAst))] array of name/function Ast pair, which
145
+ # any address implements.
146
+ def getAddressFunctions
147
+ return @addressFunctions if @addressFunctions
148
+ @addressFunctions
149
+ end
150
+
151
+
152
+ # ------------------------------------------------------------------
153
+ # @!group Tree traversal
154
+ def process_GlobalScope( exp )
155
+
156
+ mapLiterals
157
+ process_rest( exp )
158
+
159
+ end
160
+
161
+ def process_ContractDefinition( exp )
162
+ logger.debug "#{__method__}: exp=#{exp}" if logger.debug?
163
+
164
+
165
+ # Add constructor?
166
+ logger.debug "#{__method__}: #{compileUnit} needs.needConstructor=#{needs.needConstructor}" if logger.debug?
167
+ if needs.needConstructor
168
+ constructor = SexpUtils.createConstructorNode( exp.name )
169
+ logger.info "#{__method__}: add constructor=#{constructor} to exp=#{exp}"
170
+ # exp << constructor
171
+ addNewNode( exp, constructor )
172
+ end
173
+
174
+
175
+ # Add variableDeclation?
176
+ logger.debug "#{__method__}: #{compileUnit} needs.needVariableDeclarations=#{needs.needVariableDeclarations}" if logger.debug?
177
+ needs.needVariableDeclarations.each do |variableName|
178
+
179
+ newVariableDeclaration = SexpUtils.createVariableDeclaration( variableName )
180
+ logger.info "#{__method__}: add newVariableDeclaration=#{newVariableDeclaration} to #{exp.name}"
181
+
182
+ addNewNode( exp, newVariableDeclaration )
183
+ end
184
+
185
+ # Add getters?
186
+ logger.debug "#{__method__}: needs.neededGetters=#{needs.neededGetters}" if logger.debug?
187
+ needs.neededGetters.each do |variableName|
188
+
189
+ newGetter = SexpUtils.createGetter( variableName )
190
+ logger.info "#{__method__}: add newGetter=#{newGetter} to exp=#{exp}"
191
+ addNewNode( exp, newGetter )
192
+ end
193
+
194
+ logger.debug "#{__method__}: needs.assignmentOperatorSplits=#{needs.assignmentOperatorSplits}" if logger.debug?
195
+ needs.assignmentOperatorSplits.each do |assignmentOperatorSplit|
196
+ logger.info "#{__method__}: split assignment assignmentOperatorSplit=#{assignmentOperatorSplit}"
197
+ binOp = SexpUtils.createBinaryOperator( SexpUtils.mapAssignmentOperator(assignmentOperatorSplit.operator) )
198
+ binOp << assignmentOperatorSplit.lval
199
+ binOp << assignmentOperatorSplit.rval
200
+ # canonize
201
+ assignmentOperatorSplit.setOperator
202
+ assignmentOperatorSplit.setRval( binOp )
203
+ logger.info "#{__method__}: canonizned assignment=#{assignmentOperatorSplit}"
204
+ end
205
+
206
+ # # TODO remove
207
+ # # Change assignment rval from :FunctionCall to :FunctionCallReadReturn
208
+ # logger.debug "#{__method__}: needs.assignmentsToSplit=#{needs.assignmentsToSplit}" if logger.debug?
209
+ # needs.assignmentsToSplit.each do |assignmentToSplit|
210
+ # readReturn = FunctionCallReadReturn.define( assignmentToSplit.rval )
211
+ # assignmentToSplit.changeRval( readReturn )
212
+ # logger.info "#{__method__}: split assignmentToSplit=#{assignmentToSplit}"
213
+ # end
214
+
215
+ mapLiterals
216
+
217
+ contracted( exp ) do
218
+ process_rest(exp)
219
+ end
220
+ logger.info "#{__method__}: #{compileUnit} needs. somethingCanonized=#{somethingCanonized}"
221
+
222
+ exp
223
+ end
224
+
225
+
226
+ def process_FunctionDefinition( exp )
227
+ logger.debug "#{__method__}: exp=#{exp}" if logger.debug?
228
+
229
+ # [ s( FUnctionDef, [name, ...] )]
230
+ parametersToAdd = needs.missing_request_parameters.
231
+ select { |sexp| sexp[0] == exp }.
232
+ map { |sexp| sexp[1] }.first
233
+
234
+ # something to add
235
+ if parametersToAdd && parametersToAdd.any? then
236
+ logger.info "#{__method__}: #{exp.name} should add parametersToAdd=#{parametersToAdd} to with #{exp.parameterList.length} "
237
+
238
+ # parameter = s(:parameter, name, domainName )
239
+ parametersToAdd.each do |parameter|
240
+ # exp.parameterList << s(:VariableDeclaration, name, s(:Domain, domainName ))
241
+ newParameter = SexpUtils.createVariableDeclarationWithDomain( parameter[1], parameter[2] )
242
+ addNewNode( exp.parameterList, newParameter )
243
+ end
244
+ logger.info "#{__method__}: after add #{exp}"
245
+
246
+ end
247
+
248
+ functed( exp ) do
249
+ process_rest(exp)
250
+ end
251
+
252
+ s()
253
+ end
254
+
255
+ def process_Block( exp )
256
+ logger.debug "#{__method__}: exp=#{exp}" if logger.debug?
257
+
258
+ # functionCallsToSplit: s( s(:Block), s(:Statement), s(:FunctionCall) )
259
+ bodySplitters = needs.functionCallsToSplit.select{ |functionCallToSplit| functionCallToSplit[0].equal?(exp) }
260
+
261
+ # something to expand in this body before recursion
262
+ if bodySplitters.any? then
263
+
264
+ logger.debug "#{__method__}: should split #{bodySplitters.length} stmts with #{bodySplitters} in block #{exp} " if logger.debug?
265
+
266
+ bodySplitters.each do |bodySplitter|
267
+
268
+ bodyStatement = bodySplitter[1]
269
+ functionCall = bodySplitter[2]
270
+
271
+ logger.info "#{__method__} split stmt #{functionCall} for function call #{functionCall}"
272
+ # add s(:FunctionCall) to s(:Body) just before s(:Statement)
273
+ raise "Could not find #{bodyStatement} in #{exp}" if exp.find_index( bodyStatement ).nil?
274
+ exp.insert( exp.find_index( bodyStatement ), functionCall )
275
+
276
+ # wrap s(:FunctionCall ) in parent with s(:FunctionCallReadReturn)
277
+ wrappedFunctionCall = FunctionCallReadReturn.define( functionCall )
278
+ functionCall.parent[functionCall.parent.find_index( functionCall)] = wrappedFunctionCall
279
+ end
280
+ logger.info "#{__method__}: after split #{exp}"
281
+ end
282
+
283
+ process_rest( exp )
284
+ end
285
+
286
+
287
+
288
+ def process_VariableDeclaration( exp )
289
+ logger.debug "#{__method__}: exp=#{exp}" if logger.debug?
290
+
291
+ ##
292
+ # If there is variable declatrion without name for 'exp'
293
+ if needs.variable_declarations_without_name.include?( exp )
294
+ logger.info "#{__method__}: update name '#{currentFunction.name}' for #{exp}"
295
+ exp.setName( currentFunction.name )
296
+ end
297
+
298
+ s()
299
+ end
300
+
301
+ # @!endgroup
302
+
303
+ # ------------------------------------------------------------------
304
+ # @!group Utilities
305
+
306
+ ##
307
+ # Change value in literal
308
+ #
309
+ # @param [s(literalSexp,value):Array] map_literalValue
310
+ private def mapLiterals()
311
+ logger.debug "#{__method__}: needs.map_literalValue=#{needs.map_literalValue}" if logger.debug?
312
+ if needs.map_literalValue && needs.map_literalValue.any?
313
+ needs.map_literalValue.each do |literalSexpToValue|
314
+ literalSexp = literalSexpToValue[0]
315
+ newValue = literalSexpToValue[1]
316
+ logger.info "#{__method__}: set newValue=#{newValue} in literalSexp #{literalSexp}"
317
+ literalSexp.setValue( newValue )
318
+ end
319
+ end
320
+ end
321
+
322
+ # @!endgroup
323
+
324
+ end
325
+ end
326
+ end