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,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