Skip to content

Commit

Permalink
feat!: preregistration for Tangle blueprints
Browse files Browse the repository at this point in the history
  • Loading branch information
Tjemmmic committed Jan 30, 2025
1 parent 765b3e5 commit 8778ef9
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 21 deletions.
1 change: 1 addition & 0 deletions blueprints/incredible-squaring/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
src = "contracts/src"
out = "contracts/out"
libs = ["dependencies"]
remappings = ["incredible-squaring/=contracts/src/"]
auto_detect_remappings = true
solc_version = "0.8.20"

Expand Down
1 change: 0 additions & 1 deletion blueprints/incredible-squaring/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
incredible-squaring/=contracts/src/
tnt-core/=dependencies/tnt-core-0.1.0/src/
51 changes: 50 additions & 1 deletion blueprints/incredible-squaring/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use blueprint_sdk::testing::utils::harness::TestHarness;
use blueprint_sdk::testing::utils::runner::TestEnv;
use blueprint_sdk::testing::utils::tangle::{InputValue, OutputValue, TangleTestHarness};
use color_eyre::Result;
use std::time::Duration;

#[tokio::test]
async fn test_incredible_squaring() -> Result<()> {
Expand All @@ -27,7 +28,7 @@ async fn test_incredible_squaring() -> Result<()> {
.unwrap();

// Setup service
let (mut test_env, service_id) = harness.setup_services().await?;
let (mut test_env, service_id, _blueprint_id) = harness.setup_services(true).await?;
test_env.add_job(handler);

tokio::spawn(async move {
Expand All @@ -47,3 +48,51 @@ async fn test_incredible_squaring() -> Result<()> {
assert_eq!(results.service_id, service_id);
Ok(())
}

#[tokio::test]
async fn test_pre_registration_incredible_squaring() -> Result<()> {
setup_log();

// Initialize test harness (node, keys, deployment)
let temp_dir = tempfile::TempDir::new()?;
let harness = TangleTestHarness::setup(temp_dir).await?;
let env = harness.env().clone();

// Create blueprint-specific context
let blueprint_ctx = MyContext {
env: env.clone(),
call_id: None,
};

// Initialize event handler
let handler = XsquareEventHandler::new(&env.clone(), blueprint_ctx)
.await
.unwrap();

// Setup service, but we don't register yet
let (mut test_env, _, blueprint_id) = harness.setup_services(false).await?;
test_env.add_job(handler);

// Run once for pre-registration
test_env.run_runner().await.unwrap();
let service_id = harness.request_service(blueprint_id).await.unwrap();

tokio::spawn(async move {
// Run again to actually run the service, now that we have registered
test_env.run_runner().await.unwrap();
});

tokio::time::sleep(Duration::from_secs(2)).await;

// Execute job and verify result
let _results = harness
.execute_job(
service_id,
0,
vec![InputValue::Uint64(5)],
vec![OutputValue::Uint64(25)],
)
.await?;

Ok(())
}
2 changes: 2 additions & 0 deletions crates/runners/core/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ impl BlueprintRunner {
pub async fn run(&mut self) -> Result<(), Error> {
if self.config.requires_registration(&self.env).await? {
self.config.register(&self.env).await?;
// Return from pre-registration
return Ok(());
}

let mut background_receivers = Vec::new();
Expand Down
49 changes: 44 additions & 5 deletions crates/testing-utils/tangle/src/harness.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::node::transactions::join_operators;
use crate::Error;
use crate::{
keys::inject_tangle_key,
Expand Down Expand Up @@ -208,25 +209,63 @@ impl TangleTestHarness {
}

/// Sets up a complete service environment with initialized event handlers
pub async fn setup_services(&self) -> Result<(TangleTestEnv, u64), Error> {
///
/// # Returns
/// A tuple of the test environment, the service ID, and the blueprint ID i.e., (test_env, service_id, blueprint_id)
///
/// # Note
/// The Service ID will always be 0 if automatic registration is disabled, as there is not yet a service to have an ID
pub async fn setup_services(
&self,
automatic_registration: bool,
) -> Result<(TangleTestEnv, u64, u64), Error> {
// Deploy blueprint
let blueprint_id = self.deploy_blueprint().await?;

// Join operators
join_operators(&self.client, &self.sr25519_signer)
.await
.map_err(|e| Error::Setup(e.to_string()))?;

// Setup operator and get service
let preferences = self.get_default_operator_preferences();
let service_id = if automatic_registration {
setup_operator_and_service(
&self.client,
&self.sr25519_signer,
blueprint_id,
preferences,
automatic_registration,
)
.await
.map_err(|e| Error::Setup(e.to_string()))?
} else {
0
};

// Create and spawn test environment
let test_env = TangleTestEnv::new(TangleConfig::default(), self.env().clone())?;

Ok((test_env, service_id, blueprint_id))
}

/// Requests a service with the given blueprint and returns the newly created service ID
///
/// This function does not register for a service, it only requests service for a blueprint
/// that has already been registered to.
pub async fn request_service(&self, blueprint_id: u64) -> Result<u64, Error> {
let preferences = self.get_default_operator_preferences();
let service_id = setup_operator_and_service(
&self.client,
&self.sr25519_signer,
blueprint_id,
preferences,
false,
)
.await
.map_err(|e| Error::Setup(e.to_string()))?;

// Create and spawn test environment
let test_env = TangleTestEnv::new(TangleConfig::default(), self.env().clone())?;

Ok((test_env, service_id))
Ok(service_id)
}

/// Executes a job and verifies its output matches the expected result
Expand Down
27 changes: 13 additions & 14 deletions crates/testing-utils/tangle/src/node/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,20 +388,20 @@ pub async fn setup_operator_and_service<T: Signer<TangleConfig>>(
sr25519_signer: &T,
blueprint_id: u64,
preferences: Preferences,
automatic_registration: bool,
) -> Result<u64, TransactionError> {
// Join operators
join_operators(client, sr25519_signer).await?;

// Register for blueprint
register_blueprint(
client,
sr25519_signer,
blueprint_id,
preferences,
RegistrationArgs::new(),
0,
)
.await?;
if automatic_registration {
// Register for blueprint
register_blueprint(
client,
sr25519_signer,
blueprint_id,
preferences,
RegistrationArgs::new(),
0,
)
.await?;
}

// Get the current service ID before requesting new service
let prev_service_id = get_next_service_id(client).await?;
Expand Down Expand Up @@ -442,7 +442,6 @@ pub async fn setup_operator_and_service<T: Signer<TangleConfig>>(
if service.blueprint != blueprint_id {
return Err(TransactionError::ServiceIdMismatch);
}

Ok(new_service_id.saturating_sub(1))
}

Expand Down

0 comments on commit 8778ef9

Please sign in to comment.