Skip to content

Commit 877077e

Browse files
authored
feat: allow multiple blueprint source types (#983)
1 parent 21c2419 commit 877077e

File tree

10 files changed

+1426
-1340
lines changed

10 files changed

+1426
-1340
lines changed

Cargo.lock

Lines changed: 716 additions & 881 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pallets/services/src/benchmarking.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fn cggmp21_blueprint<T: Config>() -> ServiceBlueprint<<T as Config>::Constraints
7979
.unwrap(),
8080
registration_params: Default::default(),
8181
request_params: Default::default(),
82-
gadget: Default::default(),
82+
sources: Default::default(),
8383
supported_membership_models: vec![MembershipModelType::Fixed, MembershipModelType::Dynamic]
8484
.try_into()
8585
.unwrap(),

pallets/services/src/tests/hooks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn hooks() {
3939
},],
4040
registration_params: bounded_vec![],
4141
request_params: bounded_vec![],
42-
gadget: Default::default(),
42+
sources: Default::default(),
4343
supported_membership_models: bounded_vec![
4444
MembershipModelType::Fixed,
4545
MembershipModelType::Dynamic,

pallets/services/src/tests/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ pub(crate) fn cggmp21_blueprint() -> ServiceBlueprint<ConstraintsOf<Runtime>> {
108108
],
109109
registration_params: bounded_vec![],
110110
request_params: bounded_vec![],
111-
gadget: Default::default(),
111+
sources: Default::default(),
112112
supported_membership_models: bounded_vec![
113113
MembershipModelType::Fixed,
114114
MembershipModelType::Dynamic,

precompiles/services/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ fn cggmp21_blueprint() -> ServiceBlueprint<ConstraintsOf<Runtime>> {
9292
],
9393
registration_params: bounded_vec![],
9494
request_params: bounded_vec![],
95-
gadget: Default::default(),
95+
sources: Default::default(),
9696
supported_membership_models: bounded_vec![
9797
MembershipModelType::Fixed,
9898
MembershipModelType::Dynamic,

primitives/src/services/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@
1919
pub mod constraints;
2020
pub mod evm;
2121
pub mod field;
22-
pub mod gadget;
2322
pub mod jobs;
2423
pub mod service;
24+
pub mod sources;
2525
pub mod types;
2626

2727
pub use constraints::*;
2828
pub use evm::*;
2929
pub use field::*;
30-
pub use gadget::*;
3130
pub use jobs::*;
3231
pub use service::*;
32+
pub use sources::*;
3333
pub use types::*;

primitives/src/services/service.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// along with Tangle. If not, see <http://www.gnu.org/licenses/>.
1616

1717
use super::{
18-
AssetIdT, AssetSecurityCommitment, AssetSecurityRequirement, BoundedString, Gadget,
18+
AssetIdT, AssetSecurityCommitment, AssetSecurityRequirement, BlueprintSource, BoundedString,
1919
MembershipModelType, TypeCheckError,
2020
constraints::Constraints,
2121
jobs::{JobDefinition, type_checker},
@@ -137,8 +137,8 @@ pub struct ServiceBlueprint<C: Constraints> {
137137
/// If not sure what to use, use `MasterBlueprintServiceManagerRevision::default()` which will
138138
/// use the latest revision available.
139139
pub master_manager_revision: MasterBlueprintServiceManagerRevision,
140-
/// The gadget that will be executed for the service.
141-
pub gadget: Gadget<C>,
140+
/// The binary sources for the blueprint.
141+
pub sources: BoundedVec<BlueprintSource<C>, C::MaxFields>,
142142
/// The membership models supported by this blueprint
143143
pub supported_membership_models: BoundedVec<MembershipModelType, ConstU32<2>>,
144144
}
Lines changed: 92 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -27,36 +27,108 @@ use serde::{Deserialize, Serialize};
2727
#[codec(encode_bound(skip_type_params(C)))]
2828
#[codec(decode_bound(skip_type_params(C)))]
2929
#[codec(mel_bound(skip_type_params(C)))]
30-
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
31-
pub enum Gadget<C: Constraints> {
32-
/// A Gadget that is a WASM binary that will be executed.
33-
/// inside the shell using the wasm runtime.
34-
Wasm(WasmGadget<C>),
35-
/// A Gadget that is a native binary that will be executed.
36-
/// inside the shell using the OS.
37-
Native(NativeGadget<C>),
38-
/// A Gadget that is a container that will be executed.
39-
/// inside the shell using the container runtime (e.g. Docker, Podman, etc.)
40-
Container(ContainerGadget<C>),
30+
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(tag = "type", bound = ""))]
31+
pub enum BlueprintSource<C: Constraints> {
32+
/// A blueprint that is a WASM binary that will be executed with the specified runtime.
33+
Wasm {
34+
runtime: WasmRuntime,
35+
#[cfg_attr(feature = "std", serde(flatten))]
36+
fetcher: WasmFetcher<C>,
37+
},
38+
/// A blueprint that is a native binary that will be executed.
39+
Native(NativeFetcher<C>),
40+
/// A blueprint contained in a container image.
41+
Container(ImageRegistryFetcher<C>),
42+
/// A binary source used for testing the blueprint.
43+
Testing(TestFetcher<C>),
4144
}
4245

43-
impl<C: Constraints> Default for Gadget<C> {
46+
impl<C: Constraints> Default for BlueprintSource<C> {
4447
fn default() -> Self {
45-
Gadget::Wasm(WasmGadget { runtime: WasmRuntime::Wasmtime, sources: Default::default() })
48+
BlueprintSource::Wasm {
49+
runtime: WasmRuntime::Wasmtime,
50+
fetcher: WasmFetcher::Github(Default::default()),
51+
}
4652
}
4753
}
4854

49-
/// A binary that is stored in the Github release.
50-
/// this will constuct the URL to the release and download the binary.
51-
/// The URL will be in the following format:
52-
/// https://github.com/<owner>/<repo>/releases/download/v<tag>/<path>
5355
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
5456
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
5557
#[scale_info(skip_type_params(C))]
5658
#[codec(encode_bound(skip_type_params(C)))]
5759
#[codec(decode_bound(skip_type_params(C)))]
5860
#[codec(mel_bound(skip_type_params(C)))]
5961
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
62+
pub enum WasmRuntime {
63+
/// The WASM binary will be executed using the WASMtime runtime.
64+
#[codec(index = 0)]
65+
Wasmtime,
66+
/// The WASM binary will be executed using the Wasmer runtime.
67+
#[codec(index = 1)]
68+
Wasmer,
69+
}
70+
71+
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
72+
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
73+
#[scale_info(skip_type_params(C))]
74+
#[codec(encode_bound(skip_type_params(C)))]
75+
#[codec(decode_bound(skip_type_params(C)))]
76+
#[codec(mel_bound(skip_type_params(C)))]
77+
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = "", untagged))]
78+
pub enum WasmFetcher<C: Constraints> {
79+
/// A WASM binary that will be fetched from the IPFS.
80+
#[codec(index = 0)]
81+
IPFS(BoundedVec<u8, C::MaxIpfsHashLength>),
82+
/// A WASM binary that will be fetched from a GitHub release.
83+
#[codec(index = 1)]
84+
Github(GithubFetcher<C>),
85+
}
86+
87+
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
88+
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
89+
#[scale_info(skip_type_params(C))]
90+
#[codec(encode_bound(skip_type_params(C)))]
91+
#[codec(decode_bound(skip_type_params(C)))]
92+
#[codec(mel_bound(skip_type_params(C)))]
93+
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = "", untagged))]
94+
pub enum NativeFetcher<C: Constraints> {
95+
/// A blueprint that will be fetched from the IPFS.
96+
#[codec(index = 0)]
97+
IPFS(BoundedVec<u8, C::MaxIpfsHashLength>),
98+
/// A blueprint that will be fetched from a GitHub release.
99+
#[codec(index = 1)]
100+
Github(GithubFetcher<C>),
101+
}
102+
103+
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
104+
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
105+
#[scale_info(skip_type_params(C))]
106+
#[codec(encode_bound(skip_type_params(C)))]
107+
#[codec(decode_bound(skip_type_params(C)))]
108+
#[codec(mel_bound(skip_type_params(C)))]
109+
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
110+
pub struct ImageRegistryFetcher<C: Constraints> {
111+
/// The URL of the container registry.
112+
registry: BoundedString<C::MaxContainerRegistryLength>,
113+
/// The name of the image.
114+
image: BoundedString<C::MaxContainerImageNameLength>,
115+
/// The tag of the image.
116+
tag: BoundedString<C::MaxContainerImageTagLength>,
117+
}
118+
119+
/// A binary that is stored in a GitHub release.
120+
///
121+
/// This will construct the URL to the release and download the binary.
122+
/// The URL will be in the following format:
123+
///
124+
/// `https://github.com/<owner>/<repo>/releases/download/v<tag>/<path>`
125+
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
126+
#[educe(Default(bound()), Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
127+
#[scale_info(skip_type_params(C))]
128+
#[codec(encode_bound(skip_type_params(C)))]
129+
#[codec(decode_bound(skip_type_params(C)))]
130+
#[codec(mel_bound(skip_type_params(C)))]
131+
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
60132
pub struct GithubFetcher<C: Constraints> {
61133
/// The owner of the repository.
62134
pub owner: BoundedString<C::MaxGitOwnerLength>,
@@ -66,11 +138,11 @@ pub struct GithubFetcher<C: Constraints> {
66138
/// NOTE: The tag should be a valid semver tag.
67139
pub tag: BoundedString<C::MaxGitTagLength>,
68140
/// The names of the binary in the release by the arch and the os.
69-
pub binaries: BoundedVec<GadgetBinary<C>, C::MaxBinariesPerGadget>,
141+
pub binaries: BoundedVec<BlueprintBinary<C>, C::MaxBinariesPerGadget>,
70142
}
71143

72144
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
73-
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
145+
#[educe(Default(bound()), Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
74146
#[scale_info(skip_type_params(C))]
75147
#[codec(encode_bound(skip_type_params(C)))]
76148
#[codec(decode_bound(skip_type_params(C)))]
@@ -178,7 +250,7 @@ pub enum OperatingSystem {
178250
#[codec(decode_bound(skip_type_params(C)))]
179251
#[codec(mel_bound(skip_type_params(C)))]
180252
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
181-
pub struct GadgetBinary<C: Constraints> {
253+
pub struct BlueprintBinary<C: Constraints> {
182254
/// CPU or System architecture.
183255
pub arch: Architecture,
184256
/// Operating System that the binary is compiled for.
@@ -189,111 +261,3 @@ pub struct GadgetBinary<C: Constraints> {
189261
/// used to verify the downloaded binary.
190262
pub sha256: [u8; 32],
191263
}
192-
193-
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
194-
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
195-
#[scale_info(skip_type_params(C))]
196-
#[codec(encode_bound(skip_type_params(C)))]
197-
#[codec(decode_bound(skip_type_params(C)))]
198-
#[codec(mel_bound(skip_type_params(C)))]
199-
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
200-
pub struct GadgetSource<C: Constraints> {
201-
/// The fetcher that will fetch the gadget from a remote source.
202-
fetcher: GadgetSourceFetcher<C>,
203-
}
204-
205-
/// A Gadget Source Fetcher is a fetcher that will fetch the gadget
206-
/// from a remote source.
207-
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
208-
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
209-
#[scale_info(skip_type_params(C))]
210-
#[codec(encode_bound(skip_type_params(C)))]
211-
#[codec(decode_bound(skip_type_params(C)))]
212-
#[codec(mel_bound(skip_type_params(C)))]
213-
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
214-
pub enum GadgetSourceFetcher<C: Constraints> {
215-
/// A Gadget that will be fetched from the IPFS.
216-
#[codec(index = 0)]
217-
IPFS(BoundedVec<u8, C::MaxIpfsHashLength>),
218-
/// A Gadget that will be fetched from the Github release.
219-
#[codec(index = 1)]
220-
Github(GithubFetcher<C>),
221-
/// A Gadgets that will be fetched from the container registry.
222-
#[codec(index = 2)]
223-
ContainerImage(ImageRegistryFetcher<C>),
224-
/// For tests only
225-
#[codec(index = 3)]
226-
Testing(TestFetcher<C>),
227-
}
228-
229-
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
230-
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
231-
#[scale_info(skip_type_params(C))]
232-
#[codec(encode_bound(skip_type_params(C)))]
233-
#[codec(decode_bound(skip_type_params(C)))]
234-
#[codec(mel_bound(skip_type_params(C)))]
235-
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
236-
pub struct ImageRegistryFetcher<C: Constraints> {
237-
/// The URL of the container registry.
238-
registry: BoundedString<C::MaxContainerRegistryLength>,
239-
/// The name of the image.
240-
image: BoundedString<C::MaxContainerImageNameLength>,
241-
/// The tag of the image.
242-
tag: BoundedString<C::MaxContainerImageTagLength>,
243-
}
244-
245-
/// A WASM binary that contains all the compiled gadget code.
246-
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
247-
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
248-
#[scale_info(skip_type_params(C))]
249-
#[codec(encode_bound(skip_type_params(C)))]
250-
#[codec(decode_bound(skip_type_params(C)))]
251-
#[codec(mel_bound(skip_type_params(C)))]
252-
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
253-
pub struct WasmGadget<C: Constraints> {
254-
/// Which runtime to use to execute the WASM binary.
255-
pub runtime: WasmRuntime,
256-
/// Where the WASM binary is stored.
257-
pub sources: BoundedVec<GadgetSource<C>, C::MaxSourcesPerGadget>,
258-
}
259-
260-
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
261-
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
262-
#[scale_info(skip_type_params(C))]
263-
#[codec(encode_bound(skip_type_params(C)))]
264-
#[codec(decode_bound(skip_type_params(C)))]
265-
#[codec(mel_bound(skip_type_params(C)))]
266-
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
267-
pub enum WasmRuntime {
268-
/// The WASM binary will be executed using the WASMtime runtime.
269-
#[codec(index = 0)]
270-
Wasmtime,
271-
/// The WASM binary will be executed using the Wasmer runtime.
272-
#[codec(index = 1)]
273-
Wasmer,
274-
}
275-
276-
/// A Native binary that contains all the gadget code.
277-
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
278-
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
279-
#[scale_info(skip_type_params(C))]
280-
#[codec(encode_bound(skip_type_params(C)))]
281-
#[codec(decode_bound(skip_type_params(C)))]
282-
#[codec(mel_bound(skip_type_params(C)))]
283-
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
284-
pub struct NativeGadget<C: Constraints> {
285-
/// Where the WASM binary is stored.
286-
pub sources: BoundedVec<GadgetSource<C>, C::MaxSourcesPerGadget>,
287-
}
288-
289-
#[derive(Educe, Encode, Decode, TypeInfo, MaxEncodedLen)]
290-
#[educe(Debug(bound()), Clone(bound()), PartialEq(bound()), Eq)]
291-
#[scale_info(skip_type_params(C))]
292-
#[codec(encode_bound(skip_type_params(C)))]
293-
#[codec(decode_bound(skip_type_params(C)))]
294-
#[codec(mel_bound(skip_type_params(C)))]
295-
#[cfg_attr(feature = "std", derive(Serialize, Deserialize), serde(bound = ""))]
296-
pub struct ContainerGadget<C: Constraints> {
297-
/// Where the Image of the gadget binary is stored.
298-
pub sources: BoundedVec<GadgetSource<C>, C::MaxSourcesPerGadget>,
299-
}
1.39 KB
Binary file not shown.

0 commit comments

Comments
 (0)