Skip to content

Commit

Permalink
feat: refactor test cases and complete proxy/agent co-build
Browse files Browse the repository at this point in the history
  • Loading branch information
liyukun committed Jan 6, 2024
1 parent 884923a commit c0dd5d5
Show file tree
Hide file tree
Showing 17 changed files with 2,228 additions and 977 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/cluster_agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
ckb-std = "0.14.3"
spore-utils = { path = "../../lib/utils" }
spore-types = { path = "../../lib/types" }
spore-errors = { path = "../../lib/errors" }

[build-dependencies]
Expand Down
45 changes: 35 additions & 10 deletions contracts/cluster_agent/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ use ckb_std::ckb_constants::Source::{CellDep, GroupInput, GroupOutput, Input, Ou
use ckb_std::ckb_types::packed::Script;
use ckb_std::high_level::{load_cell_data, load_cell_lock_hash, load_cell_type, QueryIter};
use ckb_std::{ckb_types::prelude::*, debug, high_level::load_script};

use spore_errors::error::Error;
use spore_utils::{calc_capacity_sum, find_position_by_type, find_posityion_by_type_hash};
use spore_types::generated::action;
use spore_utils::{
calc_capacity_sum, find_position_by_type, find_posityion_by_type_hash, load_type_args,
};
use spore_utils::{check_spore_address, extract_spore_action};

const CLUSTER_PROXY_ID_LEN: usize = 32;

Expand All @@ -33,17 +38,17 @@ fn process_creation(_index: usize) -> Result<(), Error> {
// verify cluster ID
let cluster_id = load_cell_data(cell_dep_index, CellDep)?;
let script = load_script()?;
let script_args: Vec<u8> = script.args().unpack();
if script_args.as_slice()[..] != cluster_id.as_slice()[..] {
if script.args().raw_data().as_ref() != &cluster_id {
return Err(Error::InvalidAgentArgs);
}

// Condition 1: Check if cluster proxy exist in Inputs & Outputs
return if find_posityion_by_type_hash(proxy_type_hash.as_slice(), Input).is_some()
&& find_posityion_by_type_hash(proxy_type_hash.as_slice(), Output).is_some()
{
Ok(())
} else {
let proxy_cell_in_input =
find_posityion_by_type_hash(proxy_type_hash.as_slice(), Input).is_some();
let proxy_cell_in_output =
find_posityion_by_type_hash(proxy_type_hash.as_slice(), Output).is_some();

if !proxy_cell_in_input || !proxy_cell_in_output {
// Condition 2: Check for minimal payment
let proxy_type_args = load_cell_type(cell_dep_index, CellDep)?
.unwrap_or_default()
Expand All @@ -62,18 +67,38 @@ fn process_creation(_index: usize) -> Result<(), Error> {
} else {
return Err(Error::PaymentMethodNotSupport);
}
Ok(())
}

// co-build check @lyk
let action::SporeActionUnion::AgentCreate(create) = extract_spore_action()?.to_enum() else {
return Err(Error::SporeActionMismatch);
};
if &cluster_id != create.cluster_id().as_slice() {
return Err(Error::SporeActionFieldMismatch);
}
check_spore_address(GroupOutput, create.to())?;

Ok(())
}

fn process_transfer() -> Result<(), Error> {
let input_agent_data = load_cell_data(0, GroupInput)?;
let output_agent_data = load_cell_data(0, GroupOutput)?;

if input_agent_data.as_slice()[..] != output_agent_data.as_slice()[..] {
if input_agent_data != output_agent_data {
return Err(Error::ImmutableAgentFieldModification);
}

// co-build check @lyk
let action::SporeActionUnion::AgentTransfer(transfer) = extract_spore_action()?.to_enum() else {
return Err(Error::SporeActionMismatch);
};
if load_type_args(0, GroupInput).as_ref() != transfer.cluster_id().as_slice() {
return Err(Error::SporeActionFieldMismatch);
}
check_spore_address(GroupInput, transfer.from())?;
check_spore_address(GroupOutput, transfer.to())?;

Ok(())
}

Expand Down
1 change: 1 addition & 0 deletions contracts/cluster_proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
ckb-std = "0.14.3"
spore-utils = { path = "../../lib/utils" }
spore-types = { path = "../../lib/types" }
spore-errors = { path = "../../lib/errors" }

[build-dependencies]
Expand Down
61 changes: 44 additions & 17 deletions contracts/cluster_proxy/src/entry.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use alloc::vec::Vec;
use ckb_std::ckb_types::prelude::Entity;
use core::result::Result;

// Import from `core` instead of from `std` since we are in no-std mode
use ckb_std::ckb_constants::Source::{CellDep, GroupInput, GroupOutput, Input, Output};
use ckb_std::ckb_types::packed::Script;
use ckb_std::high_level::{load_cell_data, load_cell_lock_hash, load_cell_type, QueryIter};
use core::result::Result;

use spore_errors::error::Error;
use spore_types::generated::action;
use spore_utils::{
find_position_by_lock_hash, find_position_by_type, find_position_by_type_args, verify_type_id,
check_spore_address, extract_spore_action, find_position_by_lock_hash, find_position_by_type,
find_position_by_type_args, load_type_args, verify_type_id,
};

const CLUSTER_PROXY_ID_LEN: usize = 32;
Expand All @@ -16,46 +21,68 @@ fn is_valid_cluster_cell(script_hash: &[u8; 32]) -> bool {
}

fn process_creation(index: usize) -> Result<(), Error> {
let target_cluster_id = load_cell_data(0, GroupOutput)?;
let cluster_id = load_cell_data(0, GroupOutput)?;
// check cluster in Deps
let cell_dep_index =
find_position_by_type_args(&target_cluster_id, CellDep, Some(is_valid_cluster_cell))
find_position_by_type_args(&cluster_id, CellDep, Some(is_valid_cluster_cell))
.ok_or(Error::ClusterCellNotInDep)?;

// verify Proxy ID
if verify_type_id(index, Output).is_none() {
let Some(proxy_id) = verify_type_id(index, Output) else {
return Err(Error::InvalidProxyID);
}
};

// Condition 1: Check if cluster exist in Inputs & Outputs
return if find_position_by_type_args(&target_cluster_id, Input, Some(is_valid_cluster_cell))
.is_some()
&& find_position_by_type_args(&target_cluster_id, Output, Some(is_valid_cluster_cell))
.is_some()
{
Ok(())
} else {
let cluster_cell_in_input =
find_position_by_type_args(&cluster_id, Input, Some(is_valid_cluster_cell)).is_some();
let cluster_cell_in_output =
find_position_by_type_args(&cluster_id, Output, Some(is_valid_cluster_cell)).is_some();

if !cluster_cell_in_input || !cluster_cell_in_output {
// Condition 2: Check if Lock Proxy exist in Inputs & Outputs
let cluster_lock_hash = load_cell_lock_hash(cell_dep_index, CellDep)?;
find_position_by_lock_hash(&cluster_lock_hash, Output)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
find_position_by_lock_hash(&cluster_lock_hash, Input)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
Ok(())
}

// co-build check @lyk
let action::SporeActionUnion::ProxyCreate(create) = extract_spore_action()?.to_enum() else {
return Err(Error::SporeActionMismatch);
};
if proxy_id != create.proxy_id().as_slice() || &cluster_id != create.cluster_id().as_slice() {
return Err(Error::SporeActionFieldMismatch);
}
check_spore_address(GroupOutput, create.to())?;

Ok(())
}

fn process_transfer() -> Result<(), Error> {
let input_proxy_type = load_cell_type(0, GroupInput)?.unwrap_or_default();
let output_proxy_type = load_cell_type(0, GroupOutput)?.unwrap_or_default();

let source_cluster_id = &input_proxy_type.args().raw_data()[..CLUSTER_PROXY_ID_LEN];
let target_cluster_id = &output_proxy_type.args().raw_data()[..CLUSTER_PROXY_ID_LEN];

// NOTE: We allow minimal payment modification during transfer
if input_proxy_type.args().raw_data()[..CLUSTER_PROXY_ID_LEN]
!= output_proxy_type.args().raw_data()[..CLUSTER_PROXY_ID_LEN]
{
if source_cluster_id != target_cluster_id {
return Err(Error::ImmutableProxyFieldModification);
}

// co-build check @lyk
let action::SporeActionUnion::ProxyTransfer(transfer) = extract_spore_action()?.to_enum() else {
return Err(Error::SporeActionMismatch);
};
if source_cluster_id != transfer.cluster_id().as_slice()
|| load_type_args(0, GroupInput).as_ref() != transfer.proxy_id().as_slice()
{
return Err(Error::SporeActionFieldMismatch);
}
check_spore_address(GroupInput, transfer.from())?;
check_spore_address(GroupOutput, transfer.to())?;

Ok(())
}

Expand Down
58 changes: 31 additions & 27 deletions contracts/spore/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ fn process_creation(index: usize) -> Result<(), Error> {
.ok_or(Error::InvalidMultipartContent)?;
}

// check in Cluster mode
if spore_data.cluster_id().to_opt().is_some() {
// check if cluster cell in deps
let cluster_id = spore_data
Expand Down Expand Up @@ -97,38 +98,41 @@ fn process_creation(index: usize) -> Result<(), Error> {
}

// Condition 1: Check if cluster exist in Inputs & Outputs
return if find_position_by_type_args(&cluster_id, Input, Some(cluster_fn)).is_some()
&& find_position_by_type_args(&cluster_id, Output, Some(cluster_fn)).is_some()
{
Ok(())
}
let cluster_cell_in_input =
find_position_by_type_args(&cluster_id, Input, Some(cluster_fn)).is_some();
let cluster_cell_in_output =
find_position_by_type_args(&cluster_id, Output, Some(cluster_fn)).is_some();

// Condition 2: Check if cluster agent in Inputs & Outputs
else if find_position_by_type_args(&cluster_id, Input, Some(agent_fn)).is_some()
&& find_position_by_type_args(&cluster_id, Output, Some(agent_fn)).is_some()
let agent_cell_in_input =
find_position_by_type_args(&cluster_id, Input, Some(agent_fn)).is_some();
let agent_cell_in_output =
find_position_by_type_args(&cluster_id, Output, Some(agent_fn)).is_some();

if (!cluster_cell_in_input || !cluster_cell_in_output)
&& (!agent_cell_in_input || !agent_cell_in_output)
{
Ok(())
// Condition 3: Use cluster agent by lock proxy
if let Some(agent_index) =
find_position_by_type_args(&cluster_id, CellDep, Some(agent_fn))
{
let agent_lock_hash = load_cell_lock_hash(agent_index, CellDep)?;
find_position_by_lock_hash(&agent_lock_hash, Output)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
find_position_by_lock_hash(&agent_lock_hash, Input)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
} else {
// Condition 4: Check if Lock Proxy exist in Inputs & Outputs
let cluster_lock_hash = load_cell_lock_hash(cell_dep_index, CellDep)?;
find_position_by_lock_hash(&cluster_lock_hash, Output)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
find_position_by_lock_hash(&cluster_lock_hash, Input)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
}
}
// Condition 3: Use cluster agent by lock proxy
else if let Some(agent_index) =
find_position_by_type_args(&cluster_id, CellDep, Some(agent_fn))
{
let agent_lock_hash = load_cell_lock_hash(agent_index, CellDep)?;
find_position_by_lock_hash(&agent_lock_hash, Output)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
find_position_by_lock_hash(&agent_lock_hash, Input)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
Ok(())
} else {
// Condition 4: Check if Lock Proxy exist in Inputs & Outputs
let cluster_lock_hash = load_cell_lock_hash(cell_dep_index, CellDep)?;
find_position_by_lock_hash(&cluster_lock_hash, Output)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
find_position_by_lock_hash(&cluster_lock_hash, Input)
.ok_or(Error::ClusterOwnershipVerifyFailed)?;
Ok(())
};
}

// check in Mutant mode
if !mime.mutants.is_empty() {
verify_extension(&mime, 0, vec![index as u8])?;
}
Expand Down
1 change: 1 addition & 0 deletions lib/errors/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub enum Error {
ClusterOwnershipVerifyFailed,
InvliadCoBuildWitnessLayout,
InvliadCoBuildMessage,
SporeActionDuplicated,
SporeActionMismatch,
SporeActionFieldMismatch,

Expand Down
34 changes: 34 additions & 0 deletions lib/types/schemas/action.mol
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,34 @@ table ClusterTransfer {
to: Address,
}

/* Actions for Cluster/Proxy */

table ProxyCreate {
cluster_id: Byte32,
proxy_id: Byte32,
to: Address,
}

table ProxyTransfer {
cluster_id: Byte32,
proxy_id: Byte32,
from: Address,
to: Address,
}

/* Actions for Cluster/Agent */

table AgentCreate {
cluster_id: Byte32,
to: Address,
}

table AgentTransfer {
cluster_id: Byte32,
from: Address,
to: Address,
}

/* Action in ScriptInfo */

union SporeAction {
Expand All @@ -53,4 +81,10 @@ union SporeAction {

ClusterCreate,
ClusterTransfer,

ProxyCreate,
ProxyTransfer,

AgentCreate,
AgentTransfer,
}
Loading

0 comments on commit c0dd5d5

Please sign in to comment.