syntax = "proto3"; package neo.fs.v2.netmap; option go_package = "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc;netmap"; option csharp_namespace = "Neo.FileStorage.API.Netmap"; // Operations on filters enum Operation { // No Operation defined OPERATION_UNSPECIFIED = 0; // Equal EQ = 1; // Not Equal NE = 2; // Greater then GT = 3; // Greater or equal GE = 4; // Less then LT = 5; // Less or equal LE = 6; // Logical OR OR = 7; // Logical AND AND = 8; // Logical negation NOT = 9; // Matches pattern LIKE = 10; } // Selector modifier shows how the node set will be formed. By default selector // just groups nodes into a bucket by attribute, selecting nodes only by their // hash distance. enum Clause { // No modifier defined. Nodes will be selected from the bucket randomly CLAUSE_UNSPECIFIED = 0; // SAME will select only nodes having the same value of bucket attribute SAME = 1; // DISTINCT will select nodes having different values of bucket attribute DISTINCT = 2; } // This filter will return the subset of nodes from `NetworkMap` or another // filter's results that will satisfy filter's conditions. message Filter { // Name of the filter or a reference to a named filter. '*' means // application to the whole unfiltered NetworkMap. At top level it's used as a // filter name. At lower levels it's considered to be a reference to another // named filter string name = 1 [ json_name = "name" ]; // Key to filter string key = 2 [ json_name = "key" ]; // Filtering operation Operation op = 3 [ json_name = "op" ]; // Value to match string value = 4 [ json_name = "value" ]; // List of inner filters. Top level operation will be applied to the whole // list. repeated Filter filters = 5 [ json_name = "filters" ]; } // Selector chooses a number of nodes from the bucket taking the nearest nodes // to the provided `ContainerID` by hash distance. message Selector { // Selector name to reference in object placement section string name = 1 [ json_name = "name" ]; // How many nodes to select from the bucket uint32 count = 2 [ json_name = "count" ]; // Selector modifier showing how to form a bucket Clause clause = 3 [ json_name = "clause" ]; // Bucket attribute to select from string attribute = 4 [ json_name = "attribute" ]; // Filter reference to select from string filter = 5 [ json_name = "filter" ]; } // Number of object replicas in a set of nodes from the defined selector. If no // selector set, the root bucket containing all possible nodes will be used by // default. message Replica { // How many object replicas to put uint32 count = 1 [ json_name = "count" ]; // Named selector bucket to put replicas string selector = 2 [ json_name = "selector" ]; // Data shards count uint32 ec_data_count = 3 [ json_name = "ecDataCount" ]; // Parity shards count uint32 ec_parity_count = 4 [ json_name = "ecParityCount" ]; } // Set of rules to select a subset of nodes from `NetworkMap` able to store // container's objects. The format is simple enough to transpile from different // storage policy definition languages. message PlacementPolicy { // Rules to set number of object replicas and place each one into a named // bucket repeated Replica replicas = 1 [ json_name = "replicas" ]; // Container backup factor controls how deep FrostFS will search for nodes // alternatives to include into container's nodes subset uint32 container_backup_factor = 2 [ json_name = "containerBackupFactor" ]; // Set of Selectors to form the container's nodes subset repeated Selector selectors = 3 [ json_name = "selectors" ]; // List of named filters to reference in selectors repeated Filter filters = 4 [ json_name = "filters" ]; // Unique flag defines non-overlapping application for replicas bool unique = 5 [ json_name = "unique" ]; } // FrostFS node description message NodeInfo { // Public key of the FrostFS node in a binary format bytes public_key = 1 [ json_name = "publicKey" ]; // Ways to connect to a node repeated string addresses = 2 [ json_name = "addresses" ]; // Administrator-defined Attributes of the FrostFS Storage Node. // // `Attribute` is a Key-Value metadata pair. Key name must be a valid UTF-8 // string. Value can't be empty. // // Attributes can be constructed into a chain of attributes: any attribute can // have a parent attribute and a child attribute (except the first and the // last one). A string representation of the chain of attributes in FrostFS // Storage Node configuration uses ":" and "/" symbols, e.g.: // // `FrostFS_NODE_ATTRIBUTE_1=key1:val1/key2:val2` // // Therefore the string attribute representation in the Node configuration // must use "\:", "\/" and "\\" escaped symbols if any of them appears in an // attribute's key or value. // // Node's attributes are mostly used during Storage Policy evaluation to // calculate object's placement and find a set of nodes satisfying policy // requirements. There are some "well-known" node attributes common to all the // Storage Nodes in the network and used implicitly with default values if not // explicitly set: // // * Capacity \ // Total available disk space in Gigabytes. // * Price \ // Price in GAS tokens for storing one GB of data during one Epoch. In node // attributes it's a string presenting floating point number with comma or // point delimiter for decimal part. In the Network Map it will be saved as // 64-bit unsigned integer representing number of minimal token fractions. // * UN-LOCODE \ // Node's geographic location in // [UN/LOCODE](https://www.unece.org/cefact/codesfortrade/codes_index.html) // format approximated to the nearest point defined in the standard. // * CountryCode \ // Country code in // [ISO 3166-1_alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) // format. Calculated automatically from `UN-LOCODE` attribute. // * Country \ // Country short name in English, as defined in // [ISO-3166](https://www.iso.org/obp/ui/#search). Calculated automatically // from `UN-LOCODE` attribute. // * Location \ // Place names are given, whenever possible, in their national language // versions as expressed in the Roman alphabet using the 26 characters of // the character set adopted for international trade data interchange, // written without diacritics . Calculated automatically from `UN-LOCODE` // attribute. // * SubDivCode \ // Country's administrative subdivision where node is located. Calculated // automatically from `UN-LOCODE` attribute based on `SubDiv` field. // Presented in [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) // format. // * SubDiv \ // Country's administrative subdivision name, as defined in // [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2). Calculated // automatically from `UN-LOCODE` attribute. // * Continent \ // Node's continent name according to the [Seven-Continent // model](https://en.wikipedia.org/wiki/Continent#Number). Calculated // automatically from `UN-LOCODE` attribute. // * ExternalAddr // Node's preferred way for communications with external clients. // Clients SHOULD use these addresses if possible. // Must contain a comma-separated list of multi-addresses. // // For detailed description of each well-known attribute please see the // corresponding section in FrostFS Technical Specification. message Attribute { // Key of the node attribute string key = 1 [ json_name = "key" ]; // Value of the node attribute string value = 2 [ json_name = "value" ]; // Parent keys, if any. For example for `City` it could be `Region` and // `Country`. repeated string parents = 3 [ json_name = "parents" ]; } // Carries list of the FrostFS node attributes in a key-value form. Key name // must be a node-unique valid UTF-8 string. Value can't be empty. NodeInfo // structures with duplicated attribute names or attributes with empty values // will be considered invalid. repeated Attribute attributes = 3 [ json_name = "attributes" ]; // Represents the enumeration of various states of the FrostFS node. enum State { // Unknown state UNSPECIFIED = 0; // Active state in the network ONLINE = 1; // Network unavailable state OFFLINE = 2; // Maintenance state MAINTENANCE = 3; } // Carries state of the FrostFS node State state = 4 [ json_name = "state" ]; } // Network map structure message Netmap { // Network map revision number. uint64 epoch = 1 [ json_name = "epoch" ]; // Nodes presented in network. repeated NodeInfo nodes = 2 [ json_name = "nodes" ]; } // FrostFS network configuration message NetworkConfig { // Single configuration parameter. Key MUST be network-unique. // // System parameters: // - **AuditFee** \ // Fee paid by the storage group owner to the Inner Ring member. // Value: little-endian integer. Default: 0. // - **BasicIncomeRate** \ // Cost of storing one gigabyte of data for a period of one epoch. Paid by // container owner to container nodes. // Value: little-endian integer. Default: 0. // - **ContainerAliasFee** \ // Fee paid for named container's creation by the container owner. // Value: little-endian integer. Default: 0. // - **ContainerFee** \ // Fee paid for container creation by the container owner. // Value: little-endian integer. Default: 0. // - **EpochDuration** \ // FrostFS epoch duration measured in Sidechain blocks. // Value: little-endian integer. Default: 0. // - **HomomorphicHashingDisabled** \ // Flag of disabling the homomorphic hashing of objects' payload. // Value: true if any byte != 0. Default: false. // - **InnerRingCandidateFee** \ // Fee for entrance to the Inner Ring paid by the candidate. // Value: little-endian integer. Default: 0. // - **MaintenanceModeAllowed** \ // Flag allowing setting the MAINTENANCE state to storage nodes. // Value: true if any byte != 0. Default: false. // - **MaxObjectSize** \ // Maximum size of physically stored FrostFS object measured in bytes. // Value: little-endian integer. Default: 0. // // This value refers to the maximum size of a **physically** stored object // in FrostFS. However, from a user's perspective, the **logical** size of a // stored object can be significantly larger. The relationship between the // physical and logical object sizes is governed by the following formula // // ```math // \mathrm{Stored\ Object\ Size} \le // \frac{ // \left(\mathrm{Max\ Object\ Size}\right)^2 // }{ // \mathrm{Object\ ID\ Size} // } // ``` // // This arises from the fact that a tombstone, also being an object, stores // the IDs of inhumed objects and cannot be divided into smaller objects, // thus having an upper limit for its size. // // For example, if: // * Max Object Size Size = 64 MiB; // * Object ID Size = 32 B; // // then: // ```math // \mathrm{Stored\ Object\ Size} \le // \frac{\left(64\ \mathrm{MiB}\right)^2}{32\ \mathrm{B}} = // \frac{2^{52}}{2^5}\ \mathrm{B} = // 2^{47}\ \mathrm{B} = // 128\ \mathrm{TiB} // ``` // - **WithdrawFee** \ // Fee paid for withdrawal of funds paid by the account owner. // Value: little-endian integer. Default: 0. // - **MaxECDataCount** \ // Maximum number of data shards for EC placement policy. // Value: little-endian integer. Default: 0. // - **MaxECParityCount** \ // Maximum number of parity shards for EC placement policy. // Value: little-endian integer. Default: 0. message Parameter { // Parameter key. UTF-8 encoded string bytes key = 1 [ json_name = "key" ]; // Parameter value bytes value = 2 [ json_name = "value" ]; } // List of parameter values repeated Parameter parameters = 1 [ json_name = "parameters" ]; } // Information about FrostFS network message NetworkInfo { // Number of the current epoch in the FrostFS network uint64 current_epoch = 1 [ json_name = "currentEpoch" ]; // Magic number of the sidechain of the FrostFS network uint64 magic_number = 2 [ json_name = "magicNumber" ]; // MillisecondsPerBlock network parameter of the sidechain of the FrostFS // network int64 ms_per_block = 3 [ json_name = "msPerBlock" ]; // FrostFS network configuration NetworkConfig network_config = 4 [ json_name = "networkConfig" ]; }