Skip to content

Commit 0201340

Browse files
committed
feat: fix wasm registry
1 parent 5443d21 commit 0201340

File tree

8 files changed

+95
-116
lines changed

8 files changed

+95
-116
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
target/
22
.soroban/
33
.env
4-
test_snapshots/
4+
# test_snapshots/

contracts/registry/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#![no_std]
22
use loam_sdk::soroban_sdk;
33
use loam_subcontract_core::{admin::Admin, Core};
4+
5+
use metadata::PublishedWasm;
46
use registry::{
5-
contract::Contract as Contract_, wasm::Wasm, Claimable, Deployable, DevDeployable, Publishable,
7+
contract::Contract as Contract_, Claimable, Deployable, DevDeployable, Publishable
68
};
79

810
pub mod error;
@@ -16,7 +18,7 @@ use version::Version;
1618

1719
#[loam_sdk::derive_contract(
1820
Core(Admin),
19-
Publishable(Wasm),
21+
Publishable(PublishedWasm),
2022
Deployable(Contract_),
2123
Claimable(Contract_),
2224
DevDeployable(Contract_)
Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,68 @@
1-
use loam_sdk::soroban_sdk::{self, contracttype, env, to_string, Address, Map, String};
1+
use loam_sdk::{
2+
loamstorage,
3+
soroban_sdk::{self, env, Address, LoamKey, PersistentMap, String},
4+
};
25

3-
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
4-
#[contracttype]
5-
pub struct ContractMetadata {
6-
pub repo: String,
7-
}
8-
9-
impl Default for ContractMetadata {
10-
fn default() -> Self {
11-
Self {
12-
repo: to_string(""),
13-
}
14-
}
15-
}
166
//
177

188
use crate::{error::Error, version::Version};
199

20-
use super::PublishedWasm;
10+
use super::Wasm;
2111
/// Contains
22-
#[contracttype]
23-
#[derive(Clone)]
24-
pub struct PublishedContract {
25-
pub versions: Map<Version, PublishedWasm>,
26-
pub author: Address,
12+
#[loamstorage]
13+
pub struct PublishedWasm {
14+
pub versions: PersistentMap<(String, Version), Wasm>,
15+
pub author: PersistentMap<String, Address>,
16+
pub most_recent_version: PersistentMap<String, Version>,
2717
}
2818

29-
impl PublishedContract {
30-
pub fn new(author: Address) -> Self {
31-
Self {
32-
author,
33-
versions: Map::new(env()),
34-
}
19+
impl PublishedWasm {
20+
pub fn new(name: &String, author: Address) -> Self {
21+
env().deployer().with_stellar_asset(serialized_asset)
22+
let mut s = Self::default();
23+
s.author.set(name.clone(), &author);
24+
s
3525
}
3626
}
3727

38-
impl PublishedContract {
39-
pub fn most_recent_version(&self) -> Result<Version, Error> {
40-
self.versions.keys().last().ok_or(Error::NoSuchVersion)
28+
impl PublishedWasm {
29+
pub fn most_recent_version(&self, name: &String) -> Result<Version, Error> {
30+
self.most_recent_version
31+
.get(name.clone())
32+
.ok_or(Error::NoSuchVersion)
4133
}
4234

43-
pub fn get(&self, version: Option<Version>) -> Result<PublishedWasm, Error> {
35+
pub fn set_most_recent_version(&mut self, name: &String, version: Version) {
36+
self.most_recent_version.set(name.clone(), &version);
37+
}
38+
39+
pub fn get(&self, name: &String, version: Option<Version>) -> Result<Wasm, Error> {
4440
let version = if let Some(version) = version {
4541
version
4642
} else {
47-
self.most_recent_version()?
43+
self.most_recent_version(name)?
4844
};
49-
self.versions.get(version).ok_or(Error::NoSuchVersion)
45+
self.versions
46+
.get((name.clone(), version))
47+
.ok_or(Error::NoSuchVersion)
5048
}
5149

52-
pub fn set(&mut self, version: Option<Version>, binary: PublishedWasm) -> Result<(), Error> {
50+
pub fn set(
51+
&mut self,
52+
name: String,
53+
version: Option<Version>,
54+
binary: Wasm,
55+
) -> Result<(), Error> {
5356
let version = if let Some(version) = version {
5457
version
5558
} else {
56-
self.most_recent_version()?
59+
self.most_recent_version(&name)?
5760
};
58-
self.versions.set(version, binary);
61+
self.versions.set((name, version), &binary);
5962
Ok(())
6063
}
64+
65+
pub fn author(&self, name: &String) -> Option<Address> {
66+
self.author.get(name.clone())
67+
}
6168
}
Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
1-
use loam_sdk::soroban_sdk::{self, contracttype, BytesN};
1+
use loam_sdk::soroban_sdk::{self, contracttype, to_string, BytesN, String};
22

3-
use super::ContractMetadata;
3+
4+
5+
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
6+
#[contracttype]
7+
pub struct Metadata {
8+
pub repo: String,
9+
}
10+
11+
impl Default for Metadata {
12+
fn default() -> Self {
13+
Self {
14+
repo: to_string(""),
15+
}
16+
}
17+
}
418

519
/// Contains info about specific version of published binary
620
#[contracttype]
721
#[derive(Clone, Debug)]
8-
pub struct PublishedWasm {
22+
pub struct Wasm {
923
pub hash: BytesN<32>,
10-
pub metadata: ContractMetadata,
24+
pub metadata: Metadata,
1125
}

contracts/registry/src/registry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub trait IsPublishable {
2727
&self,
2828
contract_name: soroban_sdk::String,
2929
version: Option<Version>,
30-
) -> Result<crate::metadata::PublishedWasm, Error>;
30+
) -> Result<crate::metadata::Wasm, Error>;
3131

3232
/// Publish a binary. If contract had been previously published only previous author can publish again
3333
fn publish(

contracts/registry/src/registry/contract.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
use loam_sdk::{
33
loamstorage,
44
soroban_sdk::{
5-
self, contracttype, env, symbol_short, Address, BytesN, Env, IntoVal, Lazy, LoamKey,
5+
self, contracttype, env, symbol_short, Address, BytesN, Env, IntoVal, LoamKey,
66
PersistentMap, String, Symbol, Val,
77
},
88
};
99

1010
use crate::{
11-
error::Error, registry::Publishable, util::hash_string, version::Version,
12-
Contract as Contract_, Wasm,
11+
error::Error, metadata::PublishedWasm, registry::Publishable, util::hash_string,
12+
version::Version, Contract as Contract_,
1313
};
1414

1515
use super::{IsClaimable, IsDeployable, IsDevDeployable};
@@ -87,10 +87,7 @@ impl IsDeployable for Contract {
8787
// Publish a deploy event
8888
let version = version.map_or_else(
8989
|| {
90-
let published_contract = Wasm::get_lazy()
91-
.unwrap()
92-
.find_contract(contract_name.clone())?;
93-
published_contract.most_recent_version()
90+
PublishedWasm::default().most_recent_version(&contract_name)
9491
},
9592
Ok,
9693
)?;
Lines changed: 19 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,20 @@
1-
use loam_sdk::{
2-
loamstorage, log,
3-
soroban_sdk::{self, env, Address, LoamKey, PersistentMap, String},
4-
};
1+
use loam_sdk::soroban_sdk::{self, env, Address, String};
52

63
use crate::{
74
error::Error,
8-
metadata::{ContractMetadata, PublishedContract, PublishedWasm},
5+
metadata::{Metadata, PublishedWasm, Wasm},
96
version::{self, Version, INITAL_VERSION},
107
};
118

129
use super::IsPublishable;
1310

14-
#[loamstorage]
15-
16-
pub struct Wasm {
17-
registry: PersistentMap<String, PublishedContract>,
18-
}
19-
20-
impl Wasm {
21-
pub fn find_contract(&self, name: String) -> Result<PublishedContract, Error> {
22-
self.registry
23-
.get(name)
24-
.ok_or(Error::NoSuchContractPublished)
25-
}
26-
27-
pub fn find_version(
28-
&self,
29-
name: String,
30-
version: Option<Version>,
31-
) -> Result<PublishedWasm, Error> {
32-
self.find_contract(name)?.get(version)
33-
}
34-
35-
pub fn set_contract(&mut self, name: String, contract: &PublishedContract) {
36-
self.registry.set(name, contract);
37-
}
38-
}
39-
40-
impl IsPublishable for Wasm {
41-
fn fetch(
42-
&self,
43-
contract_name: String,
44-
version: Option<Version>,
45-
) -> Result<PublishedWasm, Error> {
46-
self.find_version(contract_name, version)
11+
impl IsPublishable for PublishedWasm {
12+
fn fetch(&self, contract_name: String, version: Option<Version>) -> Result<Wasm, Error> {
13+
self.get(&contract_name, version)
4714
}
4815

4916
fn current_version(&self, contract_name: String) -> Result<Version, Error> {
50-
self.find_contract(contract_name)?.most_recent_version()
17+
self.most_recent_version(&contract_name)
5118
}
5219

5320
fn publish(
@@ -70,34 +37,31 @@ impl IsPublishable for Wasm {
7037
repo: Option<soroban_sdk::String>,
7138
kind: Option<version::Update>,
7239
) -> Result<(), Error> {
73-
let mut contract = self
74-
.find_contract(wasm_name.clone())
75-
.unwrap_or_else(|_| PublishedContract::new(author.clone()));
76-
77-
if author != contract.author {
78-
return Err(Error::AlreadyPublished);
40+
if let Some(cunnet_author) = self.author(&wasm_name) {
41+
if author != cunnet_author {
42+
return Err(Error::AlreadyPublished);
43+
}
7944
}
80-
contract.author.require_auth();
8145

82-
let keys = contract.versions.keys();
83-
let last_version = keys.last().unwrap_or_default();
46+
author.require_auth();
47+
48+
let last_version: Version = self.most_recent_version(&wasm_name).unwrap_or_default();
8449
last_version.log();
8550
let new_version = last_version.clone().update(&kind.unwrap_or_default());
8651
new_version.log();
8752

8853
let metadata = if let Some(repo) = repo {
89-
ContractMetadata { repo }
54+
Metadata { repo }
9055
} else if new_version == INITAL_VERSION {
91-
ContractMetadata::default()
56+
Metadata::default()
9257
} else {
93-
contract.get(Some(last_version))?.metadata
58+
self.get(&wasm_name, Some(last_version))?.metadata
9459
};
95-
let published_binary = PublishedWasm {
60+
let published_binary = Wasm {
9661
hash: wasm_hash,
9762
metadata,
9863
};
99-
contract.versions.set(new_version, published_binary);
100-
self.set_contract(wasm_name, &contract);
101-
Ok(())
64+
self.set_most_recent_version(&wasm_name, new_version.clone());
65+
self.set(wasm_name, Some(new_version), published_binary)
10266
}
10367
}

contracts/registry/src/test.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,20 @@ fn handle_error_cases() {
3232
let name = &to_string("publisher");
3333
assert_matches!(
3434
client.try_fetch(name, &None).unwrap_err(),
35-
Ok(Error::NoSuchContractPublished)
35+
Ok(Error::NoSuchVersion)
3636
);
3737

3838
let wasm_hash = env.deployer().upload_contract_wasm(loam_registry::WASM);
3939

4040
assert_matches!(
4141
client.try_fetch(name, &None).unwrap_err(),
42-
Ok(Error::NoSuchContractPublished)
42+
Ok(Error::NoSuchVersion)
4343
);
4444

4545
let bytes = Bytes::from_slice(env, loam_registry::WASM);
4646
env.mock_all_auths();
47-
let res = client.try_publish(name, address, &bytes, &None, &None);
48-
res.unwrap();
49-
// assert_eq!(client.try_fetch(name, &None).unwrap().unwrap().hash, wasm_hash);
47+
client.publish(name, address, &bytes, &None, &None);
48+
assert_eq!(client.fetch(name, &None).hash, wasm_hash);
5049

5150
// let other_address = Address::generate(env);
5251
// let res = client
@@ -64,17 +63,13 @@ fn returns_most_recent_version() {
6463
// client.register_name(address, name);
6564
let bytes = Bytes::from_slice(env, loam_registry::WASM);
6665
env.mock_all_auths();
67-
client
68-
.try_publish(name, address, &bytes, &None, &None)
69-
.unwrap();
66+
client.publish(name, address, &bytes, &None, &None);
7067
let fetched_hash = client.fetch(name, &None).hash;
7168
let wasm_hash = env.deployer().upload_contract_wasm(loam_registry::WASM);
7269
assert_eq!(fetched_hash, wasm_hash);
7370

7471
let second_hash: BytesN<32> = BytesN::random(env);
75-
client
76-
.try_publish_hash(name, address, &second_hash.into_val(env), &None, &None)
77-
.unwrap();
72+
client.publish_hash(name, address, &second_hash.into_val(env), &None, &None);
7873
let res = client.fetch(name, &None).hash;
7974
assert_eq!(res, second_hash);
8075

0 commit comments

Comments
 (0)