Skip to content

Commit d6829b7

Browse files
authored
feat(lazer): improve metadata in protobuf (#2856)
* feat(lazer): update metadata proto, rename and clarify docs * feat(lazer): add DynamicValue parsed type * test(lazer): add DynamicValue tests * feat(lazer): add FeedKind to protocol * feat(lazer): add feed kind to protocol * fix(lazer): expose dynamic_value protobuf as rust module, move type to protocol * fix: add FeedKind to AddFeed * doc(lazer): improve proto comments
1 parent 75ccb88 commit d6829b7

File tree

16 files changed

+611
-233
lines changed

16 files changed

+611
-233
lines changed

Cargo.lock

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lazer/publisher_sdk/proto/dynamic_value.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ syntax = "proto3";
33
import "google/protobuf/timestamp.proto";
44
import "google/protobuf/duration.proto";
55

6-
package pyth_lazer_transaction;
6+
package pyth_lazer;
77

88
// A dynamically typed value similar to `google.protobuf.Value`
99
// but supporting more types.

lazer/publisher_sdk/proto/governance_instruction.proto

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import "google/protobuf/duration.proto";
55
import "google/protobuf/empty.proto";
66

77
import "dynamic_value.proto";
8+
import "state.proto";
89

910
// If any field documented as `[required]` is not present in the instruction,
1011
// the instruction will be rejected.
1112

12-
package pyth_lazer_transaction;
13+
package pyth_lazer;
1314

1415
// Representation of a complete governance instruction. This value will be signed
1516
// by a governance source.
@@ -130,9 +131,10 @@ message Permissions {
130131
enum UpdateFeedAction {
131132
// Required by protobuf. Instruction will be rejected if this value is encountered.
132133
UPDATE_FEED_ACTION_UNSPECIFIED = 0;
133-
UPDATE_FEED_METADATA = 101;
134-
ACTIVATE_FEED = 102;
135-
DEACTIVATE_FEED = 103;
134+
UPDATE_FEED_PROPERTIES = 101;
135+
UPDATE_FEED_METADATA = 102;
136+
ENABLE_FEED_IN_SHARD = 103;
137+
DISABLE_FEED_IN_SHARD = 104;
136138
REMOVE_FEED = 199;
137139
}
138140

@@ -302,17 +304,33 @@ message SetPublisherActive {
302304
optional bool is_active = 1;
303305
}
304306

305-
// Feed is inactive when added, meaning that it will be available to publishers but not to consumers.
307+
// Add a new feed. Refer to `Feed` message fields documentation.
306308
message AddFeed {
307-
// [required] ID of the feed. Must be unique (within the shard).
309+
// [required]
308310
optional uint32 feed_id = 1;
309-
// [required] Feed metadata. Some properties are required (name, exponent, etc.).
310-
// Known properties must have the expected type.
311-
// Additional arbitrary properties are allowed.
312-
// (TODO: document known metadata properties)
313-
optional DynamicValue.Map metadata = 2;
314-
// IDs of publishers enabled for this feed.
315-
repeated uint32 permissioned_publishers = 3;
311+
// [required]
312+
optional DynamicValue.Map metadata = 3;
313+
// [required]
314+
optional string name = 101;
315+
// [required]
316+
optional sint32 exponent = 102;
317+
// [required]
318+
optional uint32 min_publishers = 103;
319+
// [required]
320+
optional google.protobuf.Duration min_rate = 104;
321+
// [required]
322+
optional google.protobuf.Duration expiry_time = 105;
323+
// [required]
324+
optional string market_schedule = 106;
325+
// [required]
326+
optional FeedState state = 107;
327+
// [required]
328+
optional FeedKind kind = 108;
329+
// [required]
330+
optional bool is_enabled_in_shard = 201;
331+
332+
// TODO: IDs of publishers enabled for this feed.
333+
// repeated uint32 permissioned_publishers = 3;
316334
}
317335

318336
message UpdateFeed {
@@ -321,43 +339,68 @@ message UpdateFeed {
321339
// [required]
322340
// Note: when adding a new variant here, update `Permissions` as well.
323341
oneof action {
324-
UpdateFeedMetadata update_feed_metadata = 101;
325-
ActivateFeed activate_feed = 102;
326-
DeactivateFeed deactivate_feed = 103;
342+
UpdateFeedProperties update_feed_properties = 101;
343+
UpdateFeedMetadata update_feed_metadata = 102;
344+
EnableFeedInShard enable_feed_in_shard = 103;
345+
DisableFeedInShard disable_feed_in_shard = 104;
327346
google.protobuf.Empty remove_feed = 199;
328347
}
329348
}
330349

350+
// Update a feed's properties. The feed will be updated with values present in each field.
351+
// If a value is not supplied, the corresponding property will remain unchanged.
352+
// Refer to `Feed` message fields documentation.
353+
message UpdateFeedProperties {
354+
// [optional]
355+
optional DynamicValue.Map metadata = 3;
356+
// [optional]
357+
optional string name = 101;
358+
// [optional]
359+
optional sint32 exponent = 102;
360+
// [optional]
361+
optional uint32 min_publishers = 103;
362+
// [optional]
363+
optional google.protobuf.Duration min_rate = 104;
364+
// [optional]
365+
optional google.protobuf.Duration expiry_time = 105;
366+
// [optional]
367+
optional string market_schedule = 106;
368+
// [optional]
369+
optional FeedState state = 107;
370+
// [optional]
371+
optional bool is_enabled_in_shard = 201;
372+
}
373+
331374
message UpdateFeedMetadata {
332375
// [required] Property name.
333376
optional string name = 1;
334377
// [optional] Property value. If unset, the property will be removed.
335378
optional DynamicValue value = 2;
336379
}
337380

338-
// Set the feed as active or shedule an activation.
339-
// If there was already a pending activation or deactivation, it will be cleared
381+
// Set the feed as enabled in this shard or shedule it for a certain timestamp.
382+
// If there was already a pending status change, it will be cleared
340383
// when this governance instruction is processed.
341-
// Warning: there must never be two feeds with the same name active at the same time
384+
// Warning: there must never be two feeds with the same name enabled at the same time
342385
// within a shard group. This cannot be enforced within a shard. When a feed needs to be
343-
// moved between shards, use `activation_timestamp` and `deactivation_timestamp`
344-
// to deactivate it in the old shard and activate it in the new shard at the same time.
345-
message ActivateFeed {
346-
// [optional] If provided, the feed will activate at the specified timestamp.
347-
// If `activation_timestamp` is already passed or if it's unset,
348-
// the feed will be activated immediately when this
386+
// moved between shards, use `enable_in_shard_timestamp` and `disable_in_shard_timestamp`
387+
// to disable it in the old shard and enable it in the new shard at the same time.
388+
message EnableFeedInShard {
389+
// [optional] If provided, the feed will be enabled at the specified timestamp.
390+
// If `enable_in_shard_timestamp` is already passed or if it's unset,
391+
// the feed will be enabled immediately when this
349392
// governance instruction is processed.
350-
optional google.protobuf.Timestamp activation_timestamp = 1;
393+
optional google.protobuf.Timestamp enable_in_shard_timestamp = 1;
351394
}
352395

353-
// Set the feed as inactive or shedule a deactivation.
354-
// If there was already a pending activation or deactivation, it will be cleared
396+
// Set the feed as disabled in this shard or shedule it for a certain timestamp.
397+
// If there was already a pending status change, it will be cleared
355398
// when this governance instruction is processed.
356-
// See also: `ActivateFeed` docs.
357-
message DeactivateFeed {
358-
// [optional] If provided, the feed will deactivate at the specified timestamp.
359-
// If `deactivation_timestamp` is already passed or if it's unset,
360-
// the feed will be deactivated immediately when this
399+
// See also: `EnableFeedInShard` docs.
400+
message DisableFeedInShard {
401+
// [optional] If provided, the feed will be disabled at the specified timestamp.
402+
// If `disable_in_shard_timestamp` is already passed or if it's unset,
403+
// the feed will be disabled immediately when this
361404
// governance instruction is processed.
362-
optional google.protobuf.Timestamp deactivation_timestamp = 1;
405+
optional google.protobuf.Timestamp disable_in_shard_timestamp = 1;
363406
}

lazer/publisher_sdk/proto/publisher_update.proto

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
syntax = "proto3";
2-
package pyth_lazer_transaction;
2+
package pyth_lazer;
33

44
import "google/protobuf/timestamp.proto";
55

@@ -28,7 +28,7 @@ message FeedUpdate {
2828
// [required] timestamp when this data was first acquired or generated
2929
optional google.protobuf.Timestamp source_timestamp = 2;
3030

31-
// [required] one type of update containing specific data
31+
// [required] one type of update containing specific data
3232
oneof update {
3333
PriceUpdate price_update = 3;
3434
FundingRateUpdate funding_rate_update = 4;

lazer/publisher_sdk/proto/pyth_lazer_transaction.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
syntax = "proto3";
2-
package pyth_lazer_transaction;
2+
package pyth_lazer;
33

44
import "publisher_update.proto";
55
import "governance_instruction.proto";

lazer/publisher_sdk/proto/state.proto

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
syntax = "proto3";
2-
package lazer;
2+
package pyth_lazer;
33

44
import "google/protobuf/duration.proto";
55
import "google/protobuf/timestamp.proto";
66

7+
import "dynamic_value.proto";
8+
79
// All optional fields should always be set unless documented otherwise.
810

911
// State of a Pyth Lazer shard.
@@ -45,67 +47,76 @@ message Publisher {
4547
}
4648

4749
enum FeedState {
48-
COMING_SOON = 0; // Default value
50+
// Default value. Feeds in this state are not available to consumers.
51+
// `COMING_SOON` feeds are expected to become stable in the future.
52+
COMING_SOON = 0;
53+
// A fully available feed.
4954
STABLE = 1;
55+
// Inactive feeds are not available to consumers.
56+
// `INACTIVE` feeds are not expected to become stable again.
5057
INACTIVE = 2;
5158
}
5259

53-
// Static data for a feed.
54-
message FeedMetadata {
55-
// [required] ID of the price feed.
56-
optional uint32 price_feed_id = 1;
57-
// [required] Feed name.
58-
optional string name = 2;
59-
// [required] Feed symbol.
60-
optional string symbol = 3;
61-
// [required] Feed description.
62-
optional string description = 4;
63-
// [required] Feed asset type.
64-
optional string asset_type = 5;
60+
// Feed kind determines the set of data fields available in the feed.
61+
// It also determines the kind of data accepted from publishers for this feed
62+
// (`PriceUpdate` or `FundingRateUpdate`).
63+
enum FeedKind {
64+
// Fields: price, best_bid_price, best_ask_price
65+
PRICE = 0;
66+
// Fields: price, rate.
67+
FUNDING_RATE = 1;
68+
}
69+
70+
// An item of the state describing a feed.
71+
message Feed {
72+
// [required] ID of the feed.
73+
optional uint32 feed_id = 1;
74+
// Additional state per publisher.
75+
// If an eligible publisher is not listed here, the corresponding state should be considered empty.
76+
repeated FeedPublisherState per_publisher = 2;
77+
// [required] Additional metadata values. These values will be exposed in the APIs, but
78+
// are not directly used in the aggregator.
79+
optional DynamicValue.Map metadata = 3;
80+
81+
// [required] A readable feed name. It must be unique across all feeds in the shard.
82+
// Used for logs, metrics, feed search API, TradingView API.
83+
optional string name = 101;
6584
// [required] Exponent applied to all price and rate values for this feed.
6685
// Actual value is `mantissa * 10 ^ exponent`.
6786
// Restricted to int16.
68-
optional sint32 exponent = 6;
69-
// [optional] CoinMarketCap ID. Can be absent if there is no CoinMarketCap ID for this symbol.
70-
optional uint32 cmc_id = 7;
71-
// [optional] Funding rate interval. Only present for funding rate feeds.
72-
optional google.protobuf.Duration funding_rate_interval = 8;
87+
optional sint32 exponent = 102;
7388
// [required] Minimal number of publisher prices required to produce an aggregate.
74-
optional uint32 min_publishers = 9;
89+
optional uint32 min_publishers = 103;
7590
// [required] Minimal rate of aggregation performed by the aggregator for this feed.
7691
// Cannot be lower than the shard's top level `State.min_rate`.
77-
optional google.protobuf.Duration min_rate = 10;
92+
optional google.protobuf.Duration min_rate = 104;
7893
// [required] Time after which the publisher update is discarded.
79-
optional google.protobuf.Duration expiry_time = 11;
80-
// [required] If true, the feed is visible to the consumers. This can be used to prepare and verify
81-
// new feeds before releasing them. This can also be used to migrate a feed from
82-
// one shard to another. If a feed is present in
94+
optional google.protobuf.Duration expiry_time = 105;
95+
// [required] Market schedule in Pythnet format.
96+
optional string market_schedule = 106;
97+
// [required] Feed state.
98+
optional FeedState state = 107;
99+
// [required] Feed kind.
100+
optional FeedKind kind = 108;
101+
102+
103+
// [required] Feed status in the current shard. Disabled feeds will not be visible in
104+
// the consumer API for the current shard. This setting should only be used
105+
// to migrate a feed from one shard to another.
106+
//
107+
// If a feed is present in
83108
// multiple shards, it must only be active in one of them at each time.
84-
// To enforce this, `pending_activation` and `pending_deactivation` fields
109+
// To enforce this, `enable_in_shard_timestamp` and `disable_in_shard_timestamp` fields
85110
// can be used to deactivate a feed in one shard and activate it in another shard
86111
// at the same instant.
87-
optional bool is_activated = 12;
88-
// [optional] ID of the corresponding price feed in Hermes (Pythnet).
89-
optional string hermes_id = 13;
90-
// [optional] Quote currency of the asset.
91-
optional string quote_currency = 14;
92-
// [optional] Market schedule in Pythnet format.
93-
// If absent, the default schedule is used (market is always open).
94-
optional string market_schedule = 15;
95-
// [required] Feed state
96-
optional FeedState state = 16;
97-
}
112+
optional bool is_enabled_in_shard = 201;
113+
// [optional] If present, the aggregator will enable the feed in the current shard
114+
// at the specified instant.
115+
optional google.protobuf.Timestamp enable_in_shard_timestamp = 202;
116+
// [optional] If present, the aggregator will disable the feed in the current shard
117+
// at the specified instant.
118+
optional google.protobuf.Timestamp disable_in_shard_timestamp = 203;
98119

99-
// An item of the state describing a feed.
100-
message Feed {
101-
optional FeedMetadata metadata = 1;
102-
// [optional] If present, the aggregator will activate the feed at the specified instant.
103-
optional google.protobuf.Timestamp pending_activation = 2;
104-
// [optional] If present, the aggregator will deactivate the feed at the specified instant.
105-
optional google.protobuf.Timestamp pending_deactivation = 3;
106-
// Additional state per publisher.
107-
// If an eligible publisher is not listed here, the corresponding state should be considered empty.
108-
repeated FeedPublisherState per_publisher = 4;
109120
// TODO: list of permissioned publisher IDs.
110121
}
111122

lazer/publisher_sdk/proto/transaction_envelope.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
syntax = "proto3";
2-
package pyth_lazer_transaction;
2+
package pyth_lazer;
33

44
import "google/protobuf/timestamp.proto";
55
import "pyth_lazer_transaction.proto";

lazer/publisher_sdk/rust/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ repository = "https://github.com/pyth-network/pyth-crosschain"
1010
pyth-lazer-protocol = { version = "0.9.0", path = "../../sdk/rust/protocol" }
1111
anyhow = "1.0.98"
1212
protobuf = "3.7.2"
13-
serde-value = "0.7.0"
1413
humantime = "2.2.0"
1514
tracing = "0.1.41"
15+
serde = { version = "1.0.219", features = ["derive"] }
16+
serde_json = "1.0.140"
17+
derive_more = { version = "2.0.1", features = ["from"] }
18+
hex = "0.4.3"
1619

1720
[build-dependencies]
1821
fs-err = "3.1.0"

0 commit comments

Comments
 (0)