Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscribe "Publish" and "Deploy" events when deploying smartdeploy #46

Merged
merged 2 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .env

This file was deleted.

6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SOROBAN_NETWORK=testnet
SOROBAN_ACCOUNT=default
CONFIG_DIR=.
SOROBAN_FEE=10000000
MERCURY_BACKEND_ENDPOINT=https://api.mercurydata.app:8443
MERCURY_JWT_TOKEN=request-access-to-mercury-team
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/target/
.soroban

.env
40 changes: 40 additions & 0 deletions contracts/smartdeploy/src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use crate::{
metadata::ContractMetadata,
version::{Update, Version},
};
use loam_sdk::soroban_sdk::{self, contracttype, Address, Env, IntoVal, String, Val};
use loam_sdk::IntoKey;

#[contracttype]
#[derive(IntoKey)]
pub struct Publish {
pub published_name: String,
pub author: Address,
pub hash: soroban_sdk::BytesN<32>,
pub repo: ContractMetadata,
pub kind: Update,
}

#[contracttype]
#[derive(IntoKey)]
pub struct Deploy {
pub published_name: String,
pub deployed_name: String,
pub version: Version,
pub deployer: Address,
pub contract_id: Address,
}

pub trait EventPublishable {
/// Publish an event on the blockchain
fn publish_event(self, env: &Env);
}

impl<T> EventPublishable for T
where
T: soroban_sdk::IntoKey + IntoVal<Env, Val>,
{
fn publish_event(self, env: &Env) {
env.events().publish((T::into_key(),), self);
}
}
1 change: 1 addition & 0 deletions contracts/smartdeploy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use registry::{
};

pub mod error;
pub mod events;
pub mod metadata;
pub mod registry;
pub mod util;
Expand Down
21 changes: 7 additions & 14 deletions contracts/smartdeploy/src/registry/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use loam_sdk::soroban_sdk::{

use crate::{
error::Error,
events::{Deploy, EventPublishable},
registry::Publishable,
util::{hash_string, MAX_BUMP},
version::Version,
Expand All @@ -23,16 +24,6 @@ loam_sdk::import_contract!(core_riff);
// loam_sdk::soroban_sdk::contractimport!(file = "../../target/loam/core_riff.wasm",);
// }

#[contracttype]
pub struct DeployEventData {
published_name: String,
deployed_name: String,
version: Version,
deployer: Address,
contract_id: Address,
}
#[contracttype(export = false)]
pub struct ContractRegistry(pub Map<String, ContractType>);

#[contracttype(export = false)]
#[derive(Clone)]
Expand Down Expand Up @@ -103,19 +94,21 @@ impl IsDeployable for ContractRegistry {
// Publish a deploy event
let version = version.map_or_else(
|| {
let published_contract = WasmRegistry::get_lazy().unwrap().find_contract(contract_name.clone())?;
let published_contract = WasmRegistry::get_lazy()
.unwrap()
.find_contract(contract_name.clone())?;
published_contract.most_recent_version()
},
Ok,
)?;
let deploy_datas = DeployEventData {
Deploy {
published_name: contract_name,
deployed_name,
version,
deployer: owner,
contract_id: address.clone(),
};
env().events().publish((symbol_short!("deploy"),), deploy_datas);
}
.publish_event(env());

Ok(address)
}
Expand Down
20 changes: 16 additions & 4 deletions contracts/smartdeploy/src/registry/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use loam_sdk::soroban_sdk::{

use crate::{
error::Error,
events::{EventPublishable, Publish},
metadata::{ContractMetadata, PublishedContract, PublishedWasm},
util::MAX_BUMP,
version::{self, Version, INITAL_VERSION},
Expand Down Expand Up @@ -77,13 +78,13 @@ impl IsPublishable for WasmRegistry {
) -> Result<(), Error> {
let mut contract = self
.find_contract(contract_name.clone())
.unwrap_or_else(|_| PublishedContract::new(author));
.unwrap_or_else(|_| PublishedContract::new(author.clone()));
contract.author.require_auth();
let keys = contract.versions.keys();
let last_version = keys.last().unwrap_or_default();

last_version.log();
let new_version = last_version.clone().update(&kind.unwrap_or_default());
let new_version = last_version.clone().update(&kind.clone().unwrap_or_default());
new_version.log();

let metadata = if let Some(repo) = repo {
Expand All @@ -94,9 +95,20 @@ impl IsPublishable for WasmRegistry {
contract.get(Some(last_version))?.metadata
};
let hash = env().deployer().upload_contract_wasm(wasm);
let published_binary = PublishedWasm { hash, metadata };
let published_binary = PublishedWasm { hash: hash.clone(), metadata: metadata.clone() };
contract.versions.set(new_version, published_binary);
self.set_contract(contract_name, contract);
self.set_contract(contract_name.clone(), contract);

// Publish a publish event
Publish {
published_name: contract_name,
author,
hash,
repo: metadata,
kind: kind.unwrap_or_default(),
}
.publish_event(env());

Ok(())
}

Expand Down
57 changes: 56 additions & 1 deletion contracts/smartdeploy/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#![cfg(test)]
use super::*;
use crate::{error::Error, SorobanContract, SorobanContractClient};
use loam_sdk::soroban_sdk::{testutils::Address as _, Address, Bytes, Env, String};
use loam_sdk::soroban_sdk::{
testutils::{ Address as _, Events },
Address, Bytes, Env, String, IntoVal,
vec,
};
extern crate std;

// The contract that will be deployed by the Publisher contract.
Expand Down Expand Up @@ -52,6 +57,56 @@ fn handle_error_cases() {
// std::println!("{res:?}");
}

#[test]
fn publish_deploy_events() {

let (env, client, address) = &init();
env.mock_all_auths();

let published_name = String::from_str(env, "contract_a");

let bytes = Bytes::from_slice(env, contract::WASM);

client.publish(&published_name, address, &bytes, &None, &None);

let publish_data = events::Publish {
published_name: published_name.clone(),
author: address.clone(),
hash: env.deployer().upload_contract_wasm(bytes),
repo: metadata::ContractMetadata::default(),
kind: version::Update::default(),
};

let deployed_name = String::from_str(env, "deployed_contract_a");

let contract_id = client.deploy(&published_name, &Some(version::INITAL_VERSION), &deployed_name, address, &None, &None);

let deploy_data = events::Deploy {
published_name,
deployed_name,
version: version::INITAL_VERSION,
deployer: address.clone(),
contract_id,
};

assert_eq!(
env.events().all(),
vec![
&env,
(
client.address.clone(),
(String::from_str(env, "Publish"),).into_val(env),
publish_data.into_val(env)
),
(
client.address.clone(),
(String::from_str(env, "Deploy"),).into_val(env),
deploy_data.into_val(env)
),
]
);
}

// #[test]
// fn returns_most_recent_version() {
// let (env, client, address) = &init();
Expand Down
2 changes: 1 addition & 1 deletion contracts/smartdeploy/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl Version {
}

#[contracttype]
#[derive(Default)]
#[derive(Default, Clone)]
pub enum Update {
#[default]
Patch,
Expand Down
2 changes: 2 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ if test "$ID" = ""; then
fi
echo $ID

./subscribe_events.sh $ID

# smartdeploy="soroban --quiet contract invoke --id $ID"

if test "$FILE_HASH" = ""; then
Expand Down
33 changes: 33 additions & 0 deletions subscribe_events.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash

# Load the .env variables
if [ -f .env ]; then
source .env
else
echo "The file .env doesn't exist"
exit 1
fi

# Subscribe to the "Publish" event
# XDR built with JS: sorobanClient.xdr.ScVal.scvString("Publish").toXDR("base64")
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MERCURY_JWT_TOKEN" \
-d '{
"contract_id": "'"$1"'",
"topic1": "AAAADgAAAAdQdWJsaXNoAA=="
}' \
$MERCURY_BACKEND_ENDPOINT/event

# Subscribe to the "Deploy" event
# XDR built with JS: sorobanClient.xdr.ScVal.scvString("Deploy").toXDR("base64")
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MERCURY_JWT_TOKEN" \
-d '{
"contract_id": "'"$1"'",
"topic1": "AAAADgAAAAZEZXBsb3kAAA=="
}' \
$MERCURY_BACKEND_ENDPOINT/event

echo "\n\nSuccessfully subscribed to the events"
Loading