-
Notifications
You must be signed in to change notification settings - Fork 7
/
rollup.yaml
504 lines (442 loc) · 16.5 KB
/
rollup.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
openapi: 3.0.0
info:
title: Cartesi Rollup HTTP API
version: '0.9.0'
license:
name: Apache-2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
description: |
API that the Cartesi Rollup HTTP Server implements.
In the box below, there is an example of a DApp backend that uses the Rollup HTTP API.
```
import requests
import sys
rollup = sys.argv[1]
def check_status_code(response):
if response.status_code not in range(200, 300):
print(f'Error: invalid status code {response.status_code}')
sys.exit(1)
return response
finish = {'status': 'accept'}
while True:
print('Sending finish')
r = check_status_code(requests.post(rollup + '/finish', json=finish))
if r.status_code == 202:
print('No pending rollup request, trying again')
continue
rollup_request = r.json()
if rollup_request['request_type'] == 'advance_state':
print('Sending voucher')
voucher = {
'destination': rollup_request['data']['metadata']['msg_sender'],
'payload': rollup_request['data']['payload']
}
check_status_code(requests.post(rollup + '/voucher', json=voucher))
print('Sending notice')
notice = {'payload': rollup_request['data']['payload']}
check_status_code(requests.post(rollup + '/notice', json=notice))
print('Sending report')
report = {'payload': rollup_request['data']['payload']}
check_status_code(requests.post(rollup + '/report', json=report))
finish['status'] = 'accept'
elif rollup_request['request_type'] == 'inspect_state':
print('Sending report per inspect request')
report = {'payload': rollup_request['data']['payload']}
check_status_code(requests.post(rollup + '/report', json=report))
else:
print('Throwing rollup exception')
exception = {'payload': rollup_request['data']['payload']}
requests.post(rollup + '/exception', json=exception)
break
```
In production mode, if the DApp exits the Rollups initialization script will register a Rollup Exception.
See [/exception](#api-Default-registerException).
In host mode, the Cartesi Rollups infrastructure is not able to detect that the DApp exited.
It is up to the DApp developer to re-launch the DApp.
paths:
/finish:
post:
operationId: finish
summary: Finish and get next request
description: |
The DApp backend should call this method to start processing rollup requests.
The Rollup HTTP Server returns the next rollup request in the response body.
The possible values for the request_type field are 'advance_state' and 'inspect_state'.
The data field contains the rollup request input data.
For advance-state requests, the input data contains the advance-state metadata and the payload.
For inspect-state requests, the input data contains only the payload.
After processing a rollup request, the DApp back-end should call again the finish method.
For advance-state requests, depending on the result of the request processing, it should fill the status field of the request body with 'accept' or 'reject'.
The Rollup HTTP Server ignores the content of the status field for the first finish request and after an inspect-state request.
If the advance-state request is rejected, the vouchers and notices are discarded.
In contrast, reports are not discarded in case of rejection.
When running inside a Cartesi machine, the Cartesi Server Manager reverts the entire state of the machine to what it was before receiving the request.
During a finish call, the next rollup request might not be immediately available.
When the DApp backend and the Rollup HTTP Server are running inside a Cartesi machine, the Cartesi Server Manager pauses the whole machine execution until the next request is ready.
When running in host mode, the Rollup HTTP Server returns the status code 202 after 10 seconds to avoid the connection timing out.
When the Rollup HTTP Server returns 202, the DApp backend should retry the call to finish passing the same arguments as before.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Finish"
required: true
responses:
"200":
description: Finish accepted and next rollup request returned.
content:
application/json:
schema:
$ref: "#/components/schemas/RollupRequest"
"202":
description: Finish accepted but try again to obtain the next request.
content:
text/plain:
schema:
type: string
example: "no rollup request available"
default:
description: Error response.
content:
text/plain:
schema:
$ref: "#/components/schemas/Error"
/voucher:
post:
operationId: addVoucher
summary: Add a new voucher
description: |
The DApp backend can call this method to add a new voucher when processing an advance-state request.
Vouchers are collateral effects actionable in the blockchain.
Between calls to the finish method, the voucher method can be called up to 32k times.
The returned value is the index of the voucher for the current advance-state request.
In other words, the index counting restarts at every request.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Voucher"
required: true
responses:
"201":
description: Created the voucher.
content:
application/json:
schema:
$ref: "#/components/schemas/IndexResponse"
default:
description: Error response.
content:
text/plain:
schema:
$ref: "#/components/schemas/Error"
/notice:
post:
operationId: addNotice
summary: Add a new notice
description: |
The DApp backend can call this method to add a new notice when processing the advance-state request.
A notice describes any changes to the internal state of the DApp that may be relevant to the blockchain.
Between calls to the finish method, the notice method can be called up to 32k times.
The returned value is the index of the notice for the current advance request.
In other words, the index counting restarts at every request.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Notice"
required: true
responses:
"201":
description: Created the notice.
content:
application/json:
schema:
$ref: "#/components/schemas/IndexResponse"
default:
description: Error response.
content:
text/plain:
schema:
$ref: "#/components/schemas/Error"
/report:
post:
operationId: addReport
summary: Add a new report
description: |
The DApp can call this method to add a new report for the given rollup request.
A report can be a diagnostic or a log; reports are not discarded when a request is rejected.
Between calls to the finish method, the report method can be called any number of times.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Report"
required: true
responses:
"202":
description: Created the report.
default:
description: Error response.
content:
text/plain:
schema:
$ref: "#/components/schemas/Error"
/gio:
post:
operationId: gio
summary: Generic Input/Output
description: |
The DApp can call this method to perform a generic input/output request.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/GioRequest"
required: true
responses:
"200":
description: Request performed successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/GioResponse"
default:
description: Error response.
content:
text/plain:
schema:
$ref: "#/components/schemas/Error"
/exception:
post:
operationId: registerException
summary: Register an exception
description: |
The DApp should call this method when it cannot proceed with the request processing after an exception happens.
This method should be the last method ever called by the DApp backend while processing a request.
When running in production mode, the Cartesi Server Manager pauses the Cartesi Machine and reverts the entire state of the machine to what it was before receiving the request.
No HTTP status code will be sent or received.
When running in host mode, the Rollup HTTP Server returns the status code 200.
In both cases, the input will be skipped with the reason EXCEPTION and the exception message will be forwarded.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Exception"
required: true
responses:
"202":
description: Accepted the exception throw.
default:
description: Error response.
content:
text/plain:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Finish:
type: object
properties:
status:
type: string
enum: [accept, reject]
example: "accept"
required:
- status
RollupRequest:
type: object
properties:
request_type:
type: string
enum: [advance_state, inspect_state]
example: "advance_state"
data:
type: object
oneOf:
- $ref: "#/components/schemas/Advance"
- $ref: "#/components/schemas/Inspect"
required:
- request_type
- data
Advance:
type: object
properties:
metadata:
$ref: "#/components/schemas/Metadata"
payload:
$ref: "#/components/schemas/Payload"
required:
- metadata
- payload
Metadata:
type: object
properties:
chain_id:
type: integer
format: uint64
description: Network identifier.
example: 42
app_contract:
type: string
description: 20-byte address of the application contract.
example: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
pattern: "^0x([0-9a-fA-F]{40})$"
format: address
msg_sender:
type: string
description: 20-byte address of the account that submitted the input.
example: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
pattern: "^0x([0-9a-fA-F]{40})$"
format: address
input_index:
type: integer
format: uint64
description: Input index starting from genesis.
example: 123
block_number:
type: integer
format: uint64
description: Block number when input was posted.
example: 10000000
block_timestamp:
type: integer
format: uint64
description: Unix timestamp of block in milliseconds.
example: 1588598533000
prev_randao:
type: string
description: The latest RANDAO mix of the post beacon state of the previous block.
example: "0x0000000000000000000000000000000000000000000000000000000000000001"
pattern: "^0x([0-9a-fA-F]{64})$"
format: hex
required:
- chain_id
- app_contract
- msg_sender
- input_index
- block_number
- block_timestamp
- prev_randao
Payload:
type: string
description: |
The payload is in the Ethereum hex binary format.
The first two characters are '0x' followed by pairs of hexadecimal numbers that correspond to one byte.
For instance, '0xdeadbeef' corresponds to a payload with length 4 and bytes 222, 173, 190, 175.
An empty payload is represented by the string '0x'.
example: "0xdeadbeef"
pattern: "^0x([0-9a-fA-F]{2})*$"
format: hex
Inspect:
type: object
properties:
payload:
type: string
description: |
The payload contains arbitrary hex-encoded binary data.
The first two characters are '0x' followed by pairs of hexadecimal numbers that correspond to one byte.
For instance, '0xdeadbeef' corresponds to a payload with length 4 and bytes 222, 173, 190, 175.
An empty payload is represented by the string '0x'.
example: "0xdeadbeef"
pattern: "^0x([0-9a-fA-F]{2})*$"
format: hex
required:
- payload
Voucher:
type: object
properties:
destination:
type: string
description: 20-byte address of the destination contract for which the payload will be sent.
example: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
pattern: "^0x([0-9a-fA-F]{40})$"
format: address
value:
type: string
description: A big-endian 32-byte unsigned integer in hex.
example: "0x0000000000000000000000000000000000000000000000000000000000000001"
pattern: "^0x([0-9a-fA-F]{64})$"
format: hex
payload:
type: string
description: |
String in Ethereum hex binary format describing a method call to be executed by the destination contract.
The first two characters are '0x' followed by pairs of hexadecimal numbers that correspond to one byte.
For instance, '0xcdcd77c0' corresponds to a payload with length 4 and bytes 205, 205, 119, 192.
To describe the method call, the payload should consist of a function selector (method identifier) followed
by its ABI-encoded arguments.
ref: https://docs.soliditylang.org/en/v0.8.19/abi-spec.html
example: "0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001"
format: hex
required:
- destination
- value
- payload
Notice:
type: object
properties:
payload:
$ref: "#/components/schemas/Payload"
required:
- payload
Report:
type: object
properties:
payload:
$ref: "#/components/schemas/Payload"
required:
- payload
GioRequest:
type: object
properties:
domain:
type: integer
format: uint16
description: An arbitrary number representing the request domain. Domains less then 0x10 are reserved.
example: 16
id:
type: string
format: hex
description: Domain-specific information identifying the request.
example: "0xdeadbeef"
required:
- domain
- id
GioResponse:
type: object
properties:
code:
type: integer
format: uint16
description: A number representing the response code.
example: 8
data:
type: string
format: hex
description: The response data.
example: "0xdeadbeef"
required:
- code
- data
Exception:
type: object
properties:
payload:
$ref: "#/components/schemas/Payload"
required:
- payload
IndexResponse:
type: object
properties:
index:
type: integer
format: uint64
description: Position in the Merkle tree.
example: 123
required:
- index
Error:
type: string
description: Detailed error message.
example: "The request could not be understood by the server due to malformed syntax"