Skip to content

Commit

Permalink
feat: add automatic deployment for MBSM in blueprint test utils
Browse files Browse the repository at this point in the history
  • Loading branch information
shekohex committed Dec 2, 2024
1 parent ac05dc7 commit 08b31e7
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 18 deletions.
74 changes: 70 additions & 4 deletions blueprint-test-utils/src/tangle/transactions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use alloy_provider::network::{ReceiptResponse, TransactionBuilder};
use alloy_provider::{Provider, WsConnect};
use cargo_tangle::deploy::PrivateKeySigner;
use gadget_sdk::keystore::TanglePairSigner;
use sp_core::H160;
use subxt::blocks::ExtrinsicEvents;
use subxt::client::OnlineClientT;
use std::error::Error;
use gadget_sdk::event_listener::tangle::AccountId32;
use gadget_sdk::{error, info};
Expand All @@ -7,12 +13,54 @@ use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::runtime_types::sp_ari
use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::services::calls::types::call::{Args, Job};
use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::services::calls::types::create_blueprint::Blueprint;
use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::services::calls::types::register::{Preferences, RegistrationArgs};
use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::services::events::{JobCalled, JobResultSubmitted};
use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::services::events::{JobCalled, JobResultSubmitted, MasterBlueprintServiceManagerRevised};
use subxt::tx::TxProgress;
use gadget_sdk::clients::tangle::runtime::TangleConfig;
use gadget_sdk::subxt_core::tx::signer::Signer;
use crate::TestClient;

/// Deploy a new MBSM revision and returns the result.
pub async fn deploy_new_mbsm_revision(
evm_rpc_endpoint: &str,
client: &TestClient,
account_id: &TanglePairSigner<sp_core::sr25519::Pair>,
signer_evm: PrivateKeySigner,
bytecode: &[u8],
) -> Result<MasterBlueprintServiceManagerRevised, Box<dyn Error>> {
info!("Deploying new MBSM revision ...");

let wallet = alloy_provider::network::EthereumWallet::from(signer_evm);
let provider = alloy_provider::ProviderBuilder::new()
.with_recommended_fillers()
.wallet(wallet)
.on_ws(WsConnect::new(evm_rpc_endpoint))
.await?;

let tx = alloy_rpc_types::TransactionRequest::default().with_deploy_code(bytecode.to_vec());
// Deploy the contract.
let receipt = provider.send_transaction(tx).await?.get_receipt().await?;
// Check the receipt status.
let mbsm_address = if receipt.status() {
ReceiptResponse::contract_address(&receipt).unwrap()
} else {
error!("MBSM Contract deployment failed!");
error!("Receipt: {receipt:#?}");
return Err("MBSM Contract deployment failed!".into());
};
let call = api::tx()
.services()
.update_master_blueprint_service_manager(mbsm_address.0 .0.into());
let res = client
.tx()
.sign_and_submit_then_watch_default(&call, account_id)
.await?;
let evts = wait_for_in_block_success(res).await?;
let ev = evts
.find_first::<MasterBlueprintServiceManagerRevised>()?
.expect("MBSM Revised Event to be emitted");
Ok(ev)
}

pub async fn create_blueprint(
client: &TestClient,
account_id: &TanglePairSigner<sp_core::sr25519::Pair>,
Expand Down Expand Up @@ -121,14 +169,16 @@ pub async fn request_service(

pub async fn wait_for_in_block_success(
mut res: TxProgress<TangleConfig, TestClient>,
) -> Result<(), Box<dyn Error>> {
) -> Result<ExtrinsicEvents<TangleConfig>, Box<dyn Error>> {
let mut val = Err("Failed to get in block success".into());
while let Some(Ok(event)) = res.next().await {
let Some(block) = event.as_in_block() else {
continue;
};
block.wait_for_success().await?;
val = block.wait_for_success().await;
}
Ok(())

val.map_err(Into::into)
}

pub async fn wait_for_completion_of_tangle_job(
Expand Down Expand Up @@ -202,6 +252,22 @@ pub async fn get_next_call_id(client: &TestClient) -> Result<u64, Box<dyn Error>
Ok(res)
}

pub async fn get_latest_mbsm_revision(
client: &TestClient,
) -> Result<Option<(u64, H160)>, Box<dyn Error>> {
let call = api::storage()
.services()
.master_blueprint_service_manager_revisions();
let mut res = client
.storage()
.at_latest()
.await?
.fetch_or_default(&call)
.await?;
let ver = res.0.len() as u64;
Ok(res.0.pop().map(|addr| (ver, addr)))
}

/// Approves a service request. This is meant for testing, and will always approve the request.
pub async fn approve_service(
client: &TestClient,
Expand Down
25 changes: 25 additions & 0 deletions blueprint-test-utils/src/test_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with Tangle. If not, see <http://www.gnu.org/licenses/>.

use crate::PerTestNodeInput;
use alloy_primitives::hex;
use futures::StreamExt;
use blueprint_manager::executor::BlueprintManagerHandle;
use blueprint_manager::sdk::entry::SendFuture;
Expand All @@ -23,6 +24,7 @@ use gadget_sdk::clients::tangle::runtime::TangleClient;
use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::runtime_types::tangle_primitives::services::PriceTargets;
use gadget_sdk::tangle_subxt::tangle_testnet_runtime::api::services::calls::types::register::{Preferences, RegistrationArgs};
use libp2p::Multiaddr;
use log::debug;
use std::collections::HashSet;
use std::future::Future;
use std::net::IpAddr;
Expand Down Expand Up @@ -206,6 +208,29 @@ pub async fn new_test_ext_blueprint_manager<
.collect::<Vec<BlueprintManagerHandle>>()
.await;

// Check if the MBSM is already deployed.
let latest_revision = transactions::get_latest_mbsm_revision(&client)
.await
.expect("Get latest MBSM revision");
match latest_revision {
Some((rev, addr)) => debug!("MBSM is deployed at revision #{rev} at address {addr}"),
None => {
let bytecode_hex = include_str!("../tnt-core/MasterBlueprintServiceManager.hex");
let bytecode = hex::decode(bytecode_hex).expect("valid bytecode in hex format");
let ev = transactions::deploy_new_mbsm_revision(
&local_tangle_node_http,
&client,
handles[0].sr25519_id(),
opts.signer_evm.clone().expect("Signer EVM is set"),
&bytecode,
)
.await
.expect("deploy new MBSM revision");
let rev = ev.revision;
let addr = ev.address;
debug!("Deployed MBSM at revision #{rev} at address {addr}");
}
};
// Step 3: request a service
let all_nodes = handles
.iter()
Expand Down
Loading

0 comments on commit 08b31e7

Please sign in to comment.