Repository: tangle-network/gadget (language: rust)

Issue:
[TASK] Add Support for MBSM in `blueprint-test-utils` crate
After the following PRs are merged:
1. https://github.com/tangle-network/tangle/pull/830
2. https://github.com/tangle-network/tnt-core/pull/22

We should add support for Master Blueprint Service Manager contract in the `blueprint-test-utils` by deploying the smart contract to the running tangle node, and check if it is already deployed before deploying a new revision.


Discussion / hints:

Fix patch:
diff --git a/blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std b/blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std
index 1eea5bae1..1de6eecf8 160000
--- a/blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std
+++ b/blueprints/incredible-squaring-eigenlayer/contracts/lib/forge-std
@@ -1,1 +1,1 @@
-Subproject commit 1eea5bae12ae557d589f9f0f0edae2faa47cb262
+Subproject commit 1de6eecf821de7fe2c908cc48d3ab3dced20717f
diff --git a/blueprints/incredible-squaring/contracts/lib/forge-std b/blueprints/incredible-squaring/contracts/lib/forge-std
index 1eea5bae1..1de6eecf8 160000
--- a/blueprints/incredible-squaring/contracts/lib/forge-std
+++ b/blueprints/incredible-squaring/contracts/lib/forge-std
@@ -1,1 +1,1 @@
-Subproject commit 1eea5bae12ae557d589f9f0f0edae2faa47cb262
+Subproject commit 1de6eecf821de7fe2c908cc48d3ab3dced20717f
diff --git a/flake.lock b/flake.lock
index 01d277c4c..63fc2a2c2 100644
--- a/flake.lock
+++ b/flake.lock
@@ -5,11 +5,11 @@
         "systems": "systems"
       },
       "locked": {
-        "lastModified": 1726560853,
-        "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
+        "lastModified": 1731533236,
+        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
         "owner": "numtide",
         "repo": "flake-utils",
-        "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
+        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
         "type": "github"
       },
       "original": {
@@ -28,11 +28,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1728119511,
-        "narHash": "sha256-kJHt+BoDTc9aYXnmy7X+kQto9cT77lDKHAYp5FyY4OY=",
+        "lastModified": 1733130721,
+        "narHash": "sha256-FeL2dez6gE3/u+Dq5Ot4TA0EbonBRo2/7pTYNmBBTNY=",
         "owner": "shazow",
         "repo": "foundry.nix",
-        "rev": "c45f6bc1f2110b1d209e116be203648a06a02f80",
+        "rev": "277722b2fc52af44c0827c47f0f170c7a9b17b0e",
         "type": "github"
       },
       "original": {
@@ -44,11 +44,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1729265718,
-        "narHash": "sha256-4HQI+6LsO3kpWTYuVGIzhJs1cetFcwT7quWCk/6rqeo=",
+        "lastModified": 1733064805,
+        "narHash": "sha256-7NbtSLfZO0q7MXPl5hzA0sbVJt6pWxxtGWbaVUDDmjs=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "ccc0c2126893dd20963580b6478d1a10a4512185",
+        "rev": "31d66ae40417bb13765b0ad75dd200400e98de84",
         "type": "github"
       },
       "original": {
@@ -73,11 +73,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1729477859,
-        "narHash": "sha256-r0VyeJxy4O4CgTB/PNtfQft9fPfN1VuGvnZiCxDArvg=",
+        "lastModified": 1733106880,
+        "narHash": "sha256-aJmAIjZfWfPSWSExwrYBLRgXVvgF5LP1vaeUGOOIQ98=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "ada8266712449c4c0e6ee6fcbc442b3c217c79e1",
+        "rev": "e66c0d43abf5bdefb664c3583ca8994983c332ae",
         "type": "github"
       },
       "original": {


Test patch:
diff --git a/blueprint-test-utils/src/tangle/transactions.rs b/blueprint-test-utils/src/tangle/transactions.rs
index 310e688ae..f43e4284e 100644
--- a/blueprint-test-utils/src/tangle/transactions.rs
+++ b/blueprint-test-utils/src/tangle/transactions.rs
@@ -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};
@@ -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>,
@@ -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(
@@ -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,
diff --git a/blueprint-test-utils/src/test_ext.rs b/blueprint-test-utils/src/test_ext.rs
index 4fd0dc670..f81975dd2 100644
--- a/blueprint-test-utils/src/test_ext.rs
+++ b/blueprint-test-utils/src/test_ext.rs
@@ -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;
@@ -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;
@@ -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()
diff --git a/blueprint-test-utils/tnt-core/MasterBlueprintServiceManager.hex b/blueprint-test-utils/tnt-core/MasterBlueprintServiceManager.hex
new file mode 100644
index 000000000..745cb77c0
--- /dev/null
+++ b/blueprint-test-utils/tnt-core/MasterBlueprintServiceManager.hex
@@ -0,0 +1,1 @@
+0x60806040526004361061019c5760003560e01c8063727391f2116100ec578063a4d91fe91161008a578063b89af90411610064578063b89af9041461047c578063b9315d3a1461048f578063c97008e0146104a2578063d547741f146104c257600080fd5b8063a4d91fe914610438578063a6a7853814610456578063a8f7c5ed1461046957600080fd5b80638e6f8c60116100c65780638e6f8c60146103c257806391d14854146103e2578063987ab9db14610402578063a217fddf1461042357600080fd5b8063727391f21461036d57806382a1ece414610380578063884673ac146103a057600080fd5b80632f2ff15d11610159578063410fdec811610133578063410fdec81461030f5780634984ee6b1461032f5780634efb4b8b146103425780635c975abb1461035557600080fd5b80632f2ff15d146102af57806333db3920146102cf57806336568abe146102ef57600080fd5b806301ffc9a7146101a15780630633da77146101d65780630d0dd399146101f85780631fb27b3414610230578063248a9ca314610250578063274ef0151461028f575b600080fd5b3480156101ad57600080fd5b506101c16101bc3660046116e7565b6104e2565b60405190151581526020015b60405180910390f35b3480156101e257600080fd5b506101f66101f136600461174d565b610519565b005b34801561020457600080fd5b50600054610218906001600160a01b031681565b6040516001600160a01b0390911681526020016101cd565b34801561023c57600080fd5b506101f661024b3660046117ac565b610640565b34801561025c57600080fd5b5061028161026b3660046117f9565b6000908152600160208190526040909120015490565b6040519081526020016101cd565b34801561029b57600080fd5b506102186102aa366004611812565b610745565b3480156102bb57600080fd5b506101f66102ca366004611845565b6107d9565b3480156102db57600080fd5b506101f66102ea3660046118ce565b610805565b3480156102fb57600080fd5b506101f661030a366004611845565b610926565b34801561031b57600080fd5b506101f661032a36600461194b565b61095e565b6101f661033d3660046119a8565b610a62565b6101f6610350366004611a71565b610b72565b34801561036157600080fd5b5060025460ff166101c1565b6101f661037b366004611b4e565b610c9d565b34801561038c57600080fd5b506101f661039b366004611bc4565b610da8565b3480156103ac57600080fd5b5061021860008051602061248583398151915281565b3480156103ce57600080fd5b506102186103dd366004611812565b610ed1565b3480156103ee57600080fd5b506101c16103fd366004611845565b610f20565b34801561040e57600080fd5b50600080516020612485833981519152610218565b34801561042f57600080fd5b50610281600081565b34801561044457600080fd5b506000546001600160a01b0316610218565b6101f66104643660046117ac565b610f4b565b6101f6610477366004611c5c565b611043565b6101f661048a366004611d34565b61116b565b6101f661049d366004611d8f565b611240565b3480156104ae57600080fd5b506101f66104bd3660046118ce565b611357565b3480156104ce57600080fd5b506101f66104dd366004611845565b611467565b60006001600160e01b03198216637965db0b60e01b148061051357506301ffc9a760e01b6001600160e01b03198316145b92915050565b336000805160206124858339815191521461056257336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b60405180910390fd5b61056a61148d565b600061058060036001600160401b0386166114b3565b604051630a24e8a960e41b81526001600160401b03851660048201526001600160a01b0384811660248301529192509082169063a24e8a9090604401600060405180830381600087803b1580156105d657600080fd5b505af11580156105ea573d6000803e3d6000fd5b50506040516001600160a01b03851681526001600160401b038087169350871691507f5267932e6c1b678e74efba1e4d6c8b3fd7504cf0fa8eea462efac2c590a21d56906020015b60405180910390a350505050565b336000805160206124858339815191521461068057336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b61068861148d565b600061069e60036001600160401b0385166114b3565b60405163434698bb60e01b81529091506001600160a01b0382169063434698bb906106cd908590600401611f18565b600060405180830381600087803b1580156106e757600080fd5b505af11580156106fb573d6000803e3d6000fd5b50505050826001600160401b03167fde25c2b146db36cbc91715fdf29cb0eb556eed7678e0bf13563bf7050e8f0bbd836040516107389190611f18565b60405180910390a2505050565b60008061075c60036001600160401b0386166114b3565b6040516374ceeb5560e01b81526001600160401b03851660048201529091506001600160a01b038216906374ceeb55906024015b602060405180830381865afa1580156107ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d19190611f2b565b949350505050565b600082815260016020819052604090912001546107f5816114c6565b6107ff83836114d3565b50505050565b336000805160206124858339815191521461084557336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b61084d61148d565b600061086360036001600160401b0389166114b3565b604051630af7d74360e01b81529091506001600160a01b03821690630af7d7439061089a9089908990899089908990600401611f48565b600060405180830381600087803b1580156108b457600080fd5b505af11580156108c8573d6000803e3d6000fd5b50505050856001600160401b0316876001600160401b03167f7d2ac4c1544e07516def74ce3ada12ff791868ed07d6da82694ae2c0342c8371878787876040516109159493929190611f82565b60405180910390a350505050505050565b6001600160a01b038116331461094f5760405163334bd91960e11b815260040160405180910390fd5b610959828261154c565b505050565b336000805160206124858339815191521461099e57336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b6109a661148d565b60006109bc60036001600160401b0386166114b3565b60405163410e3df160e11b81529091506001600160a01b0382169063821c7be2906109ed9086908690600401611fac565b600060405180830381600087803b158015610a0757600080fd5b505af1158015610a1b573d6000803e3d6000fd5b50505050816001600160401b0316846001600160401b03167f4ca48d7cb411035a931da7a686ea77bc413069de12d844c47daf9242b765cba4856040516106329190611f18565b3360008051602061248583398151915214610aa257336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b610aaa61148d565b6000610ac060036001600160401b0389166114b3565b604051639838caa360e01b81529091506001600160a01b03821690639838caa390610af79089908990899089908990600401611fd7565b600060405180830381600087803b158015610b1157600080fd5b505af1158015610b25573d6000803e3d6000fd5b50506040805160ff891681526001600160401b038881166020830152808b1694508b1692507fa9aaaef624d196d961d053fc29d4331e5cb45d62195d99814d29a94f46fa9d4b9101610915565b3360008051602061248583398151915214610bb257336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b610bba61148d565b6000610bd060036001600160401b038d166114b3565b6040516332e72cfd60e11b81529091506001600160a01b038216906365ce59fa90610c0f908d908d908d908d908d908d908d908d908d90600401612061565b600060405180830381600087803b158015610c2957600080fd5b505af1158015610c3d573d6000803e3d6000fd5b50506040516001600160401b0385811682526001600160a01b038d169350808e1692508e16907f43200f1363ce7ac3780a4c2c5835bf74800937ca5cbc69c4f4d666cf92b0c54c9060200160405180910390a45050505050505050505050565b3360008051602061248583398151915214610cdd57336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b610ce561148d565b6000610cfb60036001600160401b0387166114b3565b604051634e82087760e11b81529091506001600160a01b03821690639d0410ee90610d2e90879087908790600401612136565b600060405180830381600087803b158015610d4857600080fd5b505af1158015610d5c573d6000803e3d6000fd5b50505050846001600160401b03167f7814301100cb38a35027dd63a29aa14c3f73188f15cf9f027655257c45016e8785604051610d999190611f18565b60405180910390a25050505050565b3360008051602061248583398151915214610de857336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b610df061148d565b6000610e0660036001600160401b038a166114b3565b604051636bef5a4160e11b81529091506001600160a01b0382169063d7deb48290610e3f908a908a908a908a908a908a90600401612166565b600060405180830381600087803b158015610e5957600080fd5b505af1158015610e6d573d6000803e3d6000fd5b5050604080516001600160a01b03891681526001600160401b038681166020830152808b1694508b811693508c16917f93927390d124732c66289c6e22370514ddd612a9cc6bff5671cbf2cbc15ddfe3910160405180910390a45050505050505050565b600080610ee860036001600160401b0386166114b3565b60405163052d37d360e21b81526001600160401b03851660048201529091506001600160a01b038216906314b4df4c90602401610790565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b3360008051602061248583398151915214610f8b57336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b610f9361148d565b6000610fa960036001600160401b0385166114b3565b60405163fe0dd37160e01b81529091506001600160a01b0382169063fe0dd37190610fd8908590600401611f18565b600060405180830381600087803b158015610ff257600080fd5b505af1158015611006573d6000803e3d6000fd5b50505050826001600160401b03167febc442018e78570634a88dbac83d4677ae1a5cf8491fb0fc166a7306ba1ff051836040516107389190611f18565b336000805160206124858339815191521461108357336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b61108b61148d565b60006110a160036001600160401b038c166114b3565b604051631be14b3160e11b81529091506001600160a01b038216906337c29662906110de908c908c908c908c908c908c908c908c906004016121b6565b600060405180830381600087803b1580156110f857600080fd5b505af115801561110c573d6000803e3d6000fd5b50505050886001600160401b03168a6001600160401b03167f08e18861659838cad8b04f4687aca1dfb93336e750acf5c3699637ed8ca4c27a8a8a8a60405161115793929190612222565b60405180910390a350505050505050505050565b33600080516020612485833981519152146111ab57336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b6111b361148d565b6111d96001600160401b0384166111d06040840160208501612256565b600391906115b9565b506111ef60066001600160401b038516846115b9565b50826001600160401b0316826001600160a01b03167f278018182b7c51e2da72c1f465c26c12d9606099af0f08db420378344b352223836040516112339190612287565b60405180910390a3505050565b336000805160206124858339815191521461128057336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b61128861148d565b600061129e60036001600160401b0387166114b3565b60405163bb43abd960e01b81529091506001600160a01b0382169063bb43abd9906112d19087908790879060040161242a565b600060405180830381600087803b1580156112eb57600080fd5b505af11580156112ff573d6000803e3d6000fd5b50505050826001600160401b0316856001600160401b03167f219c2fdfbe4f111dda584eefbcb4eb2370cec850e2a79e4fed3a8f708006e7a9868560405161134892919061245f565b60405180910390a35050505050565b336000805160206124858339815191521461139757336000805160206124858339815191526040516359afe8af60e11b8152600401610559929190611dfd565b61139f61148d565b60006113b560036001600160401b0389166114b3565b60405163e926cbd160e01b81529091506001600160a01b0382169063e926cbd1906113ec9089908990899089908990600401611f48565b600060405180830381600087803b15801561140657600080fd5b505af115801561141a573d6000803e3d6000fd5b50505050856001600160401b0316876001600160401b03167f0145a8acdb5e19e431ea924e2c8997b01f0869cad2a2c6927c8645a5938cf0c3878787876040516109159493929190611f82565b60008281526001602081905260409091200154611483816114c6565b6107ff838361154c565b60025460ff16156114b15760405163d93c066560e01b815260040160405180910390fd5b565b60006114bf83836115cf565b9392505050565b6114d08133611616565b50565b60006114df8383610f20565b6115445760008381526001602081815260408084206001600160a01b0387168086529252808420805460ff19169093179092559051339286917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a4506001610513565b506000610513565b60006115588383610f20565b156115445760008381526001602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610513565b60006107d184846001600160a01b038516611653565b6000818152600283016020526040812054801580156115f557506115f38484611670565b155b156114bf5760405163015ab34360e11b815260048101849052602401610559565b6116208282610f20565b61164f5760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401610559565b5050565b600082815260028401602052604081208290556107d1848461167c565b60006114bf8383611688565b60006114bf83836116a0565b600081815260018301602052604081205415156114bf565b600081815260018301602052604081205461154457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610513565b6000602082840312156116f957600080fd5b81356001600160e01b0319811681146114bf57600080fd5b80356001600160401b038116811461172857600080fd5b919050565b6001600160a01b03811681146114d057600080fd5b80356117288161172d565b60008060006060848603121561176257600080fd5b61176b84611711565b925061177960208501611711565b915060408401356117898161172d565b809150509250925092565b600060c082840312156117a657600080fd5b50919050565b600080604083850312156117bf57600080fd5b6117c883611711565b915060208301356001600160401b038111156117e357600080fd5b6117ef85828601611794565b9150509250929050565b60006020828403121561180b57600080fd5b5035919050565b6000806040838503121561182557600080fd5b61182e83611711565b915061183c60208401611711565b90509250929050565b6000806040838503121561185857600080fd5b82359150602083013561186a8161172d565b809150509250929050565b60008083601f84011261188757600080fd5b5081356001600160401b0381111561189e57600080fd5b6020830191508360208285010111156118b657600080fd5b9250929050565b803560ff8116811461172857600080fd5b60008060008060008060a087890312156118e757600080fd5b6118f087611711565b95506118fe60208801611711565b945060408701356001600160401b0381111561191957600080fd5b61192589828a01611875565b90955093506119389050606088016118bd565b9150608087013590509295509295509295565b60008060006060848603121561196057600080fd5b61196984611711565b925060208401356001600160401b0381111561198457600080fd5b61199086828701611794565b92505061199f60408501611711565b90509250925092565b60008060008060008060a087890312156119c157600080fd5b6119ca87611711565b95506119d860208801611711565b94506119e6604088016118bd565b93506119f460608801611711565b925060808701356001600160401b03811115611a0f57600080fd5b611a1b89828a01611875565b979a9699509497509295939492505050565b60008083601f840112611a3f57600080fd5b5081356001600160401b03811115611a5657600080fd5b6020830191508360208260051b85010111156118b657600080fd5b60008060008060008060008060008060e08b8d031215611a9057600080fd5b611a998b611711565b9950611aa760208c01611711565b985060408b0135611ab78161172d565b975060608b01356001600160401b0380821115611ad357600080fd5b611adf8e838f01611a2d565b909950975060808d0135915080821115611af857600080fd5b611b048e838f01611875565b909750955060a08d0135915080821115611b1d57600080fd5b50611b2a8d828e01611a2d565b9094509250611b3d905060c08c01611711565b90509295989b9194979a5092959850565b60008060008060608587031215611b6457600080fd5b611b6d85611711565b935060208501356001600160401b0380821115611b8957600080fd5b611b9588838901611794565b94506040870135915080821115611bab57600080fd5b50611bb887828801611875565b95989497509550505050565b600080600080600080600060c0888a031215611bdf57600080fd5b611be888611711565b9650611bf660208901611711565b9550611c0460408901611711565b94506060880135611c148161172d565b935060808801356001600160401b03811115611c2f57600080fd5b611c3b8a828b01611a2d565b9094509250611c4e905060a08901611711565b905092959891949750929550565b600080600080600080600080600060e08a8c031215611c7a57600080fd5b611c838a611711565b9850611c9160208b01611711565b9750611c9f60408b016118bd565b9650611cad60608b01611711565b955060808a01356001600160401b0380821115611cc957600080fd5b611cd58d838e01611794565b965060a08c0135915080821115611ceb57600080fd5b611cf78d838e01611875565b909650945060c08c0135915080821115611d1057600080fd5b50611d1d8c828d01611875565b915080935050809150509295985092959850929598565b600080600060608486031215611d4957600080fd5b611d5284611711565b92506020840135611d628161172d565b915060408401356001600160401b03811115611d7d57600080fd5b84016060818703121561178957600080fd5b60008060008060808587031215611da557600080fd5b611dae85611711565b935060208501356001600160401b03811115611dc957600080fd5b611dd587828801611794565b935050611de460408601611711565b9150611df2606086016118bd565b905092959194509250565b6001600160a01b0392831681529116602082015260400190565b6000808335601e19843603018112611e2e57600080fd5b83016020810192503590506001600160401b03811115611e4d57600080fd5b8036038213156118b657600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000611e918283611e17565b60c08552611ea360c086018284611e5c565b9150506001600160401b0380611ebb60208601611711565b16602086015280611ece60408601611711565b16604086015280611ee160608601611711565b16606086015280611ef460808601611711565b16608086015280611f0760a08601611711565b1660a0860152508091505092915050565b6020815260006114bf6020830184611e85565b600060208284031215611f3d57600080fd5b81516114bf8161172d565b6001600160401b0386168152608060208201526000611f6b608083018688611e5c565b60ff94909416604083015250606001529392505050565b606081526000611f96606083018688611e5c565b60ff949094166020830152506040015292915050565b604081526000611fbf6040830185611e85565b90506001600160401b03831660208301529392505050565b60006001600160401b03808816835260ff871660208401528086166040840152506080606083015261200d608083018486611e5c565b979650505050505050565b8183526000602080850194508260005b8581101561205657813561203b8161172d565b6001600160a01b031687529582019590820190600101612028565b509495945050505050565b6001600160401b038a1681526001600160a01b038916602082015260c0604082018190528101879052600060e0600589901b830181019083018a835b8b8110156120e55785840360df190183528135368e900360be190181126120c357600080fd5b6120cf858f8301611e85565b945050602092830192919091019060010161209d565b50505082810360608401526120fb81888a611e5c565b90508281036080840152612110818688612018565b91505061212860a08301846001600160401b03169052565b9a9950505050505050505050565b6040815260006121496040830186611e85565b828103602084015261215c818587611e5c565b9695505050505050565b60006001600160401b038089168352808816602084015260018060a01b038716604084015260a060608401526121a060a084018688612018565b9150808416608084015250979650505050505050565b60006001600160401b03808b16835260ff8a16602084015280891660408401525060c060608301526121eb60c0830188611e85565b82810360808401526121fe818789611e5c565b905082810360a0840152612213818587611e5c565b9b9a5050505050505050505050565b60ff841681526001600160401b038316602082015260606040820152600061224d6060830184611e85565b95945050505050565b60006020828403121561226857600080fd5b81356114bf8161172d565b803563ffffffff8116811461172857600080fd5b602081526000823560fe198436030181126122a157600080fd5b6060602084015283016122b48180611e17565b6101008060808701526122cc61018087018385611e5c565b92506122db6020850185611e17565b9250607f19808886030160a08901526122f5858584611e5c565b94506123046040870187611e17565b94509150808886030160c089015261231d858584611e5c565b945061232c6060870187611e17565b94509150808886030160e0890152612345858584611e5c565b94506123546080870187611e17565b9450915080888603018389015261236c858584611e5c565b945061237b60a0870187611e17565b945092508088860301610120890152612395858585611e5c565b94506123a460c0870187611e17565b9450925080888603016101408901526123be858585611e5c565b94506123cd60e0870187611e17565b9650935080888603016101608901525050506123ea828483611e5c565b925050506123fa60208501611742565b6001600160a01b03811660408501525061241660408501612273565b63ffffffff81166060850152509392505050565b60608152600061243d6060830186611e85565b90506001600160401b038416602083015260ff83166040830152949350505050565b6040815260006124726040830185611e85565b905060ff83166020830152939250505056fe0000000000000000000000001111111111111111111111111111111111111111a164736f6c6343000814000a