| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- syntax = "proto3";
- import "google/protobuf/timestamp.proto";
- import "google/protobuf/duration.proto";
- import "google/protobuf/empty.proto";
- import "dynamic_value.proto";
- import "state.proto";
- // If any field documented as `[required]` is not present in the instruction,
- // the instruction will be rejected.
- package pyth_lazer;
- // Representation of a complete governance instruction. This value will be signed
- // by a governance source.
- //
- // If the governance source is SingleEd25519, this message will be the payload of LazerTransaction.
- //
- // If the governance source is Wormhole emitter, this message will be the body of the GovernancePayload which
- // is the VAA message Pyth governance sends to Wormhole. The GovernancePayload follows xc-admin spec
- // and looks like so:
- // <magic:u32><module:u8><action:u8><chain:u16><GovernanceInstruction:bytes>
- // You can find the xc-admin spec in: ../../../governance/xc_admin/packages/xc_admin_common/src/governance_payload
- message GovernanceInstruction {
- // Action requested by this instruction. For the instruction to be accepted, all items
- // must be successfully applied. In case of any failure, the whole instruction is reverted.
- // However, note that if the instruction targets multiple (or all) shards, each shard will
- // accept or reject the instruction independently of other shards.
- repeated GovernanceInstructionItem items = 2;
- // [optional] If specified, the instruction will be rejected if the current timestamp
- // is less than the specified value. In case of rejection, the same instruction can be resubmitted
- // and executed later once the time requirement is met.
- optional google.protobuf.Timestamp min_execution_timestamp = 3;
- // [optional] If specified, the instruction will be rejected if the current timestamp
- // is greater than the specified value. After `max_execution_timestamp` is in the past,
- // it will no longer be possible to execute this instruction.
- optional google.protobuf.Timestamp max_execution_timestamp = 4;
- // [optional] Sequence number of this instruction. Required for SingleEd25519 governance source
- // and optional for WomrholeEmitter governance source (because Wormhole has its own sequence
- // numbers). If set, it must be greater than 0, and always be increasing, but not required to be
- // strictly sequential (i.e. gaps are allowed). Each shard separately keeps track of the last
- // executed governance instruction and will reject instructions with the same or smaller
- // sequence no. Note that if instructions are received out of order, some of them may become
- // permanently rejected (e.g. if instruction #3 has been successfully processed before
- // instruction #2 was observed, #2 will always be rejected). Sequence numbers are assigned and
- // tracked separately for each governance source.
- optional uint32 governance_sequence_no = 5;
- }
- // Specifies which shards the governance instruction applies to.
- message ShardFilter {
- // The instruction applies to the specified shards.
- message ShardNames {
- // Must not be empty.
- repeated string shard_names = 1;
- }
- // The instruction applies to the specified shard groups.
- message ShardGroups {
- // Must not be empty.
- repeated string shard_groups = 1;
- }
- // [required]
- oneof filter {
- // The instruction applies to all shards.
- google.protobuf.Empty all_shards = 1;
- ShardNames shard_names = 2;
- ShardGroups shard_groups = 3;
- }
- }
- // An item of a governance instruction.
- message GovernanceInstructionItem {
- // [required] Specifies which shards the governance instruction applies to.
- // The instruction applies to each shard independently of other shards and may apply
- // at a different time. The instruction may succeed on some shards and fail on other shards.
- // Note that each shard has its own list of governance sources and permissions,
- // and a `GovernanceInstruction` is issued by a single source, so multiple instructions
- // from different sources may be needed to apply a change to multiple shards or shard groups.
- optional ShardFilter shard_filter = 1;
- // [required]
- // Note: when adding a new variant here, update `Permissions` as well.
- oneof action {
- CreateShard create_shard = 101;
- AddGovernanceSource add_governance_source = 102;
- UpdateGovernanceSource update_governance_source = 103;
- SetShardName set_shard_name = 105;
- SetShardGroup set_shard_group = 106;
- ResetLastSequenceNo reset_last_sequence_no = 107;
- AddPublisher add_publisher = 108;
- UpdatePublisher update_publisher = 109;
- RemovePublisher remove_publisher = 110;
- AddFeed add_feed = 111;
- UpdateFeed update_feed = 112;
- RemoveFeed remove_feed = 113;
- AddFeatureFlag add_feature_flag = 114;
- RemoveFeatureFlag remove_feature_flag = 115;
- }
- }
- // Create a new shard. A shard is a partially isolated part of Lazer that has its own state and
- // cannot be directly influenced by other shards. The main purpose of shards in Lazer is
- // to allow horizontal scaling when the number of feeds grows. Feeds can be divided into subsets
- // and each subset will be assigned to a shard.
- //
- // Shard name will be determined by the value of `GovernanceInstructionItem.filter`.
- // This action will be rejected unless `GovernanceInstructionItem.filter` specified a single shard.
- // Shard name must be unique across all shards in all groups.
- // (Warning: it's not possible to enforce this rule within a shard!)
- message CreateShard {
- // [required] ID of the new shard.
- // Shard ID must be unique across all shards in all groups.
- // (Warning: it's not possible to enforce this rule within a shard!)
- optional uint32 shard_id = 1;
- // [required] Group name, e.g. "production", "staging", "testing", etc.
- // Data from shards belonging to the same group can be joined and served to consumers as a whole.
- // Active feed names must be unique within a group, but not across all groups.
- optional string shard_group = 2;
- // [required] Minimal aggregation rate allowed in this shard.
- optional google.protobuf.Duration min_rate = 3;
- }
- message AddGovernanceSource {
- // [required] Governance source that should be added.
- optional GovernanceSource new_source = 1;
- // [required] Permissions granted to this source.
- optional Permissions permissions = 2;
- }
- message UpdateGovernanceSource {
- // [required] Governance source that should be updated. Rejects if there is no such source.
- // Rejects if the specified source is the same as the source of the current instruction.
- optional GovernanceSource source = 1;
- // [required]
- // Note: when adding a new variant here, update `Permissions` as well.
- oneof action {
- SetGovernanceSourcePermissions set_governance_source_permissions = 101;
- }
- }
- message SetGovernanceSourcePermissions {
- // [required] Permissions granted to this source. Replaces all previous permissions.
- optional Permissions permissions = 1;
- }
- // Set shard name. This action will be rejected if `GovernanceInstructionItem.shard_names` is empty or contains
- // more than one item.
- message SetShardName {
- // [required] New shard name. Must be unique across all shards in all groups.
- // (Warning: it's not possible to enforce this rule within a shard!)
- optional string shard_name = 1;
- }
- // Set shard group. This action will be rejected if `GovernanceInstructionItem.shard_names` is empty or contains
- // more than one item.
- message SetShardGroup {
- // [required] Group name, e.g. "production", "staging", "testing", etc.
- // Data from shards belonging to the same group can be joined and served to consumers as a whole.
- // Active feed names must be unique within a group, but not across all groups.
- optional string shard_group = 1;
- }
- // Set `last_sequence_no`. This can be used as a workaround in case some updates are lost and
- // the services are unable to proceed.
- message ResetLastSequenceNo {
- optional uint64 last_sequence_no = 1;
- }
- message AddPublisher {
- // [required] Publisher ID. Restricted to uint16. Must be different from existing ids.
- optional uint32 publisher_id = 1;
- // [required] Publisher name (only for debug/monitoring/management purposes).
- // Must be different from existing publisher names.
- optional string name = 2;
- // Public keys used to sign publisher update transactions.
- repeated bytes public_keys = 3;
- // [required] If true, the publisher is active, i.e. it's allowed to publish updates.
- optional bool is_active = 4;
- // IDs of the feeds for which the publisher's price will be included in the aggregate.
- repeated uint32 allowed_feed_ids = 5;
- }
- message UpdatePublisher {
- // [required] ID of the publisher that is being updated. Rejects if there is no such publisher.
- optional uint32 publisher_id = 1;
- // [required]
- // Note: when adding a new variant here, update `Permissions` as well.
- oneof action {
- SetPublisherName set_publisher_name = 101;
- AddPublisherPublicKeys add_publisher_public_keys = 102;
- RemovePublisherPublicKeys remove_publisher_public_keys = 103;
- SetPublisherPublicKeys set_publisher_public_keys = 104;
- SetPublisherActive set_publisher_active = 105;
- AddPublisherAllowedFeedIds add_publisher_allowed_feed_ids = 106;
- RemovePublisherAllowedFeedIds remove_publisher_allowed_feed_ids = 107;
- SetPublisherAllowedFeedIds set_publisher_allowed_feed_ids = 108;
- }
- }
- message RemovePublisher {
- // [required] ID of the publisher that is being deleted. Rejects if there is no such publisher.
- optional uint32 publisher_id = 1;
- }
- message SetPublisherName {
- // [required] New name.
- optional string name = 1;
- }
- // Add new keys.
- message AddPublisherPublicKeys {
- // Must not be empty.
- repeated bytes public_keys = 1;
- }
- // Remove existing keys.
- message RemovePublisherPublicKeys {
- // Must not be empty.
- repeated bytes public_keys = 1;
- }
- // Remove all existing public keys and add new keys (if specified).
- message SetPublisherPublicKeys {
- repeated bytes public_keys = 1;
- }
- // Allow publisher to publish for the specified feeds.
- message AddPublisherAllowedFeedIds {
- // Must not be empty.
- repeated bytes allowed_feed_ids_to_add = 1;
- }
- // Disallow publisher to publish for the specified feeds.
- message RemovePublisherAllowedFeedIds {
- // Must not be empty.
- repeated bytes allowed_feed_ids_to_remove = 1;
- }
- // Allow publisher to publish for only the specified feeds.
- // Remove all previous allowances.
- message SetPublisherAllowedFeedIds {
- repeated bytes allowed_feed_ids = 1;
- }
- message SetPublisherActive {
- // [required]
- optional bool is_active = 1;
- }
- // Add a new feed. Refer to `Feed` message fields documentation.
- message AddFeed {
- // [required]
- optional uint32 feed_id = 1;
- // [required]
- optional DynamicValue.Map metadata = 3;
- // [required]
- optional string name = 101;
- // [required]
- optional sint32 exponent = 102;
- // [required]
- optional uint32 min_publishers = 103;
- // [required]
- optional Channel min_channel = 104;
- // [required]
- optional google.protobuf.Duration expiry_time = 105;
- // [required]
- optional string market_schedule = 106;
- // [required]
- optional FeedState state = 107;
- // [required]
- optional FeedKind kind = 108;
- // [required]
- optional bool is_enabled_in_shard = 201;
- // TODO: IDs of publishers enabled for this feed.
- // repeated uint32 permissioned_publishers = 3;
- }
- message UpdateFeed {
- // [required] ID of the feed that is being updated. Rejects if there is no such feed.
- optional uint32 feed_id = 1;
- // [required]
- // Note: when adding a new variant here, update `Permissions` as well.
- oneof action {
- UpdateFeedProperties update_feed_properties = 101;
- UpdateFeedMetadata update_feed_metadata = 102;
- EnableFeedInShard enable_feed_in_shard = 103;
- DisableFeedInShard disable_feed_in_shard = 104;
- }
- }
- message RemoveFeed {
- // [required] ID of the feed that is being removed. Rejects if there is no such feed.
- optional uint32 feed_id = 1;
- }
- // Update a feed's properties. The feed will be updated with values present in each field.
- // If a value is not supplied, the corresponding property will remain unchanged.
- // Refer to `Feed` message fields documentation.
- message UpdateFeedProperties {
- // [optional]
- optional DynamicValue.Map metadata = 3;
- // [optional]
- optional string name = 101;
- // [optional]
- optional sint32 exponent = 102;
- // [optional]
- optional uint32 min_publishers = 103;
- // [optional]
- optional Channel min_channel = 104;
- // [optional]
- optional google.protobuf.Duration expiry_time = 105;
- // [optional]
- optional string market_schedule = 106;
- // [optional]
- optional FeedState state = 107;
- // [optional]
- optional bool is_enabled_in_shard = 201;
- }
- message UpdateFeedMetadata {
- // [required] Property name.
- optional string name = 1;
- // [optional] Property value. If unset, the property will be removed.
- optional DynamicValue value = 2;
- }
- // Set the feed as enabled in this shard or shedule it for a certain timestamp.
- // If there was already a pending status change, it will be cleared
- // when this governance instruction is processed.
- // Warning: there must never be two feeds with the same name enabled at the same time
- // within a shard group. This cannot be enforced within a shard. When a feed needs to be
- // moved between shards, use `enable_in_shard_timestamp` and `disable_in_shard_timestamp`
- // to disable it in the old shard and enable it in the new shard at the same time.
- message EnableFeedInShard {
- // [required] The feed will be enabled at the specified timestamp.
- // If `enable_in_shard_timestamp` is already passed,
- // the feed will be enabled immediately when this
- // governance instruction is processed.
- optional google.protobuf.Timestamp enable_in_shard_timestamp = 1;
- }
- // Set the feed as disabled in this shard or shedule it for a certain timestamp.
- // If there was already a pending status change, it will be cleared
- // when this governance instruction is processed.
- // See also: `EnableFeedInShard` docs.
- message DisableFeedInShard {
- // [required] The feed will be disabled at the specified timestamp.
- // If `disable_in_shard_timestamp` is already passed,
- // the feed will be disabled immediately when this
- // governance instruction is processed.
- optional google.protobuf.Timestamp disable_in_shard_timestamp = 1;
- }
- // Add a new feature flag.
- message AddFeatureFlag {
- // [required] Feature flag to add.
- optional string feature_flag = 1;
- }
- // Remove a feature flag.
- message RemoveFeatureFlag {
- // [required] Feature flag to remove.
- optional string feature_flag = 1;
- }
|