-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathapi_version.rs
More file actions
146 lines (116 loc) · 5.84 KB
/
api_version.rs
File metadata and controls
146 lines (116 loc) · 5.84 KB
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
use itertools::Itertools;
use semver::Version;
use std::collections::BTreeSet;
use thiserror::Error;
pub const API_VERSION_0_0_2: Version = Version::new(0, 0, 2);
/// This version adds a new subgraph validation step that rejects manifests whose mappings have
/// different API versions if at least one of them is equal to or higher than `0.0.5`.
pub const API_VERSION_0_0_5: Version = Version::new(0, 0, 5);
// Adds two new fields to the Transaction object: nonce and input
pub const API_VERSION_0_0_6: Version = Version::new(0, 0, 6);
/// Enables event handlers to require transaction receipts in the runtime.
pub const API_VERSION_0_0_7: Version = Version::new(0, 0, 7);
/// Enables validation for fields that doesnt exist in the schema for an entity.
pub const API_VERSION_0_0_8: Version = Version::new(0, 0, 8);
/// Enables new host function `eth_get_balance`
pub const API_VERSION_0_0_9: Version = Version::new(0, 0, 9);
/// Before this check was introduced, there were already subgraphs in the wild with spec version
/// 0.0.3, due to confusion with the api version. To avoid breaking those, we accept 0.0.3 though it
/// doesn't exist.
pub const SPEC_VERSION_0_0_3: Version = Version::new(0, 0, 3);
/// This version supports subgraph feature management.
pub const SPEC_VERSION_0_0_4: Version = Version::new(0, 0, 4);
/// This version supports event handlers having access to transaction receipts.
pub const SPEC_VERSION_0_0_5: Version = Version::new(0, 0, 5);
/// Enables the Fast POI calculation variant.
pub const SPEC_VERSION_0_0_6: Version = Version::new(0, 0, 6);
/// Enables offchain data sources.
pub const SPEC_VERSION_0_0_7: Version = Version::new(0, 0, 7);
/// Enables polling block handlers and initialisation handlers.
pub const SPEC_VERSION_0_0_8: Version = Version::new(0, 0, 8);
// Enables `endBlock` feature.
pub const SPEC_VERSION_0_0_9: Version = Version::new(0, 0, 9);
// Enables `indexerHints` feature.
pub const SPEC_VERSION_1_0_0: Version = Version::new(1, 0, 0);
// Enables @aggregation entities
// Enables `id: Int8`
pub const SPEC_VERSION_1_1_0: Version = Version::new(1, 1, 0);
// Enables eth call declarations and indexed arguments(topics) filtering in manifest
pub const SPEC_VERSION_1_2_0: Version = Version::new(1, 2, 0);
// Enables subgraphs as datasource.
// Changes the way the VID field is generated. It used to be autoincrement. Now its
// based on block number and the order of the entities in a block. The latter
// represents the write order across all entity types in the subgraph.
pub const SPEC_VERSION_1_3_0: Version = Version::new(1, 3, 0);
// Enables struct field access in declarative calls
pub const SPEC_VERSION_1_4_0: Version = Version::new(1, 4, 0);
// The latest spec version available
pub const LATEST_VERSION: &Version = &SPEC_VERSION_1_4_0;
pub const MIN_SPEC_VERSION: Version = Version::new(0, 0, 2);
#[derive(Clone, PartialEq, Debug)]
pub struct UnifiedMappingApiVersion(Option<Version>);
impl UnifiedMappingApiVersion {
pub fn equal_or_greater_than(&self, other_version: &Version) -> bool {
assert!(
other_version >= &API_VERSION_0_0_5,
"api versions before 0.0.5 should not be used for comparison"
);
match &self.0 {
Some(version) => version >= other_version,
None => false,
}
}
pub(super) fn try_from_versions(
versions: impl Iterator<Item = Version>,
) -> Result<Self, DifferentMappingApiVersions> {
let unique_versions: BTreeSet<Version> = versions.collect();
let all_below_referential_version = unique_versions.iter().all(|v| *v < API_VERSION_0_0_5);
let all_the_same = unique_versions.len() == 1;
let unified_version: Option<Version> = match (all_below_referential_version, all_the_same) {
(false, false) => return Err(DifferentMappingApiVersions(unique_versions)),
(false, true) => Some(unique_versions.iter().next().unwrap().clone()),
(true, _) => None,
};
Ok(UnifiedMappingApiVersion(unified_version))
}
pub fn version(&self) -> Option<&Version> {
self.0.as_ref()
}
}
pub(super) fn format_versions(versions: &BTreeSet<Version>) -> String {
versions.iter().map(ToString::to_string).join(", ")
}
#[derive(Error, Debug, PartialEq)]
#[error("Expected a single apiVersion for mappings. Found: {}.", format_versions(.0))]
pub struct DifferentMappingApiVersions(pub BTreeSet<Version>);
#[test]
fn unified_mapping_api_version_from_iterator() {
let input = [
vec![Version::new(0, 0, 5), Version::new(0, 0, 5)], // Ok(Some(0.0.5))
vec![Version::new(0, 0, 6), Version::new(0, 0, 6)], // Ok(Some(0.0.6))
vec![Version::new(0, 0, 3), Version::new(0, 0, 4)], // Ok(None)
vec![Version::new(0, 0, 4), Version::new(0, 0, 4)], // Ok(None)
vec![Version::new(0, 0, 3), Version::new(0, 0, 5)], // Err({0.0.3, 0.0.5})
vec![Version::new(0, 0, 6), Version::new(0, 0, 5)], // Err({0.0.5, 0.0.6})
];
let output: [Result<UnifiedMappingApiVersion, DifferentMappingApiVersions>; 6] = [
Ok(UnifiedMappingApiVersion(Some(Version::new(0, 0, 5)))),
Ok(UnifiedMappingApiVersion(Some(Version::new(0, 0, 6)))),
Ok(UnifiedMappingApiVersion(None)),
Ok(UnifiedMappingApiVersion(None)),
Err(DifferentMappingApiVersions(
input[4].iter().cloned().collect::<BTreeSet<Version>>(),
)),
Err(DifferentMappingApiVersions(
input[5].iter().cloned().collect::<BTreeSet<Version>>(),
)),
];
for (version_vec, expected_unified_version) in input.iter().zip(output.iter()) {
let unified = UnifiedMappingApiVersion::try_from_versions(version_vec.iter().cloned());
match (unified, expected_unified_version) {
(Ok(a), Ok(b)) => assert_eq!(a, *b),
(Err(a), Err(b)) => assert_eq!(a, *b),
_ => panic!(),
}
}
}