Skip to content

Commit 5ebda33

Browse files
committed
Documentation of a decentralized sequencer
1 parent 671a928 commit 5ebda33

20 files changed

+1096
-12
lines changed

warp-academy-docs/docs/sdk/advanced/bundled-interaction.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,3 @@ query {
200200
## Interaction retrieval via Warp gateway
201201

202202
The Warp `/gateway/interactions/:id` endpoint allows to retrieve the interaction info based on its original id.
203-
204-
## Further development
205-
206-
1. Blind/trustless sequencing - https://github.com/warp-contracts/gateway/issues/48
207-
2. Sequencer decentralization - https://github.com/warp-contracts/gateway/issues/93

warp-academy-docs/docs/sdk/advanced/vrf.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Verifiable randomness
22

3+
:::caution
4+
Random values will be handled in a new way once the decentralized sequencer is launched.
5+
More details can be found [here](/docs/sequencer/lifecycle/ordering#random-values).
6+
For backward compatibility, the function `SmartWeave.vrf.randomInt(maxValue)` will still work, but it will use the new function `SmartWeave.randomNumber(maxValue)` under the hood.
7+
:::
8+
39
You have an option to use random values in contracts via Verifiable Random Functions.
410
This may be a very useful feature in gaming, dynamic NFT generation, etc.
511

warp-academy-docs/docs/sdk/legacy/bundled-interaction-legacy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Warp Sequencer - legacy
22

33
:::caution
4-
Please note, that you are viewing old Warp Sequencer docs. Since `[email protected]` nested bundles have been introduced instead of the format described in this file. In order to read about current interaction format, please head to [Warp Sequencer](../advanced/bundled-interaction.md).
4+
Please note, that you are viewing old Warp Sequencer docs. Since `[email protected]` nested bundles have been introduced instead of the format described in this file. In order to read about current interaction format, please head to [Warp Sequencer](../../sequencer/introduction.md).
55
:::
66

77
Warp Sequencer is a module that is responsible for submitting users' transactions into Arweave (via [Bundlr Network](https://bundlr.network/)).
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# API methods
2+
3+
Every sequencer node provides endpoints through a REST API that allows querying the network state or sending new interactions.
4+
Below are listed the methods directly related to the functionality of the sequencer.
5+
6+
:::tip
7+
In addition to the methods listed below, sequencer nodes offer endpoints related to the framework and consensus algorithm.
8+
For example, a list of these methods for the testnet network can be found at: https://sequencer-0.testnet.warp.cc.
9+
:::
10+
11+
## Submits a new interaction to the sequencer
12+
```
13+
/api/v1/data-item
14+
```
15+
This method is used to submit a new interaction to the sequencer.
16+
The request payload should contain the interaction in the form of a DataItem, conforming to the [ANS-104](https://github.com/ArweaveTeam/arweave-standards/blob/master/ans/ANS-104.md) format.
17+
Upon receiving such a request, the node validates the interaction.
18+
If it is valid, the node encapsulates it in a message, adds a sequencer transaction to its mempool, and broadcasts it to the other nodes in the network.
19+
20+
### Possible responses
21+
22+
| Code | Description | Example value |
23+
| ---- | ------------------------------------------ | -------------------------------- |
24+
| 200 | The interaction was successfully submitted |<pre>{data_item_id: 'GHBDu8MoQcTSrvTHF_5LGwe_YEXb6dgMfGuWgIgcK-U',<br /> nonce: 1,<br /> sender: 'warp16ayu6zt7pxlmgf708agsxv2qmnfpfrh0pay3e0'}</pre> |
25+
| 400 | The request was invalid |<pre>{type: 'broadcast response with non-zero code',<br /> message:<br /> {Code: 1110,<br /> RawLog: 'data item does not have "Contract" tag:<br /> no contract tag'},<br /> status: { code: 400, text: 'Bad Request'}}</pre>|
26+
| 409 | Invalid `Nonce` value for the given sender |<pre>{type: 'broadcast response with non-zero code',<br /> message:<br /> {Code: 32,<br /> RawLog: 'account sequence mismatch, expected 3, got 4:<br /> incorrect account sequence'},<br /> status: { code: 409, text: 'Conflict'}}</pre>|
27+
| 503 | Mempool is full |<pre>{type: 'broadcast response with non-zero code',<br /> message:<br /> {Code: 20,<br /> RawLog: 'mempool is full'},<br /> status: { code: 503, text: 'Service Unavailable'}}</pre>|
28+
29+
## Expected nonce value
30+
```
31+
/api/v1/nonce
32+
```
33+
This method returns the expected next nonce value for a given sender.
34+
35+
### Request
36+
The request body should be in the form of JSON:
37+
```json
38+
{
39+
"signature_type":1,
40+
"owner":"..."
41+
}
42+
```
43+
Where:
44+
- `signature_type` - the integer that specifies the type of signature that the sender uses. Possible values that are currently supported by the sequencer:
45+
- `1` - Arweave signature
46+
- `3` - Ethereum signature
47+
- `owner` - the public key of the owner
48+
49+
### Possible responses
50+
51+
| Code | Description | Example value |
52+
| ---- | ------------------------------------------ | -------------------------------- |
53+
| 200 | The nonce was successfully returned |<pre>{address: 'warp17jupac353t0euh95f70thl5vs8xcs4m0ydjq5q',<br /> nonce: 0}</pre> |
54+
| 400 | The request was invalid |<pre>{type: 'invalid request',<br /> message: '...',<br /> status: {code: 400,text: 'Bad Request'}}</pre>|
55+
56+
## Get transaction by data item id
57+
```
58+
/api/v1/tx-data-item-id
59+
```
60+
61+
This method returns the hash of the sequencer transaction that contains interactions with the given ID.
62+
The request body must contain JSON with the following field:
63+
- `data_item_id` - the ID of the interaction.
64+
65+
The response body contains the following field:
66+
- `tx_hash` - the hash of the sequencer transaction.
67+
68+
### Possible responses
69+
70+
| Code | Description | Example value |
71+
| ---- | ---------------------------------------------- | -------------------------------- |
72+
| 200 | The transaction hash was successfully returned |<pre>{tx_hash:'...'}</pre> |
73+
| 400 | The request was invalid |<pre>{type: 'invalid request',<br /> message: '...',<br /> status:{ code: 400, text: 'Bad Request'}}</pre>|
74+
| 404 | No transaction found |<pre>{type: 'not found',<br /> message: 'transaction not found for the given data item id',<br /> status:{code:404,text: 'Not Found'}}</pre>|
75+
76+
77+
:::tip
78+
With the hash of a transaction, querying the sequencer node for transaction details is possible using the following endpoint: `/cosmos/tx/v1beta1/txs/{hash}`.
79+
:::
80+
81+
## Get transaction by sender and nonce
82+
```
83+
/api/v1/tx-sender-nonce
84+
```
85+
86+
This method returns the hash of the sequencer transaction for a given sender address and nonce.
87+
The request body must contain JSON with the following fields:
88+
- `sender` - the address of the sender.
89+
- `nonce` - the nonce of the interaction.
90+
91+
The response body contains the following field:
92+
- `tx_hash` - the hash of the sequencer transaction.
93+
94+
### Possible responses
95+
96+
| Code | Description | Example value |
97+
| ---- | ---------------------------------------------- | -------------------------------- |
98+
| 200 | The transaction hash was successfully returned |<pre>{tx_hash:'...'}</pre> |
99+
| 400 | The request was invalid |<pre>{type: 'invalid request',<br /> message: '...',<br /> status:{ code: 400, text: 'Bad Request'}}</pre>|
100+
| 404 | No transaction found |<pre>{type: 'not found',<br /> message: 'transaction not found for the given sender and nonce',<br /> status:{code:404,text: 'Not Found'}}</pre>|
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# Warp Centralized Sequencer
2+
3+
:::caution
4+
This section describes the operation of the current centralized sequencer, which will soon be replaced by the new [decentralized solution](/docs/sequencer/decentralized).
5+
:::
6+
7+
## How it works
8+
9+
Instead of posting the interaction transactions directly to Arweave mainnet, Warp SDK creates a data item with interaction input and tags which is then signed with user's wallet. Data item is then sent to Warp Sequencer (`/gateway/v2/sequencer/register` endpoint) (this is the default behaviour of Warp's SDK `contract.writeInteraction`
10+
function, when `forMainnet` instance is being used).
11+
12+
The Warp Sequencer then:
13+
14+
#### 1. Generates a sort key
15+
16+
A sort key is generated from:
17+
18+
1. current mainnet network height
19+
2. current sequence value
20+
3. original transaction id
21+
4. current mainnet block hash
22+
23+
In the original SmartWeave protocol specification, a _sort key_ is defined
24+
as a `[ block_height,sha256(transactionId + blockHash) ]`, where:
25+
26+
1. `block_height` - current network height, l-padded with `0` to 12 chars, e.g. for block height `1015556`, the
27+
result is `000001015556`
28+
2. `sha256(transactionId + blockHash)` - a `sha256` hash of the concatenated buffers of the transaction id and block
29+
hash,
30+
e.g. for txId `UR_35HORbjjZ_NnUqinkZuWkcNB1-gBST3Rezt5JrDs` and block
31+
hash `ixWCxRN36DjVUxQRa68xIeoZLfvLDTtX78e0ae8RAAJjOPpDBuVKVaEKYOpq7bLS`,
32+
the result is `44edd70f2018924f22a878a558a8f2d5cae8bc1f718d567df43bf52b6384d260`.
33+
34+
The complete _sort key_ for the above values would
35+
be: `000001015556,44edd70f2018924f22a878a558a8f2d5cae8bc1f718d567df43bf52b6384d260`.
36+
37+
The generated sort keys are then used by the SmartWeave protocol to lexicographically sort the transactions.
38+
39+
The Warp Sequencer extends this default mechanism by the current sequence value.
40+
The formula for the _sort key_ is extended to:
41+
`[ block_height,sequence_value,sha256(transactionId + blockHash) ]`
42+
43+
This sequence value can be obtained from the Sequencer's node timestamp, database or other sources.
44+
In its current implementation - a Sequencer node timestamp value is being used.
45+
This in effect gives a fair transactions ordering - the transactions will have the sequence assigned in order in which
46+
they are processed by the Sequencer.
47+
48+
Assuming transaction id `La_NpAFAWxGj-VIiLfg7NbBfox0RZ8uuEJSOOZykd48`, block
49+
hash `-o88tFYsMG9RXSGcNXX5sVDuSV5uHy7zuFRj6vYo91e3mXpmng6qw322Ip0-EguA`,
50+
block height `1015560` and current Sequencer value `1663069424541`, the generated _sort key_ would
51+
be `000001015560,1663069424541,a21ac8a60326ba8c2bb8caa05cff3334a22e9960ef55de0b5392caa30b484d0a`
52+
53+
**NOTE** All the transactions sent to Arweave directly, have the sequence value assigned to `0000000000000000`.
54+
This effectively means that if transactions to a given contract are sent both directly to Arweave mainnet and Warp
55+
Sequencer -
56+
if two transactions happen to be at the same block height, the "direct" Arweave transactions take precedence.
57+
This also means that the sequencing algorithm is fully backwards compatible with the original SmartWeave protocol.
58+
59+
#### 2. Generates tags for the Bundlr transaction
60+
61+
| Tag Name | Tag Value |
62+
| ------------------------------------------- | -------------------------------------------------------------------- |
63+
| `Sequencer` | `Warp` |
64+
| `Sequencer-Owner` | The original owner/signar of the contract transaction |
65+
| `Sequencer-Mills` | The sequence value used by the Sequencer for this transaction |
66+
| `Sequencer-Sort-Key` | The generated sort key for this transaction |
67+
| `Sequencer-Prev-Sort-Key` | The sort key of the previous transaction |
68+
| `Sequencer-Tx-Id` | The original transaction id |
69+
| `Sequencer-Block-Height` | The block height used for generating the sort key |
70+
| `Sequencer-Block-Id` | The block hash used for generating the sort key |
71+
| `Sequencer-Block-Timestamp` | The timestamp of the block that was used for generating the sort key |
72+
| ...all the tags of the original transaction | |
73+
74+
:::tip
75+
The `Sequencer-Prev-Sort-Key` tells what is the sort key of the 'previous' transaction in the sequencer and
76+
can be used to verify whether all transactions have been properly loaded (i.e. if one
77+
decides to load them directly from L1 nodes) and none is missing.
78+
:::
79+
80+
Additional set of tags are added in case user requests generating a random value using VRF (Verifiable Random Function):
81+
82+
| Tag Name | Tag Value |
83+
| ------------ | ----------------------------------------------------------------------- |
84+
| `vrf-index` | The original hash generated by the VRF (using `sort_key` as input data) |
85+
| `vrf-proof` | The original proof generated by the VRF |
86+
| `vrf-bigint` | A BigInt value evaluated from the hash generated by the VRF |
87+
| `vrf-pubkey` | The public key used by the VRF |
88+
89+
Verifiable randomness can be used by contracts that require using random values - e.g. gaming contracts, nft/loot
90+
generating contracts, etc.
91+
Using the `sort_key`, `vrf-proof` and `vrf-pubkey`, the client can always verify the generated random value.
92+
93+
#### 3. Wrap original data item in a bundle and uploads the bundle to Bundlr
94+
95+
Apart from all the tags from point 2, some additional tags are added to the wrapping bundle:
96+
97+
| Tag Name | Tag Value |
98+
| ---------------- | ----------------- |
99+
| `Bundle-Format` | `binary` |
100+
| `Bundle-Version` | `2.0.0` |
101+
| `App-Name` | `Warp` |
102+
| `Action` | `WarpInteraction` |
103+
104+
In order to send original data item to Bundlr, we use the concept of nested bundles and set an interaction data item inside a bundle. If you're not faimiliar with this concept, here is a quick summary:
105+
106+
:::info
107+
Bundling allows to write multiple data items into one top level transaction. A data item differs from a regular transaction by not allowing to transfer AR tokens and passing reward but it has most of the transaction's properties - such as owner, data, tags, owner and id.
108+
109+
In a nutshell, the nested bundles concept means that a data item of a bundle can also be a bundle containg other data items. According to ANS-104 standard it can lead to theoretically unbounded levels of nesting.
110+
111+
You can read the specification for nested bundles standard in [ANS-104](https://github.com/ArweaveTeam/arweave-standards/blob/master/ans/ANS-104.md#31-nested-bundle).
112+
:::
113+
114+
:::info
115+
Obviously the data-item is signed by the Sequencer's wallet - and as such can be easily verified.
116+
The Sequencer wallet address is `jnioZFibZSCcV8o-HkBXYPYEYNib4tqfexP0kCBXX_M`.
117+
:::
118+
119+
**NOTE** The original data item is not modified in any way - this is to preserve the original
120+
signature!
121+
122+
After receiving proper response and receipt from Bundlr, the Warp gateway indexes the contract interaction
123+
internally - to make it instantly available.
124+
125+
#### 4. Finally, the Warp gateway returns the response from the Bundlr to the client.
126+
127+
## Interaction data item retrieval (generated by the Warp Sequencer) via Arweave gateway
128+
129+
Use the GQL endpoint, with the original data item id passed in the `Contract` tag. Note that all the
130+
interactions will be part of a bundle (i.e. will have the `edges.node.bundledIn.id` value set).
131+
132+
```qql
133+
query {
134+
transactions(
135+
ids: ["1UIhK4vL5lc2X4aMsJFmMpJqfdgrjznVzi2F17yLBlc"]
136+
) {
137+
edges {
138+
node {
139+
id
140+
tags {
141+
name
142+
value
143+
}
144+
block {
145+
height
146+
}
147+
bundledIn {
148+
id
149+
}
150+
}
151+
}
152+
}
153+
}
154+
```
155+
156+
## Interaction retrieval via Warp gateway
157+
158+
The Warp `/gateway/interactions/:id` endpoint allows to retrieve the interaction info based on its original id.

0 commit comments

Comments
 (0)