tla-trace-filter 0.0.3
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/README.org +66 -0
- data/VERSION +1 -0
- data/bin/tla-trace-filter.rb +5 -0
- data/lib/cli/cli.rb +563 -0
- data/lib/filter/filter.rb +134 -0
- data/lib/parser/grammar.treetop +132 -0
- data/lib/parser/node_extensions.rb +267 -0
- data/lib/parser/parser.rb +85 -0
- data/lib/render/render.rb +510 -0
- data/lib/tla-trace-filter.rb +6 -0
- data/lib/util/logger.rb +82 -0
- data/mustache/add-links-interface.mustache +33 -0
- data/mustache/add-links-state-dump.mustache +28 -0
- data/mustache/add-links-transition.mustache +14 -0
- data/mustache/add-links.mustache +43 -0
- data/mustache/api-call-default.mustache +14 -0
- data/mustache/api-call-init.mustache +70 -0
- data/mustache/api-call-input.mustache +20 -0
- data/mustache/api-call-link.mustache +2 -0
- data/mustache/api-call-main.mustache +86 -0
- data/mustache/api-call-output.mustache +18 -0
- data/mustache/api-call-return.mustache +13 -0
- data/mustache/api-call.mustache +34 -0
- data/spec/cli/cli_spec.rb +73 -0
- data/spec/filter/filter_spec.rb +53 -0
- data/spec/fixtures/interfaces.yaml +22 -0
- data/spec/fixtures/model.tla +1195 -0
- data/spec/fixtures/trace.txt +102 -0
- data/spec/parser/node_extensions_spec.rb +9 -0
- data/spec/parser/parser_spec.rb +392 -0
- data/spec/render/render_spec.rb +177 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/test_spec.rb +8 -0
- data/tla-trace-filter.gemspec +45 -0
- metadata +171 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
{{!
|
2
|
+
|
3
|
+
Root Mustache template
|
4
|
+
|
5
|
+
Can access to following data:
|
6
|
+
|
7
|
+
:options : options passed from command line
|
8
|
+
|
9
|
+
:interface_started : 'true' when transition represents interface
|
10
|
+
invocation, 'false' when transition represents
|
11
|
+
service execution
|
12
|
+
|
13
|
+
:interface : interface definition for transition step interface with
|
14
|
+
properties :source.sourceModule and :source.sourceLine
|
15
|
+
pointing to solidity source of the transition
|
16
|
+
|
17
|
+
:parsed: data parsed from TLC trace file with properties:
|
18
|
+
- :line= string which triggers state space dump to parse state space
|
19
|
+
- :actionLine= line number (parser from ':line')
|
20
|
+
- :state_space = state variables as parsed from the dump, particularly
|
21
|
+
variable :step, which is used as a key to 'interfaces.yaml'
|
22
|
+
to create :source reference
|
23
|
+
|
24
|
+
API call releated stuff
|
25
|
+
|
26
|
+
:inputState : state space parsed before making API-call
|
27
|
+
:outputState : state space parsed after making API-call
|
28
|
+
:now : time when making :interface -call
|
29
|
+
|
30
|
+
}}{{>api-call-main}}{{!
|
31
|
+
Local Variables:
|
32
|
+
require-final-newline: nil
|
33
|
+
End:
|
34
|
+
}}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative "../../lib/cli/cli.rb"
|
2
|
+
|
3
|
+
describe TlaTraceFilter::Cli do
|
4
|
+
|
5
|
+
# Found in namapce
|
6
|
+
it { expect( described_class ).to be_a Class }
|
7
|
+
|
8
|
+
let( :cli ) { described_class.new }
|
9
|
+
|
10
|
+
it { expect( cli ).to be_a( Thor ) }
|
11
|
+
|
12
|
+
let( :cli ) { described_class.new }
|
13
|
+
|
14
|
+
# ------------------------------------------------------------------
|
15
|
+
# Helpers
|
16
|
+
|
17
|
+
# Captures the output for analysis later
|
18
|
+
#
|
19
|
+
# @example Capture `$stderr`
|
20
|
+
#
|
21
|
+
# output = capture(:stderr) { $stderr.puts "this is captured" }
|
22
|
+
#
|
23
|
+
# @param [Symbol] stream `:stdout` or `:stderr`
|
24
|
+
# @yield The block to capture stdout/stderr for.
|
25
|
+
# @return [String] The contents of $stdout or $stderr
|
26
|
+
|
27
|
+
# # https://github.com/docwhat/homedir/blob/homedir3/spec/spec_helper.rb
|
28
|
+
|
29
|
+
def capture(stream)
|
30
|
+
begin
|
31
|
+
stream = stream.to_s
|
32
|
+
eval "$#{stream} = StringIO.new"
|
33
|
+
yield
|
34
|
+
result = eval("$#{stream}").string
|
35
|
+
ensure
|
36
|
+
eval("$#{stream} = #{stream.upcase}")
|
37
|
+
end
|
38
|
+
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# ------------------------------------------------------------------
|
44
|
+
describe "module interface" do
|
45
|
+
describe "class-methods" do
|
46
|
+
subject { described_class }
|
47
|
+
%i[ help ].each do |op|
|
48
|
+
specify { is_expected.to respond_to(op) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "instance-methods" do
|
53
|
+
subject { described_class.new }
|
54
|
+
%i[ add_links api_calls ].each do |op|
|
55
|
+
specify { is_expected.to respond_to(op) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# ------------------------------------------------------------------
|
62
|
+
# commands
|
63
|
+
|
64
|
+
describe ".help" do
|
65
|
+
let( :help ) { capture(:stdout) { cli.help } }
|
66
|
+
%w[ help version ].each do |cmd|
|
67
|
+
describe "Help documents command #{cmd}" do
|
68
|
+
it { expect( help ).to match /#{cmd}.*#/ }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative "../spec_helper.rb"
|
2
|
+
|
3
|
+
describe TlaTraceFilter::Filter do
|
4
|
+
|
5
|
+
# FOund in namespace
|
6
|
+
it { expect( described_class ).to be_a Class }
|
7
|
+
|
8
|
+
# ------------------------------------------------------------------
|
9
|
+
# @!group Interfae
|
10
|
+
|
11
|
+
describe "module interface" do
|
12
|
+
describe "class-methods" do
|
13
|
+
subject { described_class }
|
14
|
+
%i[ ].each do |op|
|
15
|
+
specify { is_expected.to respond_to(op) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "instance-methods" do
|
20
|
+
subject { described_class.new }
|
21
|
+
%i[ filter ].each do |op|
|
22
|
+
specify { is_expected.to respond_to(op) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @!endgroup
|
28
|
+
|
29
|
+
describe ".start" do
|
30
|
+
let( :start ) { described_class.new }
|
31
|
+
it { expect( start ).to be_a described_class }
|
32
|
+
|
33
|
+
let ( :filter ) do
|
34
|
+
filterLines.map do |line|
|
35
|
+
start.filter( line)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "emptylines" do
|
40
|
+
let( :filterLines ) { [] }
|
41
|
+
it { expect( filter ).to eql filterLines }
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "no changes" do
|
45
|
+
let( :filterLines ) { [ "aa", "bb"] }
|
46
|
+
it { expect( filter ).to eql filterLines }
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Interfaces Model interfaces
|
2
|
+
# - modelData interfaces
|
3
|
+
# - template interfaces/interface_mapper.mustache
|
4
|
+
---
|
5
|
+
- :interface_name: _customer_post_
|
6
|
+
:interface_operation: "/customer(post)"
|
7
|
+
:implementation: customer_post
|
8
|
+
:source:
|
9
|
+
:sourceModule: test.sol
|
10
|
+
:sourceLine: 89
|
11
|
+
:sourceColumn:
|
12
|
+
:completion:
|
13
|
+
_comma: ''
|
14
|
+
:parameter_definitions:
|
15
|
+
- :parameter_name: customer
|
16
|
+
:isArray: false
|
17
|
+
:type: Customer
|
18
|
+
:metatype: definitions
|
19
|
+
_comma: ''
|
20
|
+
:response_definitions: false
|
21
|
+
|
22
|
+
|
@@ -0,0 +1,1195 @@
|
|
1
|
+
Model version: Model version file /home/jj/work/sbuilder-eth/tmp/aruba/solidity/new-account/VERSION not found
|
2
|
+
Generator version: 0.3.5-SNAPSHOT
|
3
|
+
Generation timestemp: 2017-10-02 07:52:38
|
4
|
+
|
5
|
+
|
6
|
+
------------------------------ MODULE model ------------------------------
|
7
|
+
|
8
|
+
EXTENDS TLC, FiniteSets, Sequences, Integers
|
9
|
+
|
10
|
+
(* Execution environment *)
|
11
|
+
|
12
|
+
CONSTANTS Steps \* Sequence process/parameter records
|
13
|
+
(* Magic values *)
|
14
|
+
|
15
|
+
CONSTANTS WildCard \* bind to any value
|
16
|
+
CONSTANTS Nil \* no value
|
17
|
+
CONSTANTS Abort \* response.status error
|
18
|
+
|
19
|
+
\* Extension point template extend/extend_const.mustache:
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
(******************************************************************
|
25
|
+
Domain definitions
|
26
|
+
- modelData domains
|
27
|
+
- template domains.mustache
|
28
|
+
******************************************************************)
|
29
|
+
|
30
|
+
CONSTANTS d_intti
|
31
|
+
CONSTANTS d_Intti
|
32
|
+
CONSTANTS d_domari
|
33
|
+
CONSTANTS d_eth_address
|
34
|
+
CONSTANTS d_eth_value
|
35
|
+
CONSTANTS d_eth_gas
|
36
|
+
CONSTANTS d_eth_code_hash
|
37
|
+
CONSTANTS d_BOOLEAN
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
(* schedule operators *)
|
42
|
+
|
43
|
+
\* Notice: cardinality of +steps+ sequence elements is 1, change in future?
|
44
|
+
ProcessStep( stepdefs ) == (CHOOSE s \in Head( stepdefs ): TRUE )
|
45
|
+
ProcessRunning( stepdefs ) == ProcessStep( stepdefs ).process
|
46
|
+
ProcessEnabled( stepdefs, s ) == Len( stepdefs ) # 0 /\ s = ProcessRunning( stepdefs )
|
47
|
+
ProcessesToRun( stepdefs ) == Tail( stepdefs )
|
48
|
+
ProcessParameter( stepdefs ) == ProcessStep( stepdefs )
|
49
|
+
|
50
|
+
TickNext( t ) == t + 1 \* advance time (when process start)
|
51
|
+
InTransaction == FALSE \* TRUE when application service running, FALSE when not
|
52
|
+
(******************************************************************
|
53
|
+
Initial value for infrastructure service responses
|
54
|
+
- modelData infrastructureServices
|
55
|
+
- template infrastructure-service-init.mustache
|
56
|
+
|
57
|
+
******************************************************************)
|
58
|
+
|
59
|
+
\* create record to put into 'responses'variable field
|
60
|
+
InfrastructureServiceResponse( status, response ) == [ status |-> status, response |-> response ]
|
61
|
+
|
62
|
+
\* Initial value to variable 'responses'
|
63
|
+
InfrastructureServiceInit == [ i_geth_newAccount_ |-> InfrastructureServiceResponse( Nil, Nil ), i_geth_mine_ |-> InfrastructureServiceResponse( Nil, Nil ) ]
|
64
|
+
|
65
|
+
|
66
|
+
(******************************************************************
|
67
|
+
Defined types Data type definitions
|
68
|
+
- modelData definitions
|
69
|
+
- template definition_types.mustache
|
70
|
+
*******************************************************************)
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
(******************************************************************
|
75
|
+
Interface input types: Interface types
|
76
|
+
- modelData interfaces
|
77
|
+
- template interface_types.mustache
|
78
|
+
*******************************************************************)
|
79
|
+
|
80
|
+
|
81
|
+
(* REQUEST: geth(newAccount) --> TLA process: p_geth_newAccount_ *)
|
82
|
+
t_req_geth_newAccount_ == [
|
83
|
+
sender: d_eth_address,
|
84
|
+
originator: d_eth_address,
|
85
|
+
recipient: d_eth_address,
|
86
|
+
value: d_eth_value
|
87
|
+
]
|
88
|
+
(* END-OF-REQUEST *)
|
89
|
+
|
90
|
+
(* REQUEST: geth(mine) --> TLA process: p_geth_mine_ *)
|
91
|
+
t_req_geth_mine_ == [
|
92
|
+
sender: d_eth_address,
|
93
|
+
originator: d_eth_address,
|
94
|
+
recipient: d_eth_address,
|
95
|
+
value: d_eth_value
|
96
|
+
]
|
97
|
+
(* END-OF-REQUEST *)
|
98
|
+
|
99
|
+
\* end of Interface input types
|
100
|
+
|
101
|
+
(******************************************************************
|
102
|
+
Interface response types: Interface types
|
103
|
+
- modelData interfaces
|
104
|
+
- template interface_types.mustache
|
105
|
+
*******************************************************************)
|
106
|
+
|
107
|
+
(* RESPONSE: geth(newAccount) --> TLA process: p_geth_newAccount_ *)
|
108
|
+
t_resp_geth_newAccount_ == { Nil }
|
109
|
+
(* END-OF-RESPONSE *)
|
110
|
+
|
111
|
+
(* RESPONSE: geth(mine) --> TLA process: p_geth_mine_ *)
|
112
|
+
t_resp_geth_mine_ == { Nil }
|
113
|
+
(* END-OF-RESPONSE *)
|
114
|
+
|
115
|
+
(*
|
116
|
+
--algorithm model {
|
117
|
+
(******************************************************************
|
118
|
+
State environment model
|
119
|
+
- modelData none
|
120
|
+
- template tla/plc_run_state.mustache
|
121
|
+
******************************************************************)
|
122
|
+
|
123
|
+
variables
|
124
|
+
\* sequence of [ { process |-> {}, parameter |-> {} }]
|
125
|
+
steps = Steps;
|
126
|
+
\* process currently running = self with _ replcing non-numeric
|
127
|
+
step = Nil;
|
128
|
+
\* head from +steps+ sequence used to schedule +step+
|
129
|
+
step_parameter = {};
|
130
|
+
\* current time tick, each process run in own tick
|
131
|
+
now = 0;
|
132
|
+
\* TRUE when process is running
|
133
|
+
tx_running = FALSE;
|
134
|
+
\* rec [ ret_ctx |-> stack entry push in resume ], when resuming, Nil when not
|
135
|
+
resume_context = Nil;
|
136
|
+
(******************************************************************
|
137
|
+
Variables used by infrastructure-services
|
138
|
+
- modelData none
|
139
|
+
- template infrastructure-service-variables.mustache
|
140
|
+
|
141
|
+
******************************************************************)
|
142
|
+
|
143
|
+
\* Variable for returning responses from infrastructure services
|
144
|
+
responses = InfrastructureServiceInit;
|
145
|
+
|
146
|
+
|
147
|
+
\* Extension point template extend/extend_state.mustache:
|
148
|
+
|
149
|
+
(* SNIPPET: eth/accounts --> eth_accounts *)
|
150
|
+
eth_accounts = { };
|
151
|
+
(* --END OF SNIPPET-- *)
|
152
|
+
|
153
|
+
(* SNIPPET: eth/storageRoot --> eth_storageRoot *)
|
154
|
+
eth_storageRoot = { };
|
155
|
+
(* --END OF SNIPPET-- *)
|
156
|
+
|
157
|
+
(* SNIPPET: eth/addressPool --> eth_addressPool *)
|
158
|
+
eth_addressPool = d_eth_address \ { Nil };
|
159
|
+
(* --END OF SNIPPET-- *)
|
160
|
+
|
161
|
+
define {
|
162
|
+
|
163
|
+
(*
|
164
|
+
Current time in state variable now gets ticked
|
165
|
+
when process starts.
|
166
|
+
*)
|
167
|
+
currentTime == now
|
168
|
+
|
169
|
+
(*
|
170
|
+
Return set of possible bindings to an enabled process
|
171
|
+
|
172
|
+
@param [Set] inputSet set of all possible inputs to a process
|
173
|
+
@return first that matches
|
174
|
+
- inputSet if step_parameter.bindSet == Nil
|
175
|
+
- step_parameter.bindSet if step_parameter.bindSet != Nil
|
176
|
+
*)
|
177
|
+
ProcessParameterInput( inputSet ) ==
|
178
|
+
IF step_parameter'.bindSet = Nil
|
179
|
+
THEN inputSet
|
180
|
+
ELSE step_parameter'.bindSet
|
181
|
+
|
182
|
+
(* All record fields in 'bindDef' must bind with corresponding fields in 'inputParam' *)
|
183
|
+
\* ProcessParameterEnablesTst( inputParam, bindDefs ) == \A key \in { k \in DOMAIN bindDefs : k # "_key" }: bindDefs[key] = inputParam[key]
|
184
|
+
|
185
|
+
(*
|
186
|
+
ProcessParameterEnables: 'inputParam' satisfies 'bindDefs'
|
187
|
+
|
188
|
+
- all 'normal' field in 'bindDefs' are found in 'inputParam'
|
189
|
+
- and all subrecords can be validated recursively using 'ProcessParameterEnables' using a the set in field '_key'
|
190
|
+
- and for each record in the set in field '_rows'
|
191
|
+
-- validates at least one row in 'inputParam'
|
192
|
+
--- cardinality of inputParam[key] = cardinality _row.set
|
193
|
+
-- OR equals 'values' set
|
194
|
+
|
195
|
+
Recurse one level down in 'inputParam' using keys 'bindDefs._key.key'.
|
196
|
+
Recursion is done only if 'bindDefs' defines field '_key'.
|
197
|
+
|
198
|
+
|
199
|
+
*)
|
200
|
+
RECURSIVE ProcessParameterEnables( _, _ )
|
201
|
+
ProcessParameterEnables( inputParam, bindDefs ) ==
|
202
|
+
( \A key \in { k \in DOMAIN bindDefs : Len(k)<4 \/ (SubSeq(k,1,4) # "_key" /\ k # "_rows" )}: bindDefs[key] = inputParam[key] )
|
203
|
+
/\ ( \A reckey \in { k \in DOMAIN bindDefs : Len(k)>3 /\SubSeq(k,1,4) = "_key" }: \A r \in bindDefs[reckey] : ProcessParameterEnables( inputParam[r.key], r.rec ) )
|
204
|
+
/\ ( \A reckey \in { k \in DOMAIN bindDefs : k = "_rows" }: \A r \in bindDefs[reckey] :
|
205
|
+
(r.row_types = "singletons" /\ r.set = inputParam[r.key] )
|
206
|
+
\/ (r.row_types = "hashes" /\ Cardinality( r.set ) = Cardinality( inputParam[r.key] ) /\ \A bDef \in r.set: \E ip \in inputParam[r.key]: ProcessParameterEnables( ip, bDef ) )
|
207
|
+
)
|
208
|
+
|
209
|
+
|
210
|
+
(*
|
211
|
+
|
212
|
+
Predicate to filter elements in ProcessParameterInput set to pass
|
213
|
+
to +steps+ element in +step_parameter' variable.
|
214
|
+
|
215
|
+
Pass +inputParameter+ to a process if one the following matches
|
216
|
+
- resume_contex # Nil (i.e. process execution is resuming)
|
217
|
+
- step_parameter = WildCard (i.e. Head elemend of +steps+ sequence is WildCard, allow everything )
|
218
|
+
- step_parameter.bindSet = WildCard (i.e. Head element defines bindSet element)
|
219
|
+
- predicate 'ProcessParameterEnables' resolves TRUE for step_parameter'.bindRule
|
220
|
+
*)
|
221
|
+
|
222
|
+
ProcessParameterBind( inputParam ) ==
|
223
|
+
\/ resume_context' # Nil
|
224
|
+
\/ step_parameter' = WildCard
|
225
|
+
\/ step_parameter'.bindRule = WildCard
|
226
|
+
\/ ProcessParameterEnables( inputParam, step_parameter'.bindRule )
|
227
|
+
|
228
|
+
(******************************************************************
|
229
|
+
Operators for infrastrcuture service (generated)
|
230
|
+
- modelData infrastructureServices
|
231
|
+
- template operator-infrastructure-service.mustache
|
232
|
+
|
233
|
+
******************************************************************)
|
234
|
+
InterfaceOperation2ProcessName( op ) == CASE op = "xxXXxx" -> Nil
|
235
|
+
[] op = "geth(newAccount)" -> "i_geth_newAccount_"
|
236
|
+
[] op = "geth(mine)" -> "i_geth_mine_"
|
237
|
+
[] OTHER -> Assert( FALSE, "Unknown infrastructure service" )
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
(******************************************************************
|
242
|
+
Operators supporting infrastructure services
|
243
|
+
- modelData none
|
244
|
+
- template tla/operators-infrastructure-service.mustache
|
245
|
+
******************************************************************)
|
246
|
+
|
247
|
+
\* return response for 'operation' from 'responses' state variable
|
248
|
+
InfrastructureServiceGetResponse( operation ) == responses[InterfaceOperation2ProcessName(operation)].response
|
249
|
+
|
250
|
+
\* return status for 'operation' from 'responses' state variable
|
251
|
+
InfrastructureServiceGetStatus( operation ) == responses[InterfaceOperation2ProcessName(operation)].status
|
252
|
+
|
253
|
+
|
254
|
+
\* Extension point template extend/extend_operations.mustache:
|
255
|
+
|
256
|
+
(* SNIPPET: framework-svc/NewStep --> NewStep *)
|
257
|
+
(* Create a step entry to schedule in +steps+ sequence
|
258
|
+
* @param procci process identifier to schedule
|
259
|
+
* @param procInput an elment in process input set to pass to the process
|
260
|
+
* @param ctx context where to resume, Nil if no resume
|
261
|
+
*)
|
262
|
+
NewStep( procci, procInput, ctx ) == [ process |-> procci, bindRule |-> WildCard ,bindSet |-> procInput, ctx |-> ctx ]
|
263
|
+
|
264
|
+
|
265
|
+
(* --END OF SNIPPET-- *)
|
266
|
+
|
267
|
+
(* SNIPPET: eth/elementExists --> eth_elementExists *)
|
268
|
+
(*
|
269
|
+
* Unique element exists
|
270
|
+
*)
|
271
|
+
eth_elementExists( set, key, id ) == Cardinality( { e \in set : e[key] = id } ) = 1
|
272
|
+
|
273
|
+
(* --END OF SNIPPET-- *)
|
274
|
+
|
275
|
+
(* SNIPPET: eth/gasPrice --> eth_gasPrice *)
|
276
|
+
(* Use integer math, and gasPrice is just 0 *)
|
277
|
+
eth_gasPrice == 0
|
278
|
+
|
279
|
+
(* --END OF SNIPPET-- *)
|
280
|
+
|
281
|
+
(* SNIPPET: eth/gasValue --> eth_gasValue *)
|
282
|
+
(* @return [Integer] value of 'gas' *)
|
283
|
+
eth_gasValue( gas ) == gas * eth_gasPrice
|
284
|
+
|
285
|
+
(* --END OF SNIPPET-- *)
|
286
|
+
|
287
|
+
(* SNIPPET: eth/intrinsicGas --> eth_intrinsicGas *)
|
288
|
+
(*
|
289
|
+
*Always consume at least ''intrinsicGas' units of gas, i.e.
|
290
|
+
* account must have balance >= intrinsicGas*gasPrice before execution
|
291
|
+
*)
|
292
|
+
eth_intrinsicGas == 1
|
293
|
+
|
294
|
+
(* --END OF SNIPPET-- *)
|
295
|
+
|
296
|
+
(* SNIPPET: eth/NextId --> eth_NextId *)
|
297
|
+
(*
|
298
|
+
* Take one 'address'' from set 'ids'. If 'address' parameter 'Nil' address
|
299
|
+
* is unspecified is bound to an element in 'ids' when NextId called for the
|
300
|
+
* first time in a transition.
|
301
|
+
*)
|
302
|
+
eth_NextId( ids, address ) == CHOOSE x \in ids: (address = x /\ address # Nil) \/ address = Nil
|
303
|
+
|
304
|
+
(* --END OF SNIPPET-- *)
|
305
|
+
|
306
|
+
(* SNIPPET: eth/upFrontCost --> eth_upFrontCost *)
|
307
|
+
(*
|
308
|
+
** Value account must hold before transaction possible to start
|
309
|
+
*
|
310
|
+
* @return [Integer] request.value + gasPrice * intrinsicGas
|
311
|
+
*)
|
312
|
+
eth_upFrontCost( request ) == request.value + eth_gasPrice * eth_intrinsicGas
|
313
|
+
|
314
|
+
(* --END OF SNIPPET-- *)
|
315
|
+
|
316
|
+
} \* define
|
317
|
+
(***********************************************************************
|
318
|
+
Macros to control process execution && time
|
319
|
+
***********************************************************************)
|
320
|
+
macro tick() {
|
321
|
+
now := TickNext( now ); \* now := now + 1;
|
322
|
+
}
|
323
|
+
|
324
|
+
macro enable( s ) {
|
325
|
+
(* head in sequence 'steps' enable processes *)
|
326
|
+
\* await Len( steps ) # 0 /\ ProcessEnabled( steps, s );
|
327
|
+
await ProcessEnabled( steps, s );
|
328
|
+
|
329
|
+
(* process entered, remove head from sequence 'steps' *)
|
330
|
+
step := ProcessRunning( steps ); \* Head( steps ).process;
|
331
|
+
step_parameter := ProcessParameter( steps );
|
332
|
+
\* steps := ProcessesToRun( steps ); \* Tail( steps );
|
333
|
+
|
334
|
+
\* Context to resume to from Head(steps ), Nil = not resuming
|
335
|
+
resume_context := ProcessStep( steps ).ctx;
|
336
|
+
|
337
|
+
(* Reset infrastructure service responses on process entry *)
|
338
|
+
responses := InfrastructureServiceInit;
|
339
|
+
|
340
|
+
(* Flag Transaction started *)
|
341
|
+
tx_running := TRUE;
|
342
|
+
|
343
|
+
(* time advances by one tick for each process step *)
|
344
|
+
tick();
|
345
|
+
\* debug( s );
|
346
|
+
}
|
347
|
+
|
348
|
+
(* Remove currently running prosess from head of 'step'.
|
349
|
+
|
350
|
+
Calling this macro enables next process to take turn.
|
351
|
+
If a process comprises several steps, this results
|
352
|
+
processes runing parallel, unless 'process_done' is
|
353
|
+
called in the end of the process.
|
354
|
+
|
355
|
+
*)
|
356
|
+
|
357
|
+
macro process_done( s ) {
|
358
|
+
|
359
|
+
steps := ProcessesToRun( steps ); \* Tail( steps );
|
360
|
+
|
361
|
+
\* process must clear resume context
|
362
|
+
assert( resume_context = Nil );
|
363
|
+
|
364
|
+
(* Flag Transaction started *)
|
365
|
+
tx_running := FALSE;
|
366
|
+
|
367
|
+
}
|
368
|
+
|
369
|
+
|
370
|
+
|
371
|
+
(******************************************************************
|
372
|
+
Macros for infrastructure services
|
373
|
+
- modelData none
|
374
|
+
- template tla/macro-infrastructure-service.mustache
|
375
|
+
******************************************************************)
|
376
|
+
|
377
|
+
\* set 'status' with 'response' for 'operation' into state variable 'responses'
|
378
|
+
macro InfrastructureServiceReturn( operation, status, response ) {
|
379
|
+
|
380
|
+
\* update field for 'operation' in 'responses' variable with record [ status |-> s , response |-> r ]
|
381
|
+
responses[InterfaceOperation2ProcessName(operation)] := InfrastructureServiceResponse( status, response );
|
382
|
+
}
|
383
|
+
|
384
|
+
|
385
|
+
|
386
|
+
\* Extension point template extend/extend_macros.mustache:
|
387
|
+
|
388
|
+
(* SNIPPET: framework-svc/schedule_throw --> schedule_throw *)
|
389
|
+
(*
|
390
|
+
Throw exception and exit current process via +exitLocation+.
|
391
|
+
|
392
|
+
Modify +stack+ top to return from current procedure to
|
393
|
+
+exitLocation+, and retain stack bottom to return from current
|
394
|
+
process. *)
|
395
|
+
|
396
|
+
macro schedule_throw( exitLocation ) {
|
397
|
+
|
398
|
+
|
399
|
+
stack := <<
|
400
|
+
[ stack[self][1] EXCEPT !.pc = exitLocation ],
|
401
|
+
stack[self][ Len(stack[self]) ]
|
402
|
+
>>;
|
403
|
+
|
404
|
+
}
|
405
|
+
(* --END OF SNIPPET-- *)
|
406
|
+
|
407
|
+
(* SNIPPET: framework-svc/schedule_process_mac --> schedule_process_mac *)
|
408
|
+
(*
|
409
|
+
|
410
|
+
Schedule a call for an external process +called+ with +input+, and
|
411
|
+
+resume+ back to the calling process in context +resumeCtx+.
|
412
|
+
|
413
|
+
Implementation adds two step entries in +steps+ sequence.
|
414
|
+
Entries cannot be made to position 1 because it represents
|
415
|
+
currently running process, which get shifted away the sequnce
|
416
|
+
once the process finishes.
|
417
|
+
|
418
|
+
*)
|
419
|
+
|
420
|
+
macro schedule_process_mac( called, input, resume, resumeCtx ) {
|
421
|
+
|
422
|
+
\* NOTICE!!: call and resume steps always successive elements
|
423
|
+
\* The only option is to apped to +steps+
|
424
|
+
if ( Cardinality( { p \in 1..Len(steps) : \A s \in steps[p]: s.ctx = Nil } ) <= 1 ) {
|
425
|
+
steps := steps \o
|
426
|
+
<< { NewStep( called, input, Nil ) },
|
427
|
+
{ NewStep( resume, Nil, resumeCtx ) } >>;
|
428
|
+
} else {
|
429
|
+
\* Non-deteministic choice where to put
|
430
|
+
with ( pos \in { p \in 2..Len(steps) : \A s \in steps[p]: s.ctx = Nil } ) {
|
431
|
+
steps := IF pos = Len(steps) THEN
|
432
|
+
steps \o
|
433
|
+
<< { NewStep( called, input, Nil ) },
|
434
|
+
{ NewStep( resume, Nil, resumeCtx ) } >>
|
435
|
+
ELSE
|
436
|
+
SubSeq( steps, 1, pos-1 ) \o
|
437
|
+
<< { NewStep( called, input, Nil ) },
|
438
|
+
{ NewStep( resume, Nil, resumeCtx ) } >> \o
|
439
|
+
SubSeq( steps, pos, Len(steps))
|
440
|
+
;
|
441
|
+
}; \* with
|
442
|
+
}; \* else
|
443
|
+
skip;
|
444
|
+
}
|
445
|
+
(* --END OF SNIPPET-- *)
|
446
|
+
|
447
|
+
(* SNIPPET: service_implementation/geth(newAccount) --> i__geth_newAccount_ *)
|
448
|
+
macro i__geth_newAccount_( input ) {
|
449
|
+
print << "TODO: Greetings from service-implementation",input >>;
|
450
|
+
call eth_geth_newAccount_( input);
|
451
|
+
}
|
452
|
+
(* --END OF SNIPPET-- *)
|
453
|
+
|
454
|
+
(* SNIPPET: service_implementation/geth(mine) --> i__geth_mine_ *)
|
455
|
+
macro i__geth_mine_( input ) {
|
456
|
+
print << "TODO: Greetings from service-implementation",input >>;
|
457
|
+
call eth_geth_mine_( input);
|
458
|
+
}
|
459
|
+
(* --END OF SNIPPET-- *)
|
460
|
+
|
461
|
+
(******************************************************************
|
462
|
+
Interfaces generated Create a dummy procedure to have 'defaultInitValue' in the model
|
463
|
+
- modelData none
|
464
|
+
- template interface_stubs_dummy.mustache
|
465
|
+
******************************************************************)
|
466
|
+
|
467
|
+
(* Allow 'interface-extension.implementation' without specification code snippet *)
|
468
|
+
macro dummy( dummy_input ) {
|
469
|
+
print << "Dummy macro called should replace with actual macro" >>;
|
470
|
+
}
|
471
|
+
|
472
|
+
|
473
|
+
(* Create a dummy procedure with input variable so that pcal creates
|
474
|
+
constant defaultInitValue (which is assigned a value in setup.tla)
|
475
|
+
*)
|
476
|
+
|
477
|
+
procedure dummy( dummy_input ) {
|
478
|
+
dummy_start: skip;
|
479
|
+
}
|
480
|
+
|
481
|
+
|
482
|
+
\* Extension point template extend/extend_implementation.mustache:
|
483
|
+
|
484
|
+
(* SNIPPET: framework-svc/schedule_process_proc --> schedule_process_proc *)
|
485
|
+
(*
|
486
|
+
|
487
|
+
Schedule process +input.called+ with +input.input+, and resume back
|
488
|
+
to currently running process +step+ to pc of +self+ ProcDef.
|
489
|
+
|
490
|
+
Creates a record with +ret_ctx+ property, which calling process can
|
491
|
+
use to restore its context, adds call step and resume step to
|
492
|
+
+steps+ sequence.
|
493
|
+
|
494
|
+
*)
|
495
|
+
|
496
|
+
procedure schedule_process_proc( input ) {
|
497
|
+
|
498
|
+
schedule_process_start:
|
499
|
+
|
500
|
+
schedule_process_mac(
|
501
|
+
input.called, input.input, step,
|
502
|
+
[ ret_ctx |-> [ stack[self][2] EXCEPT !.pc = stack[self][1].pc ] ]
|
503
|
+
);
|
504
|
+
|
505
|
+
return;
|
506
|
+
}
|
507
|
+
(* --END OF SNIPPET-- *)
|
508
|
+
|
509
|
+
(* SNIPPET: eth/geth(newAccount) --> eth_geth_newAccount_ *)
|
510
|
+
procedure eth_geth_newAccount_( eth_geth_newAccount__input )
|
511
|
+
variable contractId;
|
512
|
+
{
|
513
|
+
eth_geth_newAccount__start:
|
514
|
+
\* print "ENTRY:";
|
515
|
+
skip
|
516
|
+
;
|
517
|
+
|
518
|
+
(* Body of geth(newAccount) *)
|
519
|
+
eth_geth_newAccount__0: print << "new.account",eth_geth_newAccount__input,"free-pool=",eth_addressPool >>;
|
520
|
+
eth_accounts := eth_accounts \union { [ address |-> eth_NextId( eth_addressPool,Nil ), balance |-> 0, codeHash |-> Nil ] };
|
521
|
+
eth_addressPool := eth_addressPool \ { eth_NextId( eth_addressPool,Nil ) };
|
522
|
+
print << "after-free-pool=",eth_addressPool >>;
|
523
|
+
print << "after-accounts=",eth_accounts >>;
|
524
|
+
|
525
|
+
|
526
|
+
eth_geth_newAccount__exit:
|
527
|
+
goto eth_geth_newAccount__end;
|
528
|
+
eth_geth_newAccount__fail:
|
529
|
+
\* throw command sends here
|
530
|
+
InfrastructureServiceReturn( "geth(newAccount)", FALSE, Nil);
|
531
|
+
goto eth_geth_newAccount__end;
|
532
|
+
|
533
|
+
eth_geth_newAccount__abort:
|
534
|
+
\* should not happen??
|
535
|
+
print <<"ABORT eth_geth_newAccount_">>;
|
536
|
+
InfrastructureServiceReturn( "geth(newAccount)", Abort, Nil);
|
537
|
+
\* schedule_throw( "eth_geth_newAccount__exit" );
|
538
|
+
eth_geth_newAccount__end:
|
539
|
+
skip;
|
540
|
+
(* ethereum_service_pop( "geth(newAccount)" ); *)
|
541
|
+
\* print "EXIT:";
|
542
|
+
return
|
543
|
+
;
|
544
|
+
}
|
545
|
+
|
546
|
+
(* --END OF SNIPPET-- *)
|
547
|
+
|
548
|
+
(* SNIPPET: eth/geth(mine) --> eth_geth_mine_ *)
|
549
|
+
procedure eth_geth_mine_( eth_geth_mine__input )
|
550
|
+
variable contractId;
|
551
|
+
{
|
552
|
+
eth_geth_mine__start:
|
553
|
+
\* print "ENTRY:";
|
554
|
+
skip
|
555
|
+
;
|
556
|
+
|
557
|
+
(* Body of geth(mine) *)
|
558
|
+
|
559
|
+
|
560
|
+
eth_geth_mine__exit:
|
561
|
+
goto eth_geth_mine__end;
|
562
|
+
eth_geth_mine__fail:
|
563
|
+
\* throw command sends here
|
564
|
+
InfrastructureServiceReturn( "geth(mine)", FALSE, Nil);
|
565
|
+
goto eth_geth_mine__end;
|
566
|
+
|
567
|
+
eth_geth_mine__abort:
|
568
|
+
\* should not happen??
|
569
|
+
print <<"ABORT eth_geth_mine_">>;
|
570
|
+
InfrastructureServiceReturn( "geth(mine)", Abort, Nil);
|
571
|
+
\* schedule_throw( "eth_geth_mine__exit" );
|
572
|
+
eth_geth_mine__end:
|
573
|
+
skip;
|
574
|
+
(* ethereum_service_pop( "geth(mine)" ); *)
|
575
|
+
\* print "EXIT:";
|
576
|
+
return
|
577
|
+
;
|
578
|
+
}
|
579
|
+
|
580
|
+
(* --END OF SNIPPET-- *)
|
581
|
+
|
582
|
+
|
583
|
+
(******************************************************************
|
584
|
+
Interfaces generated Process interfaces
|
585
|
+
- modelData interfaces
|
586
|
+
- template interface_processes.mustache
|
587
|
+
******************************************************************)
|
588
|
+
|
589
|
+
(* Process geth(newAccount) *)
|
590
|
+
fair process (p_geth_newAccount_="geth(newAccount)") {
|
591
|
+
p_geth_newAccount__enter: while (TRUE) {
|
592
|
+
enable( "p_geth_newAccount_" );
|
593
|
+
(* enable next process to run parallel *)
|
594
|
+
\* process_done( "geth(newAccount)" );
|
595
|
+
with ( _input \in { t \in ProcessParameterInput( t_req_geth_newAccount_ ) : ProcessParameterBind( t ) } ) {
|
596
|
+
\* PREFERENCES.debug-output: true
|
597
|
+
print <<"Default process p_geth_newAccount_ for operation 'geth(newAccount)',tick=", currentTime>>;
|
598
|
+
(* Valid input type? - _input must match type of API request *)
|
599
|
+
assert( _input \in t_req_geth_newAccount_ );
|
600
|
+
i__geth_newAccount_( _input );
|
601
|
+
}; \* with _input
|
602
|
+
(* enable next process - after current process *)
|
603
|
+
p_geth_newAccount__exit:
|
604
|
+
process_done( "geth(newAccount)" );
|
605
|
+
} \* while(TRUE)
|
606
|
+
} \* fair process p_geth_newAccount_
|
607
|
+
|
608
|
+
(* Process geth(mine) *)
|
609
|
+
fair process (p_geth_mine_="geth(mine)") {
|
610
|
+
p_geth_mine__enter: while (TRUE) {
|
611
|
+
enable( "p_geth_mine_" );
|
612
|
+
(* enable next process to run parallel *)
|
613
|
+
\* process_done( "geth(mine)" );
|
614
|
+
with ( _input \in { t \in ProcessParameterInput( t_req_geth_mine_ ) : ProcessParameterBind( t ) } ) {
|
615
|
+
\* PREFERENCES.debug-output: true
|
616
|
+
print <<"Default process p_geth_mine_ for operation 'geth(mine)',tick=", currentTime>>;
|
617
|
+
(* Valid input type? - _input must match type of API request *)
|
618
|
+
assert( _input \in t_req_geth_mine_ );
|
619
|
+
i__geth_mine_( _input );
|
620
|
+
}; \* with _input
|
621
|
+
(* enable next process - after current process *)
|
622
|
+
p_geth_mine__exit:
|
623
|
+
process_done( "geth(mine)" );
|
624
|
+
} \* while(TRUE)
|
625
|
+
} \* fair process p_geth_mine_
|
626
|
+
|
627
|
+
|
628
|
+
fair process ( tail="Tail") {
|
629
|
+
tail_wait: await( Len(steps) = 0 );
|
630
|
+
step := "Tail";
|
631
|
+
step_parameter := {};
|
632
|
+
tail: while( TRUE ) {
|
633
|
+
skip;
|
634
|
+
}
|
635
|
+
}
|
636
|
+
} \* end of algorithm
|
637
|
+
*)
|
638
|
+
\* BEGIN TRANSLATION
|
639
|
+
\* Label tail of process tail at line 632 col 15 changed to tail_
|
640
|
+
\* Procedure variable contractId of procedure eth_geth_newAccount_ at line 511 col 14 changed to contractId_
|
641
|
+
CONSTANT defaultInitValue
|
642
|
+
VARIABLES steps, step, step_parameter, now, tx_running, resume_context,
|
643
|
+
responses, eth_accounts, eth_storageRoot, eth_addressPool, pc,
|
644
|
+
stack
|
645
|
+
|
646
|
+
(* define statement *)
|
647
|
+
currentTime == now
|
648
|
+
|
649
|
+
|
650
|
+
|
651
|
+
|
652
|
+
|
653
|
+
|
654
|
+
|
655
|
+
|
656
|
+
|
657
|
+
ProcessParameterInput( inputSet ) ==
|
658
|
+
IF step_parameter'.bindSet = Nil
|
659
|
+
THEN inputSet
|
660
|
+
ELSE step_parameter'.bindSet
|
661
|
+
|
662
|
+
|
663
|
+
|
664
|
+
|
665
|
+
|
666
|
+
|
667
|
+
|
668
|
+
|
669
|
+
|
670
|
+
|
671
|
+
|
672
|
+
|
673
|
+
|
674
|
+
|
675
|
+
|
676
|
+
|
677
|
+
|
678
|
+
|
679
|
+
|
680
|
+
RECURSIVE ProcessParameterEnables( _, _ )
|
681
|
+
ProcessParameterEnables( inputParam, bindDefs ) ==
|
682
|
+
( \A key \in { k \in DOMAIN bindDefs : Len(k)<4 \/ (SubSeq(k,1,4) # "_key" /\ k # "_rows" )}: bindDefs[key] = inputParam[key] )
|
683
|
+
/\ ( \A reckey \in { k \in DOMAIN bindDefs : Len(k)>3 /\SubSeq(k,1,4) = "_key" }: \A r \in bindDefs[reckey] : ProcessParameterEnables( inputParam[r.key], r.rec ) )
|
684
|
+
/\ ( \A reckey \in { k \in DOMAIN bindDefs : k = "_rows" }: \A r \in bindDefs[reckey] :
|
685
|
+
(r.row_types = "singletons" /\ r.set = inputParam[r.key] )
|
686
|
+
\/ (r.row_types = "hashes" /\ Cardinality( r.set ) = Cardinality( inputParam[r.key] ) /\ \A bDef \in r.set: \E ip \in inputParam[r.key]: ProcessParameterEnables( ip, bDef ) )
|
687
|
+
)
|
688
|
+
|
689
|
+
|
690
|
+
|
691
|
+
|
692
|
+
|
693
|
+
|
694
|
+
|
695
|
+
|
696
|
+
|
697
|
+
|
698
|
+
|
699
|
+
|
700
|
+
|
701
|
+
|
702
|
+
ProcessParameterBind( inputParam ) ==
|
703
|
+
\/ resume_context' # Nil
|
704
|
+
\/ step_parameter' = WildCard
|
705
|
+
\/ step_parameter'.bindRule = WildCard
|
706
|
+
\/ ProcessParameterEnables( inputParam, step_parameter'.bindRule )
|
707
|
+
|
708
|
+
|
709
|
+
|
710
|
+
|
711
|
+
|
712
|
+
|
713
|
+
|
714
|
+
InterfaceOperation2ProcessName( op ) == CASE op = "xxXXxx" -> Nil
|
715
|
+
[] op = "geth(newAccount)" -> "i_geth_newAccount_"
|
716
|
+
[] op = "geth(mine)" -> "i_geth_mine_"
|
717
|
+
[] OTHER -> Assert( FALSE, "Unknown infrastructure service" )
|
718
|
+
|
719
|
+
|
720
|
+
|
721
|
+
|
722
|
+
|
723
|
+
|
724
|
+
|
725
|
+
|
726
|
+
|
727
|
+
|
728
|
+
InfrastructureServiceGetResponse( operation ) == responses[InterfaceOperation2ProcessName(operation)].response
|
729
|
+
|
730
|
+
|
731
|
+
InfrastructureServiceGetStatus( operation ) == responses[InterfaceOperation2ProcessName(operation)].status
|
732
|
+
|
733
|
+
|
734
|
+
|
735
|
+
|
736
|
+
|
737
|
+
|
738
|
+
|
739
|
+
|
740
|
+
|
741
|
+
|
742
|
+
NewStep( procci, procInput, ctx ) == [ process |-> procci, bindRule |-> WildCard ,bindSet |-> procInput, ctx |-> ctx ]
|
743
|
+
|
744
|
+
|
745
|
+
|
746
|
+
|
747
|
+
|
748
|
+
|
749
|
+
|
750
|
+
|
751
|
+
eth_elementExists( set, key, id ) == Cardinality( { e \in set : e[key] = id } ) = 1
|
752
|
+
|
753
|
+
|
754
|
+
|
755
|
+
|
756
|
+
|
757
|
+
eth_gasPrice == 0
|
758
|
+
|
759
|
+
|
760
|
+
|
761
|
+
|
762
|
+
|
763
|
+
eth_gasValue( gas ) == gas * eth_gasPrice
|
764
|
+
|
765
|
+
|
766
|
+
|
767
|
+
|
768
|
+
|
769
|
+
|
770
|
+
|
771
|
+
|
772
|
+
eth_intrinsicGas == 1
|
773
|
+
|
774
|
+
|
775
|
+
|
776
|
+
|
777
|
+
|
778
|
+
|
779
|
+
|
780
|
+
|
781
|
+
|
782
|
+
eth_NextId( ids, address ) == CHOOSE x \in ids: (address = x /\ address # Nil) \/ address = Nil
|
783
|
+
|
784
|
+
|
785
|
+
|
786
|
+
|
787
|
+
|
788
|
+
|
789
|
+
|
790
|
+
|
791
|
+
|
792
|
+
eth_upFrontCost( request ) == request.value + eth_gasPrice * eth_intrinsicGas
|
793
|
+
|
794
|
+
VARIABLES dummy_input, input, eth_geth_newAccount__input, contractId_,
|
795
|
+
eth_geth_mine__input, contractId
|
796
|
+
|
797
|
+
vars == << steps, step, step_parameter, now, tx_running, resume_context,
|
798
|
+
responses, eth_accounts, eth_storageRoot, eth_addressPool, pc,
|
799
|
+
stack, dummy_input, input, eth_geth_newAccount__input, contractId_,
|
800
|
+
eth_geth_mine__input, contractId >>
|
801
|
+
|
802
|
+
ProcSet == {"geth(newAccount)"} \cup {"geth(mine)"} \cup {"Tail"}
|
803
|
+
|
804
|
+
Init == (* Global variables *)
|
805
|
+
/\ steps = Steps
|
806
|
+
/\ step = Nil
|
807
|
+
/\ step_parameter = {}
|
808
|
+
/\ now = 0
|
809
|
+
/\ tx_running = FALSE
|
810
|
+
/\ resume_context = Nil
|
811
|
+
/\ responses = InfrastructureServiceInit
|
812
|
+
/\ eth_accounts = { }
|
813
|
+
/\ eth_storageRoot = { }
|
814
|
+
/\ eth_addressPool = d_eth_address \ { Nil }
|
815
|
+
(* Procedure dummy *)
|
816
|
+
/\ dummy_input = [ self \in ProcSet |-> defaultInitValue]
|
817
|
+
(* Procedure schedule_process_proc *)
|
818
|
+
/\ input = [ self \in ProcSet |-> defaultInitValue]
|
819
|
+
(* Procedure eth_geth_newAccount_ *)
|
820
|
+
/\ eth_geth_newAccount__input = [ self \in ProcSet |-> defaultInitValue]
|
821
|
+
/\ contractId_ = [ self \in ProcSet |-> defaultInitValue]
|
822
|
+
(* Procedure eth_geth_mine_ *)
|
823
|
+
/\ eth_geth_mine__input = [ self \in ProcSet |-> defaultInitValue]
|
824
|
+
/\ contractId = [ self \in ProcSet |-> defaultInitValue]
|
825
|
+
/\ stack = [self \in ProcSet |-> << >>]
|
826
|
+
/\ pc = [self \in ProcSet |-> CASE self = "geth(newAccount)" -> "p_geth_newAccount__enter"
|
827
|
+
[] self = "geth(mine)" -> "p_geth_mine__enter"
|
828
|
+
[] self = "Tail" -> "tail_wait"]
|
829
|
+
|
830
|
+
dummy_start(self) == /\ pc[self] = "dummy_start"
|
831
|
+
/\ TRUE
|
832
|
+
/\ pc' = [pc EXCEPT ![self] = "Error"]
|
833
|
+
/\ UNCHANGED << steps, step, step_parameter, now,
|
834
|
+
tx_running, resume_context, responses,
|
835
|
+
eth_accounts, eth_storageRoot,
|
836
|
+
eth_addressPool, stack, dummy_input,
|
837
|
+
input, eth_geth_newAccount__input,
|
838
|
+
contractId_, eth_geth_mine__input,
|
839
|
+
contractId >>
|
840
|
+
|
841
|
+
dummy(self) == dummy_start(self)
|
842
|
+
|
843
|
+
schedule_process_start(self) == /\ pc[self] = "schedule_process_start"
|
844
|
+
/\ IF Cardinality( { p \in 1..Len(steps) : \A s \in steps[p]: s.ctx = Nil } ) <= 1
|
845
|
+
THEN /\ steps' = steps \o
|
846
|
+
<< { NewStep( (input[self].called), (input[self].input), Nil ) },
|
847
|
+
{ NewStep( step, Nil, ([ ret_ctx |-> [ stack[self][2] EXCEPT !.pc = stack[self][1].pc ] ]) ) } >>
|
848
|
+
ELSE /\ \E pos \in { p \in 2..Len(steps) : \A s \in steps[p]: s.ctx = Nil }:
|
849
|
+
steps' = (IF pos = Len(steps) THEN
|
850
|
+
steps \o
|
851
|
+
<< { NewStep( (input[self].called), (input[self].input), Nil ) },
|
852
|
+
{ NewStep( step, Nil, ([ ret_ctx |-> [ stack[self][2] EXCEPT !.pc = stack[self][1].pc ] ]) ) } >>
|
853
|
+
ELSE
|
854
|
+
SubSeq( steps, 1, pos-1 ) \o
|
855
|
+
<< { NewStep( (input[self].called), (input[self].input), Nil ) },
|
856
|
+
{ NewStep( step, Nil, ([ ret_ctx |-> [ stack[self][2] EXCEPT !.pc = stack[self][1].pc ] ]) ) } >> \o
|
857
|
+
SubSeq( steps, pos, Len(steps)))
|
858
|
+
/\ TRUE
|
859
|
+
/\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc]
|
860
|
+
/\ input' = [input EXCEPT ![self] = Head(stack[self]).input]
|
861
|
+
/\ stack' = [stack EXCEPT ![self] = Tail(stack[self])]
|
862
|
+
/\ UNCHANGED << step, step_parameter, now,
|
863
|
+
tx_running, resume_context,
|
864
|
+
responses, eth_accounts,
|
865
|
+
eth_storageRoot,
|
866
|
+
eth_addressPool, dummy_input,
|
867
|
+
eth_geth_newAccount__input,
|
868
|
+
contractId_,
|
869
|
+
eth_geth_mine__input,
|
870
|
+
contractId >>
|
871
|
+
|
872
|
+
schedule_process_proc(self) == schedule_process_start(self)
|
873
|
+
|
874
|
+
eth_geth_newAccount__start(self) == /\ pc[self] = "eth_geth_newAccount__start"
|
875
|
+
/\ TRUE
|
876
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_newAccount__0"]
|
877
|
+
/\ UNCHANGED << steps, step,
|
878
|
+
step_parameter, now,
|
879
|
+
tx_running, resume_context,
|
880
|
+
responses, eth_accounts,
|
881
|
+
eth_storageRoot,
|
882
|
+
eth_addressPool, stack,
|
883
|
+
dummy_input, input,
|
884
|
+
eth_geth_newAccount__input,
|
885
|
+
contractId_,
|
886
|
+
eth_geth_mine__input,
|
887
|
+
contractId >>
|
888
|
+
|
889
|
+
eth_geth_newAccount__0(self) == /\ pc[self] = "eth_geth_newAccount__0"
|
890
|
+
/\ PrintT(<< "new.account",eth_geth_newAccount__input[self],"free-pool=",eth_addressPool >>)
|
891
|
+
/\ eth_accounts' = (eth_accounts \union { [ address |-> eth_NextId( eth_addressPool,Nil ), balance |-> 0, codeHash |-> Nil ] })
|
892
|
+
/\ eth_addressPool' = eth_addressPool \ { eth_NextId( eth_addressPool,Nil ) }
|
893
|
+
/\ PrintT(<< "after-free-pool=",eth_addressPool' >>)
|
894
|
+
/\ PrintT(<< "after-accounts=",eth_accounts' >>)
|
895
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_newAccount__exit"]
|
896
|
+
/\ UNCHANGED << steps, step, step_parameter,
|
897
|
+
now, tx_running,
|
898
|
+
resume_context, responses,
|
899
|
+
eth_storageRoot, stack,
|
900
|
+
dummy_input, input,
|
901
|
+
eth_geth_newAccount__input,
|
902
|
+
contractId_,
|
903
|
+
eth_geth_mine__input,
|
904
|
+
contractId >>
|
905
|
+
|
906
|
+
eth_geth_newAccount__exit(self) == /\ pc[self] = "eth_geth_newAccount__exit"
|
907
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_newAccount__end"]
|
908
|
+
/\ UNCHANGED << steps, step, step_parameter,
|
909
|
+
now, tx_running,
|
910
|
+
resume_context, responses,
|
911
|
+
eth_accounts,
|
912
|
+
eth_storageRoot,
|
913
|
+
eth_addressPool, stack,
|
914
|
+
dummy_input, input,
|
915
|
+
eth_geth_newAccount__input,
|
916
|
+
contractId_,
|
917
|
+
eth_geth_mine__input,
|
918
|
+
contractId >>
|
919
|
+
|
920
|
+
eth_geth_newAccount__fail(self) == /\ pc[self] = "eth_geth_newAccount__fail"
|
921
|
+
/\ responses' = [responses EXCEPT ![InterfaceOperation2ProcessName("geth(newAccount)")] = InfrastructureServiceResponse( FALSE, Nil )]
|
922
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_newAccount__end"]
|
923
|
+
/\ UNCHANGED << steps, step, step_parameter,
|
924
|
+
now, tx_running,
|
925
|
+
resume_context,
|
926
|
+
eth_accounts,
|
927
|
+
eth_storageRoot,
|
928
|
+
eth_addressPool, stack,
|
929
|
+
dummy_input, input,
|
930
|
+
eth_geth_newAccount__input,
|
931
|
+
contractId_,
|
932
|
+
eth_geth_mine__input,
|
933
|
+
contractId >>
|
934
|
+
|
935
|
+
eth_geth_newAccount__abort(self) == /\ pc[self] = "eth_geth_newAccount__abort"
|
936
|
+
/\ PrintT(<<"ABORT eth_geth_newAccount_">>)
|
937
|
+
/\ responses' = [responses EXCEPT ![InterfaceOperation2ProcessName("geth(newAccount)")] = InfrastructureServiceResponse( Abort, Nil )]
|
938
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_newAccount__end"]
|
939
|
+
/\ UNCHANGED << steps, step,
|
940
|
+
step_parameter, now,
|
941
|
+
tx_running, resume_context,
|
942
|
+
eth_accounts,
|
943
|
+
eth_storageRoot,
|
944
|
+
eth_addressPool, stack,
|
945
|
+
dummy_input, input,
|
946
|
+
eth_geth_newAccount__input,
|
947
|
+
contractId_,
|
948
|
+
eth_geth_mine__input,
|
949
|
+
contractId >>
|
950
|
+
|
951
|
+
eth_geth_newAccount__end(self) == /\ pc[self] = "eth_geth_newAccount__end"
|
952
|
+
/\ TRUE
|
953
|
+
/\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc]
|
954
|
+
/\ contractId_' = [contractId_ EXCEPT ![self] = Head(stack[self]).contractId_]
|
955
|
+
/\ eth_geth_newAccount__input' = [eth_geth_newAccount__input EXCEPT ![self] = Head(stack[self]).eth_geth_newAccount__input]
|
956
|
+
/\ stack' = [stack EXCEPT ![self] = Tail(stack[self])]
|
957
|
+
/\ UNCHANGED << steps, step, step_parameter,
|
958
|
+
now, tx_running,
|
959
|
+
resume_context, responses,
|
960
|
+
eth_accounts,
|
961
|
+
eth_storageRoot,
|
962
|
+
eth_addressPool, dummy_input,
|
963
|
+
input, eth_geth_mine__input,
|
964
|
+
contractId >>
|
965
|
+
|
966
|
+
eth_geth_newAccount_(self) == eth_geth_newAccount__start(self)
|
967
|
+
\/ eth_geth_newAccount__0(self)
|
968
|
+
\/ eth_geth_newAccount__exit(self)
|
969
|
+
\/ eth_geth_newAccount__fail(self)
|
970
|
+
\/ eth_geth_newAccount__abort(self)
|
971
|
+
\/ eth_geth_newAccount__end(self)
|
972
|
+
|
973
|
+
eth_geth_mine__start(self) == /\ pc[self] = "eth_geth_mine__start"
|
974
|
+
/\ TRUE
|
975
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_mine__exit"]
|
976
|
+
/\ UNCHANGED << steps, step, step_parameter, now,
|
977
|
+
tx_running, resume_context,
|
978
|
+
responses, eth_accounts,
|
979
|
+
eth_storageRoot, eth_addressPool,
|
980
|
+
stack, dummy_input, input,
|
981
|
+
eth_geth_newAccount__input,
|
982
|
+
contractId_,
|
983
|
+
eth_geth_mine__input, contractId >>
|
984
|
+
|
985
|
+
eth_geth_mine__exit(self) == /\ pc[self] = "eth_geth_mine__exit"
|
986
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_mine__end"]
|
987
|
+
/\ UNCHANGED << steps, step, step_parameter, now,
|
988
|
+
tx_running, resume_context,
|
989
|
+
responses, eth_accounts,
|
990
|
+
eth_storageRoot, eth_addressPool,
|
991
|
+
stack, dummy_input, input,
|
992
|
+
eth_geth_newAccount__input,
|
993
|
+
contractId_, eth_geth_mine__input,
|
994
|
+
contractId >>
|
995
|
+
|
996
|
+
eth_geth_mine__fail(self) == /\ pc[self] = "eth_geth_mine__fail"
|
997
|
+
/\ responses' = [responses EXCEPT ![InterfaceOperation2ProcessName("geth(mine)")] = InfrastructureServiceResponse( FALSE, Nil )]
|
998
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_mine__end"]
|
999
|
+
/\ UNCHANGED << steps, step, step_parameter, now,
|
1000
|
+
tx_running, resume_context,
|
1001
|
+
eth_accounts, eth_storageRoot,
|
1002
|
+
eth_addressPool, stack,
|
1003
|
+
dummy_input, input,
|
1004
|
+
eth_geth_newAccount__input,
|
1005
|
+
contractId_, eth_geth_mine__input,
|
1006
|
+
contractId >>
|
1007
|
+
|
1008
|
+
eth_geth_mine__abort(self) == /\ pc[self] = "eth_geth_mine__abort"
|
1009
|
+
/\ PrintT(<<"ABORT eth_geth_mine_">>)
|
1010
|
+
/\ responses' = [responses EXCEPT ![InterfaceOperation2ProcessName("geth(mine)")] = InfrastructureServiceResponse( Abort, Nil )]
|
1011
|
+
/\ pc' = [pc EXCEPT ![self] = "eth_geth_mine__end"]
|
1012
|
+
/\ UNCHANGED << steps, step, step_parameter, now,
|
1013
|
+
tx_running, resume_context,
|
1014
|
+
eth_accounts, eth_storageRoot,
|
1015
|
+
eth_addressPool, stack,
|
1016
|
+
dummy_input, input,
|
1017
|
+
eth_geth_newAccount__input,
|
1018
|
+
contractId_,
|
1019
|
+
eth_geth_mine__input, contractId >>
|
1020
|
+
|
1021
|
+
eth_geth_mine__end(self) == /\ pc[self] = "eth_geth_mine__end"
|
1022
|
+
/\ TRUE
|
1023
|
+
/\ pc' = [pc EXCEPT ![self] = Head(stack[self]).pc]
|
1024
|
+
/\ contractId' = [contractId EXCEPT ![self] = Head(stack[self]).contractId]
|
1025
|
+
/\ eth_geth_mine__input' = [eth_geth_mine__input EXCEPT ![self] = Head(stack[self]).eth_geth_mine__input]
|
1026
|
+
/\ stack' = [stack EXCEPT ![self] = Tail(stack[self])]
|
1027
|
+
/\ UNCHANGED << steps, step, step_parameter, now,
|
1028
|
+
tx_running, resume_context,
|
1029
|
+
responses, eth_accounts,
|
1030
|
+
eth_storageRoot, eth_addressPool,
|
1031
|
+
dummy_input, input,
|
1032
|
+
eth_geth_newAccount__input,
|
1033
|
+
contractId_ >>
|
1034
|
+
|
1035
|
+
eth_geth_mine_(self) == eth_geth_mine__start(self)
|
1036
|
+
\/ eth_geth_mine__exit(self)
|
1037
|
+
\/ eth_geth_mine__fail(self)
|
1038
|
+
\/ eth_geth_mine__abort(self)
|
1039
|
+
\/ eth_geth_mine__end(self)
|
1040
|
+
|
1041
|
+
p_geth_newAccount__enter == /\ pc["geth(newAccount)"] = "p_geth_newAccount__enter"
|
1042
|
+
/\ ProcessEnabled( steps, "p_geth_newAccount_" )
|
1043
|
+
/\ step' = ProcessRunning( steps )
|
1044
|
+
/\ step_parameter' = ProcessParameter( steps )
|
1045
|
+
/\ resume_context' = ProcessStep( steps ).ctx
|
1046
|
+
/\ responses' = InfrastructureServiceInit
|
1047
|
+
/\ tx_running' = TRUE
|
1048
|
+
/\ now' = TickNext( now )
|
1049
|
+
/\ \E _input \in { t \in ProcessParameterInput( t_req_geth_newAccount_ ) : ProcessParameterBind( t ) }:
|
1050
|
+
/\ PrintT(<<"Default process p_geth_newAccount_ for operation 'geth(newAccount)',tick=", currentTime>>)
|
1051
|
+
/\ Assert(( _input \in t_req_geth_newAccount_ ),
|
1052
|
+
"Failure of assertion at line 599, column 13.")
|
1053
|
+
/\ PrintT(<< "TODO: Greetings from service-implementation",_input >>)
|
1054
|
+
/\ /\ eth_geth_newAccount__input' = [eth_geth_newAccount__input EXCEPT !["geth(newAccount)"] = _input]
|
1055
|
+
/\ stack' = [stack EXCEPT !["geth(newAccount)"] = << [ procedure |-> "eth_geth_newAccount_",
|
1056
|
+
pc |-> "p_geth_newAccount__exit",
|
1057
|
+
contractId_ |-> contractId_["geth(newAccount)"],
|
1058
|
+
eth_geth_newAccount__input |-> eth_geth_newAccount__input["geth(newAccount)"] ] >>
|
1059
|
+
\o stack["geth(newAccount)"]]
|
1060
|
+
/\ contractId_' = [contractId_ EXCEPT !["geth(newAccount)"] = defaultInitValue]
|
1061
|
+
/\ pc' = [pc EXCEPT !["geth(newAccount)"] = "eth_geth_newAccount__start"]
|
1062
|
+
/\ UNCHANGED << steps, eth_accounts,
|
1063
|
+
eth_storageRoot, eth_addressPool,
|
1064
|
+
dummy_input, input,
|
1065
|
+
eth_geth_mine__input, contractId >>
|
1066
|
+
|
1067
|
+
p_geth_newAccount__exit == /\ pc["geth(newAccount)"] = "p_geth_newAccount__exit"
|
1068
|
+
/\ steps' = ProcessesToRun( steps )
|
1069
|
+
/\ Assert(( resume_context = Nil ),
|
1070
|
+
"Failure of assertion at line 362, column 9 of macro called at line 604, column 14.")
|
1071
|
+
/\ tx_running' = FALSE
|
1072
|
+
/\ pc' = [pc EXCEPT !["geth(newAccount)"] = "p_geth_newAccount__enter"]
|
1073
|
+
/\ UNCHANGED << step, step_parameter, now,
|
1074
|
+
resume_context, responses,
|
1075
|
+
eth_accounts, eth_storageRoot,
|
1076
|
+
eth_addressPool, stack, dummy_input,
|
1077
|
+
input, eth_geth_newAccount__input,
|
1078
|
+
contractId_, eth_geth_mine__input,
|
1079
|
+
contractId >>
|
1080
|
+
|
1081
|
+
p_geth_newAccount_ == p_geth_newAccount__enter \/ p_geth_newAccount__exit
|
1082
|
+
|
1083
|
+
p_geth_mine__enter == /\ pc["geth(mine)"] = "p_geth_mine__enter"
|
1084
|
+
/\ ProcessEnabled( steps, "p_geth_mine_" )
|
1085
|
+
/\ step' = ProcessRunning( steps )
|
1086
|
+
/\ step_parameter' = ProcessParameter( steps )
|
1087
|
+
/\ resume_context' = ProcessStep( steps ).ctx
|
1088
|
+
/\ responses' = InfrastructureServiceInit
|
1089
|
+
/\ tx_running' = TRUE
|
1090
|
+
/\ now' = TickNext( now )
|
1091
|
+
/\ \E _input \in { t \in ProcessParameterInput( t_req_geth_mine_ ) : ProcessParameterBind( t ) }:
|
1092
|
+
/\ PrintT(<<"Default process p_geth_mine_ for operation 'geth(mine)',tick=", currentTime>>)
|
1093
|
+
/\ Assert(( _input \in t_req_geth_mine_ ),
|
1094
|
+
"Failure of assertion at line 618, column 13.")
|
1095
|
+
/\ PrintT(<< "TODO: Greetings from service-implementation",_input >>)
|
1096
|
+
/\ /\ eth_geth_mine__input' = [eth_geth_mine__input EXCEPT !["geth(mine)"] = _input]
|
1097
|
+
/\ stack' = [stack EXCEPT !["geth(mine)"] = << [ procedure |-> "eth_geth_mine_",
|
1098
|
+
pc |-> "p_geth_mine__exit",
|
1099
|
+
contractId |-> contractId["geth(mine)"],
|
1100
|
+
eth_geth_mine__input |-> eth_geth_mine__input["geth(mine)"] ] >>
|
1101
|
+
\o stack["geth(mine)"]]
|
1102
|
+
/\ contractId' = [contractId EXCEPT !["geth(mine)"] = defaultInitValue]
|
1103
|
+
/\ pc' = [pc EXCEPT !["geth(mine)"] = "eth_geth_mine__start"]
|
1104
|
+
/\ UNCHANGED << steps, eth_accounts, eth_storageRoot,
|
1105
|
+
eth_addressPool, dummy_input, input,
|
1106
|
+
eth_geth_newAccount__input, contractId_ >>
|
1107
|
+
|
1108
|
+
p_geth_mine__exit == /\ pc["geth(mine)"] = "p_geth_mine__exit"
|
1109
|
+
/\ steps' = ProcessesToRun( steps )
|
1110
|
+
/\ Assert(( resume_context = Nil ),
|
1111
|
+
"Failure of assertion at line 362, column 9 of macro called at line 623, column 14.")
|
1112
|
+
/\ tx_running' = FALSE
|
1113
|
+
/\ pc' = [pc EXCEPT !["geth(mine)"] = "p_geth_mine__enter"]
|
1114
|
+
/\ UNCHANGED << step, step_parameter, now, resume_context,
|
1115
|
+
responses, eth_accounts, eth_storageRoot,
|
1116
|
+
eth_addressPool, stack, dummy_input,
|
1117
|
+
input, eth_geth_newAccount__input,
|
1118
|
+
contractId_, eth_geth_mine__input,
|
1119
|
+
contractId >>
|
1120
|
+
|
1121
|
+
p_geth_mine_ == p_geth_mine__enter \/ p_geth_mine__exit
|
1122
|
+
|
1123
|
+
tail_wait == /\ pc["Tail"] = "tail_wait"
|
1124
|
+
/\ ( Len(steps) = 0 )
|
1125
|
+
/\ step' = "Tail"
|
1126
|
+
/\ step_parameter' = {}
|
1127
|
+
/\ pc' = [pc EXCEPT !["Tail"] = "tail_"]
|
1128
|
+
/\ UNCHANGED << steps, now, tx_running, resume_context, responses,
|
1129
|
+
eth_accounts, eth_storageRoot, eth_addressPool,
|
1130
|
+
stack, dummy_input, input,
|
1131
|
+
eth_geth_newAccount__input, contractId_,
|
1132
|
+
eth_geth_mine__input, contractId >>
|
1133
|
+
|
1134
|
+
tail_ == /\ pc["Tail"] = "tail_"
|
1135
|
+
/\ TRUE
|
1136
|
+
/\ pc' = [pc EXCEPT !["Tail"] = "tail_"]
|
1137
|
+
/\ UNCHANGED << steps, step, step_parameter, now, tx_running,
|
1138
|
+
resume_context, responses, eth_accounts,
|
1139
|
+
eth_storageRoot, eth_addressPool, stack, dummy_input,
|
1140
|
+
input, eth_geth_newAccount__input, contractId_,
|
1141
|
+
eth_geth_mine__input, contractId >>
|
1142
|
+
|
1143
|
+
tail == tail_wait \/ tail_
|
1144
|
+
|
1145
|
+
Next == p_geth_newAccount_ \/ p_geth_mine_ \/ tail
|
1146
|
+
\/ (\E self \in ProcSet: \/ dummy(self) \/ schedule_process_proc(self)
|
1147
|
+
\/ eth_geth_newAccount_(self)
|
1148
|
+
\/ eth_geth_mine_(self))
|
1149
|
+
|
1150
|
+
Spec == /\ Init /\ [][Next]_vars
|
1151
|
+
/\ WF_vars(p_geth_newAccount_)
|
1152
|
+
/\ WF_vars(p_geth_mine_)
|
1153
|
+
/\ WF_vars(tail)
|
1154
|
+
|
1155
|
+
\* END TRANSLATION
|
1156
|
+
(******************************************************************
|
1157
|
+
Validate types for infrastructure service return values
|
1158
|
+
- modelData infrastructureServices
|
1159
|
+
- template state_type_invariant-infrastructure-service.mustache
|
1160
|
+
|
1161
|
+
******************************************************************)
|
1162
|
+
|
1163
|
+
(*
|
1164
|
+
Type invariants for infrastructure service return values.
|
1165
|
+
|
1166
|
+
|
1167
|
+
All fields in 'responses' state variable store a record [ status |-> ... , response |-> ... ]
|
1168
|
+
|
1169
|
+
*)
|
1170
|
+
|
1171
|
+
InfrastructureService_TypeInvariant_i_geth_newAccount_ == responses.i_geth_newAccount_.response \in { Nil }
|
1172
|
+
|
1173
|
+
|
1174
|
+
\* Type invariant for infrastructure service return values
|
1175
|
+
|
1176
|
+
InfrastructureService_TypeInvariant_i_geth_mine_ == responses.i_geth_mine_.response \in { Nil }
|
1177
|
+
|
1178
|
+
|
1179
|
+
\* Type invariant for infrastructure service return values
|
1180
|
+
|
1181
|
+
InfrastructureService_TypeInvariant == TRUE
|
1182
|
+
/\ InfrastructureService_TypeInvariant_i_geth_newAccount_
|
1183
|
+
/\ InfrastructureService_TypeInvariant_i_geth_mine_
|
1184
|
+
|
1185
|
+
|
1186
|
+
|
1187
|
+
\* Extension point template extend/extend_invariant.mustache:
|
1188
|
+
|
1189
|
+
|
1190
|
+
|
1191
|
+
\* Extension point template extend/extend_assumptions.mustache:
|
1192
|
+
|
1193
|
+
|
1194
|
+
|
1195
|
+
=============================================================================
|