-
Notifications
You must be signed in to change notification settings - Fork 58
/
kv.proto
286 lines (232 loc) · 7.58 KB
/
kv.proto
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
syntax = "proto3";
import "google/protobuf/empty.proto";
import "types/types.proto";
package remote;
option go_package = "./remote;remoteproto";
//Variables Naming:
// ts - TimeStamp
// tx - Database Transaction
// txn - Ethereum Transaction (and TxNum - is also number of Ethereum Transaction)
// RoTx - Read-Only Database Transaction
// RwTx - Read-Write Database Transaction
// k - key
// v - value
//Methods Naming:
// Get: exact match of criterias
// Range: [from, to)
// Each: [from, INF)
// Prefix: Has(k, prefix)
// Amount: [from, INF) AND maximum N records
//Entity Naming:
// State: simple table in db
// InvertedIndex: supports range-scans
// History: can return value of key K as of given TimeStamp. Doesn't know about latest/current value of key K. Returns NIL if K not changed after TimeStamp.
// Domain: as History but also aware about latest/current value of key K.
// Provides methods to access key-value data
service KV {
// Version returns the service version number
rpc Version(google.protobuf.Empty) returns (types.VersionReply);
// Tx exposes read-only transactions for the key-value store
//
// When tx open, client must receive 1 message from server with txID
// When cursor open, client must receive 1 message from server with cursorID
// Then only client can initiate messages from server
rpc Tx(stream Cursor) returns (stream Pair);
rpc StateChanges(StateChangeRequest) returns (stream StateChangeBatch);
// Snapshots returns list of current snapshot files. Then client can just open all of them.
rpc Snapshots(SnapshotsRequest) returns (SnapshotsReply);
// Range [from, to)
// Range(from, nil) means [from, EndOfTable)
// Range(nil, to) means [StartOfTable, to)
// If orderAscend=false server expecting `from`<`to`. Example: Range("B", "A")
rpc Range(RangeReq) returns (Pairs);
// rpc Stream(RangeReq) returns (stream Pairs);
//Temporal methods
rpc GetLatest(GetLatestReq) returns (GetLatestReply); // can return latest value or as of given timestamp
rpc HistorySeek(HistorySeekReq) returns (HistorySeekReply);
rpc IndexRange(IndexRangeReq) returns (IndexRangeReply);
rpc HistoryRange(HistoryRangeReq) returns (Pairs);
rpc RangeAsOf(RangeAsOfReq) returns (Pairs);
}
enum Op {
FIRST = 0;
FIRST_DUP = 1;
SEEK = 2;
SEEK_BOTH = 3;
CURRENT = 4;
LAST = 6;
LAST_DUP = 7;
NEXT = 8;
NEXT_DUP = 9;
NEXT_NO_DUP = 11;
PREV = 12;
PREV_DUP = 13;
PREV_NO_DUP = 14;
SEEK_EXACT = 15;
SEEK_BOTH_EXACT = 16;
OPEN = 30;
CLOSE = 31;
OPEN_DUP_SORT = 32;
}
message Cursor {
Op op = 1;
string bucket_name = 2;
uint32 cursor = 3;
bytes k = 4;
bytes v = 5;
}
message Pair {
bytes k = 1;
bytes v = 2;
uint32 cursor_id = 3; // send once after new cursor open
uint64 view_id = 4; // return once after tx open. mdbx's tx.ViewID() - id of write transaction in db
uint64 tx_id = 5; // return once after tx open. internal identifier - use it in other methods - to achieve consistent DB view (to read data from same DB tx on server).
}
enum Action {
STORAGE = 0; // Change only in the storage
UPSERT = 1; // Change of balance or nonce (and optionally storage)
CODE = 2; // Change of code (and optionally storage)
UPSERT_CODE = 3; // Change in (balance or nonce) and code (and optionally storage)
REMOVE = 4; // Account is deleted
}
message StorageChange {
types.H256 location = 1;
bytes data = 2;
}
message AccountChange {
types.H160 address = 1;
uint64 incarnation = 2;
Action action = 3;
bytes data = 4; // nil if there is no UPSERT in action
bytes code = 5; // nil if there is no CODE in action
repeated StorageChange storage_changes = 6;
}
enum Direction {
FORWARD = 0;
UNWIND = 1;
}
// StateChangeBatch - list of StateDiff done in one DB transaction
message StateChangeBatch {
uint64 state_version_id = 1; // mdbx's tx.ID() - id of write transaction in db - where this changes happened
repeated StateChange change_batch = 2;
uint64 pending_block_base_fee = 3; // BaseFee of the next block to be produced
uint64 block_gas_limit = 4; // GasLimit of the latest block - proxy for the gas limit of the next block to be produced
uint64 finalized_block = 5;
uint64 pending_blob_fee_per_gas = 6; // Base Blob Fee for the next block to be produced
}
// StateChange - changes done by 1 block or by 1 unwind
message StateChange {
Direction direction = 1;
uint64 block_height = 2;
types.H256 block_hash = 3;
repeated AccountChange changes = 4;
repeated bytes txs = 5; // enable by withTransactions=true
}
message StateChangeRequest {
bool with_storage = 1;
bool with_transactions = 2;
}
message SnapshotsRequest {
}
message SnapshotsReply {
repeated string blocks_files = 1;
repeated string history_files = 2;
}
message RangeReq {
uint64 tx_id = 1; // returned by .Tx()
// It's ok to query wide/unlimited range of data, server will use `pagination params`
// reply by limited batches/pages and client can decide: request next page or not
// query params
string table = 2;
bytes from_prefix = 3;
bytes to_prefix = 4;
bool order_ascend = 5;
sint64 limit = 6; // <= 0 means no limit
// pagination params
int32 page_size = 7; // <= 0 means server will choose
string page_token = 8;
}
//Temporal methods
message GetLatestReq {
uint64 tx_id = 1; // returned by .Tx()
// query params
string table = 2;
bytes k = 3;
uint64 ts = 4;
bytes k2 = 5;
bool latest = 6; // if true, then `ts` ignored and return latest state (without history lookup)
}
message GetLatestReply{
bytes v = 1;
bool ok = 2;
}
message HistorySeekReq {
uint64 tx_id = 1; // returned by .Tx()
string table = 2;
bytes k = 3;
uint64 ts = 4;
}
message HistorySeekReply{
bytes v = 1;
bool ok = 2;
}
message IndexRangeReq {
uint64 tx_id = 1; // returned by .Tx()
// query params
string table = 2;
bytes k = 3;
sint64 from_ts = 4; // -1 means Inf
sint64 to_ts = 5; // -1 means Inf
bool order_ascend = 6;
sint64 limit = 7; // <= 0 means no limit
// pagination params
int32 page_size = 8; // <= 0 means server will choose
string page_token = 9;
}
message IndexRangeReply {
repeated uint64 timestamps = 1; //TODO: it can be a bitmap
string next_page_token = 2;
}
message HistoryRangeReq {
uint64 tx_id = 1; // returned by .Tx()
// query params
string table = 2;
sint64 from_ts = 4; // -1 means Inf
sint64 to_ts = 5; // -1 means Inf
bool order_ascend = 6;
sint64 limit = 7; // <= 0 means no limit
// pagination params
int32 page_size = 8; // <= 0 means server will choose
string page_token = 9;
}
message RangeAsOfReq {
uint64 tx_id = 1; // returned by .Tx()
// query params
string table = 2;
bytes from_key = 3; // nil means Inf
bytes to_key = 4; // nil means Inf
uint64 ts = 5;
bool latest = 6; // if true, then `ts` ignored and return latest state (without history lookup)
bool order_ascend = 7;
sint64 limit = 8; // <= 0 means no limit
// pagination params
int32 page_size = 9; // <= 0 means server will choose
string page_token = 10;
}
message Pairs {
repeated bytes keys = 1; // TODO: replace by lengtsh+arena? Anyway on server we need copy (serialization happening outside tx)
repeated bytes values = 2;
string next_page_token = 3;
// uint32 estimateTotal = 3; // send once after stream creation
// repeated sint64 lengths = 1; //A length of -1 means that the field is NULL
// bytes keys = 2;
// bytes values = 3;
}
message PairsPagination {
bytes next_key = 1;
sint64 limit = 2;
}
message IndexPagination {
sint64 next_time_stamp = 1;
sint64 limit = 2;
}